cancel
Showing results for 
Search instead for 
Did you mean: 

Transaction error trying to use DMA to write to GPIO

Elin
Associate II

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?

1 ACCEPTED SOLUTION

Accepted Solutions
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".

View solution in original post

5 REPLIES 5
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
Associate II

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.
Elin
Associate II

I see now. I was trying to find something like that bus matrix table before but didn't know where to look. That makes sense then why it wouldn't work. Now I need to modify our hardware since it's locked into TIM2 which can't be used with DMA2.

Thanks for the quick help anyway!