📄 level2.c
字号:
//SPI start event
cbi(PORTC, MOD_PIN);
WaitSPI();
sbi(PORTC, DCLK_PIN);
WaitSPI();
sbi(PORTC, MOD_PIN);
WaitSPI();
while (bitcnt-- > 0) {
cbi(PORTC, DCLK_PIN);
WaitSPI();
if(data & 1) sbi(PORTC, MOD_PIN); else cbi(PORTC, MOD_PIN);
WaitSPI();
data >>= 1;
if(bitcnt == 16)
data = hi;
sbi(PORTC, DCLK_PIN);
WaitSPI();
}
cbi(PORTC, DCLK_PIN); //for the first time, DCLK is '1', for the next, enable DIN
WaitSPI();
cbi(PORTC, MOD_PIN);
}
// ==================================================================
uint16_t CRC(uint8_t *data, uint8_t len) {
uint16_t crc = 0xFFFF; //CRC preset
uint8_t i, j, feedback;
#define crc_poly 0x8408 //CRC polynom
for (i=0;i<len;i++) {
crc ^= *data++;
for (j=0; j<8; j++) {
feedback = crc & 1;
crc >>= 1;
if (feedback)
crc ^= crc_poly;
}
}
return ~crc;
}
// ==================================================================
// ISO3309 CRC
// Results: 16 bit binary CRC
// Side effects: None
uint16_t ISO3309CRC(uint8_t *data, uint8_t len) {
uint16_t crc = 0; //CRC preset
uint8_t i;
int8_t j;
uint8_t value, feedback;
#define crc3309poly 0x1021 //CRC polynom
for (i=0;i<len;i++) {
value = *data++;
for (j=7; j>=0; j--) {
feedback = crc >> 8;
feedback ^= value;
crc <<= 1;
if ( feedback & 0x80 )
crc ^= crc3309poly;
value <<= 1;
}
}
return crc;
}
// ==================================================================
// Search 1st valid bit ('1' from SOF)
// maximum size bits to be searched from start position to end position
//
// ASK data usually starts at bit position 0 or 1 of captured_data
// FSK data usually starts at 4th bit position
uint8_t SearchValidBit( uint8_t start, uint8_t end ) {
uint8_t bitcnt = start % 8;
uint8_t byte = start / 8;
uint8_t valid;
uint8_t *ptr = capture.capture_valid + start/8;
if ((decode_number & 1) == 0) { //ASK specific
while (start < end) {
valid = ((*ptr) >> (7-bitcnt)) & 1;
if (valid == 0) return start; //return 1st valid bit position
if (++bitcnt > 7) {
bitcnt = 0;
ptr++;
}
start++;
}
} else { //FSK specific
valid = capture.capture_data[byte];
byte = valid & 0xF0;
if (byte == 0x50)
if (((*ptr) & 0xF0) == 0)
return 3;
byte = valid & 0x78;
if (byte == 0x28)
if (((*ptr) & 0x78) == 0)
return 4;
}
return 255; //no valid bit
}
// ==================================================================
// Extracts decoded data to bytes accroding to start position
// valid start range is < 255
uint8_t ExtractData( uint8_t size ) {
uint8_t value = 0;
uint8_t valid;
uint8_t pom;
uint8_t start;
uint8_t bitcnt;
uint8_t ptr = 0;
uint8_t running_one;
pom = SearchValidBit( 0, 7 ); //find the first valid bit in 0th byte of capture_valid
if (pom == 255) return size;
start = pom;
#if 0
//#ifdef DEBUG
UDR = size;
while (!(UCSRA & (1<<UDRE)))
{}
UDR = start;
while (!(UCSRA & (1<<UDRE)))
{}
#endif
bitcnt = start % 8; //set the pointers
start = start / 8;
running_one = 1 << (7-bitcnt);
pom = capture.capture_data[start] & running_one; //check the 1st bit is '1'
if (pom == 0) return size;
while (size > 0) {
if (bitcnt == 7) { //increment position to next bit
bitcnt = 0;
running_one = 0x80;
start++;
} else {
bitcnt++;
running_one >>= 1;
}
pom = capture.capture_data[start] & running_one;
value >>= 1;
if (pom != 0) value |= 0x80;
valid = capture.capture_valid[start] & running_one;
if(valid != 0)
break;
size--;
#if 0
//#ifdef DEBUG
UDR = ptr;
while (!(UCSRA & (1<<UDRE)))
{}
UDR = value;
while (!(UCSRA & (1<<UDRE)))
{}
#endif
data_buffer[ptr/8] = value >> (7-(ptr & 7)); //always store the byte (for inventory)
ptr++;
}
return size;
}
// ==================================================================
// Extracts EM4006 decoded data to bytes accroding to start position
// valid start range is < 255
//#define DEBUG_EM4006
uint8_t Extract_EM4006( uint8_t size ) {
uint8_t value;
uint8_t valid;
uint8_t pom;
uint8_t start, local_start;
uint8_t bitcnt, local_bitcnt;
uint8_t ptr = 0;
uint8_t running_one = 0x80;
start = 0;
bitcnt = 0;
//try to find EM4006 UID
while(start <= size) {
valid = capture.capture_valid[start] & running_one;
pom = capture.capture_data[start] & running_one;
#if 0
//#ifdef DEBUG_EM4006
SendByte(valid);
SendByte(pom);
#endif
running_one >>= 1; //increment position
if (++bitcnt > 7) {
bitcnt = 0;
start++;
running_one = 0x80;
}
if ((valid == 0) && (pom != 0)) { //start bit?
//#if 0
#ifdef DEBUG_EM4006
SendByte(start);
SendByte(bitcnt);
#endif
local_start = start;
local_bitcnt = bitcnt;
value = 0;
ptr = 0;
while(local_start <= size) {
valid = capture.capture_valid[local_start] & running_one;
pom = capture.capture_data[local_start] & running_one;
running_one >>= 1; //increment position
if (++local_bitcnt > 7) {
local_bitcnt = 0;
local_start++;
running_one = 0x80;
}
if (valid != 0) break;
value <<= 1;
if (pom) value |= 1;
ptr++;
if ((ptr & 7) == 0) {
data_buffer[(ptr >> 3) - 1] = value;
//#if 0
#ifdef DEBUG_EM4006
SendByte(ptr);
SendByte(value);
#endif
if (ptr == 80) { //enough bits, check the crc
uint16_t crc, crc2;
crc2 = ISO3309CRC(data_buffer, 8);
crc = (data_buffer[8] << 8) | data_buffer[9];
if (crc2 == crc) {
return UART_MESSAGE_OK;
}
local_start = start;
local_bitcnt = bitcnt;
break;
}
}
}
start = local_start; //invalid bit found, restart search
bitcnt = local_bitcnt;
}
}
return ERR_EM4035_NO_TAG;
}
// ==================================================================
// CPLD transaction delay loop
// WARNING!!! - this timing is sensitive to compiler version / optimization
void WaitCPLD(void) {
uint8_t register x = 5;
while(x-->0)
{ asm ( "nop" ); }
}
// ==================================================================
void HWTransaction(uint8_t *data, uint8_t *dst, uint8_t len) {
uint8_t read = 7;
uint8_t byte = 7;
uint8_t cnt = 7;
while (len-->0) {
if (++cnt==8) {
cnt = 0;
byte = *data++;
}
if(byte & 1) SetSDA(); else ResetSDA();
byte >>= 1;
read = (read >> 1) | ((PINB << (7-SDO_PIN)) & 0x80);
#ifdef DEBUG
PORTD = PIND ^ (1<<DBG_FORWARD);
#endif
if (cnt==7) {
*dst++ = read ^ 0xFF;
}
SetSCK();
WaitCPLD();
ResetSCK();
WaitCPLD();
}
SetSSN();
}
// ==================================================================
void HWSign(uint8_t *data, uint8_t *dst, uint8_t len) {
uint8_t read = 7;
uint8_t byte = 7;
uint8_t cnt = 7;
while (len-->0) {
if (++cnt==8) {
cnt = 0;
byte = *data++;
}
if(byte & 1) SetSDA(); else ResetSDA();
byte >>= 1;
WaitCPLD();
SetSCK();
WaitCPLD();
read = (read >> 1) | ((PINB << (7-SDO_PIN)) & 0x80);
ResetSCK();
if (cnt==7)
*dst++ = read ^ 0xFF;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -