Teensy4.1 project has several SPI sensor devices tied to just one Teensy SPI port. The sensor has its output SDO and input SDI on the same sensor pin. So it's bi-directional SDIO for reading data from and writing to the sensors.
Every 10 ms, a timer interrupt triggers successive readout of 4 of those sensors. A readout means CS low, send one byte, and then receive 6 bytes back. and CS high again (it's a 3 axis accelerometer). And that 4 times in a row for the 4 sensors that all have their own CS pin, but share SCK and SDIO. SCK frequency cannot be super high (long wires).
My problem is that as this sensor interrogation happens all in a timer interrupt service routine, I am blocking other tasks while the CPU waits for each of 2*4= 8 SPI transactions to be done. 10% of the time, the CPU is waiting for SPI transactions to complete.
What I want instead is just one trigger that says go and execute this series of SPI transactions as listed below, say:
1. claim SPI port, CS1 low
2. SPI write 1 command byte 'read xyz words'
3. SPI read 6 bytes
4. CS1 high, CS2 low
5. SPI write 1 command byte 'read xyz words'
6. SPI read 6 bytes
7. CS2 high, CS3 low
8. SPI write 1 command byte 'read xyz words'
9. SPI read 6 bytes
10. CS3 high, CS4 low
11. SPI write 1 command byte 'read xyz words'
12. SPI read 6 bytes
13. CS4 high, release claim on SPI port
And all of that without ever polling (in a blocking way) for peripheral (or DMA) status bits that indicate that the LPSPI port is busy clocking bits in or out.
What I want to happen under the hood is that each of these 8 SPI transactions run in sequence, automatically. Without me firing these one by one.
As in I prepare the table with pointers to 8 buffers in RAM, indices for CS pin numbers, #bytes per transaction, and a read/write direction flag and then after one trigger call, the SPI transactions, all 13 steps, just happen, in a none-blocking way.
Do I need to rewrite a new low level SPI driver myself, or can I reuse something precooked from a library?
I looked in the current T4 SPI library sources, it seems to be doing DMA by default (does it indeed?), its interrupt/event based I think, but I cannot find anything yet on modes with bidirectional SDI/SDO in one wire, and there's no clue on how to make it execute a series of transactions to multiple devices with multiple CS pins.
Anyone any ideas, hints?
Every 10 ms, a timer interrupt triggers successive readout of 4 of those sensors. A readout means CS low, send one byte, and then receive 6 bytes back. and CS high again (it's a 3 axis accelerometer). And that 4 times in a row for the 4 sensors that all have their own CS pin, but share SCK and SDIO. SCK frequency cannot be super high (long wires).
My problem is that as this sensor interrogation happens all in a timer interrupt service routine, I am blocking other tasks while the CPU waits for each of 2*4= 8 SPI transactions to be done. 10% of the time, the CPU is waiting for SPI transactions to complete.
What I want instead is just one trigger that says go and execute this series of SPI transactions as listed below, say:
1. claim SPI port, CS1 low
2. SPI write 1 command byte 'read xyz words'
3. SPI read 6 bytes
4. CS1 high, CS2 low
5. SPI write 1 command byte 'read xyz words'
6. SPI read 6 bytes
7. CS2 high, CS3 low
8. SPI write 1 command byte 'read xyz words'
9. SPI read 6 bytes
10. CS3 high, CS4 low
11. SPI write 1 command byte 'read xyz words'
12. SPI read 6 bytes
13. CS4 high, release claim on SPI port
And all of that without ever polling (in a blocking way) for peripheral (or DMA) status bits that indicate that the LPSPI port is busy clocking bits in or out.
What I want to happen under the hood is that each of these 8 SPI transactions run in sequence, automatically. Without me firing these one by one.
As in I prepare the table with pointers to 8 buffers in RAM, indices for CS pin numbers, #bytes per transaction, and a read/write direction flag and then after one trigger call, the SPI transactions, all 13 steps, just happen, in a none-blocking way.
Do I need to rewrite a new low level SPI driver myself, or can I reuse something precooked from a library?
I looked in the current T4 SPI library sources, it seems to be doing DMA by default (does it indeed?), its interrupt/event based I think, but I cannot find anything yet on modes with bidirectional SDI/SDO in one wire, and there's no clue on how to make it execute a series of transactions to multiple devices with multiple CS pins.
Anyone any ideas, hints?