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

📄 main.c

📁 em公司的RFID源程序,适合EM4094,绝对震撼!
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
*-------------------------------------------------------------------------------
*--  RCSId: $Id: main.c,v 1.50 2005-04-12 14:54:27+02 mjg Exp mjg $
*--         $Name:  $
*-------------------------------------------------------------------------------
*-- main.c (level1)
*-------------------------------------------------------------------------------
*-- $Log: main.c,v $*-- Revision 1.50  2005-04-12 14:54:27+02  mjg*-- switch to normal mode*--*-- Revision 1.49  2005-03-21 17:01:05+01  mjg*-- Uplink timing tuned*--*-- Revision 1.47  2005-02-28 13:35:30+01  mjg*-- EM4006 uid crc check*--*-- Revision 1.46  2005-02-25 11:23:13+01  mjg*-- EM4006 extraction routine, no crc check*--*-- Revision 1.44  2005-02-25 09:12:50+01  mjg*-- EM4006 decode mode*--
*-- Revision 1.43  2005-02-23 16:04:15+01  mjg
*-- EM4006 raw mode, not tested
*--
*-- Revision 1.42  2005-02-21 18:13:56+01  mjg
*-- hubneme IV
*--
*-- Revision 1.41  2005-02-21 10:56:31+01  mjg
*-- hubneme III
*--
*-- Revision 1.38  2005-01-19 15:53:52+01  mjg
*-- EM4034 EAS off support corrected
*--
*-- Revision 1.37  2004-12-13 08:49:34+01  mjg
*-- compiler sensitive code in HWTransaction
*--
*-- Revision 1.36  2004-12-07 17:22:17+01  mjg
*-- version 4 of 1TS ready
*--
*-- Revision 1.35  2004-12-07 15:22:21+01  mjg
*-- 1.33 strikes back!
*--
*-- Revision 1.33  2004-06-30 12:47:41+02  mjg
*-- key selection extension
*--
*-- Revision 1.32  2004-05-31 16:41:51+02  mjg
*-- single carrier too slow caused CRC errors, speeded up
*--
*-- Revision 1.31  2004-05-21 09:29:37+02  mjg
*-- startup inventory, to toggle EAS off for EM4034
*--
*-- Revision 1.30  2004-05-10 09:23:28+02  mjg
*-- to toggle EAS off
*--
*-- Revision 1.29  2004-05-07 08:10:25+02  mjg
*-- HW auth passed
*--
*-- Revision 1.28  2004-04-27 17:05:44+02  mjg
*-- to better test the design
*--
*-- Revision 1.27  2004-04-21 15:48:47+02  mjg
*-- FSK low data rate support
*--
*-- Revision 1.26  2004-04-21 13:05:21+02  mjg
*-- EOF ignored because of FSK and 4034 support
*--
*-- Revision 1.25  2004-04-13 11:21:39+02  mjg
*-- sync
*--
*-- Revision 1.24  2004-03-25 16:09:19+01  mjg
*-- to add delayed EOF feature
*--
*-- Revision 1.23  2004-03-25 15:13:24+01  mjg
*-- to add delayed EOF feature
*--
*-- Revision 1.22  2004-03-24 13:35:36+01  mjg
*-- error msg needs better handling
*--
*-- Revision 1.21  2004-03-15 16:59:07+01  mjg
*-- to check SPI
*--
*-- Revision 1.20  2004-02-16 08:04:12+01  mjg
*-- preliminary CD
*--
*-- Revision 1.18  2004-02-10 19:24:41+01  mjg
*-- FSK to add valid bits
*--
*-- Revision 1.17  2004-02-10 18:30:47+01  mjg
*-- dual carrier raw, decoded 1st try
*--
*-- Revision 1.16  2004-02-09 18:03:33+01  mjg
*-- raw dual carrier capture
*--
*-- Revision 1.15  2004-02-08 12:30:53+01  mjg
*-- Decode var removed, FSK polling added
*--
*-- Revision 1.14  2004-02-07 14:59:47+01  mjg
*-- Response parsing correction
*--
*-- Revision 1.13  2004-02-03 08:42:52+01  mjg
*-- hubneme II
*--
*-- Revision 1.12  2004-02-03 07:24:38+01  mjg
*-- fwd debug implemented and removed from being compiled
*--
*-- Revision 1.11  2004-01-19 14:08:05+01  mjg
*-- hubneme I
*--
*-- Revision 1.10  2004-01-14 14:57:35+01  mjg
*-- to Invenotry version 2
*--
*-- Revision 1.9  2003-12-11 17:37:21+01  mjg
*-- yes
*--
*-- Revision 1.8  2003-12-11 16:33:41+01  mjg
*-- 1TS gives too much responses, stayquiet ?
*--
*-- Revision 1.7  2003-12-10 08:15:49+01  mjg
*-- to add dbg code
*--
*-- Revision 1.6  2003-12-09 12:43:01+01  mjg
*-- to 1TS inventory
*--
*-- Revision 1.5  2003-12-09 12:42:44+01  mjg
*-- to 1TS inventory
*--
*-- Revision 1.4  2003-12-05 13:37:16+01  mjg
*-- Reset2Ready, GetSystemInfo
*--
*-- Revision 1.3  2003-12-05 08:38:56+01  mjg
*-- write update
*--
*-- Revision 1.2  2003-12-04 15:58:09+01  mjg
*-- to write
*--
*-- Revision 1.1  2003-12-01 08:18:05+01  mjg
*-- single carrier low drate level1 ok
*--
*-- Revision 1.0  2003-11-26 09:01:03+01  mjg
*-- Initial revision
*--
*-------------------------------------------------------------------------------
*/

