Project

General

Profile

Statistics
| Revision:

root / trunk / cardbox / main.c @ 277

History | View | Annotate | Download (6.81 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
#include "main.h"
20

    
21
/***** Keypad definitions ******/
22
#define KEYPORT PORTB
23
#define KEYPIN PINB
24
#define KEYDDR  DDRB
25
/** @brief ROW1 of the keypad */
26
#define ROW4 (_BV(PB0))
27
/** @brief ROW2 of the keypad */
28
#define ROW3 (_BV(PB1))
29
/** @brief ROW3 of the keypad */
30
#define ROW2 (_BV(PB2))
31
/** @brief ROW4 of the keypad */
32
#define ROW1 (_BV(PB3))
33
/** @brief COL1 of the keypad */
34
#define COL4 (_BV(PB4))
35
/** @brief COL2 of the keypad */
36
#define COL3 (_BV(PB5))
37
/** @brief COL3 of the keypad */
38
#define COL2 (_BV(PB6))
39
/** @brief COL4 of the keypad */
40
#define COL1 (_BV(PB7))
41

    
42
#define ADDR 2
43

    
44
/***** Global variables *****/
45

    
46
void init_pins(void) {
47
  KEYDDR = ROW1 | ROW2 | ROW3 | ROW4;
48
  //KEYDDR = 0;
49
  KEYPORT = COL1 | COL2 | COL3 | COL4;
50
  LEDDDR = LED_RED | LED_YELLOW | LED_GREEN;
51

    
52
  // Turn the LEDs off
53
  LEDPORT |= LED_RED | LED_GREEN | LED_YELLOW;
54
  
55
  return;        
56
}
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
        LEDPORT &= ~(which);
71
    } else {
72
        LEDPORT |= (which);
73
    }
