cancel
Showing results for 
Search instead for 
Did you mean: 

Using Timer to trigger DMA event to write into GPIO->BSRR

Essometer
Associate

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;
View more

 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.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Super User

The GPIO ports are not connected to the DMA bus on this chip.

TDK_0-1745629752342.png

 

You're probably getting an error flag in the DMA when you start the transfer.

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

2 REPLIES 2
TDK
Super User

The GPIO ports are not connected to the DMA bus on this chip.

TDK_0-1745629752342.png

 

You're probably getting an error flag in the DMA when you start the transfer.

If you feel a post has answered your question, please click "Accept as Solution".
Essometer
Associate

Thank you so much. I completely missed that and would have probably sunken so many hours into it.