You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2021/05/12 13:15:13 UTC
[incubator-nuttx] branch master updated: risc-v/esp32c3: Support
ESP32-C3 PM standby and sleep
This is an automated email from the ASF dual-hosted git repository.
acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 1666793 risc-v/esp32c3: Support ESP32-C3 PM standby and sleep
1666793 is described below
commit 16667930cba1265dee2e7a5ef7cf92cc6d954d21
Author: chenwen <ch...@espressif.com>
AuthorDate: Wed Apr 28 18:40:56 2021 +0800
risc-v/esp32c3: Support ESP32-C3 PM standby and sleep
---
arch/risc-v/src/esp32c3/Make.defs | 9 +
arch/risc-v/src/esp32c3/esp32c3_idle.c | 129 +-
arch/risc-v/src/esp32c3/esp32c3_pm.c | 1266 ++++++++++++
arch/risc-v/src/esp32c3/esp32c3_pm.h | 155 ++
.../{esp32c3_idle.c => esp32c3_pminitialize.c} | 42 +-
arch/risc-v/src/esp32c3/esp32c3_rtc.c | 2099 ++++++++++++++++++++
arch/risc-v/src/esp32c3/esp32c3_rtc.h | 437 ++++
arch/risc-v/src/esp32c3/hardware/apb_ctrl_reg.h | 73 +
arch/risc-v/src/esp32c3/hardware/bb_reg.h | 49 +
arch/risc-v/src/esp32c3/hardware/esp32c3_soc.h | 38 +
arch/risc-v/src/esp32c3/hardware/esp32c3_uart.h | 21 +
arch/risc-v/src/esp32c3/hardware/extmem_reg.h | 57 +
arch/risc-v/src/esp32c3/hardware/fe_reg.h | 50 +
arch/risc-v/src/esp32c3/hardware/nrx_reg.h | 52 +
arch/risc-v/src/esp32c3/hardware/regi2c_bbpll.h | 75 +
arch/risc-v/src/esp32c3/hardware/regi2c_ctrl.h | 69 +
arch/risc-v/src/esp32c3/hardware/regi2c_dig_reg.h | 59 +
arch/risc-v/src/esp32c3/hardware/regi2c_lp_bias.h | 40 +
arch/risc-v/src/esp32c3/hardware/spi_mem_reg.h | 46 +
boards/risc-v/esp32c3/esp32c3-devkit/Kconfig | 32 +
.../esp32c3/esp32c3-devkit/configs/pm/defconfig | 47 +
.../esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld | 4 +-
22 files changed, 4816 insertions(+), 33 deletions(-)
diff --git a/arch/risc-v/src/esp32c3/Make.defs b/arch/risc-v/src/esp32c3/Make.defs
index 369dceb..a65498b 100644
--- a/arch/risc-v/src/esp32c3/Make.defs
+++ b/arch/risc-v/src/esp32c3/Make.defs
@@ -112,6 +112,15 @@ ifeq ($(CONFIG_ESP32C3_DMA),y)
CHIP_CSRCS += esp32c3_dma.c
endif
+ifeq ($(CONFIG_PM),y)
+ifneq ($(CONFIG_ARCH_CUSTOM_PMINIT),y)
+CHIP_CSRCS += esp32c3_pminitialize.c
+endif
+CHIP_CSRCS += esp32c3_pm.c
+endif
+
+CHIP_CSRCS += esp32c3_rtc.c
+
ifeq ($(CONFIG_ESP32C3_WIRELESS),y)
WIRELESS_DRV_UNPACK = esp-wireless-drivers-3rdparty
WIRELESS_DRV_ID = 2b53111
diff --git a/arch/risc-v/src/esp32c3/esp32c3_idle.c b/arch/risc-v/src/esp32c3/esp32c3_idle.c
index 079bfd4..2807612 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_idle.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_idle.c
@@ -28,19 +28,142 @@
#include <nuttx/power/pm.h>
#include "esp32c3.h"
+#include "esp32c3_pm.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
+/* Values for the RTC Alarm to wake up from the PM_STANDBY mode
+ * (which corresponds to ESP32-C3 stop mode). If this alarm expires,
+ * the logic in this file will wakeup from PM_STANDBY mode and
+ * transition to PM_SLEEP mode (ESP32-C3 standby mode).
+ */
+
+#ifdef CONFIG_PM
+#ifndef CONFIG_PM_ALARM_SEC
+# define CONFIG_PM_ALARM_SEC 15
+#endif
+
+#ifndef CONFIG_PM_ALARM_NSEC
+# define CONFIG_PM_ALARM_NSEC 0
+#endif
+
+#ifndef CONFIG_PM_SLEEP_WAKEUP_SEC
+# define CONFIG_PM_SLEEP_WAKEUP_SEC 20
+#endif
+
+#ifndef CONFIG_PM_SLEEP_WAKEUP_NSEC
+# define CONFIG_PM_SLEEP_WAKEUP_NSEC 0
+#endif
+
+#define PM_IDLE_DOMAIN 0 /* Revisit */
+#endif
+
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
- * Public Functions
+ * Name: up_idlepm
+ *
+ * Description:
+ * Perform IDLE state power management.
+ *
****************************************************************************/
+#ifdef CONFIG_PM
+static void up_idlepm(void)
+{
+ static enum pm_state_e oldstate = PM_NORMAL;
+ enum pm_state_e newstate;
+ irqstate_t flags;
+ int ret;
+
+ /* Decide, which power saving level can be obtained */
+
+ newstate = pm_checkstate(PM_IDLE_DOMAIN);
+
+ /* Check for state changes */
+
+ if (newstate != oldstate)
+ {
+ flags = spin_lock_irqsave(NULL);
+
+ /* Perform board-specific, state-dependent logic here */
+
+ _info("newstate= %d oldstate=%d\n", newstate, oldstate);
+
+ /* Then force the global state change */
+
+ ret = pm_changestate(PM_IDLE_DOMAIN, newstate);
+ if (ret < 0)
+ {
+ /* The new state change failed, revert to the preceding state */
+
+ pm_changestate(PM_IDLE_DOMAIN, oldstate);
+ }
+ else
+ {
+ /* Save the new state */
+
+ oldstate = newstate;
+ }
+
+ spin_unlock_irqrestore(NULL, flags);
+
+ /* MCU-specific power management logic */
+
+ switch (newstate)
+ {
+ case PM_NORMAL:
+ break;
+
+ case PM_IDLE:
+ break;
+
+ case PM_STANDBY:
+ {
+ /* Enter Force-sleep mode */
+
+ esp32c3_pmstandby(CONFIG_PM_ALARM_SEC * 1000000 +
+ CONFIG_PM_ALARM_NSEC / 1000);
+ }
+ break;
+
+ case PM_SLEEP:
+ {
+ /* Enter Deep-sleep mode */
+
+ esp32c3_pmsleep(CONFIG_PM_SLEEP_WAKEUP_SEC * 1000000 +
+ CONFIG_PM_SLEEP_WAKEUP_NSEC / 1000);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ if (oldstate == PM_NORMAL)
+ {
+ /* Relax normal operation */
+
+ pm_relax(PM_IDLE_DOMAIN, PM_NORMAL);
+ }
+
+#ifdef CONFIG_WATCHDOG
+ /* Announce the power management state change to feed watchdog */
+
+ pm_changestate(PM_IDLE_DOMAIN, PM_NORMAL);
+#endif
+ }
+}
+#else
+# define up_idlepm()
+#endif
+
/****************************************************************************
* Name: up_idle
*
@@ -69,5 +192,9 @@ void up_idle(void)
asm("WFI");
+ /* Perform IDLE mode power management */
+
+ up_idlepm();
+
#endif
}
diff --git a/arch/risc-v/src/esp32c3/esp32c3_pm.c b/arch/risc-v/src/esp32c3/esp32c3_pm.c
new file mode 100644
index 0000000..e1957d7
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_pm.c
@@ -0,0 +1,1266 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_pm.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 <nuttx/config.h>
+#include <nuttx/arch.h>
+#include <nuttx/irq.h>
+
+#ifdef CONFIG_PM
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include "chip.h"
+#include "riscv_arch.h"
+
+#include "hardware/esp32c3_rtccntl.h"
+#include "hardware/esp32c3_system.h"
+#include "hardware/esp32c3_syscon.h"
+#include "hardware/esp32c3_soc.h"
+#include "hardware/esp32c3_uart.h"
+#include "hardware/esp32c3_gpio.h"
+
+#include "esp32c3_attr.h"
+#include "esp32c3_rtc.h"
+#include "esp32c3_clockconfig.h"
+#include "esp32c3_pm.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* If light sleep time is less than that, don't power down flash */
+
+#define FLASH_PD_MIN_SLEEP_TIME_US 2000
+
+/* Minimal amount of time we can sleep for. */
+
+#define LIGHT_SLEEP_MIN_TIME_US 200
+
+#define RTC_MODULE_SLEEP_PREPARE_CYCLES (6)
+
+#ifndef MAX
+#define MAX(a,b) a > b ? a : b
+#endif
+
+/* Time from VDD_SDIO power up to first flash read in ROM code */
+
+#define VDD_SDIO_POWERUP_TO_FLASH_READ_US (700)
+
+/* Extra time it takes to enter and exit light sleep and deep sleep */
+
+#define LIGHT_SLEEP_TIME_OVERHEAD_US (37)
+
+#ifdef CONFIG_ESP32C3_CPU_FREQ_MHZ
+#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32C3_CPU_FREQ_MHZ
+#else
+#define DEFAULT_CPU_FREQ_MHZ (160)
+#endif
+
+#define DEFAULT_SLEEP_OUT_OVERHEAD_US (105)
+#define DEEP_SLEEP_TIME_OVERHEAD_US (250 + 100 * 240 / DEFAULT_CPU_FREQ_MHZ)
+
+#define DEEP_SLEEP_WAKEUP_DELAY 0
+
+#define RTC_VDDSDIO_TIEH_1_8V 0 /* TIEH field value for 1.8V VDDSDIO */
+#define RTC_VDDSDIO_TIEH_3_3V 1 /* TIEH field value for 3.3V VDDSDIO */
+
+#define RTC_GPIO_TRIG_EN BIT(2) /* GPIO wakeup */
+#define RTC_TIMER_TRIG_EN BIT(3) /* Timer wakeup */
+#define RTC_WIFI_TRIG_EN BIT(5) /* Wi-Fi wakeup (light sleep only) */
+#define RTC_UART0_TRIG_EN BIT(6) /* UART0 wakeup (light sleep only) */
+#define RTC_UART1_TRIG_EN BIT(7) /* UART1 wakeup (light sleep only) */
+#define RTC_BT_TRIG_EN BIT(10) /* BT wakeup (light sleep only) */
+#define RTC_XTAL32K_DEAD_TRIG_EN BIT(12)
+#define RTC_USB_TRIG_EN BIT(14)
+#define RTC_BROWNOUT_DET_TRIG_EN BIT(16)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* Power down options */
+
+enum esp32c3_sleep_pd_option_e
+{
+ /* Power down the power domain in sleep mode */
+
+ ESP_PD_OPTION_OFF,
+
+ /* Keep power domain enabled during sleep mode */
+
+ ESP_PD_OPTION_ON,
+
+ /* Keep power domain enabled in sleep mode if it is needed
+ * by one of the wakeup options, otherwise power it down.
+ */
+
+ ESP_PD_OPTION_AUTO
+};
+
+/* Power domains which can be powered down in sleep mode. */
+
+enum esp32c3_sleep_pd_domain_e
+{
+ ESP_PD_DOMAIN_RTC_PERIPH = 0, /* RTC IO, sensors */
+ ESP_PD_DOMAIN_RTC_SLOW_MEM, /* RTC slow memory */
+ ESP_PD_DOMAIN_RTC_FAST_MEM, /* RTC fast memory */
+ ESP_PD_DOMAIN_XTAL, /* XTAL oscillator */
+ ESP_PD_DOMAIN_CPU, /* CPU core */
+ ESP_PD_DOMAIN_MAX /* Number of domains */
+};
+
+enum esp32c3_periph_module_e
+{
+ PERIPH_LEDC_MODULE = 0,
+ PERIPH_UART0_MODULE,
+ PERIPH_UART1_MODULE,
+ PERIPH_USB_DEVICE_MODULE,
+ PERIPH_I2C0_MODULE,
+ PERIPH_I2S1_MODULE,
+ PERIPH_TIMG0_MODULE,
+ PERIPH_TIMG1_MODULE,
+ PERIPH_UHCI0_MODULE,
+ PERIPH_RMT_MODULE,
+ PERIPH_SPI_MODULE,
+ PERIPH_SPI2_MODULE,
+ PERIPH_TWAI_MODULE,
+ PERIPH_RNG_MODULE,
+ PERIPH_WIFI_MODULE,
+ PERIPH_BT_MODULE,
+ PERIPH_WIFI_BT_COMMON_MODULE,
+ PERIPH_BT_BASEBAND_MODULE,
+ PERIPH_BT_LC_MODULE,
+ PERIPH_RSA_MODULE,
+ PERIPH_AES_MODULE,
+ PERIPH_SHA_MODULE,
+ PERIPH_HMAC_MODULE,
+ PERIPH_DS_MODULE,
+ PERIPH_GDMA_MODULE,
+ PERIPH_SYSTIMER_MODULE,
+ PERIPH_SARADC_MODULE,
+ PERIPH_MODULE_MAX
+};
+
+/* Internal structure which holds all requested deep sleep parameters. */
+
+struct esp32c3_sleep_config_s
+{
+ enum esp32c3_sleep_pd_option_e pd_options[ESP_PD_DOMAIN_MAX];
+ uint64_t sleep_duration;
+ uint32_t wakeup_triggers : 15;
+ uint32_t ext1_trigger_mode : 1;
+ uint32_t ext1_rtc_gpio_mask : 18;
+ uint32_t ext0_trigger_level : 1;
+ uint32_t ext0_rtc_gpio_num : 5;
+ uint32_t gpio_wakeup_mask : 6;
+ uint32_t gpio_trigger_mode : 6;
+ uint32_t sleep_time_adjustment;
+ uint32_t ccount_ticks_record;
+ uint32_t sleep_time_overhead_out;
+ uint32_t rtc_clk_cal_period;
+ uint64_t rtc_ticks_at_sleep_start;
+ void *cpu_pd_mem;
+};
+
+/* Structure describing vddsdio configuration. */
+
+struct esp32c3_rtc_vddsdio_config_s
+{
+ uint32_t force : 1; /* If 1, use configuration from RTC registers;
+ * if 0, use EFUSE/bootstrapping pins.
+ */
+ uint32_t enable : 1; /* Enable VDDSDIO regulator */
+ uint32_t tieh : 1; /* Select VDDSDIO voltage. One of
+ * RTC_VDDSDIO_TIEH_1_8V, RTC_VDDSDIO_TIEH_3_3V
+ */
+ uint32_t drefh : 2; /* Tuning parameter for VDDSDIO regulator */
+ uint32_t drefm : 2; /* Tuning parameter for VDDSDIO regulator */
+ uint32_t drefl : 2; /* Tuning parameter for VDDSDIO regulator */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static inline uint32_t esp32c3_periph_ll_get_rst_en_mask
+ (enum esp32c3_periph_module_e periph, bool enable);
+static uint32_t IRAM_ATTR esp32c3_periph_ll_get_rst_en_reg(
+ enum esp32c3_periph_module_e periph);
+static uint32_t IRAM_ATTR esp32c3_periph_ll_get_clk_en_reg(
+ enum esp32c3_periph_module_e periph);
+static inline uint32_t esp32c3_periph_ll_get_clk_en_mask(
+ enum esp32c3_periph_module_e periph);
+static inline bool IRAM_ATTR esp32c3_periph_ll_periph_enabled(
+ enum esp32c3_periph_module_e periph);
+static inline void esp32c3_uart_tx_wait_idle(uint8_t uart_no);
+static void IRAM_ATTR esp32c3_flush_uarts(void);
+static void IRAM_ATTR esp32c3_suspend_uarts(void);
+static void IRAM_ATTR esp32c3_resume_uarts(void);
+static void esp32c3_timer_wakeup_prepare(void);
+static uint32_t esp32c3_get_power_down_flags(void);
+static void IRAM_ATTR esp32c3_set_vddsdio_config(
+ struct esp32c3_rtc_vddsdio_config_s config);
+static int IRAM_ATTR esp32c3_get_vddsdio_config(
+ struct esp32c3_rtc_vddsdio_config_s *config);
+static int IRAM_ATTR esp32c3_light_sleep_inner(uint32_t pd_flags,
+ uint32_t time_us, struct esp32c3_rtc_vddsdio_config_s config);
+static int IRAM_ATTR esp32c3_sleep_start(uint32_t pd_flags);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct esp32c3_sleep_config_s s_config =
+{
+ .pd_options =
+ { ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO,
+ ESP_PD_OPTION_AUTO, ESP_PD_OPTION_AUTO,
+ ESP_PD_OPTION_AUTO
+ },
+ .ccount_ticks_record = 0,
+ .sleep_time_overhead_out = DEFAULT_SLEEP_OUT_OVERHEAD_US,
+ .wakeup_triggers = 0
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Set the real CPU ticks per us to the ets,
+ * so that ets_delay_us will be accurate.
+ */
+
+extern void ets_update_cpu_frequency(uint32_t ticks_per_us);
+
+/* Pauses execution for us microseconds. */
+
+extern void esp_rom_delay_us(uint32_t us);
+
+/****************************************************************************
+ * Name: esp32c3_periph_ll_get_rst_en_mask
+ *
+ * Description:
+ * Get system reset bit through periph module
+ *
+ * Input Parameters:
+ * periph - Periph module (one of enum esp32c3_periph_module_e values)
+ * enable - Whether hardware acceleration is enabled
+ *
+ * Returned Value:
+ * System reset bit
+ *
+ ****************************************************************************/
+
+static inline uint32_t esp32c3_periph_ll_get_rst_en_mask
+ (enum esp32c3_periph_module_e periph, bool enable)
+{
+ switch (periph)
+ {
+ case PERIPH_SARADC_MODULE:
+ return SYSTEM_APB_SARADC_RST;
+
+ case PERIPH_RMT_MODULE:
+ return SYSTEM_RMT_RST;
+
+ case PERIPH_LEDC_MODULE:
+ return SYSTEM_LEDC_RST;
+
+ case PERIPH_UART0_MODULE:
+ return SYSTEM_UART_RST;
+
+ case PERIPH_UART1_MODULE:
+ return SYSTEM_UART1_RST;
+
+ case PERIPH_I2C0_MODULE:
+ return SYSTEM_I2C_EXT0_RST;
+
+ case PERIPH_I2S1_MODULE:
+ return SYSTEM_I2S1_RST;
+
+ case PERIPH_TIMG0_MODULE:
+ return SYSTEM_TIMERGROUP_RST;
+
+ case PERIPH_TIMG1_MODULE:
+ return SYSTEM_TIMERGROUP1_RST;
+
+ case PERIPH_UHCI0_MODULE:
+ return SYSTEM_UHCI0_RST;
+
+ case PERIPH_SYSTIMER_MODULE:
+ return SYSTEM_SYSTIMER_RST;
+
+ case PERIPH_GDMA_MODULE:
+ return SYSTEM_DMA_RST;
+
+ case PERIPH_SPI_MODULE:
+ return SYSTEM_SPI01_RST;
+
+ case PERIPH_SPI2_MODULE:
+ return SYSTEM_SPI2_RST;
+
+ case PERIPH_TWAI_MODULE:
+ return SYSTEM_TWAI_RST;
+
+ case PERIPH_HMAC_MODULE:
+ return SYSTEM_CRYPTO_HMAC_RST;
+
+ case PERIPH_AES_MODULE:
+ if (enable == true)
+ {
+ /* Clear reset on digital signature,
+ * otherwise AES unit is held in reset also.
+ */
+
+ return (SYSTEM_CRYPTO_AES_RST | SYSTEM_CRYPTO_DS_RST);
+ }
+
+ /* Don't return other units to reset,
+ * as this pulls reset on RSA & SHA units, respectively.
+ */
+
+ return SYSTEM_CRYPTO_AES_RST;
+
+ case PERIPH_SHA_MODULE:
+ if (enable == true)
+ {
+ /* Clear reset on digital signature and HMAC,
+ * otherwise SHA is held in reset
+ */
+
+ return (SYSTEM_CRYPTO_SHA_RST |
+ SYSTEM_CRYPTO_DS_RST | SYSTEM_CRYPTO_HMAC_RST);
+ }
+
+ /* Don't assert reset on secure boot,
+ * otherwise AES is held in reset
+ */
+
+ return SYSTEM_CRYPTO_SHA_RST;
+
+ case PERIPH_RSA_MODULE:
+ if (enable == true)
+ {
+ /* also clear reset on digital signature,
+ * otherwise RSA is held in reset
+ */
+
+ return (SYSTEM_CRYPTO_RSA_RST | SYSTEM_CRYPTO_DS_RST);
+ }
+
+ /* don't reset digital signature unit,
+ * as this resets AES also.
+ */
+
+ return SYSTEM_CRYPTO_RSA_RST;
+
+ case PERIPH_DS_MODULE:
+ return SYSTEM_CRYPTO_DS_RST;
+
+ default:
+ return 0;
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_periph_ll_get_rst_en_reg
+ *
+ * Description:
+ * Get system reset register through periph module
+ *
+ * Input Parameters:
+ * periph - Periph module (one of enum esp32c3_periph_module_e values)
+ *
+ * Returned Value:
+ * System reset register
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR esp32c3_periph_ll_get_rst_en_reg(
+ enum esp32c3_periph_module_e periph)
+{
+ switch (periph)
+ {
+ case PERIPH_RNG_MODULE:
+ case PERIPH_WIFI_MODULE:
+ case PERIPH_BT_MODULE:
+ case PERIPH_WIFI_BT_COMMON_MODULE:
+ case PERIPH_BT_BASEBAND_MODULE:
+ case PERIPH_BT_LC_MODULE:
+ return SYSTEM_WIFI_RST_EN_REG;
+
+ case PERIPH_HMAC_MODULE:
+ case PERIPH_DS_MODULE:
+ case PERIPH_AES_MODULE:
+ case PERIPH_RSA_MODULE:
+ case PERIPH_SHA_MODULE:
+ case PERIPH_GDMA_MODULE:
+ return SYSTEM_PERIP_RST_EN1_REG;
+
+ default:
+ return SYSTEM_PERIP_RST_EN0_REG;
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_periph_ll_get_clk_en_reg
+ *
+ * Description:
+ * Get module clock register through periph module
+ *
+ * Input Parameters:
+ * periph - Periph module (one of enum esp32c3_periph_module_e values)
+ *
+ * Returned Value:
+ * Module clock register
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR esp32c3_periph_ll_get_clk_en_reg(
+ enum esp32c3_periph_module_e periph)
+{
+ switch (periph)
+ {
+ case PERIPH_RNG_MODULE:
+ case PERIPH_WIFI_MODULE:
+ case PERIPH_BT_MODULE:
+ case PERIPH_WIFI_BT_COMMON_MODULE:
+ case PERIPH_BT_BASEBAND_MODULE:
+ case PERIPH_BT_LC_MODULE:
+ return SYSTEM_WIFI_CLK_EN_REG;
+
+ case PERIPH_HMAC_MODULE:
+ case PERIPH_DS_MODULE:
+ case PERIPH_AES_MODULE:
+ case PERIPH_RSA_MODULE:
+ case PERIPH_SHA_MODULE:
+ case PERIPH_GDMA_MODULE:
+ return SYSTEM_PERIP_CLK_EN1_REG;
+
+ default:
+ return SYSTEM_PERIP_CLK_EN0_REG;
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_periph_ll_get_clk_en_mask
+ *
+ * Description:
+ * Get module clock bit through periph module
+ *
+ * Input Parameters:
+ * periph - Periph module (one of enum esp32c3_periph_module_e values)
+ *
+ * Returned Value:
+ * Module clock bit
+ *
+ ****************************************************************************/
+
+static inline uint32_t esp32c3_periph_ll_get_clk_en_mask(
+ enum esp32c3_periph_module_e periph)
+{
+ switch (periph)
+ {
+ case PERIPH_SARADC_MODULE:
+ return SYSTEM_APB_SARADC_CLK_EN;
+
+ case PERIPH_RMT_MODULE:
+ return SYSTEM_RMT_CLK_EN;
+
+ case PERIPH_LEDC_MODULE:
+ return SYSTEM_LEDC_CLK_EN;
+
+ case PERIPH_UART0_MODULE:
+ return SYSTEM_UART_CLK_EN;
+
+ case PERIPH_UART1_MODULE:
+ return SYSTEM_UART1_CLK_EN;
+
+ case PERIPH_I2C0_MODULE:
+ return SYSTEM_I2C_EXT0_CLK_EN;
+
+ case PERIPH_I2S1_MODULE:
+ return SYSTEM_I2S1_CLK_EN;
+
+ case PERIPH_TIMG0_MODULE:
+ return SYSTEM_TIMERGROUP_CLK_EN;
+
+ case PERIPH_TIMG1_MODULE:
+ return SYSTEM_TIMERGROUP1_CLK_EN;
+
+ case PERIPH_UHCI0_MODULE:
+ return SYSTEM_UHCI0_CLK_EN;
+
+ case PERIPH_SYSTIMER_MODULE:
+ return SYSTEM_SYSTIMER_CLK_EN;
+
+ case PERIPH_SPI_MODULE:
+ return SYSTEM_SPI01_CLK_EN;
+
+ case PERIPH_SPI2_MODULE:
+ return SYSTEM_SPI2_CLK_EN;
+
+ case PERIPH_TWAI_MODULE:
+ return SYSTEM_TWAI_CLK_EN;
+
+ case PERIPH_GDMA_MODULE:
+ return SYSTEM_DMA_CLK_EN;
+
+ case PERIPH_AES_MODULE:
+ return SYSTEM_CRYPTO_AES_CLK_EN;
+
+ case PERIPH_SHA_MODULE:
+ return SYSTEM_CRYPTO_SHA_CLK_EN;
+
+ case PERIPH_RSA_MODULE:
+ return SYSTEM_CRYPTO_RSA_CLK_EN;
+
+ case PERIPH_HMAC_MODULE:
+ return SYSTEM_CRYPTO_HMAC_CLK_EN;
+
+ case PERIPH_DS_MODULE:
+ return SYSTEM_CRYPTO_DS_CLK_EN;
+
+ case PERIPH_RNG_MODULE:
+ return SYSTEM_WIFI_CLK_RNG_EN;
+
+ case PERIPH_WIFI_MODULE:
+ return SYSTEM_WIFI_CLK_WIFI_EN_M;
+
+ case PERIPH_BT_MODULE:
+ return SYSTEM_WIFI_CLK_BT_EN_M;
+
+ case PERIPH_WIFI_BT_COMMON_MODULE:
+ return SYSTEM_WIFI_CLK_WIFI_BT_COMMON_M;
+
+ case PERIPH_BT_BASEBAND_MODULE:
+ return SYSTEM_BT_BASEBAND_EN;
+
+ case PERIPH_BT_LC_MODULE:
+ return SYSTEM_BT_LC_EN;
+
+ default:
+ return 0;
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_periph_ll_periph_enabled
+ *
+ * Description:
+ * Whether the current Periph module is enabled
+ *
+ * Input Parameters:
+ * periph - Periph module (one of enum esp32c3_periph_module_e values)
+ *
+ * Returned Value:
+ * Periph module is enabled or not
+ *
+ ****************************************************************************/
+
+static inline bool IRAM_ATTR esp32c3_periph_ll_periph_enabled(
+ enum esp32c3_periph_module_e periph)
+{
+ return ((getreg32(esp32c3_periph_ll_get_rst_en_reg(periph)) &
+ esp32c3_periph_ll_get_rst_en_mask(periph, false)) == 0) &&
+ ((getreg32(esp32c3_periph_ll_get_clk_en_reg(periph)) &
+ esp32c3_periph_ll_get_clk_en_mask(periph)) != 0);
+}
+
+/****************************************************************************
+ * Name: esp32c3_uart_tx_wait_idle
+ *
+ * Description:
+ * Wait until uart tx full empty and the last char send ok.
+ *
+ * Input Parameters:
+ * uart_no - 0 for UART0, 1 for UART1, 2 for UART2
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static inline void IRAM_ATTR esp32c3_uart_tx_wait_idle(uint8_t uart_no)
+{
+ uint32_t status;
+ do
+ {
+ status = getreg32(UART_STATUS_REG(uart_no));
+ }
+ while ((status & (UART_ST_UTX_OUT_M | UART_TXFIFO_CNT_M)) != 0);
+}
+
+/****************************************************************************
+ * Name: esp32c3_flush_uarts
+ *
+ * Description:
+ * Wait until UART0/UART1 tx full empty and the last char send ok
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_flush_uarts(void)
+{
+ int i;
+
+ for (i = 0; i < ESP32C3_NUARTS; ++i)
+ {
+ if (esp32c3_periph_ll_periph_enabled(PERIPH_UART0_MODULE + i))
+ {
+ esp32c3_uart_tx_wait_idle(i);
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_suspend_uarts
+ *
+ * Description:
+ * Suspend UART0/UART1 output
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_suspend_uarts(void)
+{
+ int i;
+ uint32_t uart_fsm = 0;
+
+ for (i = 0; i < ESP32C3_NUARTS; ++i)
+ {
+ if (!esp32c3_periph_ll_periph_enabled(PERIPH_UART0_MODULE + i))
+ {
+ continue;
+ }
+
+ modifyreg32(UART_FLOW_CONF_REG(i), 0, UART_FORCE_XOFF);
+ do
+ {
+ uart_fsm = REG_GET_FIELD(UART_STATUS_REG(i), UART_ST_UTX_OUT);
+ }
+ while (!(uart_fsm == UART_FSM_IDLE ||
+ uart_fsm == UART_FSM_TX_WAIT_SEND));
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_resume_uarts
+ *
+ * Description:
+ * Re-enable UART0/UART1/UART2 output
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_resume_uarts(void)
+{
+ int i;
+
+ for (i = 0; i < ESP32C3_NUARTS; ++i)
+ {
+ if (!esp32c3_periph_ll_periph_enabled(PERIPH_UART0_MODULE + i))
+ {
+ continue;
+ }
+
+ REG_CLR_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XOFF);
+ REG_SET_BIT(UART_FLOW_CONF_REG(i), UART_FORCE_XON);
+ REG_CLR_BIT(UART_FLOW_CONF_REG(i),
+ UART_SW_FLOW_CON_EN | UART_FORCE_XON);
+ REG_SET_BIT(UART_ID_REG(i), UART_UPDATE);
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_get_power_down_flags
+ *
+ * Description:
+ * Get power domains that can be powered down
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Power domains
+ *
+ ****************************************************************************/
+
+static uint32_t esp32c3_get_power_down_flags(void)
+{
+ uint32_t pd_flags = 0;
+
+ s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
+
+ if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO)
+ {
+ if (s_config.wakeup_triggers & RTC_GPIO_TRIG_EN)
+ {
+ s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] =
+ ESP_PD_OPTION_ON;
+ }
+ else
+ {
+ s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] =
+ ESP_PD_OPTION_OFF;
+ }
+ }
+
+ if (s_config.cpu_pd_mem == NULL)
+ {
+ s_config.pd_options[ESP_PD_DOMAIN_CPU] = ESP_PD_OPTION_ON;
+ }
+
+ if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] == ESP_PD_OPTION_AUTO)
+ {
+ s_config.pd_options[ESP_PD_DOMAIN_XTAL] = ESP_PD_OPTION_OFF;
+ }
+
+ /* Prepare flags based on the selected options */
+
+ if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON)
+ {
+ pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM;
+ }
+
+ if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON)
+ {
+ pd_flags |= RTC_SLEEP_PD_RTC_PERIPH;
+ }
+
+ if (s_config.pd_options[ESP_PD_DOMAIN_CPU] != ESP_PD_OPTION_ON)
+ {
+ pd_flags |= RTC_SLEEP_PD_CPU;
+ }
+
+ return pd_flags;
+}
+
+/****************************************************************************
+ * Name: esp32c3_timer_wakeup_prepare
+ *
+ * Description:
+ * Configure timer to wake-up
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_timer_wakeup_prepare(void)
+{
+ int64_t ticks;
+ int64_t sleep_duration = (int64_t)s_config.sleep_duration -
+ (int64_t) s_config.sleep_time_adjustment;
+ if (sleep_duration < 0)
+ {
+ sleep_duration = 0;
+ }
+
+ ticks = esp32c3_rtc_time_us_to_slowclk(sleep_duration,
+ s_config.rtc_clk_cal_period);
+ esp32c3_rtc_sleep_set_wakeup_time(s_config.rtc_ticks_at_sleep_start
+ + ticks);
+}
+
+/****************************************************************************
+ * Name: esp32c3_set_vddsdio_config
+ *
+ * Description:
+ * Set new VDDSDIO configuration using RTC registers.
+ *
+ * Input Parameters:
+ * New VDDSDIO configuration
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_set_vddsdio_config(
+ struct esp32c3_rtc_vddsdio_config_s config)
+{
+ uint32_t val = 0;
+ val |= (config.force << RTC_CNTL_SDIO_FORCE_S);
+ val |= (config.enable << RTC_CNTL_XPD_SDIO_REG_S);
+ val |= (config.drefh << RTC_CNTL_DREFH_SDIO_S);
+ val |= (config.drefm << RTC_CNTL_DREFM_SDIO_S);
+ val |= (config.drefl << RTC_CNTL_DREFL_SDIO_S);
+ val |= (config.tieh << RTC_CNTL_SDIO_TIEH_S);
+ val |= RTC_CNTL_SDIO_PD_EN;
+ putreg32((uint32_t)val, RTC_CNTL_SDIO_CONF_REG);
+}
+
+/****************************************************************************
+ * Name: esp32c3_get_vddsdio_config
+ *
+ * Description:
+ * Get current VDDSDIO configuration.
+ *
+ * Input Parameters:
+ * Incoming parameter address of VDDSDIO configuration to be saved
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success.
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR esp32c3_get_vddsdio_config(
+ struct esp32c3_rtc_vddsdio_config_s *config)
+{
+ struct esp32c3_rtc_vddsdio_config_s *result = config;
+ uint32_t strap_reg;
+ uint32_t sdio_conf_reg = getreg32(RTC_CNTL_SDIO_CONF_REG);
+
+ result->drefh = (sdio_conf_reg & RTC_CNTL_DREFH_SDIO_M)
+ >> RTC_CNTL_DREFH_SDIO_S;
+ result->drefm = (sdio_conf_reg & RTC_CNTL_DREFM_SDIO_M)
+ >> RTC_CNTL_DREFM_SDIO_S;
+ result->drefl = (sdio_conf_reg & RTC_CNTL_DREFL_SDIO_M)
+ >> RTC_CNTL_DREFL_SDIO_S;
+
+ if (sdio_conf_reg & RTC_CNTL_SDIO_FORCE)
+ {
+ /* Get configuration from RTC */
+
+ result->force = 1;
+ result->enable = (sdio_conf_reg & RTC_CNTL_XPD_SDIO_REG_M)
+ >> RTC_CNTL_XPD_SDIO_REG_S;
+ result->tieh = (sdio_conf_reg & RTC_CNTL_SDIO_TIEH_M)
+ >> RTC_CNTL_SDIO_TIEH_S;
+
+ return OK;
+ }
+
+ /* Otherwise, VDD_SDIO is controlled by bootstrapping pin */
+
+ strap_reg = getreg32(GPIO_STRAP_REG);
+ result->force = 0;
+ result->tieh = (strap_reg & BIT(5)) ? RTC_VDDSDIO_TIEH_1_8V
+ : RTC_VDDSDIO_TIEH_3_3V;
+ result->enable = 1;
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: esp32c3_sleep_start
+ *
+ * Description:
+ * Enter low power mode.
+ *
+ * Input Parameters:
+ * Power domains
+ *
+ * Returned Value:
+ * 0 is returned on success or a negated errno value is returned
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR esp32c3_sleep_start(uint32_t pd_flags)
+{
+ int result;
+ struct esp32c3_cpu_freq_config_s cpu_freq_config;
+ bool deep_sleep = pd_flags & RTC_SLEEP_PD_DIG;
+
+ /* Stop UART output so that output is not lost due to APB frequency change.
+ * For light sleep, suspend UART output — it will resume after wakeup.
+ * For deep sleep, wait for the contents of UART FIFO to be sent.
+ */
+
+ if (deep_sleep)
+ {
+ esp32c3_flush_uarts();
+ }
+ else
+ {
+ esp32c3_suspend_uarts();
+ }
+
+ /* Save current frequency and switch to XTAL */
+
+ esp32c3_rtc_clk_cpu_freq_get_config(&cpu_freq_config);
+ esp32c3_rtc_cpu_freq_set_xtal();
+
+ /* Enter sleep */
+
+ esp32c3_rtc_sleep_init(pd_flags);
+
+ esp32c3_rtc_sleep_low_init(s_config.rtc_clk_cal_period);
+
+ /* Set state machine time for light sleep */
+
+ if (deep_sleep == false)
+ {
+ esp32c3_rtc_sleep_low_init(s_config.rtc_clk_cal_period);
+ }
+
+ /* Configure timer wakeup */
+
+ if ((s_config.wakeup_triggers & RTC_TIMER_TRIG_EN)
+ && s_config.sleep_duration > 0)
+ {
+ esp32c3_timer_wakeup_prepare();
+ }
+
+ if (deep_sleep)
+ {
+ /* Otherwise, need to call the dedicated soc function for this */
+
+ result = esp32c3_rtc_deep_sleep_start(s_config.wakeup_triggers, 0);
+ }
+ else
+ {
+ result = esp32c3_rtc_sleep_start(s_config.wakeup_triggers, 0, 1);
+ }
+
+ /* Restore CPU frequency */
+
+ esp32c3_rtc_clk_cpu_freq_set_config(&cpu_freq_config);
+
+ if (!deep_sleep)
+ {
+ s_config.ccount_ticks_record = esp32c3_cpu_cycle_count();
+ }
+
+ REG_CLR_BIT(RTC_CNTL_RETENTION_CTRL_REG, RTC_CNTL_RETENTION_EN);
+
+ /* Re-enable UART output */
+
+ esp32c3_resume_uarts();
+
+ return result;
+}
+
+/****************************************************************************
+ * Name: esp32c3_light_sleep_inner
+ *
+ * Description:
+ * Enter low power mode, then wait for flash to be ready on wakeup
+ *
+ * Input Parameters:
+ * pd_flags - Power domains
+ * time_us - Time to wait for spi_flash become ready
+ * config - VDDSDIO configuration
+ *
+ * Returned Value:
+ * 0 is returned on success or a negated errno value is returned
+ *
+ ****************************************************************************/
+
+static int IRAM_ATTR esp32c3_light_sleep_inner(uint32_t pd_flags,
+ uint32_t time_us, struct esp32c3_rtc_vddsdio_config_s config)
+{
+ /* Enter sleep */
+
+ int err = esp32c3_sleep_start(pd_flags);
+
+ /* If VDDSDIO regulator was controlled by RTC registers before sleep.
+ * restore the configuration.
+ */
+
+ if (config.force)
+ {
+ esp32c3_set_vddsdio_config(config);
+ }
+
+ /* If SPI flash was powered down, wait for it to become ready. */
+
+ if (pd_flags & RTC_SLEEP_PD_VDDSDIO)
+ {
+ /* Wait for the flash chip to start up. */
+
+ esp_rom_delay_us(time_us);
+ }
+
+ return err;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_sleep_enable_timer_wakeup
+ *
+ * Description:
+ * Configure wake-up interval
+ *
+ * Input Parameters:
+ * time_in_us - Configure wake-up time interval
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_sleep_enable_timer_wakeup(uint64_t time_in_us)
+{
+ s_config.wakeup_triggers |= RTC_TIMER_TRIG_EN;
+ s_config.sleep_duration = time_in_us;
+}
+
+/****************************************************************************
+ * Name: esp32c3_light_sleep_start
+ *
+ * Description:
+ * Enter light sleep mode
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * 0 is returned on success or a negated errno value is returned
+ *
+ ****************************************************************************/
+
+int esp32c3_light_sleep_start(void)
+{
+ int ret = OK;
+ irqstate_t flags;
+ uint32_t pd_flags;
+ uint32_t flash_enable_time_us;
+ uint32_t vddsdio_pd_sleep_duration;
+ struct esp32c3_rtc_vddsdio_config_s vddsdio_config;
+ uint32_t rtc_cntl_xtl_buf_wait_cycles;
+ uint32_t sleep_time_overhead_in;
+ uint32_t ccount_at_sleep_start;
+
+ flags = enter_critical_section();
+
+ s_config.ccount_ticks_record = esp32c3_cpu_cycle_count();
+ s_config.rtc_ticks_at_sleep_start = esp32c3_rtc_time_get();
+ ccount_at_sleep_start = esp32c3_cpu_cycle_count();
+ sleep_time_overhead_in = (ccount_at_sleep_start -
+ s_config.ccount_ticks_record) / (esp32c3_clk_cpu_freq() / 1000000ULL);
+
+ /* Decide which power domains can be powered down */
+
+ pd_flags = esp32c3_get_power_down_flags();
+
+ s_config.rtc_clk_cal_period =
+ esp32c3_rtc_clk_cal(RTC_CAL_RTC_MUX, RTC_CLK_SRC_CAL_CYCLES);
+
+ /* Adjustment time consists of parts below:
+ * 1. Hardware time waiting for internal 8M oscilate clock and XTAL;
+ * 2. Hardware state swithing time of the rtc main state machine;
+ * 3. Code execution time when clock is not stable;
+ * 4. Code execution time which can be measured;
+ */
+
+ rtc_cntl_xtl_buf_wait_cycles = esp32c3_rtc_time_us_to_slowclk(
+ RTC_CNTL_XTL_BUF_WAIT_SLP_US, s_config.rtc_clk_cal_period);
+
+ s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US +
+ sleep_time_overhead_in + s_config.sleep_time_overhead_out
+ + esp32c3_rtc_time_slowclk_to_us(rtc_cntl_xtl_buf_wait_cycles +
+ RTC_CNTL_CK8M_WAIT_SLP_CYCLES + RTC_CNTL_WAKEUP_DELAY_CYCLES,
+ s_config.rtc_clk_cal_period);
+
+ /* Decide if VDD_SDIO needs to be powered down;
+ * If it needs to be powered down, adjust sleep time.
+ */
+
+ flash_enable_time_us = VDD_SDIO_POWERUP_TO_FLASH_READ_US
+ + DEEP_SLEEP_WAKEUP_DELAY;
+
+ /* When SPIRAM is disabled in menuconfig, the minimum sleep time of the
+ * system needs to meet the sum below:
+ * 1. Wait time for the flash power-on after waking up;
+ * 2. The execution time of codes between RTC Timer get start time
+ * with hardware starts to switch state to sleep;
+ * 3. The hardware state switching time of the rtc state machine during
+ * sleep and wake-up. This process requires 6 cycles to complete.
+ * The specific hardware state switching process and the cycles
+ * consumed are rtc_cpu_run_stall(1), cut_pll_rtl(2), cut_8m(1),
+ * min_protect(2);
+ * 4. All the adjustment time which is
+ * s_config.sleep_time_adjustment below.
+ */
+
+ vddsdio_pd_sleep_duration = MAX(FLASH_PD_MIN_SLEEP_TIME_US,
+ flash_enable_time_us + LIGHT_SLEEP_MIN_TIME_US +
+ s_config.sleep_time_adjustment + esp32c3_rtc_time_slowclk_to_us(
+ RTC_MODULE_SLEEP_PREPARE_CYCLES, s_config.rtc_clk_cal_period));
+
+ if (s_config.sleep_duration > vddsdio_pd_sleep_duration)
+ {
+ pd_flags |= RTC_SLEEP_PD_VDDSDIO;
+ if (s_config.sleep_time_overhead_out < flash_enable_time_us)
+ {
+ s_config.sleep_time_adjustment += flash_enable_time_us;
+ }
+ }
+ else
+ {
+ if (s_config.sleep_time_overhead_out > flash_enable_time_us)
+ {
+ s_config.sleep_time_adjustment -= flash_enable_time_us;
+ }
+ }
+
+ esp32c3_get_vddsdio_config(&vddsdio_config);
+
+ /* Enter sleep, then wait for flash to be ready on wakeup */
+
+ ret = esp32c3_light_sleep_inner(pd_flags, flash_enable_time_us,
+ vddsdio_config);
+ s_config.sleep_time_overhead_out = (esp32c3_cpu_cycle_count() -
+ s_config.ccount_ticks_record) / (esp32c3_clk_cpu_freq() / 1000000ULL);
+
+ leave_critical_section(flags);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: esp32c3_pminit
+ *
+ * Description:
+ * Initialize force sleep parameters.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_pminit(void)
+{
+ /* Initialize RTC parameters */
+
+ esp32c3_rtc_init();
+ esp32c3_rtc_clk_set();
+}
+
+/****************************************************************************
+ * Name: esp32c3_pmstandby
+ *
+ * Description:
+ * Enter force sleep.
+ *
+ * Input Parameters:
+ * time_in_us - force sleep time interval
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_pmstandby(uint64_t time_in_us)
+{
+ /* don't power down XTAL — powering it up takes different time on. */
+
+ fflush(stdout);
+ esp32c3_sleep_enable_timer_wakeup(time_in_us);
+ esp32c3_light_sleep_start();
+}
+
+/****************************************************************************
+ * Name: esp32c3_deep_sleep_start
+ *
+ * Description:
+ * Enter deep sleep mode
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp32c3_deep_sleep_start(void)
+{
+ uint32_t pd_flags;
+
+ /* record current RTC time */
+
+ s_config.rtc_ticks_at_sleep_start = esp32c3_rtc_time_get();
+
+ /* Decide which power domains can be powered down */
+
+ pd_flags = esp32c3_get_power_down_flags();
+ s_config.rtc_clk_cal_period = getreg32(RTC_SLOW_CLK_CAL_REG);
+
+ /* Correct the sleep time */
+
+ s_config.sleep_time_adjustment = DEEP_SLEEP_TIME_OVERHEAD_US;
+
+ /* Enter deep sleep */
+
+ esp32c3_sleep_start(RTC_SLEEP_PD_DIG | RTC_SLEEP_PD_VDDSDIO | pd_flags);
+
+ /* Because RTC is in a slower clock domain than the CPU, it
+ * can take several CPU cycles for the sleep mode to start.
+ */
+
+ while (1);
+}
+
+/****************************************************************************
+ * Name: esp32c3_pmsleep
+ *
+ * Description:
+ * Enter deep sleep.
+ *
+ * Input Parameters:
+ * time_in_us - deep sleep time interval
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_pmsleep(uint64_t time_in_us)
+{
+ fflush(stdout);
+ esp32c3_sleep_enable_timer_wakeup(time_in_us);
+ esp32c3_deep_sleep_start();
+}
+
+#endif /* CONFIG_PM */
\ No newline at end of file
diff --git a/arch/risc-v/src/esp32c3/esp32c3_pm.h b/arch/risc-v/src/esp32c3/esp32c3_pm.h
new file mode 100644
index 0000000..7081b04
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_pm.h
@@ -0,0 +1,155 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_pm.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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_PM_H
+#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_PM_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#ifdef CONFIG_PM
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_sleep_enable_timer_wakeup
+ *
+ * Description:
+ * Configure wake-up interval
+ *
+ * Input Parameters:
+ * time_in_us - Configure wake-up time interval
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_sleep_enable_timer_wakeup(uint64_t time_in_us);
+
+/****************************************************************************
+ * Name: esp32c3_light_sleep_start
+ *
+ * Description:
+ * Enter sleep mode
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * 0 is returned on success or a negated errno value is returned
+ *
+ ****************************************************************************/
+
+int esp32c3_light_sleep_start(void);
+
+/****************************************************************************
+ * Name: esp32c3_pminit
+ *
+ * Description:
+ * Initialize force sleep parameters.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_pminit(void);
+
+/****************************************************************************
+ * Name: esp32c3_pmstandby
+ *
+ * Description:
+ * Enter force sleep time interval.
+ *
+ * Input Parameters:
+ * time_in_us - force sleep time interval
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_pmstandby(uint64_t time_in_us);
+
+/****************************************************************************
+ * Name: esp32c3_deep_sleep_start
+ *
+ * Description:
+ * Enter deep sleep mode
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_deep_sleep_start(void);
+
+/****************************************************************************
+ * Name: esp32c3_pmsleep
+ *
+ * Description:
+ * Enter deep sleep.
+ *
+ * Input Parameters:
+ * time_in_us - deep sleep time interval
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_pmsleep(uint64_t time_in_us);
+
+#endif /* CONFIG_PM */
+
+#ifdef __cplusplus
+}
+#endif
+#undef EXTERN
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_PM_H */
diff --git a/arch/risc-v/src/esp32c3/esp32c3_idle.c b/arch/risc-v/src/esp32c3/esp32c3_pminitialize.c
similarity index 54%
copy from arch/risc-v/src/esp32c3/esp32c3_idle.c
copy to arch/risc-v/src/esp32c3/esp32c3_pminitialize.c
index 079bfd4..ad1e87a 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_idle.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_pminitialize.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * arch/risc-v/src/esp32c3/esp32c3_idle.c
+ * arch/risc-v/src/esp32c3/esp32c3_pminitialize.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -23,51 +23,33 @@
****************************************************************************/
#include <nuttx/config.h>
-#include <nuttx/irq.h>
-#include <nuttx/arch.h>
#include <nuttx/power/pm.h>
-#include "esp32c3.h"
+#include "esp32c3_pm.h"
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
+#ifdef CONFIG_PM
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
- * Name: up_idle
+ * Name: xtensa_pminitialize
*
* Description:
- * up_idle() is the logic that will be executed when their is no other
- * ready-to-run task. This is processor idle time and will continue until
- * some interrupt occurs to cause a context switch from the idle task.
- *
- * Processing in this state may be processor-specific. e.g., this is where
- * power management operations might be performed.
+ * Initialize the power management subsystem.
*
****************************************************************************/
-void up_idle(void)
+void riscv_pminitialize(void)
{
-#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
- /* If the system is idle and there are no timer interrupts, then process
- * "fake" timer interrupts. Hopefully, something will wake up.
- */
+ /* Initialize RTC parameters */
- nxsched_process_timer();
-#else
- /* This would be an appropriate place to put some MCU-specific logic to
- * sleep in a reduced power mode until an interrupt occurs to save power
- */
+ esp32c3_pminit();
- asm("WFI");
+ /* Then initialize the NuttX power management subsystem proper */
-#endif
+ pm_initialize();
}
+
+#endif /* CONFIG_PM */
diff --git a/arch/risc-v/src/esp32c3/esp32c3_rtc.c b/arch/risc-v/src/esp32c3/esp32c3_rtc.c
new file mode 100644
index 0000000..f1947a6
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_rtc.c
@@ -0,0 +1,2099 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_rtc.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 <stdint.h>
+#include <assert.h>
+
+#include "riscv_arch.h"
+
+#include "hardware/esp32c3_rtccntl.h"
+#include "hardware/esp32c3_soc.h"
+#include "hardware/esp32c3_system.h"
+#include "hardware/esp32c3_tim.h"
+#include "hardware/apb_ctrl_reg.h"
+#include "hardware/bb_reg.h"
+#include "hardware/nrx_reg.h"
+#include "hardware/fe_reg.h"
+#include "hardware/regi2c_lp_bias.h"
+#include "hardware/regi2c_dig_reg.h"
+#include "hardware/regi2c_bbpll.h"
+#include "hardware/regi2c_ctrl.h"
+#include "hardware/extmem_reg.h"
+#include "hardware/spi_mem_reg.h"
+
+#include "esp32c3_rtc.h"
+#include "esp32c3_clockconfig.h"
+#include "esp32c3_attr.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define OTHER_BLOCKS_POWERUP 1
+#define OTHER_BLOCKS_WAIT 1
+
+#define STR2(X) #X
+#define STR(X) STR2(X)
+
+#define MHZ (1000000)
+
+/* Lower threshold for a reasonably-looking calibration value for a 32k XTAL.
+ * The ideal value (assuming 32768 Hz frequency)
+ * is 1000000/32768*(2**19) = 16*10^6.
+ */
+
+#define MIN_32K_XTAL_CAL_VAL 15000000L
+#define DELAY_FAST_CLK_SWITCH 3
+#define DELAY_SLOW_CLK_SWITCH 300
+#define DELAY_8M_ENABLE 50
+
+/* Indicates that this 32k oscillator gets input from external oscillator,
+ * rather than a crystal.
+ */
+
+#define EXT_OSC_FLAG BIT(3)
+
+/* Number of cycles to wait from the 32k XTAL oscillator to
+ * consider it running. Larger values increase startup delay.
+ * Smaller values may cause false positive detection
+ * (i.e. oscillator runs for a few cycles and then stops).
+ */
+
+#define SLOW_CLK_CAL_CYCLES 1024
+
+#define RTC_FAST_CLK_FREQ_8M 8500000
+
+/* With the default value of CK8M_DFREQ,
+ * 8M clock frequency is 8.5 MHz +/- 7%.
+ */
+
+#define RTC_FAST_CLK_FREQ_APPROX 8500000
+
+#define RTC_PLL_FREQ_320M 320
+#define RTC_PLL_FREQ_480M 480
+
+#define RTC_SLOW_CLK_FREQ_90K 90000
+#define RTC_SLOW_CLK_FREQ_8MD256 (RTC_FAST_CLK_FREQ_APPROX / 256)
+#define RTC_SLOW_CLK_FREQ_32K 32768
+
+#define RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
+#define RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(cycles) (cycles << 12)
+#define RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(cycles) (cycles << 10)
+
+/* Number of fractional bits in values returned by rtc_clk_cal */
+
+#define RTC_CLK_CAL_FRACT 19
+
+/* set sleep_init default param. */
+
+#define RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT 3
+#define RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT 15
+#define RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT 0
+#define RTC_CNTL_BIASSLP_MONITOR_DEFAULT 0
+#define RTC_CNTL_BIASSLP_SLEEP_DEFAULT 1
+#define RTC_CNTL_PD_CUR_MONITOR_DEFAULT 0
+#define RTC_CNTL_PD_CUR_SLEEP_DEFAULT 1
+#define RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT 254
+
+#define RTC_CK8M_ENABLE_WAIT_DEFAULT 5
+
+/* Approximate mapping of voltages to RTC_CNTL_DBIAS_WAK,
+ * RTC_CNTL_DBIAS_SLP, RTC_CNTL_DIG_DBIAS_WAK,
+ * RTC_CNTL_DIG_DBIAS_SLP values. Valid if RTC_CNTL_DBG_ATTEN is 0.
+ */
+
+#define RTC_CNTL_DBIAS_SLP 0
+#define RTC_CNTL_DBIAS_0V90 13
+#define RTC_CNTL_DBIAS_0V95 16
+#define RTC_CNTL_DBIAS_1V00 18
+#define RTC_CNTL_DBIAS_1V05 20
+#define RTC_CNTL_DBIAS_1V10 23
+#define RTC_CNTL_DBIAS_1V15 25
+#define RTC_CNTL_DBIAS_1V20 28
+#define RTC_CNTL_DBIAS_1V25 30
+#define RTC_CNTL_DBIAS_1V30 31
+
+#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
+#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
+
+#define DIG_DBIAS_80M RTC_CNTL_DBIAS_1V20
+#define DIG_DBIAS_160M RTC_CNTL_DBIAS_1V20
+
+/* Default initializer for esp32c3_rtc_sleep_config_s
+ * This initializer sets all fields to "reasonable" values
+ * (e.g. suggested for production use) based on a combination
+ * of RTC_SLEEP_PD_x flags.
+ */
+
+#define RTC_SLEEP_CONFIG_DEFAULT(sleep_flags) { \
+ .lslp_mem_inf_fpu = 0, \
+ .rtc_mem_inf_follow_cpu = ((sleep_flags) & RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU) ? 1 : 0, \
+ .rtc_fastmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_FAST_MEM) ? 1 : 0, \
+ .rtc_slowmem_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_SLOW_MEM) ? 1 : 0, \
+ .rtc_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_RTC_PERIPH) ? 1 : 0, \
+ .wifi_pd_en = ((sleep_flags) & RTC_SLEEP_PD_WIFI) ? 1 : 0, \
+ .bt_pd_en = ((sleep_flags) & RTC_SLEEP_PD_BT) ? 1 : 0, \
+ .cpu_pd_en = ((sleep_flags) & RTC_SLEEP_PD_CPU) ? 1 : 0, \
+ .dig_peri_pd_en = ((sleep_flags) & RTC_SLEEP_PD_DIG_PERIPH) ? 1 : 0, \
+ .deep_slp = ((sleep_flags) & RTC_SLEEP_PD_DIG) ? 1 : 0, \
+ .wdt_flashboot_mod_en = 0, \
+ .dig_dbias_wak = RTC_CNTL_DBIAS_1V10, \
+ .dig_dbias_slp = RTC_CNTL_DBIAS_SLP, \
+ .rtc_dbias_wak = RTC_CNTL_DBIAS_1V10, \
+ .rtc_dbias_slp = RTC_CNTL_DBIAS_SLP, \
+ .vddsdio_pd_en = ((sleep_flags) & RTC_SLEEP_PD_VDDSDIO) ? 1 : 0, \
+ .deep_slp_reject = 1, \
+ .light_slp_reject = 1 \
+};
+
+#define X32K_CONFIG_DEFAULT() { \
+ .dac = 3, \
+ .dres = 3, \
+ .dgm = 3, \
+ .dbuf = 1, \
+}
+
+/* Initializer for struct esp32c3_rtc_sleep_pu_config_s
+ * which sets all flags to the same value
+ */
+
+#define RTC_SLEEP_PU_CONFIG_ALL(val) {\
+ .dig_fpu = (val), \
+ .rtc_fpu = (val), \
+ .cpu_fpu = (val), \
+ .i2s_fpu = (val), \
+ .bb_fpu = (val), \
+ .nrx_fpu = (val), \
+ .fe_fpu = (val), \
+ .sram_fpu = (val), \
+ .rom_ram_fpu = (val), \
+}
+
+#define RTC_INIT_CONFIG_DEFAULT() { \
+ .wifi_powerup_cycles = OTHER_BLOCKS_POWERUP, \
+ .wifi_wait_cycles = OTHER_BLOCKS_WAIT, \
+ .bt_powerup_cycles = OTHER_BLOCKS_POWERUP, \
+ .bt_wait_cycles = OTHER_BLOCKS_WAIT, \
+ .cpu_top_powerup_cycles = OTHER_BLOCKS_POWERUP, \
+ .cpu_top_wait_cycles = OTHER_BLOCKS_WAIT, \
+ .dg_wrap_powerup_cycles = OTHER_BLOCKS_POWERUP, \
+ .dg_wrap_wait_cycles = OTHER_BLOCKS_WAIT, \
+ .dg_peri_powerup_cycles = OTHER_BLOCKS_POWERUP, \
+ .dg_peri_wait_cycles = OTHER_BLOCKS_WAIT, \
+}
+
+/* Default initializer of struct esp32c3_rtc_config_s.
+ * This initializer sets all fields to "reasonable" values
+ * (e.g. suggested for production use).
+ */
+
+#define RTC_CONFIG_DEFAULT() {\
+ .ck8m_wait = RTC_CNTL_CK8M_WAIT_DEFAULT, \
+ .xtal_wait = RTC_CNTL_XTL_BUF_WAIT_DEFAULT, \
+ .pll_wait = RTC_CNTL_PLL_BUF_WAIT_DEFAULT, \
+ .clkctl_init = 1, \
+ .pwrctl_init = 1, \
+ .rtc_dboost_fpd = 1, \
+ .xtal_fpu = 0, \
+ .bbpll_fpu = 0, \
+ .cpu_waiti_clk_gate = 1, \
+ .cali_ocode = 0\
+}
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This is almost the same as esp32c3_rtc_slow_freq_e, except that we define
+ * an extra enum member for the external 32k oscillator. For convenience,
+ * lower 2 bits should correspond to esp32c3_rtc_slow_freq_e values.
+ */
+
+enum esp32c3_slow_clk_sel_e
+{
+ /* Internal 90 kHz RC oscillator */
+
+ SLOW_CLK_RTC = RTC_SLOW_FREQ_RTC,
+
+ /* External 32 kHz XTAL */
+
+ SLOW_CLK_32K_XTAL = RTC_SLOW_FREQ_32K_XTAL,
+
+ /* Internal 8 MHz RC oscillator, divided by 256 */
+
+ SLOW_CLK_8MD256 = RTC_SLOW_FREQ_8MD256,
+
+ /* External 32k oscillator connected to 32K_XP pin */
+
+ SLOW_CLK_32K_EXT_OSC = RTC_SLOW_FREQ_32K_XTAL | EXT_OSC_FLAG
+};
+
+/* RTC FAST_CLK frequency values */
+
+enum esp32c3_rtc_fast_freq_e
+{
+ RTC_FAST_FREQ_XTALD4 = 0, /* Main XTAL, divided by 4 */
+ RTC_FAST_FREQ_8M = 1, /* Internal 8 MHz RC oscillator */
+};
+
+struct esp32c3_x32k_config_s
+{
+ uint32_t dac : 6;
+ uint32_t dres : 3;
+ uint32_t dgm : 3;
+ uint32_t dbuf: 1;
+};
+
+/* Power down flags for rtc_sleep_pd function */
+
+struct esp32c3_rtc_sleep_pu_config_s
+{
+ uint32_t dig_fpu : 1; /* Set to 1 to power UP digital part in sleep */
+ uint32_t rtc_fpu : 1; /* Set to 1 to power UP RTC memories in sleep */
+ uint32_t cpu_fpu : 1; /* Set to 1 to power UP digital memories and
+ * CPU in sleep
+ */
+ uint32_t i2s_fpu : 1; /* Set to 1 to power UP I2S in sleep */
+ uint32_t bb_fpu : 1; /* Set to 1 to power UP WiFi in sleep */
+ uint32_t nrx_fpu : 1; /* Set to 1 to power UP WiFi in sleep */
+ uint32_t fe_fpu : 1; /* Set to 1 to power UP WiFi in sleep */
+ uint32_t sram_fpu : 1; /* Set to 1 to power UP SRAM in sleep */
+ uint32_t rom_ram_fpu : 1; /* Set to 1 to power UP ROM/IRAM0_DRAM0 in sleep */
+};
+
+struct esp32c3_rtc_init_config_s
+{
+ uint16_t wifi_powerup_cycles : 7;
+ uint16_t wifi_wait_cycles : 9;
+ uint16_t bt_powerup_cycles : 7;
+ uint16_t bt_wait_cycles : 9;
+ uint16_t cpu_top_powerup_cycles : 7;
+ uint16_t cpu_top_wait_cycles : 9;
+ uint16_t dg_wrap_powerup_cycles : 7;
+ uint16_t dg_wrap_wait_cycles : 9;
+ uint16_t dg_peri_powerup_cycles : 7;
+ uint16_t dg_peri_wait_cycles : 9;
+};
+
+/* RTC power and clock control initialization settings */
+
+struct esp32c3_rtc_priv_s
+{
+ uint32_t ck8m_wait : 8; /* Number of rtc_fast_clk cycles to
+ * wait for 8M clock to be ready
+ */
+ uint32_t xtal_wait : 8; /* Number of rtc_fast_clk cycles to
+ * wait for XTAL clock to be ready
+ */
+ uint32_t pll_wait : 8; /* Number of rtc_fast_clk cycles to
+ * wait for PLL to be ready
+ */
+ uint32_t clkctl_init : 1; /* Perform clock control related initialization */
+ uint32_t pwrctl_init : 1; /* Perform power control related initialization */
+ uint32_t rtc_dboost_fpd : 1; /* Force power down RTC_DBOOST */
+ uint32_t xtal_fpu : 1;
+ uint32_t bbpll_fpu : 1;
+ uint32_t cpu_waiti_clk_gate : 1;
+ uint32_t cali_ocode : 1; /* Calibrate Ocode to make bangap voltage more precise. */
+};
+
+/* sleep configuration for rtc_sleep_init function */
+
+struct esp32c3_rtc_sleep_config_s
+{
+ uint32_t lslp_mem_inf_fpu : 1; /* force normal voltage in sleep mode */
+ uint32_t rtc_mem_inf_follow_cpu : 1; /* keep low voltage in sleep mode */
+ uint32_t rtc_fastmem_pd_en : 1; /* power down RTC fast memory */
+ uint32_t rtc_slowmem_pd_en : 1; /* power down RTC slow memory */
+ uint32_t rtc_peri_pd_en : 1; /* power down RTC peripherals */
+ uint32_t wifi_pd_en : 1; /* power down WiFi */
+ uint32_t bt_pd_en : 1; /* power down BT */
+ uint32_t cpu_pd_en : 1; /* power down CPU, but not
+ * restart when lightsleep.
+ */
+ uint32_t dig_peri_pd_en : 1; /* power down digital peripherals */
+ uint32_t deep_slp : 1; /* power down digital domain */
+ uint32_t wdt_flashboot_mod_en : 1; /* enable WDT flashboot mode */
+ uint32_t dig_dbias_wak : 5; /* set bias for digital domain,
+ * in active mode
+ */
+ uint32_t dig_dbias_slp : 5; /* set bias for digital domain,
+ * in sleep mode
+ */
+ uint32_t rtc_dbias_wak : 5; /* set bias for RTC domain, in active mode */
+ uint32_t rtc_dbias_slp : 5; /* set bias for RTC domain, in sleep mode */
+ uint32_t vddsdio_pd_en : 1; /* power down VDDSDIO regulator */
+ uint32_t deep_slp_reject : 1;
+ uint32_t light_slp_reject : 1;
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_sleep_pu(
+ struct esp32c3_rtc_sleep_pu_config_s cfg);
+static inline bool esp32c3_clk_val_is_valid(uint32_t val);
+static uint32_t IRAM_ATTR esp32c3_rtc_clk_cal_internal(
+ enum esp32c3_rtc_cal_sel_e cal_clk, uint32_t slowclk_cycles);
+static void IRAM_ATTR esp32c3_rtc_clk_32k_enable(bool enable);
+static void IRAM_ATTR esp32c3_rtc_clk_8m_enable(
+ bool clk_8m_en, bool d256_en);
+static uint32_t IRAM_ATTR esp32c3_rtc_clk_slow_freq_get_hz(void);
+static void IRAM_ATTR esp32c3_select_rtc_slow_clk(
+ enum esp32c3_slow_clk_sel_e slow_clk);
+static void IRAM_ATTR esp32c3_rtc_clk_fast_freq_set(
+ enum esp32c3_rtc_fast_freq_e fast_freq);
+static uint32_t IRAM_ATTR esp32c3_rtc_sleep_finish(uint32_t
+ lslp_mem_inf_fpu);
+static void IRAM_ATTR esp32c3_rtc_clk_apb_freq_update(uint32_t apb_freq);
+static void IRAM_ATTR esp32c3_wait_dig_dbias_valid(uint64_t rtc_cycles);
+static void IRAM_ATTR esp32c3_rtc_update_to_xtal(int freq, int div);
+static void IRAM_ATTR esp32c3_rtc_clk_bbpll_disable(void);
+static void IRAM_ATTR esp32c3_rtc_clk_set_xtal_wait(void);
+static void IRAM_ATTR esp32c3_rtc_bbpll_configure(
+ enum esp32c3_rtc_xtal_freq_e xtal_freq, int pll_freq);
+static void IRAM_ATTR esp32c3_rtc_clk_cpu_freq_to_8m(void);
+static void IRAM_ATTR esp32c3_rtc_clk_cpu_freq_to_pll_mhz(
+ int cpu_freq_mhz);
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* Pauses execution for us microseconds */
+
+extern void esp_rom_delay_us(uint32_t us);
+
+/* Set the real CPU ticks per us to the ets, so that ets_delay_us
+ * will be accurate. Call this function when CPU frequency is changed.
+ */
+
+extern void ets_update_cpu_frequency(uint32_t ticks_per_us);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_pu
+ *
+ * Description:
+ * Configure whether certain peripherals are powered down in deep sleep.
+ *
+ * Input Parameters:
+ * cfg - power down flags as esp32c3_rtc_sleep_pu_config_s structure
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_sleep_pu(
+ struct esp32c3_rtc_sleep_pu_config_s cfg)
+{
+ REG_SET_FIELD(RTC_CNTL_DIG_PWC_REG,
+ RTC_CNTL_LSLP_MEM_FORCE_PU, cfg.dig_fpu);
+ REG_SET_FIELD(RTC_CNTL_PWC_REG, RTC_CNTL_FASTMEM_FORCE_LPU, cfg.rtc_fpu);
+ REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG,
+ APB_CTRL_DC_MEM_FORCE_PU, cfg.fe_fpu);
+ REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG,
+ APB_CTRL_PBUS_MEM_FORCE_PU, cfg.fe_fpu);
+ REG_SET_FIELD(APB_CTRL_FRONT_END_MEM_PD_REG,
+ APB_CTRL_AGC_MEM_FORCE_PU, cfg.fe_fpu);
+ REG_SET_FIELD(BBPD_CTRL, BB_FFT_FORCE_PU, cfg.bb_fpu);
+ REG_SET_FIELD(BBPD_CTRL, BB_DC_EST_FORCE_PU, cfg.bb_fpu);
+ REG_SET_FIELD(NRXPD_CTRL, NRX_RX_ROT_FORCE_PU, cfg.nrx_fpu);
+ REG_SET_FIELD(NRXPD_CTRL, NRX_VIT_FORCE_PU, cfg.nrx_fpu);
+ REG_SET_FIELD(NRXPD_CTRL, NRX_DEMAP_FORCE_PU, cfg.nrx_fpu);
+ REG_SET_FIELD(FE_GEN_CTRL, FE_IQ_EST_FORCE_PU, cfg.fe_fpu);
+ REG_SET_FIELD(FE2_TX_INTERP_CTRL, FE2_TX_INF_FORCE_PU, cfg.fe_fpu);
+ if (cfg.sram_fpu)
+ {
+ REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG,
+ APB_CTRL_SRAM_POWER_UP, APB_CTRL_SRAM_POWER_UP);
+ }
+ else
+ {
+ REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG,
+ APB_CTRL_SRAM_POWER_UP, 0);
+ }
+
+ if (cfg.rom_ram_fpu)
+ {
+ REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG,
+ APB_CTRL_ROM_POWER_UP, APB_CTRL_ROM_POWER_UP);
+ }
+ else
+ {
+ REG_SET_FIELD(APB_CTRL_MEM_POWER_UP_REG,
+ APB_CTRL_ROM_POWER_UP, 0);
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_fast_freq_set
+ *
+ * Description:
+ * Select source for RTC_FAST_CLK.
+ *
+ * Input Parameters:
+ * fast_freq - Clock source (one of enum esp32c3_rtc_fast_freq_e values)
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_clk_fast_freq_set(
+ enum esp32c3_rtc_fast_freq_e fast_freq)
+{
+ REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG,
+ RTC_CNTL_FAST_CLK_RTC_SEL, fast_freq);
+ esp_rom_delay_us(DELAY_FAST_CLK_SWITCH);
+}
+
+/****************************************************************************
+ * Name: esp32c3_clk_val_is_valid
+ *
+ * Description:
+ * Values of RTC_XTAL_FREQ_REG and RTC_APB_FREQ_REG are
+ * stored as two copies in lower and upper 16-bit halves.
+ * These are the routines to work with such a representation.
+ *
+ * Input Parameters:
+ * val - register value
+ *
+ * Returned Value:
+ * true: Valid register value.
+ * false: Invalid register value.
+ *
+ ****************************************************************************/
+
+static inline bool esp32c3_clk_val_is_valid(uint32_t val)
+{
+ return (val & 0xffff) == ((val >> 16) & 0xffff)
+ && val != 0 && val != UINT32_MAX;
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_cal_internal
+ *
+ * Description:
+ * Clock calibration function used by rtc_clk_cal and rtc_clk_cal_ratio
+ *
+ * Input Parameters:
+ * cal_clk - which clock to calibrate
+ * slowclk_cycles - number of slow clock cycles to count.
+ *
+ * Returned Value:
+ * Number of XTAL clock cycles within the given number of slow clock cycles
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR esp32c3_rtc_clk_cal_internal(
+ enum esp32c3_rtc_cal_sel_e cal_clk, uint32_t slowclk_cycles)
+{
+ uint32_t cal_val;
+ uint32_t expected_freq;
+ uint32_t us_time_estimate;
+ int dig_32k_xtal_state;
+ enum esp32c3_rtc_slow_freq_e slow_freq;
+ if (cal_clk == RTC_CAL_RTC_MUX)
+ {
+ slow_freq = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG,
+ RTC_CNTL_ANA_CLK_RTC_SEL);
+ if (slow_freq == RTC_SLOW_FREQ_32K_XTAL)
+ {
+ cal_clk = RTC_CAL_32K_XTAL;
+ }
+ else if (slow_freq == RTC_SLOW_FREQ_8MD256)
+ {
+ cal_clk = RTC_CAL_8MD256;
+ }
+ }
+
+ /* Enable requested clock (150k clock is always on) */
+
+ dig_32k_xtal_state = REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG,
+ RTC_CNTL_DIG_XTAL32K_EN);
+
+ if (cal_clk == RTC_CAL_32K_XTAL && !dig_32k_xtal_state)
+ {
+ REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN, 1);
+ }
+
+ if (cal_clk == RTC_CAL_8MD256)
+ {
+ modifyreg32(RTC_CNTL_CLK_CONF_REG, 0, RTC_CNTL_DIG_CLK8M_D256_EN);
+ }
+
+ /* Prepare calibration */
+
+ REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_CLK_SEL, cal_clk);
+
+ /* There may be another calibration process already running during we
+ * call this function, so we should wait the last process is done.
+ */
+
+ if ((getreg32(TIMG_RTCCALICFG2_REG(0)) & TIMG_RTC_CALI_TIMEOUT) == 0)
+ {
+ if (getreg32(TIMG_RTCCALICFG_REG(0)) & TIMG_RTC_CALI_START_CYCLING)
+ {
+ while ((getreg32(TIMG_RTCCALICFG_REG(0)) &
+ TIMG_RTC_CALI_RDY) == 0);
+ }
+ }
+
+ modifyreg32(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START_CYCLING, 0);
+ REG_SET_FIELD(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_MAX, slowclk_cycles);
+
+ /* Set timeout reg and expect time delay */
+
+ if (cal_clk == RTC_CAL_32K_XTAL)
+ {
+ REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES,
+ RTC_SLOW_CLK_X32K_CAL_TIMEOUT_THRES(slowclk_cycles));
+ expected_freq = RTC_SLOW_CLK_FREQ_32K;
+ }
+ else if (cal_clk == RTC_CAL_8MD256)
+ {
+ REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES,
+ RTC_SLOW_CLK_8MD256_CAL_TIMEOUT_THRES(slowclk_cycles));
+ expected_freq = RTC_SLOW_CLK_FREQ_8MD256;
+ }
+ else
+ {
+ REG_SET_FIELD(TIMG_RTCCALICFG2_REG(0), TIMG_RTC_CALI_TIMEOUT_THRES,
+ RTC_SLOW_CLK_150K_CAL_TIMEOUT_THRES(slowclk_cycles));
+ expected_freq = RTC_SLOW_CLK_FREQ_90K;
+ }
+
+ us_time_estimate = (uint32_t) (((uint64_t) slowclk_cycles) *
+ MHZ / expected_freq);
+
+ /* Start calibration */
+
+ modifyreg32(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START, 0);
+ modifyreg32(TIMG_RTCCALICFG_REG(0), 0, TIMG_RTC_CALI_START);
+
+ /* Wait for calibration to finish up to another us_time_estimate */
+
+ esp_rom_delay_us(us_time_estimate);
+ while (1)
+ {
+ if (getreg32(TIMG_RTCCALICFG_REG(0)) & TIMG_RTC_CALI_RDY)
+ {
+ cal_val = REG_GET_FIELD(TIMG_RTCCALICFG1_REG(0),
+ TIMG_RTC_CALI_VALUE);
+ break;
+ }
+
+ if (getreg32(TIMG_RTCCALICFG2_REG(0)) & TIMG_RTC_CALI_TIMEOUT)
+ {
+ cal_val = 0;
+ break;
+ }
+ }
+
+ modifyreg32(TIMG_RTCCALICFG_REG(0), TIMG_RTC_CALI_START, 0);
+ REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG,
+ RTC_CNTL_DIG_XTAL32K_EN, dig_32k_xtal_state);
+ if (cal_clk == RTC_CAL_8MD256)
+ {
+ modifyreg32(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_CLK8M_D256_EN, 0);
+ }
+
+ return cal_val;
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_32k_enable
+ *
+ * Description:
+ * Enable or disable 32 kHz XTAL oscillator
+ *
+ * Input Parameters:
+ * enable - true to enable, false to disable
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_clk_32k_enable(bool enable)
+{
+ struct esp32c3_x32k_config_s cfg = X32K_CONFIG_DEFAULT();
+ if (enable)
+ {
+ REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG,
+ RTC_CNTL_DAC_XTAL_32K, cfg.dac);
+ REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG,
+ RTC_CNTL_DRES_XTAL_32K, cfg.dres);
+ REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG,
+ RTC_CNTL_DGM_XTAL_32K, cfg.dgm);
+ REG_SET_FIELD(RTC_CNTL_EXT_XTL_CONF_REG,
+ RTC_CNTL_DBUF_XTAL_32K, cfg.dbuf);
+ modifyreg32(RTC_CNTL_EXT_XTL_CONF_REG, 0,
+ RTC_CNTL_XPD_XTAL_32K);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_EXT_XTL_CONF_REG, RTC_CNTL_XPD_XTAL_32K,
+ RTC_CNTL_XTAL32K_XPD_FORCE);
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_8m_enable
+ *
+ * Description:
+ * Enable or disable 8 MHz internal oscillator
+ *
+ * Input Parameters:
+ * clk_8m_en - true to enable 8MHz generator, false to disable
+ * d256_en - true to enable /256 divider, false to disable
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_clk_8m_enable(bool clk_8m_en, bool d256_en)
+{
+ if (clk_8m_en)
+ {
+ modifyreg32(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M, 0);
+
+ /* no need to wait once enabled by software */
+
+ REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT,
+ RTC_CK8M_ENABLE_WAIT_DEFAULT);
+ esp_rom_delay_us(DELAY_8M_ENABLE);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_CLK_CONF_REG, 0, RTC_CNTL_ENB_CK8M);
+ REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT,
+ RTC_CNTL_CK8M_WAIT_DEFAULT);
+ }
+
+ /* d256 should be independent configured with 8M
+ * Maybe we can split this function into 8m and dmd256
+ */
+
+ if (d256_en)
+ {
+ modifyreg32(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ENB_CK8M_DIV, 0);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_CLK_CONF_REG, 0, RTC_CNTL_ENB_CK8M_DIV);
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_slow_freq_get_hz
+ *
+ * Description:
+ * Get the approximate frequency of RTC_SLOW_CLK, in Hz
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * slow_clk_freq - RTC_SLOW_CLK frequency, in Hz
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR esp32c3_rtc_clk_slow_freq_get_hz(void)
+{
+ enum esp32c3_rtc_slow_freq_e slow_clk_freq =
+ esp32c3_rtc_clk_slow_freq_get();
+ switch (slow_clk_freq)
+ {
+ case RTC_SLOW_FREQ_RTC:
+ return RTC_SLOW_CLK_FREQ_90K;
+
+ case RTC_SLOW_FREQ_32K_XTAL:
+ return RTC_SLOW_CLK_FREQ_32K;
+
+ case RTC_SLOW_FREQ_8MD256:
+ return RTC_SLOW_CLK_FREQ_8MD256;
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: esp32c3_select_rtc_slow_clk
+ *
+ * Description:
+ * Selects an clock source for RTC.
+ *
+ * Input Parameters:
+ * slow_clk - RTC SLOW_CLK frequency values
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_select_rtc_slow_clk(
+ enum esp32c3_slow_clk_sel_e slow_clk)
+{
+ uint32_t cal_val = 0;
+ int retry_32k_xtal = 3;
+ uint64_t cal_dividend;
+ enum esp32c3_rtc_slow_freq_e rtc_slow_freq = slow_clk &
+ RTC_CNTL_ANA_CLK_RTC_SEL_V;
+ do
+ {
+ if (rtc_slow_freq == RTC_SLOW_FREQ_32K_XTAL)
+ {
+ /* 32k XTAL oscillator needs to be enabled and running before
+ * it can be used. Hardware doesn't have a direct way of checking
+ * if the oscillator is running. Here we use rtc_clk_cal function
+ * to count the number of main XTAL cycles in the given number of
+ * 32k XTAL oscillator cycles. If the 32k XTAL has not started up,
+ * calibration will time out, returning 0.
+ */
+
+ if (slow_clk == SLOW_CLK_32K_XTAL ||
+ slow_clk == SLOW_CLK_32K_EXT_OSC)
+ {
+ esp32c3_rtc_clk_32k_enable(true);
+ }
+
+ if (SLOW_CLK_CAL_CYCLES > 0)
+ {
+ cal_val = esp32c3_rtc_clk_cal(RTC_CAL_32K_XTAL,
+ SLOW_CLK_CAL_CYCLES);
+ if (cal_val == 0 || cal_val < MIN_32K_XTAL_CAL_VAL)
+ {
+ if (retry_32k_xtal-- > 0)
+ {
+ continue;
+ }
+
+ rtc_slow_freq = RTC_SLOW_FREQ_RTC;
+ }
+ }
+ }
+ else if (rtc_slow_freq == RTC_SLOW_FREQ_8MD256)
+ {
+ esp32c3_rtc_clk_8m_enable(true, true);
+ }
+
+ esp32c3_rtc_clk_slow_freq_set(rtc_slow_freq);
+ if (SLOW_CLK_CAL_CYCLES > 0)
+ {
+ /* 32k XTAL oscillator has some frequency drift at startup. Improve
+ * calibration routine to wait until the frequency is stable.
+ */
+
+ cal_val = esp32c3_rtc_clk_cal(RTC_CAL_RTC_MUX,
+ SLOW_CLK_CAL_CYCLES);
+ }
+ else
+ {
+ cal_dividend = (1ULL << RTC_CLK_CAL_FRACT) * 1000000ULL;
+ cal_val = (uint32_t) (cal_dividend /
+ esp32c3_rtc_clk_slow_freq_get_hz());
+ }
+ }
+ while (cal_val == 0);
+
+ putreg32((uint32_t)cal_val, RTC_SLOW_CLK_CAL_REG);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_finish
+ *
+ * Description:
+ * Wake up from sleep.
+ *
+ * Input Parameters:
+ * lslp_mem_inf_fpu - If non-zero then the low power config
+ * is restored immediately on wake
+ *
+ * Returned Value:
+ * non-zero if sleep was rejected by hardware
+ *
+ ****************************************************************************/
+
+static uint32_t IRAM_ATTR esp32c3_rtc_sleep_finish(uint32_t lslp_mem_inf_fpu)
+{
+ uint32_t reject;
+ struct esp32c3_rtc_sleep_pu_config_s pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
+
+ /* In deep sleep mode, we never get here */
+
+ reject = REG_GET_FIELD(RTC_CNTL_INT_RAW_REG, RTC_CNTL_SLP_REJECT_INT_RAW);
+ modifyreg32(RTC_CNTL_INT_CLR_REG, 0,
+ RTC_CNTL_SLP_REJECT_INT_CLR | RTC_CNTL_SLP_WAKEUP_INT_CLR);
+
+ /* restore config if it is a light sleep */
+
+ if (lslp_mem_inf_fpu)
+ {
+ esp32c3_rtc_sleep_pu(pu_cfg);
+ }
+
+ return reject;
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_apb_freq_update
+ *
+ * Description:
+ * Store new APB frequency value into RTC_APB_FREQ_REG
+ *
+ * Input Parameters:
+ * apb_freq - New APB frequency, in Hz
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_clk_apb_freq_update(uint32_t apb_freq)
+{
+ uint32_t val = ((apb_freq >> 12) & UINT16_MAX) |
+ (((apb_freq >> 12) & UINT16_MAX) << 16);
+ putreg32(val, RTC_APB_FREQ_REG);
+}
+
+/****************************************************************************
+ * Name: esp32c3_wait_dig_dbias_valid
+ *
+ * Description:
+ * Wait digtial dbias valid
+ *
+ * Input Parameters:
+ * rtc_cycles - RTC count
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_wait_dig_dbias_valid(uint64_t rtc_cycles)
+{
+ enum esp32c3_rtc_slow_freq_e slow_clk_freq =
+ esp32c3_rtc_clk_slow_freq_get();
+ enum esp32c3_rtc_cal_sel_e cal_clk = RTC_CAL_RTC_MUX;
+ if (slow_clk_freq == RTC_SLOW_FREQ_32K_XTAL)
+ {
+ cal_clk = RTC_CAL_32K_XTAL;
+ }
+ else if (slow_clk_freq == RTC_SLOW_FREQ_8MD256)
+ {
+ cal_clk = RTC_CAL_8MD256;
+ }
+
+ esp32c3_rtc_clk_cal(cal_clk, rtc_cycles);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_update_to_xtal
+ *
+ * Description:
+ * Switch to XTAL frequency, does not disable the PLL
+ *
+ * Input Parameters:
+ * freq - XTAL frequency
+ * div - REF_TICK divider
+ *
+ * Returned Value:
+ * none
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_update_to_xtal(int freq, int div)
+{
+ int origin_soc_clk = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG,
+ SYSTEM_SOC_CLK_SEL);
+ int origin_div_cnt = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG,
+ SYSTEM_PRE_DIV_CNT);
+ ets_update_cpu_frequency(freq);
+
+ /* lower the voltage */
+
+ if (freq <= 2)
+ {
+ REGI2C_WRITE_MASK(I2C_DIG_REG,
+ I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_2M);
+ }
+ else
+ {
+ REGI2C_WRITE_MASK(I2C_DIG_REG,
+ I2C_DIG_REG_EXT_DIG_DREG, DIG_DBIAS_XTAL);
+ }
+
+ if ((DPORT_SOC_CLK_SEL_XTAL == origin_soc_clk)
+ && (origin_div_cnt > 0))
+ {
+ esp32c3_wait_dig_dbias_valid(2);
+ }
+
+ /* Set divider from XTAL to APB clock.
+ * Need to set divider to 1 (reg. value 0) first.
+ */
+
+ REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
+ REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, div - 1);
+
+ /* No need to adjust the REF_TICK.
+ * Switch clock source.
+ */
+
+ REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG,
+ SYSTEM_SOC_CLK_SEL, DPORT_SOC_CLK_SEL_XTAL);
+ esp32c3_rtc_clk_apb_freq_update(freq * MHZ);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_bbpll_disable
+ *
+ * Description:
+ * disable BBPLL.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_clk_bbpll_disable(void)
+{
+ modifyreg32(RTC_CNTL_OPTIONS0_REG, 0, RTC_CNTL_BB_I2C_FORCE_PD |
+ RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_set_xtal_wait
+ *
+ * Description:
+ * Set XTAL wait cycles by RTC slow clock's period
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_clk_set_xtal_wait(void)
+{
+ uint32_t slow_clk_period;
+
+ /* the `xtal_wait` time need 1ms, so we need calibrate slow clk period,
+ * and `RTC_CNTL_XTL_BUF_WAIT` depend on it.
+ */
+
+ uint32_t xtal_wait_1ms = 100;
+ enum esp32c3_rtc_slow_freq_e slow_clk_freq =
+ esp32c3_rtc_clk_slow_freq_get();
+ enum esp32c3_rtc_cal_sel_e cal_clk = RTC_CAL_RTC_MUX;
+ if (slow_clk_freq == RTC_SLOW_FREQ_32K_XTAL)
+ {
+ cal_clk = RTC_CAL_32K_XTAL;
+ }
+ else if (slow_clk_freq == RTC_SLOW_FREQ_8MD256)
+ {
+ cal_clk = RTC_CAL_8MD256;
+ }
+
+ slow_clk_period = esp32c3_rtc_clk_cal(cal_clk, 2000);
+ if (slow_clk_period)
+ {
+ xtal_wait_1ms = (1000 << RTC_CLK_CAL_FRACT) / slow_clk_period;
+ }
+
+ REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT, xtal_wait_1ms);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_bbpll_configure
+ *
+ * Description:
+ * Configure main XTAL frequency values according to pll_freq.
+ *
+ * Input Parameters:
+ * xtal_freq - XTAL frequency values
+ * pll_freq - PLL frequency values
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_bbpll_configure(
+ enum esp32c3_rtc_xtal_freq_e xtal_freq, int pll_freq)
+{
+ uint8_t div_ref;
+ uint8_t div7_0;
+ uint8_t dr1;
+ uint8_t dr3;
+ uint8_t dchgp;
+ uint8_t dcur;
+ uint8_t dbias;
+ uint8_t i2c_bbpll_lref;
+ uint8_t i2c_bbpll_div_7_0;
+ uint8_t i2c_bbpll_dcur;
+
+ modifyreg32(I2C_MST_ANA_CONF0_REG,
+ I2C_MST_BBPLL_STOP_FORCE_HIGH, 0);
+ modifyreg32(I2C_MST_ANA_CONF0_REG, 0, I2C_MST_BBPLL_STOP_FORCE_LOW);
+ if (pll_freq == RTC_PLL_FREQ_480M)
+ {
+ /* Set this register to let the digital part know 480M PLL is used */
+
+ modifyreg32(SYSTEM_CPU_PER_CONF_REG, 0, SYSTEM_PLL_FREQ_SEL);
+
+ /* Configure 480M PLL */
+
+ switch (xtal_freq)
+ {
+ case RTC_XTAL_FREQ_40M:
+ {
+ div_ref = 0;
+ div7_0 = 8;
+ dr1 = 0;
+ dr3 = 0;
+ dchgp = 5;
+ dcur = 3;
+ dbias = 2;
+ }
+ break;
+
+ case RTC_XTAL_FREQ_32M:
+ {
+ div_ref = 1;
+ div7_0 = 26;
+ dr1 = 1;
+ dr3 = 1;
+ dchgp = 4;
+ dcur = 0;
+ dbias = 2;
+ }
+ break;
+
+ default:
+ {
+ div_ref = 0;
+ div7_0 = 8;
+ dr1 = 0;
+ dr3 = 0;
+ dchgp = 5;
+ dcur = 3;
+ dbias = 2;
+ }
+ break;
+ }
+
+ REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x6b);
+ }
+ else
+ {
+ /* Clear this register to let the digital part know 320M PLL is used */
+
+ modifyreg32(SYSTEM_CPU_PER_CONF_REG, SYSTEM_PLL_FREQ_SEL, 0);
+
+ /* Configure 320M PLL */
+
+ switch (xtal_freq)
+ {
+ case RTC_XTAL_FREQ_40M:
+ {
+ div_ref = 0;
+ div7_0 = 4;
+ dr1 = 0;
+ dr3 = 0;
+ dchgp = 5;
+ dcur = 3;
+ dbias = 2;
+ }
+ break;
+
+ case RTC_XTAL_FREQ_32M:
+ {
+ div_ref = 1;
+ div7_0 = 6;
+ dr1 = 0;
+ dr3 = 0;
+ dchgp = 5;
+ dcur = 3;
+ dbias = 2;
+ }
+ break;
+
+ default:
+ {
+ div_ref = 0;
+ div7_0 = 4;
+ dr1 = 0;
+ dr3 = 0;
+ dchgp = 5;
+ dcur = 3;
+ dbias = 2;
+ }
+ break;
+ }
+
+ REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_MODE_HF, 0x69);
+ }
+
+ i2c_bbpll_lref = (dchgp << I2C_BBPLL_OC_DCHGP_LSB) | (div_ref);
+ i2c_bbpll_div_7_0 = div7_0;
+ i2c_bbpll_dcur = (2 << I2C_BBPLL_OC_DLREF_SEL_LSB)
+ | (1 << I2C_BBPLL_OC_DHREF_SEL_LSB) | dcur;
+ REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_REF_DIV, i2c_bbpll_lref);
+ REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DIV_7_0, i2c_bbpll_div_7_0);
+ REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR1, dr1);
+ REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_DR3, dr3);
+ REGI2C_WRITE(I2C_BBPLL, I2C_BBPLL_OC_DCUR, i2c_bbpll_dcur);
+ REGI2C_WRITE_MASK(I2C_BBPLL, I2C_BBPLL_OC_VCO_DBIAS, dbias);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_cpu_freq_to_8m
+ *
+ * Description:
+ * Switch CPU frequency to 8 Mhz.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_clk_cpu_freq_to_8m(void)
+{
+ int origin_soc_clk = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG,
+ SYSTEM_SOC_CLK_SEL);
+ int origin_div_cnt = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG,
+ SYSTEM_PRE_DIV_CNT);
+ ets_update_cpu_frequency(8);
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG,
+ DIG_DBIAS_XTAL);
+ if ((DPORT_SOC_CLK_SEL_XTAL == origin_soc_clk)
+ && (origin_div_cnt > 4))
+ {
+ esp32c3_wait_dig_dbias_valid(2);
+ }
+
+ REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
+ REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL,
+ DPORT_SOC_CLK_SEL_8M);
+ esp32c3_rtc_clk_apb_freq_update(RTC_FAST_CLK_FREQ_8M);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_cpu_freq_to_pll_mhz
+ *
+ * Description:
+ * Switch to one of PLL-based frequencies.
+ *
+ * Input Parameters:
+ * cpu_freq_mhz - CPU frequency
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void IRAM_ATTR esp32c3_rtc_clk_cpu_freq_to_pll_mhz(
+ int cpu_freq_mhz)
+{
+ int origin_soc_clk = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG,
+ SYSTEM_SOC_CLK_SEL);
+ int origin_cpuperiod_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG,
+ SYSTEM_CPUPERIOD_SEL);
+ int dbias = DIG_DBIAS_80M;
+ int per_conf = DPORT_CPUPERIOD_SEL_80;
+ if (cpu_freq_mhz == 160)
+ {
+ dbias = DIG_DBIAS_160M;
+ per_conf = DPORT_CPUPERIOD_SEL_160;
+ }
+ else
+ {
+ ASSERT(cpu_freq_mhz != 80);
+ }
+
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, dbias);
+ if ((origin_soc_clk == DPORT_SOC_CLK_SEL_XTAL)
+ || (origin_soc_clk == DPORT_SOC_CLK_SEL_8M)
+ || (((origin_soc_clk == DPORT_SOC_CLK_SEL_PLL)
+ && (0 == origin_cpuperiod_sel))))
+ {
+ esp32c3_wait_dig_dbias_valid(2);
+ }
+
+ REG_SET_FIELD(SYSTEM_CPU_PER_CONF_REG, SYSTEM_CPUPERIOD_SEL, per_conf);
+ REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_PRE_DIV_CNT, 0);
+ REG_SET_FIELD(SYSTEM_SYSCLK_CONF_REG, SYSTEM_SOC_CLK_SEL,
+ DPORT_SOC_CLK_SEL_PLL);
+ esp32c3_rtc_clk_apb_freq_update(80 * MHZ);
+ ets_update_cpu_frequency(cpu_freq_mhz);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_xtal_freq_get
+ *
+ * Description:
+ * Get main XTAL frequency
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * XTAL frequency (one of enum esp32c3_rtc_xtal_freq_e values)
+ *
+ ****************************************************************************/
+
+enum esp32c3_rtc_xtal_freq_e IRAM_ATTR
+ esp32c3_rtc_clk_xtal_freq_get(void)
+{
+ /* We may have already written XTAL value into RTC_XTAL_FREQ_REG */
+
+ uint32_t xtal_freq_reg = getreg32(RTC_XTAL_FREQ_REG);
+ if (!esp32c3_clk_val_is_valid(xtal_freq_reg))
+ {
+ return RTC_XTAL_FREQ_40M;
+ }
+
+ return (xtal_freq_reg & UINT16_MAX);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_slow_freq_set
+ *
+ * Description:
+ * Select source for RTC_SLOW_CLK
+ *
+ * Input Parameters:
+ * slow_freq - clock source (one of esp32c3_rtc_slow_freq_e values)
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp32c3_rtc_clk_slow_freq_set(
+ enum esp32c3_rtc_slow_freq_e slow_freq)
+{
+ REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL, slow_freq);
+
+ /* Why we need to connect this clock to digital? Or maybe this clock
+ * should be connected to digital when xtal 32k clock is enabled instead?
+ */
+
+ REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_DIG_XTAL32K_EN,
+ (slow_freq == RTC_SLOW_FREQ_32K_XTAL) ? 1 : 0);
+
+ /* The clk_8m_d256 will be closed when rtc_state in SLEEP,
+ * so if the slow_clk is 8md256, clk_8m must be force power on
+ */
+
+ REG_SET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU,
+ (slow_freq == RTC_SLOW_FREQ_8MD256) ? 1 : 0);
+ esp32c3_rtc_clk_set_xtal_wait();
+ esp_rom_delay_us(DELAY_SLOW_CLK_SWITCH);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_slow_freq_get
+ *
+ * Description:
+ * Get the RTC_SLOW_CLK source
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Currently selected clock source
+ * (one of enum esp32c3_rtc_slow_freq_e values)
+ *
+ ****************************************************************************/
+
+enum esp32c3_rtc_slow_freq_e IRAM_ATTR esp32c3_rtc_clk_slow_freq_get(void)
+{
+ return REG_GET_FIELD(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_ANA_CLK_RTC_SEL);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_cal
+ *
+ * Description:
+ * Measure RTC slow clock's period, based on main XTAL frequency
+ *
+ * Input Parameters:
+ * cal_clk - clock to be measured
+ * slowclk_cycles - number of slow clock cycles to average
+ *
+ * Returned Value:
+ * Average slow clock period in microseconds, Q13.19 fixed point format
+ * or 0 if calibration has timed out
+ *
+ ****************************************************************************/
+
+uint32_t IRAM_ATTR esp32c3_rtc_clk_cal(enum esp32c3_rtc_cal_sel_e cal_clk,
+ uint32_t slowclk_cycles)
+{
+ enum esp32c3_rtc_xtal_freq_e xtal_freq;
+ uint64_t xtal_cycles;
+ uint64_t divider;
+ uint64_t period_64;
+ uint32_t period;
+
+ xtal_freq = esp32c3_rtc_clk_xtal_freq_get();
+ xtal_cycles = esp32c3_rtc_clk_cal_internal(cal_clk, slowclk_cycles);
+ divider = ((uint64_t)xtal_freq) * slowclk_cycles;
+ period_64 = ((xtal_cycles << RTC_CLK_CAL_FRACT) + divider / 2 - 1)
+ / divider;
+ period = (uint32_t)(period_64 & UINT32_MAX);
+
+ return period;
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_set
+ *
+ * Description:
+ * Set RTC CLK frequency.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_clk_set()
+{
+ esp32c3_rtc_clk_fast_freq_set(RTC_FAST_FREQ_8M);
+ esp32c3_select_rtc_slow_clk(RTC_SLOW_FREQ_RTC);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_init
+ *
+ * Description:
+ * Initialize RTC clock and power control related functions.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp32c3_rtc_init()
+{
+ struct esp32c3_rtc_priv_s cfg = RTC_CONFIG_DEFAULT();
+ struct esp32c3_rtc_init_config_s rtc_init_cfg = RTC_INIT_CONFIG_DEFAULT();
+
+ /* If this pd_cfg is set to 1, all memory won't
+ * enter low power mode during light sleep.
+ * If this pd_cfg is set to 0, all memory will
+ * enter low power mode during light sleep
+ */
+
+ struct esp32c3_rtc_sleep_pu_config_s pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(0);
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0);
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0);
+ modifyreg32(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PVTMON_PU, 0);
+ esp32c3_rtc_clk_set_xtal_wait();
+ REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT, cfg.pll_wait);
+ REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT, cfg.ck8m_wait);
+ REG_SET_FIELD(RTC_CNTL_TIMER5_REG, RTC_CNTL_MIN_SLP_VAL,
+ RTC_CNTL_MIN_SLP_VAL_MIN);
+
+ /* set default powerup & wait time */
+
+ REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_WIFI_POWERUP_TIMER,
+ rtc_init_cfg.wifi_powerup_cycles);
+ REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_WIFI_WAIT_TIMER,
+ rtc_init_cfg.wifi_wait_cycles);
+ REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_BT_POWERUP_TIMER,
+ rtc_init_cfg.bt_powerup_cycles);
+ REG_SET_FIELD(RTC_CNTL_TIMER3_REG, RTC_CNTL_BT_WAIT_TIMER,
+ rtc_init_cfg.bt_wait_cycles);
+ REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_CPU_TOP_POWERUP_TIMER,
+ rtc_init_cfg.cpu_top_powerup_cycles);
+ REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_CPU_TOP_WAIT_TIMER,
+ rtc_init_cfg.cpu_top_wait_cycles);
+ REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_DG_WRAP_POWERUP_TIMER,
+ rtc_init_cfg.dg_wrap_powerup_cycles);
+ REG_SET_FIELD(RTC_CNTL_TIMER4_REG, RTC_CNTL_DG_WRAP_WAIT_TIMER,
+ rtc_init_cfg.dg_wrap_wait_cycles);
+ REG_SET_FIELD(RTC_CNTL_TIMER6_REG, RTC_CNTL_DG_PERI_POWERUP_TIMER,
+ rtc_init_cfg.dg_peri_powerup_cycles);
+ REG_SET_FIELD(RTC_CNTL_TIMER6_REG, RTC_CNTL_DG_PERI_WAIT_TIMER,
+ rtc_init_cfg.dg_peri_wait_cycles);
+
+ /* Reset RTC bias to default value (needed if waking up from deep sleep) */
+
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP,
+ RTC_CNTL_DBIAS_1V10);
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG,
+ RTC_CNTL_DBIAS_1V10);
+ if (cfg.clkctl_init)
+ {
+ /* clear CMMU clock force on */
+
+ modifyreg32(EXTMEM_CACHE_MMU_POWER_CTRL_REG,
+ EXTMEM_CACHE_MMU_MEM_FORCE_ON, 0);
+
+ /* clear tag clock force on */
+
+ modifyreg32(EXTMEM_ICACHE_TAG_POWER_CTRL_REG,
+ EXTMEM_ICACHE_TAG_MEM_FORCE_ON, 0);
+
+ /* clear register clock force on */
+
+ modifyreg32(SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLK_EN, 0);
+ modifyreg32(SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLK_EN, 0);
+ }
+
+ if (cfg.pwrctl_init)
+ {
+ modifyreg32(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_CK8M_FORCE_PU, 0);
+
+ /* cancel xtal force pu if no need to force power up
+ * cannot cancel xtal force pu if pll is force power on
+ */
+
+ if (!(cfg.xtal_fpu | cfg.bbpll_fpu))
+ {
+ modifyreg32(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_XTL_FORCE_PU, 0);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_OPTIONS0_REG, 0, RTC_CNTL_XTL_FORCE_PU);
+ }
+
+ /* force pd APLL */
+
+ modifyreg32(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_PLLA_FORCE_PU, 0);
+ modifyreg32(RTC_CNTL_ANA_CONF_REG, 0, RTC_CNTL_PLLA_FORCE_PD);
+
+ /* open sar_i2c protect function to avoid sar_i2c
+ * reset when rtc_ldo is low.
+ */
+
+ modifyreg32(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_I2C_RESET_POR_FORCE_PD, 0);
+
+ /* cancel bbpll force pu if setting no force power up */
+
+ if (!cfg.bbpll_fpu)
+ {
+ modifyreg32(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BBPLL_FORCE_PU |
+ RTC_CNTL_BBPLL_I2C_FORCE_PU | RTC_CNTL_BB_I2C_FORCE_PU, 0);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_OPTIONS0_REG, 0, RTC_CNTL_BBPLL_FORCE_PU |
+ RTC_CNTL_BBPLL_I2C_FORCE_PU | RTC_CNTL_BB_I2C_FORCE_PU);
+ }
+
+ modifyreg32(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU |
+ RTC_CNTL_DBOOST_FORCE_PU, 0);
+ if (cfg.rtc_dboost_fpd)
+ {
+ modifyreg32(RTC_CNTL_REG, 0, RTC_CNTL_DBOOST_FORCE_PD);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_REG, RTC_CNTL_DBOOST_FORCE_PD, 0);
+ }
+
+ /* If this mask is enabled, all soc memories
+ * cannot enter power down mode.
+ * We should control soc memory power down mode from RTC,
+ * so we will not touch this register any more.
+ */
+
+ modifyreg32(SYSTEM_MEM_PD_MASK_REG, SYSTEM_LSLP_MEM_PD_MASK, 0);
+ esp32c3_rtc_sleep_pu(pu_cfg);
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_FORCE_PU |
+ RTC_CNTL_WIFI_FORCE_PU | RTC_CNTL_BT_FORCE_PU |
+ RTC_CNTL_CPU_TOP_FORCE_PU | RTC_CNTL_DG_PERI_FORCE_PU , 0);
+
+ modifyreg32(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_WRAP_FORCE_NOISO |
+ RTC_CNTL_WIFI_FORCE_NOISO | RTC_CNTL_BT_FORCE_NOISO |
+ RTC_CNTL_CPU_TOP_FORCE_NOISO | RTC_CNTL_DG_PERI_FORCE_NOISO , 0);
+
+ /* cancel digital PADS force no iso */
+
+ if (cfg.cpu_waiti_clk_gate)
+ {
+ modifyreg32(SYSTEM_CPU_PER_CONF_REG,
+ SYSTEM_CPU_WAIT_MODE_FORCE_ON, 0);
+ }
+ else
+ {
+ modifyreg32(SYSTEM_CPU_PER_CONF_REG, 0,
+ SYSTEM_CPU_WAIT_MODE_FORCE_ON);
+ }
+
+ /* if SYSTEM_CPU_WAIT_MODE_FORCE_ON == 0 ,
+ * the cpu clk will be closed when cpu enter WAITI mode.
+ */
+
+ modifyreg32(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD |
+ RTC_CNTL_DG_PAD_FORCE_NOISO, 0);
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_time_get
+ *
+ * Description:
+ * Get current value of RTC counter.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * current value of RTC counter
+ *
+ ****************************************************************************/
+
+uint64_t IRAM_ATTR esp32c3_rtc_time_get(void)
+{
+ uint64_t rtc_time;
+
+ modifyreg32(RTC_CNTL_TIME_UPDATE_REG, 0, RTC_CNTL_TIME_UPDATE);
+ rtc_time = getreg32(RTC_CNTL_TIME0_REG);
+ rtc_time |= ((uint64_t) getreg32(RTC_CNTL_TIME1_REG)) << 32;
+
+ return rtc_time;
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_time_us_to_slowclk
+ *
+ * Description:
+ * Convert time interval from microseconds to RTC_SLOW_CLK cycles.
+ *
+ * Input Parameters:
+ * time_in_us - Time interval in microseconds
+ * slow_clk_period - Period of slow clock in microseconds
+ *
+ * Returned Value:
+ * number of slow clock cycles
+ *
+ ****************************************************************************/
+
+uint64_t IRAM_ATTR esp32c3_rtc_time_us_to_slowclk(uint64_t time_in_us,
+ uint32_t period)
+{
+ /* Overflow will happen in this function if time_in_us >= 2^45,
+ * which is about 400 days. TODO: fix overflow.
+ */
+
+ return (time_in_us << RTC_CLK_CAL_FRACT) / period;
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_time_slowclk_to_us
+ *
+ * Description:
+ * Convert time interval from RTC_SLOW_CLK to microseconds
+ *
+ * Input Parameters:
+ * rtc_cycles - Time interval in RTC_SLOW_CLK cycles
+ * period - Period of slow clock in microseconds
+ *
+ * Returned Value:
+ * time interval in microseconds
+ *
+ ****************************************************************************/
+
+uint64_t IRAM_ATTR esp32c3_rtc_time_slowclk_to_us(uint64_t rtc_cycles,
+ uint32_t period)
+{
+ return (rtc_cycles * period) >> RTC_CLK_CAL_FRACT;
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_cpu_freq_set_xtal
+ *
+ * Description:
+ * Switch CPU clock source to XTAL
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp32c3_rtc_cpu_freq_set_xtal(void)
+{
+ int freq_mhz = (int) esp32c3_rtc_clk_xtal_freq_get();
+ esp32c3_rtc_update_to_xtal(freq_mhz, 1);
+ esp32c3_rtc_clk_bbpll_disable();
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_init
+ *
+ * Description:
+ * Prepare the chip to enter sleep mode
+ *
+ * Input Parameters:
+ * flags - sleep mode configuration
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp32c3_rtc_sleep_init(uint32_t flags)
+{
+ struct esp32c3_rtc_sleep_config_s cfg = RTC_SLEEP_CONFIG_DEFAULT(flags);
+ struct esp32c3_rtc_sleep_pu_config_s pu_cfg = RTC_SLEEP_PU_CONFIG_ALL(1);
+ if (cfg.lslp_mem_inf_fpu)
+ {
+ esp32c3_rtc_sleep_pu(pu_cfg);
+ }
+
+ if (cfg.wifi_pd_en)
+ {
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, 0, RTC_CNTL_WIFI_PD_EN);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_WIFI_PD_EN, 0);
+ }
+
+ if (cfg.bt_pd_en)
+ {
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, 0, RTC_CNTL_BT_PD_EN);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_BT_PD_EN, 0);
+ }
+
+ if (cfg.cpu_pd_en)
+ {
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, 0, RTC_CNTL_CPU_TOP_PD_EN);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_CPU_TOP_PD_EN, 0);
+ }
+
+ if (cfg.dig_peri_pd_en)
+ {
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, 0, RTC_CNTL_DG_PERI_PD_EN);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_PERI_PD_EN, 0);
+ }
+
+ REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_MONITOR,
+ RTC_CNTL_DBG_ATTEN_MONITOR_DEFAULT);
+ REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_MONITOR,
+ RTC_CNTL_BIASSLP_MONITOR_DEFAULT);
+ REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_BIAS_SLEEP_DEEP_SLP,
+ RTC_CNTL_BIASSLP_SLEEP_DEFAULT);
+ REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_MONITOR,
+ RTC_CNTL_PD_CUR_MONITOR_DEFAULT);
+ REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_PD_CUR_DEEP_SLP,
+ RTC_CNTL_PD_CUR_SLEEP_DEFAULT);
+ if (cfg.deep_slp)
+ {
+ REGI2C_WRITE_MASK(I2C_ULP, I2C_ULP_IR_FORCE_XPD_CK, 0);
+ modifyreg32(RTC_CNTL_REG, RTC_CNTL_REGULATOR_FORCE_PU, 0);
+
+ /* It's only a temporary configuration to set dbg 0 to make
+ * deepsleep run successfully when in high temperature.
+ * We will restore it to RTC_CNTL_DBG_ATTEN_DEEPSLEEP_DEFAULT
+ * when ECO chip come back. TODO ESP32-C3 IDF-2568
+ */
+
+ REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP, 0);
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, 0, RTC_CNTL_DG_WRAP_PD_EN);
+ modifyreg32(RTC_CNTL_ANA_CONF_REG, RTC_CNTL_CKGEN_I2C_PU |
+ RTC_CNTL_PLL_I2C_PU | RTC_CNTL_RFRX_PBUS_PU | RTC_CNTL_TXRF_I2C_PU, 0);
+ }
+ else
+ {
+ modifyreg32(RTC_CNTL_BIAS_CONF_REG, 0, RTC_CNTL_DG_VDD_DRV_B_SLP_EN);
+ REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DG_VDD_DRV_B_SLP,
+ RTC_CNTL_DG_VDD_DRV_B_SLP_DEFAULT);
+ modifyreg32(RTC_CNTL_REG, 0, RTC_CNTL_REGULATOR_FORCE_PU);
+ modifyreg32(RTC_CNTL_DIG_PWC_REG, RTC_CNTL_DG_WRAP_PD_EN, 0);
+ REG_SET_FIELD(RTC_CNTL_BIAS_CONF_REG, RTC_CNTL_DBG_ATTEN_DEEP_SLP,
+ RTC_CNTL_DBG_ATTEN_LIGHTSLEEP_DEFAULT);
+ }
+
+ /* enable VDDSDIO control by state machine */
+
+ REG_CLR_BIT(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_FORCE);
+ REG_SET_FIELD(RTC_CNTL_SDIO_CONF_REG, RTC_CNTL_SDIO_PD_EN,
+ cfg.vddsdio_pd_en);
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG_SLEEP,
+ cfg.rtc_dbias_slp);
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG,
+ cfg.rtc_dbias_wak);
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG_SLEEP,
+ cfg.dig_dbias_slp);
+ REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG,
+ cfg.dig_dbias_wak);
+ REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_DEEP_SLP_REJECT_EN,
+ cfg.deep_slp_reject);
+ REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG, RTC_CNTL_LIGHT_SLP_REJECT_EN,
+ cfg.light_slp_reject);
+
+ /* gating XTAL clock */
+
+ REG_CLR_BIT(RTC_CNTL_CLK_CONF_REG, RTC_CNTL_XTAL_GLOBAL_FORCE_NOGATING);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_deep_sleep_start
+ *
+ * Description:
+ * Enter deep sleep mode.
+ *
+ * Input Parameters:
+ * wakeup_opt - bit mask wake up reasons to enable
+ * reject_opt - bit mask of sleep reject reasons.
+ *
+ * Returned Value:
+ * non-zero if sleep was rejected by hardware
+ *
+ ****************************************************************************/
+
+uint32_t IRAM_ATTR esp32c3_rtc_deep_sleep_start(uint32_t wakeup_opt,
+ uint32_t reject_opt)
+{
+ /* Values used to set the SYSTEM_RTC_FASTMEM_CONFIG_REG value */
+
+ const unsigned CRC_START_ADDR = 0;
+ const unsigned CRC_LEN = 0x7ff;
+
+ REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
+ putreg32(reject_opt, RTC_CNTL_SLP_REJECT_CONF_REG);
+
+ /* Calculate RTC Fast Memory CRC (for wake stub) & go to deep sleep
+ * Because we may be running from RTC memory as stack, we can't easily
+ * call any functions to do this (as registers will spill to stack,
+ * corrupting the CRC). Instead, load all the values we need into registers
+ * then use register ops only to calculate the CRC value, write it to the
+ * RTC CRC value register, and immediately go into deep sleep.
+ */
+
+ asm volatile(
+
+ /* Start CRC calculation */
+
+ "sw %1, 0(%0)\n"
+ "or t0, %1, %2\n"
+ "sw t0, 0(%0)\n"
+
+ /* Wait for the CRC calculation to finish */
+
+ ".Lwaitcrc:\n"
+ "fence\n"
+ "lw t0, 0(%0)\n"
+ "li t1, "STR(SYSTEM_RTC_MEM_CRC_FINISH)"\n"
+ "and t0, t0, t1\n"
+ "beqz t0, .Lwaitcrc\n"
+ "not %2, %2\n"
+ "and t0, t0, %2\n"
+ "sw t0, 0(%0)\n"
+ "fence\n"
+ "not %2, %2\n"
+
+ /* Store the calculated value in RTC_MEM_CRC_REG */
+
+ "lw t0, 0(%3)\n"
+ "sw t0, 0(%4)\n"
+ "fence\n"
+
+ /* Set register bit to go into deep sleep */
+
+ "lw t0, 0(%5)\n"
+ "or t0, t0, %6\n"
+ "sw t0, 0(%5)\n"
+ "fence\n"
+
+ /* Wait for sleep reject interrupt (never finishes if successful) */
+
+ ".Lwaitsleep:"
+ "fence\n"
+ "lw t0, 0(%7)\n"
+ "and t0, t0, %8\n"
+ "beqz t0, .Lwaitsleep\n"
+
+ :
+ :
+ "r" (SYSTEM_RTC_FASTMEM_CONFIG_REG),
+ "r" ((CRC_START_ADDR << SYSTEM_RTC_MEM_CRC_START_S)
+ | (CRC_LEN << SYSTEM_RTC_MEM_CRC_LEN_S)),
+ "r" (SYSTEM_RTC_MEM_CRC_START),
+ "r" (SYSTEM_RTC_FASTMEM_CRC_REG),
+ "r" (RTC_MEMORY_CRC_REG),
+ "r" (RTC_CNTL_STATE0_REG),
+ "r" (RTC_CNTL_SLEEP_EN),
+ "r" (RTC_CNTL_INT_RAW_REG),
+ "r" (RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW)
+ : "t0", "t1"
+ );
+
+ return esp32c3_rtc_sleep_finish(0);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_start
+ *
+ * Description:
+ * Enter force sleep mode.
+ *
+ * Input Parameters:
+ * wakeup_opt - bit mask wake up reasons to enable
+ * reject_opt - bit mask of sleep reject reasons.
+ *
+ * Returned Value:
+ * non-zero if sleep was rejected by hardware
+ *
+ ****************************************************************************/
+
+uint32_t IRAM_ATTR esp32c3_rtc_sleep_start(uint32_t wakeup_opt,
+ uint32_t reject_opt, uint32_t lslp_mem_inf_fpu)
+{
+ REG_SET_FIELD(RTC_CNTL_WAKEUP_STATE_REG, RTC_CNTL_WAKEUP_ENA, wakeup_opt);
+ REG_SET_FIELD(RTC_CNTL_SLP_REJECT_CONF_REG,
+ RTC_CNTL_SLEEP_REJECT_ENA, reject_opt);
+
+ /* Start entry into sleep mode */
+
+ modifyreg32(RTC_CNTL_STATE0_REG, 0, RTC_CNTL_SLEEP_EN);
+
+ while ((getreg32(RTC_CNTL_INT_RAW_REG) &
+ (RTC_CNTL_SLP_REJECT_INT_RAW | RTC_CNTL_SLP_WAKEUP_INT_RAW)) == 0);
+
+ return esp32c3_rtc_sleep_finish(lslp_mem_inf_fpu);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_cpu_freq_set_config
+ *
+ * Description:
+ * Set CPU frequency configuration.
+ *
+ * Input Parameters:
+ * config - CPU frequency configuration
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp32c3_rtc_clk_cpu_freq_set_config(
+ const struct esp32c3_cpu_freq_config_s *config)
+{
+ uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG,
+ SYSTEM_SOC_CLK_SEL);
+ if (config->source == RTC_CPU_FREQ_SRC_XTAL)
+ {
+ esp32c3_rtc_update_to_xtal(config->freq_mhz, config->div);
+ if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL)
+ {
+ esp32c3_rtc_clk_bbpll_disable();
+ }
+ }
+ else if (config->source == RTC_CPU_FREQ_SRC_PLL)
+ {
+ if (soc_clk_sel != DPORT_SOC_CLK_SEL_PLL)
+ {
+ modifyreg32(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BB_I2C_FORCE_PD |
+ RTC_CNTL_BBPLL_FORCE_PD | RTC_CNTL_BBPLL_I2C_FORCE_PD, 0);
+ esp32c3_rtc_bbpll_configure(esp32c3_rtc_clk_xtal_freq_get(),
+ config->source_freq_mhz);
+ }
+
+ esp32c3_rtc_clk_cpu_freq_to_pll_mhz(config->freq_mhz);
+ }
+ else if (config->source == RTC_CPU_FREQ_SRC_8M)
+ {
+ esp32c3_rtc_clk_cpu_freq_to_8m();
+ if (soc_clk_sel == DPORT_SOC_CLK_SEL_PLL)
+ {
+ esp32c3_rtc_clk_bbpll_disable();
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_low_init
+ *
+ * Description:
+ * Low level initialize for rtc state machine waiting
+ * cycles after waking up.
+ *
+ * Input Parameters:
+ * slowclk_period - Re-calibrated slow clock period
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp32c3_rtc_sleep_low_init(uint32_t slowclk_period)
+{
+ /* Set 5 PWC state machine times to fit in main state machine time */
+
+ REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_PLL_BUF_WAIT,
+ RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES);
+ REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_XTL_BUF_WAIT,
+ esp32c3_rtc_time_us_to_slowclk(
+ RTC_CNTL_XTL_BUF_WAIT_SLP_US, slowclk_period));
+ REG_SET_FIELD(RTC_CNTL_TIMER1_REG, RTC_CNTL_CK8M_WAIT,
+ RTC_CNTL_CK8M_WAIT_SLP_CYCLES);
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_cpu_freq_get_config
+ *
+ * Description:
+ * Get the currently used CPU frequency configuration.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * CPU clock configuration structure
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp32c3_rtc_clk_cpu_freq_get_config(
+ struct esp32c3_cpu_freq_config_s *out_config)
+{
+ uint32_t div = 3;
+ uint32_t freq_mhz = 160;
+ uint32_t source_freq_mhz = RTC_PLL_FREQ_480M;
+ enum esp32c3_rtc_cpu_freq_src_e source = RTC_CPU_FREQ_SRC_PLL;
+ uint32_t soc_clk_sel = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG,
+ SYSTEM_SOC_CLK_SEL);
+ switch (soc_clk_sel)
+ {
+ case DPORT_SOC_CLK_SEL_XTAL:
+ {
+ source = RTC_CPU_FREQ_SRC_XTAL;
+ div = REG_GET_FIELD(SYSTEM_SYSCLK_CONF_REG,
+ SYSTEM_PRE_DIV_CNT) + 1;
+ source_freq_mhz = (uint32_t) esp32c3_rtc_clk_xtal_freq_get();
+ freq_mhz = source_freq_mhz / div;
+ }
+ break;
+
+ case DPORT_SOC_CLK_SEL_PLL:
+ {
+ uint32_t cpuperiod_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG,
+ SYSTEM_CPUPERIOD_SEL);
+ uint32_t pllfreq_sel = REG_GET_FIELD(SYSTEM_CPU_PER_CONF_REG,
+ SYSTEM_PLL_FREQ_SEL);
+ source = RTC_CPU_FREQ_SRC_PLL;
+ source_freq_mhz = (pllfreq_sel) ?
+ RTC_PLL_FREQ_480M : RTC_PLL_FREQ_320M;
+ if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_80)
+ {
+ div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 6 : 4;
+ freq_mhz = 80;
+ }
+ else if (cpuperiod_sel == DPORT_CPUPERIOD_SEL_160)
+ {
+ div = (source_freq_mhz == RTC_PLL_FREQ_480M) ? 3 : 2;
+ div = 3;
+ freq_mhz = 160;
+ }
+ else
+ {
+ ASSERT(0);
+ }
+ }
+ break;
+
+ case DPORT_SOC_CLK_SEL_8M:
+ {
+ source = RTC_CPU_FREQ_SRC_8M;
+ source_freq_mhz = 8;
+ div = 1;
+ freq_mhz = source_freq_mhz;
+ }
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ *out_config = (struct esp32c3_cpu_freq_config_s)
+ {
+ .source = source,
+ .source_freq_mhz = source_freq_mhz,
+ .div = div,
+ .freq_mhz = freq_mhz
+ };
+}
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_set_wakeup_time
+ *
+ * Description:
+ * Set target value of RTC counter for RTC_TIMER_TRIG_EN wakeup source.
+ *
+ * Input Parameters:
+ * t - value of RTC counter at which wakeup from sleep will happen.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void IRAM_ATTR esp32c3_rtc_sleep_set_wakeup_time(uint64_t t)
+{
+ putreg32(t & UINT32_MAX, RTC_CNTL_SLP_TIMER0_REG);
+ putreg32((uint32_t)(t >> 32), RTC_CNTL_SLP_TIMER1_REG);
+ modifyreg32(RTC_CNTL_INT_CLR_REG, 0, RTC_CNTL_MAIN_TIMER_INT_CLR_M);
+ modifyreg32(RTC_CNTL_SLP_TIMER1_REG, 0, RTC_CNTL_MAIN_TIMER_ALARM_EN_M);
+}
diff --git a/arch/risc-v/src/esp32c3/esp32c3_rtc.h b/arch/risc-v/src/esp32c3/esp32c3_rtc.h
new file mode 100644
index 0000000..ab5fdec
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/esp32c3_rtc.h
@@ -0,0 +1,437 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/esp32c3_rtc.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.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#ifndef __ARCH_RISCV_SRC_ESP32C3_ESP32C3_RTC_H
+#define __ARCH_RISCV_SRC_ESP32C3_ESP32C3_RTC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include "hardware/esp32c3_soc.h"
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Cycles for RTC Timer clock source (internal oscillator) calibrate */
+
+#define RTC_CLK_SRC_CAL_CYCLES (10)
+
+/* Various delays to be programmed into power control state machines */
+
+#define RTC_CNTL_XTL_BUF_WAIT_SLP_US (250)
+#define RTC_CNTL_PLL_BUF_WAIT_SLP_CYCLES (1)
+#define RTC_CNTL_CK8M_WAIT_SLP_CYCLES (4)
+#define RTC_CNTL_WAKEUP_DELAY_CYCLES (5)
+
+#define RTC_SLOW_CLK_CAL_REG RTC_CNTL_STORE1_REG
+#define RTC_BOOT_TIME_LOW_REG RTC_CNTL_STORE2_REG
+#define RTC_BOOT_TIME_HIGH_REG RTC_CNTL_STORE3_REG
+#define RTC_XTAL_FREQ_REG RTC_CNTL_STORE4_REG
+#define RTC_APB_FREQ_REG RTC_CNTL_STORE5_REG
+#define RTC_ENTRY_ADDR_REG RTC_CNTL_STORE6_REG
+#define RTC_RESET_CAUSE_REG RTC_CNTL_STORE6_REG
+#define RTC_MEMORY_CRC_REG RTC_CNTL_STORE7_REG
+
+#define RTC_SLEEP_PD_DIG BIT(0) /* Deep sleep */
+#define RTC_SLEEP_PD_RTC_PERIPH BIT(1) /* Power down RTC peripherals */
+#define RTC_SLEEP_PD_RTC_SLOW_MEM BIT(2) /* Power down RTC SLOW memory */
+#define RTC_SLEEP_PD_RTC_FAST_MEM BIT(3) /* Power down RTC FAST memory */
+
+/* RTC FAST and SLOW memories are automatically
+ * powered up and down along with the CPU
+ */
+
+#define RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU BIT(4)
+#define RTC_SLEEP_PD_VDDSDIO BIT(5) /* Power down VDDSDIO regulator */
+#define RTC_SLEEP_PD_WIFI BIT(6) /* Power down Wi-Fi */
+#define RTC_SLEEP_PD_BT BIT(7) /* Power down BT */
+#define RTC_SLEEP_PD_CPU BIT(8) /* Power down CPU when in light-sleep */
+#define RTC_SLEEP_PD_DIG_PERIPH BIT(9) /* Power down DIG peripherals */
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* Clock source to be calibrated using rtc_clk_cal function */
+
+enum esp32c3_rtc_cal_sel_e
+{
+ RTC_CAL_RTC_MUX = 0, /* Currently selected RTC SLOW_CLK */
+ RTC_CAL_8MD256 = 1, /* Internal 8 MHz RC oscillator, divided by 256 */
+ RTC_CAL_32K_XTAL = 2 /* External 32 kHz XTAL */
+};
+
+/* CPU clock source */
+
+enum esp32c3_rtc_cpu_freq_src_e
+{
+ RTC_CPU_FREQ_SRC_XTAL, /* XTAL */
+ RTC_CPU_FREQ_SRC_PLL, /* PLL (480M or 320M) */
+ RTC_CPU_FREQ_SRC_8M, /* Internal 8M RTC oscillator */
+ RTC_CPU_FREQ_SRC_APLL /* APLL */
+};
+
+/* Possible main XTAL frequency values.
+ * Enum values should be equal to frequency in MHz.
+ */
+
+enum esp32c3_rtc_xtal_freq_e
+{
+ RTC_XTAL_FREQ_32M = 32,
+ RTC_XTAL_FREQ_40M = 40,
+};
+
+/* RTC SLOW_CLK frequency values */
+
+enum esp32c3_rtc_slow_freq_e
+{
+ RTC_SLOW_FREQ_RTC = 0, /* Internal 150 kHz RC oscillator */
+ RTC_SLOW_FREQ_32K_XTAL = 1, /* External 32 kHz XTAL */
+ RTC_SLOW_FREQ_8MD256 = 2, /* Internal 8 MHz RC oscillator, divided by 256 */
+};
+
+/* CPU clock configuration structure */
+
+struct esp32c3_cpu_freq_config_s
+{
+ /* The clock from which CPU clock is derived */
+
+ enum esp32c3_rtc_cpu_freq_src_e source;
+ uint32_t source_freq_mhz; /* Source clock frequency */
+ uint32_t div; /* Divider, freq_mhz = source_freq_mhz / div */
+ uint32_t freq_mhz; /* CPU clock frequency */
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_xtal_freq_get
+ *
+ * Description:
+ * Get main XTAL frequency
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * XTAL frequency (one of enum esp32c3_rtc_xtal_freq_e values)
+ *
+ ****************************************************************************/
+
+enum esp32c3_rtc_xtal_freq_e esp32c3_rtc_clk_xtal_freq_get(void);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_slow_freq_get
+ *
+ * Description:
+ * Get the RTC_SLOW_CLK source
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * Currently selected clock source
+ * (one of enum esp32c3_rtc_slow_freq_e values)
+ *
+ ****************************************************************************/
+
+enum esp32c3_rtc_slow_freq_e esp32c3_rtc_clk_slow_freq_get(void);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_slow_freq_set
+ *
+ * Description:
+ * Select source for RTC_SLOW_CLK
+ *
+ * Input Parameters:
+ * slow_freq - clock source (one of esp32c3_rtc_slow_freq_e values)
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_clk_slow_freq_set(enum esp32c3_rtc_slow_freq_e slow_freq);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_set
+ *
+ * Description:
+ * Set RTC CLK frequency.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_clk_set(void);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_init
+ *
+ * Description:
+ * Initialize RTC clock and power control related functions.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_init(void);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_time_get
+ *
+ * Description:
+ * Get current value of RTC counter.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * current value of RTC counter
+ *
+ ****************************************************************************/
+
+uint64_t esp32c3_rtc_time_get(void);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_time_us_to_slowclk
+ *
+ * Description:
+ * Convert time interval from microseconds to RTC_SLOW_CLK cycles.
+ *
+ * Input Parameters:
+ * time_in_us - Time interval in microseconds
+ * slow_clk_period - Period of slow clock in microseconds
+ *
+ * Returned Value:
+ * number of slow clock cycles
+ *
+ ****************************************************************************/
+
+uint64_t esp32c3_rtc_time_us_to_slowclk(uint64_t time_in_us,
+ uint32_t period);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_cpu_freq_set_xtal
+ *
+ * Description:
+ * Switch CPU clock source to XTAL
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_cpu_freq_set_xtal(void);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_init
+ *
+ * Description:
+ * Prepare the chip to enter sleep mode
+ *
+ * Input Parameters:
+ * flags - sleep mode configuration
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_sleep_init(uint32_t flags);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_start
+ *
+ * Description:
+ * Enter force sleep mode.
+ *
+ * Input Parameters:
+ * wakeup_opt - bit mask wake up reasons to enable
+ * reject_opt - bit mask of sleep reject reasons.
+ *
+ * Returned Value:
+ * non-zero if sleep was rejected by hardware
+ *
+ ****************************************************************************/
+
+uint32_t esp32c3_rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt,
+ uint32_t lslp_mem_inf_fpu);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_cal
+ *
+ * Description:
+ * Measure RTC slow clock's period, based on main XTAL frequency
+ *
+ * Input Parameters:
+ * cal_clk - clock to be measured
+ * slowclk_cycles - number of slow clock cycles to average
+ *
+ * Returned Value:
+ * Average slow clock period in microseconds, Q13.19 fixed point format
+ * or 0 if calibration has timed out
+ *
+ ****************************************************************************/
+
+uint32_t esp32c3_rtc_clk_cal(enum esp32c3_rtc_cal_sel_e cal_clk,
+ uint32_t slowclk_cycles);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_time_slowclk_to_us
+ *
+ * Description:
+ * Convert time interval from RTC_SLOW_CLK to microseconds
+ *
+ * Input Parameters:
+ * rtc_cycles - Time interval in RTC_SLOW_CLK cycles
+ * period - Period of slow clock in microseconds
+ *
+ * Returned Value:
+ * time interval in microseconds
+ *
+ ****************************************************************************/
+
+uint64_t esp32c3_rtc_time_slowclk_to_us(uint64_t rtc_cycles,
+ uint32_t period);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_deep_sleep_start
+ *
+ * Description:
+ * Enter deep sleep mode.
+ *
+ * Input Parameters:
+ * wakeup_opt - bit mask wake up reasons to enable
+ * reject_opt - bit mask of sleep reject reasons.
+ *
+ * Returned Value:
+ * non-zero if sleep was rejected by hardware
+ *
+ ****************************************************************************/
+
+uint32_t esp32c3_rtc_deep_sleep_start(uint32_t wakeup_opt,
+ uint32_t reject_opt);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_cpu_freq_set_config
+ *
+ * Description:
+ * Set CPU frequency configuration.
+ *
+ * Input Parameters:
+ * config - CPU frequency configuration
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_clk_cpu_freq_set_config(
+ const struct esp32c3_cpu_freq_config_s *config);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_low_init
+ *
+ * Description:
+ * Low level initialize for rtc state machine waiting
+ * cycles after waking up.
+ *
+ * Input Parameters:
+ * slowclk_period - Re-calibrated slow clock period
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_sleep_low_init(uint32_t slowclk_period);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_clk_cpu_freq_get_config
+ *
+ * Description:
+ * Get the currently used CPU frequency configuration.
+ *
+ * Input Parameters:
+ * None
+ *
+ * Returned Value:
+ * CPU clock configuration structure
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_clk_cpu_freq_get_config(
+ struct esp32c3_cpu_freq_config_s *out_config);
+
+/****************************************************************************
+ * Name: esp32c3_rtc_sleep_set_wakeup_time
+ *
+ * Description:
+ * Set target value of RTC counter for RTC_TIMER_TRIG_EN wakeup source.
+ *
+ * Input Parameters:
+ * t - value of RTC counter at which wakeup from sleep will happen.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void esp32c3_rtc_sleep_set_wakeup_time(uint64_t t);
+
+#ifdef __cplusplus
+}
+#endif
+#undef EXTERN
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_RISCV_SRC_ESP32C3_ESP32C3_RTC_H */
diff --git a/arch/risc-v/src/esp32c3/hardware/apb_ctrl_reg.h b/arch/risc-v/src/esp32c3/hardware/apb_ctrl_reg.h
new file mode 100644
index 0000000..1800a5c
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/apb_ctrl_reg.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/apb_ctrl_reg.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_RISCV_SRC_ESP32C3_HARDWARE_APB_CTRL_REG_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_APB_CTRL_REG_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32c3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define APB_CTRL_FRONT_END_MEM_PD_REG (DR_REG_APB_CTRL_BASE + 0x09C)
+
+#define APB_CTRL_MEM_POWER_UP_REG (DR_REG_APB_CTRL_BASE + 0x0AC)
+
+/* APB_CTRL_DC_MEM_FORCE_PU : R/W ;bitpos:[4] ;default: 1'b1 ; */
+
+#define APB_CTRL_DC_MEM_FORCE_PU (BIT(4))
+#define APB_CTRL_DC_MEM_FORCE_PU_M (BIT(4))
+#define APB_CTRL_DC_MEM_FORCE_PU_V 0x1
+#define APB_CTRL_DC_MEM_FORCE_PU_S 4
+
+/* APB_CTRL_PBUS_MEM_FORCE_PU : R/W ;bitpos:[2] ;default: 1'b1 ; */
+
+#define APB_CTRL_PBUS_MEM_FORCE_PU (BIT(2))
+#define APB_CTRL_PBUS_MEM_FORCE_PU_M (BIT(2))
+#define APB_CTRL_PBUS_MEM_FORCE_PU_V 0x1
+#define APB_CTRL_PBUS_MEM_FORCE_PU_S 2
+
+/* APB_CTRL_AGC_MEM_FORCE_PU : R/W ;bitpos:[0] ;default: 1'b1 ; */
+
+#define APB_CTRL_AGC_MEM_FORCE_PU (BIT(0))
+#define APB_CTRL_AGC_MEM_FORCE_PU_M (BIT(0))
+#define APB_CTRL_AGC_MEM_FORCE_PU_V 0x1
+#define APB_CTRL_AGC_MEM_FORCE_PU_S 0
+
+/* APB_CTRL_SRAM_POWER_UP : R/W ;bitpos:[5:2] ;default: ~4'b0 ; */
+
+#define APB_CTRL_SRAM_POWER_UP 0x0000000F
+#define APB_CTRL_SRAM_POWER_UP_M ((APB_CTRL_SRAM_POWER_UP_V)<<(APB_CTRL_SRAM_POWER_UP_S))
+#define APB_CTRL_SRAM_POWER_UP_V 0xF
+#define APB_CTRL_SRAM_POWER_UP_S 2
+
+/* APB_CTRL_ROM_POWER_UP : R/W ;bitpos:[1:0] ;default: ~2'b0 ; */
+
+#define APB_CTRL_ROM_POWER_UP 0x00000003
+#define APB_CTRL_ROM_POWER_UP_M ((APB_CTRL_ROM_POWER_UP_V)<<(APB_CTRL_ROM_POWER_UP_S))
+#define APB_CTRL_ROM_POWER_UP_V 0x3
+#define APB_CTRL_ROM_POWER_UP_S 0
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_APB_CTRL_REG_H_ */
diff --git a/arch/risc-v/src/esp32c3/hardware/bb_reg.h b/arch/risc-v/src/esp32c3/hardware/bb_reg.h
new file mode 100644
index 0000000..262814e
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/bb_reg.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/bb_reg.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_RISCV_SRC_ESP32C3_HARDWARE_BB_REG_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_BB_REG_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32c3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Some of the baseband control registers.
+ * PU/PD fields defined here are used in sleep related functions.
+ */
+
+#define BBPD_CTRL (DR_REG_BB_BASE + 0x0054)
+#define BB_FFT_FORCE_PU (BIT(3))
+#define BB_FFT_FORCE_PU_M (BIT(3))
+#define BB_FFT_FORCE_PU_V 1
+#define BB_FFT_FORCE_PU_S 3
+
+#define BB_DC_EST_FORCE_PU (BIT(1))
+#define BB_DC_EST_FORCE_PU_M (BIT(1))
+#define BB_DC_EST_FORCE_PU_V 1
+#define BB_DC_EST_FORCE_PU_S 1
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_BB_REG_H_ */
diff --git a/arch/risc-v/src/esp32c3/hardware/esp32c3_soc.h b/arch/risc-v/src/esp32c3/hardware/esp32c3_soc.h
index efb5bf3..9e1ba5b 100644
--- a/arch/risc-v/src/esp32c3/hardware/esp32c3_soc.h
+++ b/arch/risc-v/src/esp32c3/hardware/esp32c3_soc.h
@@ -264,5 +264,43 @@
/* Helper to place a value in a field */
#define VALUE_TO_FIELD(_value, _field) (((_value) << (_field##_S)) & (_field##_M))
+#define DPORT_CPUPERIOD_SEL_80 0
+#define DPORT_CPUPERIOD_SEL_160 1
+
+#define DPORT_SOC_CLK_SEL_XTAL 0
+#define DPORT_SOC_CLK_SEL_PLL 1
+#define DPORT_SOC_CLK_SEL_8M 2
+
+/* Write value to register */
+
+#define REG_WRITE(_r, _v) (*(volatile uint32_t *)(_r)) = (_v)
+
+/* Read value from register */
+
+#define REG_READ(_r) (*(volatile uint32_t *)(_r))
+
+/* Get bit or get bits from register */
+
+#define REG_GET_BIT(_r, _b) (*(volatile uint32_t*)(_r) & (_b))
+
+/* Set bit or set bits to register */
+
+#define REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b))
+
+/* Clear bit or clear bits of register */
+
+#define REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b))
+
+/* Get field from register,
+ * used when _f is not left shifted by _f##_S
+ */
+
+#define REG_GET_FIELD(_r, _f) ((REG_READ(_r) >> (_f##_S)) & (_f##_V))
+
+/* Set field to register,
+ * used when _f is not left shifted by _f##_S
+ */
+
+#define REG_SET_FIELD(_r, _f, _v) (REG_WRITE((_r),((REG_READ(_r) & ~((_f##_V) << (_f##_S)))|(((_v) & (_f##_V))<<(_f##_S)))))
#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_ESP32C3_SOC_H */
diff --git a/arch/risc-v/src/esp32c3/hardware/esp32c3_uart.h b/arch/risc-v/src/esp32c3/hardware/esp32c3_uart.h
index e31343e..511104f 100644
--- a/arch/risc-v/src/esp32c3/hardware/esp32c3_uart.h
+++ b/arch/risc-v/src/esp32c3/hardware/esp32c3_uart.h
@@ -2182,4 +2182,25 @@
#define UART_REG_UPDATE_V 0x00000001
#define UART_REG_UPDATE_S 31
+/* ESP32-C3 have 2 UART: UART0-1 */
+
+#define ESP32C3_NUARTS 2
+
+/* UART has an extra TX_WAIT_SEND state when the
+ * FIFO is not empty and XOFF is enabled.
+ */
+
+#define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1)
+#define UART_FSM_IDLE (0x0)
+#define UART_FSM_TX_WAIT_SEND (0xf)
+
+/* Software write 1 would synchronize registers into UART Core clock
+ * domain and would be cleared by hardware after synchronization is done.
+ */
+
+#define UART_UPDATE (BIT(31))
+#define UART_UPDATE_M (BIT(31))
+#define UART_UPDATE_V 0x1
+#define UART_UPDATE_S 31
+
#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_ESP32C3_UART_H */
\ No newline at end of file
diff --git a/arch/risc-v/src/esp32c3/hardware/extmem_reg.h b/arch/risc-v/src/esp32c3/hardware/extmem_reg.h
new file mode 100644
index 0000000..88ce7f7
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/extmem_reg.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/extmem_reg.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_RISCV_SRC_ESP32C3_HARDWARE_EXTMEM_REG_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_EXTMEM_REG_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32c3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define EXTMEM_CACHE_MMU_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x0AC)
+#define EXTMEM_ICACHE_TAG_POWER_CTRL_REG (DR_REG_EXTMEM_BASE + 0x008)
+
+/* EXTMEM_CACHE_MMU_MEM_FORCE_ON : R/W ;bitpos:[0] ;default: 1'b1.
+ * The bit is used to enable clock gating to save
+ * power when access mmu memory 0: enable 1: disable
+ */
+
+#define EXTMEM_CACHE_MMU_MEM_FORCE_ON (BIT(0))
+#define EXTMEM_CACHE_MMU_MEM_FORCE_ON_M (BIT(0))
+#define EXTMEM_CACHE_MMU_MEM_FORCE_ON_V 0x1
+#define EXTMEM_CACHE_MMU_MEM_FORCE_ON_S 0
+
+/* EXTMEM_ICACHE_TAG_MEM_FORCE_ON : R/W ;bitpos:[0] ;default: 1'b1.
+ * description: The bit is used to close clock gating of icache tag memory.
+ * 1: close gating 0: open clock gating.
+ */
+
+#define EXTMEM_ICACHE_TAG_MEM_FORCE_ON (BIT(0))
+#define EXTMEM_ICACHE_TAG_MEM_FORCE_ON_M (BIT(0))
+#define EXTMEM_ICACHE_TAG_MEM_FORCE_ON_V 0x1
+#define EXTMEM_ICACHE_TAG_MEM_FORCE_ON_S 0
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_EXTMEM_REG_H_ */
diff --git a/arch/risc-v/src/esp32c3/hardware/fe_reg.h b/arch/risc-v/src/esp32c3/hardware/fe_reg.h
new file mode 100644
index 0000000..97e6049
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/fe_reg.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/fe_reg.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_RISCV_SRC_ESP32C3_HARDWARE_FE_REG_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_FE_REG_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32c3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Some of the RF frontend control registers.
+ * PU/PD fields defined here are used in sleep related functions.
+ */
+
+#define FE_GEN_CTRL (DR_REG_FE_BASE + 0x0090)
+#define FE_IQ_EST_FORCE_PU (BIT(5))
+#define FE_IQ_EST_FORCE_PU_M (BIT(5))
+#define FE_IQ_EST_FORCE_PU_V 1
+#define FE_IQ_EST_FORCE_PU_S 5
+
+#define FE2_TX_INTERP_CTRL (DR_REG_FE2_BASE + 0x00f0)
+#define FE2_TX_INF_FORCE_PU (BIT(10))
+#define FE2_TX_INF_FORCE_PU_M (BIT(10))
+#define FE2_TX_INF_FORCE_PU_V 1
+#define FE2_TX_INF_FORCE_PU_S 10
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_FE_REG_H_ */
diff --git a/arch/risc-v/src/esp32c3/hardware/nrx_reg.h b/arch/risc-v/src/esp32c3/hardware/nrx_reg.h
new file mode 100644
index 0000000..68a55cc
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/nrx_reg.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/nrx_reg.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_RISCV_SRC_ESP32C3_HARDWARE_NRX_REG_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_NRX_REG_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32c3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Some of the Wi-Fi RX control registers.
+ * PU/PD fields defined here are used in sleep related functions.
+ */
+
+#define NRXPD_CTRL (DR_REG_NRX_BASE + 0x00d4)
+#define NRX_RX_ROT_FORCE_PU (BIT(5))
+#define NRX_RX_ROT_FORCE_PU_M (BIT(5))
+#define NRX_RX_ROT_FORCE_PU_V 1
+#define NRX_RX_ROT_FORCE_PU_S 5
+#define NRX_VIT_FORCE_PU (BIT(3))
+#define NRX_VIT_FORCE_PU_M (BIT(3))
+#define NRX_VIT_FORCE_PU_V 1
+#define NRX_VIT_FORCE_PU_S 3
+#define NRX_DEMAP_FORCE_PU (BIT(1))
+#define NRX_DEMAP_FORCE_PU_M (BIT(1))
+#define NRX_DEMAP_FORCE_PU_V 1
+#define NRX_DEMAP_FORCE_PU_S 1
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_NRX_REG_H_ */
diff --git a/arch/risc-v/src/esp32c3/hardware/regi2c_bbpll.h b/arch/risc-v/src/esp32c3/hardware/regi2c_bbpll.h
new file mode 100644
index 0000000..375dc1a
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/regi2c_bbpll.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/regi2c_bbpll.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_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_BBPLL_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_BBPLL_H_
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register definitions for digital PLL (BBPLL). This file lists
+ * register fields of BBPLL, located on an internal configuration bus.
+ */
+
+#define I2C_BBPLL 0x66
+#define I2C_BBPLL_HOSTID 0
+
+#define I2C_BBPLL_MODE_HF 4
+#define I2C_BBPLL_MODE_HF_MSB 1
+#define I2C_BBPLL_MODE_HF_LSB 1
+
+#define I2C_BBPLL_OC_DCUR 6
+#define I2C_BBPLL_OC_DCUR_MSB 2
+#define I2C_BBPLL_OC_DCUR_LSB 0
+
+#define I2C_BBPLL_OC_DR1 5
+#define I2C_BBPLL_OC_DR1_MSB 2
+#define I2C_BBPLL_OC_DR1_LSB 0
+
+#define I2C_BBPLL_OC_DR3 5
+#define I2C_BBPLL_OC_DR3_MSB 6
+#define I2C_BBPLL_OC_DR3_LSB 4
+
+#define I2C_BBPLL_OC_VCO_DBIAS 9
+#define I2C_BBPLL_OC_VCO_DBIAS_MSB 1
+#define I2C_BBPLL_OC_VCO_DBIAS_LSB 0
+
+#define I2C_BBPLL_OC_DCHGP 2
+#define I2C_BBPLL_OC_DCHGP_MSB 6
+#define I2C_BBPLL_OC_DCHGP_LSB 4
+
+#define I2C_BBPLL_OC_DLREF_SEL 6
+#define I2C_BBPLL_OC_DLREF_SEL_MSB 7
+#define I2C_BBPLL_OC_DLREF_SEL_LSB 6
+
+#define I2C_BBPLL_OC_DHREF_SEL 6
+#define I2C_BBPLL_OC_DHREF_SEL_MSB 5
+#define I2C_BBPLL_OC_DHREF_SEL_LSB 4
+
+#define I2C_BBPLL_OC_REF_DIV 2
+#define I2C_BBPLL_OC_REF_DIV_MSB 3
+#define I2C_BBPLL_OC_REF_DIV_LSB 0
+
+#define I2C_BBPLL_OC_DIV_7_0 3
+#define I2C_BBPLL_OC_DIV_7_0_MSB 7
+#define I2C_BBPLL_OC_DIV_7_0_LSB 0
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_BBPLL_H_ */
\ No newline at end of file
diff --git a/arch/risc-v/src/esp32c3/hardware/regi2c_ctrl.h b/arch/risc-v/src/esp32c3/hardware/regi2c_ctrl.h
new file mode 100644
index 0000000..24807b3
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/regi2c_ctrl.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/regi2c_ctrl.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_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_CTRL_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_CTRL_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdint.h>
+#include "esp32c3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Analog function control register */
+
+#define I2C_MST_ANA_CONF0_REG 0x6000E040
+#define I2C_MST_BBPLL_STOP_FORCE_HIGH (BIT(2))
+#define I2C_MST_BBPLL_STOP_FORCE_LOW (BIT(3))
+
+/* ROM functions which read/write internal control bus */
+
+extern uint8_t rom_i2c_readreg(uint8_t block, uint8_t host_id,
+ uint8_t reg_add);
+extern uint8_t rom_i2c_readreg_mask(uint8_t block, uint8_t host_id,
+ uint8_t reg_add, uint8_t msb, uint8_t lsb);
+extern void rom_i2c_writereg(uint8_t block, uint8_t host_id,
+ uint8_t reg_add, uint8_t data);
+extern void rom_i2c_writereg_mask(uint8_t block, uint8_t host_id,
+ uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data);
+
+/* Convenience macros for the above functions, these use register
+ * definitions from regi2c_bbpll.h/regi2c_dig_reg.h/regi2c_lp_bias.h/
+ * regi2c_bias.h header files.
+ */
+
+#define REGI2C_WRITE_MASK(block, reg_add, indata) \
+ rom_i2c_writereg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB, indata)
+
+#define REGI2C_READ_MASK(block, reg_add) \
+ rom_i2c_readreg_mask(block, block##_HOSTID, reg_add, reg_add##_MSB, reg_add##_LSB)
+
+#define REGI2C_WRITE(block, reg_add, indata) \
+ rom_i2c_writereg(block, block##_HOSTID, reg_add, indata)
+
+#define REGI2C_READ(block, reg_add) \
+ rom_i2c_readreg(block, block##_HOSTID, reg_add)
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_CTRL_H_ */
diff --git a/arch/risc-v/src/esp32c3/hardware/regi2c_dig_reg.h b/arch/risc-v/src/esp32c3/hardware/regi2c_dig_reg.h
new file mode 100644
index 0000000..027f425
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/regi2c_dig_reg.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/regi2c_dig_reg.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_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_DIG_REG_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_DIG_REG_H_
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register definitions for digital to get rtc voltage & digital voltage
+ * by setting rtc_dbias_Wak & dig_dbias_wak or by analog self-calibration.
+ */
+
+#define I2C_DIG_REG 0x6D
+#define I2C_DIG_REG_HOSTID 0
+
+#define I2C_DIG_REG_EXT_RTC_DREG 4
+#define I2C_DIG_REG_EXT_RTC_DREG_MSB 4
+#define I2C_DIG_REG_EXT_RTC_DREG_LSB 0
+
+#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP 5
+#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_MSB 4
+#define I2C_DIG_REG_EXT_RTC_DREG_SLEEP_LSB 0
+
+#define I2C_DIG_REG_EXT_DIG_DREG 6
+#define I2C_DIG_REG_EXT_DIG_DREG_MSB 4
+#define I2C_DIG_REG_EXT_DIG_DREG_LSB 0
+
+#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP 7
+#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_MSB 4
+#define I2C_DIG_REG_EXT_DIG_DREG_SLEEP_LSB 0
+
+#define I2C_DIG_REG_XPD_RTC_REG 13
+#define I2C_DIG_REG_XPD_RTC_REG_MSB 2
+#define I2C_DIG_REG_XPD_RTC_REG_LSB 2
+
+#define I2C_DIG_REG_XPD_DIG_REG 13
+#define I2C_DIG_REG_XPD_DIG_REG_MSB 3
+#define I2C_DIG_REG_XPD_DIG_REG_LSB 3
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_DIG_REG_H_ */
diff --git a/arch/risc-v/src/esp32c3/hardware/regi2c_lp_bias.h b/arch/risc-v/src/esp32c3/hardware/regi2c_lp_bias.h
new file mode 100644
index 0000000..4029863
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/regi2c_lp_bias.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/regi2c_lp_bias.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_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_LP_BIAS_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_LP_BIAS_H_
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register definitions for analog to calibrate o_code for getting a more
+ * precise voltage. This file lists register fields of low power dbais,
+ * located on an internal configuration bus.
+ */
+
+#define I2C_ULP 0x61
+#define I2C_ULP_HOSTID 0
+
+#define I2C_ULP_IR_FORCE_XPD_CK 0
+#define I2C_ULP_IR_FORCE_XPD_CK_MSB 2
+#define I2C_ULP_IR_FORCE_XPD_CK_LSB 2
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_REGI2C_LP_BIAS_H_ */
diff --git a/arch/risc-v/src/esp32c3/hardware/spi_mem_reg.h b/arch/risc-v/src/esp32c3/hardware/spi_mem_reg.h
new file mode 100644
index 0000000..0e479a6
--- /dev/null
+++ b/arch/risc-v/src/esp32c3/hardware/spi_mem_reg.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+ * arch/risc-v/src/esp32c3/hardware/spi_mem_reg.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_RISCV_SRC_ESP32C3_HARDWARE_SPI_MEM_REG_H_
+#define __ARCH_RISCV_SRC_ESP32C3_HARDWARE_SPI_MEM_REG_H_
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "esp32c3_soc.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define SPI_MEM_CMD_REG(i) (REG_SPI_MEM_BASE(i) + 0x000)
+#define SPI_MEM_CLOCK_GATE_REG(i) (REG_SPI_MEM_BASE(i) + 0x0DC)
+
+/* SPI_MEM_CLK_EN : R/W ;bitpos:[0] ;default: 1'b1.
+ * Register clock gate enable signal. 1: Enable. 0: Disable.
+ */
+
+#define SPI_MEM_CLK_EN (BIT(0))
+#define SPI_MEM_CLK_EN_M (BIT(0))
+#define SPI_MEM_CLK_EN_V 0x1
+#define SPI_MEM_CLK_EN_S 0
+
+#endif /* __ARCH_RISCV_SRC_ESP32C3_HARDWARE_SPI_MEM_REG_H_ */
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/Kconfig b/boards/risc-v/esp32c3/esp32c3-devkit/Kconfig
index 6259575..e26862b 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/Kconfig
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/Kconfig
@@ -5,6 +5,38 @@
if ARCH_BOARD_ESP32C3_DEVKIT
+if PM
+
+config PM_ALARM_SEC
+ int "PM_STANDBY delay (seconds)"
+ default 15
+ depends on PM
+ ---help---
+ Number of seconds to wait in PM_STANDBY before going to PM_STANDBY mode.
+
+config PM_ALARM_NSEC
+ int "PM_STANDBY delay (nanoseconds)"
+ default 0
+ depends on PM
+ ---help---
+ Number of additional nanoseconds to wait in PM_STANDBY before going to PM_STANDBY mode.
+
+config PM_SLEEP_WAKEUP_SEC
+ int "PM_SLEEP delay (seconds)"
+ default 20
+ depends on PM
+ ---help---
+ Number of seconds to wait in PM_SLEEP.
+
+config PM_SLEEP_WAKEUP_NSEC
+ int "PM_SLEEP delay (nanoseconds)"
+ default 0
+ depends on PM
+ ---help---
+ Number of additional nanoseconds to wait in PM_SLEEP.
+
+endif # PM
+
config ESP32C3_DEVKIT_RUN_IRAM
bool "Run from IRAM"
default n
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/configs/pm/defconfig b/boards/risc-v/esp32c3/esp32c3-devkit/configs/pm/defconfig
new file mode 100644
index 0000000..72139d4
--- /dev/null
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/configs/pm/defconfig
@@ -0,0 +1,47 @@
+#
+# This file is autogenerated: PLEASE DO NOT EDIT IT.
+#
+# You can use "make menuconfig" to make any modifications to the installed .config file.
+# You can then do "make savedefconfig" to generate a new defconfig file that includes your
+# modifications.
+#
+# CONFIG_NSH_ARGCAT is not set
+# CONFIG_NSH_CMDOPT_HEXDUMP is not set
+# CONFIG_NSH_CMDPARMS is not set
+CONFIG_ARCH="risc-v"
+CONFIG_ARCH_BOARD="esp32c3-devkit"
+CONFIG_ARCH_BOARD_ESP32C3_DEVKIT=y
+CONFIG_ARCH_CHIP="esp32c3"
+CONFIG_ARCH_CHIP_ESP32C3=y
+CONFIG_ARCH_CHIP_ESP32C3WROOM02=y
+CONFIG_ARCH_INTERRUPTSTACK=1536
+CONFIG_ARCH_RISCV=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_BOARD_LOOPSPERMSEC=15000
+CONFIG_BUILTIN=y
+CONFIG_DEV_ZERO=y
+CONFIG_FS_PROCFS=y
+CONFIG_IDLETHREAD_STACKSIZE=2048
+CONFIG_INTELHEX_BINARY=y
+CONFIG_LIBC_PERROR_STDOUT=y
+CONFIG_LIBC_STRERROR=y
+CONFIG_MAX_TASKS=8
+CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
+CONFIG_NSH_ARCHINIT=y
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_READLINE=y
+CONFIG_NSH_STRERROR=y
+CONFIG_PM=y
+CONFIG_PM_GOVERNOR_EXPLICIT_RELAX=y
+CONFIG_PM_GOVERNOR_GREEDY=y
+CONFIG_PREALLOC_TIMERS=0
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_START_DAY=29
+CONFIG_START_MONTH=11
+CONFIG_START_YEAR=2019
+CONFIG_SYSTEM_NSH=y
+CONFIG_UART0_SERIAL_CONSOLE=y
+CONFIG_USER_ENTRYPOINT="nsh_main"
diff --git a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
index c4cc218..55dc5f3 100644
--- a/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
+++ b/boards/risc-v/esp32c3/esp32c3-devkit/scripts/esp32c3_rom.ld
@@ -1815,9 +1815,9 @@ rom_get_i2c_read_mask = 0x40001948;
rom_get_pwctrl_correct = 0x4000194c;
rom_get_rf_gain_qdb = 0x40001950;
rom_i2c_readreg = 0x40001954;
-rom_i2c_readreg_Mask = 0x40001958;
+rom_i2c_readreg_mask = 0x40001958;
rom_i2c_writereg = 0x4000195c;
-rom_i2c_writereg_Mask = 0x40001960;
+rom_i2c_writereg_mask = 0x40001960;
rom_index_to_txbbgain = 0x40001964;
rom_iq_est_disable = 0x40001968;
rom_iq_est_enable = 0x4000196c;