feat(lp_i2c): Added LP I2C support on the esp32p4

This commit adds support for the LP I2C peripheral to be used from the
LP core on the esp32p4.
pull/13550/head
Sudeep Mohanty 2024-03-15 16:41:42 +01:00
rodzic 2b5517ed47
commit 5228dc348b
7 zmienionych plików z 55 dodań i 15 usunięć

Wyświetl plik

@ -199,6 +199,10 @@ config SOC_LP_PERIPHERALS_SUPPORTED
bool
default y
config SOC_LP_I2C_SUPPORTED
bool
default y
config SOC_SPIRAM_SUPPORTED
bool
default y
@ -615,6 +619,14 @@ config SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH
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 3

Wyświetl plik

@ -75,6 +75,7 @@
#define SOC_ULP_LP_UART_SUPPORTED 1
#define SOC_LP_GPIO_MATRIX_SUPPORTED 1
#define SOC_LP_PERIPHERALS_SUPPORTED 1
#define SOC_LP_I2C_SUPPORTED 1
#define SOC_SPIRAM_SUPPORTED 1
#define SOC_PSRAM_DMA_CAPABLE 1
// #define SOC_ULP_SUPPORTED 1 //TODO: IDF-7534
@ -268,6 +269,12 @@
#define SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS (1)
#define SOC_I2C_SLAVE_SUPPORT_SLAVE_UNMATCH (1)
/*-------------------------- LP_I2C CAPS -------------------------------------*/
// ESP32-P4 has 1 LP_I2C
#define SOC_LP_I2C_NUM (1U)
#define SOC_LP_I2C_FIFO_LEN (16) /*!< LP_I2C hardware FIFO depth */
/*-------------------------- I2S CAPS ----------------------------------------*/
#define SOC_I2S_NUM (3U)
#define SOC_I2S_HW_VERSION_2 (1)

Wyświetl plik

@ -59,7 +59,6 @@ if(CONFIG_ULP_COPROC_TYPE_LP_CORE)
endif()
if(CONFIG_SOC_LP_I2C_SUPPORTED)
# Add to P4 TODO IDF-7540
list(APPEND srcs "lp_core/lp_core_i2c.c")
endif()

Wyświetl plik

@ -481,4 +481,4 @@ esp_err_t lp_core_i2c_master_write_read_device(i2c_port_t lp_i2c_num, uint16_t d
return ret;
}
#endif //!SOC_LP_I2C_SUPPORTED
#endif /* SOC_LP_I2C_SUPPORTED */

Wyświetl plik

