Project

General

Profile

Statistics
| Revision:

root / trunk / toolbox / main.c @ 202

History | View | Annotate | Download (8.54 KB)

1
/********
2
 * This file is part of Tooltron.
3
 *
4
 * Tooltron is free software: you can redistribute it and/or modify
5
 * it under the terms of the Lesser GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * Tooltron is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * Lesser GNU General Public License for more details.
13
 * You should have received a copy of the Lesser GNU General Public License
14
 * along with Tooltron.  If not, see <http://www.gnu.org/licenses/>.
15
 *
16
 * Copyright 2009 Kevin Woo <kwoo@2ndt.com>
17
 *
18
 ********/
19
/** @file main.c
20
 *  @brief Contains the main function for the toolbox code.
21
 *
22
 *  @author Suresh Nidhiry (snidhiry@andrew.cmu.edu)
23
 *  @author Kevin Woo (kwoo@2ndt.com)
24
 */
25

    
26
//Includes
27
#include <avr/io.h>
28
#include <avr/interrupt.h>
29
#include <avr/eeprom.h>
30
#include <stdint.h>
31
#include <util/delay.h>
32
#include <tooltron.h>
33
#include "jumptable.h"
34
#include "reset.h"
35
#include <toolbox_pindefs.h>
36

    
37
/***
38
 * TWAIT - minutes to wait before green button is pressed to kill power
39
 * TWARN - minutes until warning (blink yellow, allow more time with green button)
40
 * TMAX  - minutes until power is killed (unless tool is on)
41
 */
42
#define TWAIT   1
43
#define TWARN   1
44
#define TMAX    2
45

    
46
uint8_t sec;
47
uint8_t min;
48

    
49
typedef enum {
50
    wait,   // wait for a turn on packet
51
    pwron,  // poweron
52
    idiot,  // user tried to hit green with the machine switch on
53
    toolon, // tool on
54
    warn,   // time warning
55
    off     // tool off
56
} state_t;
57

    
58
/**
59
 * @brief Sets the LED to the specified state
60
 *
61
 * This sets LED which to the specified state. You can use this to set
62
 * multiple LEDs if you OR the LEDs desired into the which argument.
63
 *
64
 * @param which The LEDs to set
65
 * @parma state The state ON or OFF to set to the LEDs to
66
 * @return void
67
 */
68
void toggle_led(uint8_t which, uint8_t state) {
69
    if (state == ON) {
70
        LED_PORT &= ~(which);
71
    } else {
72
        LED_PORT |= (which);
73
    }
74
}
75

    
76
/**
77
 * @brief Sets the relay to a particular state
78
 *
79
 * @param state Sets the relay to either ON or OFF
80
 * @return void
81
 */
82
void toggle_relay(uint8_t state) {
83
    if (state == ON) {
84
        RELAY_PORT |= RELAY;
85
    } else {
86
        RELAY_PORT &= ~RELAY;
87
    }
88
}
89

    
90
/**
91
 * @brief Returns the current value of the AC voltage sense
92
 *
93
 * @return ON if AC voltage is detected, OFF otherwise
94
 */
95
inline uint8_t read_vac(void) {
96
    return (!(VAC_PORT & VAC_SENSE));
97
}
98

    
99
/**
100
 * @brief Returns the current value of the buttons
101
 *
102
 * You can read multiple buttons at once but it will only return TRUE
103
 * if all of the buttons are pressed. You should OR the buttons together
104
 * while passing them into which.
105
 *
106
 * @param which The buttons to read
107
 * @return TRUE if the buttons are pressed, FALSE otherwise
108
 */
109
inline uint8_t read_button(uint8_t which) {
110
    return (!(BUT_PORT & (which)));
111
}
112

    
113
/**
114
 * @brief Initialize the hardware timer to be a realtime clock
115
 *
116
 * This will set timer 1 to cause an interrupt every 1 second assuming
117
 * you are using a 8MHz clock. The global sec and min counters are 
118
 * reset as well.
119
 *
120
 * @return void
121
 */
122
void init_timer(void) {
123
    // Clear timmer on OCRA1 Compare match
124
    // No prescale
125
    TCCR1B |= _BV(WGM12) | _BV(CS12);
126
    
127
    // 1 second @ 8MHz clock
128
    OCR1A = 0x7A12;
129

    
130
    TIMSK = _BV(OCIE1A);
131

    
132
    sec = 0;
133
    min = 0;
134
}
135

    
136
/**
137
 * @brief Resets the timer
138
 * @return void
139
 */
140
void reset_timer(void) {
141
    sec = 0;
142
    min = 0;
143
}
144

    
145
/**
146
 * @brief Timer1 interrupt vector
147
 *
148
 * This counts the seconds and minute since the last reset. Automatically
149
 * resets the seconds once it rolls over to 60s and increments minutes.
150
 *
151
 * @note minutes may overflow if you let it run long enough. There are no
152
 * checks against this
153
 */
