SPI burst read/write
mingpepe opened this issue · 8 comments
The onTransmit
has no information about if it's the same transfer (chip select pin keep low). For my case, I need to simulate a SPI slave which has different behavior for different transfer length. The CS pin is controlled directly by hardware, currently I have no idea how to fix it. Any suggestion?
rp2040js/src/peripherals/spi.ts
Lines 112 to 119 in cac702d
The CS pin is controlled directly by hardware
How is it controlled directly? I couldn't spot any SPI register that controls the CS pin?
I guess SPI hardware output CS low when TX fifo is not empty, and output high CS high after TX fifo is empty for a peroid of time. Currently I did not find detail document about it.
Couldn't find any documentation either.
Quick googling shows that SS might always be low when SPI is enabled:
The name of pin is misleading. I mean SSPFSSOUT
.
active low chip select or frame sync ss_n (referred to as SSPFSSOUT in the following sections)
https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf p504
For my case, frame format is Motorola SPI with SPO=1, SPH=1. I'm pretty sure CS pin will toggle.
Good job on finding it!
Yes, we are definitely missing this functionality. I don't have the bandwidth to work on it in the near future, but if you are up to working on a pull-request, I suggest adding a callback, onCSChange
, that will be called whenever the CS pin value needs to change, and another read-only property that will return the current value of the CS pin.
The problem is when onCSChange
is called, it's not controlled by register. When reading or writing SPI, only the DR register is read or wirtten.
Yes, it's not trivial. If I understand correctly, the logic behind onCSChange() should more or less reflect the value of the busy
flag we already have?
My understanding it's not the same with the busy
flag.
Write data to SSPDR push data to FIFO, then call doTX
Then it set the busy
flag then call user callback, and once user callback call completeTransmit
, the busy
flag is off.
And user callback must call completeTransmit
, otherwise RX has no data to read.
User will see the busy
flag on -> user callback -> flag off, only 1 byte is transfered.