Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
2032 pengi 1
/*
2
 * rfid.c
3
 *
4
 *  Created on: May 6, 2012
5
 *      Author: pengi
6
 */
7
 
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include <avr/pgmspace.h>
11
 
12
#include <drivers/mcu/gpio.h>
13
#include "rfid.h"
14
#include "config.h"
15
 
16
/* edge detection, for resynchronization */
17
volatile uint8_t rfid_m_lastbit = 0;
18
 
19
/* number of timer steps left until next sample */
20
volatile uint8_t rfid_m_nextsample = 0;
21
 
22
/* Current phase in manchester encoding */
23
volatile uint8_t rfid_m_phase = 0;
24
 
25
/* stores last bit, used for manchester decoding */
26
volatile uint8_t rfid_m_buffer = 0;
27
 
28
/* Circular buffer for reading */
29
volatile uint8_t rfid_data[8];
30
volatile uint8_t rfid_ptr = 0;
31
 
32
/* Output */
33
volatile uint8_t rfid_pkt[8];
34
volatile uint8_t rfid_trig = 0;
35
 
36
/* Parse tables */
37
const uint8_t rfid_chk_valid[32] PROGMEM = {
38
        1, // 00000
39
        0, // 00001
40
        0, // 00010
41
        1, // 00011
42
        0, // 00100
43
        1, // 00101
44
        1, // 00110
45
        0, // 00111
46
        0, // 01000
47
        1, // 01001
48
        1, // 01010
49
        0, // 01011
50
        1, // 01100
51
        0, // 01101
52
        0, // 01110
53
        1, // 01111
54
        0, // 10000
55
        1, // 10001
56
        1, // 10010
57
        0, // 10011
58
        1, // 10100
59
        0, // 10101
60
        0, // 10110
61
        1, // 10111
62
        1, // 11000
63
        0, // 11001
64
        0, // 11010
65
        1, // 11011
66
        0, // 11100
67
        1, // 11101
68
        1, // 11110
69
 
70
};
71
 
72
void rfid_handlebit( uint8_t bit );
73
 
74
static inline uint32_t rfid_bitrev32(uint32_t x);
75
static inline uint8_t rfid_bitrev8(uint8_t x);
76
 
77
static inline uint32_t rfid_bitrev32(uint32_t x) {
78
    x = (x >> 16) | (x << 16);
79
    x = (x >> 8 & 0x00ff00ff) | (x << 8 & 0xff00ff00);
80
    x = (x >> 4 & 0x0f0f0f0f) | (x << 4 & 0xf0f0f0f0);
81
    x = (x >> 2 & 0x33333333) | (x << 2 & 0xcccccccc);
82
    x = (x >> 1 & 0x55555555) | (x << 1 & 0xaaaaaaaa);
83
    return x;
84
}
85
static inline uint8_t rfid_bitrev8(uint8_t x) {
86
    x = (x >> 4 & 0x0f) | (x << 4 & 0xf0);
87
    x = (x >> 2 & 0x33) | (x << 2 & 0xcc);
88
    x = (x >> 1 & 0x55) | (x << 1 & 0xaa);
89
    return x;
90
}
91
 
92
ISR( TIMER1_COMPA_vect ) {
93
    gpio_toggle_pin( EXP_M );
94
    uint8_t bit = gpio_get_state( sns_rfid_READ_PIN );
95
 
96
    if( rfid_m_lastbit != bit ) {
97
        rfid_m_nextsample = RFID_OSR/2;
98
    }
99
    if( rfid_m_nextsample == 0 ) {
100
        rfid_m_nextsample = RFID_OSR;
101
 
102
        /* Sample */
103
        if( rfid_m_phase == 0 ) {
104
            rfid_m_buffer = bit;
105
            rfid_m_phase = 1;
106
        } else {
107
            if( rfid_m_buffer == bit ) { /* Out of phase, resynchroinzation */
108
                rfid_m_buffer = bit;
109
                rfid_m_phase = 1;
110
            } else {
111
                /* Second phase in manchester encoded bit, pass to bitstream */
112
                rfid_handlebit( !bit ); /* First bit counts */
113
                rfid_m_phase = 0;
114
            }
115
        }
116
    }
117
    rfid_m_nextsample--;
118
    rfid_m_lastbit = bit;
119
}
120
 
