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

📄 level2.c

📁 此程序为利用mage8 AVR 和EM4094实现读取TYPE B类型卡的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;                         //flag for pre-cleaning
uint8_t * forward_ptr;                       //ptr for forward message preparation
uint8_t data_buffer[ CAPTURE_SIZE ];           //array of forwarded bits XOR clean response data

//--------------------------------------------------------------
//local variables

#define SPI_DELAY 5                          //dummy cycles of WaitSPI 

uint8_t * fwd_write_ptr;                     //forwardlink bit pointer


//aliases
#define fwd_bit_sz captured_byte
#define fwd_byte_bit_cnt captured_valid
#define fwd_byte captured_bit_count

//----------------------------------------------------------------
//Local functions
void ClearCaptureBuffers( void );
uint16_t CRC( uint8_t *data , uint8_t len );
uint8_t ExtractTypeBData( uint8_t size );
uint8_t Prepare_Data( uint8_t data , uint8_t msg_size );
uint8_t Prepare_EOF( uint8_t msg_size );
uint8_t Prepare_SOF( void );
void SendForward( uint8_t fwd_bit_count );
void ShiftFwdData( uint8_t data , uint8_t cnt );
void WaitSPI( void );
void WriteSPI( uint16_t low , uint16_t hi );

// ==================================================================
// Forward link interrupt routine (implements a final state machine)

SIGNAL ( SIG_OVERFLOW1 ) 
{
    if ( fwd_bit_sz-- == 0 ) 
    {                  //prepare next bit modulation
        TCCR1B = 0;                            //no clock T1
        cbi( TIMSK , TOIE1 );                   //stop 
        cbi( TIFR , TOV1 );                     //clear pending int
        return;
    }
    if ( forward_link_type == 0x01 )  //type B forwardlink (PCD -> PICC),
    {    
        TCNT1 = fwd_B_timing;

        if ( fwd_byte & 1 ) 
        	  cbi( PORTC , MOD_PIN ); 
        else 
        	  sbi( PORTC , MOD_PIN );
    
        fwd_byte >>= 1; 

        if ( --fwd_byte_bit_cnt == 0 ) 
        {
            fwd_byte_bit_cnt = 8;
            fwd_byte = *fwd_write_ptr++;
        }
    } 
}


// ==================================================================
// 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_byte = *fwd_write_ptr++;
    fwd_byte_bit_cnt = 8;
    fwd_bit_sz = fwd_bit_count;
    uint16_t i;
    //type B

    for ( i = 0 ; i < 200 ; i++ ) 
    {
        sbi( PORTC , MOD_PIN );                     //mod pulse
    }
    TCNT1 = -316;                            //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 )
    { }

//  if (forward_link_type == 0x01) {
    for ( i = 0 ; i < 200 ; i++ ) 
    {
        sbi( PORTC , MOD_PIN );                 //mod EOF pulse
    }
//  }
    cbi( PORTC , MOD_PIN );                   //notmod pulse
}




// ==================================================================
// shift fwd data

void ShiftFwdData( uint8_t data , uint8_t cnt ) 
{
    uint8_t i;
    for ( i = 0 ; i < cnt ; i++ ) 
    {
        fwd_byte |= ( data & 1 ) << fwd_byte_bit_cnt++;
        data >>= 1;
        if ( fwd_byte_bit_cnt == 8 ) 
        {
            *forward_ptr++ = fwd_byte;
            fwd_byte_bit_cnt = 0;
            fwd_byte = 0;
        }
    }
    *forward_ptr = fwd_byte;             //store in all cases
}


// ==================================================================
// prepares SOF

uint8_t Prepare_SOF( void ) 
{
    forward_ptr = data_buffer;
    fwd_byte = 0;
    fwd_byte_bit_cnt = 0;

    return 0;                               //return number of emited bits
}

// ==================================================================
// prepares data bits for sending

uint8_t Prepare_Data( uint8_t data , uint8_t msg_size ) 
{
    //Type B
    ShiftFwdData( 0 , 1 );

    ShiftFwdData( data , 8 );

    ShiftFwdData( 3 , 2 );
    return 11;                             //return number of emited bits

}

// ==================================================================
// prepares EOF

uint8_t Prepare_EOF( uint8_t msg_size ) 
{
    return 0;
}

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

void ClearCaptureBuffers( void ) 
{
    uint8_t i;
    for( i = 0 ; i < 200 ; i++ )
    raw_data[ i ] = 0 ;
    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
    int8_t i , j;
    const uint16_t poly = 0x8408; //CRC polynom

    for ( i = 0 ; i < len ; i++ ) 
    {
        crc ^= data[ i ];
        for ( j = 0 ; j < 8 ; j++ )
        {
            if ( crc & 1 )
                crc = ( crc >> 1 ) ^ poly;
            else
                crc = ( crc >> 1 );
        }
    }
    return ~crc;
}





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

#define RAW_DATA_START 0

uint8_t ExtractTypeBData( uint8_t size ) 
{
    uint8_t value = 0;
    uint8_t pom;  
    uint8_t phase;  
    uint8_t phase_position;  
    uint8_t start;
    uint8_t ptr = 0; 
    start = 0;
    phase = phase_position = 0;

    while ( size > 0 ) 
    {  
        pom = raw_data[ start ];
        value >>= 1;
        if ( pom != 0 )
        	  value |= 0x80;  
        size--;
        start++;

        if ( phase == 0 ) 
        {                                //SOF check
            if ( pom != 0 ) 
            	  break;      
            if ( phase_position++ == 9 ) 
            {
                phase = 1;
                phase_position = 0;
            }
        } 
        else if ( phase == 1 ) 
        {                                //extra guard time and frame EOF skip
            if ( pom == 0 ) 
            {
                if ( phase_position == 0 ) 
                	  break;              //is zero => error
                phase = 2;
                phase_position = 0;
            } 
            else 
                phase_position++;   
        } 
        else if ( phase == 2 ) 
        {
            if ( phase_position++ == 7 ) 
            {
                data_buffer[ ptr / 8 ] = value;                 //store the byte
                phase = 1;
                phase_position = 0;
            }
            ptr++;
        }
    }
    return ptr;
}

⌨️ 快捷键说明

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