Skip to content

Commit 1123fe9

Browse files
committed
hal: Changes to support ULP
Add files and changes to ULP component to support Zephyr's build. Add ULP component based on a2f420a36ecf8cd19b443adde1d75e5eaecc6309 Signed-off-by: Lucas Tamborrino <[email protected]>
1 parent 045afd4 commit 1123fe9

File tree

19 files changed

+867
-103
lines changed

19 files changed

+867
-103
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include "soc/soc_caps.h"
10+
#include "esp_err.h"
11+
#include "driver/gpio.h"
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
#if SOC_LP_GPIO_MATRIX_SUPPORTED
18+
/**
19+
* @brief Connect a RTC(LP) GPIO input with a peripheral signal, which tagged as input attribute
20+
*
21+
* @note There's no limitation on the number of signals that a RTC(LP) GPIO can connect with
22+
*
23+
* @param gpio_num GPIO number, especially, `LP_GPIO_MATRIX_CONST_ZERO_INPUT` means connect logic 0 to signal
24+
* `LP_GPIO_MATRIX_CONST_ONE_INPUT` means connect logic 1 to signal
25+
* @param signal_idx LP peripheral signal index (tagged as input attribute)
26+
* @param inv Whether the RTC(LP) GPIO input to be inverted or not
27+
* @return
28+
* - ESP_OK Success
29+
* - ESP_ERR_INVALID_ARG Parameter error
30+
*/
31+
esp_err_t lp_gpio_connect_in_signal(gpio_num_t gpio_num, uint32_t signal_idx, bool inv);
32+
33+
/**
34+
* @brief Connect a peripheral signal which tagged as output attribute with a RTC(LP) GPIO
35+
*
36+
* @note There's no limitation on the number of RTC(LP) GPIOs that a signal can connect with
37+
*
38+
* @param gpio_num GPIO number
39+
* @param signal_idx LP peripheral signal index (tagged as input attribute), especially, `SIG_LP_GPIO_OUT_IDX` means disconnect RTC(LP) GPIO and other peripherals. Only the RTC GPIO driver can control the output level
40+
* @param out_inv Whether to signal to be inverted or not
41+
* @param out_en_inv Whether the output enable control is inverted or not
42+
* @return
43+
* - ESP_OK Success
44+
* - ESP_ERR_INVALID_ARG Parameter error
45+
*/
46+
esp_err_t lp_gpio_connect_out_signal(gpio_num_t gpio_num, uint32_t signal_idx, bool out_inv, bool out_en_inv);
47+
#endif // SOC_LP_GPIO_MATRIX_SUPPORTED
48+
49+
#ifdef __cplusplus
50+
}
51+
#endif

components/driver/gpio/include/driver/rtc_io.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,18 @@ esp_err_t rtc_gpio_set_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t st
198198
*/
199199
esp_err_t rtc_gpio_get_drive_capability(gpio_num_t gpio_num, gpio_drive_cap_t* strength);
200200

201+
/**
202+
* @brief Select a RTC IOMUX function for the RTC IO
203+
*
204+
* @param gpio_num GPIO number
205+
* @param func Function to assign to the pin
206+
*
207+
* @return
208+
* - ESP_OK Success
209+
* - ESP_ERR_INVALID_ARG Parameter error
210+
*/
211+
esp_err_t rtc_gpio_iomux_func_sel(gpio_num_t gpio_num, int func);
212+
201213
#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
202214

203215
#if SOC_RTCIO_HOLD_SUPPORTED

components/driver/gpio/rtc_io.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ esp_err_t rtc_gpio_pulldown_dis(gpio_num_t gpio_num)
145145
return ESP_OK;
146146
}
147147

148+
#ifdef CONFIG_SOC_SERIES_ESP32C6
149+
esp_err_t rtc_gpio_iomux_func_sel(gpio_num_t gpio_num, int func)
150+
{
151+
ESP_RETURN_ON_FALSE(rtc_gpio_is_valid_gpio(gpio_num), ESP_ERR_INVALID_ARG, RTCIO_TAG, "RTCIO number error");
152+
RTCIO_ENTER_CRITICAL();
153+
rtcio_hal_iomux_func_sel(rtc_io_number_get(gpio_num), func);
154+
RTCIO_EXIT_CRITICAL();
155+
156+
return ESP_OK;
157+
}
158+
#endif
148159
#endif // SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
149160

