cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H563ZIT6: DMA register config problem with different Keil optimization level

YukiAlice
Visitor

Dear Community,

I am currently using NUCLEO144-H563ZI board with STM32H563ZIT6 microcontroller to get ADC data via GPDMA1_CHANNEL1. The problem occurs when I change the optimization level in Keil(MDK-ARM version 5.26.2.0). If the firmware is compiled at optimization level O1, the DMA operate well and data can be read from destination memory. But if the firmware is compiled at optimization level O0, the DMA seems to be stuck in BUSY status. I simulate the process using Keil and find that if I comment out the code in red block in stm32h5xx_hal.c, the DMA can operate well even if at optimization level O0. Please see picture below.

YukiAlice_0-1722416203000.png

Additionally, I find that the DMA register configuration is different at these two optimization level. Please see pictures below.

YukiAlice_1-1722416385828.png

YukiAlice_2-1722416442251.png

And the DMA initialization code as below:

    /* ADC1 DMA Init */
    /* GPDMA1_REQUEST_ADC1 Init */
    NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
    NodeConfig.Init.Request = GPDMA1_REQUEST_ADC1;
    NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
    NodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;
    NodeConfig.Init.SrcInc = DMA_SINC_FIXED;
    NodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;
    NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD;
    NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD;
    NodeConfig.Init.Priority = DMA_HIGH_PRIORITY;
    NodeConfig.Init.SrcBurstLength = 1;
    NodeConfig.Init.DestBurstLength = 1; 
    NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT1 | DMA_DEST_ALLOCATED_PORT1;
    NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    NodeConfig.Init.Mode = DMA_NORMAL;
    
    status = HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel1);
    if (status != HAL_OK)
    {
      MemoryUpdateRegisterByte(TABLE_INDEX_UPPER_PAGE_E4H, DMA_BUILD_NODE_INIT_STATUS, status);
    }
 
status = HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel1, NULL, &Node_GPDMA1_Channel1);
    if (status != HAL_OK)
    {
      MemoryUpdateRegisterByte(TABLE_INDEX_UPPER_PAGE_E4H, DMA_INSERT_NODE_INIT_STATUS, status);
    }
 
status = HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel1);
    if (status != HAL_OK)
    {
      MemoryUpdateRegisterByte(TABLE_INDEX_UPPER_PAGE_E4H, DMA_SET_CIR_MODE_INIT_STATUS, status);
    }
  
    handle_GPDMA1_Channel1.Instance = GPDMA1_Channel1;
    handle_GPDMA1_Channel1.InitLinkedList.Priority = DMA_LOW_PRIORITY_HIGH_WEIGHT;
    handle_GPDMA1_Channel1.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
    handle_GPDMA1_Channel1.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1;
    handle_GPDMA1_Channel1.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
    handle_GPDMA1_Channel1.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
    
    status = HAL_DMAEx_List_Init(&handle_GPDMA1_Channel1);
    if (status != HAL_OK)
    {
    MemoryUpdateRegisterByte(TABLE_INDEX_UPPER_PAGE_E4H, DMA_LIST_INIT_STATUS, status);
    }
 
status = HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel1, &List_GPDMA1_Channel1);
    if (status != HAL_OK)
    {
    MemoryUpdateRegisterByte(TABLE_INDEX_UPPER_PAGE_E4H, DMA_LIST_LINKQ_INIT_STATUS, status);
    }
  
    __HAL_LINKDMA(hadc, DMA_Handle, handle_GPDMA1_Channel1);
 
    status = HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel1, DMA_CHANNEL_NPRIV);
    if (status != HAL_OK)
    {
    MemoryUpdateRegisterByte(TABLE_INDEX_UPPER_PAGE_E4H, DMA_CHANNEL_CONFIG_INIT_STATUS, status);
    }
  
    /* Enable DMA clock */
    __HAL_RCC_GPDMA1_CLK_ENABLE();
    
    /* DMA interrupt Init */
    HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, NVICPreemptionPriority_ADC_DMA, NVICSubPriority_ADC_DMA);
    HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn);
 
Thanks and Regards!

 

 

1 REPLY 1
TDK
Guru

Probably the bug is in other parts of your code, not the initialization. How are you using the DMA? Post a complete example which exhibits the problem.

The difference in C1SR values reflect the HT and TC flags are set in the top example, but not in the bottom. This is consistent with the DMA still being busy.

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