From e69b2bc45ff0940b475a1832d25e051240fbda32 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 10 Mar 2014 17:28:07 +0100 Subject: Initial accel implementation --- Makefile | 2 +- accel.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ accel.h | 8 ++++++ gyro.c | 8 +++--- i2c.h | 5 ---- 5 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 accel.c create mode 100644 accel.h diff --git a/Makefile b/Makefile index 9f3ae5c..3e37a57 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ MCU = atmega88 all: sanduhr.hex -sanduhr.elf: main.c i2c.c i2c.h uart.c uart.h timer.c timer.h gyro.c gyro.h +sanduhr.elf: main.c i2c.c i2c.h uart.c uart.h timer.c timer.h gyro.c gyro.h accel.c accel.h avr-gcc -std=gnu99 -mmcu=$(MCU) -Os -o $@ $^ sanduhr.hex: sanduhr.elf diff --git a/accel.c b/accel.c new file mode 100644 index 0000000..dc408a3 --- /dev/null +++ b/accel.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include + +#include "i2c.h" +#include "accel.h" + +/* device address */ +#define LIS302DL 0b00111000 +/* registers */ +#define LIS302DL_WHOAMI 0xf +#define LIS302DL_CTRLREG1 0x20 +#define LIS302DL_UNUSED1 0x28 + +#define sleepwhile(cond) \ + sleep_enable (); \ + while (cond) { sleep_cpu (); } \ + sleep_disable (); + +/* the first interrupt is lost */ +static volatile bool drdy = true; +/* 0, 2 and 4 are zero, as they contain the dummy register’s content */ +static volatile int8_t val[6] = {0, 0, 0, 0, 0, 0}; +/* currently reading from i2c */ +static bool reading = false; + +#warning "wrong interrupt" +/* data ready interrupt + */ +ISR(PCINT1_vect) { + drdy = true; +} + +void accelInit () { + /* set PB1 to input, with pull-up */ + //DDRB = (DDRB & ~((1 << PB1))); + //PORTB = (PORTB | (1 << PB1)); + /* enable interrupt PCI0 */ + //PCICR = (1 << PCIE0); + /* enable interrupts on PB1/PCINT1 */ + //PCMSK0 = (1 << 1); +} + +/* XXX: make nonblocking */ +void accelStart () { + /* configuration: + * disable power-down-mode + * defaults + * data ready interrupt on int2 + */ + uint8_t data[] = {0b01000111, 0b0, 0b00100000}; + + if (!twRequest (TWM_WRITE, LIS302DL, LIS302DL_CTRLREG1, data, + sizeof (data)/sizeof (*data))) { + printf ("cannot start write\n"); + } + sleepwhile (twr.status == TWST_WAIT); + printf ("final twi status was %i\n", twr.status); +} + +bool accelProcess () { + if (reading) { + if (twr.status == TWST_OK) { + /* new data transfered */ + reading = false; + return true; + } else if (twr.status == TWST_ERR) { + printf ("accel i2c error\n"); + reading = false; + } + } else { + if (drdy && twr.status != TWST_WAIT) { + /* new data available in device buffer and bus is free, we are + * reading the registers inbetween out_x/y/z and ignore them */ + if (!twRequest (TWM_READ, LIS302DL, LIS302DL_UNUSED1, (uint8_t *) val, 6)) { + printf ("cannot start read\n"); + } else { + drdy = false; + reading = true; + } + } + } + + return false; +} + diff --git a/accel.h b/accel.h new file mode 100644 index 0000000..e027946 --- /dev/null +++ b/accel.h @@ -0,0 +1,8 @@ +#ifndef ACCEL_H +#define ACCEL_H + +void accelInit (); +void accelStart (); + +#endif /* ACCEL_H */ + diff --git a/gyro.c b/gyro.c index a373d29..d6a8b48 100644 --- a/gyro.c +++ b/gyro.c @@ -33,12 +33,12 @@ sleep_disable (); /* the first interrupt is lost */ -volatile bool drdy = true; -volatile int16_t val[3] = {0, 0, 0}; +static volatile bool drdy = true; +static volatile int16_t val[3] = {0, 0, 0}; /* current (relative) angle, in millidegree */ -int16_t angle[3] = {0, 0, 0}; +static int16_t angle[3] = {0, 0, 0}; /* currently reading from i2c */ -bool reading = false; +static bool reading = false; /* data ready interrupt */ diff --git a/i2c.h b/i2c.h index eb68d8b..c02e8ad 100644 --- a/i2c.h +++ b/i2c.h @@ -31,11 +31,6 @@ typedef struct { extern volatile twReq twr; -/* i2c device addresses */ -#define LIS302DL 0b00111000 -#define LIS302DL_WHOAMI 0xf -#define LIS302DL_CTRLREG1 0x20 - #include void twInit (); -- cgit v1.2.3