Skip to content

Commit 8995226

Browse files
eren-terziogluxiaoxiang781216
authored andcommitted
arch/risc-v: Add LP I2C for esp32[-c6]
Add LP I2C peripheral support for esp32c6 Signed-off-by: Eren Terzioglu <[email protected]>
1 parent cf1b087 commit 8995226

File tree

6 files changed

+196
-20
lines changed

6 files changed

+196
-20
lines changed

arch/risc-v/src/common/espressif/Kconfig

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ config ESPRESSIF_I2C
384384
bool
385385
default n
386386

387+
config ESPRESSIF_LPI2C
388+
bool
389+
default n
390+
387391
config ESPRESSIF_I2C_PERIPH_MASTER_MODE
388392
bool
389393
depends on (ESPRESSIF_I2C0_MASTER_MODE || ESPRESSIF_I2C1_MASTER_MODE)
@@ -407,6 +411,14 @@ config ESPRESSIF_I2C1
407411
select ESPRESSIF_I2C
408412
select I2C
409413

414+
config ESPRESSIF_LP_I2C0
415+
bool "LP I2C 0"
416+
default n
417+
depends on ARCH_CHIP_ESP32C6
418+
select ESPRESSIF_I2C
419+
select ESPRESSIF_LPI2C
420+
select I2C
421+
410422
choice ESPRESSIF_I2C0_MODE
411423
prompt "I2C0 Mode"
412424
depends on ESPRESSIF_I2C0
@@ -2041,7 +2053,8 @@ if ESPRESSIF_I2C0
20412053

20422054
config ESPRESSIF_I2C0_SCLPIN
20432055
int "I2C0 SCL Pin"
2044-
default 6
2056+
default 6 if !ESPRESSIF_LPI2C
2057+
default 23 if ESPRESSIF_LPI2C
20452058
range 0 21
20462059

20472060
config ESPRESSIF_I2C0_SDAPIN

arch/risc-v/src/common/espressif/esp_i2c.c

Lines changed: 170 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,24 @@
6464
#if defined(CONFIG_ESPRESSIF_ESP32H2) || defined(CONFIG_ESPRESSIF_ESP32C6)
6565
# include "soc/pcr_reg.h"
6666
#endif
67+
#if defined(CONFIG_ESPRESSIF_LP_I2C0)
68+
# include "driver/rtc_io.h"
69+
# include "hal/rtc_io_hal.h"
70+
# include "io_mux.h"
71+
# include "lp_core_i2c.h"
72+
# include "soc/i2c_struct.h"
73+
#endif
6774

6875
/****************************************************************************
6976
* Pre-processor Definitions
7077
****************************************************************************/
7178

79+
#if defined(CONFIG_ESPRESSIF_LP_I2C0)
80+
# define ESP_LP_I2C0_ID LP_I2C_NUM_0
81+
#else
82+
# define ESP_LP_I2C0_ID I2C_NUM_MAX
83+
#endif
84+
7285
#ifdef CONFIG_ESPRESSIF_ESP32H2
7386
# define SYSTEM_I2C_EXT0_CLK_EN PCR_I2C0_CLK_EN
7487
# define SYSTEM_I2C_EXT0_RST PCR_I2C0_RST_EN
@@ -251,6 +264,8 @@ struct esp_i2c_priv_s
251264

252265
bool ready_read; /* If I2C is ready for receiving data */
253266

267+
soc_module_clk_t clk_src; /* Clock source */
268+
254269
uint32_t clk_freq; /* Current I2C Clock frequency */
255270

256271
/* I2C trace support */
@@ -373,6 +388,7 @@ static struct esp_i2c_priv_s esp_i2c0_priv =
373388
#endif
374389
.error = 0,
375390
.ready_read = false,
391+
.clk_src = I2C_CLK_SRC_DEFAULT,
376392
.clk_freq = 0,
377393
.ctx = &i2c0_ctx
378394
};
@@ -424,11 +440,63 @@ static struct esp_i2c_priv_s esp_i2c1_priv =
424440
#endif
425441
.error = 0,
426442
.ready_read = false,
443+
.clk_src = I2C_CLK_SRC_DEFAULT,
427444
.clk_freq = 0,
428445
.ctx = &i2c1_ctx
429446
};
430447
#endif /* CONFIG_ESPRESSIF_I2C1 */
431448

