I noticed in my test bench that 'tip' bit is not set when issuing a STOP command, only during read/write commands. This might give the impression the bus is free when it is busy.
I fixed this by changing tip <= (rd | wr); to: tip <= (rd | wr | sto);
In the top level class. It can take hundreds of cycles for the tip bit to be cleared by 'done' depending on the pre-scaler value.
The comment parser ate my verilog example. I changed
<pre> tip <= (rd | wr); </pre>to:
<pre> tip <= (rd | wr | sto); </pre>I changed: tip <= (rd | wr); to:
tip <= (rd | wr | sto);
Withdrawn - polling the 'busy' bit in status register is sufficient for detecting end of stop.
What confused me was the testing of 'tip' after stop condition in tst_bench_top.v lines 440-444. This should be polling busy bit q6.
As you already noted; TIP (Transfer In Progress) indicates a read/write transfer. When a master owns the i2c bus, the BUSY bit is asserted.
FWIW, having TIP support STOP condition checks is probably the better solution -- in a multi-master scenario polling BUSY is not correct because as soon as you release the bus but before you poll BUSY some other master might start a transfer, which will activate BUSY again even though your STOP is completed. You could be stuck like this indefinitely if the other masters are chatty.