I am using the Aardvark I2C/SPI Host Adapter for development and debugging. In my current System Management Bus (SMBus) project, I am applying a repeated start read from the Aardvark adapter, which in this setup is the host (master device). I am using this Aardvark Software API call:
int aa_i2c_write_read(
Aardvark aardvark,
u16 slave_addr,
AardvarkI2cFlags flags,
u16 out_num_bytes,
const u08 * out_data,
u16 * num_written,
u16 in_num_bytes,
u08 * in_data,
u16 * num_read
)
There is one case where it does not work as expected. I have two questions.
When there is an address no-match, the target slave device response with NACK. When this happens, the Aardvark adapter keeps the SCL line low, even though the target device has NACKed the address. The SCL line is kept low for a duration that exceeds the timeout limit of the slave device (40 ms).
I tried adding a breakpoint after aa_i2c_write_read(), but the SCL continued to stay low – it never goes high. How can I get the SCL signal released? Not releasing the bus after 40-100ms of NACK, the results I see are conflict with the SMBus specifications.
In the case of NACK, does the host attempt to read two more times? On a logic analyzer, I see that three write/read transactions occurred at the same address. Is the function aa_i2c_write_read() supposed to do that?
Response from Technical Support:Thanks for your questions! The Aardvark adapter can implement I2C or SPI. The SMBus is like an extra layer of I2C, which imposes some additional behaviors and/or requirements beyond the I2C specification. I2C protocols allow the bus hold that you observed. However, the Aardvark adapter can perform most of the activities defined by SMBus protocols, as well as release the bus as needed for your setup.
The SCL signal is held low because the master device, the Aardvark adapter, controls the bus. In your case, because the target device did not respond with ACK, the operation was aborted. When an operation is aborted, the bus stays low until something occurs – such as issuing a specific command to cause the bus the change state. In other words, the SCL being held low is a correct response.
The command aa_i2c_write_read() does not retry when the write operation is unsuccessful. The Aardvark adapter of its own accord does not attempt to repeat the read operation. In this case, there is probably something in the controlling software that caused the repeated attempts to read. For example, some chips use NAK to indicate busy or something similar, in which case the I2C result flows back to the caller of our API.
For your scenario, there is a command to release the bus:
aa_i2c_free_bus()int aa_i2c_free_bus (Aardvark aardvark);
Executing this command frees the Aardvark I2C subsystem from a held bus condition. For more information, please go to the General I2C section in the Aardvark I2C/SPI Host Adapter User Manual.
We hope this answers your questions. Additional resources that you may find helpful include the following:
If you want more information, feel free to contact us with your questions, or request a demo that applies to your application.