#include <stdio.h>
#define RFID_AS_CRC_TABLE_SIZE 256
#define RFID_AS_MSB_16 (1<<15)
#define RFID_AS_MSB_8 (1<<7)
#define RFID_AS_BYTE_LEN 8
#define RFID_AS_CRC5_LEN 5
#define RFID_AS_CRC16_LEN 16
#define RFID_AS_CRC5_POLYNOMIAL (0x9)
#define RFID_AS_CRC16_POLYNOMIAL (0x1021)
#define RFID_AS_CRC5_POLYNOMIAL_BMSK ((1<<RFID_AS_CRC5_LEN)-1)
#define RFID_AS_CRC5_SEED (0x9)
#define RFID_AS_CRC16_SEED (0xFFFF)
#define RFID_AS_CRC5_RESIDUAL 0x0
#define RFID_AS_CRC16_RESIDUAL (0xFFFF-0x1D0F)
typedef struct
{
unsigned int TRext:1;
unsigned int M:2;
unsigned int DR:1;
unsigned int Command:4; // end of byte 0
unsigned int Q_high:3;
unsigned int Target:1;
unsigned int Session:2;
unsigned int Sel:2; // end of byte 1
unsigned int reserved_0:2;
unsigned int CRC:5;
unsigned int Q_low:1; // end of byte 2
unsigned int reserved_1:8;
} query_cmd_s;
unsigned char rfid_as_crc5_table[RFID_AS_CRC_TABLE_SIZE];
unsigned short rfid_as_crc16_table[RFID_AS_CRC_TABLE_SIZE];
void rfid_crc5_init()
{
unsigned char bit_pos, remainder;
unsigned short byte_val;
for(byte_val = 0; byte_val < RFID_AS_CRC_TABLE_SIZE; byte_val++)
{
remainder = byte_val;
for(bit_pos = 0; bit_pos < RFID_AS_BYTE_LEN; bit_pos++)
{
if(remainder & RFID_AS_MSB_8)
{
remainder = (remainder << 1) ^ (RFID_AS_CRC5_POLYNOMIAL << (RFID_AS_BYTE_LEN - RFID_AS_CRC5_LEN));
}
else
{
remainder = remainder << 1;
}
}
rfid_as_crc5_table[byte_val] = remainder >> (RFID_AS_BYTE_LEN - RFID_AS_CRC5_LEN);
#if 0
printf("0x%02x, ", rfid_as_crc5_table
[byte_val
]); if((byte_val + 1)%8 == 0)
#endif
}
return;
}
void rfid_crc16_init()
{
unsigned char bit_pos;
unsigned short byte_val, remainder;
for(byte_val = 0; byte_val < RFID_AS_CRC_TABLE_SIZE; byte_val++)
{
remainder = byte_val << (RFID_AS_CRC16_LEN-RFID_AS_BYTE_LEN);
for(bit_pos = 0; bit_pos < RFID_AS_BYTE_LEN; bit_pos++)
{
if(remainder & RFID_AS_MSB_16)
{
remainder = (remainder << 1) ^ RFID_AS_CRC16_POLYNOMIAL;
}
else
{
remainder = remainder << 1;
}
}
rfid_as_crc16_table[byte_val] = remainder;
#if 0
printf("0x%04x, ", rfid_as_crc16_table
[byte_val
]); if((byte_val + 1)%8 == 0)
#endif
}
return;
}
unsigned char rfid_crc5_cal
(
unsigned char *buf_ptr,
unsigned short bit_len
)
{
unsigned char crc5, last_byte;
for(crc5 = RFID_AS_CRC5_SEED; bit_len >= RFID_AS_BYTE_LEN; bit_len -= RFID_AS_BYTE_LEN, buf_ptr++)
{
crc5 = rfid_as_crc5_table[(crc5 << (RFID_AS_BYTE_LEN-RFID_AS_CRC5_LEN)) ^ *buf_ptr];
}
if(bit_len !=0)
{
last_byte = *buf_ptr;
while(bit_len-- != 0)
{
if(((crc5 << (RFID_AS_BYTE_LEN - RFID_AS_CRC5_LEN)) ^ last_byte) & RFID_AS_MSB_8)
{
crc5 = ((crc5 << 1) ^ RFID_AS_CRC5_POLYNOMIAL) & RFID_AS_CRC5_POLYNOMIAL_BMSK;
}
else
{
crc5 = (crc5 << 1) & RFID_AS_CRC5_POLYNOMIAL_BMSK;
}
last_byte <<= 1;
}
}
return crc5;
}
unsigned short rfid_crc16_cal
(
unsigned char *buf_ptr,
unsigned short bit_len
)
{
unsigned short crc16, last_byte;
for(crc16 = RFID_AS_CRC16_SEED; bit_len >= RFID_AS_BYTE_LEN; bit_len -= RFID_AS_BYTE_LEN, buf_ptr++)
{
crc16 = rfid_as_crc16_table[(crc16 >> (RFID_AS_CRC16_LEN - RFID_AS_BYTE_LEN)) ^ *buf_ptr] ^ (crc16 << RFID_AS_BYTE_LEN);
}
if(bit_len !=0)
{
last_byte = (*buf_ptr) << (RFID_AS_CRC16_LEN - RFID_AS_BYTE_LEN);
while(bit_len-- != 0)
{
if((crc16 ^ last_byte) & RFID_AS_MSB_16)
{
crc16 = (crc16 << 1) ^ RFID_AS_CRC16_POLYNOMIAL;
}
else
{
crc16 = crc16 << 1;
}
last_byte <<= 1;
}
}
return ~crc16;
}
void main()
{
rfid_crc5_init();
rfid_crc16_init();
unsigned char data[] = {0x24,0x00,0xBB,0xBB,0x33,0xB2,0xDD,0xD9,0x01,0x40, 0xC4, 0xF3};
unsigned short crc = rfid_crc16_cal(data, 96);
}