Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers/soft_i2c: Add bit-banging I2C using GPIO LL #20333

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
drivers/soft_i2c: add soft_i2c_as_periph_i2c
With the new feature it should be possible to just use a software
I2C bus instead of a `periph_i2c` using the same APIs.

I tested this using the following patch using an SHT3X breakout board
connected to an nRF52840-DK:

```diff
--- a/tests/drivers/sht3x/Makefile
+++ b/tests/drivers/sht3x/Makefile
@@ -2,4 +2,19 @@ include ../Makefile.drivers_common

 USEMODULE += sht3x

+PIN_SCL ?= GPIO_PIN(0,27)
+PIN_SDA ?= GPIO_PIN(0,26)
+
+ifneq (,$(PIN_SCL))
+  CFLAGS += "-DSOFT_I2C_PARAM_SCL=$(PIN_SCL)"
+endif
+ifneq (,$(PIN_SDA))
+  CFLAGS += "-DSOFT_I2C_PARAM_SDA=$(PIN_SDA)"
+endif
+
+USEMODULE += soft_i2c
+USEMODULE += soft_i2c_as_periph_i2c
+
+CFLAGS += "-DSHT3X_PARAM_I2C_ADDR=SHT3X_I2C_ADDR_1"
+
 include $(RIOTBASE)/Makefile.include
```
  • Loading branch information
maribu committed Feb 5, 2024
commit 21deab481cfb120f7692e3b628ca7f0191d36ad0
52 changes: 52 additions & 0 deletions drivers/soft_i2c/soft_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,3 +837,55 @@ void auto_init_soft_i2c(void)
soft_i2c_init(SOFT_I2C_DEV(i));
}
}

/* provide periph_i2c API via soft_i2c as weak symbols */
__attribute__((weak, alias("soft_i2c_init")))
void i2c_init(i2c_t dev);

__attribute__((weak, alias("soft_i2c_init_pins")))
void i2c_init_pins(i2c_t dev);

__attribute__((weak, alias("soft_i2c_deinit_pins")))
void i2c_deinit_pins(i2c_t dev);

__attribute__((weak, alias("soft_i2c_pin_sda")))
gpio_t i2c_pin_sda(i2c_t dev);

__attribute__((weak, alias("soft_i2c_pin_scl")))
gpio_t i2c_pin_scl(i2c_t dev);

__attribute__((weak, alias("soft_i2c_acquire")))
void i2c_acquire(i2c_t dev);

__attribute__((weak, alias("soft_i2c_release")))
void i2c_release(i2c_t dev);

__attribute__((weak, alias("soft_i2c_read_reg")))
int i2c_read_reg(i2c_t dev, uint16_t addr, uint16_t reg,
void *data, uint8_t flags);

__attribute__((weak, alias("soft_i2c_read_regs")))
int i2c_read_regs(i2c_t dev, uint16_t addr, uint16_t reg,
void *data, size_t len, uint8_t flags);

__attribute__((weak, alias("soft_i2c_read_byte")))
int i2c_read_byte(i2c_t dev, uint16_t addr, void *data, uint8_t flags);

__attribute__((weak, alias("soft_i2c_read_bytes")))
int i2c_read_bytes(i2c_t dev, uint16_t addr,
void *data, size_t len, uint8_t flags);

__attribute__((weak, alias("soft_i2c_write_byte")))
int i2c_write_byte(i2c_t dev, uint16_t addr, uint8_t data, uint8_t flags);

__attribute__((weak, alias("soft_i2c_write_bytes")))
int i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data,
size_t len, uint8_t flags);

__attribute__((weak, alias("soft_i2c_write_reg")))
int i2c_write_reg(i2c_t dev, uint16_t addr, uint16_t reg,
uint8_t data, uint8_t flags);

__attribute__((weak, alias("soft_i2c_write_regs")))
int i2c_write_regs(i2c_t dev, uint16_t addr, uint16_t reg,
const void *data, size_t len, uint8_t flags);
4 changes: 4 additions & 0 deletions makefiles/features_check.inc.mk
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Check if all required FEATURES are provided

ifneq (,$(filter soft_i2c,$(USEMODULE)))
FEATURES_PROVIDED += periph_i2c
endif

# Features that are used without taking "one out of" dependencies into account
FEATURES_USED_SO_FAR := $(sort $(FEATURES_REQUIRED) $(FEATURES_OPTIONAL_USED))

Expand Down
5 changes: 5 additions & 0 deletions makefiles/features_modules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ PERIPH_IGNORE_MODULES := \
periph_wdog \
periph_wdt_auto_start \
#

ifneq (,$(filter soft_i2c_as_periph_i2c,$(USEMODULE)))
USEMODULE := $(filter-out periph_i2c,$(USEMODULE))
endif

PERIPH_MODULES := $(filter-out $(PERIPH_IGNORE_MODULES),\
$(filter periph_%,$(USEMODULE)))
# Use simple expansion to avoid USEMODULE referencing itself
Expand Down
5 changes: 5 additions & 0 deletions makefiles/pseudomodules.inc.mk
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,11 @@ PSEUDOMODULES += sock_ip
PSEUDOMODULES += sock_tcp
PSEUDOMODULES += sock_udp
PSEUDOMODULES += socket_zep_hello
## @defgroup drivers_soft_i2c_as_periph_i2c Use `soft_i2c` to provide `periph_i2c`
## @ingroup drivers_soft_i2c
## @{
PSEUDOMODULES += soft_i2c_as_periph_i2c
## @}
PSEUDOMODULES += soft_uart_modecfg
PSEUDOMODULES += stdin
PSEUDOMODULES += stdio_available
Expand Down