There is nothing that I can find in that document that explains the 600us wait for the sync. I could understand a few clock cycles, but not many thousands!
I have configured the ssn port with a different clock, since otherwise the clock that drives the chip select line is being stopped and started with the SPI clock. This is not desirable. However, this did not help.
Anecdotally, when the tile is busy the phenomenon is worse. One of the cores has a "default" case in its looped select. It is continually polling for new data. If this default is removed then the SPI read (in a different task) happens a lot more reliably. I have refactored that task to not use the default. This is good because it has resulted in more lean code.
But I am left with SPI reads that work correctly and in good time about 99.5% of the time. Roughly 5 in every 1000 reads takes this massive 600us. I still have no real explanation for that.
I have modified the lib_spi as a test.
I have replaced this block
Code: Select all
p_ss[selected_device] <: 1 @ time;
//TODO should this be allowed? (0.6ms max without it)
if(ss_deassert_time > 0xffff)
delay_ticks(ss_deassert_time&0xffff0000);
time += ss_deassert_time;
p_ss[selected_device] @ time <: 1;
with an immediate write
.
This seems to fix things and the write is now reliable.
But I do not understand why the original causes problems. I am passing ss_deassert_time=4. So my understanding of the code is this.
1) Write 1 to the port and record the time of the write in 'time'
2) If statement will not be entered because my value is small.
3) add 4 ticks to time.
4) Cause 1 to be written to the port, 4 ticks after the previous write. This will have no effect [writing the same value], but will mean that the sync() or writing of the 0 in the subsequent begin_transaction cannot happen until the dessert period.
So, the original code and my code, is that the next transaction cannot be run for a further 83ns. (given 48MHz clock). This is insufficient machine cycles to get around to it anyway.