74
}
75

    
76
char get_button(void) {
77

    
78
        char ret = ' ';
79
           
80
    // Row 1 Strobe
81
        
82
        
83
  DDRB = (ROW1);
84
  PORTB = (COL1|COL2|COL3|COL4);
85

    
86
  if(!(PINB&(COL1)))
87
    ret ='1';
88
  else if(!(PINB&(COL2)))
89
    ret ='2';
90
  else if(!(PINB&(COL3)))
91
    ret ='3';
92
  else if(!(PINB&(COL4)))
93
    ret ='A';
94
  else {
95

    
96
    DDRB = (ROW2);
97
    PORTB = (COL1|COL2|COL3|COL4);
98
    // Row 2 Strobe
99

    
100
    if(!(PINB&(COL1)))
101
      ret ='4';
102
    else if(!(PINB&(COL2)))
103
      ret ='5';
104
    else if(!(PINB&(COL3)))
105
      ret ='6';
106
    else if(!(PINB&(COL4)))
107
      ret ='B';
108
    else {
109
  
110
      // Row 3 Strobe
111
      DDRB = (ROW3);
112
      PORTB = (COL1|COL2|COL3|COL4);
113
  
114
      if(!(PINB&(COL1)))
115
        ret ='7';
116
      else if(!(PINB&(COL2)))
117
        ret ='8';
118
      else if(!(PINB&(COL3)))
119
        ret ='9';
120
      else if(!(PINB&(COL4)))
121
        ret ='C';
122
      else{
123
  
124
        // Row 4 Strobe
125
        DDRB = (ROW4);
126
        PORTB = (COL1|COL2|COL3|COL4);
127
  
128
        if(!(PINB&(COL1)))
129
          ret ='*';
130
        else if(!(PINB&(COL2)))
131
          ret ='0';
132
        else if(!(PINB&(COL3)))
133
          ret ='#';
134
        else if(!(PINB&(COL4)))
135
          ret ='D';
136
            }
137
          }
138
        }
139
        
140
        
141
  DDRB = 0;
142
  PORTB = (COL1|COL2|COL3|COL4);
143

    
144
  return ret;
145
}
146

    
147
typedef enum {
148
    req,
149
    press,
150
    send,
151
    rsp
152
} state_t;
153

    
154

    
155
int main(void) {
156
    uint8_t mbuf[PROGD_PACKET_SIZE];
157
    uint8_t cbuf[20];
158
    uint8_t clen;
159
    int8_t cret;
160
    uint8_t resp;
161
    uint8_t  c;
162
    uint8_t len;
163
    uint8_t retries = 0;
164
    state_t state = req;
165

    
166
    rs485_init(BAUD9600); 
167
    init_pins();
168
    init_timer();
169
    card_reader_setup();
170
    sei();
171

    
172
    toggle_led(LED_GREEN|LED_YELLOW|LED_RED, OFF);
173
    read_card = 0;
174
    rs485_send_byte('s');
175

    
176
    while(1) {
177
        while(1) {
178
            read_card = 1;
179
            if (cr_flag != CR_NONE) {
180
                read_card = 0;
181
                if ((cret = parse_card(cbuf, &clen)) < 0) {
182
                    switch (cret) {
183
                        case CR_ERR_BAD_PARITY:
184
                            toggle_led(LED_GREEN, ON);
185
                            break;
186
                        case CR_ERR_NO_START:
187
                            toggle_led(LED_YELLOW, ON);
188
                            break;
189
                        case CR_ERR_NO_STOP:
190
                            toggle_led(LED_RED, ON);
191
                            break;
192
                    }
193
                    rs485_send_byte('F');
194
                } else {
195
                    for (c = 0; c < clen; c++) {
196
                        rs485_send_byte(cbuf[c]);
197
                    }
198
                }
199
                cr_flag = CR_NONE;
200
            }
201
        }
202

    
203

    
204

    
205
        switch(state) {
206
            case req:
207
                toggle_led(LED_RED|LED_GREEN|LED_YELLOW, OFF);
208
                      
209
                // Wait for a packet
210
                resp = parse_packet(mbuf, &len, ADDR);
211

    
212
                if (resp == TT_GET_KEY) {
213
                    _delay_ms(50);
214
                    send_packet(TT_ACK, ADDR, NULL, 0);
215
                    toggle_led(LED_YELLOW, ON);
216
                    reset_timer();
217
                    reset_timeout_flag();
218
                    start_timer();
219
                    c = ' ';
220
                    state = press;
221
                } else if(resp == TT_PING){
222
                    _delay_ms(50);
223
                    send_packet(TT_ACK, ADDR, NULL, 0);
224
                }
225
                break;
226
            case press:
227
                c = get_button();
228
                retries = 0;
229
        
230
                if (seconds > TIMEOUT_SECONDS) {
231
                    set_timeout_flag();
232
                    state = send;
233
                } else if (c != ' ') {
234
                    state = send;
235
                } else {
236
                    _delay_ms(100);
237
                }
238

    
239
                break;
240
            case send:
241
                if (get_timeout_flag() == 1) {
242
                    _delay_ms(50);
243
                    send_packet(TT_TIMEOUT, ADDR, NULL, 0);
244
                    state = req;
245
                    break;
246
                } else {
247
                    _delay_ms(50);
248
                    send_packet(TT_SEND_KEY, ADDR, &c, 1);
249
                }
250

    
251
                state = rsp;
252
                break;
253
            case rsp:
254
                resp = parse_packet(mbuf, &len,  ADDR);
255

    
256
                if (resp == TT_ACK) {
257
                    toggle_led(LED_GREEN, ON);
258
                } else if ((resp == TT_NACK) || (retries == TT_MAX_RETRY)) { 
259
                    toggle_led(LED_RED, ON);
260
                } else {
261
                    retries++;
262
                    state = send;
263
                    break;
264
                }
265

    
266
                _delay_ms(1000);
267
                toggle_led(LED_RED, OFF);
268
                toggle_led(LED_GREEN, ON);
269
                state = req;
270
                break;
271
            default:
272
                state = req;
273
                break;
274
        }
275
    } 
276
    return 0;    
277
}