cancel
Showing results for 
Search instead for 
Did you mean: 

How do I move data continuously over DMA from an array in memory to a 8-bit set of GPIO pins/bus? I feel like this should be simple, but I am majorly stumped. I am using an STM32H7 Nucleo board.

thoughtbot
Associate II
 
1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

Set up a timer to trigger a periodic DMA transfer. Set up that DMA stream to transfer between an array to GPIOx->BSRR. Only works if all pins are on the same port. Frequency will be limited so something on the order of 10 MHz.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

5 REPLIES 5
TDK
Guru

Set up a timer to trigger a periodic DMA transfer. Set up that DMA stream to transfer between an array to GPIOx->BSRR. Only works if all pins are on the same port. Frequency will be limited so something on the order of 10 MHz.

If you feel a post has answered your question, please click "Accept as Solution".

0693W00000HnhZeQAJ.jpgWant a 16-bit write to ODR, or 32-bit to BSRR, would suggest the latter as you can pick the pins you want to leave an those you want to touch.

Seem to recall the GPIO is on AHB4, so perhaps SRAM4 via BDMA

I built an example the other week or two ago, and there was a thread

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

@Community member​ 

I looked for a minute on your profile and couldn't find that thread. Any chance you might be able to link it here?

After reading up on the H7 series, its looking like I have a few things I will need to do because of the problems with the M7's d-cache having issues with the DMA. I don't want to globally disable d-cache, as I will be doing more than just DMA transfers here, but yeah. The rabbit hole goes deeper on...

@TDK​ 

Your idea is kind of similar to what my team and I had hoped to do for this project initially, but we are running in to all kinds of strange errors with the H7 series that were unexpected. Ethernet and DMA alike seem to have little quirks in memory configuration and such that make this more complicated than necessary.

Thanks for your help all!

Simple way:

  1. Configure timer + circular mode + DMA
  2. Generate code
  3. Find HAL_TIM_Base_Start_DMA() function, copy-paste it to user code with a different name, for example MY_TIM_Base_Start_DMA().
  4. In renamed function find HAL_DMA_Start_IT() and replace TIMER register with GPIO register:
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE],
     (uint32_t)pData,
     (uint32_t)&htim->Instance->ARR, // before
     Length) != HAL_OK)
 
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE],
     (uint32_t)pData,
     (uint32_t)&GPIOA->ODR, // after
     Length) != HAL_OK)

Use MY_TIM_Base_Start_DMA to start timer before main loop.

Also can be used with input capture + dma to provide external clock for data output, then you alter HAL_TIM_IC_Start_DMA(). Copy-paste it to user code, rename to MY_TIM_IC_Start_DMA and alter destination to GPIO register

Any chance to see a list of "strange errors" you team is running into?