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