cancel
Showing results for 
Search instead for 
Did you mean: 

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

Essometer
Visitor

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.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

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
Guru

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
Visitor

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