www.pudn.com > EM4469firmware.zip > level2.c
/* *------------------------------------------------------------------------------- *-- RCSId: $Id: level2.c,v 0.17 2003-10-10 10:55:33+02 mjg Exp mjg $ *-- $Name: $ *------------------------------------------------------------------------------- *-- level2.c - Low level data transforming *------------------------------------------------------------------------------- *-- $Log: level2.c,v $ *-- Revision 0.17 2003-10-10 10:55:33+02 mjg *-- *** empty log message *** *-- *-- Revision 0.16 2003-08-21 16:00:20+02 mjg *-- RTF capture problem *-- *-- Revision 0.15 2003-08-20 10:53:20+02 mjg *-- to redesign SearchPattern *-- *-- Revision 0.14 2003-08-20 10:00:46+02 mjg *-- to add debug features *-- *-- Revision 0.13 2003-08-07 08:01:27+02 mjg *-- *** empty log message *** *-- *-- Revision 0.11 2003-07-22 13:27:28+02 mjg *-- cloned firmware *-- *------------------------------------------------------------------------------- */ #include#include #include #include #include #include "level4.h" #include "level3.h" #include "level2.h" #include "level1.h" //-------------------------------------------------------------- //global variables uint8_t capture_data[CAPTURE_SIZE]; //maximum bytes captured at once uint8_t capture_valid[CAPTURE_SIZE]; //their valid bits uint8_t forwardLink_data[64]; //array of forwarded bits uint8_t * forward_ptr; //ptr for forward message preparation uint8_t fwd_1st_pulse = 256 - 24; //24 ~ 200us uint8_t fwd_01_stop = 256 - 12; //12 ~ 100us uint8_t fwd_01_one = 256 - 32; //notmod full period '1' uint8_t fwd_01_zero = 256 - 20; //complement to fwd_01_stop //-------------------------------------------------------------- //local variables volatile uint8_t fwd_bit_phase; //forwardlink bit phase uint8_t fwd_bit_sz; //forwardlink bit counter uint8_t * fwd_write_ptr; //forwardlink bit pointer uint8_t field_stop; //next field stop in RF clocks // ================================================================== // Forward link interrupt routine SIGNAL (SIG_OVERFLOW0) { if (forward_link_type == 0x01) { //EM4050 forwardlink if (fwd_bit_phase == 1) { //mod pulse '0' sbi( PORTC, MOD_PIN ); TCNT0 = field_stop; field_stop = fwd_01_stop; //mod pulse fwd_bit_phase = 2; return; } cbi( PORTC, MOD_PIN ); //notmod pulse or period if (fwd_bit_phase == 2) //notmod pulse '0' TCNT0 = fwd_01_zero; else TCNT0 = fwd_01_one; //notmod period '1' if(fwd_bit_sz-- > 0) { //prepare next bit modulation if(((*fwd_write_ptr++) & 1) == 1) fwd_bit_phase = 3; else fwd_bit_phase = 1; } else { TCCR0 = 0; //no clock T0 sbi(TIMSK, TICIE1); //enable capture cbi(TIMSK, TOIE0 ); //stop cbi(TIFR, TOV0); //clear pending int } } else { //invalid modulation type TCCR0 = 0; //no clock T0 sbi(TIMSK, TICIE1); cbi(TIMSK, TOIE0); //else stop cbi(TIFR, TOV0); //clear pending int }; } // ================================================================== // Forward Link setup function // Requires: forwarLink_data filled with valid bits (1 bit per byte) // fwd_bit_count set with number of bits to be sent void SendForward(uint8_t fwd_bit_count) { fwd_write_ptr = forwardLink_data; fwd_bit_sz = fwd_bit_count; fwd_bit_phase = 3; field_stop = fwd_1st_pulse; TCNT0 = 1; //minimum startup pulse length cbi( PORTC, MOD_PIN ); //notmod pulse cbi(TIMSK, TICIE1); //disable capture sbi(TIMSK, TOIE0); TCCR0 = 7; //external clock T0. rising edge, RUN! // waiting for clearing TOIE0 => command sending while ( bit_is_set(TIMSK, TOIE0) == 1 ) { SetLEDOff(); SetLEDOn(); SetLEDOff(); } } // ================================================================== // prepares command bits // see EM4469 spec uint8_t Prepare_Cmd( uint8_t cmd ) { register uint8_t line_parity; if (forward_link_type == 0x01) { *forward_ptr++ = 0; //start bit *forward_ptr++ = 0; //second pause for 4050 code } *forward_ptr++ = cmd; line_parity = cmd; cmd >>= 1; *forward_ptr++ = cmd; line_parity ^= cmd; cmd >>= 1; *forward_ptr++ = cmd; line_parity ^= cmd; *forward_ptr++ = (line_parity & 1); if (forward_link_type == 0x01) return 6; //second pause for 4050 code return 4; //return number of emited bits } // ================================================================== // prepares address bits // see EM4469 spec uint8_t Prepare_Addr( uint8_t addr ) { register uint8_t line_parity; *forward_ptr++ = addr; line_parity = addr; addr >>= 1; *forward_ptr++ = addr; line_parity ^= addr; addr >>= 1; *forward_ptr++ = addr; line_parity ^= addr; addr >>= 1; *forward_ptr++ = addr; line_parity ^= addr; *forward_ptr++ = 0; *forward_ptr++ = 0; *forward_ptr++ = (line_parity & 1); return 7; //return number of emited bits } // ================================================================== // prepares data bits intreleaved with parity bits // see EM4469 spec uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { register uint8_t line_parity; register uint8_t column_parity; register uint8_t i, j; register uint16_t data; data = data_low; column_parity = 0; for(i=0; i<4; i++) { line_parity = 0; for(j=0; j<8; j++) { line_parity ^= data; column_parity ^= (data & 1) << j; *forward_ptr++ = data; data >>= 1; } *forward_ptr++ = line_parity; if(i == 1) data = data_hi; } for(j=0; j<8; j++) { *forward_ptr++ = column_parity; column_parity >>= 1; } *forward_ptr = 0; return 45; //return number of emited bits } // ================================================================== // Search pattern (max 32b (31.bit is first)) // length is specified by mask // maximum size bits to be searched from start position // returns last position of valid pattern found or 0 if unsuccessful uint8_t SearchPattern( uint32_t pattern, uint32_t mask, uint8_t start, uint8_t size ) { uint32_t value = 0; uint32_t valid = 0xFFFFFFFF; uint8_t bitcnt = start % 8; uint8_t pom; start = start / 8; while (size > 0) { pom = (capture_data[start] >> (7-bitcnt)) & 1; value = (value << 1) | pom; valid = (valid << 1) | ((capture_valid[start] >> (7-bitcnt)) & 1); size--; if (bitcnt == 7) { bitcnt = 0; start++; } else bitcnt++; if( ((value & mask ) == pattern) && ((valid & mask) == 0)) { //test pattern match return (start*8 + bitcnt); //return the (next) position } } return 0; } // ================================================================== // Extract data // length is specified by mask // maximum size bits to be extracted from start position uint8_t ExtractData( uint8_t start ) { register uint8_t line_parity; register uint8_t column_parity; register uint8_t i, j; register uint16_t data; uint8_t ptr; uint8_t valid; uint8_t bitcnt = start % 8; uint8_t pom; bitcnt = start % 8; ptr = start / 8; data = 0; column_parity = 0; line_parity = 0; valid = 0; for(i=0; i<5; i++) { for(j=0; j<8; j++) { pom = (capture_data[ptr] >> (7-bitcnt)) & 1; //get bit valid += (capture_valid[ptr] >> (7-bitcnt)) & 1; //count any error bits if (bitcnt == 7) { bitcnt = 0; ptr++; } else bitcnt++; data = data >> 1; if (pom != 0) data |= 0x8000; } valid += (capture_valid[ptr] >> (7-bitcnt)) & 1; //skip parities if (bitcnt == 7) { bitcnt = 0; ptr++; } else bitcnt++; if(i == 1) read_tag_memory_word_low = data; if(i == 3) read_tag_memory_word_hi = data; } if (valid != 0) return ERR_EM4469_FLOWLINK_ERR; forward_ptr = forwardLink_data; Prepare_Data( read_tag_memory_word_low, read_tag_memory_word_hi ); forward_ptr = forwardLink_data; bitcnt = start % 8; ptr = start / 8; for(i=0; i<5; i++) { for(j=0; j<9; j++) { pom = (capture_data[ptr] >> (7-bitcnt)) & 1; //get bit if (bitcnt == 7) { bitcnt = 0; ptr++; } else bitcnt++; if ( pom != ((*forward_ptr++)&1) ) return ERR_EM4469_PARITY_ERR; } } return UART_MESSAGE_OK; } // ================================================================== void SetLEDOn(void) { cbi( PORTC, LED_PIN); } void SetLEDOff(void) { sbi( PORTC, LED_PIN); } // ================================================================== void ClearCaptureBuffers(void) { uint8_t i; for(i=0; i > 24; while (!(UCSRA & (1< > (7-bitcnt)) & 1; RO_value_low = (RO_value_low << 1) | pom; valid = valid | ((capture_valid[start] >> (7-bitcnt)) & 1); ptr++; if (bitcnt == 7) { bitcnt = 0; start++; } else bitcnt++; } if (valid == 0) return 1; else return 0; }