From e3897565c342bee4765f921240b7ca91cd9b23f1 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Mon, 31 Mar 2014 11:18:32 +0200 Subject: Activate accel + timer --- accel.c | 27 +++++++++++++++------------ accel.h | 5 +++++ gyro.c | 4 ++-- i2c.c | 24 ++++++++++++++++-------- i2c.h | 2 ++ main.c | 32 ++++++++++++++++++++++++-------- 6 files changed, 64 insertions(+), 30 deletions(-) diff --git a/accel.c b/accel.c index a178fa3..670121e 100644 --- a/accel.c +++ b/accel.c @@ -23,7 +23,6 @@ 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) { @@ -31,13 +30,13 @@ ISR(PCINT1_vect) { } 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); + /* set interrupt lines to input with pull-up */ + DDRC = DDRC & ~((1 << PC0) | (1 << PC1)); + PORTC = PORTC | (1 << PC0) | (1 << PC1); + /* enable interrupt PCI1 for PCINT8/9 */ + PCICR = PCICR | (1 << PCIE1); + /* enable interrupts from port PC0/PC1 aka PCINT8/PCINT9 */ + PCMSK1 = (1 << PCINT9) | (1 << PCINT8); } /* XXX: make nonblocking */ @@ -45,9 +44,9 @@ void accelStart () { /* configuration: * disable power-down-mode * defaults - * data ready interrupt on int2 + * low active, data ready interrupt on int2 */ - uint8_t data[] = {0b01000111, 0b0, 0b00100000}; + uint8_t data[] = {0b01000111, 0b0, 0b10100000}; if (!twRequest (TWM_WRITE, LIS302DL, LIS302DL_CTRLREG1, data, sizeof (data)/sizeof (*data))) { @@ -64,11 +63,11 @@ bool accelProcess () { reading = false; return true; } else if (twr.status == TWST_ERR) { - printf ("accel i2c error\n"); + printf ("accel i2c error %x at step %i\n", twr.error, twr.step); reading = false; } } else { - if (drdy && twr.status != TWST_WAIT) { + 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)) { @@ -83,3 +82,7 @@ bool accelProcess () { return false; } +volatile const int8_t *accelGet () { + return val; +} + diff --git a/accel.h b/accel.h index e027946..7d82933 100644 --- a/accel.h +++ b/accel.h @@ -1,8 +1,13 @@ #ifndef ACCEL_H #define ACCEL_H +#include +#include + void accelInit (); void accelStart (); +bool accelProcess (); +volatile const int8_t *accelGet (); #endif /* ACCEL_H */ diff --git a/gyro.c b/gyro.c index bbcb0fe..eede345 100644 --- a/gyro.c +++ b/gyro.c @@ -48,9 +48,9 @@ void gyroInit () { DDRB = (DDRB & ~((1 << PB1))); PORTB = (PORTB | (1 << PB1)); /* enable interrupt PCI0 */ - PCICR = (1 << PCIE0); + PCICR = PCICR | (1 << PCIE0); /* enable interrupts on PB1/PCINT1 */ - PCMSK0 = (1 << 1); + PCMSK0 = (1 << PCINT1); } /* XXX: make nonblocking */ diff --git a/i2c.c b/i2c.c index ef2392e..57ee551 100644 --- a/i2c.c +++ b/i2c.c @@ -68,7 +68,7 @@ bool twRequest (const twMode mode, const uint8_t address, twr.step = 0; twr.status = TWST_WAIT; /* wait for stop finish; there is no interrupt generated for this */ - while (TW_STATUS != 0xf8); + while (TW_STATUS != 0xf8 || TWCR & (1 << TWSTO)); twStartRaw (); return true; @@ -130,62 +130,68 @@ static void twIntWrite () { /* handle interrupt, read request */ static void twIntRead () { + uint8_t status = TW_STATUS; switch (twr.step) { case 0: - if (TW_STATUS == TW_START) { + if (status == TW_START) { /* write device address */ twWriteRaw (twr.address | TW_WRITE); twFlushRaw (); ++twr.step; } else { twr.status = TWST_ERR; + twr.error = status; } break; case 1: - if (TW_STATUS == TW_MT_SLA_ACK) { + if (status == TW_MT_SLA_ACK) { /* write subaddress, enable auto-increment */ twWriteRaw ((1 << 7) | twr.subaddress); twFlushRaw (); ++twr.step; } else { twr.status = TWST_ERR; + twr.error = status; } break; case 2: - if (TW_STATUS == TW_MT_DATA_ACK) { + if (status == TW_MT_DATA_ACK) { /* send repeated start */ twStartRaw (); ++twr.step; } else { twr.status = TWST_ERR; + twr.error = status; } break; case 3: - if (TW_STATUS == TW_REP_START) { + if (status == TW_REP_START) { /* now start the actual read request */ twWriteRaw (twr.address | TW_READ); twFlushRaw (); ++twr.step; } else { twr.status = TWST_ERR; + twr.error = status; } break; case 4: - if (TW_STATUS == TW_MR_SLA_ACK) { + if (status == TW_MR_SLA_ACK) { /* send master ack if next data block is received */ twFlushContRaw (); ++twr.step; } else { twr.status = TWST_ERR; + twr.error = status; } break; case 5: - if (TW_STATUS == TW_MR_DATA_ACK) { + if (status == TW_MR_DATA_ACK) { twr.data[twr.i] = TWDR; ++twr.i; if (twr.i < twr.count-1) { @@ -199,17 +205,19 @@ static void twIntRead () { } } else { twr.status = TWST_ERR; + twr.error = status; } break; case 6: - if (TW_STATUS == TW_MR_DATA_NACK) { + if (status == TW_MR_DATA_NACK) { /* receive final byte, send stop */ twr.data[twr.i] = TWDR; twStopRaw (); twr.status = TWST_OK; } else { twr.status = TWST_ERR; + twr.error = status; } break; diff --git a/i2c.h b/i2c.h index c02e8ad..ec7fd87 100644 --- a/i2c.h +++ b/i2c.h @@ -27,6 +27,8 @@ typedef struct { /* current byte */ uint8_t i; twStatus status; + /* i2c bus status at the time if an error occured */ + uint8_t error; } twReq; extern volatile twReq twr; diff --git a/main.c b/main.c index aadd91e..372c070 100644 --- a/main.c +++ b/main.c @@ -11,6 +11,7 @@ #include "uart.h" #include "timer.h" #include "gyro.h" +#include "accel.h" static void ledInit () { /* set led1,led2 to output */ @@ -38,6 +39,7 @@ int main () { twInit (); uartInit (); gyroInit (); + accelInit (); set_sleep_mode (SLEEP_MODE_IDLE); printf ("initialization done\n"); @@ -45,18 +47,32 @@ int main () { /* global interrupt enable */ sei (); gyroStart (); + accelStart (); - //timerStart (); + timerStart (); + bool checkGyro = false; while (1) { - //sleepwhile (!timerHit ()); - //printf ("running for %u seconds\n", seconds); - - sleepwhile (!gyroProcess()); - volatile const int16_t *val = gyroGetAngle (); - printf ("%i/%i/%i\n", val[0], val[1], val[2]); + while (!timerHit ()) { + /* round-robin to prevent starvation */ + if (checkGyro) { + gyroProcess (); + accelProcess(); + } else { + accelProcess(); + gyroProcess (); + } + checkGyro = !checkGyro; + sleep_enable (); + sleep_cpu (); + sleep_disable (); + } + volatile const int16_t *gyroval = gyroGetAngle (); + volatile const int8_t *accelval = accelGet (); + printf ("%i/%i/%i - %i/%i/%i\n", gyroval[0], gyroval[1], gyroval[2], + accelval[1], accelval[3], accelval[5]); gyroResetAngle (); } - //timerStop (); + timerStop (); /* global interrupt disable */ cli (); -- cgit v1.2.3