Project

General

Profile

Statistics
| Revision:

root / trunk / cardbox / cardbox.c @ 281

History | View | Annotate | Download (6.52 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
    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

    
175
    while(1) {
176
        while(1) {
177
            read_card = 1;
178
            if (cr_flag != CR_NONE) {
179
                read_card = 0;
180
                if ((cret = parse_card(cbuf, &clen)) < 0) {
181
                    for(c=0;c < 4;c++) {
182
                        toggle_led(LED_RED,ON);
183
                        _delay_ms(250);
184
                        toggle_led(LED_RED,OFF);
185
                        _delay_ms(250);
186
                    }
187

    
188
                } else {
189
                    for (c = 0; c < clen; c++) {
190
                        rs485_send_byte(cbuf[c]);
191
                    }
192
                }
193
                cr_flag = CR_NONE;
194
            }
195
        }
196

    
197

    
198

    
199
        switch(state) {
200
            case req:
201
                toggle_led(LED_RED|LED_GREEN|LED_YELLOW, OFF);
202
                      
203
                // Wait for a packet
204
                resp = parse_packet(mbuf, &len, ADDR);
205

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

    
233
                break;
234
            case send:
235
                if (get_timeout_flag() == 1) {
236
                    _delay_ms(50);
237
                    send_packet(TT_TIMEOUT, ADDR, NULL, 0);
238
                    state = req;
239
                    break;
240
                } else {
241
                    _delay_ms(50);
242
                    send_packet(TT_SEND_KEY, ADDR, &c, 1);
243
                }
244

    
245
                state = rsp;
246
                break;
247
            case rsp:
248
                resp = parse_packet(mbuf, &len,  ADDR);
249

    
250
                if (resp == TT_ACK) {
251
                    toggle_led(LED_GREEN, ON);
252
                } else if ((resp == TT_NACK) || (retries == TT_MAX_RETRY)) { 
253
                    toggle_led(LED_RED, ON);
254
                } else {
255
                    retries++;
256
                    state = send;
257
                    break;
258
                }
259

    
260
                _delay_ms(1000);
261
                toggle_led(LED_RED, OFF);
262
                toggle_led(LED_GREEN, ON);
263
                state = req;
264
                break;
265
            default:
266
                state = req;
267
                break;
268
        }
269
    } 
270
    return 0;    
271
}