cancel
Showing results for 
Search instead for 
Did you mean: 

F429 - DMA - Memory to Peripheral Broken!

PSPF
Associate II

Hi All,

I am having trouble with DMA transfers using a F429.

I am using DMA1, Channel2, Stream6 - regulated by TIM4 Updates.

It is a memory to perpheral, 32 bit, single transfer, double buffer Off - from Flash (AHB3) to GPIOG (AHB1).

However, it breaks on the first attempted transfer with setting TEIF6 in the DMA_HISR register - I have NO idea why!

According to the data sheet I am doing everything right.

Can anyone tell me why?

Thanks

PSPF

8 REPLIES 8
TDK
Guru

I bet if you showed your code, someone could spot the bug. The reference manual lists a number of conditions that will trigger TEIF. You're likely causing one of those.

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

Thank you for your reply TDK.

I am using STM32CubeIDE. Not shown in the code below, but I have setup break points so I could examine the the registers;-

DMA CR = 0x04025540

DMA PAR = 0x40021818

DMA M0AR = 0x08004D0C

DMA NDTR = 3

DMA FCR = 0x20

....

#define TryDMA_Pin GPIO_PIN_0

#define TryDMA_GPIO_Port GPIOG

static const uint32_t GPO[] = {TryDMA_Pin, TryDMA_Pin << 16,

      TryDMA_Pin, TryDMA_Pin << 16,

      TryDMA_Pin, TryDMA_Pin << 16,

      TryDMA_Pin, TryDMA_Pin << 16};

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();

 MX_DMA_Init();

 MX_TIM4_Init();

 HAL_DMA_Start(&hdma_tim4_up, (uint32_t)RAMTab, (uint32_t)&TryDMA_GPIO_Port->BSRR, 4);

 htim4.Instance->DIER |= TIM_DIER_UDE;

 HAL_TIM_OC_Start(&htim4, TIM_CHANNEL_2);

 while (1)

 {

 }

static void MX_DMA_Init(void)

{

 /* DMA controller clock enable */

 __HAL_RCC_DMA1_CLK_ENABLE();

 /* DMA interrupt init */

 /* DMA1_Stream6_IRQn interrupt configuration */

 HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 0, 0);

 HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn);

}

static void MX_TIM4_Init(void)

{

 TIM_ClockConfigTypeDef sClockSourceConfig = {0};

 TIM_SlaveConfigTypeDef sSlaveConfig = {0};

 TIM_MasterConfigTypeDef sMasterConfig = {0};

 TIM_OC_InitTypeDef sConfigOC = {0};

 htim4.Instance = TIM4;

 htim4.Init.Prescaler = 84;

 htim4.Init.CounterMode = TIM_COUNTERMODE_DOWN;

 htim4.Init.Period = 1023;

 htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

 if (HAL_TIM_Base_Init(&htim4) != HAL_OK)

 {

   Error_Handler();

 }

 sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

 if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)

 {

   Error_Handler();

 }

 if (HAL_TIM_OC_Init(&htim4) != HAL_OK)

 {

   Error_Handler();

 }

 sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED;

 sSlaveConfig.InputTrigger = TIM_TS_TI1FP1;

 sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_BOTHEDGE;

 sSlaveConfig.TriggerFilter = 0;

 if (HAL_TIM_SlaveConfigSynchro(&htim4, &sSlaveConfig) != HAL_OK)

 {

   Error_Handler();

 }

 sMasterConfig.MasterOutputTrigger = TIM_TRGO_OC2REF;

 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;

 if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)

 {

   Error_Handler();

 }

 sConfigOC.OCMode = TIM_OCMODE_TOGGLE;

 sConfigOC.Pulse = 511;

 sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

 sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

 if (HAL_TIM_OC_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)

 {

   Error_Handler();

 }

 HAL_TIM_MspPostInit(&htim4);

}

In F4, you can't use DMA1 to transfer to GPIO. Use DMA2 (thus TIM1 or TIM8 to trigger the DMA).

JW

prain
Senior III

Are you sure you can transfer data from "Flash memory" using DMA? As I know the flash memory region have special read procedure. ​usually DMA is used to transfer data from/to RAM memory space.

> Are you sure you can transfer data from "Flash memory" using DMA? 

Yes.

See RM0090, Fig.2. Both DMA connect as masters to the slave bus, which goes to the FLASH controller's data port (the same bus to which processor's D-port connects, too).

Of course, it has the respective impact on latencies (i.e. at higher system clocks the FLASH waitstates apply) and interacts with the data cache in ART, exactly in the same way as processors data access through the D-port.

JW

That's a MEMORY to MEMORY transfer, not MEMORY to/from APB1, you need DMA2, it has better plumbing..

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

Thank you everyone for your help.

I will move it to DMA2, and give it a go.

I must admit, I didn't see figure 2 - I did get confused trying to unravel the spiderweb of figure 34...

I will post here the results - hopefully later today.

Thanks again

PSPF

PSPF
Associate II

Thanks everyone - changing it from DMA1 to DMA2 and using TIM8 fixed it...!