1 /*
2  * SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #pragma once
8 
9 #include "soc/soc.h"
10 #include "soc/rtc.h"
11 #include "esp_attr.h"
12 #include "clk_tree_ll.h"
13 #include "esp_rom_sys.h"
14 #include "hal/assert.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
rtc_cntl_ll_set_wakeup_timer(uint64_t t)20 FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t)
21 {
22     WRITE_PERI_REG(RTC_CNTL_SLP_TIMER0_REG, t & UINT32_MAX);
23     WRITE_PERI_REG(RTC_CNTL_SLP_TIMER1_REG, t >> 32);
24 }
25 
rtc_cntl_ll_ext1_clear_wakeup_status(void)26 FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_status(void)
27 {
28     REG_SET_BIT(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_STATUS_CLR);
29 }
30 
rtc_cntl_ll_ext1_get_wakeup_status(void)31 FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_status(void)
32 {
33     return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_STATUS_REG, RTC_CNTL_EXT_WAKEUP1_STATUS);
34 }
35 
rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t io_mask,uint32_t mode_mask)36 FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_set_wakeup_pins(uint32_t io_mask, uint32_t mode_mask)
37 {
38     // The target only supports a unified trigger mode among all EXT1 wakeup IOs
39     HAL_ASSERT((io_mask & mode_mask) == io_mask || (io_mask & mode_mask) == 0);
40     REG_SET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL, io_mask);
41     if ((io_mask & mode_mask) == io_mask) {
42         SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1,
43                 1, RTC_CNTL_EXT_WAKEUP1_LV_S);
44     } else {
45         SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1,
46                 0, RTC_CNTL_EXT_WAKEUP1_LV_S);
47     }
48 }
49 
rtc_cntl_ll_ext1_clear_wakeup_pins(void)50 FORCE_INLINE_ATTR void rtc_cntl_ll_ext1_clear_wakeup_pins(void)
51 {
52     CLEAR_PERI_REG_MASK(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL_M);
53 }
54 
rtc_cntl_ll_ext1_get_wakeup_pins(void)55 FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_ext1_get_wakeup_pins(void)
56 {
57     return REG_GET_FIELD(RTC_CNTL_EXT_WAKEUP1_REG, RTC_CNTL_EXT_WAKEUP1_SEL);
58 }
59 
rtc_cntl_ll_ulp_wakeup_enable(void)60 FORCE_INLINE_ATTR void rtc_cntl_ll_ulp_wakeup_enable(void)
61 {
62     SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_WAKEUP_FORCE_EN);
63 }
64 
rtc_cntl_ll_ulp_int_clear(void)65 FORCE_INLINE_ATTR void rtc_cntl_ll_ulp_int_clear(void)
66 {
67     REG_SET_BIT(RTC_CNTL_INT_CLR_REG, RTC_CNTL_SAR_INT_CLR);
68 }
69 
rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)70 FORCE_INLINE_ATTR void rtc_cntl_ll_timer2_set_touch_wait_cycle(uint32_t wait_cycle)
71 {
72     REG_SET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT, wait_cycle);
73 }
74 
rtc_cntl_ll_reset_system(void)75 FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void)
76 {
77     REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
78 }
79 
rtc_cntl_ll_reset_cpu(int cpu_no)80 FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no)
81 {
82     uint32_t rtc_cntl_rst = (cpu_no == 0) ? RTC_CNTL_SW_PROCPU_RST : RTC_CNTL_SW_APPCPU_RST;
83     REG_WRITE(RTC_CNTL_OPTIONS0_REG, rtc_cntl_rst);
84 }
85 
rtc_cntl_ll_sleep_enable(void)86 FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void)
87 {
88     SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
89 }
90 
rtc_cntl_ll_get_rtc_time(void)91 FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void)
92 {
93     SET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_UPDATE);
94     int attempts = 1000;
95     while (GET_PERI_REG_MASK(RTC_CNTL_TIME_UPDATE_REG, RTC_CNTL_TIME_VALID) == 0) {
96         esp_rom_delay_us(1);
97         if (attempts) {
98             if (--attempts == 0 && clk_ll_xtal32k_digi_is_enabled()) {
99                 esp_rom_printf("32KHz xtal has been stopped\n");
100             }
101         }
102     }
103     SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_TIME_VALID_INT_CLR);
104     uint64_t t = READ_PERI_REG(RTC_CNTL_TIME0_REG);
105     t |= ((uint64_t) READ_PERI_REG(RTC_CNTL_TIME1_REG)) << 32;
106     return t;
107 }
108 
rtc_cntl_ll_time_to_count(uint64_t time_in_us)109 FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us)
110 {
111     uint32_t slow_clk_value = REG_READ(RTC_CNTL_STORE1_REG);
112     return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value);
113 }
114 
rtc_cntl_ll_get_wakeup_cause(void)115 FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void)
116 {
117     return REG_GET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_CAUSE);
118 }
119 
120 #ifdef __cplusplus
121 }
122 #endif
123