1 /*
2 * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT espressif_esp32_rtc_timer
8
9 /*
10 * Include esp-idf headers first to avoid
11 * redefining BIT() macro
12 */
13 #include "soc/rtc_cntl_reg.h"
14 #include "soc/rtc.h"
15 #include <esp_rom_sys.h>
16 #include <hal/rtc_cntl_ll.h>
17
18 #include <zephyr/device.h>
19 #include <zephyr/drivers/counter.h>
20 #include <zephyr/spinlock.h>
21 #include <zephyr/kernel.h>
22 #include <zephyr/drivers/clock_control.h>
23 #include <zephyr/drivers/clock_control/esp32_clock_control.h>
24
25 #if defined(CONFIG_SOC_SERIES_ESP32C3)
26 #include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
27 #else
28 #include <zephyr/drivers/interrupt_controller/intc_esp32.h>
29 #endif
30
31 #include <zephyr/logging/log.h>
32 LOG_MODULE_REGISTER(esp32_counter_rtc, CONFIG_COUNTER_LOG_LEVEL);
33
34 #if defined(CONFIG_SOC_SERIES_ESP32C3)
35 #define ESP32_COUNTER_RTC_ISR_HANDLER isr_handler_t
36 #else
37 #define ESP32_COUNTER_RTC_ISR_HANDLER intr_handler_t
38 #endif
39
40 static void counter_esp32_isr(void *arg);
41
42 struct counter_esp32_config {
43 struct counter_config_info counter_info;
44 int irq_source;
45 const struct device *clock_dev;
46 };
47
48 struct counter_esp32_data {
49 struct counter_alarm_cfg alarm_cfg;
50 uint32_t ticks;
51 uint32_t clk_src_freq;
52 };
53
counter_esp32_init(const struct device * dev)54 static int counter_esp32_init(const struct device *dev)
55 {
56 const struct counter_esp32_config *cfg = dev->config;
57 struct counter_esp32_data *data = dev->data;
58
59
60 /* RTC_SLOW_CLK is the default clk source */
61 clock_control_get_rate(cfg->clock_dev,
62 (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW,
63 &data->clk_src_freq);
64
65 esp_intr_alloc(cfg->irq_source,
66 0,
67 (ESP32_COUNTER_RTC_ISR_HANDLER)counter_esp32_isr,
68 (void *)dev,
69 NULL);
70
71 return 0;
72 }
73
counter_esp32_start(const struct device * dev)74 static int counter_esp32_start(const struct device *dev)
75 {
76 ARG_UNUSED(dev);
77
78 /* RTC main timer runs after power-on reset */
79 return 0;
80 }
81
counter_esp32_stop(const struct device * dev)82 static int counter_esp32_stop(const struct device *dev)
83 {
84 ARG_UNUSED(dev);
85
86 /*
87 * Any reset/sleep mode, except for the power-up
88 * reset, will not stop or reset the RTC timer
89 * ESP32 TRM v4.6 sec. 31.3.11
90 */
91 return 0;
92 }
93
counter_esp32_get_value(const struct device * dev,uint32_t * ticks)94 static int counter_esp32_get_value(const struct device *dev, uint32_t *ticks)
95 {
96 ARG_UNUSED(dev);
97
98 *ticks = (uint32_t) rtc_cntl_ll_get_rtc_time();
99
100 return 0;
101 }
102
counter_esp32_set_alarm(const struct device * dev,uint8_t chan_id,const struct counter_alarm_cfg * alarm_cfg)103 static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id,
104 const struct counter_alarm_cfg *alarm_cfg)
105 {
106 ARG_UNUSED(chan_id);
107 struct counter_esp32_data *data = dev->data;
108 uint32_t now;
109 uint32_t ticks = 0;
110
111 #if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32C3)
112 /* In ESP32/C3 Series the min possible value is 30 us*/
113 if (counter_ticks_to_us(dev, alarm_cfg->ticks) < 30) {
114 return -EINVAL;
115 }
116 #endif
117 data->alarm_cfg.callback = alarm_cfg->callback;
118 data->alarm_cfg.user_data = alarm_cfg->user_data;
119
120 counter_esp32_get_value(dev, &now);
121
122 ticks = (alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) ? alarm_cfg->ticks
123 : now + alarm_cfg->ticks;
124
125 rtc_cntl_ll_set_wakeup_timer(ticks);
126
127 /* RTC main timer set alarm value */
128 CLEAR_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, 0xffffffff);
129
130 /* RTC main timer set alarm enable */
131 SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN);
132
133 /* RTC main timer interrupt enable */
134 SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_MAIN_TIMER_INT_ENA);
135
136 return 0;
137 }
138
counter_esp32_cancel_alarm(const struct device * dev,uint8_t chan_id)139 static int counter_esp32_cancel_alarm(const struct device *dev, uint8_t chan_id)
140 {
141 ARG_UNUSED(dev);
142 ARG_UNUSED(chan_id);
143
144 /* RTC main timer interrupt disable */
145 SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR);
146
147 /* RTC main timer set alarm disable */
148 CLEAR_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN);
149
150 return 0;
151 }
152
counter_esp32_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)153 static int counter_esp32_set_top_value(const struct device *dev,
154 const struct counter_top_cfg *cfg)
155 {
156 const struct counter_esp32_config *config = dev->config;
157
158 if (cfg->ticks != config->counter_info.max_top_value) {
159 return -ENOTSUP;
160 }
161
162 return 0;
163 }
164
counter_esp32_get_pending_int(const struct device * dev)165 static uint32_t counter_esp32_get_pending_int(const struct device *dev)
166 {
167 ARG_UNUSED(dev);
168
169 uint32_t rc = READ_PERI_REG(RTC_CNTL_INT_ST_REG) & RTC_CNTL_MAIN_TIMER_INT_ST;
170
171 return (rc >> RTC_CNTL_MAIN_TIMER_INT_ST_S);
172 }
173
174 /*
175 * Espressif's RTC Timer is actually 48-bits in resolution
176 * However, the top value returned is limited to UINT32_MAX
177 * as per the counter API.
178 */
counter_esp32_get_top_value(const struct device * dev)179 static uint32_t counter_esp32_get_top_value(const struct device *dev)
180 {
181 const struct counter_esp32_config *cfg = dev->config;
182
183 return cfg->counter_info.max_top_value;
184 }
185
counter_esp32_get_freq(const struct device * dev)186 static uint32_t counter_esp32_get_freq(const struct device *dev)
187 {
188 struct counter_esp32_data *data = dev->data;
189
190 return data->clk_src_freq;
191 }
192
193 static struct counter_esp32_data counter_data;
194
195 static const struct counter_esp32_config counter_config = {
196 .counter_info = {
197 .max_top_value = UINT32_MAX,
198 .flags = COUNTER_CONFIG_INFO_COUNT_UP,
199 .channels = 1
200 },
201 .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
202 .irq_source = DT_INST_IRQN(0),
203 };
204
205 static const struct counter_driver_api rtc_timer_esp32_api = {
206 .start = counter_esp32_start,
207 .stop = counter_esp32_stop,
208 .get_value = counter_esp32_get_value,
209 .set_alarm = counter_esp32_set_alarm,
210 .cancel_alarm = counter_esp32_cancel_alarm,
211 .set_top_value = counter_esp32_set_top_value,
212 .get_pending_int = counter_esp32_get_pending_int,
213 .get_top_value = counter_esp32_get_top_value,
214 .get_freq = counter_esp32_get_freq,
215 };
216
counter_esp32_isr(void * arg)217 static void counter_esp32_isr(void *arg)
218 {
219 const struct device *dev = (const struct device *)arg;
220 struct counter_esp32_data *data = dev->data;
221 uint32_t now;
222
223 counter_esp32_cancel_alarm(dev, 0);
224 counter_esp32_get_value(dev, &now);
225
226 if (data->alarm_cfg.callback) {
227 data->alarm_cfg.callback(dev, 0, now, data->alarm_cfg.user_data);
228 }
229
230 /* RTC timer clear interrupt status */
231 SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR);
232 }
233
234 DEVICE_DT_INST_DEFINE(0,
235 &counter_esp32_init,
236 NULL,
237 &counter_data,
238 &counter_config,
239 POST_KERNEL,
240 CONFIG_COUNTER_INIT_PRIORITY,
241 &rtc_timer_esp32_api);
242