aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2014-03-31 11:18:32 +0200
committerLars-Dominik Braun <lars@6xq.net>2014-04-22 16:51:13 +0200
commite3897565c342bee4765f921240b7ca91cd9b23f1 (patch)
treee7e328ee9452d54db9cfe66cccdb031cb704030f
parent24d11d4976062e965fb64861808548c39f53714b (diff)
downloadhourglass-e3897565c342bee4765f921240b7ca91cd9b23f1.tar.gz
hourglass-e3897565c342bee4765f921240b7ca91cd9b23f1.tar.bz2
hourglass-e3897565c342bee4765f921240b7ca91cd9b23f1.zip
Activate accel + timer
-rw-r--r--accel.c27
-rw-r--r--accel.h5
-rw-r--r--gyro.c4
-rw-r--r--i2c.c24
-rw-r--r--i2c.h2
-rw-r--r--main.c32
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 <stdbool.h>
+#include <stdint.h>
+
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 ();