[Letux-kernel] jz4730-i2c

Paul Boddie paul at boddie.org.uk
Wed Feb 17 00:49:21 CET 2021

On Sunday, 14 February 2021 17:29:04 CET H. Nikolaus Schaller wrote:
> Questions:
> * why do you wait for interrupt at all?

I'm not so much as waiting as yielding to the scheduler, with any I2C 
interrupt causing my program to be scheduled again, resuming at the point at 
which it yielded or "waited". There's no polling going on here, or at least 
not as the intended means of performing the operations involved.

In fact, I just rewrote my code to use a state machine instead with a 
dispatcher for when interrupt requests arrive. It seems to work mostly like 
the previous form of the code, so I think there isn't anything special about 
what I am doing.

> * polling for STX doesn't seem necessary from the Flow Chart

So, the manual says that STX is...

STA/STO Command is On.
0 – STA/STO FIFO buffer is empty.
1 – STA/STO FIFO buffer is not empty.

This is a bit incoherent, but I could interpret it as meaning that given the 
issuing of a start or stop condition, if STX is set then the bus is not ready 
for actual data transfer.

What I have now just done is to record various event occurrences to see what 
might be happening when interrupts occur. If I measure occurrences at the 
start of reading, after the address has been sent, when I test for the 
following condition...

STX || (!DRF && !NACK)

...which is, of course...

STX || (!DRF && ACKF)

...then, on the latest cycle of the test, I see...

393 read operations
1835 cases of the entire condition above applying, of which...
423 cases where STX is set
1412 cases where STX is not set

On average, then, STX appears to be set once per read operation, but there 
will be between 4 and 5 evaluations with the entire condition being satisfied, 
with between 3 and 4 evaluations involving STX not being set and thus the more 
interesting condition (no data available to read) being satisfied.

Since I have made my interrupt dispatch occur with no retries upon any 
timeout, and with a 0.1s timeout to prevent any premature evaluation of the 
condition, this suggests that the interrupt condition may indeed get "stuck" 
at this point in the workflow, causing my code to repeatedly evaluate the 
above condition in the program. This might answer an earlier question.

My previous experience was that I have to test for STX. What I think happens, 
and maybe can be tested tomorrow (or soon), is that when the address is sent 
the following sequence of conditions are observed...

1) !STX,  DRF, !NACK  (address issued to peripheral by program)
2)  STX,       !NACK  (address presented on bus by peripheral, DRF uncertain)
3) !STX, !DRF, !NACK  (device busy - no data available)
4) !STX,  DRF, !NACK  (data available)
 ) !STX, !DRF,  NACK  (alternative: NACK)

The challenge is distinguishing between the first and fourth steps in the 
above sequence, at least as far as I see it. If the status is tested too soon 
(thanks to that uncontrollable interrupt), then STX helps to prevent the 
interpretation of the first step as the fourth.

I hope this helps to provide some more context and useful observations.


More information about the Letux-kernel mailing list