SPI not working on pico from FreeRTOS task

I have a task where spi_write_read_blocking returns 95 for the first few task iterations then returns 1023 forever. The code works when not using it in a FreeRTOS task.

xTaskCreate(windDirectionTask, "WindDirectionTask", 1024, NULL, TASK_PRIORITY, &windDirectionTaskHandle);

the data variable below starts at 95 for the first few iterations then changes to 1023 forever:


void windDirectionTask(__unused void* pvParameters) {
  int chan = 0;
  uint8_t buffer[3];
  buffer[0] = 1;
  buffer[1] = (8 + chan) << 4;
  buffer[2] = 0;

  while(true) {
    cs_select();
    sleep_ms(10);

    uint8_t returnData[10];
    spi_write_read_blocking(SPI_PORT, buffer, returnData, sizeof(buffer));
    int data = ( (returnData[1]&3) << 8 ) | returnData[2];
    cs_deselect();
    sleep_ms(10);

    getDirectionFromADCValue(data, windDirectionName);

    vTaskDelay(pdMS_TO_TICKS(1000));
  }
}

Is there a standard way to use spi from a task? The task reads an ADC which reads the voltage from a wind vane.

Turns out I’m using FreeRTOS-FAT-CLI-for-RPi-Pico with an SPI sd card. Not running that task solves the problem. As soon as the sd card is written to via SPI the ADC return value is always 1023.

They are both on the same spi bus and the sd card task runs while the wind direction task is reading from the bus. Beginner error it seems and better synchronisation needed in the code!

Seems that cs_(de)select() stops working as a wild guess.
How is it implemented ? Are there possible race conditions manipulating the /CS pin of the associated GPIO port ?
There is no standard way of doing SPI or other HW handling. It depends on HW capabilities and the way one want to use the HW interface.
Edit: When using the same SPI controller from multiple tasks you need proper protection e.g. using a mutex lock enclosing the (SPI) transactions appropriately.