Project

General

Profile

Statistics
| Revision:

root / trunk / cardbox / cardreader.c @ 273

History | View | Annotate | Download (3.79 KB)

1
#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
#ifdef SD
9
#define CR_MAX_IDX 4
10
#else
11
#define CR_MAX_IDX 6
12
#endif
13
#define CR_SS       '%'         // Start sentinal
14
#define CR_ES       '?'         // End sentinal
15

    
16
// This is only written in the PCINT2 intterupt or in the main loop
17
// but not concurrently. read_card acts as an implicit lock
18
volatile cr_flag_t cr_flag;
19
volatile uint8_t cr_buf[512];
20
volatile uint16_t cr_buf_idx;
21
volatile uint8_t read_card;
22

    
23
#ifdef SD
24
const char cr_dict[] = {'0', '1', '2', '3', '4', '5', '6', '7',
25
                        '8', '9', ':', ';', '<', '=', '>', '?'};
26
#else
27
const char cr_dict[] = {' ', '!', '"', '#', '$', '%', '&', '\'',
28
                        '(', ')', '*', '+', ',', '-', '.', '/',
29
                        '0', '1', '2', '3', '4', '5', '6', '7',
30
                        '8', '9', ':', ';', '<', '=', '>', '?',
31
                        '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
32
                        'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
33
                        'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
34
                        'X', 'Y', 'Z', '[', '\\',']', '^', '_'};
35
#endif
36

    
37

    
38

    
39
void card_reader_setup(void) {
40
 
41
    // Turn on pin interrupts for pins D7, D6, D5
42
    PCICR = _BV(PCIE2);
43
    PCMSK2 = /*_BV(PCINT23) |*/ _BV(PCINT22) | _BV(PCINT21);
44

    
45
    // Make pins D7, D6, D5 inputs
46
    DDRD &= ~_BV(DDD7) & ~_BV(DDD6) & ~_BV(DDD5); 
47
    cr_buf_idx = 0;
48
    cr_flag = CR_NONE;
49
    read_card = 0;
50
}
51

    
52
ISR(PCINT2_vect) {    
53
    static uint8_t reading = 0;         // Currently reading
54

    
55
    // Only read card if we are expecting it
56
    if (!read_card) {
57
        return;
58
    }
59

    
60
    // Check if the card is inserted or not
61
    if (!(PIND & CR_CL) && (reading == 0)) {
62
        cr_flag = CR_NONE;
63
        cr_buf_idx = 0;
64
        reading = 1;
65
    // check if the card has finished swiping
66
    } else if (PIND & CR_CL) {
67
        toggle_led(LED_RED, ON);
68
        reading = 0;
69
        cr_flag = CR_GOOD;
70
        return;
71
    }
72

    
73
    // Read data in on the downtick of the clock
74
    if (!(PIND & (CR_CLK))) {
75
        // Read data from card reader and flip since ours inverts
76
        cr_buf[cr_buf_idx] = (PIND & CR_DATA) ? 0 : 0x20;
77
        cr_buf_idx++;
78
    }
79
}
80

    
81
int8_t parse_card(uint8_t *buf, uint8_t *buflen) {
82
    int32_t i = cr_buf_idx - 1;
83
    uint8_t j = 0;
84
    uint8_t start_sentinal = 0;
85
    uint8_t byte_idx = 0;
86
    uint8_t byte = 0;
87
    uint8_t parity;
88

    
89
    // Look for the start sentinal
90
    while (start_sentinal == 0) {
91
        byte = (((byte >> 1) & 0x1F) | (cr_buf[i]));
92
        
93
        if (cr_dict[byte] == CR_SS) {
94
            start_sentinal = 1;
95
           
96
            (buf)[j++] = cr_dict[byte];
97
            //rs485_send_byte(cr_dict[byte]);
98

    
99
            // Skip parity bit
100
            i--;
101
        }
102

    
103
        // Increment bits
104
        i--;
105

    
106
        // Ran out of buffer to search, no start sentinal found
107
        if (i == 0) {
108
            return CR_ERR_NO_START;
109
        }
110
    }
111

    
112
    // Prepare for reading of data
113
    byte = 0;
114
    byte_idx = 0;
115
    parity = 0;
116

    
117
    while (i >= 0) {
118
        // Parity bit
119
        if (byte_idx == CR_MAX_IDX) {
120

    
121
            if (!(cr_buf[i]) != (parity % 2)) {
122
                return CR_ERR_BAD_PARITY;
123
            }
124

    
125
            //rs485_send_byte(cr_dict[byte]);
126
            (buf)[j++] = cr_dict[byte];
127

    
128
            // Stop at the stop sentinal
129
            if (cr_dict[byte] == CR_ES) {
130
                *buflen = j-1;
131
                return 0;
132
            }
133

    
134
            byte_idx = 0;
135
            byte = 0;
136
            parity = 0;
137
            
138
        // Data bits
139
        } else {
140
            byte = (((byte >> 1) & 0x1F) | (cr_buf[i]));
141
            byte_idx++;
142
            parity += (cr_buf[i]) ? 0 : 1;
143
        }
144

    
145
        // Goto next bit in cr_buf
146
        i--;
147
    }
148

    
149
    return CR_ERR_NO_STOP;
150
}