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_ESP32C2) || 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_ESP32C2) || 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 	int irq_priority;
46 	int irq_flags;
47 	const struct device *clock_dev;
48 };
49 
50 struct counter_esp32_data {
51 	struct counter_alarm_cfg alarm_cfg;
52 	uint32_t ticks;
53 	uint32_t clk_src_freq;
54 };
55 
counter_esp32_init(const struct device * dev)56 static int counter_esp32_init(const struct device *dev)
57 {
58 	const struct counter_esp32_config *cfg = dev->config;
59 	struct counter_esp32_data *data = dev->data;
60 	int ret, flags;
61 
62 	/* RTC_SLOW_CLK is the default clk source */
63 	clock_control_get_rate(cfg->clock_dev,
64 			       (clock_control_subsys_t)ESP32_CLOCK_CONTROL_SUBSYS_RTC_SLOW,
65 			       &data->clk_src_freq);
66 
67 	flags = ESP_PRIO_TO_FLAGS(cfg->irq_priority) | ESP_INT_FLAGS_CHECK(cfg->irq_flags) |
68 		ESP_INTR_FLAG_SHARED;
69 	ret = esp_intr_alloc(cfg->irq_source, flags,
70 			     (ESP32_COUNTER_RTC_ISR_HANDLER)counter_esp32_isr, (void *)dev, NULL);
71 
72 	if (ret != 0) {
73 		LOG_ERR("could not allocate interrupt (err %d)", ret);
74 	}
75 
76 	return ret;
77 }
78 
counter_esp32_start(const struct device * dev)79 static int counter_esp32_start(const struct device *dev)
80 {
81 	ARG_UNUSED(dev);
82 
83 	/* RTC main timer runs after power-on reset */
84 	return 0;
85 }
86 
counter_esp32_stop(const struct device * dev)87 static int counter_esp32_stop(const struct device *dev)
88 {
89 	ARG_UNUSED(dev);
90 
91 	/*
92 	 * Any reset/sleep mode, except for the power-up
93 	 * reset, will not stop or reset the RTC timer
94 	 * ESP32 TRM v4.6 sec. 31.3.11
95 	 */
96 	return 0;
97 }
98 
counter_esp32_get_value(const struct device * dev,uint32_t * ticks)99 static int counter_esp32_get_value(const struct device *dev, uint32_t *ticks)
100 {
101 	ARG_UNUSED(dev);
102 
103 	*ticks = (uint32_t) rtc_cntl_ll_get_rtc_time();
104 
105 	return 0;
106 }
107 
counter_esp32_set_alarm(const struct device * dev,uint8_t chan_id,const struct counter_alarm_cfg * alarm_cfg)108 static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id,
109 				   const struct counter_alarm_cfg *alarm_cfg)
110 {
111 	ARG_UNUSED(chan_id);
112 	struct counter_esp32_data *data = dev->data;
113 	uint32_t now;
114 	uint32_t ticks = 0;
115 
116 #if defined(CONFIG_SOC_SERIES_ESP32) || defined(CONFIG_SOC_SERIES_ESP32C2) || \
117 	defined(CONFIG_SOC_SERIES_ESP32C3)
118 	/* In ESP32/C3 Series the min possible value is 30+ us*/
119 	if (counter_ticks_to_us(dev, alarm_cfg->ticks) <= 30) {
120 		return -EINVAL;
121 	}
122 #endif
123 	data->alarm_cfg.callback = alarm_cfg->callback;
124 	data->alarm_cfg.user_data = alarm_cfg->user_data;
125 
126 	counter_esp32_get_value(dev, &now);
127 
128 	ticks = (alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) ? alarm_cfg->ticks
129 								: now + alarm_cfg->ticks;
130 
131 	rtc_cntl_ll_set_wakeup_timer(ticks);
132 
133 	/* RTC main timer set alarm value */
134 	CLEAR_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, 0xffffffff);
135 
136 	/* RTC main timer set alarm enable */
137 	SET_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN);
138 
139 	/* RTC main timer interrupt enable */
140 	SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_MAIN_TIMER_INT_ENA);
141 
142 	return 0;
143 }
144 
counter_esp32_cancel_alarm(const struct device * dev,uint8_t chan_id)145 static int counter_esp32_cancel_alarm(const struct device *dev, uint8_t chan_id)
146 {
147 	ARG_UNUSED(dev);
148 	ARG_UNUSED(chan_id);
149 
150 	/* RTC main timer set alarm disable */
151 	CLEAR_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN);
152 
153 	/* RTC main timer interrupt disable */
154 	SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR);
155 
156 	return 0;
157 }
158 
counter_esp32_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)159 static int counter_esp32_set_top_value(const struct device *dev,
160 				       const struct counter_top_cfg *cfg)
161 {
162 	const struct counter_esp32_config *config = dev->config;
163 
164 	if (cfg->ticks != config->counter_info.max_top_value) {
165 		return -ENOTSUP;
166 	}
167 
168 	return 0;
169 }
170 
counter_esp32_get_pending_int(const struct device * dev)171 static uint32_t counter_esp32_get_pending_int(const struct device *dev)
172 {
173 	ARG_UNUSED(dev);
174 
175 	uint32_t rc = READ_PERI_REG(RTC_CNTL_INT_ST_REG) & RTC_CNTL_MAIN_TIMER_INT_ST;
176 
177 	return (rc >> RTC_CNTL_MAIN_TIMER_INT_ST_S);
178 }
179 
180 /*
181  * Espressif's RTC Timer is actually 48-bits in resolution
182  * However, the top value returned is limited to UINT32_MAX
183  * as per the counter API.
184  */
counter_esp32_get_top_value(const struct device * dev)185 static uint32_t counter_esp32_get_top_value(const struct device *dev)
186 {
187 	const struct counter_esp32_config *cfg = dev->config;
188 
189 	return cfg->counter_info.max_top_value;
190 }
191 
counter_esp32_get_freq(const struct device * dev)192 static uint32_t counter_esp32_get_freq(const struct device *dev)
193 {
194 	struct counter_esp32_data *data = dev->data;
195 
196 	return data->clk_src_freq;
197 }
198 
199 static struct counter_esp32_data counter_data;
200 
201 static const struct counter_esp32_config counter_config = {
202 	.counter_info = {
203 		.max_top_value = UINT32_MAX,
204 		.flags = COUNTER_CONFIG_INFO_COUNT_UP,
205 		.channels = 1
206 	},
207 	.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
208 	.irq_source = DT_INST_IRQ_BY_IDX(0, 0, irq),
209 	.irq_priority = DT_INST_IRQ_BY_IDX(0, 0, priority),
210 	.irq_flags = DT_INST_IRQ_BY_IDX(0, 0, flags)
211 };
212 
213 static DEVICE_API(counter, rtc_timer_esp32_api) = {
214 	.start = counter_esp32_start,
215 	.stop = counter_esp32_stop,
216 	.get_value = counter_esp32_get_value,
217 	.set_alarm = counter_esp32_set_alarm,
218 	.cancel_alarm = counter_esp32_cancel_alarm,
219 	.set_top_value = counter_esp32_set_top_value,
220 	.get_pending_int = counter_esp32_get_pending_int,
221 	.get_top_value = counter_esp32_get_top_value,
222 	.get_freq = counter_esp32_get_freq,
223 };
224 
counter_esp32_isr(void * arg)225 static void counter_esp32_isr(void *arg)
226 {
227 	const struct device *dev = (const struct device *)arg;
228 	struct counter_esp32_data *data = dev->data;
229 	uint32_t now;
230 	uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
231 
232 	if (!(status & RTC_CNTL_MAIN_TIMER_INT_ST_M)) {
233 		return;
234 	}
235 
236 	counter_esp32_cancel_alarm(dev, 0);
237 	counter_esp32_get_value(dev, &now);
238 
239 	if (data->alarm_cfg.callback) {
240 		data->alarm_cfg.callback(dev, 0, now, data->alarm_cfg.user_data);
241 	}
242 }
243 
244 DEVICE_DT_INST_DEFINE(0,
245 		      &counter_esp32_init,
246 		      NULL,
247 		      &counter_data,
248 		      &counter_config,
249 		      POST_KERNEL,
250 		      CONFIG_COUNTER_INIT_PRIORITY,
251 		      &rtc_timer_esp32_api);
252