Skip to main content
Muthanna
Associate II
January 10, 2024
Solved

Regular Conversion Manager Crashing

  • January 10, 2024
  • 2 replies
  • 2251 views

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

Best answer by Muthanna
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.


2 replies

Muthanna
MuthannaAuthorBest answer
Associate II
January 29, 2024
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.


cedric H
Technical Moderator
January 29, 2024

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

 

 

Associate II
November 16, 2024

Hello,

Can you tell me where to add these codes. In which file?