154
ISR(TIMER1_COMPA_vect) {
155
    if (sec == 59) {
156
        sec = 0;
157
        ++min;
158
    } else {
159
        ++sec;
160
    }
161
}
162

    
163

    
164
int main(void) {
165
    state_t state = wait;
166
    // This reads the node addr
167
    uint8_t addr = eeprom_read_byte((void*)EEPROM_ADDR);    
168
    uint8_t ms_timer=0;
169
    uint8_t mbuf[PROGD_PACKET_SIZE];    // For reading messages
170

    
171
        /***** Start Start-up Sequence *****/
172
    // We are initializing the pins and the RS485 in the bootloader
173
        sei();                                //Enable interrupts
174
        init_timer();                //Set registers for timer
175
        /***** End Start-up Sequence *****/
176

    
177
    uint8_t resp;
178
    
179
        while(1) {
180
        switch (state) {
181
            case wait:
182
                // Reset the lights and relay
183
                toggle_led(LED_RED, ON);
184
                toggle_led(LED_YELLOW | LED_GREEN, OFF);
185
                toggle_relay(OFF);
186

    
187
                // Wait for a packet
188
                resp = parse_packet(mbuf, addr);
189

    
190
                // Turn on the tool
191
                if (resp == TT_ON) {
192
                    send_packet(TT_ACK, addr);
193

    
194
                    toggle_led(LED_RED, OFF);
195
                    toggle_led(LED_YELLOW, ON);
196
                    state = pwron;
197
                    reset_timer();
198
                // Reset the board
199
                } else if (resp == TT_RESET) {
200
                    send_packet(TT_ACK, addr);
201
                    reset();
202
                }
203
                break;
204
            case pwron:
205
                // Make sure the tool isn't on before we apply power
206
                    if (read_vac() == ON) {
207
                            ms_timer = 0;
208
                            state = idiot;
209
                            break;
210
                    }
211

    
212
                // Wait for a black button press
213
                if (read_button(BUT_BLACK)) {
214
                    toggle_led(LED_YELLOW, OFF);
215
                    toggle_led(LED_GREEN, ON);
216
                    toggle_relay(ON);
217

    
218
                    reset_timer();
219
                    state = toolon;
220
                // Timeout waiting for the user
221
                } else if ((read_button(BUT_RED)) || (min >= TWAIT)) {
222
                    state = off;
223
                }
224
                break;
225
            case idiot:
226
                // We can safely exit this state if the tool is switched off
227
                if (read_vac() == OFF) {
228
                    state = pwron;
229
                    toggle_led(LED_RED, OFF);
230
                    toggle_led(LED_YELLOW, ON);
231
                    break;
232
                }
233

    
234
                // The user has cancelled the tooltron request
235
                if (read_button(BUT_RED)) {
236
                    state = off;
237
                    break;
238
                }
239

    
240
                // Blink code
241
                if(ms_timer >= 100) {
242
                    toggle_led(LED_YELLOW, ON);
243
                    toggle_led(LED_RED, OFF);
244
            
245
                    if(ms_timer >= 200) {
246
                        ms_timer = 0;
247
                    }
248
                } else {
249
                    toggle_led(LED_YELLOW, OFF);
250
                    toggle_led(LED_RED, ON);
251
                }
252

    
253
                _delay_ms(2);
254
                ms_timer++;
255
                break;
256

    
257
            case toolon:
258
                // Give the tool power until the red button is pressed
259
                if ((read_button(BUT_RED)) && (read_vac() == OFF)) {
260
                        state = off;
261
                        toggle_relay(OFF);
262
                // Time is about to expire
263
                } else if (min >= TWARN) {
264
                    toggle_led(LED_GREEN, OFF);
265
                    state = warn;
266
                }
267
                break;
268

    
269
            case warn:
270
                // Blink the LED
271
                        if(ms_timer >= 100) {
272
                            toggle_led(LED_YELLOW, ON);
273
                
274
                            if(ms_timer >= 200) {
275
                                ms_timer = 0;
276
                            }
277
                        } else {
278
                            toggle_led(LED_YELLOW, OFF);
279
                        }
280

    
281
                // User turns off the tool if it's safe
282
                if (read_button(BUT_RED) && read_vac() == OFF) {
283
                    toggle_relay(OFF);
284
                    state = off;
285
                // Time extension
286
                } else if (read_button(BUT_BLACK)) {
287
                    toggle_led(LED_GREEN, ON);
288
                    toggle_led(LED_YELLOW, OFF);
289
                    reset_timer();
290
                    state = toolon;
291
                // Time expired and it's safe to turn off
292
                } else if ((min >= TMAX) && (read_vac() == OFF)) {
293
                    toggle_relay(OFF);
294
                    state = off;
295
                }
296

    
297
                        _delay_ms(2);
298
                        ms_timer++;
299

    
300
                break;
301
            case off:
302
                toggle_led(LED_GREEN | LED_YELLOW, OFF);
303
                toggle_led(LED_RED, ON);
304
                state = wait;
305
                break;
306
            default: state = wait;
307
        }     
308
        }
309
        
310
        return 0;
311
}