#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/wdt.h>

#include "level4.h"
#include "level3.h"
#include "level2.h"

// ==================================================================
// capture variables

uint16_t halfDataRate;                //half period downlink data rate modul
uint8_t pulsesPerBit;                 //8 pulses for low data rate, 32 for high
uint8_t volatile sof;                 //sof and eof indication

uint8_t forward_link_type;            //forward link modulation type

uint8_t decode_number;                //decoder routine number
void (*decode)(void);                 //decoder routine variable

uint16_t last_capture;                //counter1 is now reset at capture start, we make a difference
                                      //between current and last value
register uint8_t currentMaxTimeHi asm ("r10");          //actual hi value of maximum capture time

uint16_t EM4006_bitRate;              //bit rate of EM4006 tag
uint8_t EM4006_scale;                 //scale of EM4006 bit rate 

uint8_t watchdog_reset;               //watchdog activated

// ==================================================================
// level 1 local variables

register uint8_t captured_byte asm ("r6");      //store_bit current capture bits
register uint8_t captured_valid asm ("r7");     //store_bit current capture valid bits
register uint8_t capture_cnt asm ("r8");        //store_bit current capture byte index
register uint8_t captured_bit_count asm ("r9"); //store_bit current capture bit counter

uint8_t bit_pos;                      //bit position in demodulation

uint8_t edge;                         //bit_phase FSK
uint8_t last_valid;                   //last valid value for invalid sequence compression
uint8_t last_z;                       //FSK last pulse number

uint16_t old_capture;                 //one subcarrier variable
uint16_t previous_delay;              //noise delay storage variable

uint8_t pulsesPerBit2;
uint8_t pulsesPerBit3;

#define TOLERANCE (3)

// ==================================================================
// function declarations

void EM4006_polling(void);

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

void avr_ini(void)
{

   // --------------------------------------------------------------- 
   // UART initialization                                             
   // --------------------------------------------------------------- 

   UARTIni();          // level4 uart init routine

   // --------------------------------------------------------------- 
   // 16-bit Timer/Counter1 initialization                            
   // --------------------------------------------------------------- 

   TCCR1A = 0;         // no compare otuput, no PWM mode ...  
   TCCR1B = 0;         // stopped on startup

   // --------------------------------------------------------------- 
   // I/O Ports initialization                                        
   // --------------------------------------------------------------- 

   PORTB = 0;
   PORTC = (1 << DCLK_PIN) | (0 << MOD_PIN);    //set SPI active == EM4094 normal function blocked
   PORTD = 0;                                   //    notmodulation == startup antenna on
                                                //    LED On

   DDRB = 0x02;        // PORTB.0,2-7 as input, PORTB.1 = SDA = output
   DDRC = 0x0F;        // PORTC.(3-0) = (SCK, LED, DCLK, DIN=MOD) = output, rest = input
#ifdef DEBUG
   DDRD = 0x44;        // PORTD.(7,6,2) = (SSN, DBG_TRANS, DBG_FORWARD) = output, rest = input, SSN=off
#else
   DDRD = 0x00;        // PORTD.(7,6,2) = (SSN, DBG_TRANS, DBG_FORWARD) = output, rest = input, SSN=off
#endif
                                           
   // --------------------------------------------------------------- 
   // Watch Dog Setup
   // --------------------------------------------------------------- 
   cbi( MCUCSR, WDRF);  //clear watchdog reset flag
   wdt_enable(0x7);

   // --------------------------------------------------------------- 
   // General Interrupt Enable                                        
   // --------------------------------------------------------------- 

   MCUCR = ((1<<ISC11) | (1<<ISC10));          //INT1 triggered on rising edge
   GICR = 0;                                   //INT0 & INT1 disabled

   sei();                                      // General Interrupt Enable                    
}


