Skip to main content
stst9180
Associate III
May 30, 2025
Solved

CubeMx 6.14.1, GPDMA Standard Request Mode, HAL_DMA_ERROR_DTE

  • May 30, 2025
  • 1 reply
  • 669 views

I like to use the CubeMx 6.14.1 generated code (up2date firmware packages) to use DAC 1+2 with GPDMA in circular mode (Standard-Request-Mode)

The 1st thing that makes me wonder: Although I selected "Standard Request Mode" in CubeMX a configuration for Linked-ListMode is generated. Nevertheless this seems to work with ADC. 
On DAC Channels 1+2 I get a Data-Transfer-Error although I can't figure out a CubeMX missconfiguration for now. 

See my attached .ioc File for Reference.

Expectation: CubeMx generated Standard Request code when selecting this in the GUI. 
Expectation: DAC generates HAL_DAC_CH1_COMPLETE instead of HAL_DAC_CH1_ERROR with DTE bit set.

DMA-Start-Code:

HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)output_buffer[0], SAMPLE_BLOCK_SIZE * 2, DAC_ALIGN_12B_R);

HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*)output_buffer[1], SAMPLE_BLOCK_SIZE * 2, DAC_ALIGN_12B_R);

with output_buffer being a global:

int16_t output_buffer[3][2*SAMPLE_BLOCK_SIZE];


Maybe one may give me a hint what I've been done wrong.
FYI: Same application code runs on a STM32G4 cubemx, so I suppose it's due to a CubeMX missconfiguration or a CubeMX errata.

Thanks in advance. Best Regards 
Pascal Speck

Best answer by stst9180

I now found the solution in:
https://community.st.com/t5/stm32-mcus-products/stm32u599-dac-doesn-t-work-in-dma-mode/m-p/685089
Unfortunately my first search didn't bring this article up. 
AGAIN for all with similar problems: Destination data width mus be "WORD" ( not "HalfWord" as on other derivates )

1 reply

ST Employee
May 30, 2025

Hello @stst9180

What's the Linked-ListMode configuration that is generated?

stst9180
stst9180Author
Associate III
June 2, 2025

Here U R:

/* DAC1 init function */
void MX_DAC1_Init(void)
{

 /* USER CODE BEGIN DAC1_Init 0 */

 /* USER CODE END DAC1_Init 0 */

 DAC_ChannelConfTypeDef sConfig = {0};
 DAC_AutonomousModeConfTypeDef sAutonomousMode = {0};

 /* USER CODE BEGIN DAC1_Init 1 */

 /* USER CODE END DAC1_Init 1 */

 /** DAC Initialization
 */
 hdac1.Instance = DAC1;
 if (HAL_DAC_Init(&hdac1) != HAL_OK)
 {
 Error_Handler();
 }

 /** DAC channel OUT1 config
 */
 sConfig.DAC_HighFrequency = DAC_HIGH_FREQUENCY_INTERFACE_MODE_DISABLE;
 sConfig.DAC_DMADoubleDataMode = DISABLE;
 sConfig.DAC_SignedFormat = DISABLE;
 sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
 sConfig.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
 sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
 sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_EXTERNAL;
 sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
 if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
 {
 Error_Handler();
 }

 /** Configure Autonomous Mode
 */
 sAutonomousMode.AutonomousModeState = DAC_AUTONOMOUS_MODE_DISABLE;
 if (HAL_DACEx_SetConfigAutonomousMode(&hdac1, &sAutonomousMode) != HAL_OK)
 {
 Error_Handler();
 }

 /** DAC channel OUT2 config
 */
 if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN DAC1_Init 2 */

 /* USER CODE END DAC1_Init 2 */

}

