summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2017-12-14 15:51:11 +0100
committerDaniel Friesel <derf@finalrewind.org>2017-12-14 15:51:11 +0100
commit51a00f59ea9ecb49471b30921f36821fdfa75bc4 (patch)
tree4c237974cf044d5a7067aba48070ad7f6e3c7d11
parent693afffd7b89507916ecd759767b0b7e947dca60 (diff)
Add I2C and LM75 drivers
-rw-r--r--Makefile1
-rw-r--r--include/driver/lm75.h21
-rw-r--r--include/msp430fr5969lp/driver/i2c.h19
-rw-r--r--include/object/outputstream.h2
-rw-r--r--src/arch/msp430fr5969lp/Makefile.inc7
-rw-r--r--src/arch/msp430fr5969lp/driver/i2c.cc92
-rw-r--r--src/driver/lm75.cc30
-rw-r--r--src/os/object/outputstream.cc37
8 files changed, 206 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 0860731..47454ac 100644
--- a/Makefile
+++ b/Makefile
@@ -6,6 +6,7 @@ CFLAGS = -std=c99
CXXFLAGS = -std=c++14
TARGETS = src/app/${app}/main.cc src/os/object/cpp_helpers.cc src/os/object/outputstream.cc
+TARGETS += src/driver/lm75.cc
ifeq (${timer_cycles}, 1)
COMMON_FLAGS += -DTIMER_CYCLES
diff --git a/include/driver/lm75.h b/include/driver/lm75.h
new file mode 100644
index 0000000..e357574
--- /dev/null
+++ b/include/driver/lm75.h
@@ -0,0 +1,21 @@
+#ifndef LM75_H
+#define LM75_H
+
+class LM75 {
+ private:
+ LM75(const LM75 &copy);
+ unsigned char const address;
+ unsigned char txbuf[3];
+ unsigned char rxbuf[2];
+
+ public:
+ LM75(unsigned char const addr) : address(addr) {}
+
+ float getTemp();
+ void setOS(unsigned char os);
+ void setHyst(unsigned char hyst);
+};
+
+extern LM75 lm75;
+
+#endif
diff --git a/include/msp430fr5969lp/driver/i2c.h b/include/msp430fr5969lp/driver/i2c.h
new file mode 100644
index 0000000..6d6ea66
--- /dev/null
+++ b/include/msp430fr5969lp/driver/i2c.h
@@ -0,0 +1,19 @@
+#ifndef I2C_H
+#define I2C_H
+
+class I2C {
+ private:
+ I2C(const I2C &copy);
+
+ public:
+ I2C () {}
+ signed char setup();
+ void scan(unsigned int *results);
+ signed char xmit(unsigned char address,
+ unsigned char tx_len, unsigned char *tx_buf,
+ unsigned char rx_len, unsigned char *rx_buf);
+};
+
+extern I2C i2c;
+
+#endif
diff --git a/include/object/outputstream.h b/include/object/outputstream.h
index 43e61f3..4a37977 100644
--- a/include/object/outputstream.h
+++ b/include/object/outputstream.h
@@ -38,6 +38,8 @@ class OutputStream {
OutputStream & operator<<(OutputStream & (*fun) (OutputStream &));
void setBase(uint8_t b);
+ void printf_uint8(uint8_t num);
+ void printf_float(float num);
};
diff --git a/src/arch/msp430fr5969lp/Makefile.inc b/src/arch/msp430fr5969lp/Makefile.inc
index 36d19c6..6d2ae6a 100644
--- a/src/arch/msp430fr5969lp/Makefile.inc
+++ b/src/arch/msp430fr5969lp/Makefile.inc
@@ -10,8 +10,11 @@ CC = /opt/msp430/ti/gcc/bin/msp430-elf-gcc
CXX = /opt/msp430/ti/gcc/bin/msp430-elf-g++
OBJCOPY = /opt/msp430/ti/gcc/bin/msp430-elf-objcopy
-TARGETS += src/arch/msp430fr5969lp/arch.cc src/arch/msp430fr5969lp/driver/gpio.cc
-TARGETS += src/arch/msp430fr5969lp/driver/stdout.cc src/arch/msp430fr5969lp/driver/uptime.cc
+TARGETS += src/arch/msp430fr5969lp/arch.cc
+TARGETS += src/arch/msp430fr5969lp/driver/gpio.cc
+TARGETS += src/arch/msp430fr5969lp/driver/stdout.cc
+TARGETS += src/arch/msp430fr5969lp/driver/uptime.cc
+TARGETS += src/arch/msp430fr5969lp/driver/i2c.cc
OBJECTS = ${TARGETS:.cc=.o}
diff --git a/src/arch/msp430fr5969lp/driver/i2c.cc b/src/arch/msp430fr5969lp/driver/i2c.cc
new file mode 100644
index 0000000..80f33b0
--- /dev/null
+++ b/src/arch/msp430fr5969lp/driver/i2c.cc
@@ -0,0 +1,92 @@
+#include "driver/i2c.h"
+#include <msp430.h>
+
+signed char I2C::setup()
+{
+ UCB0CTL1 = UCSWRST;
+ UCB0CTLW0 = UCMODE_3 | UCMST | UCSYNC | UCSSEL_2 | UCSWRST | UCCLTO_1;
+ UCB0BRW = 0xf00;
+ P1DIR &= ~(BIT6 | BIT7);
+ P1SEL0 &= ~(BIT6 | BIT7);
+ P1SEL1 |= BIT6 | BIT7;
+
+ UCB0CTL1 &= ~UCSWRST;
+ UCB0I2CSA = 0;
+
+ __delay_cycles(1600);
+
+ if (UCB0STAT & UCBBUSY)
+ return -1;
+
+ return 0;
+}
+
+void I2C::scan(unsigned int *results)
+{
+ for (unsigned char address = 0; address < 128; address++) {
+ UCB0I2CSA = address;
+ UCB0CTL1 |= UCTR | UCTXSTT | UCTXSTP;
+
+ while (UCB0CTL1 & UCTXSTP);
+
+ if (UCB0IFG & UCNACKIFG) {
+ UCB0IFG &= ~UCNACKIFG;
+ } else {
+ results[address / (8 * sizeof(unsigned int))] |= 1 << (address % (8 * sizeof(unsigned int)));
+ }
+ }
+ UCB0IFG = 0;
+}
+
+signed char I2C::xmit(unsigned char address,
+ unsigned char tx_len, unsigned char *tx_buf,
+ unsigned char rx_len, unsigned char *rx_buf)
+{
+ unsigned char i;
+ UCB0I2CSA = address;
+ if (tx_len) {
+ UCB0CTL1 |= UCTR | UCTXSTT;
+ for (i = 0; i < tx_len; i++) {
+ while (!(UCB0IFG & (UCTXIFG0 | UCNACKIFG | UCCLTOIFG)));
+ if (UCB0IFG & (UCNACKIFG | UCCLTOIFG)) {
+ UCB0IFG &= ~UCNACKIFG;
+ UCB0IFG &= ~UCCLTOIFG;
+ UCB0CTL1 |= UCTXSTP;
+ return -1;
+ }
+ UCB0TXBUF = tx_buf[i];
+ }
+ while (!(UCB0IFG & (UCTXIFG0 | UCNACKIFG | UCCLTOIFG)));
+ //if (UCB0IFG & (UCNACKIFG | UCCLTOIFG)) {
+ // UCB0IFG &= ~UCNACKIFG;
+ // UCB0IFG &= ~UCCLTOIFG;
+ // UCB0CTL1 |= UCTXSTP;
+ // return -1;
+ //}
+ }
+ if (rx_len) {
+ UCB0I2CSA = address;
+ UCB0IFG = 0;
+ UCB0CTL1 &= ~UCTR;
+ UCB0CTL1 |= UCTXSTT;
+
+ while (UCB0CTL1 & UCTXSTT);
+ UCB0IFG &= ~UCTXIFG0;
+
+ for (i = 0; i < rx_len; i++) {
+ if (i == rx_len - 1)
+ UCB0CTL1 |= UCTXSTP;
+ while (!(UCB0IFG & (UCRXIFG0 | UCNACKIFG | UCCLTOIFG)));
+ rx_buf[i] = UCB0RXBUF;
+ UCB0IFG &= ~UCRXIFG0;
+ }
+ UCB0IFG &= ~UCRXIFG0;
+ }
+
+ UCB0CTL1 |= UCTXSTP;
+
+ while (UCB0CTL1 & UCTXSTP);
+ return 0;
+}
+
+I2C i2c;
diff --git a/src/driver/lm75.cc b/src/driver/lm75.cc
new file mode 100644
index 0000000..0bad4a7
--- /dev/null
+++ b/src/driver/lm75.cc
@@ -0,0 +1,30 @@
+#include "driver/lm75.h"
+#include "driver/i2c.h"
+
+float LM75::getTemp()
+{
+ txbuf[0] = 0;
+ rxbuf[0] = 0;
+ rxbuf[1] = 0;
+ i2c.xmit(address, 1, txbuf, 2, rxbuf);
+
+ return rxbuf[0] + (rxbuf[1] / 256.0);
+}
+
+void LM75::setOS(unsigned char os)
+{
+ txbuf[0] = 0x03;
+ txbuf[1] = os;
+ txbuf[2] = 0;
+ i2c.xmit(address, 3, txbuf, 0, rxbuf);
+}
+
+void LM75::setHyst(unsigned char hyst)
+{
+ txbuf[0] = 0x02;
+ txbuf[1] = hyst;
+ txbuf[2] = 0;
+ i2c.xmit(address, 3, txbuf, 0, rxbuf);
+}
+
+LM75 lm75(0x48);
diff --git a/src/os/object/outputstream.cc b/src/os/object/outputstream.cc
index f308b56..31b0da4 100644
--- a/src/os/object/outputstream.cc
+++ b/src/os/object/outputstream.cc
@@ -2,7 +2,7 @@
OutputStream & OutputStream::operator<<(unsigned char c)
{
- put(c);
+ *this << (unsigned long long)c;
return *this;
}
@@ -134,6 +134,41 @@ void OutputStream::setBase(uint8_t b)
}
}
+static inline char format_hex_nibble(uint8_t num)
+{
+ if (num > 9) {
+ return 'a' + num - 10;
+ }
+ return '0' + num;
+}
+
+void OutputStream::printf_uint8(uint8_t num)
+{
+ put(format_hex_nibble(num / 16));
+ put(format_hex_nibble(num % 16));
+}
+
+void OutputStream::printf_float(float num)
+{
+ if (num < 0) {
+ put('-');
+ num *= -1;
+ }
+ if (num > 1000) {
+ put('0' + (((int)num % 10000) / 1000));
+ }
+ if (num > 100) {
+ put('0' + (((int)num % 1000) / 100));
+ }
+ if (num > 10) {
+ put('0' + (((int)num % 100) / 10));
+ }
+ put('0' + ((int)num % 10));
+ put('.');
+ put('0' + ((int)(num * 10) % 10));
+ put('0' + ((int)(num * 100) % 10));
+}
+
// FLUSH
OutputStream & flush(OutputStream & os)
{