www.pudn.com > EM4469firmware.zip > level4.c
/* *------------------------------------------------------------------------------- *-- RCSId: $Id: level4.c,v 0.17 2003-10-10 10:55:39+02 mjg Exp mjg $ *-- $Name: $ *------------------------------------------------------------------------------- *-- level4.c - UART Communication Routines *------------------------------------------------------------------------------- *-- $Log: level4.c,v $ *-- Revision 0.17 2003-10-10 10:55:39+02 mjg *-- *** empty log message *** *-- *-- Revision 0.16 2003-08-21 16:00:21+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:42+02 mjg *-- cloned firmware *-- *------------------------------------------------------------------------------- */ #include#include #include #include #include #include "level4.h" #include "level2.h" #include "level1.h" //-------------------------------------------------------------- //global declarations uint8_t volatile uart_command; // command handshake value // set by UART RECV // reset by main() when done uint8_t read_tag_memory_word_address; // address of Read cmd uint16_t read_tag_memory_word_low; // Read Cmd content low uint16_t read_tag_memory_word_hi; // Read Cmd content hi uint16_t write_tag_memory_word_address; // address of Write Tag cmd uint16_t write_tag_memory_word_low; // low word of Write Tag cmd uint16_t write_tag_memory_word_hi; // hi word of Write Tag cmd uint16_t write_tag_memory_login_low; // low word of Login cmd uint16_t write_tag_memory_login_hi; // hi word of Login cmd uint8_t write_tag_memory_forward_link; // forward item of Forward link cmd uint16_t read_only_word_low; // Read Only Cmd content low uint16_t read_only_word_hi; // Read Only Cmd content hi uint8_t switch_coil_byte; // switch item of Set Coil cmd uint8_t config_data_rate; // see EM4469 spec uint8_t config_encoder; // see EM4469 spec uint8_t config_psk_carrier; // see EM4469 spec uint8_t config_delayed; // see EM4469 spec uint8_t config_lwr; // see EM4469 spec uint8_t config_raw; // see EM4469 spec uint8_t config_forward_link; // 0=4050 type, 1=other uint8_t config_write_conf; // 1=write this configuration into the EEPROM uint8_t * read_ptr; //debug capture pulse lengths uart data pointer uint8_t volatile read_pos; //debug capture pulse lengths uart read counter uint8_t fwd_set_0; // forwadlink pulse length values to be set uint8_t fwd_set_A; uint8_t fwd_set_B; uint8_t fwd_set_C; uint8_t fwd_set_D; uint8_t fwd_set_E; uint8_t fwd_set_F; uint8_t debug_mode; //-------------------------------------------------------------- //local declarations #define UART_IN_BUFFER_SIZE 32 // incoming data uart buffer reserved size #define UART_OUT_BUFFER_SIZE 250 // outgoing data uart buffer reserved size uint8_t volatile uart_in_buffer[UART_IN_BUFFER_SIZE]; // input cyclic buffer uint8_t volatile uart_in_read; // input read index uint8_t volatile uart_in_end; // input message read index uint8_t volatile uart_in_write; // input write index uint8_t volatile uart_in_overflow; // input buffer overflow uint8_t volatile uart_in_error; // input buffer parity error, ... uint8_t volatile uart_out_buffer[UART_OUT_BUFFER_SIZE]; // output buffer uint8_t volatile uart_out_read; // output read index uint8_t volatile uart_out_write; // output write index uint8_t volatile uart_out_end; // last output write index uint8_t volatile uart_read_bytes; // number of bytes to read before parsing uint8_t volatile uart_read_msg_bytes; // actual number of bytes (msg position no.2) //UART_STATE - enum is errorneous in gcc+sim/debug #define UART_EMPTY 1 // no bytes are pending #define UART_READ_SIZE 2 // try to analyze incoming message size from pending bytes #define UART_READ_BYTES 3 // try to analyze body and ETX of message from pending bytes #define UART_WAIT_ERROR_SENT 4 // something is wrong within analysed pending bytes #define UART_VALID 5 // known message format was detected, rest is still pending uint8_t uart_state; // current state of incoming message analysis // ================================================================== void IncWriteOutIndex(void); uint8_t ParseMessage(void); void FormatResponse_ReadTagMemory(uint8_t ack); void FormatResponse_ReadOnly(uint8_t ack); void FormatResponse_Status(uint8_t ack); // ================================================================== // uart byte receive interrupt SIGNAL (SIG_UART_RECV) { uart_in_buffer[uart_in_write++] = UDR; //store byte into cyclic buffer if (uart_in_write == UART_IN_BUFFER_SIZE) uart_in_write = 0; if (uart_in_write == uart_in_read) { uart_in_overflow = 1; //set flag in overflow //block reception until some bytes are parsed out } if ((UCSRA & ((1< = 3) || (c <= 9)) { uart_read_bytes = c; uart_read_msg_bytes = c; uart_state = UART_READ_BYTES; } else { result = ERR_UART_INTERBYTE_ERR; uart_state = UART_WAIT_ERROR_SENT; } break; case UART_READ_BYTES : //read specified size bytes to allow if (--uart_read_bytes == 0) { //last byte - ETX expected //check ETX if (c == 0x03) { result = UART_MESSAGE_OK; uart_state = UART_VALID; uart_in_end = ptr; } else { result = ERR_UART_NO_ETX; uart_state = UART_WAIT_ERROR_SENT; } } break; }; if(++ptr == UART_IN_BUFFER_SIZE) ptr = 0; } if (uart_state == UART_WAIT_ERROR_SENT) { uart_in_read = uart_in_write; //dropped =async return result; } if (uart_state == UART_VALID) { result = ParseMessage(); //parse message and commit the command uart_in_read = ptr; return result; } return result; } // ================================================================== // parses valid message format and checks size according to the command type uint8_t ParseMessage(void) { uint8_t byte = 0; uint8_t ptr = uart_in_read; uint8_t ptr2 = 0, c; uint8_t temp_buffer[UART_IN_BUFFER_SIZE]; //compute checksum byte = uart_in_buffer[ptr]; while (ptr != uart_in_end) { c = uart_in_buffer[ptr++]; if(ptr == UART_IN_BUFFER_SIZE) ptr = 0; byte ^= c; temp_buffer[ptr2++] = c; } if (byte == 0) { //checksum ok byte = temp_buffer[2]; switch(byte) { case 0x80 : //Read Tag Memory if (uart_read_msg_bytes != 4) return ERR_UART_INTERBYTE_ERR; read_tag_memory_word_address = temp_buffer[3]; break; case 0x81 : //Write Tag if (uart_read_msg_bytes != 8) return ERR_UART_INTERBYTE_ERR; write_tag_memory_word_address = temp_buffer[3]; write_tag_memory_word_low = ((uint16_t)temp_buffer[5] << 8) + temp_buffer[4]; write_tag_memory_word_hi = ((uint16_t)temp_buffer[7] << 8) + temp_buffer[6]; break; case 0x82 : //Login if (uart_read_msg_bytes != 7) return ERR_UART_INTERBYTE_ERR; write_tag_memory_login_low = temp_buffer[3]; write_tag_memory_login_low = (write_tag_memory_login_low << 8) + temp_buffer[4]; write_tag_memory_login_hi = temp_buffer[5]; write_tag_memory_login_hi = (write_tag_memory_login_hi << 8) + temp_buffer[6]; break; case 0x83 : //Disable if (uart_read_msg_bytes != 3) return ERR_UART_INTERBYTE_ERR; break; case 0x84 : //Forward link if (uart_read_msg_bytes != 4) return ERR_UART_INTERBYTE_ERR; write_tag_memory_forward_link = temp_buffer[3]; break; case 0x85 : //Read Only Continuous mode if (uart_read_msg_bytes != 3) return ERR_UART_INTERBYTE_ERR; break; case 0x86 : //Read Only Continuous mode if (uart_read_msg_bytes != 3) return ERR_UART_INTERBYTE_ERR; break; case 0xF8 : //Send Capture Data if (uart_read_msg_bytes != 3) return ERR_UART_INTERBYTE_ERR; break; case 0xF9 : //Toggle debug mode if (uart_read_msg_bytes != 4) return ERR_UART_INTERBYTE_ERR; debug_mode = temp_buffer[3]; break; case 0xFA : //Forward link pulses tuning if (uart_read_msg_bytes != 0xA) return ERR_UART_INTERBYTE_ERR; fwd_set_0 = temp_buffer[3]; fwd_set_A = temp_buffer[4]; fwd_set_B = temp_buffer[5]; fwd_set_C = temp_buffer[6]; fwd_set_D = temp_buffer[7]; fwd_set_E = temp_buffer[8]; fwd_set_F = temp_buffer[9]; break; case 0xFB : //Reader Read Configuration if (uart_read_msg_bytes != 3) return ERR_UART_INTERBYTE_ERR; break; case 0xFC : //Reader Write Configuration if (uart_read_msg_bytes != 7) return ERR_UART_INTERBYTE_ERR; config_data_rate = temp_buffer[3] & 0x3F; config_encoder = ((temp_buffer[4] & 0x03) << 2) | (temp_buffer[3] >> 6); config_psk_carrier = (temp_buffer[4] >> 2) & 0x03; config_delayed = (temp_buffer[4] >> 4) & 0x03; config_lwr = ((temp_buffer[5] & 0x03) << 2) | (temp_buffer[4] >> 6); config_raw = (temp_buffer[5] >> 6) & 0x01; config_forward_link = (temp_buffer[5] >> 3) & 0x01; config_write_conf = (temp_buffer[5] >> 2) & 0x01; break; case 0xFE : //Switch Coil if (uart_read_msg_bytes != 4) return ERR_UART_INTERBYTE_ERR; switch_coil_byte = temp_buffer[3]; break; case 0xFD : //Reader Status if (uart_read_msg_bytes != 3) return ERR_UART_INTERBYTE_ERR; break; default : //Unknown command return ERR_UART_UNKNOWN_CMD; } //command was parsed successfully uart_command = byte; return UART_MESSAGE_OK; } else { //bad checksum return ERR_UART_BAD_CRC; } } // ================================================================== // send response void SendResponse(uint8_t ack) { if (ack == 0) SetLEDOff(); else SetLEDOn(); while ( (UCSRB & (1< >8); IncWriteOut((uint8_t)word_hi); IncWriteOut(word_hi>>8); IncWriteOut(0x09 ^ cmd ^ ack ^ address ^ (word_low & 0xFF) ^ (word_low >> 8) ^ (word_hi & 0xFF) ^ (word_hi >> 8) ); IncWriteOut(0x03); SendResponse(ack); } // ================================================================== void FormatResponse_Short(uint8_t cmd, uint8_t ack) { IncWriteOut(0x02); IncWriteOut(0x04); IncWriteOut(cmd); IncWriteOut(ack); IncWriteOut(0x04 ^ cmd ^ ack); IncWriteOut(0x03); SendResponse(ack); } // ================================================================== void FormatResponse_Word(uint8_t ack, uint8_t cmd, uint16_t word_low, uint16_t word_hi) { IncWriteOut(0x02); IncWriteOut(0x08); IncWriteOut(cmd); IncWriteOut(ack); IncWriteOut((uint8_t)word_low); IncWriteOut(word_low>>8); IncWriteOut((uint8_t)word_hi); IncWriteOut(word_hi>>8); IncWriteOut(0x08 ^ cmd ^ ack ^ (word_low & 0xFF) ^ (word_low >> 8) ^ (word_hi & 0xFF) ^ (word_hi >> 8)); IncWriteOut(0x03); SendResponse(ack); } // ================================================================== void FormatResponse_Status(uint8_t ack) { IncWriteOut(0x02); IncWriteOut(0x08); IncWriteOut(0xFD); IncWriteOut(ack); IncWriteOut(READER_RELEASE); IncWriteOut(READER_DATE | ((READER_MONTH & 0x07) << 5)); IncWriteOut((READER_MONTH >> 3) | (READER_YEAR << 1)); IncWriteOut(READER_FAMILY); //Read Only firmware IncWriteOut(0x08 ^ 0xFD ^ ack ^ READER_RELEASE ^ (READER_DATE | ((READER_MONTH & 0x07) << 5)) ^ ((READER_MONTH >> 3) | (READER_YEAR << 1)) ^ READER_FAMILY); IncWriteOut(0x03); SendResponse(ack); } // ================================================================== void FormatResponse_AutoDefaultRead(uint8_t ack, uint8_t cmd, uint8_t type, uint32_t byte, uint32_t word) { uint8_t checksum = 0, i; IncWriteOut(0x02); IncWriteOut(0x0A); IncWriteOut(cmd); IncWriteOut(ack); IncWriteOut(type); IncWriteOut(byte); checksum = 0x0A ^ cmd ^ ack ^ type ^ byte; for(i=0;i<4;i++) { IncWriteOut(word >> 24); checksum ^= word >> 24; word <<= 8; } IncWriteOut(checksum); IncWriteOut(0x03); SendResponse(ack); }