tweaking felica timings to see if it gets better results

This commit is contained in:
iceman1001 2024-04-22 10:41:28 +02:00
parent 5025a18722
commit 4304372858
5 changed files with 141 additions and 46 deletions

View file

@ -29,7 +29,8 @@
// FeliCa timings // FeliCa timings
// minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles // minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles
#ifndef FELICA_REQUEST_GUARD_TIME #ifndef FELICA_REQUEST_GUARD_TIME
# define FELICA_REQUEST_GUARD_TIME (6800/16 + 1) // 426 //# define FELICA_REQUEST_GUARD_TIME (6800 / 16 + 1) // 426
# define FELICA_REQUEST_GUARD_TIME ((512 + 0 * 256) * 64 / 16 + 1)
#endif #endif
// FRAME DELAY TIME 2672 carrier cycles // FRAME DELAY TIME 2672 carrier cycles
#ifndef FELICA_FRAME_DELAY_TIME #ifndef FELICA_FRAME_DELAY_TIME
@ -64,6 +65,11 @@ static uint32_t iso18092_get_timeout(void) {
#define FELICA_MAX_FRAME_SIZE 260 #define FELICA_MAX_FRAME_SIZE 260
#endif #endif
//structure to hold outgoing NFC frame //structure to hold outgoing NFC frame
static uint8_t frameSpace[FELICA_MAX_FRAME_SIZE + 4]; static uint8_t frameSpace[FELICA_MAX_FRAME_SIZE + 4];
@ -122,39 +128,46 @@ static void shiftInByte(uint8_t bt) {
} }
static void Process18092Byte(uint8_t bt) { static void Process18092Byte(uint8_t bt) {
switch (FelicaFrame.state) { switch (FelicaFrame.state) {
case STATE_UNSYNCD: { case STATE_UNSYNCD: {
//almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not always the case // almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not always the case
if (bt > 0) { if (bt > 0) {
FelicaFrame.shiftReg = reflect8(bt); FelicaFrame.shiftReg = reflect8(bt);
FelicaFrame.state = STATE_TRYING_SYNC; FelicaFrame.state = STATE_TRYING_SYNC;
} }
break; break;
} }
case STATE_TRYING_SYNC: { case STATE_TRYING_SYNC: {
if (bt == 0) { if (bt == 0) {
//desync // desync
FelicaFrame.shiftReg = bt; FelicaFrame.shiftReg = bt;
FelicaFrame.state = STATE_UNSYNCD; FelicaFrame.state = STATE_UNSYNCD;
} else { } else {
for (uint8_t i = 0; i < 8; i++) { for (uint8_t i = 0; i < 8; i++) {
if (FelicaFrame.shiftReg == SYNC_16BIT) { if (FelicaFrame.shiftReg == SYNC_16BIT) {
//SYNC done! // SYNC done!
FelicaFrame.state = STATE_GET_LENGTH; FelicaFrame.state = STATE_GET_LENGTH;
FelicaFrame.framebytes[0] = 0xb2; FelicaFrame.framebytes[0] = 0xb2;
FelicaFrame.framebytes[1] = 0x4d; FelicaFrame.framebytes[1] = 0x4d;
FelicaFrame.byte_offset = i; FelicaFrame.byte_offset = i;
//shift in remaining byte, slowly...
// shift in remaining byte, slowly...
for (uint8_t j = i; j < 8; j++) { for (uint8_t j = i; j < 8; j++) {
FelicaFrame.framebytes[2] = (FelicaFrame.framebytes[2] << 1) + (bt & 1); FelicaFrame.framebytes[2] = (FelicaFrame.framebytes[2] << 1) + (bt & 1);
bt >>= 1; bt >>= 1;
} }
FelicaFrame.posCnt = 2; FelicaFrame.posCnt = 2;
if (i == 0) if (i == 0) {
break; break;
} }
}
FelicaFrame.shiftReg = (FelicaFrame.shiftReg << 1) + (bt & 1); FelicaFrame.shiftReg = (FelicaFrame.shiftReg << 1) + (bt & 1);
bt >>= 1; bt >>= 1;
} }
@ -351,16 +364,21 @@ static void BuildFliteRdblk(const uint8_t *idm, uint8_t blocknum, const uint16_t
} }
static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const uint32_t *NYI_timing_NYI, uint8_t power, uint8_t highspeed) { static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const uint32_t *NYI_timing_NYI, uint8_t power, uint8_t highspeed) {
if (NYI_timing_NYI != NULL) { if (NYI_timing_NYI != NULL) {
Dbprintf("Error: TransmitFor18092_AsReader does not check or set parameter NYI_timing_NYI"); Dbprintf("Error: TransmitFor18092_AsReader does not check or set parameter NYI_timing_NYI");
return; return;
} }
uint16_t flags = FPGA_MAJOR_MODE_HF_ISO18092; uint16_t flags = FPGA_MAJOR_MODE_HF_ISO18092;
if (power)
if (power) {
flags |= FPGA_HF_ISO18092_FLAG_READER; flags |= FPGA_HF_ISO18092_FLAG_READER;
if (highspeed) }
if (highspeed) {
flags |= FPGA_HF_ISO18092_FLAG_424K; flags |= FPGA_HF_ISO18092_FLAG_424K;
}
FpgaWriteConfWord(flags); FpgaWriteConfWord(flags);
@ -419,9 +437,13 @@ static void TransmitFor18092_AsReader(const uint8_t *frame, uint16_t len, const
// stop when button is pressed // stop when button is pressed
// or return TRUE when command is captured // or return TRUE when command is captured
bool WaitForFelicaReply(uint16_t maxbytes) { bool WaitForFelicaReply(uint16_t maxbytes) {
if (g_dbglevel >= DBG_DEBUG)
if (g_dbglevel >= DBG_DEBUG) {
Dbprintf("WaitForFelicaReply Start"); Dbprintf("WaitForFelicaReply Start");
}
uint32_t c = 0; uint32_t c = 0;
// power, no modulation // power, no modulation
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
FelicaFrameReset(); FelicaFrameReset();
@ -433,12 +455,19 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
uint32_t timeout = iso18092_get_timeout(); uint32_t timeout = iso18092_get_timeout();
for (;;) { for (;;) {
WDT_HIT(); WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR); b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR);
Process18092Byte(b); Process18092Byte(b);
if (FelicaFrame.state == STATE_FULL) { if (FelicaFrame.state == STATE_FULL) {
felica_nexttransfertime = MAX(felica_nexttransfertime,
felica_nexttransfertime = MAX(
felica_nexttransfertime,
(GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME); (GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME);
LogTrace( LogTrace(
@ -449,10 +478,15 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
NULL, NULL,
false false
); );
if (g_dbglevel >= DBG_DEBUG) Dbprintf("All bytes received! STATE_FULL"); if (g_dbglevel >= DBG_DEBUG) Dbprintf("All bytes received! STATE_FULL");
return true; return true;
} else if (c++ > timeout && (FelicaFrame.state == STATE_UNSYNCD || FelicaFrame.state == STATE_TRYING_SYNC)) { } else if (c++ > timeout && (FelicaFrame.state == STATE_UNSYNCD || FelicaFrame.state == STATE_TRYING_SYNC)) {
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD"); if (g_dbglevel >= DBG_DEBUG) Dbprintf("Error: Timeout! STATE_UNSYNCD");
return false; return false;
} }
} }
@ -478,8 +512,9 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
// DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); // DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
FelicaFrameinit(BigBuf_malloc(FELICA_MAX_FRAME_SIZE)); FelicaFrameinit(BigBuf_malloc(FELICA_MAX_FRAME_SIZE));
felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; felica_nexttransfertime = 2 * DELAY_ARM2AIR_AS_READER; // 418
iso18092_set_timeout(2120); // 106 * 20ms maximum start-up time of card // iso18092_set_timeout(2120); // 106 * 20ms maximum start-up time of card
iso18092_set_timeout(1060); // 106 * 10ms maximum start-up time of card
init_table(CRC_FELICA); init_table(CRC_FELICA);

View file

@ -118,7 +118,9 @@ static size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) {
volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR; volatile uint8_t adc_val = AT91C_BASE_SSC->SSC_RHR;
if (g_logging) logSampleSimple(adc_val); if (g_logging) {
logSampleSimple(adc_val);
}
// Only test field changes if state of adc values matter // Only test field changes if state of adc values matter
if (wait == false) { if (wait == false) {
@ -157,7 +159,10 @@ static size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) {
} }
} }
if (g_logging) logSampleSimple(0xFF); if (g_logging) {
logSampleSimple(0xFF);
}
return 0; return 0;
} }
@ -210,16 +215,18 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) {
sc->averaging = 0; sc->averaging = 0;
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor);
if (reader) { if (reader) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
} else { } else {
if (simulate)
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC);
else
// Sniff
//FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
if (simulate) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC);
} else {
// Sniff
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC);
// FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
}
} }
// Connect the A/D to the peak-detected low-frequency path. // Connect the A/D to the peak-detected low-frequency path.
@ -261,7 +268,9 @@ void lf_init(bool reader, bool simulate, bool ledcontrol) {
uint32_t bufsize = 10000; uint32_t bufsize = 10000;
// use malloc // use malloc
if (g_logging) initSampleBufferEx(&bufsize, true); if (g_logging) {
initSampleBufferEx(&bufsize, true);
}
lf_sample_mean(); lf_sample_mean();
} }

