Mercurial > templog
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 } |