root / trunk / cardbox / cardreader.c @ 300
History | View | Annotate | Download (3.75 KB)
1 | 267 | kwoo | #include "cardreader.h" |
---|---|---|---|
2 | |||
3 | //#define SD
|
||
4 | |||
5 | #define CR_CL (_BV(PIND5))
|
||
6 | #define CR_CLK (_BV(PIND6))
|
||
7 | #define CR_DATA (_BV(PIND7))
|
||
8 | 275 | kwoo | |
9 | #ifdef TRACK2
|
||
10 | #define CR_MAX_IDX 4 |
||
11 | #define CR_SS ':' // Start sentinal |
||
12 | 267 | kwoo | #else
|
13 | 275 | kwoo | #define CR_MAX_IDX 6 |
14 | #define CR_SS '%' // Start sentinal |
||
15 | 267 | kwoo | #endif
|
16 | 275 | kwoo | |
17 | 267 | kwoo | #define CR_ES '?' // End sentinal |
18 | |||
19 | // This is only written in the PCINT2 intterupt or in the main loop
|
||
20 | // but not concurrently. read_card acts as an implicit lock
|
||
21 | volatile cr_flag_t cr_flag;
|
||
22 | 277 | kwoo | volatile uint8_t cr_buf[CR_BUF_SIZE];
|
23 | 268 | kwoo | volatile uint16_t cr_buf_idx;
|
24 | 267 | kwoo | volatile uint8_t read_card;
|
25 | |||
26 | 275 | kwoo | #ifdef TRACK2
|
27 | 267 | kwoo | const char cr_dict[] = {'0', '1', '2', '3', '4', '5', '6', '7', |
28 | '8', '9', ':', ';', '<', '=', '>', '?'}; |
||
29 | #else
|
||
30 | const char cr_dict[] = {' ', '!', '"', '#', '$', '%', '&', '\'', |
||
31 | '(', ')', '*', '+', ',', '-', '.', '/', |
||
32 | '0', '1', '2', '3', '4', '5', '6', '7', |
||
33 | '8', '9', ':', ';', '<', '=', '>', '?', |
||
34 | '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', |
||
35 | 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', |
||
36 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', |
||
37 | 'X', 'Y', 'Z', '[', '\\',']', '^', '_'}; |
||
38 | #endif
|
||
39 | |||
40 | |||
41 | |||
42 | void card_reader_setup(void) { |
||
43 | |||
44 | // Turn on pin interrupts for pins D7, D6, D5
|
||
45 | PCICR = _BV(PCIE2); |
||
46 | 275 | kwoo | PCMSK2 = _BV(PCINT22) | _BV(PCINT21); |
47 | 267 | kwoo | |
48 | // Make pins D7, D6, D5 inputs
|
||
49 | DDRD &= ~_BV(DDD7) & ~_BV(DDD6) & ~_BV(DDD5); |
||
50 | cr_buf_idx = 0;
|
||
51 | cr_flag = CR_NONE; |
||
52 | read_card = 0;
|
||
53 | } |
||
54 | |||
55 | 273 | kwoo | int8_t parse_card(uint8_t *buf, uint8_t *buflen) { |
56 | 277 | kwoo | int16_t i = cr_buf_idx - 1;
|
57 | 273 | kwoo | uint8_t j = 0;
|
58 | 268 | kwoo | uint8_t start_sentinal = 0;
|
59 | uint8_t byte_idx = 0;
|
||
60 | uint8_t byte = 0;
|
||
61 | uint8_t parity; |
||
62 | |||
63 | 273 | kwoo | // Look for the start sentinal
|
64 | 268 | kwoo | while (start_sentinal == 0) { |
65 | 276 | kwoo | byte = (((byte >> 1) & 0x1F) | (cr_buf[i] << 5)); |
66 | 268 | kwoo | |
67 | if (cr_dict[byte] == CR_SS) {
|
||
68 | start_sentinal = 1;
|
||
69 | 273 | kwoo | |
70 | (buf)[j++] = cr_dict[byte]; |
||
71 | 267 | kwoo | |
72 | 268 | kwoo | // Skip parity bit
|
73 | i--; |
||
74 | } |
||
75 | 270 | kwoo | |
76 | 273 | kwoo | // Increment bits
|
77 | 270 | kwoo | i--; |
78 | 272 | kwoo | |
79 | 273 | kwoo | // Ran out of buffer to search, no start sentinal found
|
80 | 272 | kwoo | if (i == 0) { |
81 | return CR_ERR_NO_START;
|
||
82 | } |
||
83 | 268 | kwoo | } |
84 | 267 | kwoo | |
85 | 273 | kwoo | // Prepare for reading of data
|
86 | 268 | kwoo | byte = 0;
|
87 | byte_idx = 0;
|
||
88 | 269 | kwoo | parity = 0;
|
89 | 267 | kwoo | |
90 | 268 | kwoo | while (i >= 0) { |
91 | // Parity bit
|
||
92 | if (byte_idx == CR_MAX_IDX) {
|
||
93 | 267 | kwoo | |
94 | 269 | kwoo | if (!(cr_buf[i]) != (parity % 2)) { |
95 | 272 | kwoo | return CR_ERR_BAD_PARITY;
|
96 | 269 | kwoo | } |
97 | |||
98 | 273 | kwoo | (buf)[j++] = cr_dict[byte]; |
99 | 268 | kwoo | |
100 | // Stop at the stop sentinal
|
||
101 | if (cr_dict[byte] == CR_ES) {
|
||
102 | 274 | kwoo | *buflen = j; |
103 | 271 | kwoo | return 0; |
104 | 268 | kwoo | } |
105 | |||
106 | 267 | kwoo | byte_idx = 0;
|
107 | byte = 0;
|
||
108 | 269 | kwoo | parity = 0;
|
109 | 268 | kwoo | |
110 | // Data bits
|
||
111 | 267 | kwoo | } else {
|
112 | 276 | kwoo | byte = (((byte >> 1) & 0x1F) | (cr_buf[i] << 5)); |
113 | 267 | kwoo | byte_idx++; |
114 | 276 | kwoo | parity += cr_buf[i]; |
115 | 268 | kwoo | } |
116 | |||
117 | // Goto next bit in cr_buf
|
||
118 | i--; |
||
119 | 267 | kwoo | } |
120 | 271 | kwoo | |
121 | 272 | kwoo | return CR_ERR_NO_STOP;
|
122 | 268 | kwoo | } |
123 | 275 | kwoo | |
124 | ISR(PCINT2_vect) { |
||
125 | static uint8_t reading = 0; // Currently reading |
||
126 | |||
127 | // Only read card if we are expecting it
|
||
128 | if (!read_card) {
|
||
129 | return;
|
||
130 | } |
||
131 | |||
132 | // Check if the card is inserted or not
|
||
133 | if (!(PIND & CR_CL) && (!reading)) {
|
||
134 | cr_flag = CR_NONE; |
||
135 | cr_buf_idx = 0;
|
||
136 | reading = 1;
|
||
137 | // check if the card has finished swiping
|
||
138 | } else if (PIND & CR_CL) { |
||
139 | cr_flag = CR_GOOD; |
||
140 | reading = 0;
|
||
141 | return;
|
||
142 | } |
||
143 | |||
144 | // Read data in on the downtick of the clock
|
||
145 | 279 | kwoo | if ((!(PIND & CR_CLK)) && (cr_buf_idx < CR_BUF_SIZE)) {
|
146 | 275 | kwoo | // Read data from card reader and flip since ours inverts
|
147 | 276 | kwoo | cr_buf[cr_buf_idx] = !(PIND & CR_DATA); |
148 | 275 | kwoo | cr_buf_idx++; |
149 | } |
||
150 | } |