cancel
Showing results for 
Search instead for 
Did you mean: 

Transaction error trying to use DMA to write to GPIO

Elin
Visitor

I've been trying to set up a timer and DMA to run a synchronous parallel bus onto a GPIO. The timer works great but the DMA keeps failing with a transaction error interrupt and disables the stream. This is on an STM32F413 chip and using TIM2_CH1 as a PWM output and DMA1 Stream 1 connected to TIM2_UP event. The DMA is configured as below:

  static uint16_t _waveform[2];
  _waveform[0] = 0x0555;
  _waveform[1] = 0x0AAA;

  LL_DMA_SetChannelSelection(DMA1, LL_DMA_STREAM_1, LL_DMA_CHANNEL_3);
  LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_STREAM_1, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
  LL_DMA_SetStreamPriorityLevel(DMA1, LL_DMA_STREAM_1, LL_DMA_PRIORITY_VERYHIGH);
  LL_DMA_SetMode(DMA1, LL_DMA_STREAM_1, LL_DMA_MODE_CIRCULAR);
  LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_STREAM_1, LL_DMA_PERIPH_NOINCREMENT);
  LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_STREAM_1, LL_DMA_MEMORY_INCREMENT);
  LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_1, LL_DMA_PDATAALIGN_HALFWORD);
  LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_1, LL_DMA_MDATAALIGN_HALFWORD);
  LL_DMA_DisableFifoMode(DMA1, LL_DMA_STREAM_1);
  LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_1, (uint32_t)&GPIOD->ODR);
  LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_1, (uint32_t)_waveform);
  LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_1, 2);

  LL_TIM_EnableDMAReq_UPDATE(TIM2);

All of GPIOD is configured as outputs and as soon as DMA1 receives the DMA request from the timer I get an interrupt with TEIF1 set. I've been looking around at various similar solutions and I don't think I'm doing anything wrong?

4 REPLIES 4
mƎALLEm
ST Employee

Hello @Elin and welcome to the community,

Please refer to this thread. The OP is using DMA2.

 

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Elin
Visitor

Yes, I was looking at that post earlier and comparing with my own code and from what I can tell it's pretty much identical except different DMA and Timer. Surely this should work with DMA1 as well?

TDK
Super User

> Surely this should work with DMA1 as well?

There is no link between DMA1 and AHB1, where GPIOD is located. Use DMA2.

TDK_0-1747839416455.png

 

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

Use DMA2 not DMA1. This is what I've indicated in my post.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.