From 83f3ba6d22d063dcbe1cf042b9ef3ca274cfe7ef Mon Sep 17 00:00:00 2001 From: Gustavo Henrique Nihei Date: Tue, 22 Feb 2022 15:01:06 -0300 Subject: [PATCH] xtensa/esp32s3: Add support for Timer Groups 0 and 1 Signed-off-by: Gustavo Henrique Nihei --- arch/xtensa/src/esp32s3/Kconfig | 34 +- arch/xtensa/src/esp32s3/Make.defs | 7 + arch/xtensa/src/esp32s3/esp32s3_tim.c | 1007 +++++++++++++++++ arch/xtensa/src/esp32s3/esp32s3_tim.h | 145 +++ .../src/esp32s3/esp32s3_tim_lowerhalf.c | 602 ++++++++++ .../src/esp32s3/esp32s3_tim_lowerhalf.h | 42 + .../xtensa/src/esp32s3/hardware/esp32s3_tim.h | 944 +++++++++++++++ 7 files changed, 2780 insertions(+), 1 deletion(-) create mode 100644 arch/xtensa/src/esp32s3/esp32s3_tim.c create mode 100644 arch/xtensa/src/esp32s3/esp32s3_tim.h create mode 100644 arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.c create mode 100644 arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.h create mode 100644 arch/xtensa/src/esp32s3/hardware/esp32s3_tim.h diff --git a/arch/xtensa/src/esp32s3/Kconfig b/arch/xtensa/src/esp32s3/Kconfig index 5753d5713b..65ef82236c 100644 --- a/arch/xtensa/src/esp32s3/Kconfig +++ b/arch/xtensa/src/esp32s3/Kconfig @@ -302,6 +302,10 @@ config ESP32S3_UART bool default n +config ESP32S3_TIMER + bool + default n + config ESP32S3_UART0 bool "UART 0" default n @@ -323,7 +327,35 @@ config ESP32S3_UART2 select UART2_SERIALDRIVER select ARCH_HAVE_SERIAL_TERMIOS -endmenu # ESP32S3 Peripheral Selection +config ESP32S3_TIMER0 + bool "54-bit Timer 0 (Group 0 Timer 0)" + default n + select ESP32S3_TIMER + ---help--- + Enables Timer 0 + +config ESP32S3_TIMER1 + bool "54-bit Timer 1 (Group 0 Timer 1)" + default n + select ESP32S3_TIMER + ---help--- + Enables Timer 1 + +config ESP32S3_TIMER2 + bool "54-bit Timer 2 (Group 1 Timer 0)" + default n + select ESP32S3_TIMER + ---help--- + Enables Timer 2 + +config ESP32S3_TIMER3 + bool "54-bit Timer 3 (Group 1 Timer 1)" + default n + select ESP32S3_TIMER + ---help--- + Enables Timer 3 + +endmenu # ESP32-S3 Peripheral Selection menu "UART configuration" depends on ESP32S3_UART diff --git a/arch/xtensa/src/esp32s3/Make.defs b/arch/xtensa/src/esp32s3/Make.defs index cc3e3bba65..aa94e75119 100644 --- a/arch/xtensa/src/esp32s3/Make.defs +++ b/arch/xtensa/src/esp32s3/Make.defs @@ -72,3 +72,10 @@ CHIP_CSRCS += esp32s3_systemreset.c ifneq ($(CONFIG_ARCH_IDLE_CUSTOM),y) CHIP_CSRCS += esp32s3_idle.c endif + +ifeq ($(CONFIG_ESP32S3_TIMER),y) +CHIP_CSRCS += esp32s3_tim.c +ifeq ($(CONFIG_TIMER),y) +CHIP_CSRCS += esp32s3_tim_lowerhalf.c +endif +endif diff --git a/arch/xtensa/src/esp32s3/esp32s3_tim.c b/arch/xtensa/src/esp32s3/esp32s3_tim.c new file mode 100644 index 0000000000..9026c757d5 --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_tim.c @@ -0,0 +1,1007 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_tim.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include + +#include "xtensa.h" +#include "hardware/esp32s3_tim.h" + +#include "esp32s3_tim.h" +#include "esp32s3_irq.h" +#include "esp32s3_gpio.h" + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Timer Group IDs */ + +enum esp32s3_tim_gid_e +{ + ESP32S3_TIM_GROUP0 = 0, /* Timer Group 0 */ + ESP32S3_TIM_GROUP1, /* Timer Group 1 */ +}; + +/* Timer IDs */ + +enum esp32s3_tim_tid_e +{ + ESP32S3_TIM_TIMER0 = 0, /* Timer 0 */ + ESP32S3_TIM_TIMER1, /* Timer 1 */ +}; + +struct esp32s3_tim_priv_s +{ + struct esp32s3_tim_ops_s *ops; + enum esp32s3_tim_gid_e gid; /* Timer Group ID */ + enum esp32s3_tim_tid_e tid; /* Timer ID */ + uint8_t periph; /* Peripheral ID */ + uint8_t irq; /* Interrupt ID */ + int cpuint; /* CPU interrupt assigned to this timer */ + int core; /* Core that is taking care of the timer ints */ + bool inuse; /* Flag indicating if the timer is in use */ + uint8_t priority; /* Interrupt priority */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* TIM operations ***********************************************************/ + +static void tim_start(struct esp32s3_tim_dev_s *dev); +static void tim_stop(struct esp32s3_tim_dev_s *dev); +static void tim_clear(struct esp32s3_tim_dev_s *dev); +static void tim_setmode(struct esp32s3_tim_dev_s *dev, + enum esp32s3_tim_mode_e mode); +static void tim_setclksrc(struct esp32s3_tim_dev_s *dev, + enum esp32s3_tim_clksrc_e src); +static void tim_setpre(struct esp32s3_tim_dev_s *dev, uint16_t pre); +static void tim_getcounter(struct esp32s3_tim_dev_s *dev, uint64_t *value); +static void tim_setcounter(struct esp32s3_tim_dev_s *dev, uint64_t value); +static void tim_reload_now(struct esp32s3_tim_dev_s *dev); +static void tim_getalarmvalue(struct esp32s3_tim_dev_s *dev, + uint64_t *value); +static void tim_setalarmvalue(struct esp32s3_tim_dev_s *dev, uint64_t value); +static void tim_setalarm(struct esp32s3_tim_dev_s *dev, bool enable); +static void tim_setautoreload(struct esp32s3_tim_dev_s *dev, bool enable); +static int tim_setisr(struct esp32s3_tim_dev_s *dev, xcpt_t handler, + void *arg); +static void tim_enableint(struct esp32s3_tim_dev_s *dev); +static void tim_disableint(struct esp32s3_tim_dev_s *dev); +static void tim_ackint(struct esp32s3_tim_dev_s *dev); +static int tim_checkint(struct esp32s3_tim_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* ESP32-S3 TIM ops */ + +struct esp32s3_tim_ops_s esp32s3_tim_ops = +{ + .start = tim_start, + .stop = tim_stop, + .clear = tim_clear, + .setmode = tim_setmode, + .getcounter = tim_getcounter, + .setclksrc = tim_setclksrc, + .setpre = tim_setpre, + .setcounter = tim_setcounter, + .reloadnow = tim_reload_now, + .getalarmvalue = tim_getalarmvalue, + .setalarmvalue = tim_setalarmvalue, + .setalarm = tim_setalarm, + .setautoreload = tim_setautoreload, + .setisr = tim_setisr, + .enableint = tim_enableint, + .disableint = tim_disableint, + .ackint = tim_ackint, + .checkint = tim_checkint +}; + +#ifdef CONFIG_ESP32S3_TIMER0 +/* TIMER0 */ + +struct esp32s3_tim_priv_s g_esp32s3_tim0_priv = +{ + .ops = &esp32s3_tim_ops, + .gid = ESP32S3_TIM_GROUP0, + .tid = ESP32S3_TIM_TIMER0, + .periph = ESP32S3_PERIPH_TG_T0_LEVEL, + .irq = ESP32S3_IRQ_TG_T0_LEVEL, + .cpuint = -ENOMEM, + .core = -ENODEV, + .inuse = false, + .priority = 1, +}; +#endif + +#ifdef CONFIG_ESP32S3_TIMER1 +/* TIMER1 */ + +struct esp32s3_tim_priv_s g_esp32s3_tim1_priv = +{ + .ops = &esp32s3_tim_ops, + .gid = ESP32S3_TIM_GROUP0, + .tid = ESP32S3_TIM_TIMER1, + .periph = ESP32S3_PERIPH_TG_T1_LEVEL, + .irq = ESP32S3_IRQ_TG_T1_LEVEL, + .cpuint = -ENOMEM, + .core = -ENODEV, + .inuse = false, + .priority = 1, +}; +#endif + +#ifdef CONFIG_ESP32S3_TIMER2 +/* TIMER2 */ + +struct esp32s3_tim_priv_s g_esp32s3_tim2_priv = +{ + .ops = &esp32s3_tim_ops, + .gid = ESP32S3_TIM_GROUP1, + .tid = ESP32S3_TIM_TIMER0, + .periph = ESP32S3_PERIPH_TG1_T0_LEVEL, + .irq = ESP32S3_IRQ_TG1_T0_LEVEL, + .cpuint = -ENOMEM, + .core = -ENODEV, + .inuse = false, + .priority = 1, +}; +#endif + +#ifdef CONFIG_ESP32S3_TIMER3 +/* TIMER3 */ + +struct esp32s3_tim_priv_s g_esp32s3_tim3_priv = +{ + .ops = &esp32s3_tim_ops, + .gid = ESP32S3_TIM_GROUP1, + .tid = ESP32S3_TIM_TIMER1, + .periph = ESP32S3_PERIPH_TG1_T1_LEVEL, + .irq = ESP32S3_IRQ_TG1_T1_LEVEL, + .cpuint = -ENOMEM, + .core = -ENODEV, + .inuse = false, + .priority = 1, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tim_start + * + * Description: + * Release the counter. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * + ****************************************************************************/ + +static void tim_start(struct esp32s3_tim_dev_s *dev) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), TIMG_T0_EN_M, TIMG_T0_EN_M); + } + else + { + modifyreg32(TIMG_T1CONFIG_REG(priv->gid), TIMG_T1_EN_M, TIMG_T1_EN_M); + } +} + +/**************************************************************************** + * Name: tim_stop + * + * Description: + * Halt the counter. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * + ****************************************************************************/ + +static void tim_stop(struct esp32s3_tim_dev_s *dev) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), TIMG_T0_EN_M, 0); + } + else + { + modifyreg32(TIMG_T1CONFIG_REG(priv->gid), TIMG_T1_EN_M, 0); + } +} + +/**************************************************************************** + * Name: tim_clear + * + * Description: + * Set the counter to zero instantly. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * + ****************************************************************************/ + +static void tim_clear(struct esp32s3_tim_dev_s *dev) +{ + uint64_t clear_value = 0; + + DEBUGASSERT(dev != NULL); + + tim_setcounter(dev, clear_value); + tim_reload_now(dev); +} + +/**************************************************************************** + * Name: tim_setmode + * + * Description: + * Set counter mode. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * mode - Variable indicating the counting direction (up/down). + * + ****************************************************************************/ + +static void tim_setmode(struct esp32s3_tim_dev_s *dev, + enum esp32s3_tim_mode_e mode) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (mode == ESP32S3_TIM_MODE_DOWN) + { + if (priv->tid == ESP32S3_TIM_TIMER0) + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), TIMG_T0_INCREASE_M, 0); + } + else + { + modifyreg32(TIMG_T1CONFIG_REG(priv->gid), TIMG_T1_INCREASE_M, 0); + } + } + else if (mode == ESP32S3_TIM_MODE_UP) + { + if (priv->tid == ESP32S3_TIM_TIMER0) + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), 0, TIMG_T0_INCREASE_M); + } + else + { + modifyreg32(TIMG_T1CONFIG_REG(priv->gid), 0, TIMG_T1_INCREASE_M); + } + } +} + +/**************************************************************************** + * Name: tim_setclksrc + * + * Description: + * Set CLK source. + * NOTE: It's not necessary to configure each timer's register for clock, + * because it doesn't matter which timer is configured, the clock + * configuration will apply to the timer group. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * src - The source, it may be APB_CLK or XTAL_CLK. + * + ****************************************************************************/ + +static void tim_setclksrc(struct esp32s3_tim_dev_s *dev, + enum esp32s3_tim_clksrc_e src) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (src == ESP32S3_TIM_APB_CLK) + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), TIMG_T0_USE_XTAL_M, 0); + } + else if (src == ESP32S3_TIM_XTAL_CLK) + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), 0, TIMG_T0_USE_XTAL_M); + } +} + +/**************************************************************************** + * Name: tim_setpre + * + * Description: + * Set the prescaler. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * pre - This is the division factor. This variable accepts + * values from 0 to 65535. If pre = 0, the division factor + * is 65536, if pre = 1 or 2, the division factor is 2. + * + ****************************************************************************/ + +static void tim_setpre(struct esp32s3_tim_dev_s *dev, uint16_t pre) +{ + uint32_t mask = (uint32_t)pre << TIMG_T0_DIVIDER_S; + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), TIMG_T0_DIVIDER_M, mask); + } + else + { + modifyreg32(TIMG_T1CONFIG_REG(priv->gid), TIMG_T1_DIVIDER_M, mask); + } +} + +/**************************************************************************** + * Name: tim_getcounter + * + * Description: + * Get the current counter value. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * value - A pointer to a variable to store the current read + * value from counter. + * + ****************************************************************************/ + +static void tim_getcounter(struct esp32s3_tim_dev_s *dev, uint64_t *value) +{ + uint32_t value_32; + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + *value = 0; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + /* Dummy value (0 or 1) to latch the counter value to read it */ + + putreg32(BIT(0), TIMG_T0UPDATE_REG(priv->gid)); + + /* Read value */ + + value_32 = getreg32(TIMG_T0HI_REG(priv->gid)); /* High 32 bits */ + *value |= (uint64_t)value_32; + *value <<= SHIFT_32; + value_32 = getreg32(TIMG_T0LO_REG(priv->gid)); /* Low 32 bits */ + *value |= (uint64_t)value_32; + } + else + { + /* Dummy value (0 or 1) to latch the counter value to read it */ + + putreg32(BIT(0), TIMG_T1UPDATE_REG(priv->gid)); + + /* Read value */ + + value_32 = getreg32(TIMG_T1HI_REG(priv->gid)); /* High 32 bits */ + *value |= (uint64_t)value_32; + *value <<= SHIFT_32; + value_32 = getreg32(TIMG_T1LO_REG(priv->gid)); /* Low 32 bits */ + *value |= (uint64_t)value_32; + } +} + +/**************************************************************************** + * Name: tim_setcounter + * + * Description: + * Set the value to be loaded to the counter. + * If you want the counter to be loaded at an alarm, enable the alarm and + * the auto-reload before. + * If you want the counter to be loaded instantly, call + * tim_reload_now() after this function. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * value - The value to be loaded the counter. + * + ****************************************************************************/ + +static void tim_setcounter(struct esp32s3_tim_dev_s *dev, uint64_t value) +{ + uint64_t low_64 = value & LOW_32_MASK; + uint64_t high_64; + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + high_64 = (value >> SHIFT_32) & LOW_22_MASK; + + /* Set the counter value */ + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + putreg32((uint32_t)low_64, TIMG_T0LOADLO_REG(priv->gid)); + putreg32((uint32_t)high_64, TIMG_T0LOADHI_REG(priv->gid)); + } + else + { + putreg32((uint32_t)low_64, TIMG_T1LOADLO_REG(priv->gid)); + putreg32((uint32_t)high_64, TIMG_T1LOADHI_REG(priv->gid)); + } +} + +/**************************************************************************** + * Name: tim_reload_now + * + * Description: + * Reload the counter instantly. It may be called after + * tim_setcounter(). + * + * Parameters: + * dev - Pointer to the timer driver struct. + * + ****************************************************************************/ + +static void tim_reload_now(struct esp32s3_tim_dev_s *dev) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + /* Dummy value to trigger reloading */ + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + putreg32(BIT(0), TIMG_T0LOAD_REG(priv->gid)); + } + else + { + putreg32(BIT(0), TIMG_T1LOAD_REG(priv->gid)); + } +} + +/**************************************************************************** + * Name: tim_getalarmvalue + * + * Description: + * Get the alarm value. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * value - Pointer to retrieve the current configured alarm value. + * + ****************************************************************************/ + +static void tim_getalarmvalue(struct esp32s3_tim_dev_s *dev, uint64_t *value) +{ + uint32_t value_32; + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + *value = 0; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + value_32 = getreg32(TIMG_T0ALARMHI_REG(priv->gid)); /* High 32 bits */ + *value |= (uint64_t)value_32; + *value <<= SHIFT_32; + value_32 = getreg32(TIMG_T0ALARMLO_REG(priv->gid)); /* Low 32 bits */ + *value |= (uint64_t)value_32; + } + else + { + value_32 = getreg32(TIMG_T1ALARMHI_REG(priv->gid)); /* High 32 bits */ + *value |= (uint64_t)value_32; + *value <<= SHIFT_32; + value_32 = getreg32(TIMG_T1ALARMLO_REG(priv->gid)); /* Low 32 bits */ + *value |= (uint64_t)value_32; + } +} + +/**************************************************************************** + * Name: tim_setalarmvalue + * + * Description: + * Set the value that will trigger an alarm when the + * counter value matches this value. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * value - The alarm value. + * + ****************************************************************************/ + +static void tim_setalarmvalue(struct esp32s3_tim_dev_s *dev, uint64_t value) +{ + uint64_t low_64 = value & LOW_32_MASK; + uint64_t high_64 = (value >> SHIFT_32) & LOW_22_MASK; + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + /* Set an alarm value */ + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + putreg32((uint32_t)low_64, TIMG_T0ALARMLO_REG(priv->gid)); + putreg32((uint32_t)high_64, TIMG_T0ALARMHI_REG(priv->gid)); + } + else + { + putreg32((uint32_t)low_64, TIMG_T1ALARMLO_REG(priv->gid)); + putreg32((uint32_t)high_64, TIMG_T1ALARMHI_REG(priv->gid)); + } +} + +/**************************************************************************** + * Name: tim_setalarm + * + * Description: + * Enable/Disable the alarm. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * enable - A variable to indicate the action. If true, enable + * the alarm, if false, disable it. + * + ****************************************************************************/ + +static void tim_setalarm(struct esp32s3_tim_dev_s *dev, bool enable) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + if (enable) + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), 0, TIMG_T0_ALARM_EN_M); + } + else + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), TIMG_T0_ALARM_EN_M, 0); + } + } + else + { + if (enable) + { + modifyreg32(TIMG_T1CONFIG_REG(priv->gid), 0, TIMG_T1_ALARM_EN_M); + } + else + { + modifyreg32(TIMG_T1CONFIG_REG(priv->gid), TIMG_T1_ALARM_EN_M, 0); + } + } +} + +/**************************************************************************** + * Name: tim_setautoreload + * + * Description: + * Enable or disable the auto reload. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * enable - A variable to indicate the action. If it is true, + * enable the auto reload, if false, + * disable auto reload. + * + ****************************************************************************/ + +static void tim_setautoreload(struct esp32s3_tim_dev_s *dev, bool enable) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + if (enable) + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), 0, TIMG_T0_AUTORELOAD_M); + } + else + { + modifyreg32(TIMG_T0CONFIG_REG(priv->gid), TIMG_T0_AUTORELOAD_M, 0); + } + } + else + { + if (enable) + { + modifyreg32(TIMG_T1CONFIG_REG(priv->gid), 0, TIMG_T1_AUTORELOAD_M); + } + else + { + modifyreg32(TIMG_T1CONFIG_REG(priv->gid), TIMG_T1_AUTORELOAD_M, 0); + } + } +} + +/**************************************************************************** + * Name: tim_setisr + * + * Description: + * Allocate a CPU Interrupt, connect the peripheral source to this + * Interrupt, register the callback and enable CPU the Interruption. + * In case a NULL handler is provided, deallocate the interrupt and + * unregister the previously provided handler. + * + * Parameters: + * dev - Pointer to the driver state structure. + * handler - Callback to be invoked on timer interrupt. + * arg - Argument to be passed to the handler callback. + * + * Returned Values: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +static int tim_setisr(struct esp32s3_tim_dev_s *dev, xcpt_t handler, + void *arg) +{ + struct esp32s3_tim_priv_s *priv = NULL; + int ret = OK; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + /* Disable interrupt when callback is removed. */ + + if (handler == NULL) + { + /* If a CPU Interrupt was previously allocated, then deallocate it */ + + if (priv->cpuint != -ENOMEM) + { + /* Disable CPU Interrupt, free a previously allocated + * CPU Interrupt + */ + + up_disable_irq(priv->irq); + esp32s3_teardown_irq(priv->core, priv->periph, priv->cpuint); + irq_detach(priv->irq); + + priv->cpuint = -ENOMEM; + priv->core = -ENODEV; + } + } + + /* Otherwise set callback and enable interrupt */ + + else + { + if (priv->cpuint != -ENOMEM) + { + /* Disable the previous IRQ */ + + up_disable_irq(priv->irq); + } + + /* Set up to receive peripheral interrupts on the current CPU */ + + priv->core = up_cpu_index(); + priv->cpuint = esp32s3_setup_irq(priv->core, priv->periph, + priv->priority, ESP32S3_CPUINT_LEVEL); + if (priv->cpuint < 0) + { + tmrerr("ERROR: No CPU Interrupt available"); + ret = priv->cpuint; + goto errout; + } + + /* Associate an IRQ Number (from the timer) to an ISR */ + + ret = irq_attach(priv->irq, handler, arg); + if (ret != OK) + { + esp32s3_teardown_irq(priv->core, priv->periph, priv->cpuint); + tmrerr("ERROR: Failed to associate an IRQ Number"); + goto errout; + } + + /* Enable the CPU Interrupt that is linked to the timer */ + + up_enable_irq(priv->irq); + } + +errout: + return ret; +} + +/**************************************************************************** + * Name: tim_enableint + * + * Description: + * Enable a level Interrupt at the alarm if it is set. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * + ****************************************************************************/ + +static void tim_enableint(struct esp32s3_tim_dev_s *dev) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + modifyreg32(TIMG_INT_ENA_TIMERS_REG(priv->gid), 0, TIMG_T0_INT_ENA_M); + } + else + { + modifyreg32(TIMG_INT_ENA_TIMERS_REG(priv->gid), 0, TIMG_T1_INT_ENA_M); + } +} + +/**************************************************************************** + * Name: tim_disableint + * + * Description: + * Disable a level Interrupt at the alarm if it is set. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * + ****************************************************************************/ + +static void tim_disableint(struct esp32s3_tim_dev_s *dev) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + modifyreg32(TIMG_INT_ENA_TIMERS_REG(priv->gid), TIMG_T0_INT_ENA_M, 0); + } + else + { + modifyreg32(TIMG_INT_ENA_TIMERS_REG(priv->gid), TIMG_T1_INT_ENA_M, 0); + } +} + +/**************************************************************************** + * Name: tim_ackint + * + * Description: + * Acknowledge an interrupt, that means, clear the interrupt. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * + ****************************************************************************/ + +static void tim_ackint(struct esp32s3_tim_dev_s *dev) +{ + struct esp32s3_tim_priv_s *priv; + + DEBUGASSERT(dev != NULL); + + priv = (struct esp32s3_tim_priv_s *)dev; + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + modifyreg32(TIMG_INT_CLR_TIMERS_REG(priv->gid), 0, TIMG_T0_INT_CLR_M); + } + else + { + modifyreg32(TIMG_INT_CLR_TIMERS_REG(priv->gid), 0, TIMG_T1_INT_CLR_M); + } +} + +/**************************************************************************** + * Name: tim_checkint + * + * Description: + * Check the interrupt status bit. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * + * Returned Values: + * Return 1 in case of an interrupt is triggered, otherwise 0. + * + ****************************************************************************/ + +static int tim_checkint(struct esp32s3_tim_dev_s *dev) +{ + struct esp32s3_tim_priv_s *priv = (struct esp32s3_tim_priv_s *)dev; + uint32_t reg_value; + int ret; + + DEBUGASSERT(dev != NULL); + + reg_value = getreg32(TIMG_INT_ST_TIMERS_REG(priv->gid)); + + if (priv->tid == ESP32S3_TIM_TIMER0) + { + ret = REG_MASK(reg_value, TIMG_T0_INT_ST); + } + else + { + ret = REG_MASK(reg_value, TIMG_T1_INT_ST); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_tim_init + * + * Description: + * Initialize TIMER device. + * + * Parameters: + * timer - Timer instance to be initialized. + * Valid values: 0 or 1. + * + * Returned Values: + * If the initialization is successful, return a pointer to the timer + * driver struct associated to that timer instance. + * In case it fails, return NULL. + * + ****************************************************************************/ + +struct esp32s3_tim_dev_s *esp32s3_tim_init(int timer) +{ + struct esp32s3_tim_priv_s *tim = NULL; + + /* First, take the data structure associated with the timer instance */ + + switch (timer) + { +#ifdef CONFIG_ESP32S3_TIMER0 + case ESP32S3_TIMER0: + { + tim = &g_esp32s3_tim0_priv; + break; + } +#endif + +#ifdef CONFIG_ESP32S3_TIMER1 + case ESP32S3_TIMER1: + { + tim = &g_esp32s3_tim1_priv; + break; + } +#endif + +#ifdef CONFIG_ESP32S3_TIMER2 + case ESP32S3_TIMER2: + { + tim = &g_esp32s3_tim2_priv; + break; + } +#endif + +#ifdef CONFIG_ESP32S3_TIMER3 + case ESP32S3_TIMER3: + { + tim = &g_esp32s3_tim3_priv; + break; + } +#endif + + default: + { + tmrerr("Unsupported TIMER %d\n", timer); + goto errout; + } + } + + /* Verify if it is in use */ + + if (!tim->inuse) + { + tim->inuse = true; /* If it was not, now it is */ + } + else + { + tmrerr("TIMER %d is already in use\n", timer); + tim = NULL; + } + +errout: + return (struct esp32s3_tim_dev_s *)tim; +} + +/**************************************************************************** + * Name: esp32s3_tim_deinit + * + * Description: + * Deinit TIMER device. + * + * Parameters: + * dev - Pointer to the timer driver struct. + * + ****************************************************************************/ + +void esp32s3_tim_deinit(struct esp32s3_tim_dev_s *dev) +{ + struct esp32s3_tim_priv_s *tim = NULL; + + DEBUGASSERT(dev != NULL); + + tim = (struct esp32s3_tim_priv_s *)dev; + tim->inuse = false; +} diff --git a/arch/xtensa/src/esp32s3/esp32s3_tim.h b/arch/xtensa/src/esp32s3/esp32s3_tim.h new file mode 100644 index 0000000000..b9f7454ca2 --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_tim.h @@ -0,0 +1,145 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_tim.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_TIM_H +#define __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_TIM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_ESP32S3_TIMER0 +# define ESP32S3_TIMER0 0 +#endif + +#ifdef CONFIG_ESP32S3_TIMER1 +# define ESP32S3_TIMER1 1 +#endif + +#ifdef CONFIG_ESP32S3_TIMER2 +# define ESP32S3_TIMER2 2 +#endif + +#ifdef CONFIG_ESP32S3_TIMER3 +# define ESP32S3_TIMER3 3 +#endif + +/* Helpers ******************************************************************/ + +#define ESP32S3_TIM_START(d) ((d)->ops->start(d)) +#define ESP32S3_TIM_STOP(d) ((d)->ops->stop(d)) +#define ESP32S3_TIM_CLEAR(d) ((d)->ops->clear(d)) +#define ESP32S3_TIM_SETMODE(d, m) ((d)->ops->setmode(d, m)) +#define ESP32S3_TIM_CLK_SRC(d, s) ((d)->ops->setclksrc(d, s)) +#define ESP32S3_TIM_SETPRE(d, p) ((d)->ops->setpre(d, p)) +#define ESP32S3_TIM_GETCTR(d, v) ((d)->ops->getcounter(d, v)) +#define ESP32S3_TIM_SETCTR(d, v) ((d)->ops->setcounter(d, v)) +#define ESP32S3_TIM_RLD_NOW(d) ((d)->ops->reloadnow(d)) +#define ESP32S3_TIM_GETALRVL(d, v) ((d)->ops->getalarmvalue(d, v)) +#define ESP32S3_TIM_SETALRVL(d, v) ((d)->ops->setalarmvalue(d, v)) +#define ESP32S3_TIM_SETALRM(d, e) ((d)->ops->setalarm(d, e)) +#define ESP32S3_TIM_SETARLD(d, e) ((d)->ops->setautoreload(d, e)) +#define ESP32S3_TIM_SETISR(d, hnd, arg) ((d)->ops->setisr(d, hnd, arg)) +#define ESP32S3_TIM_ENABLEINT(d) ((d)->ops->enableint(d)) +#define ESP32S3_TIM_DISABLEINT(d) ((d)->ops->disableint(d)) +#define ESP32S3_TIM_ACKINT(d) ((d)->ops->ackint(d)) +#define ESP32S3_TIM_CHECKINT(d) ((d)->ops->checkint(d)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* Timer clock source */ + +enum esp32s3_tim_clksrc_e +{ + ESP32S3_TIM_APB_CLK, + ESP32S3_TIM_XTAL_CLK, +}; + +/* Timer mode */ + +enum esp32s3_tim_mode_e +{ + ESP32S3_TIM_MODE_DOWN, + ESP32S3_TIM_MODE_UP, +}; + +/* ESP32-S3 TIM device */ + +struct esp32s3_tim_dev_s +{ + struct esp32s3_tim_ops_s *ops; +}; + +/* ESP32-S3 TIM ops + * + * This is a struct containing the pointers to the timer operations. + */ + +struct esp32s3_tim_ops_s +{ + /* Timer tasks */ + + void (*start)(struct esp32s3_tim_dev_s *dev); + void (*stop)(struct esp32s3_tim_dev_s *dev); + void (*clear)(struct esp32s3_tim_dev_s *dev); + + /* Timer operations */ + + void (*setmode)(struct esp32s3_tim_dev_s *dev, + enum esp32s3_tim_mode_e mode); + void (*setclksrc)(struct esp32s3_tim_dev_s *dev, + enum esp32s3_tim_clksrc_e src); + void (*setpre)(struct esp32s3_tim_dev_s *dev, uint16_t pre); + void (*getcounter)(struct esp32s3_tim_dev_s *dev, uint64_t *value); + void (*setcounter)(struct esp32s3_tim_dev_s *dev, uint64_t value); + void (*reloadnow)(struct esp32s3_tim_dev_s *dev); + void (*getalarmvalue)(struct esp32s3_tim_dev_s *dev, uint64_t *value); + void (*setalarmvalue)(struct esp32s3_tim_dev_s *dev, uint64_t value); + void (*setalarm)(struct esp32s3_tim_dev_s *dev, bool enable); + void (*setautoreload)(struct esp32s3_tim_dev_s *dev, bool enable); + + /* Timer interrupts */ + + int (*setisr)(struct esp32s3_tim_dev_s *dev, xcpt_t handler, void *arg); + void (*enableint)(struct esp32s3_tim_dev_s *dev); + void (*disableint)(struct esp32s3_tim_dev_s *dev); + void (*ackint)(struct esp32s3_tim_dev_s *dev); + int (*checkint)(struct esp32s3_tim_dev_s *dev); +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct esp32s3_tim_dev_s *esp32s3_tim_init(int timer); +void esp32s3_tim_deinit(struct esp32s3_tim_dev_s *dev); + +#endif /* __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_TIM_H */ diff --git a/arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.c b/arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.c new file mode 100644 index 0000000000..fbaf40d95b --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.c @@ -0,0 +1,602 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "hardware/esp32s3_soc.h" + +#include "esp32s3_tim.h" +#include "esp32s3_tim_lowerhalf.h" +#include "esp32s3_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* TIMER configuration */ + +#define ESP32S3_TIMER_MAX_USECOND UINT32_MAX + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct esp32s3_timer_lowerhalf_s +{ + const struct timer_ops_s *ops; /* Lower half operations */ + struct esp32s3_tim_dev_s *tim; /* esp32-s3 timer driver */ + tccb_t callback; /* Current user interrupt callback */ + void *arg; /* Argument passed to upper half callback */ + bool started; /* True: Timer has been started */ + void *upper; /* Pointer to watchdog_upperhalf_s */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int timer_lh_handler(int irq, void *context, void *arg); + +/* "Lower half" driver methods **********************************************/ + +static int timer_lh_start(struct timer_lowerhalf_s *lower); +static int timer_lh_stop(struct timer_lowerhalf_s *lower); +static int timer_lh_getstatus(struct timer_lowerhalf_s *lower, + struct timer_status_s *status); +static int timer_lh_settimeout(struct timer_lowerhalf_s *lower, + uint32_t timeout); +static int timer_lh_maxtimeout(struct timer_lowerhalf_s *lower, + uint32_t *timeout); +static void timer_lh_setcallback(struct timer_lowerhalf_s *lower, + tccb_t callback, void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* "Lower half" driver methods */ + +static const struct timer_ops_s g_esp32s3_timer_ops = +{ + .start = timer_lh_start, + .stop = timer_lh_stop, + .getstatus = timer_lh_getstatus, + .settimeout = timer_lh_settimeout, + .setcallback = timer_lh_setcallback, + .maxtimeout = timer_lh_maxtimeout, + .ioctl = NULL, +}; + +#if defined(CONFIG_ESP32S3_TIMER0) +/* TIMER0 lower-half */ + +static struct esp32s3_timer_lowerhalf_s g_esp32s3_timer0_lowerhalf = +{ + .ops = &g_esp32s3_timer_ops, +}; +#endif + +#ifdef CONFIG_ESP32S3_TIMER1 +/* TIMER1 lower-half */ + +static struct esp32s3_timer_lowerhalf_s g_esp32s3_timer1_lowerhalf = +{ + .ops = &g_esp32s3_timer_ops, +}; +#endif + +#ifdef CONFIG_ESP32S3_TIMER2 + +/* TIMER2 lower-half */ + +static struct esp32s3_timer_lowerhalf_s g_esp32s3_timer2_lowerhalf = +{ + .ops = &g_esp32s3_timer_ops, +}; +#endif + +#ifdef CONFIG_ESP32S3_TIMER3 + +/* TIMER3 lower-half */ + +static struct esp32s3_timer_lowerhalf_s g_esp32s3_timer3_lowerhalf = +{ + .ops = &g_esp32s3_timer_ops, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: timer_lh_handler + * + * Description: + * Timer interrupt handler + * + ****************************************************************************/ + +static int timer_lh_handler(int irq, void *context, void *arg) +{ + struct esp32s3_timer_lowerhalf_s *priv = + (struct esp32s3_timer_lowerhalf_s *)arg; + uint32_t next_interval_us = 0; + + if (priv->callback(&next_interval_us, priv->upper)) + { + if (next_interval_us > 0) + { + /* Set a value to the alarm */ + + ESP32S3_TIM_SETALRVL(priv->tim, next_interval_us); + } + } + else + { + timer_lh_stop((struct timer_lowerhalf_s *)priv); + } + + ESP32S3_TIM_SETALRM(priv->tim, true); /* Re-enables the alarm */ + ESP32S3_TIM_ACKINT(priv->tim); /* Clear the Interrupt */ + + return OK; +} + +/**************************************************************************** + * Name: timer_lh_start + * + * Description: + * Start the timer, resetting the time to the current timeout + * + * Input Parameters: + * lower - A pointer to the representation of + * the "lower-half" driver state structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int timer_lh_start(struct timer_lowerhalf_s *lower) +{ + struct esp32s3_timer_lowerhalf_s *priv = + (struct esp32s3_timer_lowerhalf_s *)lower; + int ret = OK; + uint16_t pre; + + DEBUGASSERT(priv != NULL); + + if (priv->started) + { + /* Return EBUSY to indicate that the timer is already running */ + + ret = -EBUSY; + goto errout; + } + + /* Make sure the timer is stopped to avoid unpredictable behavior */ + + ESP32S3_TIM_STOP(priv->tim); + + /* Configure clock source */ + + ESP32S3_TIM_CLK_SRC(priv->tim, ESP32S3_TIM_APB_CLK); + + /* Calculate the suitable prescaler according to the current APB + * frequency to generate a period of 1 us. + */ + + pre = esp_clk_apb_freq() / 1000000; + + /* Configure TIMER prescaler */ + + ESP32S3_TIM_SETPRE(priv->tim, pre); + + /* Configure TIMER mode */ + + ESP32S3_TIM_SETMODE(priv->tim, ESP32S3_TIM_MODE_UP); + + /* Clear TIMER counter value */ + + ESP32S3_TIM_CLEAR(priv->tim); + + /* Enable autoreload */ + + ESP32S3_TIM_SETARLD(priv->tim, true); + + /* Enable TIMER alarm */ + + ESP32S3_TIM_SETALRM(priv->tim, true); + + /* Clear Interrupt Bits Status */ + + ESP32S3_TIM_ACKINT(priv->tim); + + /* Configure callback, in case a handler was provided before */ + + if (priv->callback != NULL) + { + irqstate_t flags = enter_critical_section(); + ret = ESP32S3_TIM_SETISR(priv->tim, timer_lh_handler, priv); + leave_critical_section(flags); + + if (ret != OK) + { + goto errout; + } + + ESP32S3_TIM_ENABLEINT(priv->tim); + } + + /* Finally, start the TIMER */ + + ESP32S3_TIM_START(priv->tim); + priv->started = true; + +errout: + return ret; +} + +/**************************************************************************** + * Name: timer_lh_stop + * + * Description: + * Stop the timer + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int timer_lh_stop(struct timer_lowerhalf_s *lower) +{ + struct esp32s3_timer_lowerhalf_s *priv = + (struct esp32s3_timer_lowerhalf_s *)lower; + int ret = OK; + irqstate_t flags; + + DEBUGASSERT(priv != NULL); + + if (!priv->started) + { + /* Return ENODEV to indicate that the timer was not running */ + + ret = -ENODEV; + goto errout; + } + + ESP32S3_TIM_DISABLEINT(priv->tim); + + flags = enter_critical_section(); + ret = ESP32S3_TIM_SETISR(priv->tim, NULL, NULL); + leave_critical_section(flags); + + ESP32S3_TIM_STOP(priv->tim); + + priv->started = false; + priv->callback = NULL; + +errout: + return ret; +} + +/**************************************************************************** + * Name: timer_lh_getstatus + * + * Description: + * Get timer status. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of the "lower- + * half" driver state structure. + * status - The location to return the status information. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int timer_lh_getstatus(struct timer_lowerhalf_s *lower, + struct timer_status_s *status) +{ + struct esp32s3_timer_lowerhalf_s *priv = + (struct esp32s3_timer_lowerhalf_s *)lower; + int ret = OK; + uint64_t current_counter_value; + uint64_t alarm_value; + + DEBUGASSERT(priv != NULL); + DEBUGASSERT(status != NULL); + + /* Return the status bit */ + + status->flags = 0; + + if (priv->started) + { + /* TIMER is running */ + + status->flags |= TCFLAGS_ACTIVE; + } + + if (priv->callback != NULL) + { + /* TIMER has a user callback function to be called when + * expiration happens + */ + + status->flags |= TCFLAGS_HANDLER; + } + + /* Get the current counter value */ + + ESP32S3_TIM_GETCTR(priv->tim, ¤t_counter_value); + + /* Get the current configured timeout */ + + ESP32S3_TIM_GETALRVL(priv->tim, &alarm_value); + + status->timeout = (uint32_t)(alarm_value); + status->timeleft = (uint32_t)(alarm_value - current_counter_value); + + return ret; +} + +/**************************************************************************** + * Name: timer_lh_settimeout + * + * Description: + * Set a new timeout value (and reset the timer) + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * timeout - The new timeout value in microseconds. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int timer_lh_settimeout(struct timer_lowerhalf_s *lower, + uint32_t timeout) +{ + struct esp32s3_timer_lowerhalf_s *priv = + (struct esp32s3_timer_lowerhalf_s *)lower; + int ret = OK; + + DEBUGASSERT(priv != NULL); + + /* Set the timeout */ + + ESP32S3_TIM_SETALRVL(priv->tim, (uint64_t)timeout); + + return ret; +} + +/**************************************************************************** + * Name: timer_lh_maxtimeout + * + * Description: + * Get the maximum timeout value + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * maxtimeout - A pointer to the variable that will store the max timeout. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int timer_lh_maxtimeout(struct timer_lowerhalf_s *lower, + uint32_t *max_timeout) +{ + DEBUGASSERT(max_timeout != NULL); + + *max_timeout = ESP32S3_TIMER_MAX_USECOND; + + return OK; +} + +/**************************************************************************** + * Name: esp32s3_setcallback + * + * Description: + * Call this user provided timeout handler. + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * callback - The new timer expiration function pointer. If this + * function pointer is NULL, then the reset-on-expiration + * behavior is restored, + * arg - Argument that will be provided in the callback + * + * Returned Value: + * The previous timer expiration function pointer or NULL is there was + * no previous function pointer. + * + ****************************************************************************/ + +static void timer_lh_setcallback(struct timer_lowerhalf_s *lower, + tccb_t callback, void *arg) +{ + struct esp32s3_timer_lowerhalf_s *priv = + (struct esp32s3_timer_lowerhalf_s *)lower; + int ret = OK; + irqstate_t flags; + + DEBUGASSERT(priv != NULL); + + /* Save the new callback */ + + priv->callback = callback; + priv->arg = arg; + + flags = enter_critical_section(); + + /* There is a user callback and the timer has already been started */ + + if (callback != NULL && priv->started) + { + ret = ESP32S3_TIM_SETISR(priv->tim, timer_lh_handler, priv); + ESP32S3_TIM_ENABLEINT(priv->tim); + } + else + { + ESP32S3_TIM_DISABLEINT(priv->tim); + ret = ESP32S3_TIM_SETISR(priv->tim, NULL, NULL); + } + + leave_critical_section(flags); + + if (ret != OK) + { + tmrerr("Error to set ISR: %d", ret); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_timer_initialize + * + * Description: + * Bind the configuration timer to a timer lower-half instance and + * register the timer drivers at 'devpath' + * + * Input Parameters: + * devpath - The full path to the timer device. This should be of the + * form /dev/timer0 + * timer - the timer's number. + * + * Returned Value: + * Zero (OK) is returned on success; A negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int esp32s3_timer_initialize(const char *devpath, uint8_t timer) +{ + struct esp32s3_timer_lowerhalf_s *lower = NULL; + int ret = OK; + + DEBUGASSERT(devpath != NULL); + + switch (timer) + { +#ifdef CONFIG_ESP32S3_TIMER0 + case ESP32S3_TIMER0: + { + lower = &g_esp32s3_timer0_lowerhalf; + break; + } +#endif + +#ifdef CONFIG_ESP32S3_TIMER1 + case ESP32S3_TIMER1: + { + lower = &g_esp32s3_timer1_lowerhalf; + break; + } +#endif + +#ifdef CONFIG_ESP32S3_TIMER2 + case ESP32S3_TIMER2: + { + lower = &g_esp32s3_timer2_lowerhalf; + break; + } +#endif + +#ifdef CONFIG_ESP32S3_TIMER3 + case ESP32S3_TIMER3: + { + lower = &g_esp32s3_timer3_lowerhalf; + break; + } +#endif + + default: + { + ret = -ENODEV; + goto errout; + } + } + + /* Initialize the elements of lower-half state structure */ + + lower->started = false; + lower->callback = NULL; + lower->tim = esp32s3_tim_init(timer); + + if (lower->tim == NULL) + { + ret = -EINVAL; + goto errout; + } + + /* Register the timer driver as /dev/timerX. The returned value from + * timer_register is a handle that could be used with timer_unregister(). + * REVISIT: The returned handle is discarded here. + */ + + lower->upper = timer_register(devpath, + (struct timer_lowerhalf_s *)lower); + if (lower->upper == NULL) + { + /* The actual cause of the failure may have been a failure to allocate + * perhaps a failure to register the timer driver (such as if the + * 'devpath' were not unique). We know here but we return EEXIST to + * indicate the failure (implying the non-unique devpath). + */ + + ret = -EEXIST; + goto errout; + } + +errout: + return ret; +} diff --git a/arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.h b/arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.h new file mode 100644 index 0000000000..da999e430a --- /dev/null +++ b/arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.h @@ -0,0 +1,42 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/esp32s3_tim_lowerhalf.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_TIM_LOWERHALF_H +#define __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_TIM_LOWERHALF_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp32s3_timer_initialize + ****************************************************************************/ + +int esp32s3_timer_initialize(const char *devpath, uint8_t timer); + +#endif /* __ARCH_XTENSA_SRC_ESP32S3_ESP32S3_TIM_LOWERHALF_H */ diff --git a/arch/xtensa/src/esp32s3/hardware/esp32s3_tim.h b/arch/xtensa/src/esp32s3/hardware/esp32s3_tim.h new file mode 100644 index 0000000000..c8be93412b --- /dev/null +++ b/arch/xtensa/src/esp32s3/hardware/esp32s3_tim.h @@ -0,0 +1,944 @@ +/**************************************************************************** + * arch/xtensa/src/esp32s3/hardware/esp32s3_tim.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_TIM_H +#define __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_TIM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "esp32s3_soc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Offset relative to each watchdog timer instance memory base */ + +#define MWDT_CONFIG0_OFFSET 0x0048 + +/* MWDT */ + +#define MWDT_CLK_PRESCALE_OFFSET 0x004c +#define MWDT_STAGE0_TIMEOUT_OFFSET 0x0050 +#define MWDT_STAGE1_TIMEOUT_OFFSET 0x0054 +#define MWDT_STAGE2_TIMEOUT_OFFSET 0x0058 +#define MWDT_STAGE3_TIMEOUT_OFFSET 0x005c +#define MWDT_FEED_OFFSET 0x0060 +#define MWDT_WP_REG 0x0064 +#define MWDT_INT_ENA_REG_OFFSET 0x0070 +#define MWDT_INT_CLR_REG_OFFSET 0x007c + +/* The value that needs to be written to TIMG_WDT_WKEY to + * write-enable the WDT registers. + */ + +#define TIMG_WDT_WKEY_VALUE 0x50d83aa1 + +/* Possible values for TIMG_WDT_STGx */ + +#define TIMG_WDT_STG_SEL_OFF 0 +#define TIMG_WDT_STG_SEL_INT 1 +#define TIMG_WDT_STG_SEL_RESET_CPU 2 +#define TIMG_WDT_STG_SEL_RESET_SYSTEM 3 + +#define TIMG_WDT_RESET_LENGTH_100_NS 0 +#define TIMG_WDT_RESET_LENGTH_200_NS 1 +#define TIMG_WDT_RESET_LENGTH_300_NS 2 +#define TIMG_WDT_RESET_LENGTH_400_NS 3 +#define TIMG_WDT_RESET_LENGTH_500_NS 4 +#define TIMG_WDT_RESET_LENGTH_800_NS 5 +#define TIMG_WDT_RESET_LENGTH_1600_NS 6 +#define TIMG_WDT_RESET_LENGTH_3200_NS 7 + +/* Maximum value in the high 22 bits from timer counters */ + +#define LOW_32_MASK 0xffffffff +#define LOW_22_MASK 0x003fffff +#define LOW_20_MASK 0x000fffff +#define LOW_26_MASK 0x03ffffff +#define SHIFT_32 32 + +/* TIMG_T0CONFIG_REG register + * Timer 0 configuration register + */ + +#define TIMG_T0CONFIG_REG(i) (REG_TIMG_BASE(i) + 0x0) + +/* TIMG_T0_EN : R/W; bitpos: [31]; default: 0; + * When set, the timer 0 time-base counter is enabled. + */ + +#define TIMG_T0_EN (BIT(31)) +#define TIMG_T0_EN_M (TIMG_T0_EN_V << TIMG_T0_EN_S) +#define TIMG_T0_EN_V 0x00000001 +#define TIMG_T0_EN_S 31 + +/* TIMG_T0_INCREASE : R/W; bitpos: [30]; default: 1; + * When set, the timer 0 time-base counter will increment every clock tick. + * When + * cleared, the timer 0 time-base counter will decrement. + */ + +#define TIMG_T0_INCREASE (BIT(30)) +#define TIMG_T0_INCREASE_M (TIMG_T0_INCREASE_V << TIMG_T0_INCREASE_S) +#define TIMG_T0_INCREASE_V 0x00000001 +#define TIMG_T0_INCREASE_S 30 + +/* TIMG_T0_AUTORELOAD : R/W; bitpos: [29]; default: 1; + * When set, timer 0 auto-reload at alarm is enabled. + */ + +#define TIMG_T0_AUTORELOAD (BIT(29)) +#define TIMG_T0_AUTORELOAD_M (TIMG_T0_AUTORELOAD_V << TIMG_T0_AUTORELOAD_S) +#define TIMG_T0_AUTORELOAD_V 0x00000001 +#define TIMG_T0_AUTORELOAD_S 29 + +/* TIMG_T0_DIVIDER : R/W; bitpos: [28:13]; default: 1; + * Timer 0 clock (T0_clk) prescaler value. + */ + +#define TIMG_T0_DIVIDER 0x0000ffff +#define TIMG_T0_DIVIDER_M (TIMG_T0_DIVIDER_V << TIMG_T0_DIVIDER_S) +#define TIMG_T0_DIVIDER_V 0x0000ffff +#define TIMG_T0_DIVIDER_S 13 + +/* TIMG_T0_ALARM_EN : R/W/SC; bitpos: [10]; default: 0; + * When set, the alarm is enabled. This bit is automatically cleared once an + * alarm occurs. + */ + +#define TIMG_T0_ALARM_EN (BIT(10)) +#define TIMG_T0_ALARM_EN_M (TIMG_T0_ALARM_EN_V << TIMG_T0_ALARM_EN_S) +#define TIMG_T0_ALARM_EN_V 0x00000001 +#define TIMG_T0_ALARM_EN_S 10 + +/* TIMG_T0_USE_XTAL : R/W; bitpos: [9]; default: 0; + * 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the + * source clock of timer group. + */ + +#define TIMG_T0_USE_XTAL (BIT(9)) +#define TIMG_T0_USE_XTAL_M (TIMG_T0_USE_XTAL_V << TIMG_T0_USE_XTAL_S) +#define TIMG_T0_USE_XTAL_V 0x00000001 +#define TIMG_T0_USE_XTAL_S 9 + +/* TIMG_T0LO_REG register + * Timer 0 current value, low 32 bits + */ + +#define TIMG_T0LO_REG(i) (REG_TIMG_BASE(i) + 0x4) + +/* TIMG_T0_LO : RO; bitpos: [31:0]; default: 0; + * After writing to TIMG_T0UPDATE_REG, the low 32 bits of the time-base + * counter + * of timer 0 can be read here. + */ + +#define TIMG_T0_LO 0xffffffff +#define TIMG_T0_LO_M (TIMG_T0_LO_V << TIMG_T0_LO_S) +#define TIMG_T0_LO_V 0xffffffff +#define TIMG_T0_LO_S 0 + +/* TIMG_T0HI_REG register + * Timer 0 current value, high 22 bits + */ + +#define TIMG_T0HI_REG(i) (REG_TIMG_BASE(i) + 0x8) + +/* TIMG_T0_HI : RO; bitpos: [21:0]; default: 0; + * After writing to TIMG_T0UPDATE_REG, the high 22 bits of the time-base + * counter + * of timer 0 can be read here. + */ + +#define TIMG_T0_HI 0x003fffff +#define TIMG_T0_HI_M (TIMG_T0_HI_V << TIMG_T0_HI_S) +#define TIMG_T0_HI_V 0x003fffff +#define TIMG_T0_HI_S 0 + +/* TIMG_T0UPDATE_REG register + * Write to copy current timer value to TIMGn_T0_(LO/HI)_REG + */ + +#define TIMG_T0UPDATE_REG(i) (REG_TIMG_BASE(i) + 0xc) + +/* TIMG_T0_UPDATE : R/W/SC; bitpos: [31]; default: 0; + * After writing 0 or 1 to TIMG_T0UPDATE_REG, the counter value is latched. + */ + +#define TIMG_T0_UPDATE (BIT(31)) +#define TIMG_T0_UPDATE_M (TIMG_T0_UPDATE_V << TIMG_T0_UPDATE_S) +#define TIMG_T0_UPDATE_V 0x00000001 +#define TIMG_T0_UPDATE_S 31 + +/* TIMG_T0ALARMLO_REG register + * Timer 0 alarm value, low 32 bits + */ + +#define TIMG_T0ALARMLO_REG(i) (REG_TIMG_BASE(i) + 0x10) + +/* TIMG_T0_ALARM_LO : R/W; bitpos: [31:0]; default: 0; + * Timer 0 alarm trigger time-base counter value, low 32 bits. + */ + +#define TIMG_T0_ALARM_LO 0xffffffff +#define TIMG_T0_ALARM_LO_M (TIMG_T0_ALARM_LO_V << TIMG_T0_ALARM_LO_S) +#define TIMG_T0_ALARM_LO_V 0xffffffff +#define TIMG_T0_ALARM_LO_S 0 + +/* TIMG_T0ALARMHI_REG register + * Timer 0 alarm value, high bits + */ + +#define TIMG_T0ALARMHI_REG(i) (REG_TIMG_BASE(i) + 0x14) + +/* TIMG_T0_ALARM_HI : R/W; bitpos: [21:0]; default: 0; + * Timer 0 alarm trigger time-base counter value, high 22 bits. + */ + +#define TIMG_T0_ALARM_HI 0x003fffff +#define TIMG_T0_ALARM_HI_M (TIMG_T0_ALARM_HI_V << TIMG_T0_ALARM_HI_S) +#define TIMG_T0_ALARM_HI_V 0x003fffff +#define TIMG_T0_ALARM_HI_S 0 + +/* TIMG_T0LOADLO_REG register + * Timer 0 reload value, low 32 bits + */ + +#define TIMG_T0LOADLO_REG(i) (REG_TIMG_BASE(i) + 0x18) + +/* TIMG_T0_LOAD_LO : R/W; bitpos: [31:0]; default: 0; + * Low 32 bits of the value that a reload will load onto timer 0 time-base + * Counter. + */ + +#define TIMG_T0_LOAD_LO 0xffffffff +#define TIMG_T0_LOAD_LO_M (TIMG_T0_LOAD_LO_V << TIMG_T0_LOAD_LO_S) +#define TIMG_T0_LOAD_LO_V 0xffffffff +#define TIMG_T0_LOAD_LO_S 0 + +/* TIMG_T0LOADHI_REG register + * Timer 0 reload value, high 22 bits + */ + +#define TIMG_T0LOADHI_REG(i) (REG_TIMG_BASE(i) + 0x1c) + +/* TIMG_T0_LOAD_HI : R/W; bitpos: [21:0]; default: 0; + * High 22 bits of the value that a reload will load onto timer 0 time-base + * counter. + */ + +#define TIMG_T0_LOAD_HI 0x003fffff +#define TIMG_T0_LOAD_HI_M (TIMG_T0_LOAD_HI_V << TIMG_T0_LOAD_HI_S) +#define TIMG_T0_LOAD_HI_V 0x003fffff +#define TIMG_T0_LOAD_HI_S 0 + +/* TIMG_T0LOAD_REG register + * Write to reload timer from TIMG_T0_(LOADLOLOADHI)_REG + */ + +#define TIMG_T0LOAD_REG(i) (REG_TIMG_BASE(i) + 0x20) + +/* TIMG_T0_LOAD : WT; bitpos: [31:0]; default: 0; + * + * Write any value to trigger a timer 0 time-base counter reload. + */ + +#define TIMG_T0_LOAD 0xffffffff +#define TIMG_T0_LOAD_M (TIMG_T0_LOAD_V << TIMG_T0_LOAD_S) +#define TIMG_T0_LOAD_V 0xffffffff +#define TIMG_T0_LOAD_S 0 + +/* TIMG_T1CONFIG_REG register + * Timer 1 configuration register + */ + +#define TIMG_T1CONFIG_REG(i) (REG_TIMG_BASE(i) + 0x24) + +/* TIMG_T1_EN : R/W; bitpos: [31]; default: 0; + * When set, the timer 1 time-base counter is enabled. + */ + +#define TIMG_T1_EN (BIT(31)) +#define TIMG_T1_EN_M (TIMG_T1_EN_V << TIMG_T1_EN_S) +#define TIMG_T1_EN_V 0x00000001 +#define TIMG_T1_EN_S 31 + +/* TIMG_T1_INCREASE : R/W; bitpos: [30]; default: 1; + * When set, the timer 1 time-base counter will increment every clock tick. + * When + * cleared, the timer 1 time-base counter will decrement. + */ + +#define TIMG_T1_INCREASE (BIT(30)) +#define TIMG_T1_INCREASE_M (TIMG_T1_INCREASE_V << TIMG_T1_INCREASE_S) +#define TIMG_T1_INCREASE_V 0x00000001 +#define TIMG_T1_INCREASE_S 30 + +/* TIMG_T1_AUTORELOAD : R/W; bitpos: [29]; default: 1; + * When set, timer 1 auto-reload at alarm is enabled. + */ + +#define TIMG_T1_AUTORELOAD (BIT(29)) +#define TIMG_T1_AUTORELOAD_M (TIMG_T1_AUTORELOAD_V << TIMG_T1_AUTORELOAD_S) +#define TIMG_T1_AUTORELOAD_V 0x00000001 +#define TIMG_T1_AUTORELOAD_S 29 + +/* TIMG_T1_DIVIDER : R/W; bitpos: [28:13]; default: 1; + * Timer 1 clock (T1_clk) prescaler value. + */ + +#define TIMG_T1_DIVIDER 0x0000ffff +#define TIMG_T1_DIVIDER_M (TIMG_T1_DIVIDER_V << TIMG_T1_DIVIDER_S) +#define TIMG_T1_DIVIDER_V 0x0000ffff +#define TIMG_T1_DIVIDER_S 13 + +/* TIMG_T1_ALARM_EN : R/W/SC; bitpos: [10]; default: 0; + * When set, the alarm is enabled. This bit is automatically cleared once an + * alarm occurs. + */ + +#define TIMG_T1_ALARM_EN (BIT(10)) +#define TIMG_T1_ALARM_EN_M (TIMG_T1_ALARM_EN_V << TIMG_T1_ALARM_EN_S) +#define TIMG_T1_ALARM_EN_V 0x00000001 +#define TIMG_T1_ALARM_EN_S 10 + +/* TIMG_T1_USE_XTAL : R/W; bitpos: [9]; default: 0; + * 1: Use XTAL_CLK as the source clock of timer group. 0: Use APB_CLK as the + * source clock of timer group. + */ + +#define TIMG_T1_USE_XTAL (BIT(9)) +#define TIMG_T1_USE_XTAL_M (TIMG_T1_USE_XTAL_V << TIMG_T1_USE_XTAL_S) +#define TIMG_T1_USE_XTAL_V 0x00000001 +#define TIMG_T1_USE_XTAL_S 9 + +/* TIMG_T1LO_REG register + * Timer 1 current value, low 32 bits + */ + +#define TIMG_T1LO_REG(i) (REG_TIMG_BASE(i) + 0x28) + +/* TIMG_T1_LO : RO; bitpos: [31:0]; default: 0; + * After writing to TIMG_T1UPDATE_REG, the low 32 bits of the time-base + * counter + * of timer 1 can be read here. + */ + +#define TIMG_T1_LO 0xffffffff +#define TIMG_T1_LO_M (TIMG_T1_LO_V << TIMG_T1_LO_S) +#define TIMG_T1_LO_V 0xffffffff +#define TIMG_T1_LO_S 0 + +/* TIMG_T1HI_REG register + * Timer 1 current value, high 22 bits + */ + +#define TIMG_T1HI_REG(i) (REG_TIMG_BASE(i) + 0x2c) + +/* TIMG_T1_HI : RO; bitpos: [21:0]; default: 0; + * After writing to TIMG_T1UPDATE_REG, the high 22 bits of the time-base + * counter + * of timer 1 can be read here. + */ + +#define TIMG_T1_HI 0x003fffff +#define TIMG_T1_HI_M (TIMG_T1_HI_V << TIMG_T1_HI_S) +#define TIMG_T1_HI_V 0x003fffff +#define TIMG_T1_HI_S 0 + +/* TIMG_T1UPDATE_REG register + * Write to copy current timer value to TIMGn_T1_(LO/HI)_REG + */ + +#define TIMG_T1UPDATE_REG(i) (REG_TIMG_BASE(i) + 0x30) + +/* TIMG_T1_UPDATE : R/W/SC; bitpos: [31]; default: 0; + * After writing 0 or 1 to TIMG_T1UPDATE_REG, the counter value is latched. + */ + +#define TIMG_T1_UPDATE (BIT(31)) +#define TIMG_T1_UPDATE_M (TIMG_T1_UPDATE_V << TIMG_T1_UPDATE_S) +#define TIMG_T1_UPDATE_V 0x00000001 +#define TIMG_T1_UPDATE_S 31 + +/* TIMG_T1ALARMLO_REG register + * Timer 1 alarm value, low 32 bits + */ + +#define TIMG_T1ALARMLO_REG(i) (REG_TIMG_BASE(i) + 0x34) + +/* TIMG_T1_ALARM_LO : R/W; bitpos: [31:0]; default: 0; + * Timer 1 alarm trigger time-base counter value, low 32 bits. + */ + +#define TIMG_T1_ALARM_LO 0xffffffff +#define TIMG_T1_ALARM_LO_M (TIMG_T1_ALARM_LO_V << TIMG_T1_ALARM_LO_S) +#define TIMG_T1_ALARM_LO_V 0xffffffff +#define TIMG_T1_ALARM_LO_S 0 + +/* TIMG_T1ALARMHI_REG register + * Timer 1 alarm value, high bits + */ + +#define TIMG_T1ALARMHI_REG(i) (REG_TIMG_BASE(i) + 0x38) + +/* TIMG_T1_ALARM_HI : R/W; bitpos: [21:0]; default: 0; + * Timer 1 alarm trigger time-base counter value, high 22 bits. + */ + +#define TIMG_T1_ALARM_HI 0x003fffff +#define TIMG_T1_ALARM_HI_M (TIMG_T1_ALARM_HI_V << TIMG_T1_ALARM_HI_S) +#define TIMG_T1_ALARM_HI_V 0x003fffff +#define TIMG_T1_ALARM_HI_S 0 + +/* TIMG_T1LOADLO_REG register + * Timer 1 reload value, low 32 bits + */ + +#define TIMG_T1LOADLO_REG(i) (REG_TIMG_BASE(i) + 0x3c) + +/* TIMG_T1_LOAD_LO : R/W; bitpos: [31:0]; default: 0; + * Low 32 bits of the value that a reload will load onto timer 1 time-base + * Counter. + */ + +#define TIMG_T1_LOAD_LO 0xffffffff +#define TIMG_T1_LOAD_LO_M (TIMG_T1_LOAD_LO_V << TIMG_T1_LOAD_LO_S) +#define TIMG_T1_LOAD_LO_V 0xffffffff +#define TIMG_T1_LOAD_LO_S 0 + +/* TIMG_T1LOADHI_REG register + * Timer 1 reload value, high 22 bits + */ + +#define TIMG_T1LOADHI_REG(i) (REG_TIMG_BASE(i) + 0x40) + +/* TIMG_T1_LOAD_HI : R/W; bitpos: [21:0]; default: 0; + * High 22 bits of the value that a reload will load onto timer 1 time-base + * counter. + */ + +#define TIMG_T1_LOAD_HI 0x003fffff +#define TIMG_T1_LOAD_HI_M (TIMG_T1_LOAD_HI_V << TIMG_T1_LOAD_HI_S) +#define TIMG_T1_LOAD_HI_V 0x003fffff +#define TIMG_T1_LOAD_HI_S 0 + +/* TIMG_T1LOAD_REG register + * Write to reload timer from TIMG_T1_(LOADLOLOADHI)_REG + */ + +#define TIMG_T1LOAD_REG(i) (REG_TIMG_BASE(i) + 0x44) + +/* TIMG_T1_LOAD : WT; bitpos: [31:0]; default: 0; + * + * Write any value to trigger a timer 1 time-base counter reload. + */ + +#define TIMG_T1_LOAD 0xffffffff +#define TIMG_T1_LOAD_M (TIMG_T1_LOAD_V << TIMG_T1_LOAD_S) +#define TIMG_T1_LOAD_V 0xffffffff +#define TIMG_T1_LOAD_S 0 + +/* TIMG_WDTCONFIG0_REG register + * Watchdog timer configuration register + */ + +#define TIMG_WDTCONFIG0_REG(i) (REG_TIMG_BASE(i) + 0x48) + +/* TIMG_WDT_EN : R/W; bitpos: [31]; default: 0; + * When set, MWDT is enabled. + */ + +#define TIMG_WDT_EN (BIT(31)) +#define TIMG_WDT_EN_M (TIMG_WDT_EN_V << TIMG_WDT_EN_S) +#define TIMG_WDT_EN_V 0x00000001 +#define TIMG_WDT_EN_S 31 + +/* TIMG_WDT_STG0 : R/W; bitpos: [30:29]; default: 0; + * Stage 0 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset + * system. + */ + +#define TIMG_WDT_STG0 0x00000003 +#define TIMG_WDT_STG0_M (TIMG_WDT_STG0_V << TIMG_WDT_STG0_S) +#define TIMG_WDT_STG0_V 0x00000003 +#define TIMG_WDT_STG0_S 29 + +/* TIMG_WDT_STG1 : R/W; bitpos: [28:27]; default: 0; + * Stage 1 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset + * system. + */ + +#define TIMG_WDT_STG1 0x00000003 +#define TIMG_WDT_STG1_M (TIMG_WDT_STG1_V << TIMG_WDT_STG1_S) +#define TIMG_WDT_STG1_V 0x00000003 +#define TIMG_WDT_STG1_S 27 + +/* TIMG_WDT_STG2 : R/W; bitpos: [26:25]; default: 0; + * Stage 2 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset + * system. + */ + +#define TIMG_WDT_STG2 0x00000003 +#define TIMG_WDT_STG2_M (TIMG_WDT_STG2_V << TIMG_WDT_STG2_S) +#define TIMG_WDT_STG2_V 0x00000003 +#define TIMG_WDT_STG2_S 25 + +/* TIMG_WDT_STG3 : R/W; bitpos: [24:23]; default: 0; + * Stage 3 configuration. 0: off, 1: interrupt, 2: reset CPU, 3: reset + * system. + */ + +#define TIMG_WDT_STG3 0x00000003 +#define TIMG_WDT_STG3_M (TIMG_WDT_STG3_V << TIMG_WDT_STG3_S) +#define TIMG_WDT_STG3_V 0x00000003 +#define TIMG_WDT_STG3_S 23 + +/* TIMG_WDT_CPU_RESET_LENGTH : R/W; bitpos: [20:18]; default: 1; + * CPU reset signal length selection. 0: 100 ns, 1: 200 ns, + * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. + */ + +#define TIMG_WDT_CPU_RESET_LENGTH 0x00000007 +#define TIMG_WDT_CPU_RESET_LENGTH_M (TIMG_WDT_CPU_RESET_LENGTH_V << TIMG_WDT_CPU_RESET_LENGTH_S) +#define TIMG_WDT_CPU_RESET_LENGTH_V 0x00000007 +#define TIMG_WDT_CPU_RESET_LENGTH_S 18 + +/* TIMG_WDT_SYS_RESET_LENGTH : R/W; bitpos: [17:15]; default: 1; + * System reset signal length selection. 0: 100 ns, 1: 200 ns, + * 2: 300 ns, 3: 400 ns, 4: 500 ns, 5: 800 ns, 6: 1.6 us, 7: 3.2 us. + */ + +#define TIMG_WDT_SYS_RESET_LENGTH 0x00000007 +#define TIMG_WDT_SYS_RESET_LENGTH_M (TIMG_WDT_SYS_RESET_LENGTH_V << TIMG_WDT_SYS_RESET_LENGTH_S) +#define TIMG_WDT_SYS_RESET_LENGTH_V 0x00000007 +#define TIMG_WDT_SYS_RESET_LENGTH_S 15 + +/* TIMG_WDT_FLASHBOOT_MOD_EN : R/W; bitpos: [14]; default: 1; + * When set, Flash boot protection is enabled. + */ + +#define TIMG_WDT_FLASHBOOT_MOD_EN (BIT(14)) +#define TIMG_WDT_FLASHBOOT_MOD_EN_M (TIMG_WDT_FLASHBOOT_MOD_EN_V << TIMG_WDT_FLASHBOOT_MOD_EN_S) +#define TIMG_WDT_FLASHBOOT_MOD_EN_V 0x00000001 +#define TIMG_WDT_FLASHBOOT_MOD_EN_S 14 + +/* TIMG_WDT_PROCPU_RESET_EN : R/W; bitpos: [13]; default: 0; + * WDT reset CPU enable. + */ + +#define TIMG_WDT_PROCPU_RESET_EN (BIT(13)) +#define TIMG_WDT_PROCPU_RESET_EN_M (TIMG_WDT_PROCPU_RESET_EN_V << TIMG_WDT_PROCPU_RESET_EN_S) +#define TIMG_WDT_PROCPU_RESET_EN_V 0x00000001 +#define TIMG_WDT_PROCPU_RESET_EN_S 13 + +/* TIMG_WDT_APPCPU_RESET_EN : R/W; bitpos: [12]; default: 0; + * Reserved + */ + +#define TIMG_WDT_APPCPU_RESET_EN (BIT(12)) +#define TIMG_WDT_APPCPU_RESET_EN_M (TIMG_WDT_APPCPU_RESET_EN_V << TIMG_WDT_APPCPU_RESET_EN_S) +#define TIMG_WDT_APPCPU_RESET_EN_V 0x00000001 +#define TIMG_WDT_APPCPU_RESET_EN_S 12 + +/* TIMG_WDTCONFIG1_REG register + * Watchdog timer prescaler register + */ + +#define TIMG_WDTCONFIG1_REG(i) (REG_TIMG_BASE(i) + 0x4c) + +/* TIMG_WDT_CLK_PRESCALE : R/W; bitpos: [31:16]; default: 1; + * MWDT clock prescaler value. MWDT clock period = 12.5 ns * + * TIMG_WDT_CLK_PRESCALE. + */ + +#define TIMG_WDT_CLK_PRESCALE 0x0000ffff +#define TIMG_WDT_CLK_PRESCALE_M (TIMG_WDT_CLK_PRESCALE_V << TIMG_WDT_CLK_PRESCALE_S) +#define TIMG_WDT_CLK_PRESCALE_V 0x0000ffff +#define TIMG_WDT_CLK_PRESCALE_S 16 + +/* TIMG_WDTCONFIG2_REG register + * Watchdog timer stage 0 timeout value + */ + +#define TIMG_WDTCONFIG2_REG(i) (REG_TIMG_BASE(i) + 0x50) + +/* TIMG_WDT_STG0_HOLD : R/W; bitpos: [31:0]; default: 26000000; + * Stage 0 timeout value, in MWDT clock cycles. + */ + +#define TIMG_WDT_STG0_HOLD 0xffffffff +#define TIMG_WDT_STG0_HOLD_M (TIMG_WDT_STG0_HOLD_V << TIMG_WDT_STG0_HOLD_S) +#define TIMG_WDT_STG0_HOLD_V 0xffffffff +#define TIMG_WDT_STG0_HOLD_S 0 + +/* TIMG_WDTCONFIG3_REG register + * Watchdog timer stage 1 timeout value + */ + +#define TIMG_WDTCONFIG3_REG(i) (REG_TIMG_BASE(i) + 0x54) + +/* TIMG_WDT_STG1_HOLD : R/W; bitpos: [31:0]; default: 134217727; + * Stage 1 timeout value, in MWDT clock cycles. + */ + +#define TIMG_WDT_STG1_HOLD 0xffffffff +#define TIMG_WDT_STG1_HOLD_M (TIMG_WDT_STG1_HOLD_V << TIMG_WDT_STG1_HOLD_S) +#define TIMG_WDT_STG1_HOLD_V 0xffffffff +#define TIMG_WDT_STG1_HOLD_S 0 + +/* TIMG_WDTCONFIG4_REG register + * Watchdog timer stage 2 timeout value + */ + +#define TIMG_WDTCONFIG4_REG(i) (REG_TIMG_BASE(i) + 0x58) + +/* TIMG_WDT_STG2_HOLD : R/W; bitpos: [31:0]; default: 1048575; + * Stage 2 timeout value, in MWDT clock cycles. + */ + +#define TIMG_WDT_STG2_HOLD 0xffffffff +#define TIMG_WDT_STG2_HOLD_M (TIMG_WDT_STG2_HOLD_V << TIMG_WDT_STG2_HOLD_S) +#define TIMG_WDT_STG2_HOLD_V 0xffffffff +#define TIMG_WDT_STG2_HOLD_S 0 + +/* TIMG_WDTCONFIG5_REG register + * Watchdog timer stage 3 timeout value + */ + +#define TIMG_WDTCONFIG5_REG(i) (REG_TIMG_BASE(i) + 0x5c) + +/* TIMG_WDT_STG3_HOLD : R/W; bitpos: [31:0]; default: 1048575; + * Stage 3 timeout value, in MWDT clock cycles. + */ + +#define TIMG_WDT_STG3_HOLD 0xffffffff +#define TIMG_WDT_STG3_HOLD_M (TIMG_WDT_STG3_HOLD_V << TIMG_WDT_STG3_HOLD_S) +#define TIMG_WDT_STG3_HOLD_V 0xffffffff +#define TIMG_WDT_STG3_HOLD_S 0 + +/* TIMG_WDTFEED_REG register + * Write to feed the watchdog timer + */ + +#define TIMG_WDTFEED_REG(i) (REG_TIMG_BASE(i) + 0x60) + +/* TIMG_WDT_FEED : WT; bitpos: [31:0]; default: 0; + * Write any value to feed the MWDT. (WO) + */ + +#define TIMG_WDT_FEED 0xffffffff +#define TIMG_WDT_FEED_M (TIMG_WDT_FEED_V << TIMG_WDT_FEED_S) +#define TIMG_WDT_FEED_V 0xffffffff +#define TIMG_WDT_FEED_S 0 + +/* TIMG_WDTWPROTECT_REG register + * Watchdog write protect register + */ + +#define TIMG_WDTWPROTECT_REG(i) (REG_TIMG_BASE(i) + 0x64) + +/* TIMG_WDT_WKEY : R/W; bitpos: [31:0]; default: 1356348065; + * If the register contains a different value than its reset value, write + * protection is enabled. + */ + +#define TIMG_WDT_WKEY 0xffffffff +#define TIMG_WDT_WKEY_M (TIMG_WDT_WKEY_V << TIMG_WDT_WKEY_S) +#define TIMG_WDT_WKEY_V 0xffffffff +#define TIMG_WDT_WKEY_S 0 + +/* TIMG_RTCCALICFG_REG register + * RTC calibration configure register + */ + +#define TIMG_RTCCALICFG_REG(i) (REG_TIMG_BASE(i) + 0x68) + +/* TIMG_RTC_CALI_START : R/W; bitpos: [31]; default: 0; + * Reserved + */ + +#define TIMG_RTC_CALI_START (BIT(31)) +#define TIMG_RTC_CALI_START_M (TIMG_RTC_CALI_START_V << TIMG_RTC_CALI_START_S) +#define TIMG_RTC_CALI_START_V 0x00000001 +#define TIMG_RTC_CALI_START_S 31 + +/* TIMG_RTC_CALI_MAX : R/W; bitpos: [30:16]; default: 1; + * Reserved + */ + +#define TIMG_RTC_CALI_MAX 0x00007fff +#define TIMG_RTC_CALI_MAX_M (TIMG_RTC_CALI_MAX_V << TIMG_RTC_CALI_MAX_S) +#define TIMG_RTC_CALI_MAX_V 0x00007fff +#define TIMG_RTC_CALI_MAX_S 16 + +/* TIMG_RTC_CALI_RDY : RO; bitpos: [15]; default: 0; + * Reserved + */ + +#define TIMG_RTC_CALI_RDY (BIT(15)) +#define TIMG_RTC_CALI_RDY_M (TIMG_RTC_CALI_RDY_V << TIMG_RTC_CALI_RDY_S) +#define TIMG_RTC_CALI_RDY_V 0x00000001 +#define TIMG_RTC_CALI_RDY_S 15 + +/* TIMG_RTC_CALI_CLK_SEL : R/W; bitpos: [14:13]; default: 1; + * 0:rtc slow clock. 1:clk_80m. 2:xtal_32k. + */ + +#define TIMG_RTC_CALI_CLK_SEL 0x00000003 +#define TIMG_RTC_CALI_CLK_SEL_M (TIMG_RTC_CALI_CLK_SEL_V << TIMG_RTC_CALI_CLK_SEL_S) +#define TIMG_RTC_CALI_CLK_SEL_V 0x00000003 +#define TIMG_RTC_CALI_CLK_SEL_S 13 + +/* TIMG_RTC_CALI_START_CYCLING : R/W; bitpos: [12]; default: 1; + * Reserved + */ + +#define TIMG_RTC_CALI_START_CYCLING (BIT(12)) +#define TIMG_RTC_CALI_START_CYCLING_M (TIMG_RTC_CALI_START_CYCLING_V << TIMG_RTC_CALI_START_CYCLING_S) +#define TIMG_RTC_CALI_START_CYCLING_V 0x00000001 +#define TIMG_RTC_CALI_START_CYCLING_S 12 + +/* TIMG_RTCCALICFG1_REG register + * RTC calibration configure1 register + */ + +#define TIMG_RTCCALICFG1_REG(i) (REG_TIMG_BASE(i) + 0x6c) + +/* TIMG_RTC_CALI_VALUE : RO; bitpos: [31:7]; default: 0; + * Reserved + */ + +#define TIMG_RTC_CALI_VALUE 0x01ffffff +#define TIMG_RTC_CALI_VALUE_M (TIMG_RTC_CALI_VALUE_V << TIMG_RTC_CALI_VALUE_S) +#define TIMG_RTC_CALI_VALUE_V 0x01ffffff +#define TIMG_RTC_CALI_VALUE_S 7 + +/* TIMG_RTC_CALI_CYCLING_DATA_VLD : RO; bitpos: [0]; default: 0; + * Reserved + */ + +#define TIMG_RTC_CALI_CYCLING_DATA_VLD (BIT(0)) +#define TIMG_RTC_CALI_CYCLING_DATA_VLD_M (TIMG_RTC_CALI_CYCLING_DATA_VLD_V << TIMG_RTC_CALI_CYCLING_DATA_VLD_S) +#define TIMG_RTC_CALI_CYCLING_DATA_VLD_V 0x00000001 +#define TIMG_RTC_CALI_CYCLING_DATA_VLD_S 0 + +/* TIMG_INT_ENA_TIMERS_REG register + * Interrupt enable bits + */ + +#define TIMG_INT_ENA_TIMERS_REG(i) (REG_TIMG_BASE(i) + 0x70) + +/* TIMG_WDT_INT_ENA : R/W; bitpos: [2]; default: 0; + * The interrupt enable bit for the TIMG_WDT_INT interrupt. + */ + +#define TIMG_WDT_INT_ENA (BIT(2)) +#define TIMG_WDT_INT_ENA_M (TIMG_WDT_INT_ENA_V << TIMG_WDT_INT_ENA_S) +#define TIMG_WDT_INT_ENA_V 0x00000001 +#define TIMG_WDT_INT_ENA_S 2 + +/* TIMG_T1_INT_ENA : R/W; bitpos: [1]; default: 0; + * The interrupt enable bit for the TIMG_T$x_INT interrupt. + */ + +#define TIMG_T1_INT_ENA (BIT(1)) +#define TIMG_T1_INT_ENA_M (TIMG_T1_INT_ENA_V << TIMG_T1_INT_ENA_S) +#define TIMG_T1_INT_ENA_V 0x00000001 +#define TIMG_T1_INT_ENA_S 1 + +/* TIMG_T0_INT_ENA : R/W; bitpos: [0]; default: 0; + * The interrupt enable bit for the TIMG_T$x_INT interrupt. + */ + +#define TIMG_T0_INT_ENA (BIT(0)) +#define TIMG_T0_INT_ENA_M (TIMG_T0_INT_ENA_V << TIMG_T0_INT_ENA_S) +#define TIMG_T0_INT_ENA_V 0x00000001 +#define TIMG_T0_INT_ENA_S 0 + +/* TIMG_INT_RAW_TIMERS_REG register + * Raw interrupt status + */ + +#define TIMG_INT_RAW_TIMERS_REG(i) (REG_TIMG_BASE(i) + 0x74) + +/* TIMG_WDT_INT_RAW : R/WTC/SS; bitpos: [2]; default: 0; + * The raw interrupt status bit for the TIMG_WDT_INT interrupt. + */ + +#define TIMG_WDT_INT_RAW (BIT(2)) +#define TIMG_WDT_INT_RAW_M (TIMG_WDT_INT_RAW_V << TIMG_WDT_INT_RAW_S) +#define TIMG_WDT_INT_RAW_V 0x00000001 +#define TIMG_WDT_INT_RAW_S 2 + +/* TIMG_T1_INT_RAW : R/WTC/SS; bitpos: [1]; default: 0; + * The raw interrupt status bit for the TIMG_T$x_INT interrupt. + */ + +#define TIMG_T1_INT_RAW (BIT(1)) +#define TIMG_T1_INT_RAW_M (TIMG_T1_INT_RAW_V << TIMG_T1_INT_RAW_S) +#define TIMG_T1_INT_RAW_V 0x00000001 +#define TIMG_T1_INT_RAW_S 1 + +/* TIMG_T0_INT_RAW : R/WTC/SS; bitpos: [0]; default: 0; + * The raw interrupt status bit for the TIMG_T$x_INT interrupt. + */ + +#define TIMG_T0_INT_RAW (BIT(0)) +#define TIMG_T0_INT_RAW_M (TIMG_T0_INT_RAW_V << TIMG_T0_INT_RAW_S) +#define TIMG_T0_INT_RAW_V 0x00000001 +#define TIMG_T0_INT_RAW_S 0 + +/* TIMG_INT_ST_TIMERS_REG register + * Masked interrupt status + */ + +#define TIMG_INT_ST_TIMERS_REG(i) (REG_TIMG_BASE(i) + 0x78) + +/* TIMG_WDT_INT_ST : RO; bitpos: [2]; default: 0; + * The masked interrupt status bit for the TIMG_WDT_INT interrupt. + */ + +#define TIMG_WDT_INT_ST (BIT(2)) +#define TIMG_WDT_INT_ST_M (TIMG_WDT_INT_ST_V << TIMG_WDT_INT_ST_S) +#define TIMG_WDT_INT_ST_V 0x00000001 +#define TIMG_WDT_INT_ST_S 2 + +/* TIMG_T1_INT_ST : RO; bitpos: [1]; default: 0; + * The masked interrupt status bit for the TIMG_T$x_INT interrupt. + */ + +#define TIMG_T1_INT_ST (BIT(1)) +#define TIMG_T1_INT_ST_M (TIMG_T1_INT_ST_V << TIMG_T1_INT_ST_S) +#define TIMG_T1_INT_ST_V 0x00000001 +#define TIMG_T1_INT_ST_S 1 + +/* TIMG_T0_INT_ST : RO; bitpos: [0]; default: 0; + * The masked interrupt status bit for the TIMG_T$x_INT interrupt. + */ + +#define TIMG_T0_INT_ST (BIT(0)) +#define TIMG_T0_INT_ST_M (TIMG_T0_INT_ST_V << TIMG_T0_INT_ST_S) +#define TIMG_T0_INT_ST_V 0x00000001 +#define TIMG_T0_INT_ST_S 0 + +/* TIMG_INT_CLR_TIMERS_REG register + * Interrupt clear bits + */ + +#define TIMG_INT_CLR_TIMERS_REG(i) (REG_TIMG_BASE(i) + 0x7c) + +/* TIMG_WDT_INT_CLR : WT; bitpos: [2]; default: 0; + * Set this bit to clear the TIMG_WDT_INT interrupt. + */ + +#define TIMG_WDT_INT_CLR (BIT(2)) +#define TIMG_WDT_INT_CLR_M (TIMG_WDT_INT_CLR_V << TIMG_WDT_INT_CLR_S) +#define TIMG_WDT_INT_CLR_V 0x00000001 +#define TIMG_WDT_INT_CLR_S 2 + +/* TIMG_T1_INT_CLR : WT; bitpos: [1]; default: 0; + * Set this bit to clear the TIMG_T$x_INT interrupt. + */ + +#define TIMG_T1_INT_CLR (BIT(1)) +#define TIMG_T1_INT_CLR_M (TIMG_T1_INT_CLR_V << TIMG_T1_INT_CLR_S) +#define TIMG_T1_INT_CLR_V 0x00000001 +#define TIMG_T1_INT_CLR_S 1 + +/* TIMG_T0_INT_CLR : WT; bitpos: [0]; default: 0; + * Set this bit to clear the TIMG_T$x_INT interrupt. + */ + +#define TIMG_T0_INT_CLR (BIT(0)) +#define TIMG_T0_INT_CLR_M (TIMG_T0_INT_CLR_V << TIMG_T0_INT_CLR_S) +#define TIMG_T0_INT_CLR_V 0x00000001 +#define TIMG_T0_INT_CLR_S 0 + +/* TIMG_RTCCALICFG2_REG register + * Timer group calibration register + */ + +#define TIMG_RTCCALICFG2_REG(i) (REG_TIMG_BASE(i) + 0x80) + +/* TIMG_RTC_CALI_TIMEOUT_THRES : R/W; bitpos: [31:7]; default: 33554431; + * Threshold value for the RTC calibration timer. If the calibration timer's + * value exceeds this threshold, a timeout is triggered. + */ + +#define TIMG_RTC_CALI_TIMEOUT_THRES 0x01ffffff +#define TIMG_RTC_CALI_TIMEOUT_THRES_M (TIMG_RTC_CALI_TIMEOUT_THRES_V << TIMG_RTC_CALI_TIMEOUT_THRES_S) +#define TIMG_RTC_CALI_TIMEOUT_THRES_V 0x01ffffff +#define TIMG_RTC_CALI_TIMEOUT_THRES_S 7 + +/* TIMG_RTC_CALI_TIMEOUT_RST_CNT : R/W; bitpos: [6:3]; default: 3; + * Cycles that release calibration timeout reset + */ + +#define TIMG_RTC_CALI_TIMEOUT_RST_CNT 0x0000000f +#define TIMG_RTC_CALI_TIMEOUT_RST_CNT_M (TIMG_RTC_CALI_TIMEOUT_RST_CNT_V << TIMG_RTC_CALI_TIMEOUT_RST_CNT_S) +#define TIMG_RTC_CALI_TIMEOUT_RST_CNT_V 0x0000000f +#define TIMG_RTC_CALI_TIMEOUT_RST_CNT_S 3 + +/* TIMG_RTC_CALI_TIMEOUT : RO; bitpos: [0]; default: 0; + * RTC calibration timeout indicator + */ + +#define TIMG_RTC_CALI_TIMEOUT (BIT(0)) +#define TIMG_RTC_CALI_TIMEOUT_M (TIMG_RTC_CALI_TIMEOUT_V << TIMG_RTC_CALI_TIMEOUT_S) +#define TIMG_RTC_CALI_TIMEOUT_V 0x00000001 +#define TIMG_RTC_CALI_TIMEOUT_S 0 + +/* TIMG_NTIMERS_DATE_REG register + * Timer version control register + */ + +#define TIMG_NTIMERS_DATE_REG(i) (REG_TIMG_BASE(i) + 0xf8) + +/* TIMG_NTIMERS_DATE : R/W; bitpos: [27:0]; default: 33566833; + * Timer version control register + */ + +#define TIMG_NTIMERS_DATE 0x0fffffff +#define TIMG_NTIMERS_DATE_M (TIMG_NTIMERS_DATE_V << TIMG_NTIMERS_DATE_S) +#define TIMG_NTIMERS_DATE_V 0x0fffffff +#define TIMG_NTIMERS_DATE_S 0 + +/* TIMG_REGCLK_REG register + * Timer group clock gate register + */ + +#define TIMG_REGCLK_REG(i) (REG_TIMG_BASE(i) + 0xfc) + +/* TIMG_CLK_EN : R/W; bitpos: [31]; default: 0; + * Register clock gate signal. 1: The clock for software to read and write + * registers is always on. 0: The clock for software to read and write + * registers only exits when the operation happens. + */ + +#define TIMG_CLK_EN (BIT(31)) +#define TIMG_CLK_EN_M (TIMG_CLK_EN_V << TIMG_CLK_EN_S) +#define TIMG_CLK_EN_V 0x00000001 +#define TIMG_CLK_EN_S 31 + +#endif /* __ARCH_XTENSA_SRC_ESP32S3_HARDWARE_ESP32S3_TIM_H */