2019-12-10 09:14 AM
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?
2019-12-15 11:20 PM
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.
2019-12-17 11:47 PM
This (My) solution is not correct!