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

📄 level2.c

📁 此程序为利用mage8 AVR 和EM4094实现读取ISO15693类型卡的C程序、读卡稳定、这个项目我们做了好久、非常不错的程序、很适合做这方面产品的朋友们参考
💻 C
字号:


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

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

uint8_t bufferClean = 0;                     //flag for pre-cleaning

struct TCAPTURE capture;

uint8_t * forward_ptr;                       //ptr for forward message preparation

uint8_t data_buffer[ CAPTURE_SIZE ];           //array of forwarded bits XOR clean response data

#ifdef DEBUG
uint16_t solich = 0;
uint16_t offset = 0;
#endif

//uint16_t fwd_delays[7] = { -81, -238, -384, -531, -685, -831, -975 };      //for 16MHz clock
uint16_t fwd_delays[ 7 ] = { -81, -238, -384, -533, -687, -833, -977 };      //for 16MHz clock
uint16_t fwd_flow[ 9 ];

//--------------------------------------------------------------
//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

#define SPI_DELAY  5                          //dummy cycles of WaitSPI 

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 (implements a final state machine)

SIGNAL ( SIG_OVERFLOW1 ) 
{
    if ( forward_link_type == 0x01 )  //1 from 4 type forwardlink
    {          
        switch ( fwd_bit_phase ) 
        {
            case 4 :
                cbi( PORTC , MOD_PIN );

                if ( fwd_bit_sz-- > 0 ) 
                {                   //prepare next bit modulation
                    TCNT1 = fwd_delays[ ( *fwd_write_ptr ) * 2 ];
                    fwd_bit_phase = 5;
                } 
                else 
                {                                 //EOF
                    TCNT1 = fwd_delays[ 1 ];
                    fwd_bit_phase = 8;
                }
                break;

            case 5:
                sbi( PORTC , MOD_PIN );
                TCNT1 = fwd_delays[ 0 ];

                if ( ( *fwd_write_ptr ) == 3 ) 
                {
                    fwd_write_ptr++;
                    fwd_bit_phase = 4;
                }
                else
                    fwd_bit_phase = 6;
                break;

            case 6:
                cbi( PORTC , MOD_PIN );

                TCNT1 = fwd_delays[ 5 - ( ( *fwd_write_ptr++ ) * 2 ) ]; 
                fwd_bit_phase = 4;
                break;

            case 12:                             //standalone EOF
                sbi( PORTC , MOD_PIN );

                TCNT1 = fwd_delays[ 0 ];
                fwd_bit_phase = 13;
                break;

            case 13:
                cbi( PORTC , MOD_PIN );
                TCNT1 = -755;
                fwd_bit_phase = 5;                 //generate 2nd standalone EOF pulse
                break;

            default :
                if ( fwd_bit_phase < 9 ) 
                {
                     TCNT1 = fwd_flow[ fwd_bit_phase ];
                     if ( fwd_bit_phase & 1 ) 
                         cbi( PORTC , MOD_PIN );
                     else
                         sbi( PORTC , MOD_PIN );
                     fwd_bit_phase++;
                } 
                else 
                {
                    TCCR1B = 0;                             //no clock T1
                    cbi( PORTC , MOD_PIN );
        						cbi( TIMSK , TOIE1 );                    //stop 
        						cbi( TIFR , TOV1 );                       //clear pending int
                }
                break;
        }
  
    } 
    else 
    {                                   //invalid modulation type
        TCCR1B = 0;                               //no clock T1
        cbi( TIMSK , TOIE1 );                       //else stop
        cbi( TIFR , TOV1 );                         //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 = data_buffer;
    fwd_bit_sz = fwd_bit_count;
    fwd_bit_phase = 0;

    int i;
    for ( i = 0 ; i < 9 ; i++ )
        fwd_flow[ i ] = fwd_delays[ 0 ];
    fwd_flow[ 1 ] = fwd_delays[ 3 ];
    fwd_flow[ 3 ] = fwd_delays[ 1 ];

    TCNT1 = -256;                            //minimum startup pulse length
    cbi( PORTC , MOD_PIN );                   //notmod pulse
    sbi( TIMSK , TOIE1 );
    TCCR1B = 1;                              //internal clock T1, RUN!

  // waiting for clearing TOIE1 => command sending
    while ( bit_is_set( TIMSK , TOIE1 ) != 0 )
    {
//      SetLEDOff();
//      SetLEDOn();
//      SetLEDOff();
    }
}



// ==================================================================
// prepares data bit pairs
// see EM4x35 uplink spec

uint8_t Prepare_Data( uint8_t data ) 
{
    register uint8_t i;

    for ( i = 0 ; i < 4 ; i++ ) 
    {
        *forward_ptr++ = data & 3;
        data >>= 2;
    }
    return 4;                             //return number of emited bits
}


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

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


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

void WaitSPI(void) {
  int register x = SPI_DELAY;
  while(x-->0)
    {}
}

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

void WriteSPI(uint16_t low, uint16_t hi) {

  int16_t data = low;  
  uint8_t bitcnt = 32;  

  //SPI start event
  cbi(PORTC, MOD_PIN);
  WaitSPI();
  sbi(PORTC, DCLK_PIN);
  WaitSPI();
  sbi(PORTC, MOD_PIN);
  WaitSPI();

  while (bitcnt-- > 0) {

    cbi(PORTC, DCLK_PIN);
    WaitSPI();
  
    if(data & 1) sbi(PORTC, MOD_PIN); else cbi(PORTC, MOD_PIN);
    WaitSPI();
  
    data >>= 1;
    if(bitcnt == 16)
      data = hi;
  
    sbi(PORTC, DCLK_PIN);
    WaitSPI();
  }

  cbi(PORTC, DCLK_PIN);              //for the first time, DCLK is '1', for the next, enable DIN
  WaitSPI();
  cbi(PORTC, MOD_PIN);
}

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

uint16_t CRC( uint8_t * data , uint8_t len )  
{
    uint16_t crc = 0xFFFF;          //CRC preset
    uint8_t i , j , feedback; 
#define crc_poly 0x8408         //CRC polynom

    for ( i = 0 ; i < len ; i++ ) 
    {
        crc ^= *data++;
        for ( j = 0 ; j < 8 ; j++ ) 
        {
            feedback = crc & 1; 
            crc >>= 1;
            if ( feedback )
                crc ^= crc_poly;
        }
    }
    return ~crc;
}


// ==================================================================
// Search 1st valid bit ('1' from SOF)
//   maximum size bits to be searched from start position to end position
//
//  ASK data usually starts at bit position 0 or 1 of captured_data
//  FSK data usually starts at 4th bit position 

uint8_t SearchValidBit( uint8_t start , uint8_t end ) 
{
    uint8_t bitcnt = start % 8;
    uint8_t byte = start / 8;
    uint8_t valid;
    uint8_t *ptr = capture.capture_valid + start / 8;

    if ( ( decode_number & 1 ) == 0 ) //ASK specific
    {              
        while ( start < end ) 
        {     
            valid = ( ( *ptr ) >> ( 7 - bitcnt ) ) & 1;
     
            if ( valid == 0 ) 
            	  return start;  //return 1st valid bit position

            if ( ++bitcnt > 7 ) 
            {
                bitcnt = 0;
                ptr++;
            }
            start++;
        }
    } 
    else 
    {                                    //FSK specific
        valid = capture.capture_data[ byte ];
    
        byte = valid & 0xF0;
        if ( byte == 0x50 ) 
            if ( ( ( *ptr ) & 0xF0 ) == 0 )
                return 3;
        byte = valid & 0x78;
        if ( byte == 0x28 ) 
            if ( ( ( *ptr ) & 0x78 ) == 0 )
                return 4;
    }
    return 255;                               //no valid bit
}


// ==================================================================
// Extracts decoded data to bytes accroding to start position
//   valid start range is < 255 

uint8_t ExtractData( uint8_t size ) 
{
    uint8_t value = 0;
    uint8_t valid;
    uint8_t pom;  
    uint8_t start;
    uint8_t bitcnt;
    uint8_t ptr = 0;  
    uint8_t running_one;
    pom = SearchValidBit( 0 , 7 );             //find the first valid bit in 0th byte of capture_valid
    if ( pom == 255 )
    	  return size;
    start = pom;
 
    bitcnt = start % 8;                                     //set the pointers
    start = start / 8;
    running_one = 1 << ( 7 - bitcnt );

    pom = capture.capture_data[ start ] & running_one;                  //check the 1st bit is '1'

    if ( pom == 0 )
    	  return size;

    while ( size > 0 ) 
    {
        if ( bitcnt == 7 ) //increment position to next bit
        {                                    
            bitcnt = 0;
            running_one = 0x80;
            start++;
        } 
        else 
        {
            bitcnt++;
            running_one >>= 1;
        } 
 
        pom = capture.capture_data[ start ] & running_one;
        value >>= 1;
        if ( pom != 0 ) 
        	  value |= 0x80;      

        valid = capture.capture_valid[ start ] & running_one;
        if ( valid != 0 )
            break;
        size--;
        data_buffer[ ptr / 8 ] = value >> ( 7 - ( ptr & 7 ) );              //always store the byte (for inventory)
        ptr++;
    }
    return size;
}

⌨️ 快捷键说明

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