I2C Busy Timeout | LabJack
 

I2C Busy Timeout

4 posts / 0 new
Last post
Chris Knudsen
chriskner's picture
I2C Busy Timeout

I'm debugging both python host code (ethernet) and microcontroller firmware (I2C), with a labjack T7 in between.

I'm using I2C clock stretching to hold the I2C bus while the uC is preparing a response from incoming T7 commands. The T7 is the master, the uC is the slave. The uC invokes clock-stretching by holding SCL low.

Sometimes, if my poorly-written uC firmware takes too long, and LJM returns with an "I2C_BUS_BUSY" error.

For example:

 Bytes_To_Read = write_device(daq, sout, verbose=verbose) #updates Bytes_To_Read with length-to-read
  File ".\sc_NERDAQ_I2C.py", line 261, in write_device
    ljm.eWriteName(daq, "I2C_GO", 1)
  File "C:\Python27\lib\site-packages\labjack\ljm\ljm.py", line 530, in eWriteName
    raise LJMError(error)
labjack.ljm.ljm.LJMError: LJM library error code 2720 I2C_BUS_BUSY

This particular instance happened when my uC was holding SCL low for ~280 mSec (delaying the ACK of the address byte).  Yes, I know that this is slow, and something is broken. 

However, I'm wondering:

  • What determines this I2C "GO" Timeout?
  • Is the timeout value readable/setable?
  • Am I correct that Ethernet Transaction Timeout is a default of 2600 mS (or thereabouts), so it's probably not that?

I2C Setup:

# Configure the T7 for I2C-serial
my_list = [
    "I2C_SDA_DIONUM",
    "I2C_SCL_DIONUM",
    "I2C_SPEED_THROTTLE",
    "I2C_OPTIONS",
    "I2C_SLAVE_ADDRESS",
]
my_data = [
    int(SDA_pin),
    int(SCL_pin),
    65516,  # Speed Throttle 65,516 is ~100 kHz, min is 46,000 (per LJM library)
    0b00000000,  #I2C options B2: disable clock stretching, B1: No STOP with RESTART, B0: Reset Bus
    int(MIN_I2C_ADDRESS),  # junk, default I2C_address of a widget
]
ljm.eWriteNames(daq, len(my_list), my_list, my_data)

Trace results of writing to I2C widget at address 0x14 "X\0x10", followed by a Read request to the same address, with clock stretching (delaying the ACK of the Address-Read byte) starting at ~390 uS:

See Attachment.

Sending code:

ljm.eWriteName(daq, "I2C_NUM_BYTES_TX", len(bytes_in))  # number of bytes in the original data
ljm.eWriteName(daq, "I2C_NUM_BYTES_RX", 1)              # read-back the length of any response, 0-128
ljm.eWriteNameByteArray(daq, "I2C_DATA_TX", len(bytes_in), [ord(ch) for ch in bytes_in])        #convert string to list of ints
ljm.eWriteName(daq, "I2C_GO", 1)

< I2C Busy Error Here >

#Get the LabJack buffer contents, that was updated from "I2C_GO".
resp = read_LabJack_I2C_buffer(daq, 1, verbose=verbose)  

Thank you for your attention.

-Chris

File Attachment: 
Chris Knudsen
chriskner's picture
**Latest firmware and LJM

**Latest firmware and LJM used.**

LabJack Support
labjack support's picture
The T7 has an internal

The T7 has an internal watchdog that will trip if any operation takes longer than 256 ms. This timeout cannot be changed.

 

When the T7 receives a request to start an I2C communication, it checks the states of the I2C lines. If one or both of the lines are low then the I2C_BUS_BUSY error is thrown. Clock stretching should only be used to stall a communication in progress. For instance, if the master addresses the slave and sends an instruction asking for a specific result, then the clock can be stretched for a short time while the result is fetched. For very long sensor operations separate start_reading and read_result functions are usually used (two separate communications).

The good news is that if you know your device will eventually be ready to send data you can ignore I2C_BUS_BUSY and just keep attempting the I2C operation. Eventually the request will go through.

 

Communication timeouts can be modified:

https://labjack.com/support/software/api/ljm/function-reference/library-...

https://labjack.com/support/software/api/ljm/constants/timeout-configs

Chris Knudsen
chriskner's picture
Thanks for the quick reply.

Thanks for the quick reply.

For very long sensor operations separate start_reading and read_result functions are usually used...

This the direction that I'm going in.  It's good to be aware of the 256mS boundary as well.

Regards,

Chris