Project

General

Profile

Statistics
| Revision:

root / trunk / cardbox / cardbox.c @ 289

History | View | Annotate | Download (7.34 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 "cardbox.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
    ack,
152
    rsp
153
} state_t;
154

    
155

    
156
int main(void) {
157
    uint8_t mbuf[PROGD_PACKET_SIZE];
158
    uint8_t cbuf[21];
159
    uint8_t clen;
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
    while(1) {
173
        switch(state) {
174
            case req:
175
                toggle_led(LED_RED|LED_GREEN|LED_YELLOW, OFF);
176

    
177
                // Start reading cards
178
                read_card = 1;
179

    
180
                // See if we have a card, otherwise check if we got
181
                // a message
182
                if (cr_flag != CR_NONE) {
183
                    read_card = 0;
184

    
185
                    // Reading failed
186
                    if (parse_card(&(cbuf[1]), &clen) < 0) {
187
                        for(c=0;c < 4;c++) {
188
                            toggle_led(LED_RED,ON);
189
                            _delay_ms(125);
190
                            toggle_led(LED_RED,OFF);
191
                            _delay_ms(125);
192
                        }
193
                    // Reading is good, wait for a key
194
                    } else {
195
                        start_timer();
196
                        reset_timer();
197
                        reset_timeout_flag();
198
                        state = press;
199
                    }
200

    
201
                    // Reset the card reader flag
202
                    cr_flag = CR_NONE;
203
                } else {
204
                    // Wait for a packet
205
                    resp = parse_packet(mbuf, &len, ADDR);
206

    
207
                    // Ping Request
208
                    if(resp == TT_PING){
209
                        _delay_ms(50);
210
                        send_packet(TT_ACK, ADDR, NULL, 0);
211
                    }
212
                }
213
                break;
214
            case press:
215
                toggle_led(LED_YELLOW,ON);
216
                cbuf[0] = get_button();
217
                retries = 0;
218
        
219
                if (seconds > TIMEOUT_SECONDS) {
220
                    set_timeout_flag();
221
                    state = send;
222
                } else if (cbuf[0] != ' ') {
223
                    state = send;
224
                } else {
225
                    _delay_ms(100);
226
                }
227

    
228
                break;
229
            case send:
230
                if (get_timeout_flag() == 1) {
231
                    toggle_led(LED_RED|LED_YELLOW,ON);
232
                    _delay_ms(500);
233
                    toggle_led(LED_RED|LED_YELLOW,OFF);
234
                    _delay_ms(500);
235
                    state = req;
236
                } else {
237
                    _delay_ms(50);
238
                    send_packet(TT_KC, ADDR, cbuf, 1 + clen);
239
                    state = ack;
240
                }
241

    
242
                break;
243
            case ack:
244
                resp = parse_packet(mbuf, &len, ADDR);
245

    
246
                if (resp == TT_ACK) {
247
                    state = rsp;
248
                    start_timer();
249
                    reset_timer();
250
                    state = rsp;
251
                } else if (retries == TT_MAX_RETRY) {
252
                    toggle_led(LED_RED, ON);
253
                    _delay_ms(1000);
254
                    toggle_led(LED_RED, OFF);
255
                    state = req;
256
                } else {
257
                    retries++;
258
                    state = send;
259
                }
260
                break;
261

    
262
            case rsp:
263
                resp = parse_packet(mbuf, &len,  ADDR);
264

    
265
                if (resp == TT_GRANT) {
266
                    toggle_led(LED_GREEN, ON);
267
                    _delay_ms(1000);
268
                    toggle_led(LED_GREEN, OFF);
269
                    state = req;
270
                } else if (resp == TT_DENY) { 
271
                    toggle_led(LED_RED, ON);
272
                    _delay_ms(1000);
273
                    toggle_led(LED_RED, OFF);
274
                    state = req;
275
                } else if (seconds > TT_MAX_RETRY) {
276
                    toggle_led(LED_RED,ON);
277
                    _delay_ms(1000);
278
                    toggle_led(LED_RED, OFF);
279
                    state = req;
280
                }
281

    
282
                break;
283
            default:
284
                state = req;
285
                break;
286
        }
287
    } 
288
    return 0;    
289
}