Subversion Repositories HomeAutomation

Rev

Rev 2032 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  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 <drivers/rfid/rfid.h>
  14.  
  15. #include <config.h>
  16.  
  17. /* edge detection, for resynchronization */
  18. volatile uint8_t rfid_m_lastbit = 0;
  19.  
  20. /* number of timer steps left until next sample */
  21. volatile uint8_t rfid_m_nextsample = 0;
  22.  
  23. /* Current phase in manchester encoding */
  24. volatile uint8_t rfid_m_phase = 0;
  25.  
  26. /* stores last bit, used for manchester decoding */
  27. volatile uint8_t rfid_m_buffer = 0;
  28.  
  29. /* Circular buffer for reading */
  30. volatile uint8_t rfid_data[8];
  31. volatile uint8_t rfid_ptr = 0;
  32.  
  33. /* Output */
  34. volatile uint8_t rfid_pkt[8];
  35. volatile uint8_t rfid_trig = 0;
  36.  
  37. /* Parse tables */
  38. const uint8_t rfid_chk_valid[32] PROGMEM = {
  39.         1, // 00000
  40.         0, // 00001
  41.         0, // 00010
  42.         1, // 00011
  43.         0, // 00100
  44.         1, // 00101
  45.         1, // 00110
  46.         0, // 00111
  47.         0, // 01000
  48.         1, // 01001
  49.         1, // 01010
  50.         0, // 01011
  51.         1, // 01100
  52.         0, // 01101
  53.         0, // 01110
  54.         1, // 01111
  55.         0, // 10000
  56.         1, // 10001
  57.         1, // 10010
  58.         0, // 10011
  59.         1, // 10100
  60.         0, // 10101
  61.         0, // 10110
  62.         1, // 10111
  63.         1, // 11000
  64.         0, // 11001
  65.         0, // 11010
  66.         1, // 11011
  67.         0, // 11100
  68.         1, // 11101
  69.         1, // 11110
  70.         0  // 11111
  71. };
  72.  
  73. void rfid_handlebit( uint8_t bit );
  74.  
  75. static inline uint32_t rfid_bitrev32(uint32_t x);
  76. static inline uint8_t rfid_bitrev8(uint8_t x);
  77.  
  78. static inline uint32_t rfid_bitrev32(uint32_t x) {
  79.     x = (x >> 16) | (x << 16);
  80.     x = (x >> 8 & 0x00ff00ff) | (x << 8 & 0xff00ff00);
  81.     x = (x >> 4 & 0x0f0f0f0f) | (x << 4 & 0xf0f0f0f0);
  82.     x = (x >> 2 & 0x33333333) | (x << 2 & 0xcccccccc);
  83.     x = (x >> 1 & 0x55555555) | (x << 1 & 0xaaaaaaaa);
  84.     return x;
  85. }
  86. static inline uint8_t rfid_bitrev8(uint8_t x) {
  87.     x = (x >> 4 & 0x0f) | (x << 4 & 0xf0);
  88.     x = (x >> 2 & 0x33) | (x << 2 & 0xcc);
  89.     x = (x >> 1 & 0x55) | (x << 1 & 0xaa);
  90.     return x;
  91. }
  92.  
  93. ISR( TIMER1_COMPA_vect ) {
  94.     uint8_t bit = gpio_get_state( 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( RFID_READ_PIN );
  158. }
  159.  
  160. uint8_t rfid_fetch( uint8_t *version, uint32_t *tag ) {
  161.     uint8_t colchksum;
  162.  
  163.     if( rfid_trig == 0 ) return 1;
  164.  
  165.  
  166.     if( (rfid_pkt[0] & 0xFF) != 0xFE ) goto rfid_fetchfail;
  167.     if( (rfid_pkt[1] & 0x03) != 0x03 ) goto rfid_fetchfail;
  168.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[1]&0x7C)>>2)                           ) ) goto rfid_fetchfail;
  169.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[1]&0x80)>>7) + ((rfid_pkt[2]&0x0F)<<1) ) ) goto rfid_fetchfail;
  170.  
  171.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[2]&0xF0)>>4) + ((rfid_pkt[3]&0x01)<<4) ) ) goto rfid_fetchfail;
  172.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[3]&0x3E)>>1)                           ) ) goto rfid_fetchfail;
  173.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[3]&0xC0)>>6) + ((rfid_pkt[4]&0x07)<<2) ) ) goto rfid_fetchfail;
  174.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[4]&0xF8)>>3)                           ) ) goto rfid_fetchfail;
  175.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[5]&0x1F)   )                           ) ) goto rfid_fetchfail;
  176.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[5]&0xE0)>>5) + ((rfid_pkt[6]&0x03)<<3) ) ) goto rfid_fetchfail;
  177.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[6]&0x7C)>>2)                           ) ) goto rfid_fetchfail;
  178.     if( !pgm_read_byte(rfid_chk_valid + ((rfid_pkt[6]&0x80)>>7) + ((rfid_pkt[7]&0x0F)<<1) ) ) goto rfid_fetchfail;
  179.  
  180.     *version = ((rfid_pkt[1]&0x3C)>>2)    // ..####.. => ....####
  181.              | ((rfid_pkt[1]&0x80)>>3)    // #....... => ...#....
  182.              | ((rfid_pkt[2]&0x07)<<5);   // .....### => ###.....
  183.  
  184.     *tag     = ((uint32_t)(rfid_pkt[2]&0xF0)>> 4)    // ####.... => ........ ........ ........ ....####
  185.              | ((uint32_t)(rfid_pkt[3]&0x1E)<< 3)    // ...####. => ........ ........ ........ ####....
  186.              | ((uint32_t)(rfid_pkt[3]&0xC0)<< 2)    // ##...... => ........ ........ ....--## ........
  187.              | ((uint32_t)(rfid_pkt[4]&0x03)<<10)    // ......## => ........ ........ ....##-- ........
  188.              | ((uint32_t)(rfid_pkt[4]&0x78)<< 9)    // .####... => ........ ........ ####.... ........
  189.              | ((uint32_t)(rfid_pkt[5]&0x0F)<<16)    // ....#### => ........ ....#### ........ ........
  190.              | ((uint32_t)(rfid_pkt[5]&0xE0)<<15)    // ###..... => ........ -###.... ........ ........
  191.              | ((uint32_t)(rfid_pkt[6]&0x01)<<23)    // .......# => ........ #---.... ........ ........
  192.              | ((uint32_t)(rfid_pkt[6]&0x3C)<<22)    // ..####.. => ....#### ........ ........ ........
  193.              | ((uint32_t)(rfid_pkt[6]&0x80)<<21)    // #....... => ---#.... ........ ........ ........
  194.              | ((uint32_t)(rfid_pkt[7]&0x07)<<29);   // .....### => ###-.... ........ ........ ........
  195.  
  196.     colchksum  = *version;
  197.     colchksum ^= (*tag >>  0) & 0xFF;
  198.     colchksum ^= (*tag >>  8) & 0xFF;
  199.     colchksum ^= (*tag >> 16) & 0xFF;
  200.     colchksum ^= (*tag >> 24) & 0xFF;
  201.     colchksum ^= colchksum>>4;
  202.     colchksum ^= rfid_pkt[7]>>4;
  203.     colchksum &= 0x0F;
  204.  
  205.     if( colchksum != 0 ) goto rfid_fetchfail;
  206.  
  207.     *version = rfid_bitrev8( *version );
  208.     *tag = rfid_bitrev32( *tag );
  209.  
  210.     rfid_trig = 0;
  211.     return 0;
  212.  
  213. rfid_fetchfail:
  214.     rfid_trig = 0;
  215.     return 2;
  216. }
  217.