arduino / ArduinoCore-mbed

329 stars 192 forks source link

Is SPI thread safe? #388

Open tokiedokie opened 2 years ago

tokiedokie commented 2 years ago

I need to use same SPI port (MOSI, MISO, SCK) with different Chip Select (CS). However SPI class is not supporting CS. Therefore I need to code like:

#include "SPI.h"
#include "mbed.h"

rtos::Thread thread;

auto CS0 = D7;
auto CS1 = D6;

void thread_func() {
    digitalWrite(CS0, LOW);
    SPI.begin();
    digitalWrite(CS0, HIGH);
}

void setup() {
    pinMode(CS0, OUTPUT);
    digitalWrite(CS0, HIGH);
    pinMode(CS1, OUTPUT);
    digitalWrite(CS1, HIGH);

    thread.start(mbed::callback(thread_func));

    digitalWrite(CS1, LOW);
    SPI.begin();
    digitalWrite(CS1, HIGH);
}

void loop() {}

Is this thread safe? Is there any chance CS0 and CS1 to go LOW at the same time?

On the other hand, mbed's SPI supports CS pin. https://github.com/arduino/ArduinoCore-mbed/blob/bbc628439eb4dd64b70348e91ecda8e0c45e318c/cores/arduino/mbed/drivers/include/drivers/SPIMaster.h#L116 If Arduino's SPI is not thread safe, how about using mbed's SPI CS pin?

tokiedokie commented 2 years ago

Any ideas?

sdzienge commented 2 years ago

@tokiedokie I would assume that Arduino SPI is not thread safe as I don't know for sure. You're already using the mbed rtos namespace for threading, why not add PlatformMutex, or rtos::Semaphore to protect access to the CS pin. I've done exactly that successfully in a few sketches.