aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--gyroscope.c84
-rw-r--r--gyroscope.h13
-rw-r--r--i2c.h3
-rw-r--r--main.c34
-rw-r--r--timer.c2
6 files changed, 114 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index ab206ef..b273b86 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
+sanduhr.elf: main.c i2c.c i2c.h uart.c uart.h timer.c timer.h gyroscope.c gyroscope.h
avr-gcc -std=gnu99 -mmcu=$(MCU) -Os -o $@ $^
sanduhr.hex: sanduhr.elf
diff --git a/gyroscope.c b/gyroscope.c
new file mode 100644
index 0000000..0f932c2
--- /dev/null
+++ b/gyroscope.c
@@ -0,0 +1,84 @@
+#include <stdio.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/sleep.h>
+
+#include "i2c.h"
+#include "gyroscope.h"
+
+/* device address */
+#define L3GD20 0b11010100
+/* registers */
+#define L3GD20_WHOAMI 0xf
+#define L3GD20_CTRLREG1 0x20
+#define L3GD20_CTRLREG3 0x22
+#define L3GD20_CTRLREG4 0x23
+
+#define sleepwhile(cond) \
+ sleep_enable (); \
+ while (cond) { sleep_cpu (); } \
+ sleep_disable ();
+
+/* the first interrupt is lost */
+volatile bool drdy = true;
+volatile int16_t val[3] = {0, 0, 0};
+
+/* data ready interrupt
+ */
+ISR(PCINT0_vect) {
+ drdy = true;
+}
+
+void gyroscopeInit () {
+ /* 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 gyroscopeStart () {
+ /* XXX: implement multi-write */
+ /* disable power-down-mode */
+ if (!twWrite (L3GD20, L3GD20_CTRLREG1, 0b00001111)) {
+ printf ("cannot start write\n");
+ }
+ sleepwhile (twr.status == TWST_WAIT);
+ printf ("final twi status was %i\n", twr.status);
+
+ /* enable drdy interrupt */
+ if (!twWrite (L3GD20, L3GD20_CTRLREG3, 0b00001000)) {
+ printf ("cannot start write\n");
+ }
+ sleepwhile (twr.status == TWST_WAIT);
+ printf ("final twi status was %i\n", twr.status);
+
+ /* select 500dps */
+ if (!twWrite (L3GD20, L3GD20_CTRLREG4, 0b00010000)) {
+ printf ("cannot start write\n");
+ }
+ sleepwhile (twr.status == TWST_WAIT);
+ printf ("final twi status was %i\n", twr.status);
+}
+
+bool gyroscopeRead () {
+ if (drdy) {
+ drdy = false;
+
+ if (!twReadMulti (L3GD20, 0x28, (uint8_t *) val, 6)) {
+ printf ("cannot start read\n");
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+volatile const int16_t *gyroscopeGet () {
+ return val;
+}
+
diff --git a/gyroscope.h b/gyroscope.h
new file mode 100644
index 0000000..20ef373
--- /dev/null
+++ b/gyroscope.h
@@ -0,0 +1,13 @@
+#ifndef GYROSCOPE_H
+#define GYROSCOPE_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+void gyroscopeInit ();
+void gyroscopeStart ();
+bool gyroscopeRead ();
+volatile const int16_t *gyroscopeGet ();
+
+#endif /* GYROSCOPE_H */
+
diff --git a/i2c.h b/i2c.h
index 1381663..abcf5f3 100644
--- a/i2c.h
+++ b/i2c.h
@@ -33,9 +33,6 @@ typedef struct {
extern volatile twReq twr;
/* i2c device addresses */
-#define L3GD20 0b11010100
-#define L3GD20_WHOAMI 0xf
-#define L3GD20_CTRLREG1 0x20
#define LIS302DL 0b00111000
#define LIS302DL_WHOAMI 0xf
#define LIS302DL_CTRLREG1 0x20
diff --git a/main.c b/main.c
index 4a65c84..fa3b3c1 100644
--- a/main.c
+++ b/main.c
@@ -11,6 +11,7 @@
#include "i2c.h"
#include "uart.h"
#include "timer.h"
+#include "gyroscope.h"
static void ledInit () {
/* set led1,led2 to output */
@@ -42,36 +43,29 @@ int main () {
ledInit ();
twInit ();
uartInit ();
+ gyroscopeInit ();
set_sleep_mode (SLEEP_MODE_IDLE);
-
+
printf ("initialization done\n");
/* global interrupt enable */
sei ();
- /* disable power-down-mode */
- if (!twWrite (LIS302DL, LIS302DL_CTRLREG1, 0b01000111)) {
- printf ("cannot start write\n");
- }
- sleepwhile (twr.status == TWST_WAIT);
- printf ("final twi status was %i\n", twr.status);
+ gyroscopeStart ();
- timerStart ();
- unsigned char seconds = 0;
+ //timerStart ();
while (1) {
- uint8_t val[6];
-
- sleepwhile (!timerHit ());
- ++seconds;
- printf ("running for %u seconds\n", seconds);
+ //sleepwhile (!timerHit ());
+ //printf ("running for %u seconds\n", seconds);
- if (!twReadMulti (LIS302DL, 0x28, val, 6)) {
- printf ("cannot start read\n");
- }
+ sleepwhile (!gyroscopeRead ());
sleepwhile (twr.status == TWST_WAIT);
- printf ("%i/%i/%i\n", (int8_t) val[1], (int8_t) val[3],
- (int8_t) val[5]);
+
+ volatile const int16_t *val = gyroscopeGet ();
+ printf ("%i/%i/%i\n", val[0], val[1], val[2]);
+
+ _delay_ms (50);
}
- timerStop ();
+ //timerStop ();
/* global interrupt disable */
cli ();
diff --git a/timer.c b/timer.c
index 5830b38..c78ebda 100644
--- a/timer.c
+++ b/timer.c
@@ -6,6 +6,8 @@
volatile unsigned char count = 0;
volatile unsigned char hit = 0;
+/* XXX: use high-res timer1 for doing this
+ */
ISR(TIMER0_OVF_vect) {
/* there seems to be no mode of operation which disconnects pin OC0A _and_
* clears the value */