121
void rfid_handlebit( uint8_t bit ) {
122
 
123
    if( bit ) {
124
        rfid_data[rfid_ptr>>3] |= 1<<(rfid_ptr&7);
125
    } else {
126
        rfid_data[rfid_ptr>>3] &= ~(1<<(rfid_ptr&7));
127
    }
128
    rfid_ptr = (rfid_ptr+1)%64;
129
 
130
    if( rfid_trig ) return; /* Ignore if still trigged, someone might parse */
131
 
132
    rfid_pkt[0] = (rfid_data[(0+(rfid_ptr>>3))%8]>>(rfid_ptr&7)) | rfid_data[(1+(rfid_ptr>>3))%8]<<(8-(rfid_ptr&7));
133
    if( rfid_pkt[0] != 0xFE ) return;
134
    rfid_pkt[1] = (rfid_data[(1+(rfid_ptr>>3))%8]>>(rfid_ptr&7)) | rfid_data[(2+(rfid_ptr>>3))%8]<<(8-(rfid_ptr&7));
135
    rfid_pkt[2] = (rfid_data[(2+(rfid_ptr>>3))%8]>>(rfid_ptr&7)) | rfid_data[(3+(rfid_ptr>>3))%8]<<(8-(rfid_ptr&7));
136
    rfid_pkt[3] = (rfid_data[(3+(rfid_ptr>>3))%8]>>(rfid_ptr&7)) | rfid_data[(4+(rfid_ptr>>3))%8]<<(8-(rfid_ptr&7));
137
    rfid_pkt[4] = (rfid_data[(4+(rfid_ptr>>3))%8]>>(rfid_ptr&7)) | rfid_data[(5+(rfid_ptr>>3))%8]<<(8-(rfid_ptr&7));
138
    rfid_pkt[5] = (rfid_data[(5+(rfid_ptr>>3))%8]>>(rfid_ptr&7)) | rfid_data[(6+(rfid_ptr>>3))%8]<<(8-(rfid_ptr&7));
139
    rfid_pkt[6] = (rfid_data[(6+(rfid_ptr>>3))%8]>>(rfid_ptr&7)) | rfid_data[(7+(rfid_ptr>>3))%8]<<(8-(rfid_ptr&7));
140
    rfid_pkt[7] = (rfid_data[(7+(rfid_ptr>>3))%8]>>(rfid_ptr&7)) | rfid_data[(0+(rfid_ptr>>3))%8]<<(8-(rfid_ptr&7));
141
 
142
    rfid_trig = 1;
143
}
144
 
145
void rfid_init( void ) {
146
    DDRD |= (1<<PORTD5); // Port out
147
    TCCR0A = (1<<COM0B1)|(0<<COM0B0)|(1<<WGM01)|(1<<WGM00);
148
    TCCR0B = (1<<WGM02)|(2<<CS00); // Fast PWM OCR0A top, prescaler 8
149
    OCR0A = (F_CPU/RFID_FREQ/8)-1; // 125kHz
150
    OCR0B = (F_CPU/RFID_FREQ/8)/2; // 50% dutycycle
151
 
152
    TCCR1A = (0<<WGM11)|(0<<WGM10);
153
    TCCR1B = (0<<WGM13)|(1<<WGM12)|(2<<CS20); // CTC OCR1A top, prescaler 8
154
    OCR1A = (RFID_BITLENGTH*F_CPU/RFID_OSR/RFID_FREQ/8)-1;
155
    TIMSK1 = (1<<OCIE1A);
156
 
157
    gpio_set_in( sns_rfid_READ_PIN );
158
 
159
    gpio_set_out( EXP_M );
160
}
161
 
