Skip to main content
Associate II
March 13, 2026
Solved

Timer triggered DMA Memory to GPIO output on the STM32G070RB

  • March 13, 2026
  • 2 replies
  • 91 views

Hello, I have used DMA for timer outputs, input compares, memory to memory, etc. and all has worked fine, however I can't seem to get a timer-triggered DMA from memory to GPIO outputs (as this post seems to have managed).

I have tried using the ODR register, the BSRR register, 16 bit transfers, 32 bit transfers, reordering the initialisation of different components, setting TIM1->DIER = TIM_DIER_UDE in different places, etc. etc. The timer is definitely incrementing and resetting correctly and I am getting a TEIF1 on DMA1.

I am less familiar with DMAMUX (I used the F401 previously) so I may be making a mistake there.

#include <stdio.h>

#include "main.h"

#include "stm32g0xx_hal_tim.h"

void SystemClock_Config(void);

static TIM_HandleTypeDef htim1 = {0};
static DMA_HandleTypeDef hdma = {0};

#define GPIO_BUF_LEN 4

static uint32_t gpio_buf[GPIO_BUF_LEN] = {
 0xFFFFFFFF,
 0x00000000,
 0xFFFFFFFF,
 0x00000000,
};

static void Init_GPIO(void) {
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_TIM1_CLK_ENABLE();
 __HAL_RCC_DMA1_CLK_ENABLE();

 GPIO_InitTypeDef gpio = {
 .Pin = GPIO_PIN_5,
 .Mode = GPIO_MODE_OUTPUT_PP,
 .Pull = GPIO_NOPULL,
 .Speed = GPIO_SPEED_FREQ_MEDIUM,
 };
 HAL_GPIO_Init(GPIOA, &gpio);

 hdma.Instance = DMA1_Channel1;
 hdma.Init.Request = DMA_REQUEST_TIM1_UP;
 hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
 hdma.Init.PeriphInc = DMA_PINC_DISABLE;
 hdma.Init.MemInc = DMA_MINC_ENABLE;
 hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
 hdma.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
 hdma.Init.Mode = DMA_CIRCULAR;
 hdma.Init.Priority = DMA_PRIORITY_HIGH;
 HAL_DMA_Init(&hdma);
 __HAL_LINKDMA(&htim1, hdma[TIM_DMA_ID_UPDATE], hdma);

 htim1.Instance = TIM1;
 htim1.Init.Prescaler = 3200 - 1;
 htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim1.Init.Period = 10000 - 1;
 htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim1.Init.RepetitionCounter = 0;
 htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;

 HAL_TIM_Base_Init(&htim1);
 
 __HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE);
 HAL_DMA_Start(&hdma,
 (uint32_t)gpio_buf,
 (uint32_t)&GPIOA->ODR,
 GPIO_BUF_LEN);

 HAL_TIM_Base_Start(&htim1);
}


int main(void)
{
 HAL_Init();
 SystemClock_Config();

 Init_GPIO();

 while (1)
 {
 printf("%i\n", DMA1->ISR);

 // GPIOA->BSRR = (GPIO_PIN_5 << 16);
 // HAL_Delay(500);
 // GPIOA->BSRR = GPIO_PIN_5;
 // HAL_Delay(500);

 // HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, (TIM1->CNT < 5000) ? GPIO_PIN_SET : GPIO_PIN_RESET);
 // HAL_Delay(500);
 }
}

Thanks!

 

Best answer by TDK

This can't be done. The GPIO ports are not accessible to the DMA on the STM32G0x0.

Screenshot 2026-03-13 090805.png

2 replies

TDK
TDKBest answer
Super User
March 13, 2026

This can't be done. The GPIO ports are not accessible to the DMA on the STM32G0x0.

Screenshot 2026-03-13 090805.png

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

Do you know where this can be found in the datasheet / reference manual, so that I can check whether other CPUs support this?

TDK
Super User
March 13, 2026

Search for "system architecture" in the Reference Manual.

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

Screenshot 2026-03-13 131401.png

I misread this as being connected to AHB 🤦