@ -7,7 +7,6 @@
#include "lp_core_i2c.h"
#include "esp_check.h"
#include "hal/i2c_hal.h"
#include "soc/lp_io_struct.h"
#include "driver/rtc_io.h"
#include "soc/rtc_io_channel.h"
#include "esp_private/esp_clk_tree_common.h"
@ -15,20 +14,28 @@
static const char *LPI2C_TAG = "lp_core_i2c";
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
#include "soc/lp_io_struct.h"
/* Use the register structure to access LP_IO module registers */
lp_io_dev_t *lp_io_dev = &LP_IO;
#else
#include "driver/lp_io.h"
#include "soc/lp_gpio_sig_map.h"
#endif /* !SOC_LP_GPIO_MATRIX_SUPPORTED */
#define LP_I2C_FILTER_CYC_NUM_DEF (7)
/* I2C LL context */
i2c_hal_context_t i2c_hal;
/* Use the register structure to access LP_IO module registers */
lp_io_dev_t *lp_io_dev = &LP_IO;
static esp_err_t lp_i2c_gpio_is_cfg_valid(gpio_num_t sda_io_num, gpio_num_t scl_io_num)
{
/* Verify that the SDA and SCL GPIOs are valid LP IO (RTCIO) pins */
ESP_RETURN_ON_ERROR(!rtc_gpio_is_valid_gpio(sda_io_num), LPI2C_TAG, "LP I2C SDA GPIO invalid");
ESP_RETURN_ON_ERROR(!rtc_gpio_is_valid_gpio(scl_io_num), LPI2C_TAG, "LP I2C SCL GPIO invalid");
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
/* Verify that the SDA and SCL line belong to the LP IO Mux I2C function group */
if (sda_io_num != RTCIO_GPIO6_CHANNEL) {
ESP_LOGE(LPI2C_TAG, "SDA pin can only be configured as GPIO#6");
@ -39,6 +46,7 @@ static esp_err_t lp_i2c_gpio_is_cfg_valid(gpio_num_t sda_io_num, gpio_num_t scl_
ESP_LOGE(LPI2C_TAG, "SCL pin can only be configured as GPIO#7");
return ESP_ERR_INVALID_ARG;
}
#endif /* !SOC_LP_GPIO_MATRIX_SUPPORTED */
return ESP_OK;
}
@ -64,6 +72,8 @@ static esp_err_t lp_i2c_configure_io(gpio_num_t io_num, bool pullup_en)
static esp_err_t lp_i2c_set_pin(const lp_core_i2c_cfg_t *cfg)
{
esp_err_t ret = ESP_OK;
gpio_num_t sda_io_num = cfg->i2c_pin_cfg.sda_io_num;
gpio_num_t scl_io_num = cfg->i2c_pin_cfg.scl_io_num;
bool sda_pullup_en = cfg->i2c_pin_cfg.sda_pullup_en;
@ -78,13 +88,23 @@ static esp_err_t lp_i2c_set_pin(const lp_core_i2c_cfg_t *cfg)
/* Initialize SCL Pin */
ESP_RETURN_ON_ERROR(lp_i2c_configure_io(scl_io_num, scl_pullup_en), LPI2C_TAG, "LP I2C SCL pin config failed");
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
/* Select LP I2C function for the SDA Pin */
lp_io_dev->gpio[sda_io_num].mcu_sel = 1;
/* Select LP I2C function for the SCL Pin */
lp_io_dev->gpio[scl_io_num].mcu_sel = 1;
#else
/* Connect the SDA pin of the LP_I2C peripheral to the LP_IO Matrix */
ret = lp_gpio_connect_out_signal(sda_io_num, LP_I2C_SDA_PAD_OUT_IDX, 0, 0);
ret = lp_gpio_connect_in_signal(sda_io_num, LP_I2C_SDA_PAD_IN_IDX, 0);
return ESP_OK;
/* Connect the SCL pin of the LP_I2C peripheral to the LP_IO Matrix */
ret = lp_gpio_connect_out_signal(scl_io_num, LP_I2C_SCL_PAD_OUT_IDX, 0, 0);
ret = lp_gpio_connect_in_signal(scl_io_num, LP_I2C_SCL_PAD_IN_IDX, 0);
#endif /* !SOC_LP_GPIO_MATRIX_SUPPORTED */
return ret;
}
static esp_err_t lp_i2c_config_clk(const lp_core_i2c_cfg_t *cfg)
@ -112,10 +132,10 @@ static esp_err_t lp_i2c_config_clk(const lp_core_i2c_cfg_t *cfg)
/* 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);
/* Configure LP I2C timing parameters. 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);
}
return ret;
}
@ -134,12 +154,13 @@ esp_err_t lp_core_i2c_master_init(i2c_port_t lp_i2c_num, const lp_core_i2c_cfg_t
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);
/* Initialize LP I2C HAL */
i2c_hal_init(&i2c_hal, lp_i2c_num);
}
/* Initialize LP I2C Master mode */
i2c_hal_master_init(&i2c_hal);
@ -148,7 +169,7 @@ esp_err_t lp_core_i2c_master_init(i2c_port_t lp_i2c_num, const lp_core_i2c_cfg_t
i2c_hal.dev->ctr.sda_force_out = 0;
i2c_hal.dev->ctr.scl_force_out = 0;
/* Configure LP I2C clock and timing paramters */
/* Configure LP I2C clock and timing parameters */
ESP_RETURN_ON_ERROR(lp_i2c_config_clk(cfg), LPI2C_TAG, "Failed to configure LP I2C source clock");
/* Enable SDA and SCL filtering. This configuration matches the HP I2C filter config */

Wyświetl plik

@ -12,6 +12,7 @@ def test_lp_core(dut: Dut) -> None:
@pytest.mark.esp32c6
# TODO: Enable LP I2C test for esp32p4 (IDF-9407)
@pytest.mark.generic_multi_device
@pytest.mark.parametrize(
'count', [2], indirect=True

Wyświetl plik

@ -276,7 +276,7 @@ examples/system/ulp/lp_core/lp_i2c:
disable:
- if: IDF_TARGET == "esp32p4"
temporary: true
reason: target esp32p4 is not supported yet, TODO IDF-7540
reason: target esp32p4 is not supported yet, TODO IDF-9407
depends_components:
- ulp