mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-09 12:35:28 +00:00
Merge branch 'change/bu_lp_i2c_c5' into 'master'
change(ulp): bring up lp i2c on esp32c5 Closes IDF-8634 See merge request espressif/esp-idf!32142
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "hal/i2c_types.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/lp_clkrst_struct.h"
|
||||
#include "soc/lpperi_struct.h"
|
||||
#include "hal/misc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -69,7 +71,7 @@ typedef enum {
|
||||
} i2c_ll_slave_intr_t;
|
||||
|
||||
// Get the I2C hardware instance
|
||||
#define I2C_LL_GET_HW(i2c_num) (&I2C0)
|
||||
#define I2C_LL_GET_HW(i2c_num) (((i2c_num) == I2C_NUM_0) ? (&I2C0) : (&LP_I2C))
|
||||
#define I2C_LL_MASTER_EVENT_INTR (I2C_NACK_INT_ENA_M|I2C_TIME_OUT_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_ARBITRATION_LOST_INT_ENA_M|I2C_END_DETECT_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M|I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M)
|
||||
#define I2C_LL_SLAVE_RX_EVENT_INTR (I2C_TRANS_COMPLETE_INT_ENA_M | I2C_RXFIFO_WM_INT_ENA_M | I2C_SLAVE_STRETCH_INT_ENA_M)
|
||||
@@ -77,6 +79,14 @@ typedef enum {
|
||||
#define I2C_LL_RESET_SLV_SCL_PULSE_NUM_DEFAULT (9)
|
||||
#define I2C_LL_SCL_WAIT_US_VAL_DEFAULT (2500) // Approximate value for SCL timeout regs (in us).
|
||||
|
||||
// Record for Pins usage logs
|
||||
|
||||
#define LP_I2C_SCL_PIN_ERR_LOG "SCL pin can only be configured as GPIO#7"
|
||||
#define LP_I2C_SDA_PIN_ERR_LOG "SDA pin can only be configured as GPIO#6"
|
||||
|
||||
#define LP_I2C_SDA_IOMUX_PAD 6
|
||||
#define LP_I2C_SCL_IOMUX_PAD 7
|
||||
|
||||
/**
|
||||
* @brief Calculate I2C bus frequency
|
||||
* Note that the clock accuracy is affected by the external pull-up resistor,
|
||||
@@ -752,6 +762,20 @@ static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw, uint32_t slave_pulses)
|
||||
hw->ctr.conf_upgate = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the ACK level that the I2C master must send when the Rx FIFO count has reached the threshold value.
|
||||
* ack_level: 1 (NACK)
|
||||
* ack_level: 0 (ACK)
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
static inline void i2c_ll_master_rx_full_ack_level(i2c_dev_t *hw, int ack_level)
|
||||
{
|
||||
hw->ctr.rx_full_ack_level = ack_level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set I2C source clock
|
||||
*
|
||||
@@ -762,10 +786,73 @@ static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw, uint32_t slave_pulses)
|
||||
*/
|
||||
static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_clk)
|
||||
{
|
||||
if (hw == &LP_I2C) {
|
||||
// Do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
// src_clk : (1) for RTC_CLK, (0) for XTAL
|
||||
PCR.i2c[0].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
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
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
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/// 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
|
||||
*
|
||||
@@ -774,7 +861,11 @@ static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_c
|
||||
*/
|
||||
static inline void i2c_ll_enable_controller_clock(i2c_dev_t *hw, bool en)
|
||||
{
|
||||
(void)hw;
|
||||
if (hw == &LP_I2C) {
|
||||
// Do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
PCR.i2c[0].i2c_sclk_conf.i2c_sclk_en = en;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user