⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 level3.c

📁 EM推出的可读写卡片EM4469
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*-------------------------------------------------------------------------------
*--  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 + -