cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 Timer->DMA->GPIO

abdullah jalloul
Associate

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);
}

3 REPLIES 3
S.Ma
Principal

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.

> 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

Hi waclawek.jan

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

Regards.