2020-07-07 09:16 AM
Whenever I call HAL_ADC_Stop_DMA before HAL_ADC_Start_DMA and the last DMA transfer was allready finished i got an unresetable error.
--> HAL_ADC_STATE_ERROR_DMA
This is my sequenze:
1:HAL_ADC_Stop_DMA
2:HAL_ADC_Start_DMA
.
.
1:HAL_ADC_Stop_DMA
2:HAL_ADC_Start_DMA
.
.
1:HAL_ADC_Stop_DMA
2:HAL_ADC_Start_DMA
.
.
At the moment I solved this like this:
if (hadc->DMA_Handle->State == HAL_DMA_STATE_BUSY) {
(void)HAL_ADC_Stop_DMA(hadc);
} else {
(void)HAL_ADC_Stop_IT(hadc);
}
When the DMA is allready finished I only call "HAL_ADC_Stop_IT" to stop the ADC measurement. Otherwise I call "HAL_ADC_Stop_DMA".
But shouldent it be possible just to call "HAL_ADC_Stop_DMA" regardless the state of the DMA?.
In my opinion the problem is in the file stm32f3xx_hal_adc_ex line 2669 & 2675.
2269:
tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
This call returns a HAL_ERROR with a "HAL_DMA_ERROR_NO_XFER" status.
This is ok when there was no transfer active.
2675:
But then here this message is treated as error. And I can not reset this error.
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
It also changed from the library version 1.10.0 to 1.11.0.
In 1.10.0 it worked because "tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);" did not return any error.
Is this a bug or am I applying it incorrectly
2021-01-15 04:38 AM
Same problem on STM32H7 when using ADC Interleaved mode + DMA in single shot mode, and calling HAL_ADCEx_MultiModeStop_DMA. I traced it to HAL_DMA_Abort function in stm32h7xx_hal_dma.c starting from line 792:
if(hdma->State != HAL_DMA_STATE_BUSY)
{
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
return HAL_ERROR;
}
Because of HAL_DMA_ERROR_NO_XFER error code HAL_ADC_STATE_ERROR_DMA bit is set. This bit prevents HAL_ADC_ConvHalfCpltCallback from running for if single shot is started again using HAL_ADCEx_MultiModeStart_DMA.
Normal operation returns if this bit is cleared, but I did not check for any additional errors:
HAL_ADCEx_MultiModeStop_DMA(&hadc1);
CLEAR_BIT(hadc1.State, HAL_ADC_STATE_ERROR_DMA);