Mercurial > templog
changeset 111:cdb26addf4f2 tilt
Add bma180 code, untested
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 19 Sep 2012 22:40:49 +0800 |
parents | 5c8404549cc0 |
children | 5234ccc416e8 |
files | Makefile bma180.c bma180.h bma180_internal.h |
diffstat | 4 files changed, 212 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Fri Sep 07 22:59:26 2012 +0800 +++ b/Makefile Wed Sep 19 22:40:49 2012 +0800 @@ -22,7 +22,7 @@ CLOCK = 2000000 PROGRAMMER = #-c stk500v2 -P avrdoper PROGRAMMER = -c stk500 -P ~/dev/stk500 -p $(PROGDEVICE) -B 2 -SOURCE_1WIRE = onewire.c simple_ds18b20.c crc8.c +SOURCE_1WIRE = onewire.c simple_ds18b20.c crc8.c bma180.c SOURCE = main.c SOURCE += $(SOURCE_1WIRE) LIBS = -lm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bma180.c Wed Sep 19 22:40:49 2012 +0800 @@ -0,0 +1,146 @@ +#include <avr/io.h> +#include <util/delay.h> + +#include "bma180.h" +#include "bma180_internal.h" + +static void +bma180_init_SPI(void) +{ + //make SPI master + //SCL idle high, sample data on rising edge + //Fosc/4 is SPI frequency + //enable SPI + SPCR = _BV(MSTR) | _BV(SPE) | _BV(CPHA) | _BV(CPOL); +} + +static char +bma180_rxdata(void) +{ + //while((SPSR&0x80) == 0x80); + SPDR = 0x55; + while((SPSR&0x80) == 0x00); + + return SPDR; +} + +static void +bma180_txdata(char data) +{ + //while((SPSR&0x80) == 0x80); + SPDR = data; + while((SPSR&0x80) == 0x00); +} + +static void +bma180_write(uint8_t address, char data) +{ + //write any data byte to any single address + //adds a 0 to the MSB of the address byte (WRITE mode) + + address &= 0x7F; + + //printf("\nWriting 0x%x to 0x%x\n", data, address); + + BMA180_CS_PORT &= ~_BV(BMA180_CS_PIN); + _delay_ms(1); + bma180_txdata(address); + _delay_ms(1); + bma180_txdata(data); + _delay_ms(1); + BMA180_CS_PORT |= _BV(BMA180_CS_PIN); +} + +static char +bma180_read(uint8_t address) +{ + //returns the contents of any 1 byte register from any address + //sets the MSB for every address byte (READ mode) + + char byte; + + address |= 0x80; + + BMA180_CS_PORT &= ~_BV(BMA180_CS_PIN); + bma180_txdata(address); + byte = bma180_rxdata(); + BMA180_CS_PORT |= _BV(BMA180_CS_PIN); + + return byte; +} + +static int +bma180_set_config(uint8_t range, uint8_t bw) +{ + char temp, temp1; + + // if connected correctly, ID register should be 3 + if(bma180_read(ID) != 3) + return -1; + + + // Set ee_w bit + temp = bma180_read(CTRLREG0); + temp |= 0x10; + bma180_write(CTRLREG0, temp); // Have to set ee_w to write any other registers + + // Set BW + temp = bma180_read(BWTCS); + temp1 = bw; + temp1 = temp1<<4; + temp &= (~BWMASK); + temp |= temp1; + bma180_write(BWTCS, temp); // Keep tcs<3:0> in BWTCS, but write new BW + + // Set Range + temp = bma180_read(OLSB1); + temp1 = range; + temp1 = (temp1<<RANGESHIFT); + temp &= (~RANGEMASK); + temp |= temp1; + bma180_write(OLSB1, temp); //Write new range data, keep other bits the same + + return 0; +} + +void +bma180_init(uint8_t range, uint8_t bw) +{ + bma180_init_SPI(); + + // CS output + // XXX checkme, sample code has the opposite? + BMA180_CS_DDR |= _BV(BMA180_CS_PIN); + + bma180_set_config(range, bw); + +} + +static uint16_t +bma_get_reading_n(uint8_t reg_lsb, uint8_t reg_msb) +{ + uint16_t ret; + uint8_t val = 0; + while (val != 1) + { + val = bma180_read(reg_lsb) & 0x01; + } + val = bma180_read(reg_msb); + ret = val << 8; + + val = bma180_read(reg_lsb); + ret |= val; + // low bits aren't the reading + ret >>= 2; + return ret; +} + +void +bma180_get_reading(uint16_t *x, uint16_t *y, uint16_t *z, uint8_t *temperature) +{ + *x = bma_get_reading_n(ACCXLSB, ACCXMSB); + *y = bma_get_reading_n(ACCYLSB, ACCYMSB); + *z = bma_get_reading_n(ACCZLSB, ACCZMSB); + + *temperature = bma180_read(TEMPERATURE); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bma180.h Wed Sep 19 22:40:49 2012 +0800 @@ -0,0 +1,14 @@ +#ifndef BMA180_H_ +#define BMA180_H_ + +#include <stdint.h> + +// hardware config +#define BMA180_CS_PORT PORTB +#define BMA180_CS_DDR DDRB +#define BMA180_CS_PIN 1 + +void bma180_get_reading(uint16_t *x, uint16_t *y, uint16_t *z, uint8_t *temperature); +void bma180_init(uint8_t range, uint8_t bw); + +#endif /* BMA180_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bma180_internal.h Wed Sep 19 22:40:49 2012 +0800 @@ -0,0 +1,51 @@ +/* + * Copied from Sparkfun example code: + * + * bma180.h + * Created on: Mar 19, 2010 + */ + +#ifndef BMA180_INTERNAL_H_ +#define BMA180_INTERNAL_H_ + +//Address defines for BMA180// +//====================// +//ID and Version Registers +#define ID 0x00 +#define Version 0x01 +#define ACCXLSB 0x02 +#define ACCXMSB 0x03 +#define ACCYLSB 0x04 +#define ACCYMSB 0x05 +#define ACCZLSB 0x06 +#define ACCZMSB 0x07 +#define TEMPERATURE 0x08 +#define STATREG1 0x09 +#define STATREG2 0x0A +#define STATREG3 0x0B +#define STATREG4 0x0C +#define CTRLREG0 0x0D +#define CTRLREG1 0x0E +#define CTRLREG2 0x0F + +#define BWTCS 0x20 +#define CTRLREG3 0x21 + +#define HILOWNFO 0x25 +#define LOWDUR 0x26 + +#define LOWTH 0x29 + +#define tco_y 0x2F +#define tco_z 0x30 + +#define OLSB1 0x35 + +//====================// +//Range setting +#define RANGESHIFT 1 +#define RANGEMASK 0x0E +#define BWMASK 0xF0 +#define BWSHIFT 4 + +#endif /* BMA180_INTERNAL_H_ */