Contiki-Inga 3.x
l3g4200d.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, TU Braunschweig.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /**
31  * \file
32  * ST L3G4200D 3-axis Gyroscope interface implementation
33  * \author
34  * Ulf Kulau <kulau@ibr.cs.tu-bs.de>
35  * Enrico Jörns <e.joerns@tu-bs.de>
36  *
37  */
38 
39 /**
40  * \addtogroup l3g4200d_interface
41  * @{
42  */
43 
44 #include "l3g4200d.h"
45 
46 #define L3G4200D_DPSDIV_250G 35
47 #define L3G4200D_DPSDIV_500G 70
48 #define L3G4200D_DPSDIV_2000G 280
49 
50 uint16_t l3g4200d_dps_scale;
51 
52 #define TEMP_OFFSET 0
53 // converts raw value to tempeartue, offset might need to be adjusted
54 #define raw_to_temp(a) (25 - TEMP_OFFSET - ((int8_t) a))
55 //*----------------------------------------------------------------------------*/
56 int8_t
58 {
59  uint8_t tries = 0;
60 
61  i2c_init();
62  while (l3g4200d_read8bit(L3G4200D_WHO_AM_I_REG) != L3G4200D_WHO_AM_I) {
63  _delay_ms(10);
64  if (tries++ > 10) {
65  return 0;
66  }
67  }
68  return 1;
69 }
70 /*----------------------------------------------------------------------------*/
71 int8_t
73 {
74 
75  if (!l3g4200d_available()) {
76  return -1;
77  }
78  // disable power down mode, enable axis
80  (1 << L3G4200D_PD)
81  | (1 << L3G4200D_ZEN)
82  | (1 << L3G4200D_YEN)
83  | (1 << L3G4200D_XEN));
84  l3g4200d_set_dps(L3G4200D_250DPS);
85  return 0;
86 }
87 /*----------------------------------------------------------------------------*/
88 int8_t
90 {
91  // enable power down mode, disable axis
93  return 0;
94 }
95 /*----------------------------------------------------------------------------*/
96 uint8_t
97 l3g4200d_set_dps(uint8_t set)
98 {
99  uint8_t tmpref = l3g4200d_read8bit(L3G4200D_CTRL_REG4);
100  l3g4200d_write8bit(L3G4200D_CTRL_REG4, (tmpref & 0xCF) | set);
101  // set dpsdiv to 4*(datasheet_value)
102  switch (set) {
103  case L3G4200D_250DPS:
104  l3g4200d_dps_scale = L3G4200D_DPSDIV_250G;
105  break;
106  case L3G4200D_500DPS:
107  l3g4200d_dps_scale = L3G4200D_DPSDIV_500G;
108  break;
109  case L3G4200D_2000DPS:
110  l3g4200d_dps_scale = L3G4200D_DPSDIV_2000G;
111  break;
112  }
113  // verify
115  return (tmpref & 0x30) ^ (set);
116 }
117 /*----------------------------------------------------------------------------*/
118 uint8_t
120 {
121  // read
122  uint8_t tmpref = l3g4200d_read8bit(L3G4200D_CTRL_REG1);
123  // write
124  l3g4200d_write8bit(L3G4200D_CTRL_REG1, (tmpref & 0x3F) | set);
125  // verify
127  return (tmpref & 0xC0) ^ (set);
128 }
129 /*----------------------------------------------------------------------------*/
130 void
132 {
133  uint8_t tmpref = l3g4200d_read8bit(L3G4200D_FIFO_CTRL_REG);
134  l3g4200d_write8bit(L3G4200D_FIFO_CTRL_REG, (tmpref & 0x1F) | set);
135 }
136 /*----------------------------------------------------------------------------*/
137 void
139 {
141 }
142 /*----------------------------------------------------------------------------*/
143 int8_t
145 {
147 }
148 /*----------------------------------------------------------------------------*/
151 {
152  angle_data_t ret_data;
153  uint8_t lsb = 0, msb = 0;
154  i2c_start(L3G4200D_DEV_ADDR_W);
155  i2c_write((L3G4200D_OUT_X_L | 0x80));
156  i2c_rep_start(L3G4200D_DEV_ADDR_R);
157  i2c_read_ack(&lsb);
158  i2c_read_ack(&msb);
159  ret_data.x = (uint16_t) ((msb << 8) + lsb);
160  i2c_read_ack(&lsb);
161  i2c_read_ack(&msb);
162  ret_data.y = (uint16_t) ((msb << 8) + lsb);
163  i2c_read_ack(&lsb);
164  i2c_read_nack(&msb);
165  ret_data.z = (uint16_t) ((msb << 8) + lsb);
166  i2c_stop();
167  return ret_data;
168 }
169 /*----------------------------------------------------------------------------*/
170 int8_t
172 {
173  uint8_t idx = 0;
174  uint8_t fifolevel = l3g4200d_read8bit(L3G4200D_FIFO_SRC_REG) & 0x1F;
175 
176  for (idx = 0; idx < fifolevel; idx++) {
177  ret[idx] = l3g4200d_get_angle();
178  }
179 
180  return fifolevel;
181 }
182 /*----------------------------------------------------------------------------*/
183 int16_t
185 {
187 }
188 /*----------------------------------------------------------------------------*/
189 int16_t
191 {
193 }
194 /*----------------------------------------------------------------------------*/
195 int16_t
197 {
199 }
200 /*----------------------------------------------------------------------------*/
201 
202 int8_t
204 {
205  return raw_to_temp(l3g4200d_read8bit(L3G4200D_OUT_TEMP));
206 }
207 /*----------------------------------------------------------------------------*/
208 uint8_t
209 l3g4200d_read8bit(uint8_t addr)
210 {
211  uint8_t lsb = 0;
212  i2c_start(L3G4200D_DEV_ADDR_W);
213  i2c_write(addr);
214  i2c_rep_start(L3G4200D_DEV_ADDR_R);
215  i2c_read_nack(&lsb);
216  i2c_stop();
217  return lsb;
218 }
219 /*----------------------------------------------------------------------------*/
220 uint16_t
221 l3g4200d_read16bit(uint8_t addr)
222 {
223  uint8_t lsb = 0, msb = 0;
224  i2c_start(L3G4200D_DEV_ADDR_W);
225  i2c_write((addr | 0x80));
226  i2c_rep_start(L3G4200D_DEV_ADDR_R);
227  i2c_read_ack(&lsb);
228  i2c_read_nack(&msb);
229  i2c_stop();
230  return (uint16_t) ((msb << 8) + lsb);
231 }
232 /*----------------------------------------------------------------------------*/
233 void
234 l3g4200d_write8bit(uint8_t addr, uint8_t data)
235 {
236  i2c_start(L3G4200D_DEV_ADDR_W);
237  i2c_write(addr);
238  i2c_write(data);
239  i2c_stop();
240 }