diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig index f83d01071fc..a1d067b1118 100644 --- a/arch/risc-v/src/common/espressif/Kconfig +++ b/arch/risc-v/src/common/espressif/Kconfig @@ -320,11 +320,17 @@ config ESPRESSIF_I2C bool default n +config ESPRESSIF_I2C_PERIPH + bool + depends on (ESPRESSIF_I2C0 || ESPRESSIF_I2C1) + default n + config ESPRESSIF_I2C0 bool "I2C 0" default n select ESPRESSIF_I2C select I2C + select ESPRESSIF_I2C_PERIPH config ESPRESSIF_I2C1 bool "I2C 1" @@ -332,6 +338,17 @@ config ESPRESSIF_I2C1 depends on ARCH_CHIP_ESP32H2 select ESPRESSIF_I2C select I2C + select ESPRESSIF_I2C_PERIPH + +config ESPRESSIF_I2C_BITBANG + bool "I2C Bitbang" + default n + select I2C_BITBANG + select ESPRESSIF_I2C + select I2C + select I2C_BITBANG + ---help--- + Software implemented I2C peripheral with GPIOs. Suggested to use if I2C peripherals are already in use. config ESPRESSIF_SPI bool @@ -1574,12 +1591,28 @@ config ESPRESSIF_I2C1_SDAPIN endif # ESPRESSIF_I2C1 +if ESPRESSIF_I2C_BITBANG + +config ESPRESSIF_I2C_BITBANG_SCLPIN + int "I2C Bitbang SCL Pin" + default 0 + range 0 21 + +config ESPRESSIF_I2C_BITBANG_SDAPIN + int "I2C Bitbang SDA Pin" + default 1 + range 0 21 + +endif # ESPRESSIF_I2C_BITBANG + config ESPRESSIF_I2CTIMEOSEC int "Timeout seconds" + depends on ESPRESSIF_I2C_PERIPH default 0 config ESPRESSIF_I2CTIMEOMS int "Timeout milliseconds" + depends on ESPRESSIF_I2C_PERIPH default 500 endmenu # I2C configuration diff --git a/arch/risc-v/src/common/espressif/Make.defs b/arch/risc-v/src/common/espressif/Make.defs index c538643a1e1..8e0791cc395 100644 --- a/arch/risc-v/src/common/espressif/Make.defs +++ b/arch/risc-v/src/common/espressif/Make.defs @@ -99,7 +99,12 @@ ifeq ($(CONFIG_ESPRESSIF_TEMP),y) endif ifeq ($(CONFIG_ESPRESSIF_I2C),y) - CHIP_CSRCS += esp_i2c.c + ifeq ($(CONFIG_ESPRESSIF_I2C_PERIPH),y) + CHIP_CSRCS += esp_i2c.c + endif + ifeq ($(CONFIG_ESPRESSIF_I2C_BITBANG),y) + CHIP_CSRCS += esp_i2c_bitbang.c + endif endif ifeq ($(CONFIG_ESPRESSIF_SPI),y) diff --git a/arch/risc-v/src/common/espressif/esp_i2c.c b/arch/risc-v/src/common/espressif/esp_i2c.c index 2cf0f64e670..d95076753ce 100644 --- a/arch/risc-v/src/common/espressif/esp_i2c.c +++ b/arch/risc-v/src/common/espressif/esp_i2c.c @@ -24,7 +24,7 @@ #include -#ifdef CONFIG_ESPRESSIF_I2C +#ifdef CONFIG_ESPRESSIF_I2C_PERIPH #include #include @@ -1604,4 +1604,4 @@ int esp_i2cbus_uninitialize(struct i2c_master_s *dev) return OK; } -#endif /* CONFIG_ESPRESSIF_I2C */ +#endif /* CONFIG_ESPRESSIF_I2C_PERIPH */ diff --git a/arch/risc-v/src/common/espressif/esp_i2c.h b/arch/risc-v/src/common/espressif/esp_i2c.h index 8a51a2ee850..dac49699a3b 100644 --- a/arch/risc-v/src/common/espressif/esp_i2c.h +++ b/arch/risc-v/src/common/espressif/esp_i2c.h @@ -51,6 +51,7 @@ * Public Function Prototypes ****************************************************************************/ +#ifdef CONFIG_ESPRESSIF_I2C_PERIPH /**************************************************************************** * Name: esp_i2cbus_initialize * @@ -86,6 +87,7 @@ struct i2c_master_s *esp_i2cbus_initialize(int port); ****************************************************************************/ int esp_i2cbus_uninitialize(struct i2c_master_s *dev); +#endif /* CONFIG_ESPRESSIF_I2C_PERIPH */ #endif /* __ASSEMBLY__ */ #endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_I2C_H */ diff --git a/arch/risc-v/src/common/espressif/esp_i2c_bitbang.c b/arch/risc-v/src/common/espressif/esp_i2c_bitbang.c new file mode 100644 index 00000000000..b728c8a4571 --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_i2c_bitbang.c @@ -0,0 +1,247 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_i2c_bitbang.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG +#include +#include +#include +#include + +#include "espressif/esp_i2c_bitbang.h" +#include "soc/gpio_sig_map.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct esp_i2c_bitbang_dev_s +{ + struct i2c_bitbang_lower_dev_s lower; + int sda_pin; + int scl_pin; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void esp_i2c_bitbang_init(struct i2c_bitbang_lower_dev_s *lower); +static void esp_i2c_bitbang_set_scl(struct i2c_bitbang_lower_dev_s *lower, + bool value); +static void esp_i2c_bitbang_set_sda(struct i2c_bitbang_lower_dev_s *lower, + bool value); +static bool esp_i2c_bitbang_get_scl(struct i2c_bitbang_lower_dev_s *lower); +static bool esp_i2c_bitbang_get_sda(struct i2c_bitbang_lower_dev_s *lower); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Lower-half I2C bitbang data */ + +const static struct i2c_bitbang_lower_ops_s g_ops = +{ + .initialize = esp_i2c_bitbang_init, + .set_scl = esp_i2c_bitbang_set_scl, + .set_sda = esp_i2c_bitbang_set_sda, + .get_scl = esp_i2c_bitbang_get_scl, + .get_sda = esp_i2c_bitbang_get_sda +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_i2c_bitbang_init + * + * Description: + * Initialize the I2C bit-bang driver + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_i2c_bitbang_init(struct i2c_bitbang_lower_dev_s *lower) +{ + struct esp_i2c_bitbang_dev_s *dev = lower->priv; + + esp_gpiowrite(dev->scl_pin, 1); + esp_gpiowrite(dev->sda_pin, 1); + + esp_configgpio(dev->scl_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN); + esp_gpio_matrix_out(dev->scl_pin, SIG_GPIO_OUT_IDX, 0, 0); + + esp_configgpio(dev->sda_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN); + esp_gpio_matrix_out(dev->sda_pin, SIG_GPIO_OUT_IDX, 0, 0); +} + +/**************************************************************************** + * Name: esp_i2c_bitbang_set_scl + * + * Description: + * Set SCL line value + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * value - The value to be written (0 or 1). + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_i2c_bitbang_set_scl(struct i2c_bitbang_lower_dev_s *lower, + bool value) +{ + struct esp_i2c_bitbang_dev_s *dev = + (struct esp_i2c_bitbang_dev_s *)lower->priv; + + esp_gpiowrite(dev->scl_pin, value); +} + +/**************************************************************************** + * Name: esp_i2c_bitbang_set_sda + * + * Description: + * Set SDA line value + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * value - The value to be written (0 or 1). + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_i2c_bitbang_set_sda(struct i2c_bitbang_lower_dev_s *lower, + bool value) +{ + struct esp_i2c_bitbang_dev_s *dev = + (struct esp_i2c_bitbang_dev_s *)lower->priv; + + esp_gpiowrite(dev->sda_pin, value); +} + +/**************************************************************************** + * Name: esp_i2c_bitbang_get_scl + * + * Description: + * Get value from SCL line + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * + * Returned Value: + * The boolean representation of the SCL line value (true/false). + * + ****************************************************************************/ + +static bool esp_i2c_bitbang_get_scl(struct i2c_bitbang_lower_dev_s *lower) +{ + struct esp_i2c_bitbang_dev_s *dev = + (struct esp_i2c_bitbang_dev_s *)lower->priv; + + return esp_gpioread(dev->scl_pin); +} + +/**************************************************************************** + * Name: esp_i2c_bitbang_get_sda + * + * Description: + * Get value from SDA line + * + * Input Parameters: + * lower - A pointer the publicly visible representation of + * the "lower-half" driver state structure. + * + * Returned Value: + * The boolean representation of the SDA line value (true/false). + * + ****************************************************************************/ + +static bool esp_i2c_bitbang_get_sda(struct i2c_bitbang_lower_dev_s *lower) +{ + struct esp_i2c_bitbang_dev_s *dev = + (struct esp_i2c_bitbang_dev_s *)lower->priv; + + return esp_gpioread(dev->sda_pin); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_i2cbus_bitbang_initialize + * + * Description: + * Initialize the I2C bitbang driver. And return a unique instance of + * struct struct i2c_master_s. This function may be called to obtain + * multiple instances of the interface, each of which may be set up with + * a different frequency and slave address. + * + * Input Parameters: + * None + * + * Returned Value: + * Valid I2C device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct i2c_master_s *esp_i2cbus_bitbang_initialize(void) +{ + struct esp_i2c_bitbang_dev_s *dev = + (struct esp_i2c_bitbang_dev_s *) + kmm_malloc(sizeof(struct esp_i2c_bitbang_dev_s)); + + DEBUGASSERT(dev); + + dev->lower.ops = &g_ops; + dev->lower.priv = dev; + dev->scl_pin = CONFIG_ESPRESSIF_I2C_BITBANG_SCLPIN; + dev->sda_pin = CONFIG_ESPRESSIF_I2C_BITBANG_SDAPIN; + + return i2c_bitbang_initialize(&dev->lower); +} +#endif /* CONFIG_ESPRESSIF_I2C_BITBANG */ diff --git a/arch/risc-v/src/common/espressif/esp_i2c_bitbang.h b/arch/risc-v/src/common/espressif/esp_i2c_bitbang.h new file mode 100644 index 00000000000..7e5a96ef6dd --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_i2c_bitbang.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_i2c_bitbang.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_I2C_BITBANG_H +#define __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_I2C_BITBANG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "espressif/esp_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG +# define ESPRESSIF_I2C_BITBANG 3 +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG +/**************************************************************************** + * Name: esp_i2cbus_bitbang_initialize + * + * Description: + * Initialize the I2C bitbang driver. And return a unique instance of + * struct struct i2c_master_s. This function may be called to obtain + * multiple instances of the interface, each of which may be set up with + * a different frequency and slave address. + * + * Input Parameters: + * None + * + * Returned Value: + * Valid I2C device structure reference on success; a NULL on failure + * + ****************************************************************************/ + +struct i2c_master_s *esp_i2cbus_bitbang_initialize(void); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_I2C_BITBANG_H */ diff --git a/boards/risc-v/esp32c3/common/src/esp_board_bmp180.c b/boards/risc-v/esp32c3/common/src/esp_board_bmp180.c index 4161a9e77fc..33d367ecc94 100644 --- a/boards/risc-v/esp32c3/common/src/esp_board_bmp180.c +++ b/boards/risc-v/esp32c3/common/src/esp_board_bmp180.c @@ -31,7 +31,11 @@ #include #include +#ifndef CONFIG_ESPRESSIF_I2C_BITBANG #include "espressif/esp_i2c.h" +#else +#include "espressif/esp_i2c_bitbang.h" +#endif #include "esp_board_bmp180.h" @@ -64,7 +68,11 @@ int board_bmp180_initialize(int devno) /* Initialize BMP180 */ +#ifndef CONFIG_ESPRESSIF_I2C_BITBANG i2c = esp_i2cbus_initialize(ESPRESSIF_I2C0); +#else + i2c = esp_i2cbus_bitbang_initialize(); +#endif if (i2c) { diff --git a/boards/risc-v/esp32c3/common/src/esp_board_i2c.c b/boards/risc-v/esp32c3/common/src/esp_board_i2c.c index 04ade5e6f9d..c974c23b59c 100644 --- a/boards/risc-v/esp32c3/common/src/esp_board_i2c.c +++ b/boards/risc-v/esp32c3/common/src/esp_board_i2c.c @@ -30,12 +30,41 @@ #include +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG +#include "espressif/esp_i2c_bitbang.h" +#endif +#ifdef CONFIG_ESPRESSIF_I2C_PERIPH #include "espressif/esp_i2c.h" +#endif /**************************************************************************** * Public Functions ****************************************************************************/ +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG +static int i2c_bitbang_driver_init(int bus) +{ + struct i2c_master_s *i2c; + int ret; + + i2c = esp_i2cbus_bitbang_initialize(); + if (i2c == NULL) + { + i2cerr("Failed to get I2C%d interface\n", bus); + return -ENODEV; + } + + ret = i2c_register(i2c, bus); + if (ret < 0) + { + i2cerr("Failed to register I2C%d driver: %d\n", bus, ret); + } + + return ret; +} +#endif + +#ifdef CONFIG_ESPRESSIF_I2C_PERIPH static int i2c_driver_init(int bus) { struct i2c_master_s *i2c; @@ -57,6 +86,7 @@ static int i2c_driver_init(int bus) return ret; } +#endif /**************************************************************************** * Name: board_i2c_init @@ -78,5 +108,9 @@ int board_i2c_init(void) ret = i2c_driver_init(ESPRESSIF_I2C0); #endif +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG + ret = i2c_bitbang_driver_init(ESPRESSIF_I2C_BITBANG); +#endif + return ret; } diff --git a/boards/risc-v/esp32c6/common/src/esp_board_bmp180.c b/boards/risc-v/esp32c6/common/src/esp_board_bmp180.c index b9327dedd31..00ab194ffdf 100644 --- a/boards/risc-v/esp32c6/common/src/esp_board_bmp180.c +++ b/boards/risc-v/esp32c6/common/src/esp_board_bmp180.c @@ -31,7 +31,11 @@ #include #include +#ifndef CONFIG_ESPRESSIF_I2C_BITBANG #include "espressif/esp_i2c.h" +#else +#include "espressif/esp_i2c_bitbang.h" +#endif #include "esp_board_bmp180.h" @@ -64,7 +68,11 @@ int board_bmp180_initialize(int devno) /* Initialize BMP180 */ +#ifndef CONFIG_ESPRESSIF_I2C_BITBANG i2c = esp_i2cbus_initialize(ESPRESSIF_I2C0); +#else + i2c = esp_i2cbus_bitbang_initialize(); +#endif if (i2c) { diff --git a/boards/risc-v/esp32c6/common/src/esp_board_i2c.c b/boards/risc-v/esp32c6/common/src/esp_board_i2c.c index 094f742b8e6..40a0e3d4d11 100644 --- a/boards/risc-v/esp32c6/common/src/esp_board_i2c.c +++ b/boards/risc-v/esp32c6/common/src/esp_board_i2c.c @@ -30,12 +30,41 @@ #include +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG +#include "espressif/esp_i2c_bitbang.h" +#endif +#ifdef CONFIG_ESPRESSIF_I2C_PERIPH #include "espressif/esp_i2c.h" +#endif /**************************************************************************** * Public Functions ****************************************************************************/ +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG +static int i2c_bitbang_driver_init(int bus) +{ + struct i2c_master_s *i2c; + int ret; + + i2c = esp_i2cbus_bitbang_initialize(); + if (i2c == NULL) + { + i2cerr("Failed to get I2C%d interface\n", bus); + return -ENODEV; + } + + ret = i2c_register(i2c, bus); + if (ret < 0) + { + i2cerr("Failed to register I2C%d driver: %d\n", bus, ret); + } + + return ret; +} +#endif + +#ifdef CONFIG_ESPRESSIF_I2C_PERIPH static int i2c_driver_init(int bus) { struct i2c_master_s *i2c; @@ -57,6 +86,7 @@ static int i2c_driver_init(int bus) return ret; } +#endif /**************************************************************************** * Name: board_i2c_init @@ -78,5 +108,9 @@ int board_i2c_init(void) ret = i2c_driver_init(ESPRESSIF_I2C0); #endif +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG + ret = i2c_bitbang_driver_init(ESPRESSIF_I2C_BITBANG); +#endif + return ret; } diff --git a/boards/risc-v/esp32h2/common/src/esp_board_bmp180.c b/boards/risc-v/esp32h2/common/src/esp_board_bmp180.c index 616a65b237e..d1768097604 100644 --- a/boards/risc-v/esp32h2/common/src/esp_board_bmp180.c +++ b/boards/risc-v/esp32h2/common/src/esp_board_bmp180.c @@ -31,7 +31,11 @@ #include #include +#ifndef CONFIG_ESPRESSIF_I2C_BITBANG #include "espressif/esp_i2c.h" +#else +#include "espressif/esp_i2c_bitbang.h" +#endif #include "esp_board_bmp180.h" @@ -63,7 +67,11 @@ int board_bmp180_initialize(int devno) /* Initialize BMP180 */ +#ifndef CONFIG_ESPRESSIF_I2C_BITBANG i2c = esp_i2cbus_initialize(ESPRESSIF_I2C0); +#else + i2c = esp_i2cbus_bitbang_initialize(); +#endif if (i2c) { diff --git a/boards/risc-v/esp32h2/common/src/esp_board_i2c.c b/boards/risc-v/esp32h2/common/src/esp_board_i2c.c index 76eda63a29b..43f7d133afc 100644 --- a/boards/risc-v/esp32h2/common/src/esp_board_i2c.c +++ b/boards/risc-v/esp32h2/common/src/esp_board_i2c.c @@ -30,12 +30,41 @@ #include +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG +#include "espressif/esp_i2c_bitbang.h" +#endif +#ifdef CONFIG_ESPRESSIF_I2C_PERIPH #include "espressif/esp_i2c.h" +#endif /**************************************************************************** * Public Functions ****************************************************************************/ +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG +static int i2c_bitbang_driver_init(int bus) +{ + struct i2c_master_s *i2c; + int ret; + + i2c = esp_i2cbus_bitbang_initialize(); + if (i2c == NULL) + { + i2cerr("Failed to get I2C%d interface\n", bus); + return -ENODEV; + } + + ret = i2c_register(i2c, bus); + if (ret < 0) + { + i2cerr("Failed to register I2C%d driver: %d\n", bus, ret); + } + + return ret; +} +#endif + +#ifdef CONFIG_ESPRESSIF_I2C_PERIPH static int i2c_driver_init(int bus) { struct i2c_master_s *i2c; @@ -57,6 +86,7 @@ static int i2c_driver_init(int bus) return ret; } +#endif /**************************************************************************** * Name: board_i2c_init @@ -86,5 +116,9 @@ int board_i2c_init(void) ret = i2c_driver_init(ESPRESSIF_I2C1); #endif +#ifdef CONFIG_ESPRESSIF_I2C_BITBANG + ret = i2c_bitbang_driver_init(ESPRESSIF_I2C_BITBANG); +#endif + return ret; }