mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'refactor/rcc_critical_section_follow_up' into 'master'
refactor(lp_periph): move enable and reset control to LL driver See merge request espressif/esp-idf!25498
This commit is contained in:
commit
cd9f48823d
@ -27,7 +27,6 @@
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/uart_select.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/lp_periph_ctrl.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
@ -77,7 +76,6 @@ static const char *UART_TAG = "uart";
|
||||
| (UART_INTR_PARITY_ERR))
|
||||
#endif
|
||||
|
||||
|
||||
#define UART_ENTER_CRITICAL_SAFE(spinlock) esp_os_enter_critical_safe(spinlock)
|
||||
#define UART_EXIT_CRITICAL_SAFE(spinlock) esp_os_exit_critical_safe(spinlock)
|
||||
#define UART_ENTER_CRITICAL_ISR(spinlock) esp_os_enter_critical_isr(spinlock)
|
||||
@ -85,7 +83,6 @@ static const char *UART_TAG = "uart";
|
||||
#define UART_ENTER_CRITICAL(spinlock) esp_os_enter_critical(spinlock)
|
||||
#define UART_EXIT_CRITICAL(spinlock) esp_os_exit_critical(spinlock)
|
||||
|
||||
|
||||
// Check actual UART mode set
|
||||
#define UART_IS_MODE_SET(uart_number, mode) ((p_uart_obj[uart_number]->uart_mode == mode))
|
||||
|
||||
@ -189,8 +186,10 @@ static void uart_module_enable(uart_port_t uart_num)
|
||||
}
|
||||
#if (SOC_UART_LP_NUM >= 1)
|
||||
else {
|
||||
lp_periph_module_enable(uart_periph_signal[uart_num].lp_module);
|
||||
lp_periph_module_reset(uart_periph_signal[uart_num].lp_module);
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lp_uart_ll_enable_bus_clock(uart_num - SOC_UART_HP_NUM, true);
|
||||
lp_uart_ll_reset_register(uart_num - SOC_UART_HP_NUM);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
uart_context[uart_num].hw_enabled = true;
|
||||
@ -207,7 +206,9 @@ static void uart_module_disable(uart_port_t uart_num)
|
||||
}
|
||||
#if (SOC_UART_LP_NUM >= 1)
|
||||
else if (uart_num >= SOC_UART_HP_NUM) {
|
||||
lp_periph_module_disable(uart_periph_signal[uart_num].lp_module);
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lp_uart_ll_enable_bus_clock(uart_num - SOC_UART_HP_NUM, false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
uart_context[uart_num].hw_enabled = false;
|
||||
@ -561,7 +562,6 @@ esp_err_t uart_enable_pattern_det_baud_intr(uart_port_t uart_num, char pattern_c
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t uart_disable_pattern_det_intr(uart_port_t uart_num)
|
||||
{
|
||||
return uart_disable_intr_mask(uart_num, UART_INTR_CMD_CHAR_DET);
|
||||
@ -747,7 +747,9 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
|
||||
}
|
||||
#if (SOC_UART_LP_NUM >= 1)
|
||||
else {
|
||||
lp_periph_set_clk_src(uart_periph_signal[uart_num].lp_module, uart_sclk_sel);
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lp_uart_ll_set_source_clk(uart_context[uart_num].hal.dev, (soc_periph_lp_uart_clk_src_t)uart_sclk_sel);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq);
|
||||
|
@ -36,10 +36,6 @@ if(NOT BOOTLOADER_BUILD)
|
||||
"port/${target}/esp_clk_tree.c"
|
||||
"port/esp_clk_tree_common.c")
|
||||
|
||||
if(CONFIG_SOC_LP_PERIPHERALS_SUPPORTED)
|
||||
list(APPEND srcs "lp_periph_ctrl.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_ADC_SUPPORTED)
|
||||
list(APPEND srcs "adc_share_hw_ctrl.c")
|
||||
endif()
|
||||
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/soc_caps.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if SOC_LP_PERIPHERALS_SUPPORTED
|
||||
/**
|
||||
* @brief Enable LP peripheral module by un-gating the clock and de-asserting the reset signal.
|
||||
*
|
||||
* @param[in] lp_periph LP peripheral module
|
||||
*
|
||||
* @note If @c lp_periph_module_enable() is called a number of times,
|
||||
* @c lp_periph_module_disable() has to be called the same number of times,
|
||||
* in order to put the peripheral into disabled state.
|
||||
*/
|
||||
void lp_periph_module_enable(lp_periph_module_t lp_periph);
|
||||
|
||||
/**
|
||||
* @brief Disable LP peripheral module by gating the clock and asserting the reset signal.
|
||||
*
|
||||
* @param[in] lp_periph LP peripheral module
|
||||
*
|
||||
* @note If @c lp_periph_module_enable() is called a number of times,
|
||||
* @c lp_periph_module_disable() has to be called the same number of times,
|
||||
* in order to put the peripheral into disabled state.
|
||||
*/
|
||||
void lp_periph_module_disable(lp_periph_module_t lp_periph);
|
||||
|
||||
/**
|
||||
* @brief Reset LP peripheral module by asserting and de-asserting the reset signal.
|
||||
*
|
||||
* @param[in] lp_periph LP peripheral module
|
||||
*
|
||||
* @note Calling this function does not enable or disable the clock for the module.
|
||||
*/
|
||||
void lp_periph_module_reset(lp_periph_module_t lp_periph);
|
||||
|
||||
/**
|
||||
* @brief Set LP peripheral module clock source.
|
||||
*
|
||||
* @param[in] lp_periph LP peripheral module
|
||||
* @param[in] clk_src Module clock source, check soc/clk_tree_defs.h for the available clock sources for each LP peripheral
|
||||
*/
|
||||
void lp_periph_set_clk_src(lp_periph_module_t lp_periph, soc_module_clk_t clk_src);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_private/lp_periph_ctrl.h"
|
||||
#include "hal/lp_periph_clk_ctrl_ll.h"
|
||||
|
||||
static portMUX_TYPE lp_periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static uint8_t ref_counts[LP_PERIPH_MODULE_MAX] = {0};
|
||||
|
||||
void lp_periph_module_enable(lp_periph_module_t lp_periph)
|
||||
{
|
||||
portENTER_CRITICAL(&lp_periph_spinlock);
|
||||
if (ref_counts[lp_periph] == 0) {
|
||||
// Enable clock and clear reset
|
||||
lp_periph_ll_enable_clk_clear_rst(lp_periph);
|
||||
}
|
||||
ref_counts[lp_periph]++;
|
||||
portEXIT_CRITICAL(&lp_periph_spinlock);
|
||||
}
|
||||
|
||||
void lp_periph_module_disable(lp_periph_module_t lp_periph)
|
||||
{
|
||||
portENTER_CRITICAL(&lp_periph_spinlock);
|
||||
ref_counts[lp_periph]--;
|
||||
if (ref_counts[lp_periph] == 0) {
|
||||
// Disable clock and set reset
|
||||
lp_periph_ll_disable_clk_set_rst(lp_periph);
|
||||
}
|
||||
portEXIT_CRITICAL(&lp_periph_spinlock);
|
||||
}
|
||||
|
||||
void lp_periph_module_reset(lp_periph_module_t lp_periph)
|
||||
{
|
||||
portENTER_CRITICAL(&lp_periph_spinlock);
|
||||
lp_periph_ll_reset(lp_periph);
|
||||
portEXIT_CRITICAL(&lp_periph_spinlock);
|
||||
}
|
||||
|
||||
void lp_periph_set_clk_src(lp_periph_module_t lp_periph, soc_module_clk_t clk_src)
|
||||
{
|
||||
portENTER_CRITICAL(&lp_periph_spinlock);
|
||||
lp_periph_ll_set_clk_src(lp_periph, clk_src);
|
||||
portEXIT_CRITICAL(&lp_periph_spinlock);
|
||||
}
|
@ -1,2 +1,2 @@
|
||||
| Supported Targets | ESP32-C6 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- |
|
||||
| Supported Targets | ESP32-C6 | ESP32-H2 | ESP32-P4 |
|
||||
| ----------------- | -------- | -------- | -------- |
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "hal/i2c_types.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/lp_clkrst_struct.h"
|
||||
#include "soc/lpperi_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -88,7 +89,7 @@ typedef enum {
|
||||
*/
|
||||
static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_freq, i2c_hal_clk_config_t *clk_cal)
|
||||
{
|
||||
uint32_t clkm_div = source_clk / (bus_freq * 1024) +1;
|
||||
uint32_t clkm_div = source_clk / (bus_freq * 1024) + 1;
|
||||
uint32_t sclk_freq = source_clk / clkm_div;
|
||||
uint32_t half_cycle = sclk_freq / bus_freq / 2;
|
||||
//SCL
|
||||
@ -97,7 +98,7 @@ static inline void i2c_ll_master_cal_bus_clk(uint32_t source_clk, uint32_t bus_f
|
||||
// default, scl_wait_high < scl_high
|
||||
// Make 80KHz as a boundary here, because when working at lower frequency, too much scl_wait_high will faster the frequency
|
||||
// according to some hardware behaviors.
|
||||
clk_cal->scl_wait_high = (bus_freq >= 80*1000) ? (half_cycle / 2 - 2) : (half_cycle / 4);
|
||||
clk_cal->scl_wait_high = (bus_freq >= 80 * 1000) ? (half_cycle / 2 - 2) : (half_cycle / 4);
|
||||
clk_cal->scl_high = half_cycle - clk_cal->scl_wait_high;
|
||||
clk_cal->sda_hold = half_cycle / 4;
|
||||
clk_cal->sda_sample = half_cycle / 2;
|
||||
@ -565,7 +566,7 @@ static inline void i2c_ll_get_stop_timing(i2c_dev_t *hw, int *setup_time, int *h
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for (int i = 0; i< len; i++) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->data, fifo_rdata, ptr[i]);
|
||||
}
|
||||
}
|
||||
@ -582,7 +583,7 @@ static inline void i2c_ll_write_txfifo(i2c_dev_t *hw, const uint8_t *ptr, uint8_
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_read_rxfifo(i2c_dev_t *hw, uint8_t *ptr, uint8_t len)
|
||||
{
|
||||
for(int i = 0; i < len; i++) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
ptr[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->data, fifo_rdata);
|
||||
}
|
||||
}
|
||||
@ -739,6 +740,62 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c
|
||||
PCR.i2c_sclk_conf.i2c_sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set LP I2C source clock
|
||||
*
|
||||
* @param hw Address offset of the LP I2C peripheral registers
|
||||
* @param src_clk Source clock for the LP I2C peripheral
|
||||
*/
|
||||
static inline void lp_i2c_ll_set_source_clk(i2c_dev_t *hw, soc_periph_lp_i2c_clk_src_t src_clk)
|
||||
{
|
||||
(void)hw;
|
||||
// src_clk : (0) for LP_FAST_CLK (RTC Fast), (1) for XTAL_D2_CLK
|
||||
switch (src_clk) {
|
||||
case LP_I2C_SCLK_LP_FAST:
|
||||
LP_CLKRST.lpperi.lp_i2c_clk_sel = 0;
|
||||
break;
|
||||
case LP_I2C_SCLK_XTAL_D2:
|
||||
LP_CLKRST.lpperi.lp_i2c_clk_sel = 1;
|
||||
break;
|
||||
default:
|
||||
// Invalid source clock selected
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// LP_CLKRST.lpperi is a shared register, so this function must be used in an atomic way
|
||||
#define lp_i2c_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_i2c_ll_set_source_clk(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Enable bus clock for the LP I2C module
|
||||
*
|
||||
* @param hw_id LP I2C instance ID
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void lp_i2c_ll_enable_bus_clock(int hw_id, bool enable)
|
||||
{
|
||||
(void)hw_id;
|
||||
LPPERI.clk_en.lp_ext_i2c_ck_en = enable;
|
||||
}
|
||||
|
||||
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
|
||||
#define lp_i2c_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_i2c_ll_enable_bus_clock(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Reset LP I2C module
|
||||
*
|
||||
* @param hw_id LP I2C instance ID
|
||||
*/
|
||||
static inline void lp_i2c_ll_reset_register(int hw_id)
|
||||
{
|
||||
(void)hw_id;
|
||||
LPPERI.reset_en.lp_ext_i2c_reset_en = 1;
|
||||
LPPERI.reset_en.lp_ext_i2c_reset_en = 0;
|
||||
}
|
||||
|
||||
/// LPPERI.reset_en is a shared register, so this function must be used in an atomic way
|
||||
#define lp_i2c_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_i2c_ll_reset_register(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Enable I2C peripheral controller clock
|
||||
*
|
||||
@ -808,7 +865,6 @@ static inline volatile void *i2c_ll_get_interrupt_status_reg(i2c_dev_t *dev)
|
||||
return &dev->int_status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable I2C slave clock stretch.
|
||||
*
|
||||
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/lpperi_reg.h"
|
||||
#include "soc/lp_clkrst_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static inline uint32_t lp_periph_ll_get_clk_en_mask(lp_periph_module_t lp_periph)
|
||||
{
|
||||
switch (lp_periph) {
|
||||
case LP_PERIPH_I2C0_MODULE:
|
||||
return LPPERI_LP_EXT_I2C_CK_EN;
|
||||
case LP_PERIPH_UART0_MODULE:
|
||||
return LPPERI_LP_UART_CK_EN;
|
||||
default:
|
||||
// Unsupported LP peripherals
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t lp_periph_ll_get_rst_en_mask(lp_periph_module_t lp_periph)
|
||||
{
|
||||
switch (lp_periph) {
|
||||
case LP_PERIPH_I2C0_MODULE:
|
||||
return LPPERI_LP_EXT_I2C_RESET_EN;
|
||||
case LP_PERIPH_UART0_MODULE:
|
||||
return LPPERI_LP_UART_RESET_EN;
|
||||
default:
|
||||
// Unsupported LP peripherals
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void lp_periph_ll_enable_clk_clear_rst(lp_periph_module_t lp_periph)
|
||||
{
|
||||
SET_PERI_REG_MASK(LPPERI_CLK_EN_REG, lp_periph_ll_get_clk_en_mask(lp_periph));
|
||||
CLEAR_PERI_REG_MASK(LPPERI_RESET_EN_REG, lp_periph_ll_get_rst_en_mask(lp_periph));
|
||||
}
|
||||
|
||||
static inline void lp_periph_ll_disable_clk_set_rst(lp_periph_module_t lp_periph)
|
||||
{
|
||||
CLEAR_PERI_REG_MASK(LPPERI_CLK_EN_REG, lp_periph_ll_get_clk_en_mask(lp_periph));
|
||||
SET_PERI_REG_MASK(LPPERI_RESET_EN_REG, lp_periph_ll_get_rst_en_mask(lp_periph));
|
||||
}
|
||||
|
||||
static inline void lp_periph_ll_reset(lp_periph_module_t lp_periph)
|
||||
{
|
||||
uint32_t bit_mask = lp_periph_ll_get_rst_en_mask(lp_periph);
|
||||
SET_PERI_REG_MASK(LPPERI_RESET_EN_REG, bit_mask);
|
||||
CLEAR_PERI_REG_MASK(LPPERI_RESET_EN_REG, bit_mask);
|
||||
}
|
||||
|
||||
static inline void lp_periph_ll_set_clk_src(lp_periph_module_t lp_periph, soc_module_clk_t clk_src)
|
||||
{
|
||||
uint32_t val;
|
||||
switch (lp_periph) {
|
||||
case LP_PERIPH_I2C0_MODULE:
|
||||
switch (clk_src) {
|
||||
case LP_I2C_SCLK_LP_FAST:
|
||||
val = 0;
|
||||
break;
|
||||
case LP_I2C_SCLK_XTAL_D2:
|
||||
val = 1;
|
||||
break;
|
||||
default:
|
||||
// Invalid LP_I2C clock source
|
||||
abort();
|
||||
}
|
||||
REG_SET_FIELD(LP_CLKRST_LPPERI_REG, LP_CLKRST_LP_I2C_CLK_SEL, val);
|
||||
break;
|
||||
case LP_PERIPH_UART0_MODULE:
|
||||
switch (clk_src) {
|
||||
case LP_UART_SCLK_LP_FAST:
|
||||
val = 0;
|
||||
break;
|
||||
case LP_UART_SCLK_XTAL_D2:
|
||||
val = 1;
|
||||
break;
|
||||
default:
|
||||
// Invalid LP_UART clock source
|
||||
abort();
|
||||
}
|
||||
REG_SET_FIELD(LP_CLKRST_LPPERI_REG, LP_CLKRST_LP_UART_CLK_SEL, val);
|
||||
break;
|
||||
default:
|
||||
// Unsupported LP peripherals
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -7,7 +7,6 @@
|
||||
// The LL layer for UART register operations.
|
||||
// Note that most of the register operations in this layer are non-atomic operations.
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_attr.h"
|
||||
@ -18,6 +17,7 @@
|
||||
#include "soc/lp_uart_reg.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/lp_clkrst_struct.h"
|
||||
#include "soc/lpperi_struct.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -105,7 +105,60 @@ FORCE_INLINE_ATTR void lp_uart_ll_get_sclk(uart_dev_t *hw, soc_module_clk_t *sou
|
||||
}
|
||||
}
|
||||
|
||||
// LP_UART clock control LL functions are located in lp_periph_clk_ctrl_ll.h
|
||||
/**
|
||||
* @brief Set LP UART source clock
|
||||
*
|
||||
* @param hw Address offset of the LP UART peripheral registers
|
||||
* @param src_clk Source clock for the LP UART peripheral
|
||||
*/
|
||||
static inline void lp_uart_ll_set_source_clk(uart_dev_t *hw, soc_periph_lp_uart_clk_src_t src_clk)
|
||||
{
|
||||
(void)hw;
|
||||
switch (src_clk) {
|
||||
case LP_UART_SCLK_LP_FAST:
|
||||
LP_CLKRST.lpperi.lp_uart_clk_sel = 0;
|
||||
break;
|
||||
case LP_UART_SCLK_XTAL_D2:
|
||||
LP_CLKRST.lpperi.lp_uart_clk_sel = 1;
|
||||
break;
|
||||
default:
|
||||
// Invalid LP_UART clock source
|
||||
HAL_ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
/// LP_CLKRST.lpperi is a shared register, so this function must be used in an atomic way
|
||||
#define lp_uart_ll_set_source_clk(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_set_source_clk(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Enable bus clock for the LP UART module
|
||||
*
|
||||
* @param hw_id LP UART instance ID
|
||||
* @param enable True to enable, False to disable
|
||||
*/
|
||||
static inline void lp_uart_ll_enable_bus_clock(int hw_id, bool enable)
|
||||
{
|
||||
(void)hw_id;
|
||||
LPPERI.clk_en.lp_uart_ck_en = enable;
|
||||
}
|
||||
|
||||
/// LPPERI.clk_en is a shared register, so this function must be used in an atomic way
|
||||
#define lp_uart_ll_enable_bus_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_enable_bus_clock(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* @brief Reset LP UART module
|
||||
*
|
||||
* @param hw_id LP UART instance ID
|
||||
*/
|
||||
static inline void lp_uart_ll_reset_register(int hw_id)
|
||||
{
|
||||
(void)hw_id;
|
||||
LPPERI.reset_en.lp_uart_reset_en = 1;
|
||||
LPPERI.reset_en.lp_uart_reset_en = 0;
|
||||
}
|
||||
|
||||
/// LPPERI.reset_en is a shared register, so this function must be used in an atomic way
|
||||
#define lp_uart_ll_reset_register(...) (void)__DECLARE_RCC_ATOMIC_ENV; lp_uart_ll_reset_register(__VA_ARGS__)
|
||||
|
||||
/*************************************** General LL functions ******************************************/
|
||||
/**
|
||||
@ -982,7 +1035,7 @@ FORCE_INLINE_ATTR void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on)
|
||||
{
|
||||
hw->swfc_conf0_sync.force_xon = 1;
|
||||
uart_ll_update(hw);
|
||||
if(!always_on) {
|
||||
if (!always_on) {
|
||||
hw->swfc_conf0_sync.force_xon = 0;
|
||||
uart_ll_update(hw);
|
||||
}
|
||||
@ -1031,7 +1084,7 @@ FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask)
|
||||
FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd)
|
||||
{
|
||||
uint16_t tout_val = tout_thrd;
|
||||
if(tout_thrd > 0) {
|
||||
if (tout_thrd > 0) {
|
||||
hw->tout_conf_sync.rx_tout_thrhd = tout_val;
|
||||
hw->tout_conf_sync.rx_tout_en = 1;
|
||||
} else {
|
||||
@ -1050,7 +1103,7 @@ FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd)
|
||||
FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||
{
|
||||
uint16_t tout_thrd = 0;
|
||||
if(hw->tout_conf_sync.rx_tout_en > 0) {
|
||||
if (hw->tout_conf_sync.rx_tout_en > 0) {
|
||||
tout_thrd = hw->tout_conf_sync.rx_tout_thrhd;
|
||||
}
|
||||
return tout_thrd;
|
||||
|
@ -13,6 +13,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
/* HP peripherals */
|
||||
PERIPH_LEDC_MODULE = 0,
|
||||
PERIPH_UART0_MODULE,
|
||||
PERIPH_UART1_MODULE,
|
||||
@ -45,7 +46,10 @@ typedef enum {
|
||||
PERIPH_TEMPSENSOR_MODULE,
|
||||
PERIPH_REGDMA_MODULE,
|
||||
PERIPH_ASSIST_DEBUG_MODULE,
|
||||
/* Peripherals clock managed by the modem_clock driver must be listed last in the enumeration */
|
||||
/* LP peripherals */
|
||||
PERIPH_LP_I2C0_MODULE,
|
||||
PERIPH_LP_UART0_MODULE,
|
||||
/* Peripherals clock managed by the modem_clock driver must be listed last in the enumeration */
|
||||
PERIPH_WIFI_MODULE,
|
||||
PERIPH_BT_MODULE,
|
||||
PERIPH_IEEE802154_MODULE,
|
||||
@ -54,15 +58,9 @@ typedef enum {
|
||||
PERIPH_ANA_I2C_MASTER_MODULE,
|
||||
PERIPH_MODEM_ETM_MODULE,
|
||||
PERIPH_MODULE_MAX
|
||||
/* !!! Don't append soc modules here !!! */
|
||||
/* !!! Don't append soc modules here !!! */
|
||||
} periph_module_t;
|
||||
|
||||
typedef enum {
|
||||
LP_PERIPH_I2C0_MODULE = 0,
|
||||
LP_PERIPH_UART0_MODULE,
|
||||
LP_PERIPH_MODULE_MAX,
|
||||
} lp_periph_module_t;
|
||||
|
||||
#define PERIPH_MODEM_MODULE_MIN PERIPH_WIFI_MODULE
|
||||
#define PERIPH_MODEM_MODULE_MAX PERIPH_MODEM_ETM_MODULE
|
||||
#define PERIPH_MODEM_MODULE_NUM (PERIPH_MODEM_MODULE_MAX - PERIPH_MODEM_MODULE_MIN + 1)
|
||||
|
@ -109,6 +109,6 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = {
|
||||
},
|
||||
},
|
||||
.irq = ETS_LP_UART_INTR_SOURCE,
|
||||
.lp_module = LP_PERIPH_UART0_MODULE,
|
||||
.module = PERIPH_LP_UART0_MODULE,
|
||||
},
|
||||
};
|
||||
|
@ -70,16 +70,12 @@ typedef enum {
|
||||
PERIPH_AXI_PDMA_MODULE,
|
||||
PERIPH_UHCI_MODULE,
|
||||
PERIPH_PCNT_MODULE,
|
||||
|
||||
/* LP peripherals */
|
||||
PERIPH_LP_I2C0_MODULE,
|
||||
PERIPH_LP_UART0_MODULE,
|
||||
PERIPH_MODULE_MAX
|
||||
} periph_module_t;
|
||||
|
||||
typedef enum {
|
||||
LP_PERIPH_I2C0_MODULE = 0,
|
||||
LP_PERIPH_UART0_MODULE,
|
||||
LP_PERIPH_MODULE_MAX,
|
||||
} lp_periph_module_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -45,9 +45,6 @@ typedef struct {
|
||||
const uint8_t irq;
|
||||
union {
|
||||
const periph_module_t module;
|
||||
#if (SOC_UART_LP_NUM >= 1)
|
||||
const lp_periph_module_t lp_module;
|
||||
#endif
|
||||
};
|
||||
} uart_signal_conn_t;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "driver/rtc_io.h"
|
||||
#include "soc/rtc_io_channel.h"
|
||||
#include "esp_private/esp_clk_tree_common.h"
|
||||
#include "esp_private/lp_periph_ctrl.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
|
||||
static const char *LPI2C_TAG = "lp_core_i2c";
|
||||
|
||||
@ -94,7 +94,7 @@ static esp_err_t lp_i2c_config_clk(const lp_core_i2c_cfg_t *cfg)
|
||||
|
||||
/* Check if we have a valid user configured source clock */
|
||||
soc_periph_lp_i2c_clk_src_t clk_srcs[] = SOC_LP_I2C_CLKS;
|
||||
for (int i = 0; i < sizeof(clk_srcs)/sizeof(clk_srcs[0]); i++) {
|
||||
for (int i = 0; i < sizeof(clk_srcs) / sizeof(clk_srcs[0]); i++) {
|
||||
if (clk_srcs[i] == cfg->i2c_src_clk) {
|
||||
/* Clock source matches. Override the source clock type with the user configured value */
|
||||
source_clk = cfg->i2c_src_clk;
|
||||
@ -108,8 +108,10 @@ static esp_err_t lp_i2c_config_clk(const lp_core_i2c_cfg_t *cfg)
|
||||
/* Verify that the I2C_SCLK operates at a frequency 20 times larger than the requested SCL bus frequency */
|
||||
ESP_RETURN_ON_FALSE(cfg->i2c_timing_cfg.clk_speed_hz * 20 <= source_freq, ESP_ERR_INVALID_ARG, LPI2C_TAG, "I2C_SCLK frequency (%"PRId32") should operate at a frequency at least 20 times larger than the I2C SCL bus frequency (%"PRId32")", source_freq, cfg->i2c_timing_cfg.clk_speed_hz);
|
||||
|
||||
/* Set LP I2C source clock */
|
||||
lp_periph_set_clk_src(LP_PERIPH_I2C0_MODULE, (soc_module_clk_t)source_clk);
|
||||
/* LP I2C clock source is mixed with other peripherals in the same register */
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lp_i2c_ll_set_source_clk(i2c_hal.dev, source_clk);
|
||||
}
|
||||
|
||||
/* Configure LP I2C timing paramters. source_clk is ignored for LP_I2C in this call */
|
||||
i2c_hal_set_bus_timing(&i2c_hal, cfg->i2c_timing_cfg.clk_speed_hz, (i2c_clock_source_t)source_clk, source_freq);
|
||||
@ -128,12 +130,16 @@ esp_err_t lp_core_i2c_master_init(i2c_port_t lp_i2c_num, const lp_core_i2c_cfg_t
|
||||
/* Configure LP I2C GPIOs */
|
||||
ESP_RETURN_ON_ERROR(lp_i2c_set_pin(cfg), LPI2C_TAG, "Failed to configure LP I2C GPIOs");
|
||||
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
/* Enable LP I2C bus clock */
|
||||
lp_i2c_ll_enable_bus_clock(lp_i2c_num - LP_I2C_NUM_0, true);
|
||||
/* Reset LP I2C register */
|
||||
lp_i2c_ll_reset_register(lp_i2c_num - LP_I2C_NUM_0);
|
||||
}
|
||||
|
||||
/* Initialize LP I2C HAL */
|
||||
i2c_hal_init(&i2c_hal, lp_i2c_num);
|
||||
|
||||
/* Enable LP I2C controller clock */
|
||||
lp_periph_module_enable(LP_PERIPH_I2C0_MODULE);
|
||||
|
||||
/* Initialize LP I2C Master mode */
|
||||
i2c_hal_master_init(&i2c_hal);
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "hal/uart_hal.h"
|
||||
#include "hal/rtc_io_types.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "esp_private/lp_periph_ctrl.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
|
||||
#define LP_UART_PORT_NUM LP_UART_NUM_0
|
||||
#define LP_UART_TX_IDLE_NUM_DEFAULT (0U)
|
||||
@ -39,15 +39,19 @@ static esp_err_t lp_core_uart_param_config(const lp_core_uart_cfg_t *cfg)
|
||||
|
||||
/* Get LP UART source clock frequency */
|
||||
uint32_t sclk_freq = 0;
|
||||
soc_module_clk_t clk_src = (soc_module_clk_t)(cfg->lp_uart_source_clk) ? (cfg->lp_uart_source_clk) : LP_UART_SCLK_DEFAULT;
|
||||
ret = esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq);
|
||||
soc_periph_lp_uart_clk_src_t clk_src = cfg->lp_uart_source_clk ? cfg->lp_uart_source_clk : LP_UART_SCLK_DEFAULT;
|
||||
ret = esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq);
|
||||
if (ret != ESP_OK) {
|
||||
// Unable to fetch LP UART source clock frequency
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// LP UART clock source is mixed with other peripherals in the same register
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lp_uart_ll_set_source_clk(hal.dev, clk_src);
|
||||
}
|
||||
|
||||
/* Override protocol parameters from the configuration */
|
||||
lp_periph_set_clk_src(LP_PERIPH_UART0_MODULE, clk_src);
|
||||
uart_hal_set_baudrate(&hal, cfg->uart_proto_cfg.baud_rate, sclk_freq);
|
||||
uart_hal_set_parity(&hal, cfg->uart_proto_cfg.parity);
|
||||
uart_hal_set_data_bit_num(&hal, cfg->uart_proto_cfg.data_bits);
|
||||
|
@ -1,5 +1,5 @@
|
||||
| Supported Targets | ESP32-C6 | ESP32-H2 |
|
||||
| ----------------- | -------- | -------- |
|
||||
| Supported Targets | ESP32-C6 | ESP32-H2 | ESP32-P4 |
|
||||
| ----------------- | -------- | -------- | -------- |
|
||||
|
||||
# HC-SR04 Example based on GPTimer Capture and ETM
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user