449+
#ifdef CONFIG_ESPRESSIF_LP_I2C0
450+
i2c_hal_context_t lp_i2c0_ctx =
451+
{
452+
0
453+
};
454+
455+
/* I2C device structure */
456+
457+
static const struct esp_i2c_config_s esp_lp_i2c0_config =
458+
{
459+
.clk_freq = I2C_CLK_FREQ_DEF,
460+
.scl_pin = 7,
461+
.sda_pin = 6,
462+
#ifndef CONFIG_I2C_POLLED
463+
.periph = ETS_LP_I2C_INTR_SOURCE,
464+
.irq = ESP_IRQ_LP_I2C,
465+
#endif
466+
.clk_bit = SYSTEM_I2C_EXT0_CLK_EN,
467+
.rst_bit = SYSTEM_I2C_EXT0_RST,
468+
.scl_insig = 0,
469+
.scl_outsig = 0,
470+
.sda_insig = 0,
471+
.sda_outsig = 0
472+
};
473+
474+
static struct esp_i2c_priv_s esp_lp_i2c0_priv =
475+
{
476+
.ops = &esp_i2c_ops,
477+
.id = LP_I2C_NUM_0,
478+
.module = PERIPH_LP_I2C0_MODULE,
479+
.config = &esp_lp_i2c0_config,
480+
.refs = 0,
481+
.lock = NXMUTEX_INITIALIZER,
482+
#ifndef CONFIG_I2C_POLLED
483+
.sem_isr = SEM_INITIALIZER(0),
484+
#endif
485+
.i2cstate = I2CSTATE_IDLE,
486+
.msgv = NULL,
487+
.msgid = 0,
488+
.bytes = 0,
489+
#ifndef CONFIG_I2C_POLLED
490+
.cpuint = -ENOMEM,
491+
#endif
492+
.error = 0,
493+
.ready_read = false,
494+
.clk_src = LP_I2C_SCLK_DEFAULT,
495+
.clk_freq = 0,
496+
.ctx = &lp_i2c0_ctx
497+
};
498+
#endif /* CONFIG_ESPRESSIF_LP_I2C0 */
499+
432500
/* Trace events strings */
433501

434502
#ifdef CONFIG_I2C_TRACE
@@ -718,25 +786,64 @@ static void esp_i2c_sendstop(struct esp_i2c_priv_s *priv)
718786
static void esp_i2c_init_clock(struct esp_i2c_priv_s *priv,
719787
uint32_t bus_freq)
720788
{
721-
uint32_t src_clk_frequency;
789+
uint32_t src_clk_frequency = 0;
722790

723791
if (bus_freq == priv->clk_freq)
724792
{
725793
return ;
726794
}
727795

728-
i2c_clock_source_t src_clk = I2C_CLK_SRC_DEFAULT;
729-
esp_clk_tree_src_get_freq_hz((soc_module_clk_t)src_clk,
730-
ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED,
796+
esp_clk_tree_src_get_freq_hz(priv->clk_src,
797+
ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX,
731798
&src_clk_frequency);
732799
i2c_hal_set_bus_timing(priv->ctx, priv->config->clk_freq,
733-
src_clk, src_clk_frequency);
800+
priv->clk_src, src_clk_frequency);
734801
i2c_hal_master_set_scl_timeout_val(priv->ctx, SCL_TIMEOUT_VAL_US,
735802
src_clk_frequency);
803+
804+
#ifdef CONFIG_ESPRESSIF_LPI2C
805+
PERIPH_RCC_ATOMIC()
806+
{
807+
lp_i2c_ll_set_source_clk(priv->ctx->dev, priv->clk_src);
808+
}
809+
#endif
810+
736811
i2c_ll_update(priv->ctx->dev);
737812
priv->clk_freq = bus_freq;
738813
}
739814

