Skip to main content
VYare
Associate II
December 10, 2019
Question

STM32F103 and ADC & DMA using latest Firmware Package 1.8.0

  • December 10, 2019
  • 1 reply
  • 1129 views

Sup! I've tried to revive my old HAL-based project written a while ago for FW 1.6.1, fixing some minor bugs. Unfortunately, i removed old package long time ago, so i installed latest version 1.8.0. And my code isn't working anymore. After calling to 'HAL_ADC_Stop_DMA', the hdma->State has bit 'HAL_ADC_STATE_ERROR_DMA' set and all further conversions are screwed. After first conversion, HAL_ADC_ConvCpltCallback is never called again, only half transfer and error callbacks are called. The code sample:

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
	UNUSED(hadc);
	bConvInProgress = 0;
}
 
 
void joystickCalibrationMidPoint(p_joystick_calibration_data_t joy) {
...
 HAL_ADC_Start_DMA(&hadc1, (uint32_t*) dacBuffer, AdcNumChannels);
 while (bConvInProgress == 1) {
 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
 };
 HAL_ADC_Stop_DMA(&hadc1);
...
}

Since i didn't changed anything ADC/DMA related in my code yet, there is definitely something wrong with a new firmware package.

I've noticed HAL_ADC_Stop_DMA calls HAL_DMA_Abort internally, which expects the hdma->State to be HAL_DMA_STATE_BUSY for some reason, but the State is HAL_DMA_STATE_READY in my case.

Old stm32f1xx_hal_dma.c:

HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
{
 HAL_StatusTypeDef status = HAL_OK;
 
 /* Disable DMA IT */
 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
 
 /* Disable the channel */
 __HAL_DMA_DISABLE(hdma);
 
 /* Clear all flags */
 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
 
 /* Change the DMA state */
 hdma->State = HAL_DMA_STATE_READY;
 
 /* Process Unlocked */
 __HAL_UNLOCK(hdma); 
 
 return status; 
}

Latest version of stm32f1xx_hal_dma.c:

HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
{
 HAL_StatusTypeDef status = HAL_OK;
 
 if(hdma->State != HAL_DMA_STATE_BUSY)
 {
 /* no transfer ongoing */
 hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
 
 /* Process Unlocked */
 __HAL_UNLOCK(hdma);
 
 return HAL_ERROR;
 }
 else
 
 {
 /* Disable DMA IT */
 __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
 
 /* Disable the channel */
 __HAL_DMA_DISABLE(hdma);
 
 /* Clear all flags */
 hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
 }
 /* Change the DMA state */
 hdma->State = HAL_DMA_STATE_READY;
 
 /* Process Unlocked */
 __HAL_UNLOCK(hdma); 
 
 return status; 
}

So, i commented out this check, and now my code works fine. Is there an actual bug in the latest FW package or am I doing something wrong?

This topic has been closed for replies.

1 reply

Gianluca Costa
Associate II
December 16, 2019

I found the same issue and I think that there is a bug in the last HAL version.

The issue is the line:

 if(hdma->State != HAL_DMA_STATE_BUSY)

In the HAL_DMA_Abort function. I suppose that the real "if" condition must be:

 if(hdma->State == HAL_DMA_STATE_BUSY)

with this change my code work fine.

Gianluca Costa
Associate II
December 18, 2019

This (My) solution is not correct!