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:
> * 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
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