summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2018-10-24 10:20:19 +0200
committerDaniel Friesel <derf@finalrewind.org>2018-10-24 10:20:19 +0200
commitf6c24bc802f2cb5ec959a768b60dadc957f113cb (patch)
tree7052d5ad788702893e6002b3107dcd1883eeab0b
parent7dac0cccc846d4452293b47b40d43f6b50ebcc33 (diff)
I2C: Add support for manual / always-on gpio pullups
-rw-r--r--Makefile16
-rw-r--r--include/driver/soft_i2c.h9
-rw-r--r--src/arch/msp430fr5969lp/driver/i2c.cc4
-rw-r--r--src/driver/soft_i2c.cc39
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 &copy);
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 */