From 9479340e19bbc98eb1bbbefe4cb9043bc9ce78b2 Mon Sep 17 00:00:00 2001 From: Antiklesys Date: Mon, 31 Aug 2026 02:57:12 +0800 Subject: [PATCH] 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. --- armsrc/iso14443a.c | 8 ++++++++ armsrc/iso14443a.h | 3 +++ armsrc/sam_sc.c | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index d1692e2ac..8d2bdd1ba 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -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 //----------------------------------------------------------------------------- diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 1f39be439..575a23184 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -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); diff --git a/armsrc/sam_sc.c b/armsrc/sam_sc.c index 5bcd88395..cf7e7b73c 100644 --- a/armsrc/sam_sc.c +++ b/armsrc/sam_sc.c @@ -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();