I’m not sure that is correct. The master will normally send a command and
then your slave driver will have to respond with relevant packet. The
protocol will have to be well defined.None of that is required by SPI (in the most basic form it is just a
shift
register). What I was alluding it protocol games that be played like
Master
writes byte to slave and waits for an active GPIO before anymore clocking.
Or even a dumb (unidirectional) protocol where the master waits for a
GPIO to go active before clocking out data.Well, technically, that is correct, because data is shifted in and out at
the same time, using the same clock. However, when the master hasn’t
requested a specific data, what do you respond with? Random data? Perhaps
if it was just streaming channel data, then I can see your point.Since SPI is always full duplex, it comes down to protocol definition. It
could be a fixed pattern, 0, 0xff, or random, or undefined data during the
initial clock out for the command byte.In contrast, doing it like a lot of common devices where you can clock in
a
byte (i.e. register address or a command) and expect data after another 8
clocks could impose some very tight timing requirements.I agree, this could be very difficult to achieve using interrupts, but using
DMA that should be pretty simple. That presupposes that the data is already
in the DMA buffer and this is some streaming interface I spoke of
previously. Streaming channel data into the BBB using DMA would also be
pretty simple. Exchanging of short master/slave command/response would need
interrupt processing. Maybe using fixed size messages and using fifo
watermark might limit the interrupt overhead.However, you are correct that the
SPI slave must be preconfigured and waiting for the master to start
clocking the interface. The problem with the SPI framework and in
particular the McSPI driver is that they is written around a master
implementation and adding slave support is almost impossible. It would be
easier to write a slave McSPI from scratch. The I2C slave framework might
be a good guide on how to make this work.There are 2 things being mixed up here -
Merely grafting on slave functionality isn't too difficult with the
current
McSPI driver (that's what I did). The main thing this gets you is a lot of
the driver registration and McSPI init is reused; this is a big hack but
it gets data flowing.Can you share that with me? I would be interested to see how you managed to
do this. I’ve looked at this several times and each time my head wants to
explode.Unfortunately, I cannot share that code (paperwork reasons, owned by
customer). The differences between slave/master from a pure driver's point of
view is a few register settings. A naive way of doing this is -Initialize as slave
Have a callback in the driver that queue's data for transmission.
Driver user (aka data consumer) registers a receive callback that is invoked
when data comes in. Driver user is responsible for ignoring data when
appropriate.
Yeah, this is the approach used by the I2C Slave Framework. So traditionally, the McSPI driver registers with the SPI Framework as an SPI Master. Now through DT config, we could have the McSPI driver register with the SPI Framework as an SPI Slave and then the SPI framework registers a callback with the McSPI driver (Slave Provider). On receiving event from the master, McSPI driver calls Custom Driver callback, which responds by writing to McSPI FIFO. Does that sound reasonable?
On receive, queue more data for xfer to avoid underruns on the MISO end. If
nothing is queued by the driver user, put in fix data to keep the McSPI happy
(avoid underruns).
I agree. In the case when the slave driver cannot respond in time, simply send a wait response and have the master retry until successful.
A better implementation may be to use a work queue arrangement to limit the
exposure of the driver user to time criticality. Probally need to propagate
the CS (SS) signal up to the driver user to help synchronize things.
The McSPI hardware will take care of this. From what I recall, McSPI does not process SPI signals until Slave Select is true.