150161
#if SOC_RTCIO_HOLD_SUPPORTED

components/esp_hw_support/include/esp_private/periph_ctrl.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,55 @@
1111
extern "C" {
1212
#endif
1313

14+
/**
15+
* @defgroup Reset and Clock Control APIs
16+
* @{
17+
*/
18+
19+
/**
20+
* @brief Acquire the RCC lock for a peripheral module
21+
*
22+
* @note User code protected by this macro should be as short as possible, because it's a critical section
23+
* @note This macro will increase the reference lock of that peripheral.
24+
* You can get the value before the increment from the `rc_name` local variable
25+
*/
26+
#define PERIPH_RCC_ACQUIRE_ATOMIC(rc_periph, rc_name) \
27+
for (uint8_t rc_name, _rc_cnt = 1, __DECLARE_RCC_RC_ATOMIC_ENV; \
28+
_rc_cnt ? (rc_name = periph_rcc_acquire_enter(rc_periph), 1) : 0; \
29+
periph_rcc_acquire_exit(rc_periph, rc_name), _rc_cnt--)
30+
31+
/**
32+
* @brief Release the RCC lock for a peripheral module
33+
*
34+
* @note User code protected by this macro should be as short as possible, because it's a critical section
35+
* @note This macro will decrease the reference lock of that peripheral.
36+
* You can get the value after the decrease from the `rc_name` local variable
37+
*/
38+
#define PERIPH_RCC_RELEASE_ATOMIC(rc_periph, rc_name) \
39+
for (uint8_t rc_name, _rc_cnt = 1, __DECLARE_RCC_RC_ATOMIC_ENV; \
40+
_rc_cnt ? (rc_name = periph_rcc_release_enter(rc_periph), 1) : 0; \
41+
periph_rcc_release_exit(rc_periph, rc_name), _rc_cnt--)
42+
43+
/**
44+
* @brief A simplified version of `PERIPH_RCC_ACQUIRE/RELEASE_ATOMIC`, without a reference count
45+
*
46+
* @note User code protected by this macro should be as short as possible, because it's a critical section
47+
*/
48+
#define PERIPH_RCC_ATOMIC() \
49+
for (int _rc_cnt = 1, __DECLARE_RCC_ATOMIC_ENV; \
50+
_rc_cnt ? (periph_rcc_enter(), 1) : 0; \
51+
periph_rcc_exit(), _rc_cnt--)
52+
53+
/** @cond */
54+
// The following functions are not intended to be used directly by the developers
55+
uint8_t periph_rcc_acquire_enter(periph_module_t periph);
56+
void periph_rcc_acquire_exit(periph_module_t periph, uint8_t ref_count);
57+
uint8_t periph_rcc_release_enter(periph_module_t periph);
58+
void periph_rcc_release_exit(periph_module_t periph, uint8_t ref_count);
59+
void periph_rcc_enter(void);
60+
void periph_rcc_exit(void);
61+
/** @endcond */
62+
1463
/**
1564
* @brief Enable peripheral module by un-gating the clock and de-asserting the reset signal.
1665
*
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
2+
/*
3+
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#pragma once
9+
10+
#include "soc/soc_caps.h"
11+
#include "esp_private/periph_ctrl.h"
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
#if SOC_PERIPH_CLK_CTRL_SHARED
18+
#define HP_UART_SRC_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
19+
#else
20+
#define HP_UART_SRC_CLK_ATOMIC()
21+
#endif
22+
23+
#if SOC_RCC_IS_INDEPENDENT
24+
#define HP_UART_BUS_CLK_ATOMIC()
25+
#else
26+
#define HP_UART_BUS_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
27+
#endif
28+
29+
#if (SOC_UART_LP_NUM >= 1)
30+
#define LP_UART_SRC_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
31+
#define LP_UART_BUS_CLK_ATOMIC() PERIPH_RCC_ATOMIC()
32+
#endif
33+
34+
#ifdef __cplusplus
35+
}
36+
#endif

components/esp_hw_support/periph_ctrl.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,40 @@ static int periph_spinlock;
2121

2222
static uint8_t ref_counts[PERIPH_MODULE_MAX] = {0};
2323

24+
IRAM_ATTR void periph_rcc_enter(void)
25+
{
26+
ENTER_CRITICAL_SECTION();
27+
}
28+
29+
IRAM_ATTR void periph_rcc_exit(void)
30+
{
31+
LEAVE_CRITICAL_SECTION();
32+
}
33+
34+
IRAM_ATTR uint8_t periph_rcc_acquire_enter(periph_module_t periph)
35+
{
36+
periph_rcc_enter();
37+
return ref_counts[periph];
38+
}
39+
40+
IRAM_ATTR void periph_rcc_acquire_exit(periph_module_t periph, uint8_t ref_count)
41+
{
42+
ref_counts[periph] = ++ref_count;
43+
periph_rcc_exit();
44+
}
45+
46+
IRAM_ATTR uint8_t periph_rcc_release_enter(periph_module_t periph)
47+
{
48+
periph_rcc_enter();
49+
return ref_counts[periph] - 1;
50+
}
51+
52+
IRAM_ATTR void periph_rcc_release_exit(periph_module_t periph, uint8_t ref_count)
53+
{
54+
ref_counts[periph] = ref_count;
55+
periph_rcc_exit();
56+
}
57+
2458
void periph_module_enable(periph_module_t periph)
2559
{
2660
assert(periph < PERIPH_MODULE_MAX);
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/*******************************************************************************
8+
* NOTICE
9+
* The hal is not public api, don't use it in application code.
10+
******************************************************************************/
11+
12+
#pragma once
13+
14+
#include <stdbool.h>
15+
#include <stdint.h>
16+
#include "soc/lpperi_struct.h"
17+
#include "soc/pmu_struct.h"
18+
#include "soc/lp_aon_struct.h"
19+
20+
#ifdef __cplusplus
21+
extern "C" {
22+
#endif
23+
24+
25+
#define LP_CORE_LL_WAKEUP_SOURCE_HP_CPU BIT(0) // Started by HP core (1 single wakeup)
26+
#define LP_CORE_LL_WAKEUP_SOURCE_LP_UART BIT(1) // Enable wake-up by a certain number of LP UART RX pulses
27+
#define LP_CORE_LL_WAKEUP_SOURCE_LP_IO BIT(2) // Enable wake-up by LP IO interrupt
28+
#define LP_CORE_LL_WAKEUP_SOURCE_ETM BIT(3) // Enable wake-up by ETM event
29+
#define LP_CORE_LL_WAKEUP_SOURCE_LP_TIMER BIT(4) // Enable wake-up by LP timer
30+
31+
/**
32+
* @brief Enable the bus clock for LP-core
33+
*
34+
* @param enable Enable if true, disable if false
35+
*/
36+
static inline void lp_core_ll_enable_bus_clock(bool enable)
37+
{
38+
/* ESP32C6 does not have clk/rst periph control for LP-core */
39+
(void)enable;
40+
}
41+
42+
/**
43+
* @brief Reset the lp_core module
44+
*
45+
*/
46+
static inline void lp_core_ll_reset_register(void)
47+
{
48+
/* ESP32C6 does not have clk/rst periph control for LP-core */
49+
}
50+
51+
/**
52+
* @brief Enable fast access of LP memory
53+
*
54+
* @note When fast access is activated, LP-core cannot access LP mem during deep sleep
55+
*
56+
* @param enable Enable if true, disable if false
57+
*/
58+
static inline void lp_core_ll_fast_lp_mem_enable(bool enable)
59+
{
60+
LP_AON.lpbus.fast_mem_mux_sel = enable;
61+
LP_AON.lpbus.fast_mem_mux_sel_update = 1;
62+
}
63+
64+
/**
65+
* @brief Trigger a LP_CORE_LL_WAKEUP_SOURCE_HP_CPU wake-up on the LP-core
66+
*
67+
*/
68+
static inline void lp_core_ll_hp_wake_lp(void)
69+
{
70+
PMU.hp_lp_cpu_comm.hp_trigger_lp = 1;
71+
}
72+
73+
/**
74+
* @brief Enable the debug module of LP-core, allowing JTAG to connect
75+
*
76+
* @param enable Enable if true, disable if false
77+
*/
78+
static inline void lp_core_ll_debug_module_enable(bool enable)
79+
{
80+
LPPERI.cpu.lpcore_dbgm_unavaliable = !enable;
81+
}
82+
83+
/**
84+
* @brief Enable CPU reset at sleep
85+
*
86+
* @param enable Enable if true, disable if false
87+
*/
88+
static inline void lp_core_ll_rst_at_sleep_enable(bool enable)
89+
{
90+
PMU.lp_ext.pwr0.slp_reset_en = enable;
91+
}
92+
93+
/**
94+
* @brief Stall LP-core at sleep requests
95+
*
96+
* @param enable Enable if true, disable if false
97+
*/
98+
static inline void lp_core_ll_stall_at_sleep_request(bool enable)
99+
{
100+
PMU.lp_ext.pwr0.slp_stall_en = enable;
101+
}
102+
103+
/**
104+
* @brief Set wake-up sources for the LP-core
105+
*
106+
* @param flags Wake-up sources
107+
*/
108+
static inline void lp_core_ll_set_wakeup_source(uint32_t flags)
109+
{
110+
PMU.lp_ext.pwr1.wakeup_en = flags;
111+
}
112+
113+
/**
114+
* @brief Get wake-up sources for the LP-core
115+
*/
116+
static inline uint32_t lp_core_ll_get_wakeup_source(void)
117+
{
118+
return PMU.lp_ext.pwr1.wakeup_en;
119+
}
120+
121+
/**
122+
* @brief Request PMU to put LP core to sleep
123+
*/
124+
static inline void lp_core_ll_request_sleep(void)
125+
{
126+
PMU.lp_ext.pwr1.sleep_req = 1;
127+
}
128+
129+
/**
130+
* @brief Get which interrupts have triggered on the LP core
131+
*
132+
* @return uint8_t bit mask of triggered LP interrupt sources
133+
*/
134+
static inline uint8_t lp_core_ll_get_triggered_interrupt_srcs(void)
135+
{
136+
return LPPERI.interrupt_source.lp_interrupt_source;
137+
}
138+
139+
/**
140+
* @brief Get the flag that marks whether LP CPU is awakened by ETM
141+
*
142+
* @return Return true if lpcore is woken up by soc_etm
143+
*/
144+
static inline bool lp_core_ll_get_etm_wakeup_flag(void)
145+
{
146+
return LP_AON.lpcore.lpcore_etm_wakeup_flag;
147+
}
148+
149+
/**
150+
* @brief Clear the flag that marks whether LP CPU is awakened by soc_etm
151+
*/
152+
static inline void lp_core_ll_clear_etm_wakeup_flag(void)
153+
{
154+
LP_AON.lpcore.lpcore_etm_wakeup_flag_clr = 0x01;
155+
}
156+
157+
#ifdef __cplusplus
158+
}
159+
#endif

components/hal/esp32c6/include/hal/pmu_ll.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,16 @@ FORCE_INLINE_ATTR void pmu_ll_lp_clear_intsts_mask(pmu_dev_t *hw, uint32_t mask)
542542
hw->lp_ext.int_clr.val = mask;
543543
}
544544

545+
FORCE_INLINE_ATTR void pmu_ll_lp_clear_sw_intr_status(pmu_dev_t *hw)
546+
{
547+
hw->lp_ext.int_clr.sw_trigger = 1;
548+
}
549+
550+
FORCE_INLINE_ATTR void pmu_ll_lp_enable_sw_intr(pmu_dev_t *hw, bool enable)
551+
{
552+
hw->lp_ext.int_ena.sw_trigger = enable;
553+
}
554+
545555
FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle)
546556
{
547557
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->wakeup.cntl3, lp_min_slp_val, slow_clk_cycle);

0 commit comments

Comments
 (0)