2025-01-02 10:53 PM
@ABN
Hello All,
Steps happening in the code (FREERTOS based).
1. Initialization ( 4 ADC channels, DMA, BLE)
2. Take 1 sample of each channel. Store in register.
3. GOTO STOP2 mode.
4. Wakeup at 10th second using LPTIM.
5. Reinint everything above menitoned.
6. Take ADC samples of the 4 channels.
The problem.
ADC samples taken after 1st init is correct. ADC samples taken hereafter on wakeup are incorrect.
This is being checked by debugging through STM programmer.
2025-01-02 11:18 PM - edited 2025-01-02 11:21 PM
The code snippet is the Init of ADC
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.NbrOfConversion = 4;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.OversamplingMode = ENABLE;
hadc1.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_16;
hadc1.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4;
hadc1.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
hadc1.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_47CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_4;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_VREFINT;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_9;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
This snippet is application Init and refresh of ADC
status_code_t AdcInput_StPort_init(uint16_t *adcBuffer, uint16_t adcBufferLength)
{
status_code_t status = STATUS_OK;
/* ADC Calibration starts */
HAL_StatusTypeDef ret;
/* Stops the ADC */
ret = HAL_ADC_Stop(myHalAdcPtr);
if(ret != HAL_OK)
{
status = STATUS_ERR_PROTOCOL;
}
/* Start the Calibration */
ret = HAL_ADCEx_Calibration_Start(myHalAdcPtr, ADC_SINGLE_ENDED);
if(ret != HAL_OK)
{
status = STATUS_ERR_PROTOCOL;
}
/* ADC Calibration Done */
if(HAL_OK != HAL_ADC_Start_DMA(myHalAdcPtr, (uint32_t *)adcBuffer, adcBufferLength))
{
status = STATUS_ERR_PROTOCOL;
}
return status;
}
status_code_t AdcInput_StPort_refresh(AdcInputCallback_t cb)
{
status_code_t status = STATUS_OK;
myAdcInputCallback = cb;
/* ADC Calibration Done */
if(HAL_OK != HAL_ADC_Start(myHalAdcPtr))
{
status = STATUS_ERR_PROTOCOL;
}
return status;
}
2025-01-03 12:51 AM
Hello @rapoorv
Could you please try to disable ADC and ADC regulator before entering STOP 2 mode then after the wake-up, reconfigure them and check the clock configuration after the wake-up. Also, After the Wake-up, you can disable and enable again the ADC, then perform an ADC calibration. Don't forget to leave some time before the conversation after the Wake-up.
Best Regards.
STTwo-32
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-01-03 01:51 AM
Hi @STTwo-32
In the PreSleepProcessing function the following code is executed
__weak void PreSleepProcessing(uint32_t ulExpectedIdleTime)
{
/* place for user code */
HAL_SuspendTick();
HAL_LPTIM_TimeOut_Start_IT(&hlptim1, 0xFFFF, ulExpectedIdleTime);
LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
LL_C2_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
__HAL_RCC_I2C3_CLK_DISABLE();
__HAL_RCC_I2C1_CLK_DISABLE();
HAL_NVIC_DisableIRQ(DMA1_Channel5_IRQn);
/*De-initialize the DMA and ADC */
HAL_ADC_DeInit(&hadc1);
HAL_DMA_DeInit(&hdma_adc1);
}
As per the 'HAL_ADC_DeInit' definition in 'stm32wbxx_hal_adc.c', ADC regulator is getting disabled
/* Reset register CR */
/* Bits ADC_CR_JADSTP, ADC_CR_ADSTP, ADC_CR_JADSTART, ADC_CR_ADSTART,
ADC_CR_ADCAL, ADC_CR_ADDIS and ADC_CR_ADEN are in access mode "read-set":
no direct reset applicable.
Update CR register to reset value where doable by software */
CLEAR_BIT(hadc->Instance->CR, ADC_CR_ADVREGEN | ADC_CR_ADCALDIF);
SET_BIT(hadc->Instance->CR, ADC_CR_DEEPPWD);
After wakeup, the post sleep operations are as follows
__weak void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
/* place for user code */
SystemClock_Config();
PeriphCommonClock_Config();
HAL_LPTIM_TimeOut_Stop_IT(&hlptim1);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
HAL_ResumeTick();
__HAL_RCC_I2C3_CLK_ENABLE();
__HAL_RCC_I2C1_CLK_ENABLE();
MX_DMA_Init();
MX_ADC1_Init();
}
2025-01-06 10:48 PM
Hi @STTwo-32
Can you suggest something after going through the problem point and the code ?
2025-01-06 11:04 PM
Hello @rapoorv
Could you try to test it first without BLE et activated in a baremetal code. If it works fine integrate RTOS and test it again. If this also go fine, try to test it all. If possible on a NUCLEO Board just to make sure we dont have any design issue.
Best Regards.
STTwo-32
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2025-01-13 03:57 AM
hello @STTwo-32
We could not try the above thing suggested by you, but in the code mentioned by @ABN there is a delay inserted. check below code.
__weak void PostSleepProcessing(uint32_t ulExpectedIdleTime)
{
/* place for user code */
SystemClock_Config();
PeriphCommonClock_Config();
HAL_LPTIM_TimeOut_Stop_IT(&hlptim1);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
HAL_ResumeTick();
__HAL_RCC_I2C3_CLK_ENABLE();
__HAL_RCC_I2C1_CLK_ENABLE();
MX_DMA_Init();
MX_ADC1_Init();
HAL_Delay(35);
}
Seems like the 35ms delay inserted after the ADC init. gives us the corrrect values of the ADC sampling.
We could not figure out why this delay is required. Anything below 35ms messes up the ADC conversions.
Any idea what are the things in the initilization phase which can take this much of startup time.?