i2c problem (timeout ?)
Display Name
Posts: 7
I have a problem with the i2c driver. I know there are several of these drivers about for the SX28, but the one I’m using is the Slave one that runs entirely in the ISR and is controlled by a series of state tables. However, there does seem to be two versions of this knocking about in i2cs.zip. One called i2cs.src and the other i2cs_vp.src. The only difference seems to be some extra code in i2cs_vp.src that manipulate two more flags. I’ve used i2cs_vp.src – although I don’t reference the two new flags.
The SX28 is communicating with Linux over the I2C link, and the SX28 is connected to an ultra-sonic range finder. So the general idea is Linux asks the SX28 what the current ping range is, the SX28 starts a ping, times it, and returns a two byte answer. Simple, and it works most of the time.
The problem is, when the ping range is long, i.e. there is a long delay (typically > 10mS) before the SX28 can return an answer, the 2nd byte of the answer is never returned. The ping hardware is working OK in these cases because I can see the result with SX-Key.
It appears as if the i2csDataNeeded flag doesn’t always get set when requesting the 2nd byte, and so my code never even attempts to send the second byte, but I can’t see why this flag doesn’t get set.
I initially thought it was some sort of timeout problem on the i2c bus or in Linux, but I have changed the timeout values in Linux, and built the kernel with debugging support in the i2c modules, and the trace from Linux looks like it’s asking for data but not getting it. To back this up is the evidence…
1) the two byte answer is created and the first byte is sent and received OK – so if there was a timeout problem it would surely timeout waiting for the first byte
2) putting a breakpoint after the check for i2csDataNeeded and execution doesn’t break
3) for short delay pings the code works OK in passing both bytes to Linux so the code logic is OK.
Has anyone here had experience of using the i2c driver to talk to Linux ? Any ideas of what the problem might be ?
By the way, this is Linux 2.4.16. The 2.6.x versions of Linux appear to have been changed significantly in the I2C arena to cater for (I think) onboard PC diagnostics and are known to be “different”. However, I'm fairly sure the problem is not in Linux but is more with the i2cs sllave vp not always setting the dataneeded flag.
The SX28 is communicating with Linux over the I2C link, and the SX28 is connected to an ultra-sonic range finder. So the general idea is Linux asks the SX28 what the current ping range is, the SX28 starts a ping, times it, and returns a two byte answer. Simple, and it works most of the time.
The problem is, when the ping range is long, i.e. there is a long delay (typically > 10mS) before the SX28 can return an answer, the 2nd byte of the answer is never returned. The ping hardware is working OK in these cases because I can see the result with SX-Key.
It appears as if the i2csDataNeeded flag doesn’t always get set when requesting the 2nd byte, and so my code never even attempts to send the second byte, but I can’t see why this flag doesn’t get set.
I initially thought it was some sort of timeout problem on the i2c bus or in Linux, but I have changed the timeout values in Linux, and built the kernel with debugging support in the i2c modules, and the trace from Linux looks like it’s asking for data but not getting it. To back this up is the evidence…
1) the two byte answer is created and the first byte is sent and received OK – so if there was a timeout problem it would surely timeout waiting for the first byte
2) putting a breakpoint after the check for i2csDataNeeded and execution doesn’t break
3) for short delay pings the code works OK in passing both bytes to Linux so the code logic is OK.
Has anyone here had experience of using the i2c driver to talk to Linux ? Any ideas of what the problem might be ?
By the way, this is Linux 2.4.16. The 2.6.x versions of Linux appear to have been changed significantly in the I2C arena to cater for (I think) onboard PC diagnostics and are known to be “different”. However, I'm fairly sure the problem is not in Linux but is more with the i2cs sllave vp not always setting the dataneeded flag.
Comments
It was my fault. The ISR was running at irregular intervals because occassionally the RTCC wrapped while in the ISR (Oooops!). I now use multi-threading, and run the I2C bus at just uner 100KHz on 4 of the threads, mess about with two stepper motors on a 5th thread, service the Ultra-sonics on the 6th thread, giving me two spare threads for future use.
When the ISR is running at irregular intervals because of RTCC wrapping, this means that the ISR code takes too many instruction cycles, i.e. you either need to increase the interrupt period, or try to get rid of instructions.
As I²C communications are not really critical concerning precise timing, I usually do the I²C stuff outside of the ISR. Ok, when you operate an I²C slave, you must detect SCL changes, and Start/Stop conditions w/o missing some, so this is more critical than operating a master who can control the system even with varying SCL clocks.
Nevertheless, my main program loops usually even execute faster than the ISR period, i.e. sampling SDA and SCL for a start condition, and sampling SCL for reading/writing data takes place more often compared to have that code within the ISR.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
Günther