SPI over DMA circular mode

Hi all,
has anyone been successful in implementing SPI over DMA in circular mode (Tx or TxRx) in connection with libdaisy?
I have no problem implementing that using STM32Cube, but i would rather want to use libdaisy because of the QSPI infrastructure that i would otherwise have to redo.

The problem i am having is that the IRQs (i.e., half and full DMA callbacks) are not called periodically although the DMA transfer is running as seen in the oscilloscope.
I am using DMA2 to avoid resource conflicts with libdaisy.

I have tried to debug as much as possible and it seems the HAL_DMA_IRQHandler gets stuck with DME error which is really strange.
I have tried disabling most unneeded functionality in libdaisy, to no avail.

Working example code would be really helpful.
Thanks, Thomas

I’ve only used single transfer DMA for SPI on Daisy (and not using libDaisy itself), so can’t help with this issue.

But I can tell you that decoupling QSPI functions from libDaisy and using it from the Cube generated project is fairly straightforward. I did that for porting OWL firmware to Daisy Patch and it worked well.

SPI via DMA is coming really soon (in a similar overhaul as what happened with I2C). This is the next libdaisy thing I’ll be working on adding. Do you have a specific device you’re working with so I can keep it in mind while adding support?

FWIW you should be able to include the HAL files, and overwrite whatever you need. (sys/dma.c will be a good indicator on which DMA streams are currently in use).

On an F7 processor I have done circular DMA SPI Tx with SPI4 and DMA2 Stream1, but many of the peripherals are a bit different.

That said, it looks like either the configuration you have is invalid, or something else is wrong (most likely within the init code).

From the reference manual page 654:

Direct mode error: the direct mode error interrupt flag (DMEIFx) can only be set in the
peripheral-to-memory mode while operating in direct mode and when the MINC bit in
the DMA_SxCR register is cleared. This flag is set when a DMA request occurs while
the previous data have not yet been fully transferred into the memory (because the
memory bus was not granted). In this case, the flag indicates that two data items were
be transferred successively to the same destination address, which could be an issue if
the destination is not able to manage this situation

Hi all, thank you for your thoughts.

The SPI interface is not used to communicate to a device, but rather to transmit a 1-bit audio stream at about 3 MHz sample rate (64-fold oversampling) over a laser link and to receive it again. This is running as an installation:

Currently, we have a STM32F407 in operation, but in combination with the flash memory it is a tiny bit too slow. As said, i have been able to use that and also the daisy’s STM32H7 successfully with the Cube IDE and the configuration stays exactly the same in combination with libdaisy, except the clock setup. I have no idea whether this could be the reason - the SPI clock rate is in a quite moderate range.

Anyways, dear Stephen, looking forward to your code!



That looks amazing! Woah!!! What a seriously cool installation, and I love the concept of the room itself corrupting the audio.

It could be a clock related issue if something isn’t configured quite right for that SPI peripheral (or for DMA2) in libdaisy. But I’ll be getting to that in about a week or two probably. So I’ll keep you posted!

1 Like

Ok, I see, it’s the dust that corrupts DMA transfers. Case solved!

Hahaha that’s a good point, if the dust is making the SPI signal an invalid message, the peripheral could be throwing errors for that.

You can probably still get it to work, but you’ll have to manage the ErrorCallback, and clear whatever flags (or just disable those error IRQs). Though, if you can run it from Cube generated files without the same error then it is just some software or clock config somewhere in libdaisy tripping up your DMA config.

Hehe, no, the dust is fine!
There is no external logic, the SPI interface simply pumps out a bit stream and reads it again with the same clock and no CRC.
Btw., for the current test purposes MOSI is cable-bridged to MISO, without dust.

It was meant to be a joke, not sure how Stephen ended up taking it seriously.

OTOH, it’s probably worth checking if this could be a bug in ST HAL if those builds used different version. I recall they had half-broken I2S in circular mode, won’t be surprised if something like this happens for other peripherals.

1 Like

I took it as a joke with the possibility of some validity. :smile:

Definitely worth looking into whether its a HAL bug, though if it is a different version than in libdaisy. Which, if you’re generating from cube it’s probably a newer version.

I haven’t seen them too often, but there is/was one in the blocking SDMMC stuff that did some loop unrolling to fill the FIFO without checking the size of the buffer.

Hi all,
i found the problem, and i am ashamed to say it was a trivial programmer error, namely a local variable name shadowing a global one.
It is working now, will deploy the daisy soon as part of the installation.

I bet that you’ve missed it earlier because dust corrupted your eyesight!

On a serious note, you should be getting about x3.5 higher CPU performance from such upgrade. And if that won’t be enough, libDaisy currently configures it to only 400MHz for compatibility with older MCU revision. You can get +20% higher clock if you reclock it to standard 480Mhz and looks like you don’t need an explanation how to do it.

1 Like

Yes, although the clock rate is not an issue.
With the F4 i had serious troubles because of an extremely tight timing betwen SPI I/O and flash memory, even with all copying processes running on DMA.
The installation uses 16MiB of RAM as a ringbuffer, previously in flash, with the daisy now in SDRAM.
This is also solves the problem of flash RAM degrading over time, which is an issue for the installation constantly transferring data over months of runtime.