mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
CHG: a better micro second (us) spindely function. At average it has 8-10us delay, but its linear. Making error less when you want to wait longer..
SpinDelayCountUs(20) gives a delay of 28us. SpinDelayCountUs(100) gives a delay of 110us. SpinDelayCountUs(500) gives a delay of 508us.
This commit is contained in:
parent
f72669f366
commit
b4a6775b5e
4 changed files with 116 additions and 107 deletions
152
armsrc/legicrf.c
152
armsrc/legicrf.c
|
@ -63,17 +63,15 @@ static void setup_timer(void) {
|
||||||
//#define RWD_TIME_0 90 /* RWD_TIME_PAUSE off, 40us on = 60us */
|
//#define RWD_TIME_0 90 /* RWD_TIME_PAUSE off, 40us on = 60us */
|
||||||
//#define RWD_TIME_PAUSE 30 /* 20us */
|
//#define RWD_TIME_PAUSE 30 /* 20us */
|
||||||
|
|
||||||
#define RWD_TIME_1 80 /* READER_TIME_PAUSE off, 80us on = 100us */
|
#define RWD_TIME_1 80-4 /* READER_TIME_PAUSE off, 80us on = 100us */
|
||||||
#define RWD_TIME_0 40 /* READER_TIME_PAUSE off, 40us on = 60us */
|
#define RWD_TIME_0 40-4 /* READER_TIME_PAUSE off, 40us on = 60us */
|
||||||
#define RWD_TIME_PAUSE 20 /* 20us */
|
#define RWD_TIME_PAUSE 20-4 /* 20us */
|
||||||
|
|
||||||
#define TAG_BIT_PERIOD 100 // 100us for every bit
|
#define TAG_BIT_PERIOD 100-8 // 100us for every bit
|
||||||
|
|
||||||
#define RWD_TIME_FUZZ 20 /* rather generous 13us, since the peak detector + hysteresis fuzz quite a bit */
|
#define RWD_TIME_FUZZ 20 /* rather generous 13us, since the peak detector + hysteresis fuzz quite a bit */
|
||||||
|
|
||||||
|
#define TAG_TIME_WAIT 330 // 330us from READER frame end to TAG frame start, experimentally determined (490)
|
||||||
//#define TAG_TIME_WAIT 490 /* 490 time from READER frame end to TAG frame start, experimentally determined */
|
|
||||||
#define TAG_TIME_WAIT 258 // 330us from READER frame end to TAG frame start, experimentally determined
|
|
||||||
#define RDW_TIME_WAIT 258 //
|
#define RDW_TIME_WAIT 258 //
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,24 +84,19 @@ static void setup_timer(void) {
|
||||||
|
|
||||||
#ifndef SHORT_COIL
|
#ifndef SHORT_COIL
|
||||||
//#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x)
|
//#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x)
|
||||||
# define SHORT_COIL() LOW(GPIO_SSC_DOUT);
|
# define SHORT_COIL LOW(GPIO_SSC_DOUT);
|
||||||
#endif
|
#endif
|
||||||
#ifndef OPEN_COIL
|
#ifndef OPEN_COIL
|
||||||
//#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x)
|
//#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x)
|
||||||
# define OPEN_COIL() HIGH(GPIO_SSC_DOUT);
|
# define OPEN_COIL HIGH(GPIO_SSC_DOUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t stop_send_frame_us = 0;
|
uint32_t stop_send_frame_us = 0;
|
||||||
|
|
||||||
// ~ 258us + 100us*delay
|
// ~ 258us + 100us*delay
|
||||||
#define WAIT(delay) SpinDelayUs(delay);
|
#define WAIT(delay) SpinDelayCountUs((delay));
|
||||||
#define WAIT_100 WAIT(100)
|
#define COIL_PULSE(x) { SHORT_COIL; WAIT(RWD_TIME_PAUSE); OPEN_COIL; WAIT((x)); }
|
||||||
|
#define COIL_PULSE_PAUSE { SHORT_COIL; WAIT(RWD_TIME_PAUSE); OPEN_COIL; }
|
||||||
#define COIL_PULSE(delay) \
|
|
||||||
SHORT_COIL() \
|
|
||||||
SpinDelayUs(RWD_TIME_PAUSE); \
|
|
||||||
OPEN_COIL() \
|
|
||||||
SpinDelayUs(delay);
|
|
||||||
|
|
||||||
// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces.
|
// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces.
|
||||||
// Historically it used to be FREE_BUFFER_SIZE, which was 2744.
|
// Historically it used to be FREE_BUFFER_SIZE, which was 2744.
|
||||||
|
@ -121,9 +114,22 @@ static void ResetClock(void){
|
||||||
Reset(timer);
|
Reset(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void frame_append_bit(struct legic_frame * const f, int bit) {
|
||||||
|
// Overflow, won't happen
|
||||||
|
if (f->bits >= 31) return;
|
||||||
|
|
||||||
|
f->data |= (bit << f->bits);
|
||||||
|
f->bits++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void frame_clean(struct legic_frame * const f) {
|
||||||
|
f->data = 0;
|
||||||
|
f->bits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Prng works when waiting in 99.1us cycles.
|
// Prng works when waiting in 99.1us cycles.
|
||||||
// and while sending/receiving in bit frames (100, 60)
|
// and while sending/receiving in bit frames (100, 60)
|
||||||
static void CalibratePrng( uint32_t time){
|
/*static void CalibratePrng( uint32_t time){
|
||||||
// Calculate Cycles based on timer 100us
|
// Calculate Cycles based on timer 100us
|
||||||
uint32_t i = (time - stop_send_frame_us) / 100 ;
|
uint32_t i = (time - stop_send_frame_us) / 100 ;
|
||||||
|
|
||||||
|
@ -134,6 +140,7 @@ static void CalibratePrng( uint32_t time){
|
||||||
if ( k > 0 )
|
if ( k > 0 )
|
||||||
legic_prng_forward(k);
|
legic_prng_forward(k);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/* Generate Keystream */
|
/* Generate Keystream */
|
||||||
static uint32_t get_key_stream(int skip, int count)
|
static uint32_t get_key_stream(int skip, int count)
|
||||||
|
@ -205,7 +212,7 @@ static void frame_send_tag(uint16_t response, uint8_t bits, uint8_t crypt) {
|
||||||
else
|
else
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
|
||||||
WAIT_100
|
WAIT(100)
|
||||||
}
|
}
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
}
|
}
|
||||||
|
@ -226,20 +233,20 @@ static void frame_sendAsReader(uint32_t data, uint8_t bits){
|
||||||
|
|
||||||
for (; mask < BITMASK(bits); mask <<= 1) {
|
for (; mask < BITMASK(bits); mask <<= 1) {
|
||||||
if (send & mask) {
|
if (send & mask) {
|
||||||
COIL_PULSE(RWD_TIME_1)
|
COIL_PULSE(RWD_TIME_1);
|
||||||
} else {
|
} else {
|
||||||
COIL_PULSE(RWD_TIME_0)
|
COIL_PULSE(RWD_TIME_0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// One final pause to mark the end of the frame
|
// One final pause to mark the end of the frame
|
||||||
COIL_PULSE(0)
|
COIL_PULSE_PAUSE;
|
||||||
|
|
||||||
// log
|
|
||||||
stop_send_frame_us = GetCountUS();
|
stop_send_frame_us = GetCountUS();
|
||||||
uint8_t cmdbytes[] = {
|
uint8_t cmdbytes[] = {
|
||||||
data & 0xFF,
|
data & 0xFF,
|
||||||
(data >> 8) & 0xFF,
|
(data >> 8) & 0xFF,
|
||||||
|
bits,
|
||||||
lfsr & 0xFF,
|
lfsr & 0xFF,
|
||||||
(lfsr >> 8) & 0xFF,
|
(lfsr >> 8) & 0xFF,
|
||||||
prng1,
|
prng1,
|
||||||
|
@ -271,62 +278,60 @@ static void frame_sendAsReader(uint32_t data, uint8_t bits){
|
||||||
*/
|
*/
|
||||||
static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits, uint8_t crypt) {
|
static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits, uint8_t crypt) {
|
||||||
|
|
||||||
uint32_t starttime = GetCountUS();
|
frame_clean(f);
|
||||||
|
|
||||||
uint8_t i = 0;
|
uint8_t i = 0, edges = 0;
|
||||||
uint32_t the_bit = 1;
|
uint16_t lsfr = 0;
|
||||||
uint32_t next_bit_at;
|
uint32_t the_bit = 1, next_bit_at, data;
|
||||||
uint32_t data;/* Use a bitmask to save on shifts */
|
int old_level = 0, level = 0;
|
||||||
|
|
||||||
int old_level = 0, edges = 0, level = 0;
|
|
||||||
|
|
||||||
if(bits > 32) bits = 32;
|
if(bits > 32) bits = 32;
|
||||||
|
|
||||||
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_DIN;
|
uint32_t starttime = GetCountUS();
|
||||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DIN;
|
|
||||||
|
|
||||||
// calibrate the prng.
|
// calibrate the prng.
|
||||||
// the time between end-of-send and here, div 100us
|
legic_prng_forward(2);
|
||||||
CalibratePrng( starttime );
|
//CalibratePrng( starttime );
|
||||||
|
|
||||||
// precompute the cipher
|
// precompute the cipher
|
||||||
uint8_t prng1 = legic_prng_count() ;
|
uint8_t prng_before = legic_prng_count() ;
|
||||||
|
|
||||||
if(crypt)
|
if(crypt)
|
||||||
data = legic_prng_get_bits(bits);
|
lsfr = legic_prng_get_bits(bits);
|
||||||
|
|
||||||
uint16_t lsfr = data;
|
data = lsfr;
|
||||||
|
|
||||||
// FIXED time between sending frame and now listening frame.
|
next_bit_at = GetCountUS() + TAG_BIT_PERIOD;
|
||||||
WAIT(TAG_TIME_WAIT)
|
|
||||||
//uint32_t iced = GetCountUS() - starttime;
|
|
||||||
//uint32_t icetime = TAG_TIME_WAIT - iced;
|
|
||||||
// if (icetime > TAG_TIME_WAIT)
|
|
||||||
// icetime = TAG_TIME_WAIT;
|
|
||||||
//WAIT( icetime )
|
|
||||||
|
|
||||||
next_bit_at = GetCountUS();
|
//FIXED time between sending frame and now listening frame. 330us
|
||||||
next_bit_at += TAG_BIT_PERIOD;
|
uint32_t icetime = TAG_TIME_WAIT - ( GetCountUS() - stop_send_frame_us );
|
||||||
|
//
|
||||||
|
WAIT( icetime ); // 21.3us inc.
|
||||||
|
|
||||||
|
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_DIN;
|
||||||
|
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DIN;
|
||||||
|
|
||||||
for( i = 0; i < bits; i++) {
|
for( i = 0; i < bits; i++) {
|
||||||
edges = 0;
|
edges = 0;
|
||||||
while ( GetCountUS() < next_bit_at) {
|
while ( GetCountUS() < next_bit_at) {
|
||||||
|
|
||||||
level = AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN;
|
level = (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN);
|
||||||
|
|
||||||
if (level != old_level)
|
if (level != old_level)
|
||||||
edges++;
|
++edges;
|
||||||
|
|
||||||
old_level = level;
|
old_level = level;
|
||||||
}
|
}
|
||||||
next_bit_at += TAG_BIT_PERIOD;
|
next_bit_at += TAG_BIT_PERIOD;
|
||||||
|
|
||||||
// We expect 42 edges == ONE
|
// We expect 42 edges == ONE
|
||||||
if(edges > 20 && edges < 60) {
|
if(edges > 20 && edges < 60)
|
||||||
DbpString("one");
|
|
||||||
data ^= the_bit;
|
data ^= the_bit;
|
||||||
}
|
|
||||||
the_bit <<= 1;
|
the_bit <<= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// output
|
||||||
f->data = data;
|
f->data = data;
|
||||||
f->bits = bits;
|
f->bits = bits;
|
||||||
|
|
||||||
|
@ -334,25 +339,16 @@ static void frame_receiveAsReader(struct legic_frame * const f, uint8_t bits, ui
|
||||||
uint8_t cmdbytes[] = {
|
uint8_t cmdbytes[] = {
|
||||||
(data & 0xFF),
|
(data & 0xFF),
|
||||||
(data >> 8) & 0xFF,
|
(data >> 8) & 0xFF,
|
||||||
|
bits,
|
||||||
(lsfr & 0xFF),
|
(lsfr & 0xFF),
|
||||||
(lsfr >> 8) & 0xFF,
|
(lsfr >> 8) & 0xFF,
|
||||||
prng1,
|
prng_before,
|
||||||
legic_prng_count()
|
legic_prng_count(),
|
||||||
|
icetime & 0xff,
|
||||||
|
(icetime >> 8) & 0xFF
|
||||||
};
|
};
|
||||||
LogTrace(cmdbytes, sizeof(cmdbytes), starttime, GetCountUS(), NULL, FALSE);
|
LogTrace(cmdbytes, sizeof(cmdbytes), starttime, GetCountUS(), NULL, FALSE);
|
||||||
}
|
|
||||||
|
|
||||||
static void frame_append_bit(struct legic_frame * const f, int bit) {
|
|
||||||
// Overflow, won't happen
|
|
||||||
if (f->bits >= 31) return;
|
|
||||||
|
|
||||||
f->data |= (bit << f->bits);
|
|
||||||
f->bits++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void frame_clean(struct legic_frame * const f) {
|
|
||||||
f->data = 0;
|
|
||||||
f->bits = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup pm3 as a Legic Reader
|
// Setup pm3 as a Legic Reader
|
||||||
|
@ -360,7 +356,7 @@ static uint32_t perform_setup_phase_rwd(uint8_t iv) {
|
||||||
|
|
||||||
// Switch on carrier and let the tag charge for 1ms
|
// Switch on carrier and let the tag charge for 1ms
|
||||||
HIGH(GPIO_SSC_DOUT);
|
HIGH(GPIO_SSC_DOUT);
|
||||||
SpinDelay(40);
|
SpinDelay(20);
|
||||||
|
|
||||||
ResetUSClock();
|
ResetUSClock();
|
||||||
|
|
||||||
|
@ -373,8 +369,6 @@ static uint32_t perform_setup_phase_rwd(uint8_t iv) {
|
||||||
// Now both tag and reader has same IV. Prng can start.
|
// Now both tag and reader has same IV. Prng can start.
|
||||||
legic_prng_init(iv);
|
legic_prng_init(iv);
|
||||||
|
|
||||||
frame_clean(¤t_frame);
|
|
||||||
|
|
||||||
frame_receiveAsReader(¤t_frame, 6, 1);
|
frame_receiveAsReader(¤t_frame, 6, 1);
|
||||||
|
|
||||||
// fixed delay before sending ack.
|
// fixed delay before sending ack.
|
||||||
|
@ -401,9 +395,9 @@ static uint32_t perform_setup_phase_rwd(uint8_t iv) {
|
||||||
|
|
||||||
static void LegicCommonInit(void) {
|
static void LegicCommonInit(void) {
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||||
FpgaSetupSsc();
|
FpgaSetupSsc();
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
|
|
||||||
|
|
||||||
/* Bitbang the transmitter */
|
/* Bitbang the transmitter */
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
|
@ -427,11 +421,12 @@ static void switch_off_tag_rwd(void) {
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
SpinDelay(10);
|
SpinDelay(10);
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
set_tracing(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate crc4 for a legic READ command
|
// calculate crc4 for a legic READ command
|
||||||
// 5,8,10 address size.
|
// 5,8,10 address size.
|
||||||
static int LegicCRC(uint16_t byte_index, uint8_t value, uint8_t cmd_sz) {
|
static uint32_t LegicCRC(uint16_t byte_index, uint8_t value, uint8_t cmd_sz) {
|
||||||
crc_clear(&legic_crc);
|
crc_clear(&legic_crc);
|
||||||
uint32_t temp = (value << cmd_sz) | (byte_index << 1) | LEGIC_READ;
|
uint32_t temp = (value << cmd_sz) | (byte_index << 1) | LEGIC_READ;
|
||||||
crc_update(&legic_crc, temp, cmd_sz + 8 );
|
crc_update(&legic_crc, temp, cmd_sz + 8 );
|
||||||
|
@ -443,20 +438,19 @@ static int LegicCRC(uint16_t byte_index, uint8_t value, uint8_t cmd_sz) {
|
||||||
|
|
||||||
int legic_read_byte(int byte_index, int cmd_sz) {
|
int legic_read_byte(int byte_index, int cmd_sz) {
|
||||||
|
|
||||||
int calcCrc = 0;
|
|
||||||
uint8_t byte = 0, crc = 0;
|
uint8_t byte = 0, crc = 0;
|
||||||
|
uint32_t calcCrc = 0;
|
||||||
uint32_t cmd = (byte_index << 1) | LEGIC_READ;
|
uint32_t cmd = (byte_index << 1) | LEGIC_READ;
|
||||||
|
|
||||||
legic_prng_forward(3);
|
legic_prng_forward(3);
|
||||||
WAIT(300)
|
WAIT(TAG_TIME_WAIT)
|
||||||
|
|
||||||
frame_sendAsReader(cmd, cmd_sz);
|
frame_sendAsReader(cmd, cmd_sz);
|
||||||
|
|
||||||
frame_clean(¤t_frame);
|
|
||||||
|
|
||||||
frame_receiveAsReader(¤t_frame, 12, 1);
|
frame_receiveAsReader(¤t_frame, 12, 1);
|
||||||
|
|
||||||
byte = current_frame.data & 0xff;
|
byte = current_frame.data & 0xFF;
|
||||||
|
|
||||||
calcCrc = LegicCRC(byte_index, byte, cmd_sz);
|
calcCrc = LegicCRC(byte_index, byte, cmd_sz);
|
||||||
crc = (current_frame.data >> 8);
|
crc = (current_frame.data >> 8);
|
||||||
|
|
||||||
|
@ -537,7 +531,12 @@ int LegicRfReader(int offset, int bytes, int iv) {
|
||||||
|
|
||||||
int byte_index = 0, cmd_sz = 0, card_sz = 0;
|
int byte_index = 0, cmd_sz = 0, card_sz = 0;
|
||||||
|
|
||||||
if ( MF_DBGLEVEL >= 2) Dbprintf("setting up legic card, IV = %x", iv);
|
if ( MF_DBGLEVEL >= 2) {
|
||||||
|
Dbprintf("setting up legic card, IV = %x", iv);
|
||||||
|
|
||||||
|
Dbprintf("ONE %d ZERO %d PAUSE %d", RWD_TIME_1 , RWD_TIME_0 , RWD_TIME_PAUSE);
|
||||||
|
Dbprintf("TAG BIT PERIOD %d FUZZ %d TAG WAIT TIME %d", TAG_BIT_PERIOD, RWD_TIME_FUZZ, TAG_TIME_WAIT);
|
||||||
|
}
|
||||||
|
|
||||||
LegicCommonInit();
|
LegicCommonInit();
|
||||||
|
|
||||||
|
@ -1682,7 +1681,6 @@ int ice_legic_select_card()
|
||||||
|
|
||||||
GetSamplesForLegicDemod(1000, TRUE);
|
GetSamplesForLegicDemod(1000, TRUE);
|
||||||
|
|
||||||
// frame_clean(¤t_frame);
|
|
||||||
//frame_receiveAsReader(¤t_frame, 6, 1);
|
//frame_receiveAsReader(¤t_frame, 6, 1);
|
||||||
|
|
||||||
legic_prng_forward(1); /* we wait anyways */
|
legic_prng_forward(1); /* we wait anyways */
|
||||||
|
|
|
@ -66,13 +66,13 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t periods, uint3
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
if(*(command++) == '0')
|
if(*(command++) == '0')
|
||||||
SpinDelayUs(period_0);
|
SpinDelayUs(period_0); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
else
|
else
|
||||||
SpinDelayUs(period_1);
|
SpinDelayUs(period_1); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
}
|
}
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
SpinDelayUs(delay_off);
|
SpinDelayUs(delay_off); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||||
|
|
||||||
|
@ -228,17 +228,17 @@ void WriteTIbyte(uint8_t b)
|
||||||
if (b&(1<<i)) {
|
if (b&(1<<i)) {
|
||||||
// stop modulating antenna
|
// stop modulating antenna
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
SpinDelayUs(1000);
|
SpinDelayUs(1000); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
// modulate antenna
|
// modulate antenna
|
||||||
HIGH(GPIO_SSC_DOUT);
|
HIGH(GPIO_SSC_DOUT);
|
||||||
SpinDelayUs(1000);
|
SpinDelayUs(1000); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
} else {
|
} else {
|
||||||
// stop modulating antenna
|
// stop modulating antenna
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
SpinDelayUs(300);
|
SpinDelayUs(300); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
// modulate antenna
|
// modulate antenna
|
||||||
HIGH(GPIO_SSC_DOUT);
|
HIGH(GPIO_SSC_DOUT);
|
||||||
SpinDelayUs(1700);
|
SpinDelayUs(1700); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,7 +437,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
||||||
if (gap) {
|
if (gap) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
SHORT_COIL();
|
SHORT_COIL();
|
||||||
SpinDelayUs(gap);
|
SpinDelayUs(gap); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1116,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||||
* Q5 tags seems to have issues when these values changes.
|
* Q5 tags seems to have issues when these values changes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
|
#define START_GAP 50*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
|
||||||
#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
|
#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
|
||||||
#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
|
#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
|
||||||
#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550
|
#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550
|
||||||
|
@ -1144,7 +1144,7 @@ void TurnReadLFOn(int delay) {
|
||||||
//int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
|
//int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
|
||||||
// where to save it
|
// where to save it
|
||||||
|
|
||||||
SpinDelayUs(delay);
|
SpinDelayUs(delay); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write one bit to card
|
// Write one bit to card
|
||||||
|
@ -1154,7 +1154,7 @@ void T55xxWriteBit(int bit) {
|
||||||
else
|
else
|
||||||
TurnReadLFOn(WRITE_1);
|
TurnReadLFOn(WRITE_1);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelayUs(WRITE_GAP);
|
SpinDelayUs(WRITE_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send T5577 reset command then read stream (see if we can identify the start of the stream)
|
// Send T5577 reset command then read stream (see if we can identify the start of the stream)
|
||||||
|
@ -1168,7 +1168,7 @@ void T55xxResetRead(void) {
|
||||||
|
|
||||||
// Trigger T55x7 in mode.
|
// Trigger T55x7 in mode.
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelayUs(START_GAP);
|
SpinDelayUs(START_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
|
|
||||||
// reset tag - op code 00
|
// reset tag - op code 00
|
||||||
T55xxWriteBit(0);
|
T55xxWriteBit(0);
|
||||||
|
@ -1198,7 +1198,7 @@ void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg)
|
||||||
|
|
||||||
// Trigger T55x7 in mode.
|
// Trigger T55x7 in mode.
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelayUs(START_GAP);
|
SpinDelayUs(START_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
|
|
||||||
// Opcode 10
|
// Opcode 10
|
||||||
T55xxWriteBit(1);
|
T55xxWriteBit(1);
|
||||||
|
@ -1247,17 +1247,18 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
||||||
bool RegReadMode = (Block == 0xFF);
|
bool RegReadMode = (Block == 0xFF);
|
||||||
|
|
||||||
//clear buffer now so it does not interfere with timing later
|
//clear buffer now so it does not interfere with timing later
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
//make sure block is at max 7
|
//make sure block is at max 7
|
||||||
Block &= 0x7;
|
Block &= 0x7;
|
||||||
|
|
||||||
// Set up FPGA, 125kHz to power up the tag
|
// Set up FPGA, 125kHz to power up the tag
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(95, true);
|
||||||
|
SpinDelay(3);
|
||||||
|
|
||||||
// Trigger T55x7 Direct Access Mode with start gap
|
// Trigger T55x7 Direct Access Mode with start gap
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelayUs(START_GAP);
|
SpinDelayUs(START_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
|
|
||||||
// Opcode 1[page]
|
// Opcode 1[page]
|
||||||
T55xxWriteBit(1);
|
T55xxWriteBit(1);
|
||||||
|
@ -1273,8 +1274,8 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
||||||
|
|
||||||
// Send Block number (if direct access mode)
|
// Send Block number (if direct access mode)
|
||||||
if (!RegReadMode)
|
if (!RegReadMode)
|
||||||
for (i = 0x04; i != 0; i >>= 1)
|
for (i = 0x04; i != 0; i >>= 1)
|
||||||
T55xxWriteBit(Block & i);
|
T55xxWriteBit(Block & i);
|
||||||
|
|
||||||
// Turn field on to read the response
|
// Turn field on to read the response
|
||||||
TurnReadLFOn(READ_GAP);
|
TurnReadLFOn(READ_GAP);
|
||||||
|
@ -1297,7 +1298,7 @@ void T55xxWakeUp(uint32_t Pwd){
|
||||||
|
|
||||||
// Trigger T55x7 Direct Access Mode
|
// Trigger T55x7 Direct Access Mode
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
SpinDelayUs(START_GAP);
|
SpinDelayUs(START_GAP); // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
|
|
||||||
// Opcode 10
|
// Opcode 10
|
||||||
T55xxWriteBit(1);
|
T55xxWriteBit(1);
|
||||||
|
@ -1628,20 +1629,20 @@ void SendForward(uint8_t fwd_bit_count) {
|
||||||
fwd_bit_sz--; //prepare next bit modulation
|
fwd_bit_sz--; //prepare next bit modulation
|
||||||
fwd_write_ptr++;
|
fwd_write_ptr++;
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||||
SpinDelayUs(55*8); //55 cycles off (8us each)for 4305
|
SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
|
||||||
SpinDelayUs(16*8); //16 cycles on (8us each)
|
SpinDelayUs(16*8); //16 cycles on (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
|
|
||||||
// now start writting
|
// now start writting
|
||||||
while(fwd_bit_sz-- > 0) { //prepare next bit modulation
|
while(fwd_bit_sz-- > 0) { //prepare next bit modulation
|
||||||
if(((*fwd_write_ptr++) & 1) == 1)
|
if(((*fwd_write_ptr++) & 1) == 1)
|
||||||
SpinDelayUs(32*8); //32 cycles at 125Khz (8us each)
|
SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
else {
|
else {
|
||||||
//These timings work for 4469/4269/4305 (with the 55*8 above)
|
//These timings work for 4469/4269/4305 (with the 55*8 above)
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||||
SpinDelayUs(23*8); //16-4 cycles off (8us each)
|
SpinDelayUs(23*8); //16-4 cycles off (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
|
||||||
SpinDelayUs(9*8); //16 cycles on (8us each)
|
SpinDelayUs(9*8); //16 cycles on (8us each) // ICEMAN: problem with (us) clock is 21.3us increments
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,10 +236,11 @@ int BUTTON_HELD(int ms) {
|
||||||
// attempt at high resolution microsecond timer
|
// attempt at high resolution microsecond timer
|
||||||
// beware: timer counts in 21.3uS increments (1024/48Mhz)
|
// beware: timer counts in 21.3uS increments (1024/48Mhz)
|
||||||
void SpinDelayUs(int us) {
|
void SpinDelayUs(int us) {
|
||||||
int ticks = (48*us) >> 10;
|
int ticks = (48 * us) >> 10;
|
||||||
|
|
||||||
// Borrow a PWM unit for my real-time clock
|
// Borrow a PWM unit for my real-time clock
|
||||||
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
|
||||||
|
|
||||||
// 48 MHz / 1024 gives 46.875 kHz
|
// 48 MHz / 1024 gives 46.875 kHz
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
|
||||||
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
|
||||||
|
@ -352,7 +353,6 @@ uint32_t RAMFUNC GetCountUS(){
|
||||||
// By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548
|
// By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548
|
||||||
//return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV * 2) / 3);
|
//return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV * 2) / 3);
|
||||||
return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV << 1) / 3);
|
return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV << 1) / 3);
|
||||||
//return (AT91C_BASE_TC1->TC_CV << 16) | ((AT91C_BASE_TC0->TC_CV << 1) / 3);
|
|
||||||
}
|
}
|
||||||
void ResetUSClock(void) {
|
void ResetUSClock(void) {
|
||||||
//enable clock of timer and software trigger
|
//enable clock of timer and software trigger
|
||||||
|
@ -360,7 +360,16 @@ void ResetUSClock(void) {
|
||||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||||
while (AT91C_BASE_TC1->TC_CV >= 1);
|
while (AT91C_BASE_TC1->TC_CV >= 1);
|
||||||
}
|
}
|
||||||
|
// attempt at high resolution microsecond timer
|
||||||
|
// beware: timer counts in 21.3uS increments (1024/48Mhz)
|
||||||
|
void SpinDelayCountUs(uint32_t us) {
|
||||||
|
|
||||||
|
us += GetCountUS();
|
||||||
|
us -= 6;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
if ( GetCountUS() >= us ) return;
|
||||||
|
}
|
||||||
// static uint32_t GlobalUsCounter = 0;
|
// static uint32_t GlobalUsCounter = 0;
|
||||||
|
|
||||||
// uint32_t RAMFUNC GetDeltaCountUS(){
|
// uint32_t RAMFUNC GetDeltaCountUS(){
|
||||||
|
|
|
@ -65,6 +65,7 @@ uint32_t RAMFUNC GetTickCount();
|
||||||
void StartCountUS();
|
void StartCountUS();
|
||||||
uint32_t RAMFUNC GetCountUS();
|
uint32_t RAMFUNC GetCountUS();
|
||||||
void ResetUSClock(void);
|
void ResetUSClock(void);
|
||||||
|
void SpinDelayCountUs(uint32_t us);
|
||||||
//uint32_t RAMFUNC GetDeltaCountUS();
|
//uint32_t RAMFUNC GetDeltaCountUS();
|
||||||
|
|
||||||
void StartCountSspClk();
|
void StartCountSspClk();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue