diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 52d1a64b4..edb4a3487 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -41,10 +41,18 @@ // cannot drift apart. #define I2C_DELAY_1CLK SpinDelayUsPrecision(I2C_DELAY_1CLK_US) #define I2C_DELAY_2CLK SpinDelayUsPrecision(I2C_DELAY_2CLK_US) -#define I2C_DELAY_SDA SpinDelayUsPrecision(I2C_DELAY_SDA_US) +#define I2C_DELAY_SDA SpinDelayUsPrecision(s_app_i2c_timing ? I2C_DELAY_SDA_APP_US : I2C_DELAY_SDA_US) #define I2C_DELAY_HOLD SpinDelayUsPrecision(I2C_DELAY_HOLD_US) #define I2C_DELAY_HIGH SpinDelayUsPrecision(I2C_DELAY_HIGH_US) +static bool s_app_i2c_timing = false; + +bool sc_set_app_i2c_timing(bool enabled) { + bool previous = s_app_i2c_timing; + s_app_i2c_timing = enabled && I2C_APP_FAST_TIMING; + return previous; +} + #define SC_PROTO_T0 (1 << 0) #define SC_PROTO_T1 (1 << 1) diff --git a/armsrc/i2c.h b/armsrc/i2c.h index e84673c2d..52617f47b 100644 --- a/armsrc/i2c.h +++ b/armsrc/i2c.h @@ -82,6 +82,8 @@ // SCL falls (spec 0.3 us) and SCL high width (spec 4 us) - so they get the // standard mode minimum with margin instead of a full clock. #define I2C_DELAY_SDA_US 15 +#define I2C_DELAY_SDA_APP_US 8 +#define I2C_APP_FAST_TIMING 1 #define I2C_DELAY_HOLD_US 2 #define I2C_DELAY_HIGH_US 6 @@ -145,6 +147,9 @@ void sc_log_trace_span(const uint8_t *d, uint16_t len, bool reader2tag, uint32_t void sc_log_trace_reset(void); bool sc_rx_bytes(uint8_t *dest, uint16_t *destlen, uint32_t wait); + +// Returns the previous app timing state. +bool sc_set_app_i2c_timing(bool enabled); // bool GetATR(smart_card_atr_t *card_ptr, bool verbose); diff --git a/armsrc/sam_sc.c b/armsrc/sam_sc.c index 8b196174e..1f1c35e48 100644 --- a/armsrc/sam_sc.c +++ b/armsrc/sam_sc.c @@ -454,10 +454,12 @@ static int sam_sc_card_api_loop(uint8_t *response, uint16_t *response_len, } void sam_sc_handler_no_trace(const PacketCommandNG *c) { + const bool app_timing = sc_set_app_i2c_timing(true); const bool tracing = get_tracing(); const bool blocked = set_tracing_blocked(true); clear_trace(); sam_sc_handler(c); + sc_set_app_i2c_timing(app_timing); set_tracing_blocked(blocked); set_tracing(tracing); }