How should an I2C driver handle missing/non responsive hardware?

Go To Last Post
2 posts / 0 new
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, I have discovered an issue with the ASF4 I2C driver that I'm a little bit uncertain about how I should handle. Before I explain why I'm uncertain, let me describe the problem:

During initialization of the device, my code adresses an I2C device that's mounted on a shield through the Arduino compatible header. This header is not always mounted, and when it's not I'd expect the I2C to "give up" when it doesn't receive a "ready" signal from the external device, however it does not.


In the file "hpl_twihs.c" the function "_i2c_m_sync_read" waits for this RXRDY signal, and gets stuck in an infinite loop when the external device does not respond:

/* Wait for a byte has been received in TWIHS_RHR since last read */
while (!hri_twihs_get_SR_RXRDY_bit(dev->hw)) {

Now this is where I'm uncertain how to proceed. I'm not fluent in "i2c timing protocol", so I don't know if this is working according to spec or if it's a bug. I realize it's an edge case, since most hardware should be expected to always be physically available, however I can imagine several cases where this infinite loop gets activated. For example if the external device at some point fails, or in "plug and play" operations where you want the software to recognize which hardware is actually available.


Anyway: I also found the following variable defined in "hal_i2c_m_sync.h"

#define I2C_M_MAX_RETRY 1

which seems like it should be linked with the issue above, but as far as I can tell it's never used in the code at all.


So, does any of you have any opinions on how the case of missing/non responsive hardware should be handled by the driver, and if the ASF4 code comforms to the spec or not?





My setup

  • ASF4 (Atmel START)
  • The "HAL:Driver:I2C_Master_Sync" Driver
  • The SAM V71Q21 on atsamv71-xult dev board
  • Shield with I2C addressable ADC that's mounted most of the time, but not always.
This topic has a solution.
Last Edited: Thu. Jul 4, 2019 - 09:21 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've further analyzed the transaction, and realized that the code doesn't look for the ACK bit before it starts waiting for the first data byte. So I've concluded that this is definetively a bug, not just a weird edge case. The code simply doesn't conform to the I2C standard.

I'll submit a bug report.


PS: I threw up a logic analyzer and found that the peripheral itself performs to the standard, this is a software implementation problem.


More visual explanation of what's going on
Logic analyzer screenshot

1. At this point the code assumes "ACK". However, when it gets "NACK", the hardware will automatically "STOP" the transaction (as it should). The code does not notice this.

2. At this point the code assumes a data byte will arrive (because it assumed "ACK" in 1.). When this doesn't happen, it doesn't check for the stop condition and gets stuck in an infinite loop, waiting for data to arrive.

Last Edited: Thu. Jul 4, 2019 - 11:31 AM