Project

General

Profile

Statistics
| Revision:

root / trunk / cardbox / main.c @ 273

History | View | Annotate | Download (6.33 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[100];
158
    uint8_t clen;
159
    uint8_t resp;
160
    uint8_t  c;
161
    uint8_t len;
162
    uint8_t retries = 0;
163
    state_t state = req;
164

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

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

    
175
    while(1) {
176
        while(1) {
177
            read_card = 1;
178
            if (cr_flag != CR_NONE) {
179
                read_card = 0;
180
                if (parse_card(cbuf, &clen) < 0) {
181
                    rs485_send_byte('F');
182
                } else {
183
                    for (c = 0; c < clen; c++) {
184
                        rs485_send_byte(cbuf[c]);
185
                    }
186
                }
187
                cr_flag = CR_NONE;
188
            }
189
        }
190

    
191

    
192

    
193
        switch(state) {
194
            case req:
195
                toggle_led(LED_RED|LED_GREEN|LED_YELLOW, OFF);
196
                      
197
                // Wait for a packet
198
                resp = parse_packet(mbuf, &len, ADDR);
199

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

    
227
                break;
228
            case send:
229
                if (get_timeout_flag() == 1) {
230
                    _delay_ms(50);
231
                    send_packet(TT_TIMEOUT, ADDR, NULL, 0);
232
                    state = req;
233
                    break;
234
                } else {
235
                    _delay_ms(50);
236
                    send_packet(TT_SEND_KEY, ADDR, &c, 1);
237
                }
238

    
239
                state = rsp;
240
                break;
241
            case rsp:
242
                resp = parse_packet(mbuf, &len,  ADDR);
243

    
244
                if (resp == TT_ACK) {
245
                    toggle_led(LED_GREEN, ON);
246
                } else if ((resp == TT_NACK) || (retries == TT_MAX_RETRY)) { 
247
                    toggle_led(LED_RED, ON);
248
                } else {
249
                    retries++;
250
                    state = send;
251
                    break;
252
                }
253

    
254
                _delay_ms(1000);
255
                toggle_led(LED_RED, OFF);
256
                toggle_led(LED_GREEN, ON);
257
                state = req;
258
                break;
259
            default:
260
                state = req;
261
                break;
262
        }
263
    } 
264
    return 0;    
265
}