diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | gyroscope.c | 84 | ||||
| -rw-r--r-- | gyroscope.h | 13 | ||||
| -rw-r--r-- | i2c.h | 3 | ||||
| -rw-r--r-- | main.c | 34 | ||||
| -rw-r--r-- | timer.c | 2 | 
6 files changed, 114 insertions, 24 deletions
@@ -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 */ + @@ -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 @@ -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 (); @@ -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 */  | 
