rtc_wdt.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "soc/efuse_periph.h"
  7. #include "rtc_wdt.h"
  8. #include "soc/rtc.h"
  9. #include "hal/efuse_ll.h"
  10. #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
  11. bool rtc_wdt_get_protect_status(void)
  12. {
  13. return READ_PERI_REG(RTC_CNTL_WDTWPROTECT_REG) != RTC_CNTL_WDT_WKEY_VALUE;
  14. }
  15. void rtc_wdt_protect_off(void)
  16. {
  17. WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, RTC_CNTL_WDT_WKEY_VALUE);
  18. }
  19. void rtc_wdt_protect_on(void)
  20. {
  21. WRITE_PERI_REG(RTC_CNTL_WDTWPROTECT_REG, 0);
  22. }
  23. void rtc_wdt_enable(void)
  24. {
  25. REG_SET_BIT(RTC_CNTL_WDTFEED_REG, RTC_CNTL_WDT_FEED);
  26. SET_PERI_REG_MASK(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN | RTC_CNTL_WDT_PAUSE_IN_SLP);
  27. }
  28. void rtc_wdt_flashboot_mode_enable(void)
  29. {
  30. REG_SET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN);
  31. }
  32. void rtc_wdt_disable(void)
  33. {
  34. bool protect = rtc_wdt_get_protect_status();
  35. if (protect) {
  36. rtc_wdt_protect_off();
  37. }
  38. REG_SET_BIT(RTC_CNTL_WDTFEED_REG, RTC_CNTL_WDT_FEED);
  39. rtc_wdt_set_stage(RTC_WDT_STAGE0, RTC_WDT_STAGE_ACTION_OFF);
  40. rtc_wdt_set_stage(RTC_WDT_STAGE1, RTC_WDT_STAGE_ACTION_OFF);
  41. rtc_wdt_set_stage(RTC_WDT_STAGE2, RTC_WDT_STAGE_ACTION_OFF);
  42. rtc_wdt_set_stage(RTC_WDT_STAGE3, RTC_WDT_STAGE_ACTION_OFF);
  43. REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN);
  44. REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN);
  45. if (protect) {
  46. rtc_wdt_protect_on();
  47. }
  48. }
  49. void rtc_wdt_feed(void)
  50. {
  51. bool protect = rtc_wdt_get_protect_status();
  52. if (protect) {
  53. rtc_wdt_protect_off();
  54. }
  55. REG_SET_BIT(RTC_CNTL_WDTFEED_REG, RTC_CNTL_WDT_FEED);
  56. if (protect) {
  57. rtc_wdt_protect_on();
  58. }
  59. }
  60. static uint32_t get_addr_reg(rtc_wdt_stage_t stage)
  61. {
  62. uint32_t reg;
  63. if (stage == RTC_WDT_STAGE0) {
  64. reg = RTC_CNTL_WDTCONFIG1_REG;
  65. } else if (stage == RTC_WDT_STAGE1) {
  66. reg = RTC_CNTL_WDTCONFIG2_REG;
  67. } else if (stage == RTC_WDT_STAGE2) {
  68. reg = RTC_CNTL_WDTCONFIG3_REG;
  69. } else {
  70. reg = RTC_CNTL_WDTCONFIG4_REG;
  71. }
  72. return reg;
  73. }
  74. esp_err_t rtc_wdt_set_time(rtc_wdt_stage_t stage, unsigned int timeout_ms)
  75. {
  76. if (stage > 3) {
  77. return ESP_ERR_INVALID_ARG;
  78. }
  79. uint32_t timeout = (uint32_t) ((uint64_t) rtc_clk_slow_freq_get_hz() * timeout_ms / 1000);
  80. #if !CONFIG_IDF_TARGET_ESP32
  81. if (stage == RTC_WDT_STAGE0) {
  82. timeout = timeout >> (1 + efuse_ll_get_wdt_delay_sel());
  83. }
  84. #endif
  85. WRITE_PERI_REG(get_addr_reg(stage), timeout);
  86. return ESP_OK;
  87. }
  88. esp_err_t rtc_wdt_get_timeout(rtc_wdt_stage_t stage, unsigned int *timeout_ms)
  89. {
  90. if (stage > 3) {
  91. return ESP_ERR_INVALID_ARG;
  92. }
  93. uint32_t time_tick;
  94. uint32_t rtc_slow_freq = rtc_clk_slow_freq_get_hz();
  95. if (rtc_slow_freq == 0) {
  96. return ESP_ERR_INVALID_STATE;
  97. }
  98. time_tick = READ_PERI_REG(get_addr_reg(stage));
  99. *timeout_ms = time_tick * 1000 / rtc_slow_freq;
  100. return ESP_OK;
  101. }
  102. esp_err_t rtc_wdt_set_stage(rtc_wdt_stage_t stage, rtc_wdt_stage_action_t stage_sel)
  103. {
  104. if (stage > 3 || stage_sel > 4) {
  105. return ESP_ERR_INVALID_ARG;
  106. }
  107. if (stage == RTC_WDT_STAGE0) {
  108. REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG0, stage_sel);
  109. } else if (stage == RTC_WDT_STAGE1) {
  110. REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG1, stage_sel);
  111. } else if (stage == RTC_WDT_STAGE2) {
  112. REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG2, stage_sel);
  113. } else {
  114. REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_STG3, stage_sel);
  115. }
  116. return ESP_OK;
  117. }
  118. esp_err_t rtc_wdt_set_length_of_reset_signal(rtc_wdt_reset_sig_t reset_src, rtc_wdt_length_sig_t reset_signal_length)
  119. {
  120. if (reset_src > 1 || reset_signal_length > 7) {
  121. return ESP_ERR_INVALID_ARG;
  122. }
  123. if (reset_src == 0) {
  124. REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_SYS_RESET_LENGTH, reset_signal_length);
  125. } else {
  126. REG_SET_FIELD(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_CPU_RESET_LENGTH, reset_signal_length);
  127. }
  128. return ESP_OK;
  129. }
  130. bool rtc_wdt_is_on(void)
  131. {
  132. return (REG_GET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_EN) != 0) || (REG_GET_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN) != 0);
  133. }
  134. #endif // CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2