815+
#ifdef CONFIG_ESPRESSIF_LPI2C
816+
/****************************************************************************
817+
* Name: esp_lp_i2c_config_io
818+
*
819+
* Description:
820+
* Configures LP I2C pin.
821+
*
822+
* Parameters:
823+
* priv - Pointer to the private driver struct.
824+
* pin - Pin number to configure.
825+
*
826+
* Return Value:
827+
* None.
828+
*
829+
****************************************************************************/
830+
831+
static void esp_lp_i2c_config_io(const struct esp_i2c_priv_s *priv,
832+
int8_t pin)
833+
{
834+
int lp_pin = rtc_io_num_map[pin];
835+
836+
DEBUGASSERT(lp_pin != -1);
837+
838+
rtc_gpio_set_level(pin, 1);
839+
rtc_gpio_init(pin);
840+
841+
rtc_gpio_set_direction(pin, RTC_GPIO_MODE_INPUT_OUTPUT_OD);
842+
rtc_gpio_pulldown_dis(pin);
843+
rtc_gpio_pullup_en(pin);
844+
}
845+
#endif /* CONFIG_ESPRESSIF_LPI2C */
846+
740847
/****************************************************************************
741848
* Name: esp_i2c_init
742849
*
@@ -752,22 +859,53 @@ static void esp_i2c_init(struct esp_i2c_priv_s *priv)
752859
{
753860
const struct esp_i2c_config_s *config = priv->config;
754861

755-
/* Configure GPIO signals for I2C SCL and SDA pins */
862+
if (priv->id < ESP_LP_I2C0_ID)
863+
{
864+
/* Configure GPIO signals for I2C SCL and SDA pins */
865+
866+
esp_gpiowrite(config->scl_pin, 1);
867+
esp_gpiowrite(config->sda_pin, 1);
756868

757-
esp_gpiowrite(config->scl_pin, 1);
758-
esp_gpiowrite(config->sda_pin, 1);
869+
esp_configgpio(config->scl_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN);
870+
esp_gpio_matrix_out(config->scl_pin, config->scl_outsig, 0, 0);
871+
esp_gpio_matrix_in(config->scl_pin, config->scl_insig, 0);
759872

760-
esp_configgpio(config->scl_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN);
761-
esp_gpio_matrix_out(config->scl_pin, config->scl_outsig, 0, 0);
762-
esp_gpio_matrix_in(config->scl_pin, config->scl_insig, 0);
873+
esp_configgpio(config->sda_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN);
874+
esp_gpio_matrix_out(config->sda_pin, config->sda_outsig, 0, 0);
875+
esp_gpio_matrix_in(config->sda_pin, config->sda_insig, 0);
763876

764-
esp_configgpio(config->sda_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN);
765-
esp_gpio_matrix_out(config->sda_pin, config->sda_outsig, 0, 0);
766-
esp_gpio_matrix_in(config->sda_pin, config->sda_insig, 0);
877+
/* Enable I2C hardware */
767878

768-
/* Enable I2C hardware */
879+
periph_module_enable(priv->module);
880+
}
881+
#ifdef CONFIG_ESPRESSIF_LPI2C
882+
else
883+
{
884+
PERIPH_RCC_ATOMIC()
885+
{
886+
/* Enable LP I2C bus clock */
887+
888+
lp_i2c_ll_enable_bus_clock(priv->id - LP_I2C_NUM_0, true);
889+
890+
/* Reset LP I2C register */
891+
892+
lp_i2c_ll_reset_register(priv->id - LP_I2C_NUM_0);
893+
}
894+
895+
esp_lp_i2c_config_io(priv, config->scl_pin);
896+
esp_lp_i2c_config_io(priv, config->sda_pin);
897+
const i2c_signal_conn_t *p_i2c_pin = &i2c_periph_signal[priv->id];
898+
#if !SOC_LP_GPIO_MATRIX_SUPPORTED
899+
rtc_gpio_iomux_func_sel(config->sda_pin, p_i2c_pin->iomux_func);
900+
rtc_gpio_iomux_func_sel(config->scl_pin, p_i2c_pin->iomux_func);
901+
#else
902+
/* ToDo: Add LP I2C for LP GPIO Matrix
903+
* supported devices (e.g ESP32-P4)
904+
*/
769905

770-
periph_module_enable(priv->module);
906+
#endif /* SOC_LP_GPIO_MATRIX_SUPPORTED */
907+
}
908+
#endif
771909

772910
i2c_hal_init(priv->ctx, priv->id);
773911

@@ -783,6 +921,17 @@ static void esp_i2c_init(struct esp_i2c_priv_s *priv)
783921

784922
i2c_ll_master_set_filter(priv->ctx->dev, I2C_FILTER_CYC_NUM_DEF);
785923

