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

Support optional SoftI2C pullups on MSP430

parent 353aa779
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -32,6 +32,10 @@ ifneq ($(findstring softi2c,${drivers}), )
	COMMON_FLAGS += -DDRIVER_SOFTI2C
endif

ifeq (${softi2c_pullup}, 1)
	COMMON_FLAGS += -DSOFTI2C_PULLUP
endif

ifeq (${timer_cycles}, 1)
	COMMON_FLAGS += -DTIMER_CYCLES
endif
+41 −0
Original line number Diff line number Diff line
@@ -63,6 +63,29 @@ class GPIO {
				PJDIR &= ~(1 << (pin - pj_0));
			}
		}
		inline void input(unsigned char const pin, unsigned char const pull) {
			if (pin < p2_0) {
				P1DIR &= ~(1 << pin);
				P1OUT = pull ? (P1OUT | (1 << pin)) : (P1OUT & ~(1 << pin));
				P1REN |= (1 << pin);
			} else if (pin < p3_0) {
				P2DIR &= ~(1 << (pin - p2_0));
				P2OUT = pull ? (P2OUT | (1 << (pin - p2_0))) : (P2OUT & ~(1 << (pin - p2_0)));
				P2REN |= (1 << (pin - p2_0));
			} else if (pin < p4_0) {
				P3DIR &= ~(1 << (pin - p3_0));
				P3OUT = pull ? (P3OUT | (1 << (pin - p3_0))) : (P3OUT & ~(1 << (pin - p3_0)));
				P3REN |= (1 << (pin - p3_0));
			} else if (pin < pj_0) {
				P4DIR &= ~(1 << (pin - p4_0));
				P4OUT = pull ? (P4OUT | (1 << (pin - p4_0))) : (P4OUT & ~(1 << (pin - p4_0)));
				P4REN |= (1 << (pin - p4_0));
			} else if (pin < PIN_INVALID) {
				PJDIR &= ~(1 << (pin - pj_0));
				PJOUT = pull ? (PJOUT | (1 << (pin - pj_0))) : (PJOUT & ~(1 << (pin - pj_0)));
				PJREN |= (1 << (pin - pj_0));
			}
		}
		inline void output(unsigned char const pin) {
			if (pin < p2_0) {
				P1DIR |= (1 << pin);
@@ -76,6 +99,24 @@ class GPIO {
				PJDIR |= (1 << (pin - pj_0));
			}
		}
		inline void output(unsigned char const pin, unsigned char const value) {
			if (pin < p2_0) {
				P1OUT = value ? (P1OUT | (1 << pin)) : (P1OUT & ~(1 << pin));
				P1DIR |= (1 << pin);
			} else if (pin < p3_0) {
				P2OUT = value ? (P2OUT | (1 << (pin - p2_0))) : (P2OUT & ~(1 << (pin - p2_0)));
				P2DIR |= (1 << (pin - p2_0));
			} else if (pin < p4_0) {
				P3OUT = value ? (P3OUT | (1 << (pin - p3_0))) : (P3OUT & ~(1 << (pin - p3_0)));
				P3DIR |= (1 << (pin - p3_0));
			} else if (pin < pj_0) {
				P4OUT = value ? (P4OUT | (1 << (pin - p4_0))) : (P4OUT & ~(1 << (pin - p4_0)));
				P4DIR |= (1 << (pin - p4_0));
			} else if (pin < PIN_INVALID) {
				PJOUT = value ? (PJOUT | (1 << (pin - pj_0))) : (PJOUT & ~(1 << (pin - pj_0)));
				PJDIR |= (1 << (pin - pj_0));
			}
		}
		inline unsigned char read(unsigned char const pin) {
			if (pin < p2_0) {
				return P1IN & (1 << pin);
+7 −0
Original line number Diff line number Diff line
@@ -72,6 +72,13 @@ extern void loop();
volatile char run_loop = 0;
#endif

void Arch::delay_us(unsigned char const us)
{
	for (int i = 0; i < us/10; i++) {
		__delay_cycles(160);
	}
}

void Arch::idle_loop(void)
{
	while (1) {
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ signed char I2C::setup()
	UCB0CTL1 &= ~UCSWRST;
	UCB0I2CSA = 0;

	__delay_cycles(1600);
	arch.delay_us(100);

	if (UCB0STAT & UCBBUSY)
		return -1;
+32 −19
Original line number Diff line number Diff line
#include "driver/soft_i2c.h"
#include "driver/gpio.h"
#include "arch.h"

#ifdef SOFTI2C_PULLUP
#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
#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

signed char SoftI2C::setup()
{
	gpio.write(sda, 0);
	gpio.write(scl, 0);
	SDA_HIGH;
	SCL_HIGH;
	return 0;
}

void SoftI2C::start()
{
	gpio.input(sda);
	gpio.input(scl);
	SDA_HIGH;
	SCL_HIGH;
	//
	gpio.output(sda);
	SDA_LOW;
	//
	gpio.output(scl);
	SCL_LOW;
}

void SoftI2C::stop()
{
	gpio.output(scl);
	SCL_LOW;
	//
	gpio.output(sda);
	SDA_LOW;
	//
	gpio.input(scl);
	SCL_HIGH;
	//
	gpio.input(sda);
	SDA_HIGH;
}

bool SoftI2C::tx(unsigned char byte)
@@ -34,20 +47,20 @@ bool SoftI2C::tx(unsigned char byte)
	unsigned char got_ack = 0;
	for (unsigned char i = 0; i <= 8; i++) {
		if ((byte & 0x80) || (i == 8)) {
			gpio.input(sda);
			SDA_HIGH;
		} else {
			gpio.output(sda);
			SDA_LOW;
		}
		byte <<= 1;
		//
		gpio.input(scl);
		SCL_HIGH;
		//
		if (i == 8) {
			if (!gpio.read(sda)) {
				got_ack = 1;
			}
		}
		gpio.output(scl);
		SCL_LOW;
		//
	}
	return got_ack;
@@ -56,21 +69,21 @@ bool SoftI2C::tx(unsigned char byte)
unsigned char SoftI2C::rx(bool send_ack)
{
	unsigned char byte = 0;
	gpio.input(sda);
	SDA_HIGH;
	for (unsigned char i = 0; i <= 8; i++) {
		//
		gpio.input(scl);
		SCL_HIGH;
		//
		if ((i < 8) && gpio.read(sda)) {
			byte |= 1 << (7 - i);
		}
		//
		gpio.output(scl);
		SCL_LOW;
		//
		if ((i == 7) && send_ack) {
			gpio.output(sda);
			SDA_LOW;
		} else if ((i == 8) && send_ack) {
			gpio.input(sda);
			SDA_HIGH;
		}
	}
	return byte;