📄 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 <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <stdio.h>
#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<CAPTURE_SIZE; i++) {
capture_data[i] = 0;
capture_valid[i] = 0xFF;
}
}
// ==================================================================
// Validity Test of data in specified range
uint8_t TestValidRange(uint8_t start, uint8_t size ) {
uint8_t valid = 0;
uint8_t bitcnt = start % 8;
uint8_t pom;
uint8_t ptr = 0;
start = start / 8;
while (ptr < size) {
RO_value_hi <<= 1;
if ((RO_value_low & 0x80000000) != 0) RO_value_hi |= 1;
#if 0
UDR = RO_value_hi >> 24;
while (!(UCSRA & (1<<UDRE)))
{}
#endif
pom = (capture_data[start] >> (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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -