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_ */