cancel
Showing results for 
Search instead for 
Did you mean: 

ADC triggered by HRTimer using DMA and FreeRTOS

BentoCopi
Associate

I'm trying to trigger ADC using an high resolution timer with period 500 KHz. The board is STM32F344. ADC is using DMA. I'm using FreeRTOS CMSIS V2. System clock 64MHz. So, two issues immediately came up: 

1) After launching the timer using HAL_HRTIM_SimpleBaseStart_IT , all the tasks get blocked giving up the control to the HRTIM. 

I lowered down the HRTIM period to 200Hz and the system got working again, although this behavior is weird: my tasks priorities are 24 and HRTIM 5. I tried to clear the update flag on the ISR handler as described in one of the posts here in the community but with no success. I always have troubles running hardware timers on FreeRTOS.

2) ADC conversions show up too fast and wrongly in the debugging window. 

Although the conversions are being triggered too fast for a human or even the debugger, we can still see some readable raw data on the debugging window. My raw ADC measurements are swapping from 0 up to 100-ish very fast, but when I stop the code I see the correct value around 3000. The ADC clock is 2MHz. I tried many different configuration combinations but with no success.

 

I leave a code snippet, my ADC and HRTIM configuration and attached  the videos below. 

 

Normal ADC measurements [video]

Abnormal ADC measurements [video]

 

ADC configurations

BentoCopi_0-1733911618862.pngBentoCopi_1-1733911644331.pngBentoCopi_2-1733911672175.png

BentoCopi_3-1733911715438.pngBentoCopi_4-1733911732315.png

HRTIM configurations

BentoCopi_5-1733911785253.pngBentoCopi_6-1733911831202.pngBentoCopi_7-1733911855941.png

BentoCopi_8-1733911967740.png

The code

 

 

void app_init(void)
{
	if(HAL_OK != HAL_ADCEx_Calibration_Start(&hadc1, ADC_SINGLE_ENDED))
	{
		  Error_Handler();
	}

	  if(HAL_OK != HAL_HRTIM_SimpleBaseStart_IT(&hhrtim1,HRTIM_TIMERINDEX_MASTER))
	  {
		  Error_Handler();
	  }

	  if(HAL_OK != HAL_ADC_Start_DMA(&hadc1, v_raw, 2))
	  {
		  Error_Handler();
	  }

	HAL_UARTEx_ReceiveToIdle_DMA(&huart1,usart1_rx_raw_buffer, USART1_BUF_LENGTH);

	main_app_handle = osThreadNew((osThreadFunc_t)main_app, NULL, &main_app_attributes);

	parser_task_handle = osThreadNew((osThreadFunc_t)parser_task, NULL, &parser_task_attributes);
}

 

 

 

 

 

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
	if(hadc == &hadc1){
		HAL_GPIO_TogglePin(ENC_KEY_GPIO_Port, ENC_KEY_Pin);
		v_ = v_raw[0]*3.3/(4096.0f);
		if(HAL_DMA_STATE_READY == HAL_DMA_GetState(&hdma_adc1)){
			HAL_ADC_Start_DMA(hadc, (uint32_t*)v_raw, 2);
		}
	}
}

 

 

 

Any help would be useful.

 

4 REPLIES 4
Saket_Om
ST Employee

Hello @BentoCopi 

I noticed that the NVIC priorities for HRTIM, ADC, and DMA are currently set to the same value. Please adjust these priorities according to the specific needs of your application.

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

@Saket_Om I dropped down the priority for HRTIM up to 15 and the problem 1) got solved . Thank you for that! 

The problem 2) persists. I set the priority for ADC DMA to 6 and just turned off the ADC global interrupts.

 

@BentoCopi 

If the ADC global interrupts is turned off the HAL_ADC_ConvCpltCallback() will not be called. 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

Hello @BentoCopi 

Is the problem 2 solved in your application? 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar