Project

General

Profile

Statistics
| Revision:

root / trunk / toolbox / main.c @ 201

History | View | Annotate | Download (8.01 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
#include <toolbox_pindefs.h>
34
#define TOOLBOX
35
#define RELAY       _BV(PORTD4)
36
#define VAC_SENSE   _BV(PIND3)
37
#define BUT_RED     _BV(PINB4)
38
#define BUT_BLACK   _BV(PINB3)
39
#define LED_GREEN   _BV(PORTB2)
40
#define LED_YELLOW  _BV(PORTB1)
41
#define LED_RED     _BV(PORTB0)
42
#define ON      0x01
43
#define OFF     0x00
44

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

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

    
60
uint8_t sec;
61
uint8_t min;
62

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

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

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

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

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

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

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

    
117
    TIMSK = _BV(OCIE1A);
118

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

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

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

    
137

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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