Skip to content

Commit

Permalink
Merge branch 'feature/add_support_for_lp_i2c' into 'master'
Browse files Browse the repository at this point in the history
lp-i2c: Added support for LP I2C peripheral to LP core

Closes IDF-6833

See merge request espressif/esp-idf!22846
  • Loading branch information
sudeep-mohanty committed May 19, 2023
2 parents 1bdcdd9 + ec742ab commit efe9192
Show file tree
Hide file tree
Showing 27 changed files with 1,246 additions and 198 deletions.
8 changes: 8 additions & 0 deletions components/driver/i2c/i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,11 @@ static const char *I2C_TAG = "i2c";
#if SOC_I2C_NUM >= 2
_Static_assert(I2C_NUM_1 == 1, "I2C_NUM_1 must be equal to 1");
#endif // SOC_I2C_NUM >= 2
#if SOC_LP_I2C_SUPPORTED
_Static_assert(I2C_NUM_MAX == (SOC_I2C_NUM + SOC_LP_I2C_NUM), "I2C_NUM_MAX must be equal to SOC_I2C_NUM + SOC_LP_I2C_NUM");
#else
_Static_assert(I2C_NUM_MAX == SOC_I2C_NUM, "I2C_NUM_MAX must be equal to SOC_I2C_NUM");
#endif /* SOC_LP_I2C_SUPPORTED */

typedef struct {
i2c_ll_hw_cmd_t hw_cmd;
Expand Down Expand Up @@ -259,6 +263,10 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_
int intr_alloc_flags)
{
ESP_RETURN_ON_FALSE(i2c_num < I2C_NUM_MAX, ESP_ERR_INVALID_ARG, I2C_TAG, I2C_NUM_ERROR_STR);
#if SOC_LP_I2C_SUPPORTED
// TODO: IDF-5817
ESP_RETURN_ON_FALSE(i2c_num != LP_I2C_NUM_0, ESP_ERR_INVALID_ARG, I2C_TAG, "LP_I2C is not supported via i2c_driver_intall()");
#endif // SOC_LP_I2C_SUPPORTED
#if SOC_I2C_SUPPORT_SLAVE
ESP_RETURN_ON_FALSE(mode == I2C_MODE_MASTER || ( slv_rx_buf_len > 100 || slv_tx_buf_len > 100 ),
ESP_ERR_INVALID_ARG, I2C_TAG, I2C_SLAVE_BUFFER_LEN_ERR_STR);
Expand Down
3 changes: 3 additions & 0 deletions components/esp_hw_support/port/esp32c6/esp_clk_tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ uint32_t *freq_value)
case SOC_MOD_CLK_XTAL32K:
clk_src_freq = esp_clk_tree_xtal32k_get_freq_hz(precision);
break;
case SOC_MOD_CLK_XTAL_D2:
clk_src_freq = (clk_hal_xtal_get_freq_mhz() * MHZ) >> 1;
break;
default:
break;
}
Expand Down
13 changes: 13 additions & 0 deletions components/hal/esp32c6/include/hal/clk_gate_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "soc/periph_defs.h"
#include "soc/pcr_reg.h"
#include "soc/soc.h"
#include "soc/lpperi_reg.h"
#include "esp_attr.h"

#ifdef __cplusplus
Expand Down Expand Up @@ -78,6 +79,9 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph)
return PCR_SDIO_SLAVE_CLK_EN;
case PERIPH_REGDMA_MODULE:
return PCR_REGDMA_CLK_EN;
//TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374).
case PERIPH_LP_I2C0_MODULE:
return LPPERI_LP_EXT_I2C_CK_EN;
// case PERIPH_RNG_MODULE:
// return PCR_WIFI_CLK_RNG_EN;
// case PERIPH_WIFI_MODULE:
Expand Down Expand Up @@ -171,6 +175,9 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en
return PCR_SDIO_SLAVE_RST_EN;
case PERIPH_REGDMA_MODULE:
return PCR_REGDMA_RST_EN;
//TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374).
case PERIPH_LP_I2C0_MODULE:
return LPPERI_LP_EXT_I2C_RESET_EN;
// case PERIPH_RNG_MODULE:
// return PCR_WIFI_CLK_RNG_EN;
// case PERIPH_WIFI_MODULE:
Expand Down Expand Up @@ -257,6 +264,9 @@ static uint32_t periph_ll_get_clk_en_reg(periph_module_t periph)
return PCR_SDIO_SLAVE_CONF_REG;
case PERIPH_REGDMA_MODULE:
return PCR_REGDMA_CONF_REG;
//TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374).
case PERIPH_LP_I2C0_MODULE:
return LPPERI_CLK_EN_REG;
default:
return 0;
}
Expand Down Expand Up @@ -323,6 +333,9 @@ static uint32_t periph_ll_get_rst_en_reg(periph_module_t periph)
return PCR_SDIO_SLAVE_CONF_REG;
case PERIPH_REGDMA_MODULE:
return PCR_REGDMA_CONF_REG;
//TODO: LP_PERIPH modules are added temporarily and will be moved to a separate API (IDF-7374).
case PERIPH_LP_I2C0_MODULE:
return LPPERI_RESET_EN_REG;
default:
return 0;
}
Expand Down
42 changes: 39 additions & 3 deletions components/hal/esp32c6/include/hal/i2c_ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "soc/pcr_struct.h"
#include "hal/i2c_types.h"
#include "soc/clk_tree_defs.h"
#include "soc/lp_clkrst_struct.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -62,7 +63,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_RXFIFO_WM_INT_ENA_M|I2C_TRANS_COMPLETE_INT_ENA_M|I2C_TXFIFO_WM_INT_ENA_M)

