Commit f6c24bc8 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

I2C: Add support for manual / always-on gpio pullups

parent 7dac0ccc
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -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)
+9 −0
Original line number Diff line number Diff line
@@ -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,
+4 −0
Original line number Diff line number Diff line
@@ -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;
+34 −5
Original line number Diff line number Diff line
@@ -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 */