Subversion Repositories HomeAutomation

Rev

Blame | 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 "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.         0  // 11111
  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. }
  219.