From 47f150bdce53a3d10cfda348ed1a989b323afb24 Mon Sep 17 00:00:00 2001 From: Dimitris Mantzouranis Date: Wed, 8 Jul 2026 13:02:55 +0300 Subject: [PATCH 1/2] i2c fallback driver: speedup and conform to i2c specs gpio mode switching is time consuming - streamline it --- os/hal/lib/fallback/I2C/hal_i2c_lld.c | 37 ++++++++++++++------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/os/hal/lib/fallback/I2C/hal_i2c_lld.c b/os/hal/lib/fallback/I2C/hal_i2c_lld.c index f01acce89a..bb263cff14 100644 --- a/os/hal/lib/fallback/I2C/hal_i2c_lld.c +++ b/os/hal/lib/fallback/I2C/hal_i2c_lld.c @@ -95,17 +95,10 @@ static inline void i2c_delay(I2CDriver *i2cp) { } static inline msg_t i2c_check_arbitration(I2CDriver *i2cp) { -#if (SW_I2C_USE_OPENDRAIN == FALSE) - palSetLineMode(i2cp->config->sda, PAL_MODE_INPUT); -#endif - i2c_delay(i2cp); if (palReadLine(i2cp->config->sda) == PAL_LOW) { i2cp->errors |= I2C_ARBITRATION_LOST; return MSG_RESET; } -#if (SW_I2C_USE_OPENDRAIN == FALSE) - palSetLineMode(i2cp->config->sda, PAL_MODE_OUTPUT_PUSHPULL); -#endif return MSG_OK; } @@ -121,9 +114,6 @@ static inline msg_t i2c_check_timeout(I2CDriver *i2cp) { } static msg_t i2c_wait_clock(I2CDriver *i2cp) { -#if (SW_I2C_USE_OPENDRAIN == FALSE) - palSetLineMode(i2cp->config->scl, PAL_MODE_INPUT); -#endif i2c_delay(i2cp); while (palReadLine(i2cp->config->scl) == PAL_LOW) { @@ -133,9 +123,6 @@ static msg_t i2c_wait_clock(I2CDriver *i2cp) { } i2c_delay(i2cp); } -#if (SW_I2C_USE_OPENDRAIN == FALSE) - palSetLineMode(i2cp->config->scl, PAL_MODE_OUTPUT_PUSHPULL); -#endif return MSG_OK; } @@ -213,7 +200,9 @@ static msg_t i2c_write_bit(I2CDriver *i2cp, unsigned bit) { static msg_t i2c_read_bit(I2CDriver *i2cp) { msg_t bit; #if (SW_I2C_USE_OPENDRAIN == FALSE) - palSetLineMode(i2cp->config->sda, PAL_MODE_INPUT); + palSetLineMode(i2cp->config->sda, PAL_MODE_INPUT_PULLUP); +#else + palSetLine(i2cp->config->sda); #endif i2c_delay(i2cp); palSetLine(i2cp->config->scl); @@ -225,10 +214,12 @@ static msg_t i2c_read_bit(I2CDriver *i2cp) { bit = palReadLine(i2cp->config->sda); #if (SW_I2C_USE_OPENDRAIN == FALSE) + palClearLine(i2cp->config->scl); + palClearLine(i2cp->config->sda); /* Pre-set output register low */ palSetLineMode(i2cp->config->sda, PAL_MODE_OUTPUT_PUSHPULL); -#endif +#else palClearLine(i2cp->config->scl); - i2c_delay(i2cp); +#endif return bit; } @@ -347,8 +338,18 @@ void i2c_lld_init(void) { */ void i2c_lld_start(I2CDriver *i2cp) { - /* Does nothing.*/ - (void)i2cp; +#if (SW_I2C_USE_OPENDRAIN == FALSE) + /* Push-pull mode with INPUT switching */ + palSetLine(i2cp->config->sda); + palSetLine(i2cp->config->scl); + palSetLineMode(i2cp->config->sda, PAL_MODE_OUTPUT_PUSHPULL); + palSetLineMode(i2cp->config->scl, PAL_MODE_OUTPUT_PUSHPULL); +#else + palSetLine(i2cp->config->sda); + palSetLine(i2cp->config->scl); + palSetLineMode(i2cp->config->sda, PAL_MODE_OUTPUT_OPENDRAIN); + palSetLineMode(i2cp->config->scl, PAL_MODE_OUTPUT_OPENDRAIN); +#endif } /** From f6b6e807c43182591c76fab6ae7a998c06499f0f Mon Sep 17 00:00:00 2001 From: Dimitris Mantzouranis Date: Wed, 8 Jul 2026 13:55:58 +0300 Subject: [PATCH 2/2] ports: switch to contrib level i2c fallback --- os/hal/ports/GD/GD32VF103/I2Cv1/driver.mk | 6 +++--- os/hal/ports/KINETIS/LLD/I2Cv1/driver.mk | 6 +++--- os/hal/ports/NUMICRO/LLD/I2Cv1/driver.mk | 6 +++--- os/hal/ports/RP/LLD/I2Cv1/driver.mk | 6 +++--- os/hal/ports/TIVA/LLD/I2C/driver.mk | 6 +++--- os/hal/ports/WB32/LLD/I2Cv1/driver.mk | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/os/hal/ports/GD/GD32VF103/I2Cv1/driver.mk b/os/hal/ports/GD/GD32VF103/I2Cv1/driver.mk index 5a4e22f595..ed7f416640 100644 --- a/os/hal/ports/GD/GD32VF103/I2Cv1/driver.mk +++ b/os/hal/ports/GD/GD32VF103/I2Cv1/driver.mk @@ -2,12 +2,12 @@ ifeq ($(USE_HAL_I2C_FALLBACK),yes) # Fallback SW driver. ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) - PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif else - PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif - PLATFORMINC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C + PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C else # Default HW driver. ifeq ($(USE_SMART_BUILD),yes) diff --git a/os/hal/ports/KINETIS/LLD/I2Cv1/driver.mk b/os/hal/ports/KINETIS/LLD/I2Cv1/driver.mk index 186249659d..e91ad7ee46 100644 --- a/os/hal/ports/KINETIS/LLD/I2Cv1/driver.mk +++ b/os/hal/ports/KINETIS/LLD/I2Cv1/driver.mk @@ -2,12 +2,12 @@ ifeq ($(USE_HAL_I2C_FALLBACK),yes) # Fallback SW driver. ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) - PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif else - PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif - PLATFORMINC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C + PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C else ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) diff --git a/os/hal/ports/NUMICRO/LLD/I2Cv1/driver.mk b/os/hal/ports/NUMICRO/LLD/I2Cv1/driver.mk index a96d2dd243..37eea3f823 100644 --- a/os/hal/ports/NUMICRO/LLD/I2Cv1/driver.mk +++ b/os/hal/ports/NUMICRO/LLD/I2Cv1/driver.mk @@ -2,12 +2,12 @@ ifeq ($(USE_HAL_I2C_FALLBACK),yes) # Fallback SW driver. ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) - PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif else - PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif - PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C + PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C else ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) diff --git a/os/hal/ports/RP/LLD/I2Cv1/driver.mk b/os/hal/ports/RP/LLD/I2Cv1/driver.mk index e9a11df94f..3975a78d6e 100644 --- a/os/hal/ports/RP/LLD/I2Cv1/driver.mk +++ b/os/hal/ports/RP/LLD/I2Cv1/driver.mk @@ -2,12 +2,12 @@ ifeq ($(USE_HAL_I2C_FALLBACK),yes) # Fallback SW driver. ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) - PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif else - PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif - PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C + PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C else ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) diff --git a/os/hal/ports/TIVA/LLD/I2C/driver.mk b/os/hal/ports/TIVA/LLD/I2C/driver.mk index 0e428f0220..32ff083ff9 100644 --- a/os/hal/ports/TIVA/LLD/I2C/driver.mk +++ b/os/hal/ports/TIVA/LLD/I2C/driver.mk @@ -2,12 +2,12 @@ ifeq ($(USE_HAL_I2C_FALLBACK),yes) # Fallback SW driver. ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) - PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif else - PLATFORMSRC += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif - PLATFORMINC += $(CHIBIOS)/os/hal/lib/fallback/I2C + PLATFORMINC += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C else ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) diff --git a/os/hal/ports/WB32/LLD/I2Cv1/driver.mk b/os/hal/ports/WB32/LLD/I2Cv1/driver.mk index b8939ed8b1..7c4d4dcb9e 100644 --- a/os/hal/ports/WB32/LLD/I2Cv1/driver.mk +++ b/os/hal/ports/WB32/LLD/I2Cv1/driver.mk @@ -2,12 +2,12 @@ ifeq ($(USE_HAL_I2C_FALLBACK),yes) # Fallback SW driver. ifeq ($(USE_SMART_BUILD),yes) ifneq ($(findstring HAL_USE_I2C TRUE,$(HALCONF)),) - PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif else - PLATFORMSRC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C/hal_i2c_lld.c + PLATFORMSRC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C/hal_i2c_lld.c endif - PLATFORMINC_CONTRIB += $(CHIBIOS)/os/hal/lib/fallback/I2C + PLATFORMINC_CONTRIB += $(CHIBIOS_CONTRIB)/os/hal/lib/fallback/I2C else # Default HW driver. ifeq ($(USE_SMART_BUILD),yes)