2026-03-13 5:58 AM - edited 2026-03-13 6:02 AM
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!
Solved! Go to Solution.
2026-03-13 6:09 AM - edited 2026-03-13 6:10 AM
This can't be done. The GPIO ports are not accessible to the DMA on the STM32G0x0.
2026-03-13 6:09 AM - edited 2026-03-13 6:10 AM
This can't be done. The GPIO ports are not accessible to the DMA on the STM32G0x0.
2026-03-13 6:10 AM - edited 2026-03-13 6:11 AM
Do you know where this can be found in the datasheet / reference manual, so that I can check whether other CPUs support this?
2026-03-13 6:13 AM
Search for "system architecture" in the Reference Manual.
2026-03-13 6:14 AM
I misread this as being connected to AHB 🤦