162
uint8_t rfid_fetch( uint8_t *version, uint32_t *tag ) {
163
    uint8_t colchksum;
164
 
165
    if( rfid_trig == 0 ) return 1;
166
 
167
 
168
    if( (rfid_pkt[0] & 0xFF) != 0xFE ) goto rfid_fetchfail;
169
    if( (rfid_pkt[1] & 0x03) != 0x03 ) goto rfid_fetchfail;
170
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[1]&0x7C)>>2)                           ) ) goto rfid_fetchfail;
171
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[1]&0x80)>>7) + ((rfid_pkt[2]&0x0F)<<1) ) ) goto rfid_fetchfail;
172
 
173
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[2]&0xF0)>>4) + ((rfid_pkt[3]&0x01)<<4) ) ) goto rfid_fetchfail;
174
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[3]&0x3E)>>1)                           ) ) goto rfid_fetchfail;
175
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[3]&0xC0)>>6) + ((rfid_pkt[4]&0x07)<<2) ) ) goto rfid_fetchfail;
176
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[4]&0xF8)>>3)                           ) ) goto rfid_fetchfail;
177
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[5]&0x1F)   )                           ) ) goto rfid_fetchfail;
178
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[5]&0xE0)>>5) + ((rfid_pkt[6]&0x03)<<3) ) ) goto rfid_fetchfail;
179
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[6]&0x7C)>>2)                           ) ) goto rfid_fetchfail;
180
    if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[6]&0x80)>>7) + ((rfid_pkt[7]&0x0F)<<1) ) ) goto rfid_fetchfail;
181
 
182
    *version = ((rfid_pkt[1]&0x3C)>>2)    // ..####.. => ....####
183
             | ((rfid_pkt[1]&0x80)>>3)    // #....... => ...#....
184
             | ((rfid_pkt[2]&0x07)<<5);   // .....### => ###.....
185
 
186
    *tag     = ((uint32_t)(rfid_pkt[2]&0xF0)>> 4)    // ####.... => ........ ........ ........ ....####
187
             | ((uint32_t)(rfid_pkt[3]&0x1E)<< 3)    // ...####. => ........ ........ ........ ####....
188
             | ((uint32_t)(rfid_pkt[3]&0xC0)<< 2)    // ##...... => ........ ........ ....--## ........
189
             | ((uint32_t)(rfid_pkt[4]&0x03)<<10)    // ......## => ........ ........ ....##-- ........
190
             | ((uint32_t)(rfid_pkt[4]&0x78)<< 9)    // .####... => ........ ........ ####.... ........
191
             | ((uint32_t)(rfid_pkt[5]&0x0F)<<16)    // ....#### => ........ ....#### ........ ........
192
             | ((uint32_t)(rfid_pkt[5]&0xE0)<<15)    // ###..... => ........ -###.... ........ ........
193
             | ((uint32_t)(rfid_pkt[6]&0x01)<<23)    // .......# => ........ #---.... ........ ........
194
             | ((uint32_t)(rfid_pkt[6]&0x3C)<<22)    // ..####.. => ....#### ........ ........ ........
195
             | ((uint32_t)(rfid_pkt[6]&0x80)<<21)    // #....... => ---#.... ........ ........ ........
196
             | ((uint32_t)(rfid_pkt[7]&0x07)<<29);   // .....### => ###-.... ........ ........ ........
197
 
198
    colchksum  = *version;
199
    colchksum ^= (*tag >>  0) & 0xFF;
200
    colchksum ^= (*tag >>  8) & 0xFF;
201
    colchksum ^= (*tag >> 16) & 0xFF;
202
    colchksum ^= (*tag >> 24) & 0xFF;
203
    colchksum ^= colchksum>>4;
204
    colchksum ^= rfid_pkt[7]>>4;
205
    colchksum &= 0x0F;
206
 
207
    if( colchksum != 0 ) goto rfid_fetchfail;
208
 
209
    *version = rfid_bitrev8( *version );
210
    *tag = rfid_bitrev32( *tag );
211
 
212
    rfid_trig = 0;
213
    return 0;
214
 
215
rfid_fetchfail:
216
    rfid_trig = 0;
217
    return 2;
218
}