cancel
Showing results for 
Search instead for 
Did you mean: 

Regular Conversion Manager Crashing

Muthanna
Associate III

Hi, 

I'm using MCSDK 5.Y.2 and STSPIN32G4 on a custom board. (this is a software thing !)
I couldn't find a way to get two (more than one) converted ADC Values using a single request using the RCM.
So I carried on converting each channel sequentially.

I made two Registrations

like so

 

 

void User_ADC_Init(void)
{
RegConv_t FES_ADC = {hadc2.Instance,MC_ADC_CHANNEL_7,ADC_SAMPLETIME_2CYCLES_5};
FEShandle = RCM_RegisterRegConv(&FES_ADC);
RegConv_t TRTL_ADC = {hadc2.Instance,MC_ADC_CHANNEL_8,ADC_SAMPLETIME_2CYCLES_5};
TRTLhandle = RCM_RegisterRegConv(&TRTL_ADC);

}

 

 

But started with converting just one of the channels

 

 

void User_ADC_Conv(void)
{


	switch( RCM_GetUserConvState())
		{
		case RCM_USERCONV_IDLE :
				RCM_RequestUserConv(FEShandle);
			break;

		case RCM_USERCONV_REQUESTED :
			break;

		case RCM_USERCONV_EOC :
			FES_Datum = RCM_GetUserConv();
			break;
		}

	/*
	switch( RCM_GetUserConvState())
	{
	case RCM_USERCONV_IDLE :
		if(adcSelect == FES_SELECTED)
			RCM_RequestUserConv(FEShandle);
		else if(adcSelect == TRTL_SELECTED)
			RCM_RequestUserConv(TRTLhandle);
		else //error
		{}
		break;

	case RCM_USERCONV_REQUESTED :
		break;

	case RCM_USERCONV_EOC :
		switch(adcSelect)
		{
		case FES_SELECTED :
			FES_Datum = RCM_GetUserConv();
			adcSelect = TRTL_SELECTED;
			break;

		case TRTL_SELECTED :
			TRTL_Datum = RCM_GetUserConv();
			adcSelect = FES_SELECTED;
			break;

		default : //error
			break;
		}
		break;
	}
	*/
}

 

 

 

I call the functions like so in the main.c 

 

 

/* USER CODE BEGIN 2 */

	__HAL_TIM_ENABLE_IT(&htim2, TIM_IT_UPDATE );
	__HAL_TIM_CLEAR_IT(&htim2 ,TIM_IT_UPDATE);
	HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);


	User_ADC_Init();

	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1)
	{
		/////////////////////////////////////////// WHILE ////////////////////////////////////////////////

		User_ADC_Conv();
		HAL_Delay(10);

		/////////////////////////////////////////// WHILE ////////////////////////////////////////////////


		/* USER CODE END WHILE */

		/* USER CODE BEGIN 3 */

	}

 

 

Apart from this I also use 
HAL_TIM_IC_CaptureCallback() and HAL_TIM_PeriodElapsedCallback() Interrupts as a part of my STSPIN32G4 application.

On running the application everything runs smoothly only for a while. I'm able to see varying ADC values in both channels. But some particular Timer Input Capture causes the code main while loop to get stuck.
Basically a rising or falling edge on a pin tied to the Timer Input Capture triggering the HAL_TIM_IC_CaptureCallback() function. 

On debugging I found that it is stuck in the while loop in RCM_ExecRegularConv() function (screenshot attached)

 

 

 /* Wait EOC */
    while ( LL_ADC_IsActiveFlag_EOC( RCM_handle_array[handle]->regADC ) == RESET )
    {
    }

 

 

basically stuck waiting for End of Conversion.

I remember everything working fine in my previous application where I used only one ADC channel and one RCM registration.

When I commented one of the registrations that I wasn't testing (to debug).

 

 

void User_ADC_Init(void)
{
	RegConv_t FES_ADC = {hadc2.Instance,MC_ADC_CHANNEL_7,ADC_SAMPLETIME_2CYCLES_5};
	FEShandle = RCM_RegisterRegConv(&FES_ADC);
	/*RegConv_t TRTL_ADC = {hadc2.Instance,MC_ADC_CHANNEL_8,ADC_SAMPLETIME_2CYCLES_5};
	TRTLhandle = RCM_RegisterRegConv(&TRTL_ADC);*/

}

 

 

 I noticed everything works fine !

I'm only having this issue when there are multiple RCM registrations and I use the TIM IC Interrupt.
Its very strange. Kindly help me work around this. 

Here are some similar questions that have gone unanswered.

@ikrosoft  ADC output suddenly becomes constant

@FChen.3  STM32L4P5CET ADC freezes at high noise environment 

I get no help from OLS /support tickets, I'm always connected to marketing team, then it goes nowhere.
Please help

-Muthanna

1 ACCEPTED SOLUTION

Accepted Solutions
Muthanna
Associate III
void User_ADC_Init(void)
{
	RegConv_t FES_ADC = {hadc2.Instance,MC_ADC_CHANNEL_7,ADC_SAMPLETIME_2CYCLES_5};
	FEShandle = RCM_RegisterRegConv(&FES_ADC);
	/*RegConv_t TRTL_ADC = {hadc2.Instance,MC_ADC_CHANNEL_8,ADC_SAMPLETIME_2CYCLES_5};
	TRTLhandle = RCM_RegisterRegConv(&TRTL_ADC);*/

}

What I missed, was a really important "Declaration" of RegConv_t object, that I had declared locally instead of declaring globally. Declaring the application channel objects (FES_ADC & TRTL_ADC) globally fixed my problem.
I'm still confused why a single registration worked smoothly and took me of course in debugging, and also getting stuck waiting for EOC.
Lesson : Wrong kind of declarations can work at that moment and screw you up later on.

Any way, thanks to whoever spent some brain time trying to help.


View solution in original post

2 REPLIES 2
Muthanna
Associate III
void User_ADC_Init(void)
{
	RegConv_t FES_ADC = {hadc2.Instance,MC_ADC_CHANNEL_7,ADC_SAMPLETIME_2CYCLES_5};
	FEShandle = RCM_RegisterRegConv(&FES_ADC);
	/*RegConv_t TRTL_ADC = {hadc2.Instance,MC_ADC_CHANNEL_8,ADC_SAMPLETIME_2CYCLES_5};
	TRTLhandle = RCM_RegisterRegConv(&TRTL_ADC);*/

}

What I missed, was a really important "Declaration" of RegConv_t object, that I had declared locally instead of declaring globally. Declaring the application channel objects (FES_ADC & TRTL_ADC) globally fixed my problem.
I'm still confused why a single registration worked smoothly and took me of course in debugging, and also getting stuck waiting for EOC.
Lesson : Wrong kind of declarations can work at that moment and screw you up later on.

Any way, thanks to whoever spent some brain time trying to help.


Hi @Muthanna,

Thanks a lot for sharing your findings in the forum.

>I'm still confused why a single registration worked smoothly and took me of course in debugging, and also getting stuck waiting for EOC.

A single registration declared locally works by chance ! and can fail randomly ...  When you call 

RCM_RegisterRegConv(&FES_ADC);

you pass then an address that is actually stored in the stack. 

Depending on the stack evolution, this address can be overwritten at any time. When you use 2 declarations, you allocate more space in the stack, so chances those addresses are corrupted are higher.

If in your application code you start to write a recursive function that will consume a huge amount of stack, I think your issue will pop-up faster.

Hope it helps.

Cedric