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

📄 level2.c

📁 EM推出的可读写卡片EM4469
💻 C
字号:
/*
*-------------------------------------------------------------------------------
*--  RCSId: $Id: level2.c,v 0.17 2003-10-10 10:55:33+02 mjg Exp mjg $
*--         $Name:  $
*-------------------------------------------------------------------------------
*-- level2.c - Low level data transforming 
*-------------------------------------------------------------------------------
*-- $Log: level2.c,v $*-- Revision 0.17  2003-10-10 10:55:33+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:27+02  mjg*-- *** empty log message ****--
*-- Revision 0.11  2003-07-22 13:27:28+02  mjg
*-- cloned firmware
*--
*-------------------------------------------------------------------------------
*/

#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <stdio.h>
#include "level4.h"
#include "level3.h"
#include "level2.h"
#include "level1.h"

//--------------------------------------------------------------
//global variables

uint8_t capture_data[CAPTURE_SIZE];          //maximum bytes captured at once
uint8_t capture_valid[CAPTURE_SIZE];         //their valid bits

uint8_t forwardLink_data[64];                //array of forwarded bits 
uint8_t * forward_ptr;                       //ptr for forward message preparation

uint8_t fwd_1st_pulse = 256 - 24;            //24 ~ 200us
uint8_t fwd_01_stop   = 256 - 12;            //12 ~ 100us
uint8_t fwd_01_one    = 256 - 32;            //notmod full period '1'
uint8_t fwd_01_zero   = 256 - 20;            //complement to fwd_01_stop
  
//--------------------------------------------------------------
//local variables

volatile uint8_t fwd_bit_phase;              //forwardlink bit phase
uint8_t fwd_bit_sz;                          //forwardlink bit counter
uint8_t * fwd_write_ptr;                     //forwardlink bit pointer

uint8_t field_stop;                          //next field stop in RF clocks

// ==================================================================
// Forward link interrupt routine

SIGNAL (SIG_OVERFLOW0) {

  if (forward_link_type == 0x01) {           //EM4050 forwardlink
    if (fwd_bit_phase == 1) {                //mod pulse '0'
      sbi( PORTC, MOD_PIN );                       
      TCNT0 = field_stop;
      field_stop = fwd_01_stop;              //mod pulse
      fwd_bit_phase = 2;
      return;
    }

    cbi( PORTC, MOD_PIN );                   //notmod pulse or period
  
    if (fwd_bit_phase == 2)                  //notmod pulse '0'
      TCNT0 = fwd_01_zero;
    else
      TCNT0 = fwd_01_one;                    //notmod period '1'

    if(fwd_bit_sz-- > 0) {                   //prepare next bit modulation
      if(((*fwd_write_ptr++) & 1) == 1) 
        fwd_bit_phase = 3;
      else
        fwd_bit_phase = 1;
    } else {
      TCCR0 = 0;                             //no clock T0
      sbi(TIMSK, TICIE1);                    //enable capture
      cbi(TIMSK, TOIE0 );                    //stop 
      cbi(TIFR, TOV0);                       //clear pending int
    }
  } else {                                   //invalid modulation type
    TCCR0 = 0;                               //no clock T0
    sbi(TIMSK, TICIE1);                      
    cbi(TIMSK, TOIE0);                       //else stop
    cbi(TIFR, TOV0);                         //clear pending int
  };
}


// ==================================================================
// Forward Link setup function
// Requires: forwarLink_data filled with valid bits (1 bit per byte)
//           fwd_bit_count set with number of bits to be sent

void SendForward(uint8_t fwd_bit_count) {

  fwd_write_ptr = forwardLink_data;
  fwd_bit_sz = fwd_bit_count;
  fwd_bit_phase = 3;
  field_stop = fwd_1st_pulse;
  TCNT0 = 1;                               //minimum startup pulse length
  cbi( PORTC, MOD_PIN );                   //notmod pulse
  cbi(TIMSK, TICIE1);                      //disable capture
  sbi(TIMSK, TOIE0);
  TCCR0 = 7;                               //external clock T0. rising edge, RUN!

  // waiting for clearing TOIE0 => command sending
  while ( bit_is_set(TIMSK, TOIE0) == 1 )
    {
      SetLEDOff();
      SetLEDOn();
      SetLEDOff();
    }
}


// ==================================================================
// prepares command bits
// see EM4469 spec

uint8_t Prepare_Cmd( uint8_t cmd ) {

  register uint8_t line_parity;

  if (forward_link_type == 0x01) {
    *forward_ptr++ = 0;               //start bit
    *forward_ptr++ = 0;               //second pause for 4050 code
  }

  *forward_ptr++ = cmd;
  line_parity = cmd;
  cmd >>= 1;
  *forward_ptr++ = cmd;
  line_parity ^= cmd;
  cmd >>= 1;
  *forward_ptr++ = cmd;
  line_parity ^= cmd;
  *forward_ptr++ = (line_parity & 1);

  if (forward_link_type == 0x01)
    return 6;                         //second pause for 4050 code

  return 4;                           //return number of emited bits
}

// ==================================================================
// prepares address bits
// see EM4469 spec

uint8_t Prepare_Addr( uint8_t addr ) {

  register uint8_t line_parity;

  *forward_ptr++ = addr;
  line_parity = addr;
  addr >>= 1;  
  *forward_ptr++ = addr;
  line_parity ^= addr;
  addr >>= 1;  
  *forward_ptr++ = addr;
  line_parity ^= addr;
  addr >>= 1;  
  *forward_ptr++ = addr;
  line_parity ^= addr;
  *forward_ptr++ = 0;
  *forward_ptr++ = 0;
  *forward_ptr++ = (line_parity & 1);

  return 7;                      //return number of emited bits
}

