Skip to main content
abdullah jalloul
Associate
March 4, 2019
Question

STM32F407 Timer->DMA->GPIO

  • March 4, 2019
  • 3 replies
  • 1314 views

Hello

I'm trying to use DMA to directly write on GPIO port, and I've attached the code snippet I'm using to do so.

But, I'm getting this exception which is stopping the DMA and fails writing data.

Any thoughts?

Regards.

GPIO Init:

__HAL_RCC_GPIOD_CLK_ENABLE();
 
 /*Configure GPIO pin Output Level */
 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15, GPIO_PIN_RESET);
 
 /*Configure GPIO pins : PD12 PD13 PD14 PD15 */
 GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

TIM6 Init:

void MX_TIM6_Init(void)
{
 
 TIM_MasterConfigTypeDef sMasterConfig = {0};
 
 htim6.Instance = TIM6;
 htim6.Init.Prescaler = 79;
 htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim6.Init.Period = 99;
 if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
 {
 Error_Handler();
 }
 sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
 sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
 if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
 {
 Error_Handler();
 }
}

DMA Init:

void MX_DMA_Init(void) 
{
 /* DMA controller clock enable */
 __HAL_RCC_DMA1_CLK_ENABLE();
 
 /* DMA interrupt init */
 /* DMA1_Stream1_IRQn interrupt configuration */
 HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
 
}
 
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
 if(htim_base->Instance==TIM6)
 {
 /* Peripheral clock enable */
 __HAL_RCC_TIM6_CLK_ENABLE();
 
 /* TIM6 DMA Init */
 /* TIM6_UP Init */
 hdma_tim6_up.Instance = DMA1_Stream1;
 hdma_tim6_up.Init.Channel = DMA_CHANNEL_7;
 hdma_tim6_up.Init.Direction = DMA_MEMORY_TO_PERIPH;
 hdma_tim6_up.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma_tim6_up.Init.MemInc = DMA_MINC_ENABLE;
 hdma_tim6_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
 hdma_tim6_up.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
 hdma_tim6_up.Init.Mode = DMA_CIRCULAR;
 hdma_tim6_up.Init.Priority = DMA_PRIORITY_HIGH;
 hdma_tim6_up.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
 if (HAL_DMA_Init(&hdma_tim6_up) != HAL_OK)
 {
 Error_Handler();
 }
 
 __HAL_LINKDMA(htim_base,hdma[TIM_DMA_ID_UPDATE],hdma_tim6_up);
 
 }
 
}

Start Transfer:

uint32_t blink_led[2] = {
	(uint32_t)GPIO_PIN_13, 		// bit = 0
	(uint32_t)GPIO_PIN_13 << 16 // bit = 1
};
 
void DMA_Start_Transfer(void) {
HAL_DMA_Start_IT(htim6.hdma[TIM_DMA_ID_UPDATE], (uint32_t)&blink_led, (uint32_t)&GPIOD->BSRR, 2);
	__HAL_TIM_ENABLE_DMA(&htim6, TIM_DMA_UPDATE);
	__HAL_TIM_ENABLE(&htim6);
}

This topic has been closed for replies.

3 replies

S.Ma
Principal
March 4, 2019

Hmmm in the STM32F407, if you want to write GPIO register at precise timer interval, it might not work.

The trigger signal for DMA is the timer, until the request is cleared. by moving data from memory to GPIO, this doesn't clear the pending timer request and probably only the first time it works then got stuck, or it repeteadly frenetically transfer taking the whole bandwidth?

I think the STM32L4R has DMAMUX which seems to enable TIMER DMA GPIO operations.

To be confirmed.

waclawek.jan
Super User
March 4, 2019

> I'm getting this exception

What exception?

If it's the DMA FIFO error, and you don't have FIFO enabled, then ignore it (best, don't enable the Fifo error interrupt).

I don't use Cube/CubeMX so don't know how to achieve that in Cube.

JW

abdullah jalloul
Associate
March 4, 2019

Hi waclawek.jan

Could you please toss me a working snippet so I can configure my code

Regards.