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<