Contiki-Inga 3.x
acc-sensor.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  * Accelerometer sensor implementation
33  * \author
34  * Ulf Kulau <kulau@ibr.cs.tu-bs.de>
35  * Georg von Zengen
36  * Enrico Jörns <e.joerns@tu-bs.de>
37  */
38 
39 #include "contiki.h"
40 #include "lib/sensors.h"
41 #include "adxl345.h"
42 #include "acc-sensor.h"
43 #include <stdbool.h>
44 
45 #define FALSE 0
46 #define TRUE 1
47 
48 const struct sensors_sensor acc_sensor;
49 bool interrupt_mode = false; // TODO: needed for possible later implementations with interrupts/events
50 static uint8_t ready = 0;
51 static bool acc_active = false;
52 static acc_data_t acc_data;
53 
54 typedef struct {
55  uint8_t active;
56 } acc_sensor_t;
57 acc_sensor_t acc_sensor_data;
58 /*---------------------------------------------------------------------------*/
59 static void
60 cond_update_acc_data(int ch)
61 {
62  /* bit positions set to one indicate that data is obsolete and a new readout will
63  * needs to be performed. */
64  static uint8_t acc_data_obsolete_vec = 0xFF;
65  /* A real readout is performed only when the channels obsolete flag is already
66  * set. I.e. the channels value has been used already.
67  * Then all obsolete flags are reset to zero. */
68  if (acc_data_obsolete_vec & (1 << ch)) {
69  acc_data = adxl345_get();
70  acc_data_obsolete_vec = 0x00;
71  }
72  /* set obsolete flag for current channel */
73  acc_data_obsolete_vec |= (1 << ch);
74 }
75 /*---------------------------------------------------------------------------*/
76 static int
77 value(int type)
78 {
79  switch (type) {
80  case ACC_X_RAW:
81  cond_update_acc_data(ACC_X_RAW);
82  return acc_data.x;
83 
84  case ACC_Y_RAW:
85  cond_update_acc_data(ACC_Y_RAW);
86  return acc_data.y;
87 
88  case ACC_Z_RAW:
89  cond_update_acc_data(ACC_Z_RAW);
90  return acc_data.z;
91 
92  case ACC_X:
93  cond_update_acc_data(ACC_X);
94  return adxl345_raw_to_mg(acc_data.x);
95 
96  case ACC_Y:
97  cond_update_acc_data(ACC_Y);
98  return adxl345_raw_to_mg(acc_data.y);
99 
100  case ACC_Z:
101  cond_update_acc_data(ACC_Z);
102  return adxl345_raw_to_mg(acc_data.z);
103  }
104  return 0;
105 }
106 /*---------------------------------------------------------------------------*/
107 static int
108 status(int type)
109 {
110  switch (type) {
111  case SENSORS_ACTIVE:
112  return acc_active; // TODO: do check
113  break;
114  case SENSORS_READY:
115  return ready;
116  break;
118  return adxl345_get_fifo_level();
119  break;
120  }
121  return 0;
122 }
123 /*---------------------------------------------------------------------------*/
124 static int
125 configure(int type, int c)
126 {
127  uint8_t value;
128  switch (type) {
129 
130  case SENSORS_HW_INIT:
131  if (adxl345_available()) {
132  ready = 1;
133  } else {
134  ready = 0;
135  }
136  return ready;
137  break;
138 
139  case SENSORS_ACTIVE:
140  if (c) {
141  return acc_active = (adxl345_init() == 0) ? 1 : 0;
142  } else {
143  adxl345_deinit();
144  return 1;
145  }
146  break;
147 
149  // map to register settings
150  switch (c) {
151  case ACC_2G:
152  value = ADXL345_MODE_2G;
153  break;
154  case ACC_4G:
155  value = ADXL345_MODE_4G;
156  break;
157  case ACC_8G:
158  value = ADXL345_MODE_8G;
159  break;
160  case ACC_16G:
161  value = ADXL345_MODE_16G;
162  break;
163  default:
164  return 0;
165  break;
166  }
167  adxl345_set_g_range(value);
168  return TRUE;
169  break;
170 
171  case ACC_CONF_FIFOMODE:
172  // map to register settings
173  switch (c) {
174  case ACC_MODE_BYPASS:
175  value = ADXL345_MODE_BYPASS;
176  break;
177  case ACC_MODE_FIFO:
178  value = ADXL345_MODE_FIFO;
179  break;
180  case ACC_MODE_STREAM:
181  value = ADXL345_MODE_STREAM;
182  break;
183  default:
184  return 0;
185  break;
186  }
187  adxl345_set_fifomode(value);
188  return TRUE;
189  break;
190 
191  case ACC_CONF_POWERMODE:
192  // TODO: implementation needed
193  return 0;
194  break;
195 
196  case ACC_CONF_DATA_RATE:
197  if (c <= ACC_0HZ10) {
198  value = ADXL345_ODR_0HZ10;
199  } else if (c <= ACC_0HZ20) {
200  value = ADXL345_ODR_0HZ20;
201  } else if (c <= ACC_0HZ39) {
202  value = ADXL345_ODR_0HZ39;
203  } else if (c <= ACC_0HZ78) {
204  value = ADXL345_ODR_0HZ78;
205  } else if (c <= ACC_1HZ56) {
206  value = ADXL345_ODR_1HZ56;
207  } else if (c <= ACC_3HZ13) {
208  value = ADXL345_ODR_3HZ13;
209  } else if (c <= ACC_6HZ25) {
210  value = ADXL345_ODR_6HZ25;
211  } else if (c <= ACC_12HZ5) {
212  value = ADXL345_ODR_12HZ5;
213  } else if (c <= ACC_25HZ) {
214  value = ADXL345_ODR_25HZ;
215  } else if (c <= ACC_50HZ) {
216  value = ADXL345_ODR_50HZ;
217  } else if (c <= ACC_100HZ) {
218  value = ADXL345_ODR_100HZ;
219  } else if (c <= ACC_200HZ) {
220  value = ADXL345_ODR_200HZ;
221  } else if (c <= ACC_400HZ) {
222  value = ADXL345_ODR_400HZ;
223  } else if (c <= ACC_800HZ) {
224  value = ADXL345_ODR_800HZ;
225  } else if (c <= ACC_1600HZ) {
226  value = ADXL345_ODR_1600HZ;
227  } else if (c <= ACC_3200HZ) {
228  value = ADXL345_ODR_3200HZ;
229  } else {
230  return 0;
231  }
232  adxl345_set_data_rate(value);
233  return 1;
234  break;
235 
236  }
237  return 0;
238 }
239 /*---------------------------------------------------------------------------*/
240 SENSORS_SENSOR(acc_sensor, ACC_SENSOR, value, configure, status);