esp_hw_support/sleep: fix cannot enable sleep reject in some cases

When enable sleep reject before this fix, we have two limitations:
1. it must be light sleep
2. RTC GPIO wakeup source must be set

We require light sleep because `esp_deep_sleep_start` function has
been declared with "noreturn" attribute, So developers don't expect
that this function may return (due to an error or a sleep reject).
But the requirement for RTC GPIO wakeup source is not reasonable for
all chips. This requirement exists because ESP32 only supports RTC GPIO
and SDIO sleep reject sources. But later chips support all sleep reject
sources.

This fix brings the following changes:
for ESP32: RTC GPIO and SDIO sleep reject sources can be enabled
           when corresponding wakeup source is set.

for later chips: all sleep reject sources can be enabled when
                 corresponding wakeup source is set.
This commit is contained in:
jingli 2022-05-07 21:52:56 +08:00
parent ddcc5bfe38
commit abb6bb1181
8 changed files with 108 additions and 17 deletions

View File

@ -201,6 +201,9 @@ void rtc_sleep_init(rtc_sleep_config_t cfg)
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, cfg.rtc_dbias_wak);
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, cfg.dig_dbias_wak);
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_SLP, cfg.dig_dbias_slp);
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN, cfg.deep_slp_reject);
REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN, cfg.light_slp_reject);
}
void rtc_sleep_low_init(uint32_t slowclk_period)

View File

