Project

General

Profile

Statistics
| Revision:

root / trunk / toolbox / main.c @ 191

History | View | Annotate | Download (7.98 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 <stdint.h>
30
#include <util/delay.h>
31
#include <tooltron.h>
32
#include "jumptable.h"
33
#define TOOLBOX
34
#define RELAY       _BV(PORTD4)
35
#define VAC_SENSE   _BV(PIND3)
36
#define BUT_RED     _BV(PINB4)
37
#define BUT_BLACK   _BV(PINB3)
38
#define LED_GREEN   _BV(PORTB2)
39
#define LED_YELLOW  _BV(PORTB1)
40
#define LED_RED     _BV(PORTB0)
41
#define ON      0x01
42
#define OFF     0x00
43

    
44
/***** change ADDR ****/
45
#define ADDR 18
46
#define DELIM '^'
47
#define SERVER 1
48
#define TURNON 'O'
49

    
50
/***
51
 * TWAIT - minutes to wait before green button is pressed to kill power
52
 * TWARN - minutes until warning (blink yellow, allow more time with green button)
53
 * TMAX  - minutes until power is killed (unless tool is on)
54
 */
55
#define TWAIT   1
56
#define TWARN   1
57
#define TMAX    2
58

    
59
uint8_t sec;
60
uint8_t min;
61

    
62
typedef enum {
63
    sd,     // start delimitor
64
    src,    // src
65
    dest,   // destination
66
    data,   // data
67
    cs,     // checksum
68
    ack,    // send ack
69
    pwron,  // poweron
70
    idiot,  // user tried to hit green with the machine switch on
71
    toolon, // tool on
72
    warn,   // time warning
73
    off     // tool off
74
} state_t;
75

    
76
void init_pins(void) {
77
    DDRB = 0x00;
78
    DDRB = _BV(DDB0) | _BV(DDB1) | _BV(DDB2) | _BV(DDB5);
79
    DDRD = _BV(DDB4);
80
    PORTB = 0x00;
81
}
82

    
83
void toggle_led(uint8_t which, uint8_t state) {
84
    if (state == ON) {
85
        PORTB &= ~which;
86
    } else {
87
        PORTB |= which;
88
    }
89
}
90

    
91
void toggle_relay(uint8_t state) {
92
    if (state == ON) {
93
        PORTD |= RELAY;
94
    } else {
95
        PORTD &= ~RELAY;
96
    }
97
}
98

    
99
inline uint8_t read_vac(void) {
100
    return (!(PIND & VAC_SENSE));
101
}
102

    
103
inline uint8_t read_button(uint8_t which) {
104
    return (!(PINB & which));
105
}
106

    
107
void init_timer(void) {
108
    // Clear timmer on OCRA1 Compare match
109
    // No prescale
110
    TCCR1B |= _BV(WGM12) | _BV(CS12);
111
    
112
    // 1 second @ 8MHz clock
113
    OCR1AH =0x7A;
114
    OCR1AL =0x12;
115

    
116
    TIMSK = _BV(OCIE1A);
117

    
118
    sec = 0;
119
    min = 0;
120
}
121

    
122
void reset_timer(void) {
123
    sec = 0;
124
    min = 0;
125
}
126

    
127
ISR(TIMER1_COMPA_vect) {
128
    if (sec == 59) {
129
        sec = 0;
130
        min++;
131
    } else {
132
        sec++;
133
    }
134
}
135

    
136

    
137
int main(int argc, char **argv) {
138
    state_t state = sd;
139
    uint8_t packet[3];
140
    uint8_t ms_timer=0;
141

    
142
        /***** Start Start-up Sequence *****/
143
        sei();                                //Enable interrupts
144
        init_timer();                //Set registers for timer
145
        init_pins();                //Set pin directions
146
    rs485_init(51);
147
        /***** End Start-up Sequence *****/
148

    
149
    uint8_t r;
150
    
151
    packet[0] = 0x00;
152
    packet[1] = 0x00;
153
    packet[2] = 0x00;
154
   
155
        while(1) {
156
        switch (state) {
157
            case sd:
158
                toggle_led(LED_RED, ON);
159
                toggle_led(LED_YELLOW, OFF);
160
                toggle_led(LED_GREEN, OFF);
161
                toggle_relay(OFF);
162
                while ((rs485_get_byte(&r)) < 0);
163
                if (r == DELIM) {
164
                    state = src;
165
                }
166
                break;
167
            case src:
168
                while ((rs485_get_byte(&r)) < 0);
169

    
170
                if (r == DELIM) {
171
                    state = src;
172
                } else {
173
                    packet[0] = r;
174
                    state = dest;
175
                }
176
                break;
177
            case dest:
178
                while ((rs485_get_byte(&r)) < 0);
179

    
180
                if (r == DELIM) {
181
                    packet[0] = 0x00;
182
                    state = src;
183
                } else if (r == ADDR) {
184
                    packet[1] = r;
185
                    state = data;
186
                } else {
187
                    packet[0] = 0x00;
188
                    state = sd;
189
                }
190
                break;
191
            case data:
192
                while ((rs485_get_byte(&r)) < 0);
193
                
194
                if (r == DELIM) {
195
                    packet[0] = 0x00;
196
                    packet[1] = 0x00;
197
                    state = src;
198
                } else {
199
                    packet[2] = r;
200
                    state = cs;
201
                }
202
                break;
203
            case cs:
204
                while ((rs485_get_byte(&r)) < 0);
205

    
206
                if (r == (packet[0] ^ packet[1] ^ packet[2])) {
207

    
208
                    if (packet[2] == TURNON) {
209
                        state = ack;
210
                        break;
211
                    }
212
                }
213

    
214
                packet[0] = 0x00;
215
                packet[1] = 0x00;
216
                packet[2] = 0x00;
217
                state = sd;
218
                break;
219
            case ack:
220
                rs485_send_byte(DELIM);
221
                rs485_send_byte(ADDR);
222
                rs485_send_byte(SERVER);
223
                rs485_send_byte('A');
224
                rs485_send_byte(ADDR ^ SERVER ^ 'A');
225

    
226
                toggle_led(LED_RED, OFF);
227
                toggle_led(LED_YELLOW, ON);
228

    
229
                state = pwron;
230
                reset_timer();
231
                break;
232
            case pwron:
233
              if (read_vac() == ON) {
234
                ms_timer = 0;
235
                state = idiot;
236
                break;
237
              }
238

    
239
                if (read_button(BUT_BLACK)) {
240
                    toggle_led(LED_YELLOW, OFF);
241
                    toggle_led(LED_GREEN, ON);
242
                    toggle_relay(ON);
243

    
244
                    reset_timer();
245
                    state = toolon;
246
                } else if ((read_button(BUT_RED)) || (min >= TWAIT)) {
247
                    state = off;
248
                }
249
                break;
250
            case idiot:
251
              if (read_vac() == OFF) {
252
                state = pwron;
253
                toggle_led(LED_RED, OFF);
254
                toggle_led(LED_YELLOW, ON);
255
                break;
256
              }
257

    
258
              if (read_button(BUT_RED)) {
259
                state = off;
260
                break;
261
              }
262

    
263
              if(ms_timer >= 100) {
264
                toggle_led(LED_YELLOW, ON);
265
                toggle_led(LED_RED, OFF);
266
                
267
                if(ms_timer >= 200) {
268
                  ms_timer = 0;
269
                }
270
              }
271
              else {
272
                toggle_led(LED_YELLOW, OFF);
273
                toggle_led(LED_RED, ON);
274
              }
275

    
276
              _delay_ms(2);
277
              ms_timer++;
278
              break;
279

    
280
            case toolon:
281
                
282
                if ((read_button(BUT_RED)) && (read_vac() == OFF)) {
283
                        state = off;
284
                        toggle_relay(OFF);
285
                } else if (min >= TWARN) {
286
                    toggle_led(LED_GREEN, OFF);
287
                    state = warn;
288
                }
289
                break;
290

    
291
            case warn:
292
                if(ms_timer >= 100) {
293
                  toggle_led(LED_YELLOW, ON);
294
                
295
                  if(ms_timer >= 200) {
296
                    ms_timer = 0;
297
                  }
298
                }
299
                else {
300
                  toggle_led(LED_YELLOW, OFF);
301
                }
302

    
303
                if (read_button(BUT_RED) && read_vac() == OFF) {
304
                    toggle_relay(OFF);
305
                    state = off;
306
                } else if (read_button(BUT_BLACK)) {
307
                    toggle_led(LED_GREEN, ON);
308
                    toggle_led(LED_YELLOW, OFF);
309
                    reset_timer();
310
                    state = toolon;
311
                } else if ((min >= TMAX) && (read_vac() == OFF)) {
312
                    toggle_relay(OFF);
313
                    state = off;
314
                }
315

    
316
                _delay_ms(2);
317
                ms_timer++;
318

    
319
                break;
320
            case off:
321
                toggle_led(LED_GREEN, OFF);
322
                toggle_led(LED_YELLOW, OFF);
323
                toggle_led(LED_RED, ON);
324
                state = sd;
325
                break;
326
            default: state = sd;
327
        }     
328
        
329
        }
330
        
331
        return 0;
332
}