Просмотр исходного кода

light sleep: enable system clock in PMU HP sleep state when selecting a 40 MHz XTAL as low power clock source of ble

Li Shuai 2 лет назад
Родитель
Сommit
efa4eeafd0

+ 9 - 0
components/esp_hw_support/include/esp_private/esp_pmu.h

@@ -249,6 +249,15 @@ bool pmu_sleep_finish(void);
  */
 void pmu_init(void);
 
+/**
+ * @brief Enable or disable system clock in PMU HP sleep state
+ *
+ * This API only used for fix BLE 40 MHz low power clock source issue
+ *
+ * @param enable  true to enable, false to disable
+ */
+void pmu_sleep_enable_hp_sleep_sysclk(bool enable);
+
 
 #endif //#if SOC_PMU_SUPPORTED
 

+ 8 - 2
components/esp_hw_support/modem_clock.c

@@ -334,6 +334,9 @@ void modem_clock_select_lp_clock_source(periph_module_t module, modem_clock_lpcl
         modem_clock_hal_select_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal, src);
         modem_clock_hal_set_ble_rtc_timer_divisor_value(MODEM_CLOCK_instance()->hal, divider);
         modem_clock_hal_enable_ble_rtc_timer_clock(MODEM_CLOCK_instance()->hal, true);
+        if (src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
+            pmu_sleep_enable_hp_sleep_sysclk(true);
+        }
         break;
 #endif // SOC_BT_SUPPORTED
 
@@ -372,6 +375,8 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module)
 {
     assert(IS_MODEM_MODULE(module));
     portENTER_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);
+    modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN];
+    MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = MODEM_CLOCK_LPCLK_SRC_INVALID;
     switch (module)
     {
 #if SOC_WIFI_SUPPORTED
@@ -385,6 +390,9 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module)
     case PERIPH_BT_MODULE:
         modem_clock_hal_deselect_all_ble_rtc_timer_lpclk_source(MODEM_CLOCK_instance()->hal);
         modem_clock_hal_enable_ble_rtc_timer_clock(MODEM_CLOCK_instance()->hal, false);
+        if (last_src == MODEM_CLOCK_LPCLK_SRC_MAIN_XTAL) {
+            pmu_sleep_enable_hp_sleep_sysclk(false);
+        }
         break;
 #endif // SOC_BT_SUPPORTED
     case PERIPH_COEX_MODULE:
@@ -394,8 +402,6 @@ void modem_clock_deselect_lp_clock_source(periph_module_t module)
     default:
         break;
     }
-    modem_clock_lpclk_src_t last_src = MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN];
-    MODEM_CLOCK_instance()->lpclk_src[module - PERIPH_MODEM_MODULE_MIN] = MODEM_CLOCK_LPCLK_SRC_INVALID;
     portEXIT_CRITICAL_SAFE(&MODEM_CLOCK_instance()->lock);
 
     esp_sleep_pd_domain_t pd_domain = (esp_sleep_pd_domain_t) ( \

+ 5 - 0
components/esp_hw_support/port/esp32c6/pmu_sleep.c

@@ -294,3 +294,8 @@ bool pmu_sleep_finish(void)
 {
     return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
 }
+
+void pmu_sleep_enable_hp_sleep_sysclk(bool enable)
+{
+    pmu_ll_hp_set_icg_sysclk_enable(PMU_instance()->hal->dev, HP(SLEEP), enable);
+}