View file

@ -246,12 +246,13 @@ void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool
**/ **/
void LFSetupFPGAForADC(int divisor, bool reader_field) { void LFSetupFPGAForADC(int divisor, bool reader_field) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
if ((divisor == 1) || (divisor < 0) || (divisor > 255)) if ((divisor == 1) || (divisor < 0) || (divisor > 255)) {
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz
else if (divisor == 0) } else if (divisor == 0) {
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
else } else {
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | (reader_field ? FPGA_LF_ADC_READER_FIELD : 0)); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | (reader_field ? FPGA_LF_ADC_READER_FIELD : 0));
@ -623,15 +624,17 @@ void doT55x7Acquisition(size_t sample_size, bool ledcontrol) {
// skip until first high samples begin to change // skip until first high samples begin to change
if (startFound || sample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL) { if (startFound || sample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL) {
// if just found start - recover last sample // if just found start - recover last sample
if (!startFound) { if (startFound == false) {
dest[i++] = lastSample; dest[i++] = lastSample;
startFound = true; startFound = true;
} }
// collect samples // collect samples
if (i < bufsize) {
dest[i++] = sample; dest[i++] = sample;
} }
} }
} }
}
} }
/** /**
* acquisition of Cotag LF signal. Similart to other LF, since the Cotag has such long datarate RF/384 * acquisition of Cotag LF signal. Similart to other LF, since the Cotag has such long datarate RF/384
@ -698,13 +701,15 @@ void doCotagAcquisition(void) {
firstlow = true; firstlow = true;
} }
++i;
if (sample > COTAG_ONE_THRESHOLD) { if (sample > COTAG_ONE_THRESHOLD) {
dest[i] = 255; dest[i] = 255;
++i;
} else if (sample < COTAG_ZERO_THRESHOLD) { } else if (sample < COTAG_ZERO_THRESHOLD) {
dest[i] = 0; dest[i] = 0;
++i;
} else { } else {
dest[i] = dest[i - 1]; dest[i] = dest[i - 1];
++i;
} }
} }
} }

View file

@ -31,67 +31,110 @@ size_t nbytes(size_t nbits) {
} }
//convert hex digit to integer //convert hex digit to integer
uint8_t hex2int(char hexchar) { uint8_t hex2int(char x) {
switch (hexchar) { switch (x) {
case '0': case '0':
return 0; return 0;
break;
case '1': case '1':
return 1; return 1;
break;
case '2': case '2':
return 2; return 2;
break;
case '3': case '3':
return 3; return 3;
break;
case '4': case '4':
return 4; return 4;
break;
case '5': case '5':
return 5; return 5;
break;
case '6': case '6':
return 6; return 6;
break;
case '7': case '7':
return 7; return 7;
break;
case '8': case '8':
return 8; return 8;
break;
case '9': case '9':
return 9; return 9;
break;
case 'a': case 'a':
case 'A': case 'A':
return 10; return 10;
break;
case 'b': case 'b':
case 'B': case 'B':
return 11; return 11;
break;
case 'c': case 'c':
case 'C': case 'C':
return 12; return 12;
break;
case 'd': case 'd':
case 'D': case 'D':
return 13; return 13;
break;
case 'e': case 'e':
case 'E': case 'E':
return 14; return 14;
break;
case 'f': case 'f':
case 'F': case 'F':
return 15; return 15;
break;
default: default:
return 0; return 0;
} }
} }
/*
The following methods comes from Rfidler sourcecode.
https://github.com/ApertureLabsLtd/RFIDler/blob/master/firmware/Pic32/RFIDler.X/src/
*/
// convert hex to sequence of 0/1 bit values
// returns number of bits converted
int hex2binarray(char *target, char *source) {
return hex2binarray_n(target, source, strlen(source));
}
int hex2binarray_n(char *target, char *source, int sourcelen) {
int count = 0;
// process 4 bits (1 hex digit) at a time
while (sourcelen--) {
char x = *(source++);
*(target++) = (x >> 7) & 1;
*(target++) = (x >> 6) & 1;
*(target++) = (x >> 5) & 1;
*(target++) = (x >> 4) & 1;
*(target++) = (x >> 3) & 1;
*(target++) = (x >> 2) & 1;
*(target++) = (x >> 1) & 1;
*(target++) = (x & 1);
count += 8;
}
return count;
}
int binarray2hex(const uint8_t *bs, int bs_len, uint8_t *hex) {
int count = 0;
int byte_index = 0;
// Clear output buffer
memset(hex, 0, bs_len >> 3);
for (int i = 0; i < bs_len; i++) {
// Set the appropriate bit in hex
if (bs[i] == 1) {
hex[byte_index] |= (1 << (7 - (count % 8)));
}
count++;
// Move to the next byte if 8 bits have been filled
if (count % 8 == 0) {
byte_index++;
}
}
return count;
}
void LEDsoff(void) { void LEDsoff(void) {
LED_A_OFF(); LED_A_OFF();
LED_B_OFF(); LED_B_OFF();

View file

@ -82,9 +82,12 @@
#endif #endif
size_t nbytes(size_t nbits); size_t nbytes(size_t nbits);
uint8_t hex2int(char hexchar); uint8_t hex2int(char hexchar);
int hex2binarray(char *target, char *source);
int hex2binarray_n(char *target, char *source, int sourcelen);
int binarray2hex(const uint8_t *bs, int bs_len, uint8_t *hex);
void LED(int led, int ms); void LED(int led, int ms);
void LEDsoff(void); void LEDsoff(void);
void SpinOff(uint32_t pause); void SpinOff(uint32_t pause);