SPI1.transfer() with NULL callback

I’m trying to piece together a library to use some 1Gb SPI flash and I’m a little confused about how the SPI1.transfer() function is supposed to work when you use a NULL callback function. According to the docs:

If NULL is passed as a callback then the result is synchronous i.e. the function will only return once the DMA transfer is complete.

I had assumed this means that the code would basically stop executing until the SPI1.transfer() was complete, however, that doesn’t appear to be how it’s working. When I execute the following code, the 2nd digital write happens long before the transfer is complete causing D5 (SS) to go high (which causes the slave to ignore the rest of the transmission). tx_buffer and rx_buffer are both of size len.

digitalWrite(D5,LOW); 
SPI1.transfer(tx_buffer, rx_buffer, len, NULL);
digitalWrite(D5,HIGH); 

I can calculate how long each transfer should take and add a delay and that solves the problem but i’m trying to figure out if this is how it’s supposed to work since this doesn’t feel like a very robust solution.

digitalWrite(D5,LOW); 
SPI1.transfer(tx_buffer, rx_buffer, len, NULL);
delayMicroseconds(writeDelay);
digitalWrite(D5,HIGH);

Anyone have any ideas?

We will be releasing 0.5.x as a prerelease this week. It includes some fixes, including the timing of the DMA callback and waiting for the function to return.

Ah, thanks @mdma! Looks like I finally have a reason to finish figuring out how to get my local toolchain up and running.

Just to follow up - it looks like the NULL callback hasn’t been properly implemented by the original developer. We’re looking into it now. The 0.5.0 pre-release is going out today, and won’t contain a fix for this. In the interim, you could do something like:

void dma_done()
{
   dma_done_flag = true;
}

void loop()
{
    dma_done_flag = false;
    SPI.transfer(.... dma_done, dma_done);
    whiel (!dma_done_flag);
}