📄 level2.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 + -