@ -357,6 +357,11 @@ inline static uint32_t call_rtc_sleep_start(uint32_t reject_triggers, uint32_t l
//TODO: IDF-4813
bool esp_no_sleep = false;
inline static bool is_light_sleep(uint32_t pd_flags)
{
return (pd_flags & RTC_SLEEP_PD_DIG) == 0;
}
static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
{
#if CONFIG_IDF_TARGET_ESP32S3
@ -433,15 +438,11 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags)
}
#endif
uint32_t reject_triggers = 0;
if ((pd_flags & RTC_SLEEP_PD_DIG) == 0 && (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)) {
if (is_light_sleep(pd_flags)) {
/* Light sleep, enable sleep reject for faster return from this function,
* in case the wakeup is already triggerred.
*/
#if CONFIG_IDF_TARGET_ESP32
reject_triggers = RTC_CNTL_LIGHT_SLP_REJECT_EN_M | RTC_CNTL_GPIO_REJECT_EN_M;
#else
reject_triggers = s_config.wakeup_triggers;
#endif
reject_triggers = s_config.wakeup_triggers & RTC_SLEEP_REJECT_MASK;
}
// Enter sleep

View File

@ -515,6 +515,8 @@ typedef struct rtc_sleep_config_s {
uint32_t lslp_meminf_pd : 1; //!< remove all peripheral force power up flags
uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator
uint32_t xtal_fpu : 1; //!< keep main XTAL powered up in sleep
uint32_t deep_slp_reject : 1; //!< enable deep sleep reject
uint32_t light_slp_reject : 1; //!< enable light sleep reject
} rtc_sleep_config_t;
/**
@ -548,7 +550,9 @@ typedef struct rtc_sleep_config_s {
: RTC_CNTL_DBIAS_0V90, \
.lslp_meminf_pd = 1, \
.vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \
.xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1 \
.xtal_fpu = ((sleep_flags) & RTC_SLEEP_PD_XTAL) ? 0 : 1, \
.deep_slp_reject = 1, \
.light_slp_reject = 1 \
};
#define RTC_SLEEP_PD_DIG BIT(0) //!< Deep sleep (power down digital domain)
@ -615,6 +619,12 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
#define RTC_ULP_TRIG_EN BIT(9) //!< ULP wakeup
#define RTC_BT_TRIG_EN BIT(10) //!< BT wakeup (light sleep only)
/**
* RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
* esp32 only supports GPIO and SDIO sleep reject sources
*/
#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN | RTC_SDIO_TRIG_EN)
/**
* @brief Enter deep or light sleep mode
*

View File

@ -610,8 +610,8 @@ typedef struct {
uint32_t rtc_dbias_slp : 5; //!< set bias for RTC domain, in sleep mode
uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator
uint32_t xtal_fpu : 1; //!< keep main XTAL powered up in sleep
uint32_t deep_slp_reject : 1;
uint32_t light_slp_reject : 1;
uint32_t deep_slp_reject : 1; //!< enable deep sleep reject
uint32_t light_slp_reject : 1; //!< enable light sleep reject
} rtc_sleep_config_t;
/**
@ -707,6 +707,19 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
#define RTC_USB_TRIG_EN BIT(14)
#define RTC_BROWNOUT_DET_TRIG_EN BIT(16)
/**
* RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
*/
#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN | \
RTC_TIMER_TRIG_EN | \
RTC_WIFI_TRIG_EN | \
RTC_UART0_TRIG_EN | \
RTC_UART1_TRIG_EN | \
RTC_BT_TRIG_EN | \
RTC_XTAL32K_DEAD_TRIG_EN | \
RTC_USB_TRIG_EN | \
RTC_BROWNOUT_DET_TRIG_EN)
/**
* @brief Enter deep or light sleep mode
*

View File

@ -626,8 +626,8 @@ typedef struct {
uint32_t rtc_dbias_slp : 5; //!< set bias for RTC domain, in sleep mode
uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator
uint32_t xtal_fpu : 1; //!< keep main XTAL powered up in sleep
uint32_t deep_slp_reject : 1;
uint32_t light_slp_reject : 1;
uint32_t deep_slp_reject : 1; //!< enable deep sleep reject
uint32_t light_slp_reject : 1; //!< enable light sleep reject
} rtc_sleep_config_t;
/**
@ -723,6 +723,19 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
#define RTC_USB_TRIG_EN BIT(14)
#define RTC_BROWNOUT_DET_TRIG_EN BIT(16)
/**
* RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
*/
#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN | \
RTC_TIMER_TRIG_EN | \
RTC_WIFI_TRIG_EN | \
RTC_UART0_TRIG_EN | \
RTC_UART1_TRIG_EN | \
RTC_BT_TRIG_EN | \
RTC_XTAL32K_DEAD_TRIG_EN | \
RTC_USB_TRIG_EN | \
RTC_BROWNOUT_DET_TRIG_EN)
/**
* @brief Enter deep or light sleep mode
*

View File

@ -642,8 +642,8 @@ typedef struct {
uint32_t rtc_dbias_slp : 5; //!< set bias for RTC domain, in sleep mode
uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator
uint32_t xtal_fpu : 1; //!< keep main XTAL powered up in sleep
uint32_t deep_slp_reject : 1;
uint32_t light_slp_reject : 1;
uint32_t deep_slp_reject : 1; //!< enable deep sleep reject
uint32_t light_slp_reject : 1; //!< enable light sleep reject
} rtc_sleep_config_t;
/**
@ -739,6 +739,19 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
#define RTC_USB_TRIG_EN BIT(14)
#define RTC_BROWNOUT_DET_TRIG_EN BIT(16)
/**
* RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
*/
#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN | \
RTC_TIMER_TRIG_EN | \
RTC_WIFI_TRIG_EN | \
RTC_UART0_TRIG_EN | \
RTC_UART1_TRIG_EN | \
RTC_BT_TRIG_EN | \
RTC_XTAL32K_DEAD_TRIG_EN | \
RTC_USB_TRIG_EN | \
RTC_BROWNOUT_DET_TRIG_EN)
/**
* @brief Enter deep or light sleep mode
*

View File

@ -683,8 +683,8 @@ typedef struct {
uint32_t rtc_dbias_slp : 3; //!< set bias for RTC domain, in sleep mode
uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator
uint32_t xtal_fpu : 1; //!< keep main XTAL powered up in sleep
uint32_t deep_slp_reject : 1;
uint32_t light_slp_reject : 1;
uint32_t deep_slp_reject : 1; //!< enable deep sleep reject
uint32_t light_slp_reject : 1; //!< enable light sleep reject
} rtc_sleep_config_t;
/**
@ -775,6 +775,25 @@ void rtc_sleep_low_init(uint32_t slowclk_period);
#define RTC_COCPU_TRAP_TRIG_EN BIT(13)
#define RTC_USB_TRIG_EN BIT(14)
/**
* RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
*/
#define RTC_SLEEP_REJECT_MASK (RTC_EXT0_TRIG_EN | \
RTC_EXT1_TRIG_EN | \
RTC_GPIO_TRIG_EN | \
RTC_TIMER_TRIG_EN | \
RTC_SDIO_TRIG_EN | \
RTC_WIFI_TRIG_EN | \
RTC_UART0_TRIG_EN | \
RTC_UART1_TRIG_EN | \
RTC_TOUCH_TRIG_EN | \
RTC_ULP_TRIG_EN | \
RTC_BT_TRIG_EN | \
RTC_COCPU_TRIG_EN | \
RTC_XTAL32K_DEAD_TRIG_EN | \
RTC_COCPU_TRAP_TRIG_EN | \
RTC_USB_TRIG_EN)
/**
* @brief Enter deep or light sleep mode
*

View File

@ -633,8 +633,8 @@ typedef struct {
uint32_t rtc_dbias_slp : 5; //!< set bias for RTC domain, in sleep mode
uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator
uint32_t xtal_fpu : 1; //!< keep main XTAL powered up in sleep
uint32_t deep_slp_reject : 1;
uint32_t light_slp_reject : 1;
uint32_t deep_slp_reject : 1; //!< enable deep sleep reject
uint32_t light_slp_reject : 1; //!< enable light sleep reject
} rtc_sleep_config_t;
/**
@ -737,6 +737,25 @@ void rtc_sleep_set_wakeup_time(uint64_t t);
#define RTC_COCPU_TRAP_TRIG_EN BIT(13)
#define RTC_USB_TRIG_EN BIT(14)
/**
* RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip
*/
#define RTC_SLEEP_REJECT_MASK (RTC_EXT0_TRIG_EN | \
RTC_EXT1_TRIG_EN | \
RTC_GPIO_TRIG_EN | \
RTC_TIMER_TRIG_EN | \
RTC_SDIO_TRIG_EN | \
RTC_WIFI_TRIG_EN | \
RTC_UART0_TRIG_EN | \
RTC_UART1_TRIG_EN | \
RTC_TOUCH_TRIG_EN | \
RTC_ULP_TRIG_EN | \
RTC_BT_TRIG_EN | \
RTC_COCPU_TRIG_EN | \
RTC_XTAL32K_DEAD_TRIG_EN | \
RTC_COCPU_TRAP_TRIG_EN | \
RTC_USB_TRIG_EN)
/**
* @brief Enter deep or light sleep mode
*