Project

General

Profile

Statistics
| Revision:

root / trunk / toolbox / main.c @ 227

History | View | Annotate | Download (8.89 KB)

1 139 kwoo
/********
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 2 snidhiry
/** @file main.c
20
 *  @brief Contains the main function for the toolbox code.
21
 *
22 191 kwoo
 *  @author Suresh Nidhiry (snidhiry@andrew.cmu.edu)
23
 *  @author Kevin Woo (kwoo@2ndt.com)
24 2 snidhiry
 */
25
26 6 kwoo
//Includes
27
#include <avr/io.h>
28 8 kwoo
#include <avr/interrupt.h>
29 202 kwoo
#include <avr/eeprom.h>
30 114 kwoo
#include <stdint.h>
31
#include <util/delay.h>
32 191 kwoo
#include <tooltron.h>
33 204 kwoo
#include <toolbox_pindefs.h>
34 191 kwoo
#include "jumptable.h"
35 114 kwoo
36 143 bneuman
/***
37
 * TWAIT - minutes to wait before green button is pressed to kill power
38
 * TWARN - minutes until warning (blink yellow, allow more time with green button)
39
 * TMAX  - minutes until power is killed (unless tool is on)
40
 */
41 129 kwoo
#define TWAIT   1
42 123 kwoo
#define TWARN   1
43
#define TMAX    2
44
45
uint8_t sec;
46
uint8_t min;
47
48 114 kwoo
typedef enum {
49 202 kwoo
    wait,   // wait for a turn on packet
50 114 kwoo
    pwron,  // poweron
51 149 bneuman
    idiot,  // user tried to hit green with the machine switch on
52 116 kwoo
    toolon, // tool on
53 129 kwoo
    warn,   // time warning
54
    off     // tool off
55 114 kwoo
} state_t;
56
57 202 kwoo
/**
58
 * @brief Sets the LED to the specified state
59
 *
60
 * This sets LED which to the specified state. You can use this to set
61
 * multiple LEDs if you OR the LEDs desired into the which argument.
62
 *
63
 * @param which The LEDs to set
64
 * @parma state The state ON or OFF to set to the LEDs to
65
 * @return void
66
 */
67 115 kwoo
void toggle_led(uint8_t which, uint8_t state) {
68 114 kwoo
    if (state == ON) {
69 202 kwoo
        LED_PORT &= ~(which);
70 114 kwoo
    } else {
71 202 kwoo
        LED_PORT |= (which);
72 114 kwoo
    }
73
}
74
75 202 kwoo
/**
76
 * @brief Sets the relay to a particular state
77
 *
78
 * @param state Sets the relay to either ON or OFF
79
 * @return void
80
 */
81 117 kwoo
void toggle_relay(uint8_t state) {
82
    if (state == ON) {
83 202 kwoo
        RELAY_PORT |= RELAY;
84 117 kwoo
    } else {
85 202 kwoo
        RELAY_PORT &= ~RELAY;
86 117 kwoo
    }
87
}
88
89 202 kwoo
/**
90
 * @brief Returns the current value of the AC voltage sense
91
 *
92
 * @return ON if AC voltage is detected, OFF otherwise
93
 */
94 129 kwoo
inline uint8_t read_vac(void) {
95 202 kwoo
    return (!(VAC_PORT & VAC_SENSE));
96 129 kwoo
}
97
98 202 kwoo
/**
99
 * @brief Returns the current value of the buttons
100
 *
101
 * You can read multiple buttons at once but it will only return TRUE
102
 * if all of the buttons are pressed. You should OR the buttons together
103
 * while passing them into which.
104
 *
105 227 bneuman
 * Software debounce is written in to protect against vibration
106
 * transients, definable by BUTTON_DEBOUNCE. Specifically, for the
107
 * button to not be pressed it only needs to read 0 once, but needs to
108
 * read 1 BUTTON_DEBONCE times in a row to return TRUE.
109
 *
110 202 kwoo
 * @param which The buttons to read
111
 * @return TRUE if the buttons are pressed, FALSE otherwise
112
 */
