Project

General

Profile

Statistics
| Revision:

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
}