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!

 

 

0 REPLIES 0