// ==================================================================
// R E C E I V E R   C O D E
// ==================================================================

// ---------------------------------------------------------------
// store bit into capture buffer bytes

void store_bit(uint8_t b, uint8_t v)
{
#if 0
def DEBUG
  b &= 1;
  v &= 1;

  PORTD = PIND ^ (1<<DBG_TRANS);
  PORTD = PIND ^ (1<<DBG_TRANS);
//  if (b == 0) cbi(PORTD, DBG_FORWARD); else sbi(PORTD, DBG_FORWARD); // debugging bitval
  if (v == 0) cbi(PORTD, DBG_TRANS); else sbi(PORTD, DBG_TRANS); // debugging bitok
#endif

  captured_byte = (captured_byte << 1) | b;
  captured_valid = (captured_valid << 1) | v;

  if (captured_bit_count == 7) {
    captured_bit_count = 0;

    if (capture_cnt < CAPTURE_SIZE) {
      capture.capture_data[capture_cnt] = captured_byte;
      capture.capture_valid[capture_cnt++] = captured_valid;
    } else {
      TIMSK = 0;                                    //finished, disable all
    }

  } else {
    captured_bit_count++;
  }
}

// ---------------------------------------------------------------
// debug routine stores the captured pulse lengths
// - very bad thing happens here, store_pulse overwrites two arrays
// - thus, capture_data & capture_valid are required placed adjacent
// - note: too much data variables is probably detected by $(OBJTOOL)
// -       warning only

void /*inline*/ store_pulse(uint8_t b)
{
  if (capture_cnt == (2 * CAPTURE_SIZE) - 0x20)         //reserve for message header
    TIMSK = 0;                       //disable all
  else
    capture.capture_data[capture_cnt++] = b;
}

// ==================================================================
// void one_subcarrier_capture(void)

SIGNAL (SIG_INPUT_CAPTURE1)
{

  uint8_t z;
  uint16_t capt, y;
  uint16_t icr;

  icr = ICR1;   

  capt = icr - last_capture;

  if (capt > halfDataRate) {            //quite good pause?

    z = TCNT0;
    TCNT0 = 0;

#ifdef DEBUG
    PORTD = PIND ^ (1<<DBG_FORWARD); // debugging 
#endif
    y = icr - old_capture;     //y

    if (debug_mode != 1) {     //data capture

      capt += previous_delay;
      previous_delay = 0;

      if (z < (uint8_t)(pulsesPerBit-TOLERANCE)) {  //kludge because of noise
        previous_delay = capt;
        store_bit(0, 1);
        store_bit(1, 1);
      } 
      else
      if ((sof == 0) && (z >= (uint8_t)(pulsesPerBit3 - TOLERANCE)) && (z <= (uint8_t)(pulsesPerBit3 + TOLERANCE)))
        sof = 1; 
      else
      if (sof == 1) {
        
        if ((z >= (uint8_t)(pulsesPerBit2 - TOLERANCE)) && (z <= (uint8_t)(pulsesPerBit2 + TOLERANCE))) {
          store_bit(1, 0);
          store_bit(0, 0);
          if (capt < (2*halfDataRate))
            bit_pos = 0;
          else
            bit_pos = 1;
        }
        else
        if ((z >= (uint8_t)(pulsesPerBit-TOLERANCE)) && (z <= (uint8_t)(pulsesPerBit+TOLERANCE))) {
          store_bit(bit_pos, 0);      //0!
          if (capt >= (2*halfDataRate))
            bit_pos = 1;
        }
        else
        if ((z >= (uint8_t)(pulsesPerBit3 - TOLERANCE)) && (z <= (uint8_t)(pulsesPerBit2 + TOLERANCE)) && (capt > (3*halfDataRate))) {
          sof = 2; 
        } else {
          if ((bit_pos == 1) && (z >= (uint8_t)(pulsesPerBit2 + TOLERANCE)))
            store_bit(1, 0);
          store_bit(0, 1);
        }
      } else {
        if ((bit_pos == 1) && (z >= (uint8_t)(pulsesPerBit2 + TOLERANCE)))
          store_bit(1, 0);
        store_bit(0, 1);
      }
    } else {                          //raw capture

      capt >>= 5;
      store_pulse(capt);              //x
      store_pulse(z);

    }

    old_capture = icr;
  }

  last_capture = icr;
}

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

void dual_subcarrier_polling(void) {

  //do not use local register variables

  uint8_t z;
  uint16_t capt;
  uint16_t icr;
  uint8_t toggle;
  uint8_t x;
  uint8_t last_x;
  uint8_t y;
  uint8_t yvld;
  uint8_t correction;

  last_z = TCNT0;

⌨️ 快捷键说明

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