www.pudn.com > EM4469firmware.zip > level3.c
/* *------------------------------------------------------------------------------- *-- RCSId: $Id: level3.c,v 0.17 2003-10-10 10:55:38+02 mjg Exp mjg $ *-- $Name: $ *------------------------------------------------------------------------------- *-- level3.c - High level data transformations and main loop *------------------------------------------------------------------------------- *-- $Log: level3.c,v $ *-- Revision 0.17 2003-10-10 10:55:38+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:29+02 mjg *-- *** empty log message *** *-- *-- Revision 0.11 2003-07-22 13:27:36+02 mjg *-- cloned firmware *-- *------------------------------------------------------------------------------- */ #include#include #include #include #include #include #include #include #include "level4.h" #include "level3.h" #include "level2.h" #include "level1.h" //-------------------------------------------------------------- //global variables uint16_t maxCaptureTimeLow; //lower part of current maximum capture time (used to initialise TCNT1) uint8_t maxCaptureTimeHi; //upper part of current maximum capture time (expected value 0xFF or 0xFE only) register uint8_t capture_cnt asm ("r8"); //store_bit current capture byte index (this is a mirror from main.c) uint32_t RO_value_low; //raw Read Only data value uint32_t RO_value_hi; //raw Read Only data value //-------------------------------------------------------------- //local declarations uint8_t raw; //raw flag to capture read after write response uint16_t maxTLogin; //current datarate maximum response capture time uint16_t maxTWrite; //current datarate maximum response capture time uint32_t maxTWriteRaw; //current datarate maximum response capture time uint16_t maxTRead; //current datarate maximum response capture time uint16_t maxTDisable; //current datarate maximum response capture time uint32_t maxTDefaultRead; //current datarate maximum response capture time uint16_t tpp_period; //Tpp pause in RF clocks // configuration EEPROM variables static uint8_t eeprom_config_data_rate __attribute__ ((section(".eeprom"))); static uint8_t eeprom_config_encoder __attribute__((section(".eeprom"))); static uint8_t eeprom_config_delayed __attribute__((section(".eeprom"))); static uint8_t eeprom_config_lwr __attribute__((section(".eeprom"))); static uint8_t eeprom_config_raw __attribute__((section(".eeprom"))); static uint8_t eeprom_config_fwlink __attribute__((section(".eeprom"))); uint8_t CheckConfiguration(void); uint8_t CheckAndSetForwardLink(uint8_t type); void ReadConfiguration(void); void WriteConfiguration(void); uint16_t get_settings_low; uint16_t get_settings_hi; //Read Only uint32_t RO_data; uint8_t RO_custID; uint8_t RO_method; void PackActualSettings(void); uint8_t ROCapture(uint8_t demod, uint8_t hDRate); uint8_t ReadWord(uint8_t address); uint8_t WriteWord(uint8_t address, uint16_t word_low, uint16_t word_hi); void SendCaptureData(uint8_t cmd); void SendRawData(uint8_t cmd); //-------------------------------------------------------------- // main loop routine //-------------------------------------------------------------- void main_receiver(void) { uint8_t check_stat; uint8_t fwd_bit_count; uint8_t i; if (watchdog_reset != 0) { FormatResponse_Short( 0x00, ERR_ASIC_ANTENNA_FAULT ); ReadConfiguration(); } else { ReadConfiguration(); } enable_capture = 0; sbi (TIMSK, TICIE1); //enable capture TCCR1B = counter1set = (1< > 16); Capture(1); SendCaptureData(0x85); break; //............................................................................................... case 0x86 : //Autodetect Read/Only mode Capture using Default Read for(i=0;i<4;i++) { check_stat = ROCapture((i>>1)+1, (((i&1)+1)<<4) - 1); if (check_stat != 0) { FormatResponse_AutoDefaultRead(UART_MESSAGE_OK, 0x86, i, RO_custID, RO_data); break; } } if (check_stat == 0) FormatResponse_AutoDefaultRead(ERR_EM4469_NO_VALID_DR, 0x86, 0, 0, 0); break; //............................................................................................... case 0xF8 : //Send Capture Data SendCaptureData(0xF8); break; //............................................................................................... case 0xF9 : //toggle debug mode FormatResponse_Short( 0xF9, check_stat ); break; //............................................................................................... case 0xFA : //get actual fwd settings fwd_1st_pulse = fwd_set_0; fwd_01_stop = fwd_set_A; fwd_01_one = fwd_set_B; fwd_01_zero = fwd_set_C; FormatResponse_Short( 0xFA, UART_MESSAGE_OK ); break; //............................................................................................... case 0xFB : //get actual reader settings PackActualSettings(); FormatResponse_Word( UART_MESSAGE_OK, 0xFB, get_settings_low, get_settings_hi ); break; //............................................................................................... case 0xFC : //set reader configuration check_stat = CheckConfiguration(); if (check_stat == UART_MESSAGE_OK) { if (config_write_conf != 0) //needs write values in eeprom WriteConfiguration(); } FormatResponse_Short( 0xFC, check_stat ); break; //............................................................................................... case 0xFD : //status FormatResponse_Word( UART_MESSAGE_OK, 0xFD, READER_RELEASE | ((uint16_t)(READER_DATE | ((READER_MONTH & 0x07) << 5)) << 8), ((READER_MONTH >> 3) | (READER_YEAR << 1)) | ((uint16_t)(READER_FAMILY) << 8) ); break; //............................................................................................... case 0xFE : //set antenna on/off if (switch_coil_byte & 1) cbi( PORTC, SHD_PIN ); //set shutdown == antenna on else sbi( PORTC, SHD_PIN ); //reset shutdown == antenna off FormatResponse_Short( 0xFE, UART_MESSAGE_OK ); break; //............................................................................................... case 0x00 : //no command continue; //............................................................................................... default: EmmitError( ERR_UART_UNKNOWN_CMD ); break; } uart_command = 0; } } } //-------------------------------------------------------------- // checks configuration values and sets them into proper registers uint8_t CheckConfiguration(void) { //check if ( (config_data_rate == 0) ) { return ERR_EM4469_WRONG_DR; } if ( (config_lwr < 5) || (config_lwr > 15) ) { return ERR_EM4469_BAD_CONF_DATA; } //set counter1set = (1< set default values, RF/32 config_delayed = 0; config_lwr = 8; //lwr config_raw = 0; CheckConfiguration(); forward_link_type = 0x01; //default value = 4050 forward link FormatResponse_Short( 0xFC, ERR_EM4469_BAD_CONF_DATA ); } } //-------------------------------------------------------------- // write configuration values to EEPROM void WriteConfiguration(void) { eeprom_wb((uint8_t)&eeprom_config_data_rate, config_data_rate); eeprom_wb((uint8_t)&eeprom_config_encoder, config_encoder); eeprom_wb((uint8_t)&eeprom_config_delayed, config_delayed); eeprom_wb((uint8_t)&eeprom_config_lwr, config_lwr); eeprom_wb((uint8_t)&eeprom_config_raw, config_raw); eeprom_wb((uint8_t)&eeprom_config_fwlink, config_forward_link); } //-------------------------------------------------------------- // pack actual configuration values to get_settings_low and ..._hi void PackActualSettings(void) { uint8_t q; if (decode == manchester_capture) q = 1; else if (decode == biphase_capture) q = 2; else if (decode == miller_capture) q = 3; else q = 0xF; //else not used get_settings_low = (q<<6) | (halfDataRate - 1); q = (q >> 2) | (delayed << 4) | ((lwr & 3) << 6); get_settings_low |= (uint16_t)q << 8; get_settings_hi = (raw << 6) | (lwr >> 2) | (forward_link_type >> 1); } //----------------------------------------------------------------- //----------------------------------------------------------------- //----------------------------------------------------------------- //Function 0x80 - Read Word // result in read_tag_memory_word_low, read_tag_memory_word_hi if result=0 uint8_t ReadWord(uint8_t address) { uint8_t check_stat; uint8_t fwd_bit_count; fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); fwd_bit_count += Prepare_Addr( address ); SendForward(fwd_bit_count); Wait(tpp_period); maxCaptureTimeLow = maxTRead; maxCaptureTimeHi = 0; if (debug_mode == 1) { Capture(2); SendRawData(0x80); check_stat = 0xFF; } else { Capture(1); read_tag_memory_word_low = 0; read_tag_memory_word_hi = 0; check_stat = SearchPattern( 0x0A, 0x3F, 0, 10 ); //search ACK[6 lsbits] within first 10 captured bits if (check_stat == 0) { check_stat = SearchPattern( 0x01, 0x3F, 0, 10 ); //search NACK within first 10 captured bits if (check_stat == 0) { check_stat = ERR_EM4469_NEITHER_ACK; } else { check_stat = ERR_EM4469_NACK; } } else { check_stat = ExtractData(check_stat); } } return check_stat; } //-------------------------------------------------------------- //Function 0x81 - Write Word // uint8_t WriteWord(uint8_t address, uint16_t word_low, uint16_t word_hi) { uint8_t check_stat; uint8_t fwd_bit_count; fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); fwd_bit_count += Prepare_Addr( address ); fwd_bit_count += Prepare_Data( word_low, word_hi ); SendForward(fwd_bit_count); Wait(tpp_period); maxCaptureTimeHi = 0; if (raw == 0) maxCaptureTimeLow = maxTWrite; else maxCaptureTimeLow = maxTWriteRaw; if (debug_mode == 1) { Capture(2); SendRawData(0x80); check_stat = 0xFF; } else { Capture(1); if (raw == 0) { //normal write acknowldge check_stat = SearchPattern( 0x01, 0x3F, 0, 10 ); //search NACK within first 10 captured bits if (check_stat == 0) { check_stat = SearchPattern( 0x0A, 0x1F, 0, 80 ); //search ACK[5 lsbits] within captured bits if (check_stat == 0) { check_stat = ERR_EM4469_NEITHER_ACK; } else { check_stat = UART_MESSAGE_OK; } } else { check_stat = ERR_EM4469_NACK; } } else { //acknowledge + read after write data check_stat = SearchPattern( 0x01, 0x3F, 0, 10 ); //search NACK[6 lsbits] within first 10 captured bits if (check_stat == 0) { check_stat = SearchPattern( 0x0A, 0x1F, 0, 80 ); //search ACK within captured bits if (check_stat == 0) { check_stat = ERR_EM4469_NEITHER_ACK; } else { check_stat = ExtractData(check_stat); if (check_stat == 0) { if ( (read_tag_memory_word_low != word_low) || (read_tag_memory_word_hi != word_hi) ) check_stat = ERR_EM4469_BAD_RAW; } } } else { check_stat = ERR_EM4469_NACK; } } } return check_stat; } //-------------------------------------------------------------- //Output of default read // void SendCaptureData(uint8_t cmd) { uint8_t check_stat; UDR = 0x02; while (!(UCSRA & (1< 0) { UDR = *read_ptr; check_stat ^= *read_ptr++; read_pos--; while (!(UCSRA & (1< 0) { UDR = *read_ptr; check_stat ^= *read_ptr++; read_pos--; while (!(UCSRA & (1< 0) { UDR = *read_ptr; check_stat ^= *read_ptr++; read_pos--; while (!(UCSRA & (1< >= 5; for(j=0; j<10; j++) { if (j==5) data |= (uint8_t)RO_value_hi << 2; //merge line_parity = (uint8_t)data & 1; col_parity ^= (uint8_t)data; data >>= 1; for(i=0; i<4; i++) { if ((i==1)&&(j==5)) data = RO_value_hi; d <<= 1; pom = (uint8_t)data & 1; line_parity ^= pom; d |= pom; data >>= 1; } #ifdef AUTO UDR = line_parity & 1; while (!(UCSRA & (1< > 16); Capture(1); status = SearchPattern( 0x1FF, 0x3FF, 0, 128 ); //search r/o header within first 128 captured bits if (status != 0) { status -= 9; #ifdef AUTO UDR = status; while (!(UCSRA & (1< 0) { UDR = *read_ptr++; read_pos--; while (!(UCSRA & (1< 0) { UDR = *read_ptr++; read_pos--; while (!(UCSRA & (1< > 24; data <<= 8; while (!(UCSRA & (1< > 24; data <<= 8; while (!(UCSRA & (1<