?? level2.c
字號:
/*
*-------------------------------------------------------------------------------
*-- RCSId: $Id: level2.c,v 1.33 2004-06-30 12:47:41+02 mjg Exp mjg $
*-- $Name: $
*-------------------------------------------------------------------------------
*-- level2.c - Low level data transforming
*-------------------------------------------------------------------------------
*-- $Log: level2.c,v $*-- 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:27+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:23+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:06+01 mjg
*-- to check SPI
*--
*-- Revision 1.20 2004-02-16 08:04:11+01 mjg
*-- preliminary CD
*--
*-- Revision 1.18 2004-02-10 19:24:40+01 mjg
*-- FSK to add valid bits
*--
*-- Revision 1.17 2004-02-10 18:30:46+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:52+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:37+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:20+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:48+01 mjg
*-- to add dbg code
*--
*-- Revision 1.6 2003-12-09 12:43:01+01 mjg
*-- to 1TS inventory
*--
*-- Revision 1.4 2003-12-09 12:42:44+01 mjg
*-- to 1TS inventory
*--
*-- Revision 1.3 2003-12-05 08:38:56+01 mjg
*-- write update
*--
*-- Revision 1.2 2003-12-04 15:58:08+01 mjg
*-- to write
*--
*-- Revision 1.1 2003-12-01 08:18:04+01 mjg
*-- single carrier low drate level1 ok
*--
*-- Revision 1.0 2003-11-26 09:01:02+01 mjg
*-- Initial revision
*--
*-------------------------------------------------------------------------------
*/
#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 {
// uint8_t capture_data[CAPTURE_SIZE]; //captured and decoded data bits
// uint8_t capture_valid[CAPTURE_SIZE]; //their valid bits
//} capture;
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, -679, -825, -972 }; //for 16MHz clock
uint16_t fwd_flow[9];
//--------------------------------------------------------------
//local variables
#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];
// TCNT1 = -226;
fwd_bit_phase = 8;
// cbi(PORTC, DBG_TRANS);
}
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];
/*
if (debug_mode == 1) {
UDR = fwd_bit_sz;
while (!(UCSRA & (1<<UDRE)))
{}
for(i=0; i<fwd_bit_sz; i++) {
UDR = data_buffer[i];
while (!(UCSRA & (1<<UDRE)))
{}
}
}
*/
// sbi(PORTD, DBG_TRANS);
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();
}
#if 0
//#ifdef DEBUG
cbi(PORTC, DBG_TRANS);
sbi(PORTC, DBG_TRANS);
cbi(PORTC, DBG_TRANS);
#endif
}
// ==================================================================
// EOF send function, assumes valid initialization by SendForward
void SendEOF(void) {
fwd_write_ptr = data_buffer;
fwd_bit_sz = 0;
fwd_bit_phase = 5;
PORTB = PINB ^ (1<<SDA_PIN);
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 )
{}
PORTB = PINB ^ (1<<SDA_PIN);
}
// ==================================================================
// 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
int 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;
}
// ==================================================================
// 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;
if ((decode_number & 1) == 0) { //ASK specific
while (start < end) {
valid = (capture.capture_valid[byte] >> (7-bitcnt)) & 1;
if (valid == 0) return start; //return 1st valid bit position
if (bitcnt == 7) {
bitcnt = 0;
byte++;
} else
bitcnt++;
start++;
}
} else { //FSK specific
if ((capture.capture_data[byte] & 0xF0) == 0x50)
if ((capture.capture_valid[byte] & 0xF0) == 0)
return 3;
if ((capture.capture_data[byte] & 0x78) == 0x28)
if ((capture.capture_valid[byte] & 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;
pom = SearchValidBit( 0, 7 ); //find the first valid bit in 0th byte of capture_valid
if (pom == 255) return size;
start = pom;
#if 0
//#ifdef DEBUG
UDR = size;
while (!(UCSRA & (1<<UDRE)))
{}
UDR = start;
while (!(UCSRA & (1<<UDRE)))
{}
#endif
bitcnt = start % 8; //set the pointers
start = start / 8;
pom = (capture.capture_data[start] >> (7-bitcnt)) & 1; //check the 1st bit is '1'
if (pom != 1) return size;
while (size > 0) {
if (bitcnt == 7) { //increment position to next bit
bitcnt = 0;
start++;
} else
bitcnt++;
pom = (capture.capture_data[start] >> (7-bitcnt)) & 1;
value >>= 1;
if (pom != 0) value |= 0x80;
valid = (capture.capture_valid[start] >> (7-bitcnt)) & 1;
if(valid != 0)
break;
size--;
#if 0
//#ifdef DEBUG
UDR = ptr;
while (!(UCSRA & (1<<UDRE)))
{}
UDR = value;
while (!(UCSRA & (1<<UDRE)))
{}
#endif
data_buffer[ptr/8] = value >> (7-(ptr%8)); //always store the byte (for inventory)
ptr++;
}
return size;
}
// ==================================================================
void WaitCPLD(void) {
int register x = 5;
while(x-->0)
{ asm ( "nop" ); }
}
// ==================================================================
void HWTransaction(uint8_t *data, uint8_t *dst, uint8_t len) {
uint8_t read = 7;
uint8_t byte = 7;
uint8_t cnt = 7;
while (len-->0) {
if (++cnt==8) {
cnt = 0;
byte = *data++;
}
if(byte & 1) SetSDA(); else ResetSDA();
byte >>= 1;
read = (read >> 1) | ((PINB << (7-SDO_PIN)) & 0x80);
if (cnt==7) {
*dst++ = read ^ 0xFF;
}
SetSCK();
WaitCPLD();
ResetSCK();
}
SetSSN();
}
// ==================================================================
void HWSign(uint8_t *data, uint8_t *dst, uint8_t len) {
uint8_t read = 7;
uint8_t byte = 7;
uint8_t cnt = 7;
while (len-->0) {
if (++cnt==8) {
cnt = 0;
byte = *data++;
}
if(byte & 1) SetSDA(); else ResetSDA();
byte >>= 1;
WaitCPLD();
SetSCK();
WaitCPLD();
read = (read >> 1) | ((PINB << (7-SDO_PIN)) & 0x80);
ResetSCK();
if (cnt==7)
*dst++ = read ^ 0xFF;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -