Skip to content
Snippets Groups Projects
Commit 51a00f59 authored by Birte Kristina Friesel's avatar Birte Kristina Friesel
Browse files

Add I2C and LM75 drivers

parent 693afffd
No related branches found
No related tags found
No related merge requests found
...@@ -6,6 +6,7 @@ CFLAGS = -std=c99 ...@@ -6,6 +6,7 @@ CFLAGS = -std=c99
CXXFLAGS = -std=c++14 CXXFLAGS = -std=c++14
TARGETS = src/app/${app}/main.cc src/os/object/cpp_helpers.cc src/os/object/outputstream.cc 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) ifeq (${timer_cycles}, 1)
COMMON_FLAGS += -DTIMER_CYCLES COMMON_FLAGS += -DTIMER_CYCLES
......
#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
#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
...@@ -38,6 +38,8 @@ class OutputStream { ...@@ -38,6 +38,8 @@ class OutputStream {
OutputStream & operator<<(OutputStream & (*fun) (OutputStream &)); OutputStream & operator<<(OutputStream & (*fun) (OutputStream &));
void setBase(uint8_t b); void setBase(uint8_t b);
void printf_uint8(uint8_t num);
void printf_float(float num);
}; };
......
...@@ -10,8 +10,11 @@ CC = /opt/msp430/ti/gcc/bin/msp430-elf-gcc ...@@ -10,8 +10,11 @@ CC = /opt/msp430/ti/gcc/bin/msp430-elf-gcc
CXX = /opt/msp430/ti/gcc/bin/msp430-elf-g++ CXX = /opt/msp430/ti/gcc/bin/msp430-elf-g++
OBJCOPY = /opt/msp430/ti/gcc/bin/msp430-elf-objcopy 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/arch.cc
TARGETS += src/arch/msp430fr5969lp/driver/stdout.cc src/arch/msp430fr5969lp/driver/uptime.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} OBJECTS = ${TARGETS:.cc=.o}
......
#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;
#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);
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
OutputStream & OutputStream::operator<<(unsigned char c) OutputStream & OutputStream::operator<<(unsigned char c)
{ {
put(c); *this << (unsigned long long)c;
return *this; return *this;
} }
...@@ -134,6 +134,41 @@ void OutputStream::setBase(uint8_t b) ...@@ -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 // FLUSH
OutputStream & flush(OutputStream & os) OutputStream & flush(OutputStream & os)
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment