Bugfix: stale ISO14443A scheduler delay

Internal Card-API code restarts the SSP clock before every RF APDU, resetting it to zero. ISO14443A retains NextTransferTime as an absolute timestamp from the prior clock instance, so each next transmit waits for stale time.
This commit is contained in:
Antiklesys
2026-08-31 02:57:12 +08:00
parent 8e405a7fe8
commit 9479340e19
3 changed files with 17 additions and 0 deletions
+8
View File
@@ -314,6 +314,14 @@ uint32_t iso14a_get_timeout(void) {
return iso14a_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 128 - 2;
}
void iso14a_rebase_transfer_time(void) {
// NextTransferTime is expressed in absolute SSP-clock counts. A caller
// that restarts StartCountSspClk() resets that counter to zero; retaining
// the old value would make ReaderTransmit() wait for stale time from the
// preceding APDU. Do not reset PCB or ATS state here.
NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER;
}
//-----------------------------------------------------------------------------
// Generate the parity value for a byte sequence
//-----------------------------------------------------------------------------
+3
View File
@@ -129,6 +129,9 @@ void setHf14aConfig(const hf14a_config_t *hc);
hf14a_config_t *getHf14aConfig(void);
void iso14a_set_timeout(uint32_t timeout);
uint32_t iso14a_get_timeout(void);
// Rebase the absolute reader-transfer schedule after a caller restarts the
// SSP clock counter. This preserves the active ISO14443-4 session.
void iso14a_rebase_transfer_time(void);
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
+6
View File
@@ -366,6 +366,12 @@ static int sam_sc_card_api_loop(uint8_t *response, uint16_t *response_len,
}
if (iso14a) {
switch_clock_to_countsspclk();
// This counter is reset for the RF exchange so the SAM
// path can return to millisecond ticks afterwards. Keep
// ISO14443A's absolute transfer scheduler in the same
// time base; otherwise it waits on a stale timestamp
// from the preceding Card-API APDU.
iso14a_rebase_transfer_time();
int apdu_len = iso14_apdu((uint8_t *)op_value, op_len, false,
nfc_rx, sizeof(nfc_rx), NULL);
switch_clock_to_ticks();