comparison bma180.c @ 111:cdb26addf4f2 tilt

Add bma180 code, untested
author Matt Johnston <matt@ucc.asn.au>
date Wed, 19 Sep 2012 22:40:49 +0800
parents
children 5234ccc416e8
comparison
equal deleted inserted replaced
106:5c8404549cc0 111:cdb26addf4f2
1 #include <avr/io.h>
2 #include <util/delay.h>
3
4 #include "bma180.h"
5 #include "bma180_internal.h"
6
7 static void
8 bma180_init_SPI(void)
9 {
10 //make SPI master
11 //SCL idle high, sample data on rising edge
12 //Fosc/4 is SPI frequency
13 //enable SPI
14 SPCR = _BV(MSTR) | _BV(SPE) | _BV(CPHA) | _BV(CPOL);
15 }
16
17 static char
18 bma180_rxdata(void)
19 {
20 //while((SPSR&0x80) == 0x80);
21 SPDR = 0x55;
22 while((SPSR&0x80) == 0x00);
23
24 return SPDR;
25 }
26
27 static void
28 bma180_txdata(char data)
29 {
30 //while((SPSR&0x80) == 0x80);
31 SPDR = data;
32 while((SPSR&0x80) == 0x00);
33 }
34
35 static void
36 bma180_write(uint8_t address, char data)
37 {
38 //write any data byte to any single address
39 //adds a 0 to the MSB of the address byte (WRITE mode)
40
41 address &= 0x7F;
42
43 //printf("\nWriting 0x%x to 0x%x\n", data, address);
44
45 BMA180_CS_PORT &= ~_BV(BMA180_CS_PIN);
46 _delay_ms(1);
47 bma180_txdata(address);
48 _delay_ms(1);
49 bma180_txdata(data);
50 _delay_ms(1);
51 BMA180_CS_PORT |= _BV(BMA180_CS_PIN);
52 }
53
54 static char
55 bma180_read(uint8_t address)
56 {
57 //returns the contents of any 1 byte register from any address
58 //sets the MSB for every address byte (READ mode)
59
60 char byte;
61
62 address |= 0x80;
63
64 BMA180_CS_PORT &= ~_BV(BMA180_CS_PIN);
65 bma180_txdata(address);
66 byte = bma180_rxdata();
67 BMA180_CS_PORT |= _BV(BMA180_CS_PIN);
68
69 return byte;
70 }
71
72 static int
73 bma180_set_config(uint8_t range, uint8_t bw)
74 {
75 char temp, temp1;
76
77 // if connected correctly, ID register should be 3
78 if(bma180_read(ID) != 3)
79 return -1;
80
81
82 // Set ee_w bit
83 temp = bma180_read(CTRLREG0);
84 temp |= 0x10;
85 bma180_write(CTRLREG0, temp); // Have to set ee_w to write any other registers
86
87 // Set BW
88 temp = bma180_read(BWTCS);
89 temp1 = bw;
90 temp1 = temp1<<4;
91 temp &= (~BWMASK);
92 temp |= temp1;
93 bma180_write(BWTCS, temp); // Keep tcs<3:0> in BWTCS, but write new BW
94
95 // Set Range
96 temp = bma180_read(OLSB1);
97 temp1 = range;
98 temp1 = (temp1<<RANGESHIFT);
99 temp &= (~RANGEMASK);
100 temp |= temp1;
101 bma180_write(OLSB1, temp); //Write new range data, keep other bits the same
102
103 return 0;
104 }
105
106 void
107 bma180_init(uint8_t range, uint8_t bw)
108 {
109 bma180_init_SPI();
110
111 // CS output
112 // XXX checkme, sample code has the opposite?
113 BMA180_CS_DDR |= _BV(BMA180_CS_PIN);
114
115 bma180_set_config(range, bw);
116
117 }
118
119 static uint16_t
120 bma_get_reading_n(uint8_t reg_lsb, uint8_t reg_msb)
121 {
122 uint16_t ret;
123 uint8_t val = 0;
124 while (val != 1)
125 {
126 val = bma180_read(reg_lsb) & 0x01;
127 }
128 val = bma180_read(reg_msb);
129 ret = val << 8;
130
131 val = bma180_read(reg_lsb);
132 ret |= val;
133 // low bits aren't the reading
134 ret >>= 2;
135 return ret;
136 }
137
138 void
139 bma180_get_reading(uint16_t *x, uint16_t *y, uint16_t *z, uint8_t *temperature)
140 {
141 *x = bma_get_reading_n(ACCXLSB, ACCXMSB);
142 *y = bma_get_reading_n(ACCYLSB, ACCYMSB);
143 *z = bma_get_reading_n(ACCZLSB, ACCZMSB);
144
145 *temperature = bma180_read(TEMPERATURE);
146 }