113 115 kwoo
inline uint8_t read_button(uint8_t which) {
114 227 bneuman
    uint8_t count = 0;
115
116
    while(!(BUT_PORT & (which))){
117
        if(++count > BUTTON_DEBOUNCE) {
118
            return TRUE;
119
        }
120
    }
121
122
    return FALSE;
123 115 kwoo
}
124
125 202 kwoo
/**
126
 * @brief Initialize the hardware timer to be a realtime clock
127
 *
128
 * This will set timer 1 to cause an interrupt every 1 second assuming
129
 * you are using a 8MHz clock. The global sec and min counters are
130
 * reset as well.
131
 *
132
 * @return void
133
 */
134 123 kwoo
void init_timer(void) {
135
    // Clear timmer on OCRA1 Compare match
136
    // No prescale
137
    TCCR1B |= _BV(WGM12) | _BV(CS12);
138
139
    // 1 second @ 8MHz clock
140 202 kwoo
    OCR1A = 0x7A12;
141 123 kwoo
142
    TIMSK = _BV(OCIE1A);
143
144
    sec = 0;
145
    min = 0;
146
}
147
148 202 kwoo
/**
149
 * @brief Resets the timer
150
 * @return void
151
 */
152 123 kwoo
void reset_timer(void) {
153
    sec = 0;
154
    min = 0;
155
}
156
157 202 kwoo
/**
158
 * @brief Timer1 interrupt vector
159
 *
160
 * This counts the seconds and minute since the last reset. Automatically
161
 * resets the seconds once it rolls over to 60s and increments minutes.
162
 *
163
 * @note minutes may overflow if you let it run long enough. There are no
164
 * checks against this
165
 */