// ==================================================================
// prepares data bits intreleaved with parity bits
// see EM4469 spec

uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) {

  register uint8_t line_parity;
  register uint8_t column_parity;
  register uint8_t i, j;
  register uint16_t data;

  data = data_low;
  column_parity = 0;

  for(i=0; i<4; i++) {
    line_parity = 0;
    for(j=0; j<8; j++) {
      line_parity ^= data;
      column_parity ^= (data & 1) << j;
      *forward_ptr++ = data;
      data >>= 1;
    }
    *forward_ptr++ = line_parity;
    if(i == 1)
      data = data_hi;
  }

  for(j=0; j<8; j++) {
    *forward_ptr++ = column_parity;
    column_parity >>= 1;
  }
  *forward_ptr = 0;

  return 45;                             //return number of emited bits
}


// ==================================================================
// Search pattern (max 32b (31.bit is first))
//   length is specified by mask
//   maximum size bits to be searched from start position
//   returns last position of valid pattern found or 0 if unsuccessful

uint8_t SearchPattern( uint32_t pattern, uint32_t mask, uint8_t start, uint8_t size ) {

  uint32_t value = 0;
  uint32_t valid = 0xFFFFFFFF;
  
  uint8_t bitcnt = start % 8;
  
  uint8_t pom;

  start = start / 8;

  while (size > 0) {
     
    pom = (capture_data[start] >> (7-bitcnt)) & 1;
    value = (value << 1) | pom;      
    valid = (valid << 1) | ((capture_valid[start] >> (7-bitcnt)) & 1);

    size--;
    if (bitcnt == 7) {
      bitcnt = 0;
      start++;
    } else
      bitcnt++;

    if( ((value & mask ) == pattern) && ((valid & mask) == 0)) {  //test pattern match
      return (start*8 + bitcnt);                       //return the (next) position 
    }

  }

  return 0;
}


// ==================================================================
// Extract data
//   length is specified by mask
//   maximum size bits to be extracted from start position

uint8_t ExtractData( uint8_t start ) {

  register uint8_t line_parity;
  register uint8_t column_parity;
  register uint8_t i, j;
  register uint16_t data;
  uint8_t ptr;
  uint8_t valid;

  uint8_t bitcnt = start % 8; 
  uint8_t pom;

  bitcnt = start % 8; 
  ptr = start / 8;

  data = 0;
  column_parity = 0;
  line_parity = 0;
  valid = 0;

  for(i=0; i<5; i++) {
  
    for(j=0; j<8; j++) {  

      pom = (capture_data[ptr] >> (7-bitcnt)) & 1;       //get bit
      valid += (capture_valid[ptr] >> (7-bitcnt)) & 1;   //count any error bits

      if (bitcnt == 7) {
        bitcnt = 0;
        ptr++;
      } else
        bitcnt++;
      
      data = data >> 1;
      if (pom != 0)
        data |= 0x8000;
    }

    valid += (capture_valid[ptr] >> (7-bitcnt)) & 1;     //skip parities

    if (bitcnt == 7) {
      bitcnt = 0;
      ptr++;
    } else
      bitcnt++;

    if(i == 1)
      read_tag_memory_word_low = data;
    if(i == 3)
      read_tag_memory_word_hi = data;
  }

  if (valid != 0)
    return ERR_EM4469_FLOWLINK_ERR;

  forward_ptr = forwardLink_data;
  Prepare_Data( read_tag_memory_word_low, read_tag_memory_word_hi );
  forward_ptr = forwardLink_data;

  bitcnt = start % 8; 
  ptr = start / 8;

  for(i=0; i<5; i++) {
    for(j=0; j<9; j++) {  

      pom = (capture_data[ptr] >> (7-bitcnt)) & 1;       //get bit
      if (bitcnt == 7) {
        bitcnt = 0;
        ptr++;
      } else
        bitcnt++;
      
      if ( pom != ((*forward_ptr++)&1) )
        return ERR_EM4469_PARITY_ERR;
    }
  }

  return UART_MESSAGE_OK;
}


// ==================================================================

void SetLEDOn(void) {
  cbi( PORTC, LED_PIN);
}

void SetLEDOff(void) {
  sbi( PORTC, LED_PIN);
}

// ==================================================================

void ClearCaptureBuffers(void) {
  uint8_t i;
  for(i=0; i<CAPTURE_SIZE; i++) {
    capture_data[i] = 0;
    capture_valid[i] = 0xFF;
  }
}

// ==================================================================
// Validity Test of data in specified range

uint8_t TestValidRange(uint8_t start, uint8_t size ) {

  uint8_t valid = 0;
  uint8_t bitcnt = start % 8;
  
  uint8_t pom;
  uint8_t ptr = 0;

  start = start / 8;

  while (ptr < size) {
     
    RO_value_hi <<= 1;
    if ((RO_value_low & 0x80000000) != 0) RO_value_hi |= 1;

#if 0
    UDR = RO_value_hi >> 24;
    while (!(UCSRA & (1<<UDRE)))
      {} 
#endif

    pom = (capture_data[start] >> (7-bitcnt)) & 1;
    RO_value_low = (RO_value_low << 1) | pom;
    valid = valid | ((capture_valid[start] >> (7-bitcnt)) & 1);

    ptr++;
    if (bitcnt == 7) {
      bitcnt = 0;
      start++;
    } else
      bitcnt++;
  }

  if (valid == 0)
    return 1;
  else
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -