Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

speedup 'hf mf chk' #901

Merged
merged 6 commits into from
Jan 9, 2020
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 37 additions & 59 deletions armsrc/iso14443a.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,7 @@ const bool Mod_Miller_LUT[] = {
#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])

static void UartReset()
{
static void UartReset() {
Uart.state = STATE_UNSYNCD;
Uart.bitCount = 0;
Uart.len = 0; // number of decoded data bytes
Expand All @@ -280,8 +279,7 @@ static void UartReset()
Uart.parityBits = 0; // holds 8 parity bits
}

static void UartInit(uint8_t *data, uint8_t *parity)
{
static void UartInit(uint8_t *data, uint8_t *parity) {
Uart.output = data;
Uart.parity = parity;
Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits
Expand All @@ -291,8 +289,7 @@ static void UartInit(uint8_t *data, uint8_t *parity)
}

// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
{
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {

Uart.fourBits = (Uart.fourBits << 8) | bit;

Expand Down Expand Up @@ -447,8 +444,7 @@ const bool Mod_Manchester_LUT[] = {
#define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)])


static void DemodReset()
{
static void DemodReset() {
Demod.state = DEMOD_UNSYNCD;
Demod.len = 0; // number of decoded data bytes
Demod.parityLen = 0;
Expand All @@ -461,16 +457,14 @@ static void DemodReset()
Demod.endTime = 0;
}

static void DemodInit(uint8_t *data, uint8_t *parity)
{
static void DemodInit(uint8_t *data, uint8_t *parity) {
Demod.output = data;
Demod.parity = parity;
DemodReset();
}

// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time)
{
static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) {

Demod.twoBits = (Demod.twoBits << 8) | bit;

Expand Down Expand Up @@ -729,8 +723,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
//-----------------------------------------------------------------------------
// Prepare tag messages
//-----------------------------------------------------------------------------
static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity)
{
static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity) {
ToSendReset();

// Correction bit, might be removed when not needed
Expand Down Expand Up @@ -778,8 +771,7 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par
}


static void Code4bitAnswerAsTag(uint8_t cmd)
{
static void Code4bitAnswerAsTag(uint8_t cmd) {
int i;

ToSendReset();
Expand Down Expand Up @@ -853,8 +845,7 @@ static void EmLogTraceTag(uint8_t *tag_data, uint16_t tag_len, uint8_t *tag_Pari
// Stop when button is pressed
// Or return true when command is captured
//-----------------------------------------------------------------------------
static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len)
{
static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) {
// Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
// only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED
Expand Down Expand Up @@ -951,8 +942,8 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info, uint8_
// Main loop of simulated tag: receive commands from reader, decide what
// response to send, and send it.
//-----------------------------------------------------------------------------
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
{
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) {

uint8_t sak;

// The first response contains the ATQA (note: bytes are transmitted in reverse order).
Expand Down Expand Up @@ -1231,8 +1222,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)

// prepare a delayed transfer. This simply shifts ToSend[] by a number
// of bits specified in the delay parameter.
static void PrepareDelayedTransfer(uint16_t delay)
{
static void PrepareDelayedTransfer(uint16_t delay) {
uint8_t bitmask = 0;
uint8_t bits_to_shift = 0;
uint8_t bits_shifted = 0;
Expand Down Expand Up @@ -1261,21 +1251,20 @@ static void PrepareDelayedTransfer(uint16_t delay)
// if == 0: transfer immediately and return time of transfer
// if != 0: delay transfer until time specified
//-------------------------------------------------------------------------------------
static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing)
{
static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) {
LED_B_ON();
LED_D_ON();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);

uint32_t ThisTransferTime = 0;

if (timing) {
if(*timing == 0) { // Measure time
if (*timing == 0) { // Measure time
*timing = (GetCountSspClk() + 8) & 0xfffffff8;
} else {
PrepareDelayedTransfer(*timing & 0x00000007); // Delay transfer (fine tuning - up to 7 MF clock ticks)
}
if(MF_DBGLEVEL >= 4 && GetCountSspClk() >= (*timing & 0xfffffff8)) Dbprintf("TransmitFor14443a: Missed timing");
if (MF_DBGLEVEL >= 4 && GetCountSspClk() >= (*timing & 0xfffffff8)) Dbprintf("TransmitFor14443a: Missed timing");
while (GetCountSspClk() < (*timing & 0xfffffff8)); // Delay transfer (multiple of 8 MF clock ticks)
LastTimeProxToAirStart = *timing;
} else {
Expand All @@ -1284,12 +1273,9 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
LastTimeProxToAirStart = ThisTransferTime;
}

// clear TXRDY
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sends a 0x00 byte just to clear TXREADY. In the following loop we are waiting for TXREADY to be set again. This wastes 9.4us.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

AT91C_BASE_SSC->SSC_THR = SEC_Y;

uint16_t c = 0;
for (;;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = cmd[c];
c++;
if(c >= len) {
Expand All @@ -1306,8 +1292,7 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
//-----------------------------------------------------------------------------
// Prepare reader command (in bits, support short frames) to send to FPGA
//-----------------------------------------------------------------------------
static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *parity)
{
static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *parity) {
int i, j;
int last;
uint8_t b;
Expand Down Expand Up @@ -1390,8 +1375,7 @@ static void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, cons
// Stop when button is pressed (return 1) or field was gone (return 2)
// Or return 0 when command is captured
//-----------------------------------------------------------------------------
int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity)
{
int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) {
uint32_t field_off_time = -1;
uint32_t samples = 0;
int ret = 0;
Expand Down Expand Up @@ -1475,8 +1459,7 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity)
}


static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen)
{
static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
LED_C_ON();

uint8_t b;
Expand Down Expand Up @@ -1578,8 +1561,7 @@ int EmSendPrecompiledCmd(tag_response_info_t *response_info) {
// If a response is captured return true
// If it takes too long return false
//-----------------------------------------------------------------------------
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
{
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) {
uint32_t c;

// Set FPGA mode to "reader listen mode", no modulation (listen
Expand All @@ -1598,9 +1580,9 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
for (;;) {
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;
if(ManchesterDecoding(b, offset, 0)) {
if (ManchesterDecoding(b, offset, 0)) {
NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD);
return true;
} else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) {
Expand All @@ -1611,55 +1593,51 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
}


void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing)
{
void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing) {

CodeIso14443aBitsAsReaderPar(frame, bits, par);

// Send command to tag
TransmitFor14443a(ToSend, ToSendMax, timing);
if(trigger)
if (trigger)
LED_A_ON();

// Log reader command in trace buffer
LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, true);
}


void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing)
{
ReaderTransmitBitsPar(frame, len*8, par, timing);
void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing) {
ReaderTransmitBitsPar(frame, len*8, par, timing);
}


static void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
{
static void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) {
// Generate parity and redirect
uint8_t par[MAX_PARITY_SIZE];
GetParity(frame, len/8, par);
ReaderTransmitBitsPar(frame, len, par, timing);
}


void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
{
void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing) {
// Generate parity and redirect
uint8_t par[MAX_PARITY_SIZE];
GetParity(frame, len, par);
ReaderTransmitBitsPar(frame, len*8, par, timing);
}


static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
{
static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity) {
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return false;
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
return Demod.len;
}


int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
{
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) {
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return false;

LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
return Demod.len;
}
Expand Down Expand Up @@ -1696,7 +1674,7 @@ static void iso14a_set_ATS_times(uint8_t *ats) {
static int GetATQA(uint8_t *resp, uint8_t *resp_par) {

#define WUPA_RETRY_TIMEOUT 10 // 10ms
uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP
uint8_t wupa[] = {ISO14443A_CMD_WUPA}; // 0x26 - REQA 0x52 - WAKE-UP

uint32_t save_iso14a_timeout = iso14a_get_timeout();
iso14a_set_timeout(1236/(16*8)+1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer.
Expand Down Expand Up @@ -1737,7 +1715,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
int len;

// init card struct
if(p_hi14a_card) {
if (p_hi14a_card) {
p_hi14a_card->uidlen = 0;
memset(p_hi14a_card->uid, 0, 10);
p_hi14a_card->ats_len = 0;
Expand All @@ -1747,7 +1725,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
return 0;
}

if(p_hi14a_card) {
if (p_hi14a_card) {
memcpy(p_hi14a_card->atqa, resp, 2);
}

Expand Down Expand Up @@ -2034,8 +2012,8 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u
// Read an ISO 14443a tag. Send out commands and store answers.
//
//-----------------------------------------------------------------------------
void ReaderIso14443a(UsbCommand *c)
{
void ReaderIso14443a(UsbCommand *c) {

iso14a_command_t param = c->arg[0];
uint8_t *cmd = c->d.asBytes;
size_t len = c->arg[1] & 0xffff;
Expand Down
1 change: 1 addition & 0 deletions armsrc/iso14443a.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *
extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);
extern void iso14a_set_trigger(bool enable);
extern void iso14a_set_timeout(uint32_t timeout);
extern uint32_t iso14a_get_timeout(void);
#endif /* __ISO14443A_H */
Loading