924+
#ifdef CONFIG_ESPRESSIF_LPI2C
925+
/* Enable internal open-drain mode for I2C IO lines */
926+
927+
priv->ctx->dev->ctr.sda_force_out = 0;
928+
priv->ctx->dev->ctr.scl_force_out = 0;
929+
930+
/* Configure the I2C master to send a NACK when the Rx FIFO count is full */
931+
932+
i2c_ll_master_rx_full_ack_level(priv->ctx->dev, 1);
933+
#endif
934+
786935
/* Initialize I2C bus clock */
787936

788937
esp_i2c_init_clock(priv, config->clk_freq);
@@ -1531,6 +1680,11 @@ struct i2c_master_s *esp_i2cbus_initialize(int port)
15311680
case ESPRESSIF_I2C1:
15321681
priv = &esp_i2c1_priv;
15331682
break;
1683+
#endif
1684+
#ifdef CONFIG_ESPRESSIF_LP_I2C0
1685+
case ESPRESSIF_LP_I2C0:
1686+
priv = &esp_lp_i2c0_priv;
1687+
break;
15341688
#endif
15351689
default:
15361690
return NULL;

arch/risc-v/src/common/espressif/esp_i2c.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@
4949
# define ESPRESSIF_I2C1 1
5050
#endif
5151

52+
#ifdef CONFIG_ESPRESSIF_LP_I2C0
53+
# define ESPRESSIF_LP_I2C0 2
54+
#endif
55+
5256
/****************************************************************************
5357
* Public Function Prototypes
5458
****************************************************************************/

arch/risc-v/src/common/espressif/esp_i2c_slave.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ static void esp_i2c_slave_init(struct esp_i2c_priv_s *priv)
540540

541541
/* Enable I2C hardware */
542542

543-
periph_module_enable(i2c_periph_signal[priv->id].module);
543+
periph_module_enable(PERIPH_I2C0_MODULE);
544544

545545
i2c_hal_init(priv->ctx, priv->id);
546546

@@ -551,7 +551,7 @@ static void esp_i2c_slave_init(struct esp_i2c_priv_s *priv)
551551
/* Initialize I2C Slave */
552552

553553
i2c_hal_slave_init(priv->ctx);
554-
i2c_ll_slave_tx_auto_start_en(priv->ctx->dev, true);
554+
i2c_ll_slave_enable_auto_start(priv->ctx->dev, true);
555555
i2c_ll_set_source_clk(priv->ctx->dev, I2C_CLK_SRC_DEFAULT);
556556
i2c_ll_set_slave_addr(priv->ctx->dev, priv->addr, false);
557557
i2c_ll_set_rxfifo_full_thr(priv->ctx->dev, I2C_FIFO_FULL_THRESH_VAL);
@@ -583,7 +583,7 @@ static void esp_i2c_slave_deinit(struct esp_i2c_priv_s *priv)
583583
const struct esp_i2c_config_s *config = priv->config;
584584

585585
i2c_hal_deinit(priv->ctx);
586-
periph_module_disable(i2c_periph_signal[priv->id].module);
586+
periph_module_disable(PERIPH_I2C0_MODULE);
587587
}
588588

589589
/****************************************************************************

arch/risc-v/src/esp32c6/hal_esp32c6.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$
212212
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)rtc_io_periph.c
213213
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)$(CHIP_SERIES)$(DELIM)temperature_sensor_periph.c
214214
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)soc$(DELIM)${CHIP_SERIES}$(DELIM)uart_periph.c
215+
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)ulp$(DELIM)lp_core$(DELIM)lp_core_i2c.c
215216

216217
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)esp_driver_gpio$(DELIM)src$(DELIM)gpio.c
217218
CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)nuttx$(DELIM)src$(DELIM)components$(DELIM)esp_driver_gpio$(DELIM)src$(DELIM)rtc_io.c

boards/risc-v/esp32c6/common/src/esp_board_i2c.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,5 +160,9 @@ int board_i2c_init(void)
160160
ret = i2c_slave_driver_init(ESPRESSIF_I2C0_SLAVE, I2C0_SLAVE_ADDR);
161161
#endif
162162

163+
#ifdef CONFIG_ESPRESSIF_LP_I2C0
164+
ret = i2c_driver_init(ESPRESSIF_LP_I2C0);
165+
#endif
166+
163167
return ret;
164168
}

0 commit comments

Comments
 (0)