cancel
Showing results for 
Search instead for 
Did you mean: 

Is it possible to trigger a DMA transfer from memory to SPI by a TIM update event?

Noel0319
Visitor

I was finishing a project that does the job of hi-speed polling from a SPI interfaced IMU chip, the frequency is about 5Khz, I know that this could be done by start a DMA transfer by software in the hardware update interrupt. But now I'm searching for a faster solution. Since the interrupt may take a very small period, when the amount of sensor chip or polling frequency increases, the whole cost of context switch may be a problem.

I'm asking that is it possible to use a timer update event to trigger a DMA transfer without using any interrupt (at least, don't trigger the interrupt every time when a poll finishes).

There was a blog that I read says that change the request source could do this job, what he means actually looks like the code below:

    hdma_spi1_tx.Instance = DMA1_Channel6;
    hdma_spi1_tx.Init.Request = DMA_REQUEST_TIM2_UP;
    hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
    hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_spi1_tx.Init.Mode = DMA_NORMAL;
    hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;

Which was simply changed the CubeMX generated code. I have already been a user of ST MCUs for many years and before I tried that I knew the solution may not work and actually it just didn't work.

But just 2 years before now I find the module named DMAMUX, at that time I was obsessed with it and thought it may be the silver bullet for all efficient transmission but now I still not clear about it.

Finally I found a trick to achieve the goal, but I have never seen anyone mentioned it, which is not possible to be configured in  CubeMX. This trick is explained as below:

1.Configure the pwm output (to pin) of a timer;

2.Configure the EXTI line at the same pin (use pin stacking function and make sure the pwm genenration is at top);

3.Configure the DMA Generator, using synchronization signal of EXTI, and SPI transmission is synchronized by the DMA Generator;

4.Add the code of EXTI configuration since Cube MX won't generate two functions code on one conflict pin. 

In summary this solution route the trigger signal as TIM->EXTI->DMA Generator->SPI DMA. Due to the long time that has passed since I firstly tried this, some details are forgotten by me, but I'm certain that it actually works except that this would cost a pin resource inevitably.   

So, I'm looking for a better solution that will not cost any pin resource and could achieve the performance as the one I mentioned above or just tell me the trick I tried was just an accident.

3 REPLIES 3
waclawek.jan
Super User

There's no need to involve a pin and EXTI, I see no reason why the DMA could not be triggered from the timer Update event.

However, Cube/HAL may not support that, so simply go for direct registers programming.

JW

Thanks for replying. Registers programming is still too hard for me and I got the deadline to finish this before the end of this week :loudly_crying_face:.I tried changing the request in the Cube generated code directly and still didn't work. 

I'm afraid to waste your time to ask a full example of reg programming, so I will be happy if you can just tell me what's the key to make tim update event triggering DMA transfer <3.

Pavel A.
Super User