From f6c24bc802f2cb5ec959a768b60dadc957f113cb Mon Sep 17 00:00:00 2001 From: Daniel Friesel Date: Wed, 24 Oct 2018 10:20:19 +0200 Subject: I2C: Add support for manual / always-on gpio pullups --- Makefile | 16 ++++++++++++-- include/driver/soft_i2c.h | 9 ++++++++ src/arch/msp430fr5969lp/driver/i2c.cc | 4 ++++ src/driver/soft_i2c.cc | 39 ++++++++++++++++++++++++++++++----- 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index cbe93c8..3148fdc 100644 --- a/Makefile +++ b/Makefile @@ -71,8 +71,20 @@ ifneq (${timer_freq}, ) COMMON_FLAGS += -DF_TIMER=${timer_freq} endif -ifeq (${softi2c_pullup}, 1) - COMMON_FLAGS += -DSOFTI2C_PULLUP +ifeq (${softi2c_pullup}, internal) + COMMON_FLAGS += -DSOFTI2C_PULLUP_INTERNAL +endif + +ifeq (${softi2c_pullup}, external) + COMMON_FLAGS += -DSOFTI2C_PULLUP_EXTERNAL +endif + +ifeq (${softi2c_pullup}, gpio) + COMMON_FLAGS += -DSOFTI2C_PULLUP_FIXED_GPIO +endif + +ifeq (${i2c_pullup}, gpio) + COMMON_FLAGS += -DI2C_PULLUP_FIXED_GPIO endif ifeq (${softi2c_timer}, 1) diff --git a/include/driver/soft_i2c.h b/include/driver/soft_i2c.h index aff63e3..f3ba14f 100644 --- a/include/driver/soft_i2c.h +++ b/include/driver/soft_i2c.h @@ -6,6 +6,9 @@ class SoftI2C { SoftI2C(const SoftI2C ©); unsigned char sda, scl; +#if SOFTI2C_PULLUP_EXTERNAL || SOFTI2C_PULLUP_FIXED_GPIO + unsigned char sda_pull, scl_pull; +#endif void start(); void stop(); @@ -13,7 +16,13 @@ class SoftI2C { unsigned char rx(bool send_ack); public: +#if SOFTI2C_PULLUP_EXTERNAL || SOFTI2C_PULLUP_FIXED_GPIO + SoftI2C(unsigned char sda, unsigned char scl, + unsigned char sda_pull, unsigned char scl_pull) : + sda(sda), scl(scl), sda_pull(sda_pull), scl_pull(scl_pull) {} +#else SoftI2C(unsigned char sda, unsigned char scl) : sda(sda), scl(scl) {} +#endif signed char setup(); void scan(unsigned int *results); signed char xmit(unsigned char address, diff --git a/src/arch/msp430fr5969lp/driver/i2c.cc b/src/arch/msp430fr5969lp/driver/i2c.cc index 5a47770..cb6fa79 100644 --- a/src/arch/msp430fr5969lp/driver/i2c.cc +++ b/src/arch/msp430fr5969lp/driver/i2c.cc @@ -10,6 +10,10 @@ volatile unsigned short old_ifg = 0; signed char I2C::setup() { +#ifdef I2C_PULLUP_FIXED_GPIO + P1DIR |= BIT4 | BIT5; + P1OUT |= BIT4 | BIT5; +#endif UCB0CTL1 = UCSWRST; UCB0CTLW0 = UCMODE_3 | UCMST | UCSYNC | UCSSEL_2 | UCSWRST | UCCLTO_1; UCB0BRW = (F_CPU / F_I2C) - 1; diff --git a/src/driver/soft_i2c.cc b/src/driver/soft_i2c.cc index 39754a3..6523286 100644 --- a/src/driver/soft_i2c.cc +++ b/src/driver/soft_i2c.cc @@ -13,17 +13,22 @@ #include "driver/timer.h" #endif -#ifdef SOFTI2C_PULLUP +#ifdef SOFTI2C_PULLUP_INTERNAL #define SDA_HIGH gpio.input(sda, 1) #define SDA_LOW gpio.output(sda, 0) #define SCL_HIGH gpio.input(scl, 1) #define SCL_LOW gpio.output(scl, 0) -#else +#elif SOFTI2C_PULLUP_EXTERNAL +#define SDA_HIGH do { gpio.input(sda); gpio.write(sda_pull, 1); } while (0) +#define SDA_LOW do { gpio.write(sda_pull, 0); gpio.output(sda); } while (0) +#define SCL_HIGH do { gpio.input(scl); gpio.write(scl_pull, 1); } while (0) +#define SCL_LOW do { gpio.write(scl_pull, 0); gpio.output(scl); } while (0) +#else /* !SOFTI2C_PULLUP_{INTERNAL,EXTERNAL} */ #define SDA_HIGH gpio.input(sda) #define SDA_LOW gpio.output(sda) #define SCL_HIGH gpio.input(scl) #define SCL_LOW gpio.output(scl) -#endif +#endif /* SOFTI2C_PULLUP */ #ifndef SOFTI2C_TIMER @@ -31,10 +36,24 @@ #define I2C_WAIT arch.delay_us((500000UL / F_I2C) - 10) #else #define I2C_WAIT -#endif +#endif /* !SOFTI2C_TIMER */ signed char SoftI2C::setup() { +#ifdef SOFTI2C_PULLUP_EXTERNAL + gpio.output(sda_pull); + gpio.output(scl_pull); +#endif +#ifdef SOFTI2C_PULLUP_FIXED_GPIO +#if MULTIPASS_ARCH_msp430fr5969lp + gpio.output(GPIO::p1_4); + gpio.output(GPIO::p1_5); + gpio.write(GPIO::p1_4, 1); + gpio.write(GPIO::p1_5, 1); +#else +#error "softi2c_pullup=gpio not supported on this architecture" +#endif /* MULTIPASS_ARCH_* */ +#endif /* SOFTI2C_PULLUP_FIXED_GPIO */ SDA_HIGH; SCL_HIGH; return 0; @@ -303,6 +322,13 @@ ON_TIMER_INTERRUPT_tail #endif +#if SOFTI2C_PULLUP_EXTERNAL +#ifdef MULTIPASS_ARCH_msp430fr5969lp +SoftI2C i2c(GPIO::p1_6, GPIO::p1_7, GPIO::p1_4, GPIO::p1_5); +#else +#error "softi2c_pullup = external not supported on this architecture" +#endif /* MULTIPASS_ARCH_* */ +#else #ifdef MULTIPASS_ARCH_esp8266 SoftI2C i2c(GPIO::d6, GPIO::d7); #elif MULTIPASS_ARCH_arduino_nano @@ -311,4 +337,7 @@ SoftI2C i2c(GPIO::pc4, GPIO::pc5); SoftI2C i2c(GPIO::pc4, GPIO::pc5); #elif MULTIPASS_ARCH_msp430fr5969lp SoftI2C i2c(GPIO::p1_6, GPIO::p1_7); -#endif +#elif MULTIPASS_ARCH_posix +SoftI2C i2c(GPIO::px00, GPIO::px01); +#endif /* MULTIPASS_ARCH_* */ +#endif /* !SOFTI2C_PULLUP_EXTERNAL */ -- cgit v1.2.3