2023-07-05 01:21 AM
We are testing the latest STM32H562RGT device on our application. I am running an eight-channel ADC (on ADC1) with DMA support. All eight channels gets populated with the correct ADC values, however, the DMA InitLinkList State stays on BUSY and thus the XferCpltCallback does not get handled.
Some debug took me into the HAL_DMA_IRQHandler function.
In this part of the function:
/* Transfer Complete Interrupt management ***************************************************************************/
if ((__HAL_DMA_GET_FLAG(hdma, DMA_FLAG_TC) != 0U))
{
/* Check if interrupt source is enabled */
if (__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
{
/* Check DMA channel transfer mode */
if ((hdma->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
{
/* If linked-list transfer */
if (hdma->Instance->CLLR == 0U)
{
if (hdma->Instance->CBR1 == 0U)
{
/* Update the DMA channel state */
hdma->State = HAL_DMA_STATE_READY;
/* Update the linked-list queue state */
hdma->LinkedListQueue->State = HAL_DMA_QUEUE_STATE_READY;
}
}
}
else
{
/* If normal transfer */
if (hdma->Instance->CBR1 == 0U)
{
/* Update the DMA channel state */
hdma->State = HAL_DMA_STATE_READY;
}
}
/* Clear TC and HT transfer flags */
__HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC | DMA_FLAG_HT));
/* Process Unlocked */
__HAL_UNLOCK(hdma);
/* Check transfer complete callback */
if (hdma->XferCpltCallback != NULL)
{
/* Channel Transfer Complete callback */
hdma->XferCpltCallback(hdma);
}
}
}
hdma->Instance->CLLR = 4160855080 and
hdma->Instance->CBR1 = 18
Thus hdma->State is never set to HAL_DMA_STATE_READY
The CLLR and CBR1 register values are set in the function call HAL_ADC_Start_DMA() in the function call HAL_DMAEx_List_Start_IT().
Is there an ADC DMA setting I must use (I used cube generated setup) or a different Start_ADC conversion call.
Included are my ADC setup:
static INFRAGLOBAL_STATUS_t bspAdc1Init(void)
{
INFRAGLOBAL_STATUS_t result = INFRAGLOBAL_STATUS_PASS;
DMA_NodeConfTypeDef NodeConfig;
GPIO_InitTypeDef GPIO_InitStruct = {0};
ADC_ChannelConfTypeDef sConfig = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/* ADC1 Port A */
GPIO_InitStruct.Pin = BSPADC_LEFT_BRIDGE_DIAG_PIN | BSPADC_MOTOR_CURRENT_LOW_RIGHT_PIN | BSPADC_INPUT1_PIN | BSPADC_OVERRIDE_PIN | BSPADC_VIN_SYS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Port C */
GPIO_InitStruct.Pin = BSPADC_MOTOR_CURRENT_LOW_LEFT_PIN | BSPADC_RIGHT_BRIDGE_DIAG_PIN | BSPADC_INPUT2_PIN | BSPADC_ORIGIN_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* ADC clock enable */
if(bspAdcClkEnabled != INFRAGLOBAL_BOOLEAN_TRUE)
{
__HAL_RCC_ADC_CLK_ENABLE();
bspAdcClkEnabled = INFRAGLOBAL_BOOLEAN_TRUE;
}
/** Common config
*/
bspAdc1Hd.Instance = ADC1;
bspAdc1Hd.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV10;
bspAdc1Hd.Init.Resolution = ADC_RESOLUTION_12B;
bspAdc1Hd.Init.DataAlign = ADC_DATAALIGN_RIGHT;
bspAdc1Hd.Init.ScanConvMode = ADC_SCAN_ENABLE;
bspAdc1Hd.Init.EOCSelection = ADC_EOC_SEQ_CONV;
bspAdc1Hd.Init.LowPowerAutoWait = DISABLE;
bspAdc1Hd.Init.ContinuousConvMode = DISABLE;
bspAdc1Hd.Init.NbrOfConversion = BSPADC_1_BUFFER_SIZE;
bspAdc1Hd.Init.DiscontinuousConvMode = DISABLE;
bspAdc1Hd.Init.ExternalTrigConv = ADC_SOFTWARE_START;
bspAdc1Hd.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
bspAdc1Hd.Init.DMAContinuousRequests = ENABLE;
bspAdc1Hd.Init.SamplingMode = ADC_SAMPLING_MODE_NORMAL;
bspAdc1Hd.Init.Overrun = ADC_OVR_DATA_PRESERVED;
bspAdc1Hd.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&bspAdc1Hd) != HAL_OK)
{
Error_Handler();
}
/* 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.SrcBurstLength = 1;
NodeConfig.Init.DestBurstLength = 1;
NodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|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_DEST_HALFWORD;
NodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;
if (HAL_DMAEx_List_BuildNode(&NodeConfig, &Node_GPDMA1_Channel1) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMAEx_List_InsertNode(&List_GPDMA1_Channel1, NULL, &Node_GPDMA1_Channel1) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMAEx_List_SetCircularMode(&List_GPDMA1_Channel1) != HAL_OK)
{
Error_Handler();
}
bspAdc1DmaHd.Instance = GPDMA1_Channel1;
bspAdc1DmaHd.InitLinkedList.Priority = DMA_LOW_PRIORITY_LOW_WEIGHT;
bspAdc1DmaHd.InitLinkedList.LinkStepMode = DMA_LSM_FULL_EXECUTION;
bspAdc1DmaHd.InitLinkedList.LinkAllocatedPort = DMA_LINK_ALLOCATED_PORT0;
bspAdc1DmaHd.InitLinkedList.TransferEventMode = DMA_TCEM_BLOCK_TRANSFER;
bspAdc1DmaHd.InitLinkedList.LinkedListMode = DMA_LINKEDLIST_CIRCULAR;
if (HAL_DMAEx_List_Init(&bspAdc1DmaHd) != HAL_OK)
{
Error_Handler();
}
if (HAL_DMAEx_List_LinkQ(&bspAdc1DmaHd, &List_GPDMA1_Channel1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&bspAdc1Hd, DMA_Handle, bspAdc1DmaHd);
if (HAL_DMA_ConfigChannelAttributes(&bspAdc1DmaHd, DMA_CHANNEL_NPRIV) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_24CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
//sConfig.SamplingTime = ADC_SAMPLETIME_24CYCLES_5; /* 3.06 micro seconds */
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_14;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_5;
if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_REGULAR_RANK_6;
if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = ADC_REGULAR_RANK_7;
if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
{
Error_Handler();
}
// /** Configure Regular Channel
// */
// sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5; /* 5.9 micro seconds */
// sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
// sConfig.Rank = ADC_REGULAR_RANK_7;
// if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
// {
// Error_Handler();
// }
/** Configure Regular Channel
*/
//sConfig.SamplingTime = ADC_SAMPLETIME_24CYCLES_5; /* 3.06 micro seconds */
sConfig.Channel = ADC_CHANNEL_18;
sConfig.Rank = ADC_REGULAR_RANK_8;
if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_19;
sConfig.Rank = ADC_REGULAR_RANK_9;
if (HAL_ADC_ConfigChannel(&bspAdc1Hd, &sConfig) != HAL_OK)
{
Error_Handler();
}
HAL_NVIC_SetPriority(GPDMA1_Channel1_IRQn, 5u, 0u); //highest priority within the RTOS
HAL_NVIC_EnableIRQ(GPDMA1_Channel1_IRQn);
bspAdc1Enabled = INFRAGLOBAL_BOOLEAN_TRUE;
return result;
}