Skip to content


WIP: firmware: guard I2C transactions with timeouts.
Browse files Browse the repository at this point in the history
If we don't add timeouts on I2C transactions, then the USB request
that caused it (for reads) or the next USB control request (for
writes) will silently hang forever until the device is power cycled.

This is clearly undesirable. However, this does not happen at all
during normal operation, and although it hardens the device, the FX2
firmware size comes at a premium, and blindly spraying these guard
conditions adds a nontrivial increase.

Therefore this code, although tested, is not currently used.
  • Loading branch information
whitequark committed Mar 1, 2019
1 parent a8ac6ba commit 0744b81
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions firmware/main.c
Expand Up @@ -284,6 +284,26 @@ static bool reset_status_bit(uint8_t bit) {
return false;

volatile uint8_t i2c_timeout;

void isr_TF0() __interrupt(_INT_TF0) {
// About 256 ms at 48 MHz clock.
if(i2c_timeout == 16) {
i2c_cancel = true;

#define I2C_PROTECT(code) \
do { \
i2c_timeout = 0; \
T0 = 0; \
TR0 = true; \
code \
TR0 = false; \
} while(0)

// We perform lengthy operations in the main loop to avoid hogging the interrupt.
// This flag is used for synchronization between the main loop and the ISR;
// to allow new SETUP requests to arrive while the previous one is still being
Expand Down Expand Up @@ -771,6 +791,10 @@ int main() {

// Use timer 0 in 16-bit timer mode for I2C timeout.
TMOD = _M0_0;
ET0 = true;

// Use timer 2 in 16-bit timer mode for ACT LED.
ET2 = true;
Expand Down

0 comments on commit 0744b81

Please sign in to comment.