void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
{

 GPIO_InitTypeDef GPIO_InitStruct = {0};
 DMA_NodeConfTypeDef NodeConfig= {0};
 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 if(dacHandle->Instance==DAC1)
 {
 /* USER CODE BEGIN DAC1_MspInit 0 */

 /* USER CODE END DAC1_MspInit 0 */

 /** Initializes the peripherals clock
 */
 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADCDAC|RCC_PERIPHCLK_DAC1;
 PeriphClkInit.AdcDacClockSelection = RCC_ADCDACCLKSOURCE_HSI;
 PeriphClkInit.Dac1ClockSelection = RCC_DAC1CLKSOURCE_LSI;
 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
 {
 Error_Handler();
 }

 /* DAC1 clock enable */
 __HAL_RCC_DAC1_CLK_ENABLE();

 __HAL_RCC_GPIOA_CLK_ENABLE();
 /**DAC1 GPIO Configuration
 PA4 ------> DAC1_OUT1
 PA5 ------> DAC1_OUT2
 */
 GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 /* DAC1 DMA Init */
 /* GPDMA1_REQUEST_DAC1_CH2 Init */
 NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
 NodeConfig.Init.Request = GPDMA1_REQUEST_DAC1_CH2;
 NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
 NodeConfig.Init.Direction = DMA_MEMORY_TO_PERIPH;
 NodeConfig.Init.SrcInc = DMA_SINC_INCREMENTED;
 NodeConfig.Init.DestInc = DMA_DINC_FIXED;
 NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD;
 NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD;
 NodeConfig.Init.SrcBurstLength = 1;
 NodeConfig.Init.DestBurstLength = 1;
 NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT1|DMA_DEST_ALLOCATED_PORT0;
 NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
 NodeConfig.Init.Mode = DMA_NORMAL;
 NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
 NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
 NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
 if (HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel4) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel4, NULL, &Node_GPDMA1_Channel4) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel4) != HAL_OK)
 {
 Error_Handler();
 }

 handle_GPDMA1_Channel4.Instance = GPDMA1_Channel4;
 handle_GPDMA1_Channel4.InitLinkedList.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
 handle_GPDMA1_Channel4.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
 handle_GPDMA1_Channel4.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1;
 handle_GPDMA1_Channel4.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
 handle_GPDMA1_Channel4.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
 if (HAL_DMAEx_List_Init(&handle_GPDMA1_Channel4) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel4, &List_GPDMA1_Channel4) != HAL_OK)
 {
 Error_Handler();
 }

 __HAL_LINKDMA(dacHandle, DMA_Handle2, handle_GPDMA1_Channel4);

 if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel4, DMA_CHANNEL_NPRIV) != HAL_OK)
 {
 Error_Handler();
 }

 /* GPDMA1_REQUEST_DAC1_CH1 Init */
 NodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;
 NodeConfig.Init.Request = GPDMA1_REQUEST_DAC1_CH1;
 NodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;
 NodeConfig.Init.Direction = DMA_MEMORY_TO_PERIPH;
 NodeConfig.Init.SrcInc = DMA_SINC_INCREMENTED;
 NodeConfig.Init.DestInc = DMA_DINC_FIXED;
 NodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_HALFWORD;
 NodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_HALFWORD;
 NodeConfig.Init.SrcBurstLength = 1;
 NodeConfig.Init.DestBurstLength = 1;
 NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT1|DMA_DEST_ALLOCATED_PORT0;
 NodeConfig.Init.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
 NodeConfig.Init.Mode = DMA_NORMAL;
 NodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;
 NodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;
 NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
 if (HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel3) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel3, NULL, &Node_GPDMA1_Channel3) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel3) != HAL_OK)
 {
 Error_Handler();
 }

 handle_GPDMA1_Channel3.Instance = GPDMA1_Channel3;
 handle_GPDMA1_Channel3.InitLinkedList.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
 handle_GPDMA1_Channel3.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
 handle_GPDMA1_Channel3.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT1;
 handle_GPDMA1_Channel3.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
 handle_GPDMA1_Channel3.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
 if (HAL_DMAEx_List_Init(&handle_GPDMA1_Channel3) != HAL_OK)
 {
 Error_Handler();
 }

 if (HAL_DMAEx_List_LinkQ(&handle_GPDMA1_Channel3, &List_GPDMA1_Channel3) != HAL_OK)
 {
 Error_Handler();
 }

 __HAL_LINKDMA(dacHandle, DMA_Handle1, handle_GPDMA1_Channel3);

 if (HAL_DMA_ConfigChannelAttributes(&handle_GPDMA1_Channel3, DMA_CHANNEL_NPRIV) != HAL_OK)
 {
 Error_Handler();
 }

 /* DAC1 interrupt Init */
 HAL_NVIC_SetPriority(DAC1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(DAC1_IRQn);
 /* USER CODE BEGIN DAC1_MspInit 1 */

 /* USER CODE END DAC1_MspInit 1 */
 }
}



I don't know if it helps guessing what's happening: 

When I debug the Core while bein in the Transfer-Error-Interrupt, the C3SAR is in the range but at position 10 ( 5 half-word-transfers). So it seems that there were some bytes transferred. C3DAR is also correct with 0x46021808.

I just tried in different directions: Enabling / Disabling caches, Trying different burst-sizes, but the error just arises.


stst9180
stst9180AuthorBest answer
Associate III
June 3, 2025

I now found the solution in:
https://community.st.com/t5/stm32-mcus-products/stm32u599-dac-doesn-t-work-in-dma-mode/m-p/685089
Unfortunately my first search didn't bring this article up. 
AGAIN for all with similar problems: Destination data width mus be "WORD" ( not "HalfWord" as on other derivates )