Skip to content

Commit 1d2f012

Browse files
Raffael Rostagnohenrikbrixandersen
authored andcommitted
drivers: counter: rtc: esp32: Add LP TIMER support
Add support to LP TIMER peripheral, for ESP32-C6 and ESP32-H2 RTC counter support. Signed-off-by: Raffael Rostagno <[email protected]>
1 parent 01d4308 commit 1d2f012

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

drivers/counter/counter_esp32_rtc.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@
66

77
#define DT_DRV_COMPAT espressif_esp32_rtc_timer
88

9+
#include <soc/soc_caps.h>
10+
#include <esp_rom_sys.h>
11+
12+
#if SOC_LP_TIMER_SUPPORTED
13+
#include "hal/lp_timer_ll.h"
14+
#else
915
#include "soc/rtc_cntl_reg.h"
1016
#include "soc/rtc.h"
11-
#include <esp_rom_sys.h>
1217
#include <hal/rtc_cntl_ll.h>
18+
#endif
1319

1420
#include <zephyr/device.h>
1521
#include <zephyr/drivers/counter.h>
@@ -26,6 +32,9 @@ static void counter_esp32_isr(void *arg);
2632

2733
struct counter_esp32_config {
2834
struct counter_config_info counter_info;
35+
#if SOC_LP_TIMER_SUPPORTED
36+
lp_timer_dev_t *dev;
37+
#endif
2938
int irq_source;
3039
int irq_priority;
3140
int irq_flags;
@@ -84,18 +93,37 @@ static int counter_esp32_stop(const struct device *dev)
8493

8594
static int counter_esp32_get_value(const struct device *dev, uint32_t *ticks)
8695
{
96+
#if SOC_LP_TIMER_SUPPORTED
97+
const struct counter_esp32_config *cfg = dev->config;
98+
99+
lp_timer_ll_counter_snapshot(cfg->dev);
100+
101+
*ticks = lp_timer_ll_get_counter_value_low(cfg->dev, 0);
102+
#else
87103
ARG_UNUSED(dev);
88104

89105
*ticks = (uint32_t) rtc_cntl_ll_get_rtc_time();
106+
#endif
90107

91108
return 0;
92109
}
93110

94111
static int counter_esp32_get_value_64(const struct device *dev, uint64_t *ticks)
95112
{
113+
#if SOC_LP_TIMER_SUPPORTED
114+
const struct counter_esp32_config *cfg = dev->config;
115+
116+
lp_timer_ll_counter_snapshot(cfg->dev);
117+
118+
uint32_t lo = lp_timer_ll_get_counter_value_low(cfg->dev, 0);
119+
uint32_t hi = lp_timer_ll_get_counter_value_high(cfg->dev, 0);
120+
121+
*ticks = ((uint64_t)hi << 32 | lo);
122+
#else
96123
ARG_UNUSED(dev);
97124

98125
*ticks = rtc_cntl_ll_get_rtc_time();
126+
#endif
99127

100128
return 0;
101129
}
@@ -104,6 +132,10 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id,
104132
const struct counter_alarm_cfg *alarm_cfg)
105133
{
106134
ARG_UNUSED(chan_id);
135+
#if SOC_LP_TIMER_SUPPORTED
136+
const struct counter_esp32_config *cfg = dev->config;
137+
lp_timer_dev_t *lp_timer = cfg->dev;
138+
#endif
107139
struct counter_esp32_data *data = dev->data;
108140
uint64_t now;
109141
uint64_t ticks = 0;
@@ -131,6 +163,12 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id,
131163

132164
data->ticks = (uint32_t)ticks;
133165

166+
#if SOC_LP_TIMER_SUPPORTED
167+
lp_timer_ll_clear_alarm_intr_status(cfg->dev);
168+
lp_timer_ll_set_alarm_target(cfg->dev, 0, ticks);
169+
lp_timer_ll_set_target_enable(cfg->dev, 0, true);
170+
lp_timer->int_en.alarm = 1;
171+
#else
134172
rtc_cntl_ll_set_wakeup_timer(ticks);
135173

136174
/* RTC main timer set alarm value */
@@ -141,6 +179,7 @@ static int counter_esp32_set_alarm(const struct device *dev, uint8_t chan_id,
141179

142180
/* RTC main timer interrupt enable */
143181
SET_PERI_REG_MASK(RTC_CNTL_INT_ENA_REG, RTC_CNTL_MAIN_TIMER_INT_ENA);
182+
#endif
144183

145184
return 0;
146185
}
@@ -150,12 +189,21 @@ static int counter_esp32_cancel_alarm(const struct device *dev, uint8_t chan_id)
150189
ARG_UNUSED(chan_id);
151190
struct counter_esp32_data *data = dev->data;
152191

192+
#if SOC_LP_TIMER_SUPPORTED
193+
const struct counter_esp32_config *cfg = dev->config;
194+
lp_timer_dev_t *lp_timer = cfg->dev;
195+
196+
lp_timer_ll_set_target_enable(cfg->dev, 0, false);
197+
lp_timer->int_en.alarm = 0;
198+
lp_timer_ll_clear_alarm_intr_status(cfg->dev);
199+
#else
153200
/* RTC main timer set alarm disable */
154201
CLEAR_PERI_REG_MASK(RTC_CNTL_SLP_TIMER1_REG, RTC_CNTL_MAIN_TIMER_ALARM_EN);
155202

156203
/* RTC main timer interrupt disable, and clear interrupt flag */
157204
REG_WRITE(RTC_CNTL_INT_ENA_REG, 0);
158205
SET_PERI_REG_MASK(RTC_CNTL_INT_CLR_REG, RTC_CNTL_MAIN_TIMER_INT_CLR);
206+
#endif
159207

160208
data->alarm_cfg.callback = NULL;
161209
data->alarm_cfg.user_data = NULL;
@@ -177,11 +225,18 @@ static int counter_esp32_set_top_value(const struct device *dev,
177225

178226
static uint32_t counter_esp32_get_pending_int(const struct device *dev)
179227
{
228+
#if SOC_LP_TIMER_SUPPORTED
229+
const struct counter_esp32_config *cfg = dev->config;
230+
lp_timer_dev_t *lp_timer = cfg->dev;
231+
232+
return lp_timer->int_st.alarm;
233+
#else
180234
ARG_UNUSED(dev);
181235

182236
uint32_t rc = READ_PERI_REG(RTC_CNTL_INT_ST_REG) & RTC_CNTL_MAIN_TIMER_INT_ST;
183237

184238
return (rc >> RTC_CNTL_MAIN_TIMER_INT_ST_S);
239+
#endif
185240
}
186241

187242
/*
@@ -211,6 +266,9 @@ static const struct counter_esp32_config counter_config = {
211266
.flags = COUNTER_CONFIG_INFO_COUNT_UP,
212267
.channels = 1
213268
},
269+
#if SOC_LP_TIMER_SUPPORTED
270+
.dev = (lp_timer_dev_t *)DT_INST_REG_ADDR(0),
271+
#endif
214272
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(0)),
215273
.irq_source = DT_INST_IRQ_BY_IDX(0, 0, irq),
216274
.irq_priority = DT_INST_IRQ_BY_IDX(0, 0, priority),
@@ -237,11 +295,21 @@ static void counter_esp32_isr(void *arg)
237295
counter_alarm_callback_t cb = data->alarm_cfg.callback;
238296
void *cb_data = data->alarm_cfg.user_data;
239297
uint32_t now;
298+
299+
#if SOC_LP_TIMER_SUPPORTED
300+
const struct counter_esp32_config *cfg = dev->config;
301+
lp_timer_dev_t *lp_timer = cfg->dev;
302+
303+
if (!lp_timer->int_st.alarm) {
304+
return;
305+
}
306+
#else
240307
uint32_t status = REG_READ(RTC_CNTL_INT_ST_REG);
241308

242309
if (!(status & RTC_CNTL_MAIN_TIMER_INT_ST_M)) {
243310
return;
244311
}
312+
#endif
245313

246314
counter_esp32_cancel_alarm(dev, 0);
247315
counter_esp32_get_value(dev, &now);

0 commit comments

Comments
 (0)