166 123 kwoo
ISR(TIMER1_COMPA_vect) {
167
    if (sec == 59) {
168
        sec = 0;
169 202 kwoo
        ++min;
170 123 kwoo
    } else {
171 202 kwoo
        ++sec;
172 123 kwoo
    }
173
}
174
175
176 202 kwoo
int main(void) {
177
    state_t state = wait;
178
    // This reads the node addr
179
    uint8_t addr = eeprom_read_byte((void*)EEPROM_ADDR);
180 148 bneuman
    uint8_t ms_timer=0;
181 202 kwoo
    uint8_t mbuf[PROGD_PACKET_SIZE];    // For reading messages
182 218 bneuman
    uint8_t len;
183 2 snidhiry
184 6 kwoo
        /***** Start Start-up Sequence *****/
185 202 kwoo
    // We are initializing the pins and the RS485 in the bootloader
186 8 kwoo
        sei();                                //Enable interrupts
187 123 kwoo
        init_timer();                //Set registers for timer
188 6 kwoo
        /***** End Start-up Sequence *****/
189 3 kwoo
190 202 kwoo
    uint8_t resp;
191 114 kwoo
192 6 kwoo
        while(1) {
193 114 kwoo
        switch (state) {
194 202 kwoo
            case wait:
195
                // Reset the lights and relay
196 150 bneuman
                toggle_led(LED_RED, ON);
197 202 kwoo
                toggle_led(LED_YELLOW | LED_GREEN, OFF);
198 117 kwoo
                toggle_relay(OFF);
199 114 kwoo
200 202 kwoo
                // Wait for a packet
201 218 bneuman
                resp = parse_packet(mbuf, &len, addr);
202 114 kwoo
203 202 kwoo
                // Turn on the tool
204
                if (resp == TT_ON) {
205 217 kwoo
                    send_packet(TT_ACK, addr, NULL, 0);
206 114 kwoo
207 202 kwoo
                    toggle_led(LED_RED, OFF);
208
                    toggle_led(LED_YELLOW, ON);
209
                    state = pwron;
210
                    reset_timer();
211 217 kwoo
                } else if (resp == TT_PING) {
212 223 kwoo
                    _delay_ms(50);
213 217 kwoo
                    send_packet(TT_ACK, addr, NULL, 0);
214 114 kwoo
                }
215
                break;
216 116 kwoo
            case pwron:
217 202 kwoo
                // Make sure the tool isn't on before we apply power
218
                    if (read_vac() == ON) {
219
                            ms_timer = 0;
220
                            state = idiot;
221
                            break;
222
                    }
223 149 bneuman
224 202 kwoo
                // Wait for a black button press
225 149 bneuman
                if (read_button(BUT_BLACK)) {
226 115 kwoo
                    toggle_led(LED_YELLOW, OFF);
227
                    toggle_led(LED_GREEN, ON);
228 149 bneuman
                    toggle_relay(ON);
229
230
                    reset_timer();
231
                    state = toolon;
232 202 kwoo
                // Timeout waiting for the user
233 129 kwoo
                } else if ((read_button(BUT_RED)) || (min >= TWAIT)) {
234
                    state = off;
235 114 kwoo
                }
236
                break;
237 202 kwoo
            case idiot:
238
                // We can safely exit this state if the tool is switched off
239
                if (read_vac() == OFF) {
240
                    state = pwron;
241
                    toggle_led(LED_RED, OFF);
242
                    toggle_led(LED_YELLOW, ON);
243
                    break;
244
                }
245 148 bneuman
246 202 kwoo
                // The user has cancelled the tooltron request
247
                if (read_button(BUT_RED)) {
248
                    state = off;
249
                    break;
250
                }
251 149 bneuman
252 202 kwoo
                // Blink code
253
                if(ms_timer >= 100) {
254
                    toggle_led(LED_YELLOW, ON);
255
                    toggle_led(LED_RED, OFF);
256
257
                    if(ms_timer >= 200) {
258
                        ms_timer = 0;
259
                    }
260
                } else {
261
                    toggle_led(LED_YELLOW, OFF);
262
                    toggle_led(LED_RED, ON);
263
                }
264 148 bneuman
265 202 kwoo
                _delay_ms(2);
266
                ms_timer++;
267
                break;
268 148 bneuman
269 116 kwoo
            case toolon:
270 202 kwoo
                // Give the tool power until the red button is pressed
271 129 kwoo
                if ((read_button(BUT_RED)) && (read_vac() == OFF)) {
272
                        state = off;
273
                        toggle_relay(OFF);
274 202 kwoo
                // Time is about to expire
275 123 kwoo
                } else if (min >= TWARN) {
276
                    toggle_led(LED_GREEN, OFF);
277
                    state = warn;
278 116 kwoo
                }
279
                break;
280 123 kwoo
281 116 kwoo
            case warn:
282 202 kwoo
                // Blink the LED
283
                        if(ms_timer >= 100) {
284
                            toggle_led(LED_YELLOW, ON);
285 148 bneuman
286 202 kwoo
                            if(ms_timer >= 200) {
287
                                ms_timer = 0;
288
                            }
289
                        } else {
290
                            toggle_led(LED_YELLOW, OFF);
291
                        }
292 123 kwoo
293 202 kwoo
                // User turns off the tool if it's safe
294 150 bneuman
                if (read_button(BUT_RED) && read_vac() == OFF) {
295 123 kwoo
                    toggle_relay(OFF);
296 129 kwoo
                    state = off;
297 202 kwoo
                // Time extension
298 116 kwoo
                } else if (read_button(BUT_BLACK)) {
299 123 kwoo
                    toggle_led(LED_GREEN, ON);
300
                    toggle_led(LED_YELLOW, OFF);
301
                    reset_timer();
302 116 kwoo
                    state = toolon;
303 202 kwoo
                // Time expired and it's safe to turn off
304 129 kwoo
                } else if ((min >= TMAX) && (read_vac() == OFF)) {
305
                    toggle_relay(OFF);
306
                    state = off;
307
                }
308 148 bneuman
309 202 kwoo
                        _delay_ms(2);
310
                        ms_timer++;
311 148 bneuman
312 116 kwoo
                break;
313 129 kwoo
            case off:
314 202 kwoo
                toggle_led(LED_GREEN | LED_YELLOW, OFF);
315 129 kwoo
                toggle_led(LED_RED, ON);
316 202 kwoo
                state = wait;
317 129 kwoo
                break;
318 202 kwoo
            default: state = wait;
319 123 kwoo
        }
320 6 kwoo
        }
321
322
        return 0;
323
}