📄 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 <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include <stdio.h>
#include <stdlib.h>
#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<<ICNC1) | (1<<CS12) | (1<<CS11); //dummy capture run!
while (21) { // infinite loop
wdt_reset(); // reset the watchdog
if((check_stat = CheckIncommingMessage()) != UART_MESSAGE_OK) // check any incoming message
EmmitError(check_stat);
else { // no error, processing command
forward_ptr = forwardLink_data;
switch (uart_command) {
//...............................................................................................
case 0x80 :
check_stat = ReadWord( read_tag_memory_word_address );
if (debug_mode == 0) {
FormatResponse_AddrWord( check_stat, 0x80,
read_tag_memory_word_address, read_tag_memory_word_low, read_tag_memory_word_hi);
} else if (debug_mode == 2)
SendCaptureData(0x80);
break;
//...............................................................................................
case 0x81 : // WRITE
check_stat = WriteWord( write_tag_memory_word_address,
write_tag_memory_word_low, write_tag_memory_word_hi );
if (debug_mode == 0)
FormatResponse_Short( 0x81, check_stat );
else if (debug_mode == 2)
SendCaptureData(0x80);
break;
//...............................................................................................
case 0x82 : //Login
fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN );
fwd_bit_count += Prepare_Data( write_tag_memory_login_low, write_tag_memory_login_hi );
maxCaptureTimeLow = maxTLogin;
maxCaptureTimeHi = 0;
SendForward(fwd_bit_count);
Wait(tpp_period);
Capture(1);
if (debug_mode == 0) {
check_stat = SearchPattern( 0x01, 0x3F, 0, 10 ); //search NACK within first 16 captured bits
if (check_stat == 0) {
check_stat = SearchPattern( 0x0A, 0x1F, 0, 10 ); //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;
}
FormatResponse_Short( 0x82, check_stat );
} else
if (debug_mode == 2)
SendCaptureData(0x82);
else
FormatResponse_Short( 0x83, ERR_EM4469_NO_VALID_DR );
break;
//...............................................................................................
case 0x83 : //Disable
fwd_bit_count = Prepare_Cmd( FWD_CMD_DISABLE );
fwd_bit_count += Prepare_Data( 0xFFFF, 0xFFFF );
maxCaptureTimeLow = maxTDisable;
maxCaptureTimeHi = 0;
SendForward(fwd_bit_count);
Wait(tpp_period);
Capture(1);
if (debug_mode == 0) {
check_stat = SearchPattern( 0x01, 0x3F, 0, 10 ); //search NACK within first 16 captured bits
if (check_stat == 0) {
check_stat = ERR_EM4469_NEITHER_ACK;
} else {
check_stat = ERR_EM4469_NACK;
}
FormatResponse_Short( 0x83, check_stat );
} else
if (debug_mode == 2)
SendCaptureData(0x83);
else
FormatResponse_Short( 0x83, ERR_EM4469_NO_VALID_DR );
break;
//...............................................................................................
case 0x84 : //set forwardlink
check_stat = CheckAndSetForwardLink(write_tag_memory_forward_link);
FormatResponse_Short( 0x84, check_stat );
break;
//...............................................................................................
case 0x85 : //Default Read capture
maxCaptureTimeLow = (uint16_t)maxTDefaultRead;
maxCaptureTimeHi = (uint8_t)(maxTDefaultRead >> 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<<ICNC1) | (1<<ICES1) | (1<<CS12) | (1<<CS11);
switch (config_encoder) { //actually supported demod routines
case 1 :
decode = manchester_capture;
break;
case 2 :
decode = biphase_capture;
break;
case 3 :
decode = miller_capture;
break;
default:
return ERR_EM4469_WRONG_DE;
}
decode_number = config_encoder;
halfDataRate = config_data_rate+1;
lwr = config_lwr;
delayed = config_delayed;
raw = config_raw;
forward_link_type = 1 << (config_forward_link << 2);
maxTLogin = MAXTRELAX + 4 + (4 + 9) * 2 * (uint16_t)halfDataRate;
maxTWrite = MAXTRELAX + 1144 + (4 + 8) * 2 * (uint16_t)halfDataRate;
maxTWriteRaw = MAXTRELAX + 1144 + (4 + 5 + 54) * 2 * (uint16_t)halfDataRate;
maxTRead = (MAXTRELAX + 100) + 4 + (5 + 54) * 2 * (uint16_t)halfDataRate;
maxTDisable = maxTLogin;
maxTDefaultRead = MAXTRELAX + 2*((lwr-4)*4*8)*2*((uint32_t)halfDataRate);
tpp_period = 4 + 2 * (uint16_t)halfDataRate - 4;
return UART_MESSAGE_OK; //success
}
//--------------------------------------------------------------
// checks forward link value and sets it into proper registers
uint8_t CheckAndSetForwardLink(uint8_t type) {
if (type != 0x01)
return ERR_EM4469_BAD_CONF_DATA;
forward_link_type = type;
return UART_MESSAGE_OK;
}
//--------------------------------------------------------------
// read configuration values from EEPROM
// silent when success/generates error messages when something is wrong
void ReadConfiguration(void) {
config_data_rate = eeprom_rb((uint8_t)&eeprom_config_data_rate);
config_encoder = eeprom_rb((uint8_t)&eeprom_config_encoder);
config_delayed = eeprom_rb((uint8_t)&eeprom_config_delayed);
config_lwr = eeprom_rb((uint8_t)&eeprom_config_lwr);
config_raw = eeprom_rb((uint8_t)&eeprom_config_raw);
config_forward_link = eeprom_rb((uint8_t)&eeprom_config_fwlink);
config_forward_link = 1 << (4 * config_forward_link);
if ((CheckConfiguration() != UART_MESSAGE_OK)||(CheckAndSetForwardLink(config_forward_link) != UART_MESSAGE_OK)) {
//check & set configuration
config_encoder = 2; //default values = biphase
config_data_rate = 15; //configuration not valid (or uninitialized) => set default values, RF/32
config_delayed = 0;
config_lwr = 8; //lwr
config_raw = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -