2025-04-25 5:11 PM
Hello, I am currently pretty stumped over the behaviour of the DMA triggered by a timer.
I want to use the DMA to toggle a GPIO pin using a timer for the right frequency. I am currently using the DMA driver from Zephyr. MY board is the STM32G071RB.
I want to use the TIM15 update event to trigger a DMA transfer from memory to BSRR to toggle a pin. The code setup is posted below. My problem is that this setup works for a memory to memory setup, e.g tx_data -> rx_data without problem, the callback is called with status 0 and the data is transferred.
However, if I set the dest_address to BSRR, in my case to 0x50000018, nothing happens. No transfer, no callback and no pin toggle whatsoever.
static struct dma_block_config dma_block_cfg = {
.dest_address = (uint32_t)rx_data,
.source_address = (uint32_t)0x50000014,
//.dest_address = (uint32_t)rx_data,
.block_size = sizeof(tx_data),
.source_addr_adj = DMA_ADDR_ADJ_INCREMENT,
.dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE
};
static struct dma_config dma_cfg = {
.dma_slot = LL_DMAMUX_REQ_TIM15_UP,
.channel_direction = MEMORY_TO_PERIPHERAL,
.complete_callback_en = 0,
.error_callback_dis = 1,
.source_data_size = sizeof(uint32_t),
.dest_data_size = sizeof(uint32_t),
.source_burst_length = 1,
.dest_burst_length = 1,
.block_count = 1,
.channel_priority = 0x03,
.head_block = &dma_block_cfg,
.dma_callback = &dma_complete
};
static void link_set_up_timer()
{
volatile int ret = dma_config(dma, 1, &dma_cfg);
ret = dma_start(dma, 1);
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM15);
LL_RCC_SetTIMClockSource(LL_RCC_TIM15_CLKSOURCE_PLL);
LL_TIM_SetCounterMode(TIM15, LL_TIM_COUNTERDIRECTION_UP);
LL_TIM_SetUpdateSource(TIM15, LL_TIM_UPDATESOURCE_COUNTER);
LL_TIM_SetAutoReload(TIM15, ARR_VALUE);
LL_TIM_SetCounter(TIM15, 0);
LL_TIM_SetPrescaler(TIM15, 0);
LL_TIM_EnableDMAReq_UPDATE(TIM15);
LL_TIM_EnableIT_UPDATE(TIM15);
LL_TIM_GenerateEvent_UPDATE(TIM15);
LL_TIM_EnableAllOutputs(TIM15);
LL_TIM_SetTriggerOutput2(TIM15, LL_TIM_TRGO2_UPDATE);
LL_TIM_SetTriggerOutput(TIM15, LL_TIM_TRGO_UPDATE);
LL_TIM_EnableCounter(TIM15);
return;
For me it feels like the GPIO address is not writable by the DMA. I also tried to set the direction to memory to memory and write half_words and bytes with the same result. Can someone please shed some light? That would be very appreciated.
Solved! Go to Solution.
2025-04-25 6:09 PM
The GPIO ports are not connected to the DMA bus on this chip.
You're probably getting an error flag in the DMA when you start the transfer.
2025-04-25 6:09 PM
The GPIO ports are not connected to the DMA bus on this chip.
You're probably getting an error flag in the DMA when you start the transfer.
2025-04-26 2:07 AM - edited 2025-04-26 2:07 AM
Thank you so much. I completely missed that and would have probably sunken so many hours into it.