feat(rtcio): support rtcio on esp32s31

This commit is contained in:
Chen Chen
2026-04-01 08:51:47 +08:00
parent f8f8219e13
commit cbb529bf97
17 changed files with 208 additions and 178 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -89,7 +89,7 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
LP_IOMUX.pad[rtcio_num].fun_sel = func;
// When using as normal (output) LP_GPIO, it is reasonable to ensure that no peripheral signal is routed to the pin
if (func == RTCIO_LL_PIN_FUNC) {
LP_GPIO.func_out_sel_cfg[rtcio_num].func_out_sel = SIG_LP_GPIO_OUT_IDX;
LP_GPIO.func_out_sel_cfg[rtcio_num].func_out_sel = LP_SIG_GPIO_OUT_IDX;
}
}
@@ -105,11 +105,7 @@ static inline void _rtcio_ll_enable_io_clock(bool enable)
;
}
}
#define rtcio_ll_enable_io_clock(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_rtcio_ll_enable_io_clock(__VA_ARGS__); \
} while(0)
#define rtcio_ll_enable_io_clock(...) _rtcio_ll_enable_io_clock(__VA_ARGS__)
/**
* @brief Select the lp_gpio/hp_gpio function to control the pad.
@@ -153,7 +149,7 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
{
LP_GPIO.enable_w1tc.val = BIT(rtcio_num);
// Ensure no other output signal is routed via LP_GPIO matrix to this pin
LP_GPIO.func_out_sel_cfg[rtcio_num].func_out_sel = SIG_LP_GPIO_OUT_IDX;
LP_GPIO.func_out_sel_cfg[rtcio_num].func_out_sel = LP_SIG_GPIO_OUT_IDX;
}
/**
@@ -1,16 +1,11 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// TODO: [ESP32S31] IDF-14785
// RTC GPIO capabilities are temporarily bypassed for ESP32-S31
// This file provides stub definitions to allow the build to succeed.
// Full RTC GPIO capabilities for ESP32-S31 need to be implemented in the future.
#pragma once
#define RTC_GPIO_CAPS_GET(_attr) _RTC_GPIO_ ## _attr
// TODO: [ESP32S31] IDF-14785
#define _RTC_GPIO_EDGE_WAKEUP_SUPPORTED 1
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -10,16 +10,17 @@
* See readme.md in hal/include/hal/readme.md
******************************************************************************/
// TODO: [ESP32S31] IDF-14785
// RTC IO LL implementation is temporarily bypassed for ESP32-S31
// This file provides stub function declarations to allow the build to succeed.
// Full RTC IO support for ESP32-S31 needs to be implemented in the future.
#pragma once
#include <stdlib.h>
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "soc/lp_gpio_struct.h"
#include "soc/lp_iomux_struct.h"
#include "soc/lp_gpio_sig_map.h"
#include "soc/lp_system_struct.h"
#include "soc/lp_peri_clkrst_struct.h"
#include "soc/pmu_struct.h"
#include "hal/gpio_types.h"
#include "hal/misc.h"
#include "hal/assert.h"
@@ -50,9 +51,10 @@ typedef enum {
*/
static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)func;
LP_IO_MUX.gpion[rtcio_num].gpion_mcu_sel = func;
if (func == RTCIO_LL_PIN_FUNC) {
LP_GPIO.funcn_out_sel_cfg[rtcio_num].funcn_out_sel = LP_SIG_GPIO_OUT_IDX;
}
}
/**
@@ -62,14 +64,18 @@ static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
*/
static inline void _rtcio_ll_enable_io_clock(bool enable)
{
// TODO: [ESP32S31] IDF-14785
(void)enable;
LP_PERI_CLKRST.iomux_ctrl.lp_iomux_clk_en = enable;
LP_GPIO.clock_gate.clk_en = enable;
while ((LP_PERI_CLKRST.iomux_ctrl.lp_iomux_clk_en != enable) ||
(LP_GPIO.clock_gate.clk_en != enable)) {
;
}
}
#define rtcio_ll_enable_io_clock(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_rtcio_ll_enable_io_clock(__VA_ARGS__); \
} while(0)
static inline void rtcio_ll_enable_io_clock(bool enable)
{
_rtcio_ll_enable_io_clock(enable);
}
/**
* @brief Select the rtcio function.
@@ -81,9 +87,16 @@ static inline void _rtcio_ll_enable_io_clock(bool enable)
*/
static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)func;
if (func == RTCIO_LL_FUNC_RTC) {
uint32_t sel = HAL_FORCE_READ_U32_REG_FIELD(LP_SYS.padctrl, pad_mux_sel);
sel |= BIT(rtcio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_SYS.padctrl, pad_mux_sel, sel);
rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC);
} else if (func == RTCIO_LL_FUNC_DIGITAL) {
uint32_t sel = HAL_FORCE_READ_U32_REG_FIELD(LP_SYS.padctrl, pad_mux_sel);
sel &= ~BIT(rtcio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_SYS.padctrl, pad_mux_sel, sel);
}
}
/**
@@ -93,8 +106,7 @@ static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
*/
static inline void rtcio_ll_output_enable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_GPIO.enable_w1ts.val = BIT(rtcio_num);
}
/**
@@ -104,8 +116,9 @@ static inline void rtcio_ll_output_enable(int rtcio_num)
*/
static inline void rtcio_ll_output_disable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_GPIO.enable_w1tc.val = BIT(rtcio_num);
// Ensure no other output signal is routed via LP_GPIO matrix to this pin
LP_GPIO.funcn_out_sel_cfg[rtcio_num].funcn_out_sel = LP_SIG_GPIO_OUT_IDX;
}
/**
@@ -116,9 +129,11 @@ static inline void rtcio_ll_output_disable(int rtcio_num)
*/
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)level;
if (level) {
LP_GPIO.out_w1ts.val = BIT(rtcio_num);
} else {
LP_GPIO.out_w1tc.val = BIT(rtcio_num);
}
}
/**
@@ -128,8 +143,7 @@ static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
*/
static inline void rtcio_ll_input_enable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_fun_ie = 1;
}
/**
@@ -139,8 +153,7 @@ static inline void rtcio_ll_input_enable(int rtcio_num)
*/
static inline void rtcio_ll_input_disable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_fun_ie = 0;
}
/**
@@ -151,9 +164,7 @@ static inline void rtcio_ll_input_disable(int rtcio_num)
*/
static inline uint32_t rtcio_ll_get_level(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
return 0;
return (HAL_FORCE_READ_U32_REG_FIELD(LP_GPIO.in, in_data_next) >> rtcio_num) & 0x1;
}
/**
@@ -164,9 +175,7 @@ static inline uint32_t rtcio_ll_get_level(int rtcio_num)
*/
static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)strength;
LP_IO_MUX.gpion[rtcio_num].gpion_fun_drv = strength;
}
/**
@@ -177,9 +186,7 @@ static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strengt
*/
static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
return 0;
return LP_IO_MUX.gpion[rtcio_num].gpion_fun_drv;
}
/**
@@ -190,9 +197,7 @@ static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num)
*/
static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t mode)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)mode;
LP_GPIO.pinn[rtcio_num].pinn_pad_driver = mode;
}
/**
@@ -202,8 +207,7 @@ static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t m
*/
static inline void rtcio_ll_pullup_enable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu = 1;
}
/**
@@ -213,8 +217,7 @@ static inline void rtcio_ll_pullup_enable(int rtcio_num)
*/
static inline void rtcio_ll_pullup_disable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu = 0;
}
/**
@@ -225,9 +228,7 @@ static inline void rtcio_ll_pullup_disable(int rtcio_num)
*/
static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
return false;
return LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpu;
}
/**
@@ -237,8 +238,7 @@ static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num)
*/
static inline void rtcio_ll_pulldown_enable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd = 1;
}
/**
@@ -248,8 +248,7 @@ static inline void rtcio_ll_pulldown_enable(int rtcio_num)
*/
static inline void rtcio_ll_pulldown_disable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd = 0;
}
/**
@@ -260,9 +259,7 @@ static inline void rtcio_ll_pulldown_disable(int rtcio_num)
*/
static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
return false;
return LP_IO_MUX.gpion[rtcio_num].gpion_fun_wpd;
}
/**
@@ -277,8 +274,9 @@ static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num)
*/
static inline void rtcio_ll_force_hold_enable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
uint32_t hold = HAL_FORCE_READ_U32_REG_FIELD(LP_SYS.padctrl, pad_hold);
hold |= BIT(rtcio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_SYS.padctrl, pad_hold, hold);
}
/**
@@ -289,8 +287,9 @@ static inline void rtcio_ll_force_hold_enable(int rtcio_num)
*/
static inline void rtcio_ll_force_hold_disable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
uint32_t hold = HAL_FORCE_READ_U32_REG_FIELD(LP_SYS.padctrl, pad_hold);
hold &= ~BIT(rtcio_num);
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_SYS.padctrl, pad_hold, hold);
}
/**
@@ -303,7 +302,7 @@ static inline void rtcio_ll_force_hold_disable(int rtcio_num)
*/
static inline void rtcio_ll_force_hold_all(void)
{
// TODO: [ESP32S31] IDF-14785
PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1;
}
/**
@@ -313,7 +312,7 @@ static inline void rtcio_ll_force_hold_all(void)
*/
static inline void rtcio_ll_force_unhold_all(void)
{
// TODO: [ESP32S31] IDF-14785
PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1;
}
/**
@@ -324,9 +323,8 @@ static inline void rtcio_ll_force_unhold_all(void)
*/
static inline void rtcio_ll_wakeup_enable(int rtcio_num, gpio_int_type_t type)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)type;
LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable = 1;
LP_GPIO.pinn[rtcio_num].pinn_int_type = type;
}
/**
@@ -336,8 +334,8 @@ static inline void rtcio_ll_wakeup_enable(int rtcio_num, gpio_int_type_t type)
*/
static inline void rtcio_ll_wakeup_disable(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable = 0;
LP_GPIO.pinn[rtcio_num].pinn_int_type = 0;
}
/**
@@ -348,9 +346,7 @@ static inline void rtcio_ll_wakeup_disable(int rtcio_num)
*/
static inline void rtcio_ll_intr_enable(int rtcio_num, gpio_int_type_t type)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)type;
LP_GPIO.pinn[rtcio_num].pinn_int_type = type;
}
/**
@@ -360,8 +356,7 @@ static inline void rtcio_ll_intr_enable(int rtcio_num, gpio_int_type_t type)
*/
static inline void rtcio_ll_enable_output_in_sleep(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_mcu_oe = 1;
}
/**
@@ -371,8 +366,7 @@ static inline void rtcio_ll_enable_output_in_sleep(int rtcio_num)
*/
static inline void rtcio_ll_disable_output_in_sleep(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_mcu_oe = 0;
}
/**
@@ -382,8 +376,7 @@ static inline void rtcio_ll_disable_output_in_sleep(int rtcio_num)
*/
static inline void rtcio_ll_enable_input_in_sleep(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_mcu_ie = 1;
}
/**
@@ -393,8 +386,7 @@ static inline void rtcio_ll_enable_input_in_sleep(int rtcio_num)
*/
static inline void rtcio_ll_disable_input_in_sleep(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_mcu_ie = 0;
}
/**
@@ -404,8 +396,7 @@ static inline void rtcio_ll_disable_input_in_sleep(int rtcio_num)
*/
static inline void rtcio_ll_enable_sleep_setting(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_slp_sel = 1;
}
/**
@@ -415,8 +406,7 @@ static inline void rtcio_ll_enable_sleep_setting(int rtcio_num)
*/
static inline void rtcio_ll_disable_sleep_setting(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
LP_IO_MUX.gpion[rtcio_num].gpion_slp_sel = 0;
}
/**
@@ -427,12 +417,8 @@ static inline void rtcio_ll_disable_sleep_setting(int rtcio_num)
*/
static inline bool rtcio_ll_wakeup_is_enabled(int rtcio_num)
{
// TODO: [ESP32S31] IDF-14785
#if SOC_RTCIO_PIN_COUNT > 0
HAL_ASSERT(rtcio_num >= 0 && rtcio_num < SOC_RTCIO_PIN_COUNT && "io does not support deep sleep wake-up function");
#endif
(void)rtcio_num;
return false;
return LP_GPIO.pinn[rtcio_num].pinn_wakeup_enable;
}
/**
@@ -442,8 +428,7 @@ static inline bool rtcio_ll_wakeup_is_enabled(int rtcio_num)
*/
static inline uint32_t rtcio_ll_get_interrupt_status(void)
{
// TODO: [ESP32S31] IDF-14785
return 0;
return HAL_FORCE_READ_U32_REG_FIELD(LP_GPIO.status, status_interrupt);
}
/**
@@ -451,57 +436,43 @@ static inline uint32_t rtcio_ll_get_interrupt_status(void)
*/
static inline void rtcio_ll_clear_interrupt_status(void)
{
// TODO: [ESP32S31] IDF-14785
LP_GPIO.status_w1tc.val = 0xFF;
}
#if SOC_LP_GPIO_MATRIX_SUPPORTED
/**
* @brief Select signal input from a RTC GPIO
* @brief Select RTC GPIO input to a signal.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx LP peripheral signal index.
* @param signal_idx LP peripheral input signal index (0 .. IN_SIGNAL_MAX - 1).
* @param inv True to invert input signal; False then no invert.
*/
static inline void rtcio_ll_matrix_in(int rtcio_num, int signal_idx, bool inv)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)signal_idx;
(void)inv;
lp_gpio_funca_in_sel_cfg_reg_t reg;
reg.funca_in_sel = rtcio_num;
reg.funca_in_inv_sel = inv;
reg.siga_in_sel = 1; // Signal should not bypass LP_GPIO matrix
LP_GPIO.funca_in_sel_cfg[signal_idx].val = reg.val;
}
/**
* @brief Select signal output to a RTC GPIO
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param signal_idx LP peripheral signal index.
* @param signal_idx Peripheral output signal index (0 .. OUT_SIGNAL_MAX - 1).
* @param out_inv True to invert output signal; False then no invert.
* @param oen_inv True to invert output enable signal; False then no invert.
*/
static inline void rtcio_ll_matrix_out(int rtcio_num, int signal_idx, bool out_inv, bool oen_inv)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)signal_idx;
(void)out_inv;
(void)oen_inv;
}
#endif // SOC_LP_GPIO_MATRIX_SUPPORTED
lp_gpio_funcn_out_sel_cfg_reg_t reg;
reg.funcn_out_sel = signal_idx;
reg.funcn_out_inv_sel = out_inv;
reg.funcn_oe_inv_sel = oen_inv;
LP_GPIO.funcn_out_sel_cfg[rtcio_num].val = reg.val;
#if SOC_RTCIO_WAKE_SUPPORTED
/**
* @brief Set specific logic level on an RTC IO pin as a ext0 wakeup trigger.
*
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
* @param level Logic level (0: low level trigger, 1: high level trigger)
*/
static inline void rtcio_ll_ext0_set_wakeup_pin(int rtcio_num, int level)
{
// TODO: [ESP32S31] IDF-14785
(void)rtcio_num;
(void)level;
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_GPIO.enable_w1ts, enable_w1ts, BIT(rtcio_num));
}
#endif // SOC_RTCIO_WAKE_SUPPORTED
#ifdef __cplusplus
}
@@ -1,27 +1,21 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// TODO: [ESP32S31] IDF-14785
// RTC IO peripheral implementation is temporarily bypassed
// This file provides a stub implementation to allow the build to succeed.
// Full RTC IO support for ESP32-S31 needs to be implemented in the future.
// Related: Need to create soc/esp32s31/include/soc/rtc_io_channel.h and
// implement proper RTC IO pin mapping and descriptor tables.
#include "hal/rtc_io_periph.h"
#include "soc/rtc_io_channel.h"
const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
-1,//GPIO0
-1,//GPIO1
-1,//GPIO2
-1,//GPIO3
-1,//GPIO4
-1,//GPIO5
-1,//GPIO6
-1,//GPIO7
RTCIO_GPIO0_CHANNEL, //GPIO0
RTCIO_GPIO1_CHANNEL, //GPIO1
RTCIO_GPIO2_CHANNEL, //GPIO2
RTCIO_GPIO3_CHANNEL, //GPIO3
RTCIO_GPIO4_CHANNEL, //GPIO4
RTCIO_GPIO5_CHANNEL, //GPIO5
RTCIO_GPIO6_CHANNEL, //GPIO6
RTCIO_GPIO7_CHANNEL, //GPIO7
-1,//GPIO8
-1,//GPIO9
-1,//GPIO10
@@ -77,14 +71,3 @@ const int8_t rtc_io_num_map[SOC_GPIO_PIN_COUNT] = {
-1,//GPIO60
-1,//GPIO61
};
// TODO: [ESP32S31] IDF-14785
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
// This requires soc/esp32s31/include/soc/rtc_io_channel.h and
// soc/esp32s31/include/soc/rtc_io_reg.h to be created first
// Currently providing empty array as placeholder - all fields will be 0
const rtc_io_desc_t rtc_io_desc[SOC_RTCIO_PIN_COUNT] = {
// TODO: Initialize 8 entries (SOC_RTCIO_PIN_COUNT = 8) with proper register addresses
// and bit masks once rtc_io_channel.h and rtc_io_reg.h are available
};
#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED