Slow SPI in Particle Argon

Hi there
Trying to drive an SPI display with a Particle Argon. The display refresh is painfully slow (taking about 2 seconds to refresh 240 lines). To investigate, I wrote a simple program sending data over the SPI port:

#define BLUE_LED D7

// setup() runs once, when the device is first turned on.
void setup() {
  // Put initialization like pinMode and begin functions here.
  pinMode (BLUE_LED, OUTPUT);

  SPI.begin();
}

void loop() {

    SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
    for (int i=32; i<96; i++){
      SPI.transfer(i);
    }
    SPI.endTransaction();

}

I can see the bursts of SPI transfer (8-bit) in the scope measuring less than 1 microsecond, but then pausing for about 12 microseconds before the next byte is transferred.

Can this be improved? I know there’s the possibility of using DMA to transfer but it comes with its complications and I would have to start modifying the display library, which I’d prefer not to do.

I also tried using SINGLE_THREADED_BLOCK(){} but no difference.

Any suggestions out there?

Definitely switch to using the DMA-based SPI.transfer API instead of the single byte API you are using.

1 Like

That worked. Fortunately the display driver was written to send large buffers at a time, so it was easy to adapt. But I still feel that writing individual bytes should not take that long to transfer.

This is the code that I used:

//callback and flag for DMA SPI transfer ready
volatile bool tranferReadyFlag = false;
void transferReady(){
  tranferReadyFlag = true;
}

//modified WRITEBUF function
INLINE void Arduino_HWSPI::WRITEBUF(uint8_t *buf, size_t count)
{
  //Modified to use Particle DMA SPI transfer
  tranferReadyFlag = false;
  SPI.transfer(buf, buf, count, transferReady);
  //wait until DMA transaction is complete
  while (!tranferReadyFlag);
}