2024-01-10 04:50 AM - edited 2024-01-11 01:16 AM
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
Solved! Go to Solution.
2024-01-28 11:59 PM
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.
2024-01-28 11:59 PM
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.
2024-01-29 08:42 AM
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
2024-11-15 08:58 PM
Hello,
Can you tell me where to add these codes. In which file?