sleep_wake_stub.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include <stddef.h>
  7. #include <string.h>
  8. #include <sys/lock.h>
  9. #include <sys/param.h>
  10. #include "esp_attr.h"
  11. #include "esp_sleep.h"
  12. #include "esp_cpu.h"
  13. #include "soc/soc.h"
  14. #include "soc/rtc.h"
  15. #include "soc/soc_caps.h"
  16. #include "hal/uart_ll.h"
  17. #if SOC_LP_TIMER_SUPPORTED
  18. #include "hal/lp_timer_ll.h"
  19. #include "hal/lp_timer_hal.h"
  20. #else
  21. #include "hal/rtc_cntl_ll.h"
  22. #endif
  23. #if SOC_PMU_SUPPORTED
  24. #include "hal/pmu_ll.h"
  25. #endif
  26. #include "sdkconfig.h"
  27. #include "esp_rom_uart.h"
  28. #include "esp_rom_sys.h"
  29. #ifdef CONFIG_IDF_TARGET_ESP32
  30. #include "esp32/rom/rtc.h"
  31. #elif CONFIG_IDF_TARGET_ESP32S2
  32. #include "esp32s2/rom/rtc.h"
  33. #elif CONFIG_IDF_TARGET_ESP32S3
  34. #include "esp32s3/rom/rtc.h"
  35. #elif CONFIG_IDF_TARGET_ESP32C3
  36. #include "esp32c3/rom/rtc.h"
  37. #elif CONFIG_IDF_TARGET_ESP32C6
  38. #include "esp32c6/rom/rtc.h"
  39. #elif CONFIG_IDF_TARGET_ESP32H2
  40. #include "esp32h2/rom/rtc.h"
  41. #endif
  42. void RTC_IRAM_ATTR esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub)
  43. {
  44. #if CONFIG_IDF_TARGET_ESP32
  45. // Since the app core of esp32 does not support access to RTC_FAST_MEMORY,
  46. // `esp_set_deep_sleep_wake_stub` is not declared in RTC_FAST_MEMORY,
  47. // so we cannot call it here
  48. REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub);
  49. #else
  50. esp_set_deep_sleep_wake_stub(new_stub);
  51. #endif
  52. #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
  53. esp_set_deep_sleep_wake_stub_default_entry();
  54. #else
  55. set_rtc_memory_crc();
  56. #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_MEM
  57. // Go to sleep.
  58. #if SOC_PMU_SUPPORTED
  59. pmu_ll_hp_clear_wakeup_intr_status(&PMU);
  60. pmu_ll_hp_clear_reject_intr_status(&PMU);
  61. pmu_ll_hp_clear_reject_cause(&PMU);
  62. pmu_ll_hp_set_sleep_enable(&PMU);
  63. #else
  64. rtc_cntl_ll_sleep_enable();
  65. #endif
  66. // A few CPU cycles may be necessary for the sleep to start...
  67. #if __XTENSA__
  68. xt_utils_wait_for_intr();
  69. #else
  70. rv_utils_wait_for_intr();
  71. #endif // __XTENSA__
  72. // never reaches here.
  73. }
  74. void RTC_IRAM_ATTR esp_wake_stub_uart_tx_wait_idle(uint8_t uart_no)
  75. {
  76. while (!uart_ll_is_tx_idle(UART_LL_GET_HW(uart_no))) {};
  77. }
  78. void RTC_IRAM_ATTR esp_wake_stub_set_wakeup_time(uint64_t time_in_us)
  79. {
  80. #if SOC_LP_TIMER_SUPPORTED
  81. uint64_t rtc_count_delta = lp_timer_ll_time_to_count(time_in_us);
  82. lp_timer_ll_counter_snapshot(&LP_TIMER);
  83. uint32_t lo = lp_timer_ll_get_counter_value_low(&LP_TIMER, 0);
  84. uint32_t hi = lp_timer_ll_get_counter_value_high(&LP_TIMER, 0);
  85. uint64_t rtc_curr_count = (uint64_t)hi << 32 | lo;
  86. lp_timer_ll_clear_alarm_intr_status(&LP_TIMER);
  87. lp_timer_ll_set_alarm_target(&LP_TIMER, 0, rtc_curr_count + rtc_count_delta);
  88. lp_timer_ll_set_target_enable(&LP_TIMER, 0, true);
  89. #else
  90. uint64_t rtc_count_delta = rtc_cntl_ll_time_to_count(time_in_us);
  91. uint64_t rtc_curr_count = rtc_cntl_ll_get_rtc_time();
  92. rtc_cntl_ll_set_wakeup_timer(rtc_curr_count + rtc_count_delta);
  93. #endif
  94. }
  95. uint32_t RTC_IRAM_ATTR esp_wake_stub_get_wakeup_cause(void)
  96. {
  97. #if SOC_PMU_SUPPORTED
  98. return pmu_ll_hp_get_wakeup_cause(&PMU);
  99. #else
  100. return rtc_cntl_ll_get_wakeup_cause();
  101. #endif
  102. }