www.pudn.com > EM4469firmware.zip > level2.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  
#include  
#include  
#include  
#include  
#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> 24; 
    while (!(UCSRA & (1<> (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; 
}