Interrupt handlers for dma events on the photon

Class STM32f2xx examples use a static c function + weak linking like:

void DMA1_Stream5_IRQHandler(void)

Now I learned already that this won’t work on the photon since it dynamically loads the user code. I also found this api:

  • attachSystemInterrupt() (since 0.4.2), but that only covers timers and a few extra ones
  • attachInterrupt() only for pins

but none of this covers DMA. I wrote a SPI code for accessing an sdcard and if I want to use DMA instead of polling I need to know when transfers have finished. Likewise I want to stream audio by using the double-buffer dma feature and I need to know when one buffer is done. This is all doable, but I need to someone be able to setup my irq handlers.

So what is the secret api that I am missing?

1 Like

For the SD side of things you might like to readup on this
https://docs.particle.io/reference/firmware/photon/#transfer-void-em-void-em-size_t-std-function-

This also provides a way to supply callback function when done.

And if you want to use a similar aproach for other things, you can have a look in the open source repo, how the SPI is implemented.

Another aproach would be multi threading
e.g. look here
Particle Photon multi blink sample using threads

Thanks for your reply. I am using fatfs and I have implemented the whole spi layer in ‘c’ to be able to easily sit under fat-fs (yes I know extern “C”). But from the C code I can’t easilly use the functions from the wiring library.

So I am not really looking for alternatives to my spi layer, I am merly looking for how to get register my irq handlers.

Fair enough.

Otherwise if you only looked for a working SD library I’d have suggested this one
https://github.com/head-labs/sd-card-library

I know, but this is GPL unfortunately and the DMA code is polling for the status. The code for dma events is disabled:

The commented code references a dma.h and that seems to be comming from https://github.com/leaflabs/libmaple. But I can’t just pull that in, since the irq handlers need to be managed by the system.

One more thing I noticed. Never, ever call DMA_ITConfig, this will freeze the photon, once the irq triggers :confused: .

Not to necrobump, But if I am correct, this issue is still not resolved in the latest firmware.

I am trying to push data from a buffer to the DAC and have a interrupt trigger on the completion of said data.

Lacking the ability to create an interrupt handler for anything other than the listed system interrupts I think I have 2 options, and please let me know if I am missing something or if there is a better way,

  1. Local copy of the firmware and write in the missing system interrupts that were overlooked from “hal/inc/interrupts_irq.h”

  2. Configure DMA in dual buffer circular mode and have a loop watching the DMA_SxCR CT flag to fill the buffer appropriately.

The problem with these two methods is that 1) Requires me to have a working offline compiler, which for the life of me I can’t work past the errors to get working. And 2) Implies I can fill the buffer before the DMA finishes with the previous, which in the case of pulling data from the internet, is and uncertainty.

Thank you.

Hello @konstantinMTS

I think that any time you are trying to use low-level features of a given CPU chip such as DMA and interrupts that are not part of the Arduino-compatible Wiring API, you really should be using the local gcc compile.

I would suggest two things:

  • File an issue on github for the firmware to add the interrupt you are interested in to the HAL layer. I would not say that these were “overlooked”; I would say there was no use case at the time for their use in this advanced manner.

  • Get the local toolchain installed. I am going to assume you are on Windows since I have installed on Ubuntu and Mac and it is not hard to get working. One Windows there are some “gotchas” mostly having to do with emulating the Unix world on a PC. Perhaps @ScruffR or @Moors7 have some advice here.

You should be able to use all (or most) of the STM32F features by just sticking to ST’s programming guidelines.
The cloud compiler should support it just as well although you might have to track back some steps introduced by the framework (e.g. NVIC table setup).

But @rickkas7 or @peekay123 may have something on that already.

Setting up a toolchain on Windows isn’t that difficult either.
I’ve used @mumblepin’s toolchain installer - which may be a bit dated by now - but it’s no black magic :wink:

2 Likes

Actually I’m on 4.9.7-1-ARCH Linux, It may be the source of issues with my gcc version.

ScruffR, it is my understanding that due to the way the wiring is configured, there is no way to have the DMA stream 6 interrupt called using the online compiler since it was not declared in the previously mentioned file. Am I correct in that?

Sounds like getting a local compiler is the recommended path rather than loop-watching the buffer use.

Thank you fer the advice all!

1 Like

Most of the STM32F205 peripheral setup can be overridden from user code… except for interrupt handlers. I’ve run into that before as well, and if the interrupt is not brought out, you unfortunately either have to poll or do a local build. Local build is not that scary, we even have an offical FAQ for it.

In my audio3 sample, the code does DMA from the ADC into double buffers. The unloading of the buffers and sending them out by TCP works from loop and polling, as it’s not actually that time-sensitive and that works quite well. That won’t be possible in all situations, of course.

1 Like