mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
refactor(gpio): split GPIO HAL into separate component
cleaned up some includes in GPIO peripheral files
This commit is contained in:
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void dedic_gpio_cpu_ll_enable_output(uint32_t mask)
|
||||
{
|
||||
// Dedicated GPIO output attribution is enabled automatically on the target
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t dedic_gpio_cpu_ll_read_in(void)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
asm volatile("ee.get_gpio_in %0" : "=r"(value) : :);
|
||||
return value;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t dedic_gpio_cpu_ll_read_out(void)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
asm volatile("rur.gpio_out %0" : "=r"(value) : :);
|
||||
return value;
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void dedic_gpio_cpu_ll_write_all(uint32_t value)
|
||||
{
|
||||
asm volatile("wur.gpio_out %0"::"r"(value):);
|
||||
}
|
||||
|
||||
__attribute__((always_inline))
|
||||
static inline void dedic_gpio_cpu_ll_write_mask(uint32_t mask, uint32_t value)
|
||||
{
|
||||
asm volatile("ee.wr_mask_gpio_out %0, %1" : : "r"(value), "r"(mask):);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/system_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline void _dedic_gpio_ll_enable_bus_clock(bool enable)
|
||||
{
|
||||
SYSTEM.cpu_peri_clk_en.clk_en_dedicated_gpio = enable;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define dedic_gpio_ll_enable_bus_clock(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_dedic_gpio_ll_enable_bus_clock(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
static inline void _dedic_gpio_ll_reset_register(void)
|
||||
{
|
||||
SYSTEM.cpu_peri_rst_en.rst_en_dedicated_gpio = 1;
|
||||
SYSTEM.cpu_peri_rst_en.rst_en_dedicated_gpio = 0;
|
||||
}
|
||||
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define dedic_gpio_ll_reset_register(...) do { \
|
||||
(void)__DECLARE_RCC_ATOMIC_ENV; \
|
||||
_dedic_gpio_ll_reset_register(__VA_ARGS__); \
|
||||
} while(0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,737 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The hal is not public api, don't use in application code.
|
||||
* See readme.md in hal/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The LL layer for ESP32-S3 GPIO register operations
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "soc/soc.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/usb_serial_jtag_reg.h"
|
||||
#include "hal/gpio_types.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Get GPIO hardware instance with giving gpio num
|
||||
#define GPIO_LL_GET_HW(num) (((num) == 0) ? (&GPIO) : NULL)
|
||||
|
||||
// On ESP32S3, pro cpu and app cpu shares the same interrupt enable bit
|
||||
#define GPIO_LL_INTR_ENA (BIT(0))
|
||||
#define GPIO_LL_NMI_INTR_ENA (BIT(1))
|
||||
|
||||
#define GPIO_LL_INTR_SOURCE0 ETS_GPIO_INTR_SOURCE
|
||||
|
||||
/**
|
||||
* @brief Enable pull-up on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
REG_SET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable pull-up on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
// The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value
|
||||
// USB DP pin is default to PU enabled
|
||||
// Note that from esp32s3 ECO1, USB_EXCHG_PINS feature has been supported. If this efuse is burnt, the gpio pin
|
||||
// which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead.
|
||||
if (gpio_num == USB_INT_PHY0_DP_GPIO_NUM) {
|
||||
SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE);
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP);
|
||||
}
|
||||
REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PU);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable pull-down on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
REG_SET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable pull-down on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
REG_CLR_BIT(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_PD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO set interrupt trigger type
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number. If you want to set the trigger type of e.g. of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param intr_type Interrupt type, select from gpio_int_type_t
|
||||
*/
|
||||
static inline void gpio_ll_set_intr_type(gpio_dev_t *hw, uint32_t gpio_num, gpio_int_type_t intr_type)
|
||||
{
|
||||
hw->pin[gpio_num].int_type = intr_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get GPIO interrupt status
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param core_id interrupt core id
|
||||
* @param status interrupt status
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_get_intr_status(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
|
||||
{
|
||||
// On ESP32S3, pcpu_int register represents GPIO0-31 interrupt status on both cores
|
||||
(void)core_id;
|
||||
*status = hw->pcpu_int;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get GPIO interrupt status high
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param core_id interrupt core id
|
||||
* @param status interrupt status high
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_get_intr_status_high(gpio_dev_t *hw, uint32_t core_id, uint32_t *status)
|
||||
{
|
||||
// On ESP32S3, pcpu_int1 register represents GPIO32-48 interrupt status on both cores
|
||||
(void)core_id;
|
||||
*status = hw->pcpu_int1.intr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear GPIO interrupt status
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param mask interrupt status clear mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_clear_intr_status(gpio_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->status_w1tc = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear GPIO interrupt status high
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param mask interrupt status high clear mask
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_clear_intr_status_high(gpio_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->status1_w1tc.intr_st = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO module interrupt signal
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param core_id Interrupt enabled CPU to corresponding ID
|
||||
* @param gpio_num GPIO number. If you want to enable the interrupt of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_intr_enable_on_core(gpio_dev_t *hw, uint32_t core_id, uint32_t gpio_num)
|
||||
{
|
||||
(void)core_id;
|
||||
GPIO.pin[gpio_num].int_ena = GPIO_LL_INTR_ENA; //enable intr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO module interrupt signal
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number. If you want to disable the interrupt of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_intr_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
hw->pin[gpio_num].int_ena = 0; //disable GPIO intr
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable input mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_DISABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable input mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_INPUT_ENABLE(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_EN(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin filter
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
*/
|
||||
static inline void gpio_ll_pin_filter_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_FILTER_DIS(IO_MUX_GPIO0_REG + (gpio_num * 4));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable output mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
if (gpio_num < 32) {
|
||||
hw->enable_w1tc = (0x1 << gpio_num);
|
||||
} else {
|
||||
hw->enable1_w1tc.data = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable output mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_output_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
if (gpio_num < 32) {
|
||||
hw->enable_w1ts = (0x1 << gpio_num);
|
||||
} else {
|
||||
hw->enable1_w1ts.data = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable open-drain mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_od_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
hw->pin[gpio_num].pad_driver = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable open-drain mode on GPIO.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_od_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
hw->pin[gpio_num].pad_driver = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select a function for the pin in the IOMUX
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
* @param func Function to assign to the pin
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_func_sel(gpio_dev_t *hw, uint8_t gpio_num, uint32_t func)
|
||||
{
|
||||
if (gpio_num == USB_INT_PHY0_DM_GPIO_NUM || gpio_num == USB_INT_PHY0_DP_GPIO_NUM) {
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_USB_PAD_ENABLE);
|
||||
}
|
||||
PIN_FUNC_SELECT(IO_MUX_GPIO0_REG + (gpio_num * 4), func);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO set output level
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number. If you want to set the output level of e.g. GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @param level Output level. 0: low ; 1: high
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_set_level(gpio_dev_t *hw, uint32_t gpio_num, uint32_t level)
|
||||
{
|
||||
if (level) {
|
||||
if (gpio_num < 32) {
|
||||
hw->out_w1ts = 1 << gpio_num;
|
||||
} else {
|
||||
hw->out1_w1ts.val = 1 << (gpio_num - 32);
|
||||
}
|
||||
} else {
|
||||
if (gpio_num < 32) {
|
||||
hw->out_w1tc = 1 << gpio_num;
|
||||
} else {
|
||||
hw->out1_w1tc.val = 1 << (gpio_num - 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO get input level
|
||||
*
|
||||
* @warning If the pad is not configured for input (or input and output) the returned value is always 0.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number. If you want to get the logic level of e.g. pin GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*
|
||||
* @return
|
||||
* - 0 the GPIO input level is 0
|
||||
* - 1 the GPIO input level is 1
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline int gpio_ll_get_level(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
if (gpio_num < 32) {
|
||||
return (hw->in >> gpio_num) & 0x1;
|
||||
} else {
|
||||
return (hw->in1.data >> (gpio_num - 32)) & 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO wake-up function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number.
|
||||
*/
|
||||
static inline void gpio_ll_wakeup_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
hw->pin[gpio_num].wakeup_enable = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO wake-up function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
static inline void gpio_ll_wakeup_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
hw->pin[gpio_num].wakeup_enable = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set GPIO pad drive capability
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
* @param strength Drive capability of the pad
|
||||
*/
|
||||
static inline void gpio_ll_set_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t strength)
|
||||
{
|
||||
uint32_t drv_cap = (uint32_t)strength;
|
||||
// DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target
|
||||
if (gpio_num == 17 || gpio_num == 18) {
|
||||
drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1
|
||||
}
|
||||
SET_PERI_REG_BITS(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, drv_cap, FUN_DRV_S);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get GPIO pad drive capability
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
* @param strength Pointer to accept drive capability of the pad
|
||||
*/
|
||||
static inline void gpio_ll_get_drive_capability(gpio_dev_t *hw, uint32_t gpio_num, gpio_drive_cap_t *strength)
|
||||
{
|
||||
uint32_t drv_cap = GET_PERI_REG_BITS2(IO_MUX_GPIO0_REG + (gpio_num * 4), FUN_DRV_V, FUN_DRV_S);
|
||||
// DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target
|
||||
if (gpio_num == 17 || gpio_num == 18) {
|
||||
drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1
|
||||
}
|
||||
*strength = (gpio_drive_cap_t)drv_cap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable all digital gpio pad hold function during Deep-sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*/
|
||||
static inline void gpio_ll_deep_sleep_hold_en(gpio_dev_t *hw)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable all digital gpio pad hold function during Deep-sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*/
|
||||
static inline void gpio_ll_deep_sleep_hold_dis(gpio_dev_t *hw)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get deep sleep hold status
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
*
|
||||
* @return
|
||||
* - true deep sleep hold is enabled
|
||||
* - false deep sleep hold is disabled
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline bool gpio_ll_deep_sleep_hold_is_en(gpio_dev_t *hw)
|
||||
{
|
||||
return !GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD) && GET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_AUTOHOLD_EN_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable gpio pad hold function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
*/
|
||||
static inline void gpio_ll_hold_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable gpio pad hold function.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
*/
|
||||
static inline void gpio_ll_hold_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, GPIO_HOLD_MASK[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get gpio pad hold status.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number, only support output GPIOs
|
||||
*
|
||||
* @note caller must ensure that gpio_num is a digital io pad
|
||||
*
|
||||
* @return
|
||||
* - true digital gpio pad is held
|
||||
* - false digital gpio pad is unheld
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline bool gpio_ll_is_digital_io_hold(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
return GET_PERI_REG_MASK(RTC_CNTL_DIG_PAD_HOLD_REG, BIT(gpio_num - 21));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure peripheral signal input whether to bypass GPIO matrix.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param signal_idx Peripheral signal id to input. One of the ``*_IN_IDX`` signals in ``soc/gpio_sig_map.h``.
|
||||
* @param from_gpio_matrix True if not to bypass GPIO matrix, otherwise False.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_set_input_signal_from(gpio_dev_t *hw, uint32_t signal_idx, bool from_gpio_matrix)
|
||||
{
|
||||
hw->func_in_sel_cfg[signal_idx].sig_in_sel = from_gpio_matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connect a GPIO input with a peripheral signal, which tagged as input attribute.
|
||||
*
|
||||
* @note There's no limitation on the number of signals that a GPIO can combine with.
|
||||
*
|
||||
* @param signal_idx Peripheral signal index (tagged as input attribute)
|
||||
* @param gpio_num GPIO number, especially, `GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal
|
||||
* `GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal
|
||||
* @param in_inv True if the GPIO input needs to be inverted, otherwise False.
|
||||
*/
|
||||
static inline void gpio_ll_set_input_signal_matrix_source(gpio_dev_t *hw, uint32_t signal_idx, uint32_t gpio_num, bool in_inv)
|
||||
{
|
||||
hw->func_in_sel_cfg[signal_idx].func_sel = gpio_num;
|
||||
hw->func_in_sel_cfg[signal_idx].sig_in_inv = in_inv;
|
||||
gpio_ll_set_input_signal_from(hw, signal_idx, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the GPIO number that is routed to the input peripheral signal through GPIO matrix.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param in_sig_idx Peripheral signal index (tagged as input attribute).
|
||||
*
|
||||
* @return
|
||||
* - -1 Signal bypassed GPIO matrix
|
||||
* - Others GPIO number
|
||||
*/
|
||||
static inline int gpio_ll_get_in_signal_connected_io(gpio_dev_t *hw, uint32_t in_sig_idx)
|
||||
{
|
||||
typeof(hw->func_in_sel_cfg[in_sig_idx]) reg;
|
||||
reg.val = hw->func_in_sel_cfg[in_sig_idx].val;
|
||||
return (reg.sig_in_sel ? reg.func_sel : -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the source of output enable signal for the pad (only takes effect if func sel is selected to be GPIO).
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number of the pad.
|
||||
* @param ctrl_by_periph True if use output enable signal from peripheral, false if force the output enable signal to be sourced from bit n of GPIO_ENABLE_REG
|
||||
* @param oen_inv True if the output enable needs to be inverted, otherwise False.
|
||||
*/
|
||||
static inline void gpio_ll_set_output_enable_ctrl(gpio_dev_t *hw, uint8_t gpio_num, bool ctrl_by_periph, bool oen_inv)
|
||||
{
|
||||
hw->func_out_sel_cfg[gpio_num].oen_inv_sel = oen_inv; // control valid only when using gpio matrix to route signal to the IO
|
||||
hw->func_out_sel_cfg[gpio_num].oen_sel = !ctrl_by_periph;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connect a peripheral signal which tagged as output attribute with a GPIO.
|
||||
*
|
||||
* @note There's no limitation on the number of signals that a GPIO can combine with.
|
||||
*
|
||||
* @param gpio_num GPIO number
|
||||
* @param signal_idx Peripheral signal index (tagged as output attribute). Particularly, `SIG_GPIO_OUT_IDX` means disconnect GPIO and other peripherals. Only the GPIO driver can control the output level.
|
||||
* @param out_inv True if the signal output needs to be inverted, otherwise False.
|
||||
*/
|
||||
static inline void gpio_ll_set_output_signal_matrix_source(gpio_dev_t *hw, uint32_t gpio_num, uint32_t signal_idx, bool out_inv)
|
||||
{
|
||||
hw->func_out_sel_cfg[gpio_num].func_sel = signal_idx;
|
||||
hw->func_out_sel_cfg[gpio_num].inv_sel = out_inv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Control the pin in the IOMUX
|
||||
*
|
||||
* @param bmap write mask of control value
|
||||
* @param val Control value
|
||||
* @param shift write mask shift of control value
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_set_pin_ctrl(uint32_t val, uint32_t bmap, uint32_t shift)
|
||||
{
|
||||
SET_PERI_REG_BITS(PIN_CTRL, bmap, val, shift);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force hold digital gpio pad.
|
||||
* @note GPIO force hold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_hold_all(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force unhold digital gpio pad.
|
||||
* @note GPIO force unhold, whether the chip in sleep mode or wakeup mode.
|
||||
*/
|
||||
static inline void gpio_ll_force_unhold_all(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_HOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_DG_PAD_FORCE_UNHOLD);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_DIG_ISO_REG, RTC_CNTL_CLR_DG_PAD_AUTOHOLD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pin used for wakeup from sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_sel_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_SEL_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pin used for wakeup from sleep.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_sel_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_SEL_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-up in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_pullup_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLUP_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-up in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_pullup_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLUP_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO pull-down in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_pulldown_en(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLDOWN_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO pull-down in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_pulldown_dis(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_PULLDOWN_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO input in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_input_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO input in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_input_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable GPIO output in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_output_disable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_OUTPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable GPIO output in sleep mode.
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void gpio_ll_sleep_output_enable(gpio_dev_t *hw, uint32_t gpio_num)
|
||||
{
|
||||
PIN_SLP_OUTPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the configuration for an IO
|
||||
*
|
||||
* @param hw Peripheral GPIO hardware instance address.
|
||||
* @param gpio_num GPIO number
|
||||
* @param[out] io_config Pointer to the structure that saves the specific IO configuration
|
||||
*/
|
||||
static inline void gpio_ll_get_io_config(gpio_dev_t *hw, uint32_t gpio_num, gpio_io_config_t *io_config)
|
||||
{
|
||||
uint32_t bit_shift = (gpio_num < 32) ? gpio_num : (gpio_num - 32);
|
||||
uint32_t bit_mask = 1 << bit_shift;
|
||||
uint32_t iomux_reg_val = REG_READ(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
io_config->pu = (iomux_reg_val & FUN_PU_M) >> FUN_PU_S;
|
||||
io_config->pd = (iomux_reg_val & FUN_PD_M) >> FUN_PD_S;
|
||||
io_config->ie = (iomux_reg_val & FUN_IE_M) >> FUN_IE_S;
|
||||
io_config->oe = (((gpio_num < 32) ? hw->enable : hw->enable1.val) & bit_mask) >> bit_shift;
|
||||
io_config->oe_ctrl_by_periph = !(hw->func_out_sel_cfg[gpio_num].oen_sel);
|
||||
io_config->oe_inv = hw->func_out_sel_cfg[gpio_num].oen_inv_sel;
|
||||
io_config->od = hw->pin[gpio_num].pad_driver;
|
||||
gpio_ll_get_drive_capability(hw, gpio_num, &(io_config->drv)); // specific workaround in the LL
|
||||
io_config->fun_sel = (iomux_reg_val & MCU_SEL_M) >> MCU_SEL_S;
|
||||
io_config->sig_out = hw->func_out_sel_cfg[gpio_num].func_sel;
|
||||
io_config->slp_sel = (iomux_reg_val & SLP_SEL_M) >> SLP_SEL_S;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,442 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in hal/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "hal/gpio_types.h"
|
||||
#include "hal/assert.h"
|
||||
#include "soc/rtc_io_struct.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/rtc_periph.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/usb_serial_jtag_reg.h"
|
||||
#include "soc/usb_serial_jtag_struct.h"
|
||||
#include "soc/sens_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RTCIO_LL_PIN_FUNC 0
|
||||
|
||||
typedef enum {
|
||||
RTCIO_LL_FUNC_RTC = 0x0, /*!< The pin controlled by RTC module. */
|
||||
RTCIO_LL_FUNC_DIGITAL = 0x1, /*!< The pin controlled by DIGITAL module. */
|
||||
} rtcio_ll_func_t;
|
||||
|
||||
typedef enum {
|
||||
RTCIO_LL_OUTPUT_NORMAL = 0, /*!< RTCIO output mode is normal. */
|
||||
RTCIO_LL_OUTPUT_OD = 0x1, /*!< RTCIO output mode is open-drain. */
|
||||
} rtcio_ll_out_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Enable/Disable LP IOMUX clock.
|
||||
*
|
||||
* @param enable true to enable the clock / false to disable the clock
|
||||
*/
|
||||
static inline void rtcio_ll_enable_io_clock(bool enable)
|
||||
{
|
||||
SENS.sar_peri_clk_gate_conf.iomux_clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select a RTC IOMUX function for the RTC IO
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @param func Function to assign to the pin
|
||||
*/
|
||||
static inline void rtcio_ll_iomux_func_sel(int rtcio_num, int func)
|
||||
{
|
||||
SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, 0x3, func, rtc_io_desc[rtcio_num].func);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Select the rtcio function.
|
||||
*
|
||||
* @note The RTC function must be selected before the pad analog function is enabled.
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @param func Select pin function.
|
||||
*/
|
||||
static inline void rtcio_ll_function_select(int rtcio_num, rtcio_ll_func_t func)
|
||||
{
|
||||
if (func == RTCIO_LL_FUNC_RTC) {
|
||||
// Disable USB Serial JTAG if pin 19 or pin 20 needs to select the rtc function
|
||||
if (rtcio_num == rtc_io_num_map[USB_INT_PHY0_DM_GPIO_NUM] || rtcio_num == rtc_io_num_map[USB_INT_PHY0_DP_GPIO_NUM]) {
|
||||
USB_SERIAL_JTAG.conf0.usb_pad_enable = 0;
|
||||
}
|
||||
// 0: GPIO connected to digital GPIO module. 1: GPIO connected to analog RTC module.
|
||||
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
|
||||
//0:RTC FUNCTION 1,2,3:Reserved
|
||||
rtcio_ll_iomux_func_sel(rtcio_num, RTCIO_LL_PIN_FUNC);
|
||||
} else if (func == RTCIO_LL_FUNC_DIGITAL) {
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, (rtc_io_desc[rtcio_num].mux));
|
||||
// USB Serial JTAG pad re-enable won't be done here (it requires both DM and DP pins not in rtc function)
|
||||
// Instead, USB_SERIAL_JTAG_USB_PAD_ENABLE needs to be guaranteed to be set in usb_serial_jtag driver
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable rtcio output.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_output_enable(int rtcio_num)
|
||||
{
|
||||
RTCIO.enable_w1ts.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TS_S));
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable rtcio output.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_output_disable(int rtcio_num)
|
||||
{
|
||||
RTCIO.enable_w1tc.val = (1U << (rtcio_num + RTC_GPIO_ENABLE_W1TC_S));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set RTCIO output level.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @param level 0: output low; ~0: output high.
|
||||
*/
|
||||
static inline void rtcio_ll_set_level(int rtcio_num, uint32_t level)
|
||||
{
|
||||
if (level) {
|
||||
RTCIO.out_w1ts.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TS_S));
|
||||
} else {
|
||||
RTCIO.out_w1tc.val = (1U << (rtcio_num + RTC_GPIO_OUT_DATA_W1TC_S));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable rtcio input.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_input_enable(int rtcio_num)
|
||||
{
|
||||
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].ie);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable rtcio input.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_input_disable(int rtcio_num)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].ie);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get RTCIO input level.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @return 0: input low; ~0: input high.
|
||||
*/
|
||||
static inline uint32_t rtcio_ll_get_level(int rtcio_num)
|
||||
{
|
||||
return (uint32_t)(RTCIO.in_val.in >> rtcio_num) & 0x1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RTC GPIO pad drive capability
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @param strength Drive capability of the pad. Range: 0 ~ 3.
|
||||
*/
|
||||
static inline void rtcio_ll_set_drive_capability(int rtcio_num, uint32_t strength)
|
||||
{
|
||||
if (rtc_io_desc[rtcio_num].drv_v) {
|
||||
uint32_t drv_cap = strength;
|
||||
// DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target
|
||||
if (rtcio_num == RTCIO_GPIO17_CHANNEL || rtcio_num == RTCIO_GPIO18_CHANNEL) {
|
||||
drv_cap = ((drv_cap & 0x1) << 1) | ((drv_cap & 0x2) >> 1); // swap bit0 and bit1
|
||||
}
|
||||
SET_PERI_REG_BITS(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, drv_cap, rtc_io_desc[rtcio_num].drv_s);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get RTC GPIO pad drive capability.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @return Drive capability of the pad. Range: 0 ~ 3.
|
||||
*/
|
||||
static inline uint32_t rtcio_ll_get_drive_capability(int rtcio_num)
|
||||
{
|
||||
uint32_t strength = GET_PERI_REG_BITS2(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].drv_v, rtc_io_desc[rtcio_num].drv_s);
|
||||
// DRV = 1 and DRV = 2 register bits are flipped for IO17, IO18 on the target
|
||||
if (rtcio_num == RTCIO_GPIO17_CHANNEL || rtcio_num == RTCIO_GPIO18_CHANNEL) {
|
||||
strength = ((strength & 0x1) << 1) | ((strength & 0x2) >> 1); // swap bit0 and bit1
|
||||
}
|
||||
return strength;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set RTC GPIO pad output mode.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @return mode Output mode.
|
||||
*/
|
||||
static inline void rtcio_ll_output_mode_set(int rtcio_num, rtcio_ll_out_mode_t mode)
|
||||
{
|
||||
RTCIO.pin[rtcio_num].pad_driver = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* RTC GPIO pullup enable.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_pullup_enable(int rtcio_num)
|
||||
{
|
||||
if (rtc_io_desc[rtcio_num].pullup) {
|
||||
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RTC GPIO pullup disable.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_pullup_disable(int rtcio_num)
|
||||
{
|
||||
// The pull-up value of the USB pins are controlled by the pins’ pull-up value together with USB pull-up value
|
||||
// USB DP pin is default to PU enabled
|
||||
// Note that from esp32s3 ECO1, USB_EXCHG_PINS feature has been supported. If this efuse is burnt, the gpio pin
|
||||
// which should be checked is USB_INT_PHY0_DM_GPIO_NUM instead.
|
||||
if (rtcio_num == USB_INT_PHY0_DP_GPIO_NUM) {
|
||||
SET_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_PAD_PULL_OVERRIDE);
|
||||
CLEAR_PERI_REG_MASK(USB_SERIAL_JTAG_CONF0_REG, USB_SERIAL_JTAG_DP_PULLUP);
|
||||
}
|
||||
if (rtc_io_desc[rtcio_num].pullup) {
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get RTC GPIO pad pullup status.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @return Whether the pullup of the pad is enabled or not.
|
||||
*/
|
||||
static inline bool rtcio_ll_is_pullup_enabled(int rtcio_num)
|
||||
{
|
||||
if (rtc_io_desc[rtcio_num].pullup) {
|
||||
return GET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pullup);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RTC GPIO pulldown enable.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_pulldown_enable(int rtcio_num)
|
||||
{
|
||||
if (rtc_io_desc[rtcio_num].pulldown) {
|
||||
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RTC GPIO pulldown disable.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_pulldown_disable(int rtcio_num)
|
||||
{
|
||||
if (rtc_io_desc[rtcio_num].pulldown) {
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get RTC GPIO pad pulldown status.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @return Whether the pulldown of the pad is enabled or not.
|
||||
*/
|
||||
static inline bool rtcio_ll_is_pulldown_enabled(int rtcio_num)
|
||||
{
|
||||
if (rtc_io_desc[rtcio_num].pulldown) {
|
||||
return GET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].pulldown);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable force hold function on an RTC IO pad.
|
||||
*
|
||||
* Enabling HOLD function will cause the pad to lock current status, such as,
|
||||
* input/output enable, input/output value, function, drive strength values.
|
||||
* This function is useful when going into light or deep sleep mode to prevent
|
||||
* the pin configuration from changing.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_force_hold_enable(int rtcio_num)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, rtc_io_desc[rtcio_num].hold_force);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable hold function on an RTC IO pad.
|
||||
*
|
||||
* @note If disable the pad hold, the status of pad maybe changed in sleep mode.
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_force_hold_disable(int rtcio_num)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, rtc_io_desc[rtcio_num].hold_force);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable force hold function on all RTC IO pads.
|
||||
*
|
||||
* Enabling HOLD function will cause the pad to lock current status, such as,
|
||||
* input/output enable, input/output value, function, drive strength values.
|
||||
* This function is useful when going into light or deep sleep mode to prevent
|
||||
* the pin configuration from changing.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_force_hold_all(void)
|
||||
{
|
||||
SET_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable hold function on all RTC IO pads.
|
||||
*
|
||||
* @note If disable the pad hold, the status of pad maybe changed in sleep mode.
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_force_unhold_all(void)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_PWC_REG, RTC_CNTL_PAD_FORCE_HOLD_M);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable wakeup function and set wakeup type from light sleep status for rtcio.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @param type Wakeup on high level or low level.
|
||||
*/
|
||||
static inline void rtcio_ll_wakeup_enable(int rtcio_num, gpio_int_type_t type)
|
||||
{
|
||||
HAL_ASSERT(type == GPIO_INTR_LOW_LEVEL || type == GPIO_INTR_HIGH_LEVEL);
|
||||
RTCIO.pin[rtcio_num].wakeup_enable = 1;
|
||||
RTCIO.pin[rtcio_num].int_type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable wakeup function from light sleep status for rtcio.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_wakeup_disable(int rtcio_num)
|
||||
{
|
||||
RTCIO.pin[rtcio_num].wakeup_enable = 0;
|
||||
RTCIO.pin[rtcio_num].int_type = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable rtc io output in deep sleep.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_enable_output_in_sleep(int rtcio_num)
|
||||
{
|
||||
if (rtc_io_desc[rtcio_num].slpoe) {
|
||||
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].slpoe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable rtc io output in deep sleep.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_disable_output_in_sleep(int rtcio_num)
|
||||
{
|
||||
if (rtc_io_desc[rtcio_num].slpoe) {
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].slpoe);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable rtc io input in deep sleep.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_enable_input_in_sleep(int rtcio_num)
|
||||
{
|
||||
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].slpie);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable rtc io input in deep sleep.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_disable_input_in_sleep(int rtcio_num)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].slpie);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable rtc io keep another setting in deep sleep.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_enable_sleep_setting(int rtcio_num)
|
||||
{
|
||||
SET_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].slpsel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable rtc io keep another setting in deep sleep. (Default)
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
*/
|
||||
static inline void rtcio_ll_disable_sleep_setting(int rtcio_num)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(rtc_io_desc[rtcio_num].reg, rtc_io_desc[rtcio_num].slpsel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set specific logic level on an RTC IO pin as a wakeup trigger.
|
||||
*
|
||||
* @param rtcio_num The index of rtcio. 0 ~ MAX(rtcio).
|
||||
* @param level Logic level (0)
|
||||
*/
|
||||
static inline void rtcio_ll_ext0_set_wakeup_pin(int rtcio_num, int level)
|
||||
{
|
||||
REG_SET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL, rtcio_num);
|
||||
// Set level which will trigger wakeup
|
||||
SET_PERI_REG_BITS(RTC_CNTL_EXT_WAKEUP_CONF_REG, 0x1,
|
||||
level , RTC_CNTL_EXT_WAKEUP0_LV_S);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "hal/assert.h"
|
||||
#include "hal/misc.h"
|
||||
#include "soc/gpio_sd_struct.h"
|
||||
#include "soc/gpio_sd_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Get SDM register base address with giving group number
|
||||
#define SDM_LL_GET_HW(group_id) ((group_id == 0) ? (&SDM) : NULL)
|
||||
|
||||
#define SDM_LL_PRESCALE_MAX (GPIO_SD0_PRESCALE_V + 1)
|
||||
|
||||
// Support APB as function clock
|
||||
#define SDM_LL_FUNC_CLOCK_SUPPORT_APB 1
|
||||
|
||||
/**
|
||||
* @brief Set Sigma-delta enable
|
||||
*
|
||||
* @param hw Peripheral SIGMADELTA hardware instance address.
|
||||
* @param en Sigma-delta enable value
|
||||
*/
|
||||
static inline void sdm_ll_enable_clock(gpio_sd_dev_t *hw, bool en)
|
||||
{
|
||||
hw->misc.function_clk_en = en;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Sigma-delta channel duty.
|
||||
*
|
||||
* @param hw Peripheral SIGMADELTA hardware instance address.
|
||||
* @param channel Sigma-delta channel number
|
||||
* @param density Sigma-delta quantized density of one channel, the value ranges from -128 to 127, recommended range is -90 ~ 90.
|
||||
* The waveform is more like a random one in this range.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void sdm_ll_set_pulse_density(gpio_sd_dev_t *hw, int channel, int8_t density)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[channel], duty, (uint32_t)density);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Sigma-delta channel's clock pre-scale value.
|
||||
*
|
||||
* @param hw Peripheral SIGMADELTA hardware instance address.
|
||||
* @param channel Sigma-delta channel number
|
||||
* @param prescale The divider of source clock, ranges from 1 to 256
|
||||
*/
|
||||
static inline void sdm_ll_set_prescale(gpio_sd_dev_t *hw, int channel, uint32_t prescale)
|
||||
{
|
||||
HAL_ASSERT(prescale && prescale <= SDM_LL_PRESCALE_MAX);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->channel[channel], prescale, prescale - 1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user