earlephilhower / arduino-pico

Raspberry Pi Pico Arduino core, for all RP2040 and RP2350 boards
GNU Lesser General Public License v2.1
2.08k stars 433 forks source link

SPI Slave possible? #265

Closed DustinWatts closed 3 years ago

DustinWatts commented 3 years ago

Looking at this great core, I don't see an obvious way of putting the RP2040 in to SPI slave mode. Am I missing something or is this not yet implemented?

earlephilhower commented 3 years ago

You're correct, there is no SPI slave mode implemented.

Do you know of an Arduino core with SPI slave implemented? I'm not quite sure how the API would be, because (at least w/the SDK) the slave read/write is a blocking operation....so you'd enable slave mode and then do nothing until a read/write comes in sometime later, as opposed to getting an interrupt or callback leaving the core free to do other work...

DustinWatts commented 3 years ago

I do not know of an Arduino RP2040 core with SPI slave. There is a similar issue on the Pico Examples here where someone seems to have implemented something that looks promising: here

Also, having the option to be a slave and not being able to do anything else seems a bit pointless, so that makes me think there should be a way to make this useful. I mean if we can read data, but not do anything with that data after reading it, what is the point? :)

I would like to use the RP2040 as a TFT driver using PIO (8 bit). Another MCU (in my case an ESP32) will tell the RP2040 to draw something to the screen while the ESP32 handles things like WiFi and BLE. Kinda like the Arduino Nano RP2040 Connect, but using the RP2040 as co-processor instead of the other way around.

But maybe I should go for I2C instead as I see your core does support I2C slave mode.

earlephilhower commented 3 years ago

I think the real issue is that SPI requires synchronous response to the master while I2C lets you clock stretch. So, for SPI you need to write the FIFO with data before the SPI request comes in, but with I2C you can get the request, take an interrupt and hold the SCK line low (the HW handles this part 100% so no race condition), do some work and then send the response thru the FIFO.

FWIW, you can use the calls they use from the example in your own code (the full SDK is included). I think, however, that example is a 1-shot and may also be blocking or will be subject to race conditions.