Expand Down Expand Up @@ -665,11 +666,42 @@ static inline void i2c_ll_master_clr_bus(i2c_dev_t *hw)
*/
static inline void i2c_ll_set_source_clk(i2c_dev_t *hw, i2c_clock_source_t src_clk)
{
(void)hw;
if (hw == &LP_I2C) {
// Do nothing
return;
}

// src_clk : (1) for RTC_CLK, (0) for XTAL
PCR.i2c_sclk_conf.i2c_sclk_sel = (src_clk == I2C_CLK_SRC_RC_FAST) ? 1 : 0;
}

#if SOC_LP_I2C_SUPPORTED
/**
* @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();
}
}
#endif /* SOC_LP_I2C_SUPPORTED */

/**
* @brief Enable I2C peripheral controller clock
*
Expand All @@ -678,7 +710,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_sclk_conf.i2c_sclk_en = en;
}

Expand Down
11 changes: 7 additions & 4 deletions components/hal/include/hal/i2c_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ extern "C" {
* @brief I2C port number, can be I2C_NUM_0 ~ (I2C_NUM_MAX-1).
*/
typedef enum {
I2C_NUM_0 = 0, /*!< I2C port 0 */
I2C_NUM_0 = 0, /*!< I2C port 0 */
#if SOC_I2C_NUM >= 2
I2C_NUM_1, /*!< I2C port 1 */
#endif
I2C_NUM_MAX, /*!< I2C port max */
I2C_NUM_1, /*!< I2C port 1 */
#endif /* SOC_I2C_NUM >= 2 */
#if SOC_LP_I2C_NUM >= 1
LP_I2C_NUM_0, /*< LP_I2C port 0 */
#endif /* SOC_LP_I2C_NUM >= 1 */
I2C_NUM_MAX, /*!< I2C port max */
} i2c_port_t;

/**
Expand Down
12 changes: 12 additions & 0 deletions components/soc/esp32c6/include/soc/Kconfig.soc_caps.in
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ config SOC_LP_AON_SUPPORTED
bool
default y

config SOC_LP_I2C_SUPPORTED
bool
default y

config SOC_XTAL_SUPPORT_40M
bool
default y
Expand Down Expand Up @@ -479,6 +483,14 @@ config SOC_I2C_SUPPORT_RTC
bool
default y

config SOC_LP_I2C_NUM
int
default 1

config SOC_LP_I2C_FIFO_LEN
int
default 16

config SOC_I2S_NUM
int
default 1
Expand Down
16 changes: 16 additions & 0 deletions components/soc/esp32c6/include/soc/clk_tree_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ typedef enum {
SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */
SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */
SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */
SOC_MOD_CLK_XTAL_D2, /*!< XTAL_D2_CLK comes from the external 40MHz crystal, passing a div of 2 to the LP peripherals */
SOC_MOD_CLK_INVALID, /*!< Indication of the end of the available module clock sources */
} soc_module_clk_t;

Expand Down Expand Up @@ -286,6 +287,21 @@ typedef enum {
I2C_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default source clock */
} soc_periph_i2c_clk_src_t;

///////////////////////////////////////////////LP_I2C///////////////////////////////////////////////////////////////////

/**
* @brief Array initializer for all supported clock sources of LP_I2C
*/
#define SOC_LP_I2C_CLKS {SOC_MOD_CLK_RTC_FAST, SOC_MOD_CLK_XTAL_D2}

/**
* @brief Type of LP_I2C clock source.
*/
typedef enum {
LP_I2C_SCLK_LP_FAST = SOC_MOD_CLK_RTC_FAST, /*!< LP_I2C source clock is RTC_FAST */
LP_I2C_SCLK_XTAL_D2 = SOC_MOD_CLK_XTAL_D2, /*!< LP_I2C source clock is XTAL_D2 */
LP_I2C_SCLK_DEFAULT = SOC_MOD_CLK_RTC_FAST, /*!< LP_I2C source clock default choice is RTC_FAST */
} soc_periph_lp_i2c_clk_src_t;

/////////////////////////////////////////////////SPI////////////////////////////////////////////////////////////////////

Expand Down
3 changes: 2 additions & 1 deletion components/soc/esp32c6/include/soc/i2c_struct.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -1013,6 +1013,7 @@ typedef struct i2c_dev_t {
} i2c_dev_t;

extern i2c_dev_t I2C0;
extern i2c_dev_t LP_I2C;

#ifndef __cplusplus
_Static_assert(sizeof(i2c_dev_t) == 0x184, "Invalid size of i2c_dev_t structure");
Expand Down
Loading

0 comments on commit efe9192

Please sign in to comment.