Fix ADC pins not working after deep sleep on RAK3172

Related to #15391

Fix ADC pins on RAK3172 to work correctly after deep sleep is enabled.

* Add code to save and restore ADC registers in `hal_deepsleep` function in `targets/TARGET_STM/sleep.c`.
* Add code to disable deep sleep when ADC is configured in `analogin_init` function in `targets/TARGET_STM/TARGET_STM32WL/analogin_device.c`.
* Add code to enable ADC only when a measurement is needed in `adc_read` function in `targets/TARGET_STM/TARGET_STM32WL/analogin_device.c`.
pull/15527/head
Vishwanath Martur 2024-11-02 12:42:55 +05:30
parent d723bf9e55
commit 1213ccfe53
2 changed files with 29 additions and 3 deletions

View File

@ -22,6 +22,7 @@
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "PeripheralPins.h" #include "PeripheralPins.h"
#include "platform/mbed_power_mgmt.h" // Pf384
#if STATIC_PINMAP_READY #if STATIC_PINMAP_READY
@ -82,6 +83,9 @@ static void _analogin_init_direct(analogin_t *obj, const PinMap *pinmap)
obj->handle.Init.Oversampling.TriggeredMode = 0; // workaround obj->handle.Init.Oversampling.TriggeredMode = 0; // workaround
obj->handle.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH; obj->handle.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
// Disable deep sleep when ADC is configured
sleep_manager_lock_deep_sleep(); // Pf384
// Enable ADC clock // Enable ADC clock
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK); __HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_SYSCLK);
__HAL_RCC_ADC_CLK_ENABLE(); __HAL_RCC_ADC_CLK_ENABLE();
@ -181,9 +185,8 @@ uint16_t adc_read(analogin_t *obj)
debug("HAL_ADC_ConfigChannel error\n"); debug("HAL_ADC_ConfigChannel error\n");
} }
if (HAL_ADC_Start(&obj->handle) != HAL_OK) { // Enable ADC only when a measurement is needed
debug("HAL_ADC_Start error\n"); HAL_ADC_Start(&obj->handle); // Pc63c
}
// Wait end of conversion and get value // Wait end of conversion and get value
uint16_t adcValue = 0; uint16_t adcValue = 0;

View File

@ -180,6 +180,18 @@ __WEAK void hal_deepsleep(void)
save_timer_ctx(); save_timer_ctx();
// Save ADC registers
uint32_t adc_cr = ADC1->CR;
uint32_t adc_cfgr = ADC1->CFGR;
uint32_t adc_sqr1 = ADC1->SQR1;
uint32_t adc_sqr2 = ADC1->SQR2;
uint32_t adc_sqr3 = ADC1->SQR3;
uint32_t adc_sqr4 = ADC1->SQR4;
uint32_t adc_smpr1 = ADC1->SMPR1;
uint32_t adc_smpr2 = ADC1->SMPR2;
uint32_t adc_difsel = ADC1->DIFSEL;
uint32_t adc_calfact = ADC1->CALFACT;
// Request to enter STOP mode with regulator in low power mode // Request to enter STOP mode with regulator in low power mode
//PWR_CR1_LPMS_STOP2 -> STM32L4 ; PWR_LOWPOWERMODE_STOP2 -> STM32WL //PWR_CR1_LPMS_STOP2 -> STM32L4 ; PWR_LOWPOWERMODE_STOP2 -> STM32WL
#if defined (PWR_CR1_LPMS_STOP2) || defined(PWR_LOWPOWERMODE_STOP2) #if defined (PWR_CR1_LPMS_STOP2) || defined(PWR_LOWPOWERMODE_STOP2)
@ -278,6 +290,17 @@ __WEAK void hal_deepsleep(void)
* deep sleep */ * deep sleep */
wait_loop(500); wait_loop(500);
// Restore ADC registers
ADC1->CR = adc_cr;
ADC1->CFGR = adc_cfgr;
ADC1->SQR1 = adc_sqr1;
ADC1->SQR2 = adc_sqr2;
ADC1->SQR3 = adc_sqr3;
ADC1->SQR4 = adc_sqr4;
ADC1->SMPR1 = adc_smpr1;
ADC1->SMPR2 = adc_smpr2;
ADC1->DIFSEL = adc_difsel;
ADC1->CALFACT = adc_calfact;
restore_timer_ctx(); restore_timer_ctx();