-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ [rtl] add optional SPI data FIFO #381
Conversation
…lement, add: mimic for handling FIFOs
…lement, add: mimic for handling FIFOs
Hi Stephan, i adjusted the driver see #382. Nevertheless there are some bugs inside. For the case IO_SPI_FIFO = 0 is all fine. But if i set IO_SPI_FIFO=32 and run following code example: while ( 1 ) {
memset(uint8MemBuf, 0, sizeof(uint8MemBuf)/sizeof(uint8MemBuf[0]));
uint8MemBuf[0] = 0x03;
neorv32_spi_rw(&g_neorv32_spi, uint8MemBuf, 0, sizeof(uint8MemBuf)/sizeof(uint8MemBuf[0]), 1);
while ( neorv32_spi_rw_busy(&g_neorv32_spi) ) {
__asm("nop");
}
while ( 1 ) {
__asm("nop");
}
} Then Performs the SPI core with disabled CSn an additional Access. One other Hint, if the FIFO=0, should tx_fifo.empty the same like busy. This relaxes the SW because you need to to change the config from tx_fifo.empty IRQ to Idle IRQ. Because it's the same. |
…into demo_spi_irq_fifo
Great! I'll have a look later.
I do not understand your code yet but I will have a closer look at this. 😉
You are right, but I was thinking about this the other way around: basically, software should only check the SPI control register's busy flag. If FIFO_SIZE = 0 this flag indicates (when set) that the SPI engine is currently doing a transmission (full backwards compatible). If FIFO_SIZE > 0 this flag is set when the SPI engine is busy OR when the TX FIFO has not run empty yet. So even software that was not written for handling the FIFO can still rely on the bus flag. The FIFO status signals should only be used by functions (or IRQ handlers) that were explicitly designed to handle "block transfers" (actually using the FIFO). |
I try to write 10 Bytes to the SPI, the core performs also this transaction. But Later when all is done, i see one additional transfer. Thanks for checking :) |
Okay, i think there i need to explain a little more. If you have FIFO=0, and setup the SPI IRQ=3d, then the Core will not produce IRQs. My segustions is: that in that case the busy irq is also produced even if tx empty IRQ is selected. |
I just simulated the code from #382. There are exactly ten transfers: SPI signals in light blue. There are 8 transfers between the two cursors; in this time CS ( |
Right. I need to modify the SPI control register so that writing interrupt configurations
Good point, but I think having the fall-back option should also resolve this. Btw, I think software should check if the SPI FIFO is implemented at all (there are 4 bits in the control register that show log2(FIFO_SIZE)) before configuring the SPI module (especially the IRQ configuration). |
* clean-up * add fall-back for interrupt configuration if FIFO size is zero
I have an idea, I need to check. |
I'll try 😉 |
…is 'neorv32_spi_rw' interrupted by ISR and after finishing ISR continued which leads the false writes on SPI bus.
Hi Stephan, with f9d8ece is the driver operable. the root cause was the interruption of the data write loop in the '_rw' function by the ISR. Now is the driver operable. |
Awesome!
That looks really good! 😉 I will test your code in a simulation later today. If everything looks fine we can merge #382 I think, right? |
Perfect, thanks for adding the FIFO. 😉 |
Your modification of However, using the "FIFO gets empty" interrupt is not really efficient here as only a single word is written to the FIFO on each IRQ. A more sophisticated approach should make use of "double buffering" utilizing half of the FIFO. But this is something we could add in the future... 😉
You're welcome! And thanks for the idea! |
[sw example] demo_spi_irq can handle FIFO
I think not directly, lets make a small deep dive. In this function:
is only written one data word. This is caused that this function can be interrupted by the ISR. If i try to write more data words then i will mess up the whole packet. In the ISR there should be written more datawords caused by:
because there is no return otherwise the data is send. But your right at the beginning fires the controller more IRQs. If the loops goes on the IRQ rate reduces. This is caused that in the higher speed modes the SPI is really fast. If you like, you can try to set-up a lower speed, then you should see the the FIFO is fully filled by the ISR without any new IRQ. This knowledge would also enables a completly different driver architecture: you bang out the bytes until the SPI return with busy then you leave the ISR. But the FIFO is much better :) |
Right. Since this is the
You are right! I keep forgetting that this runs in "highspeed" mode... 😅 Anyway, I think this is ready to be merged! 👍 |
This PR adds an optional data FIFO to the SPI module (idea by @akaeba from #378). A new top generic is added to configure the SPI FIFO size:
IO_TRNG_FIFO
, default = 0; has to be zero or a power of two. Furthermore, all FIFO status signals are added to the SPI control register and a fine grained interrupt configuration is added:✔️ The changes from this PR are fully backwards compatible.