cancel
Showing results for 
Search instead for 
Did you mean: 

Reinitilaization of ADC3 in DMA mode not working

Benjamin Brammer
Senior II

Hey Guys,

Iam using a STM32F429IDISCOVERY board with ADC3 in dma mode. Sometimes on special usage circumstances ( a lot of stuff is happening in parallel) there is an overrun error, because the processor is not fast enough to get the packages. Normally I just want the ADC to stop and reinitialize again, but sadly this is not working correctly. I use the follwoing ADC error callback fucntion which should handle the problem but after it is executed the HAL status is ok but the ADC is not converting data and streaming it via DMA.

void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)		//todo: implement ADC error handling
{
	if(hadc->Instance == ADC3)
	{
		ADC_Error3++;
		HAL_ADC_Stop_DMA(&hadc3);
		if(HAL_ADC_Start_DMA(&hadc3, (uint32_t *)&ADC3ConvertedData, \
				 ADC3_CONVERTED_DATA_BUFFER_SIZE) != HAL_OK)
	   {
		 Error_Handler();
	   }
	}
	if(hadc->Instance == ADC1)
	{
		ADC_Error1++;
		HAL_ADC_Stop_DMA(&hadc3);
		if(HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&ADC1ConvertedData, \
		 ADC1_CONVERTED_DATA_BUFFER_SIZE) != HAL_OK)
		{
		 Error_Handler();
		}
	}
}

so the Error_Handler() gets not called but ADC isn't working either. Anyone an idea where the problem lies? As far as I have seen the HAL_ADC_Stop_DMA() routine, the interrupt flags get reset.

best regards

Benjamin

5 REPLIES 5
AvaTar
Lead

I don't do Cube, and don't really care about its error handling methods.

But re-initializing the ADC is not necessary in this case, you need to clear the OV flag/condition.

Cube's re-initialization might not clear this flag.

> ... because the processor is not fast enough to get the packages.

I suggest your code architecture is not proper, or you omitted to evaluate the performance/timing relations.

Benjamin Brammer
Senior II

I have also seen some DMA timeout error in the HAL struct of the hadc->DMA_Handle. Am I correct, that this is due to not fast enough serviced DMA interrupts?

the HAL API does clear all necessary flags. As far as I have worked with them they are really robust and also track the errors good.

the problem is that I have user intervention in my task which runs over UART and handles display communication, so there exist a possibility that exactly in that moment when a touch response is send over UART the processor will interrupt an ongoing ADC dma handling, as I have set the preemption priority that way. It is not critical when the ADC is reset but it would be critical to miss UART communication. I cannot have both processes have the same priority tha's why UART goes first and ADC DMA comes second

> the HAL API does clear all necessary flags.

So, you say you actually checked the ADC overflow flag just before reenabling the ADC and DMA? How?

JW

Hey Jan,

I used to check the SFR view and checked not only on break but also after a few steps inside the HAL_ADC_DMA_Stop() API. As I have seen some people reporting here that the SFR view does not schow the current state on breakpoint events. I could off course use the SWV. But I haven't experimented with this, since my first approach completely crashed my project for reasons I don't know and didn't find out. So I would try this not with an important project at first.

It seems that the OVR errors were due to false interrupt priority handling inside the NVIC, At least they dissapeared for now. I now sometimes get these DMA timeout faults and try to implement a robust restart version. I am not quite sure if the DMA or the ADC peripheral is the problem after my reinitialization becasue I once wittnest a DMA_NO_XFER error (sorry just my abreviation, the correct macro is inside the HAL c-files). I will check on this the next few days and hope to find a solution. I believe there are some flags or perhaps the toggling of the DMA_EN Bit missing. At least I did not find a cleaqr of them inside the HAL_ADC_DMA_Stop() API

Anyhow I am happy for advise on this 🙂

Benjamin