cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_ADC_Stop_DMA cause error if called when DMA state != HAL_DMA_STATE_BUSY HAL Version: STM32F3 1.11.0

thomas
Associate

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

1 REPLY 1
Georgy Moshkin
Senior II

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);

Disappointed with crowdfunding projects? Make a lasting, meaningful impact as a Tech Sponsor instead: Visit TechSponsor.io to Start Your Journey!