ChibiOS  0.0.0
lsm303dlhc.c
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2016..2018 Rocco Marco Guglielmi
3 
4  This file is part of ChibiOS.
5 
6  ChibiOS is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 3 of the License, or
9  (at your option) any later version.
10 
11  ChibiOS is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 */
20 
21 /**
22  * @file lsm303dlhc.c
23  * @brief LSM303DLHC MEMS interface module code.
24  *
25  * @addtogroup LSM303DLHC
26  * @ingroup EX_ST
27  * @{
28  */
29 
30 #include "hal.h"
31 #include "lsm303dlhc.h"
32 
33 /*===========================================================================*/
34 /* Driver local definitions. */
35 /*===========================================================================*/
36 
37 /*===========================================================================*/
38 /* Driver exported variables. */
39 /*===========================================================================*/
40 
41 /*===========================================================================*/
42 /* Driver local variables and types. */
43 /*===========================================================================*/
44 
45 /**
46  * @brief Accelerometer and Compass Slave Address.
47  */
48 typedef enum {
49  LSM303DLHC_SAD_ACC = 0x19, /**< SAD for accelerometer. */
50  LSM303DLHC_SAD_COMP = 0x1E /**< SAD for compass. */
52 
53 /*===========================================================================*/
54 /* Driver local functions. */
55 /*===========================================================================*/
56 
57 /**
58  * @brief Reads registers value using I2C.
59  * @pre The I2C interface must be initialized and the driver started.
60  * @note IF_ADD_INC bit must be 1 in CTRL_REG8.
61  *
62  * @param[in] i2cp pointer to the I2C interface.
63  * @param[in] sad slave address without R bit.
64  * @param[in] reg first sub-register address.
65  * @param[in] rxbuf receiving buffer.
66  * @param[in] n size of rxbuf.
67  * @return the operation status.
68  */
70  uint8_t reg, uint8_t *rxbuf, size_t n) {
71 
72  uint8_t txbuf = reg | LSM303DLHC_MS;
73  return i2cMasterTransmitTimeout(i2cp, sad, &txbuf, 1, rxbuf, n,
75 }
76 
77 /**
78  * @brief Writes a value into a register using I2C.
79  * @pre The I2C interface must be initialized and the driver started.
80  *
81  * @param[in] i2cp pointer to the I2C interface.
82  * @param[in] sad slave address without R bit.
83  * @param[in] txbuf buffer containing sub-address value in first position
84  * and values to write.
85  * @param[in] n size of txbuf less one (not considering the first
86  * element).
87  * @return the operation status.
88  */
90  uint8_t *txbuf, size_t n) {
91  if (n != 1)
92  *txbuf |= LSM303DLHC_MS;
93  return i2cMasterTransmitTimeout(i2cp, sad, txbuf, n + 1, NULL, 0,
95 }
96 
97 /**
98  * @brief Return the number of axes of the BaseAccelerometer.
99  *
100  * @param[in] ip pointer to @p BaseAccelerometer interface.
101  *
102  * @return the number of axes.
103  */
104 static size_t acc_get_axes_number(void *ip) {
105  (void)ip;
106 
108 }
109 
110 /**
111  * @brief Retrieves raw data from the BaseAccelerometer.
112  * @note This data is retrieved from MEMS register without any algebraical
113  * manipulation.
114  * @note The axes array must be at least the same size of the
115  * BaseAccelerometer axes number.
116  *
117  * @param[in] ip pointer to @p BaseAccelerometer interface.
118  * @param[out] axes a buffer which would be filled with raw data.
119  *
120  * @return The operation status.
121  * @retval MSG_OK if the function succeeded.
122  * @retval MSG_RESET if one or more I2C errors occurred, the errors can
123  * be retrieved using @p i2cGetErrors().
124  * @retval MSG_TIMEOUT if a timeout occurred before operation end.
125  */
126 static msg_t acc_read_raw(void *ip, int32_t axes[]) {
127  LSM303DLHCDriver* devp;
128  uint8_t buff [LSM303DLHC_ACC_NUMBER_OF_AXES * 2], i;
129  int16_t tmp;
130  msg_t msg;
131 
132  osalDbgCheck((ip != NULL) && (axes != NULL));
133 
134  /* Getting parent instance pointer.*/
136 
137  osalDbgAssert((devp->state == LSM303DLHC_READY),
138  "acc_read_raw(), invalid state");
139  osalDbgAssert((devp->config->i2cp->state == I2C_READY),
140  "acc_read_raw(), channel not ready");
141 
142 #if LSM303DLHC_SHARED_I2C
143  i2cAcquireBus(devp->config->i2cp);
144  i2cStart(devp->config->i2cp,
145  devp->config->i2ccfg);
146 #endif /* LSM303DLHC_SHARED_I2C */
147 
148  msg = lsm303dlhcI2CReadRegister(devp->config->i2cp, LSM303DLHC_SAD_ACC,
149  LSM303DLHC_AD_ACC_OUT_X_L, buff,
151 
152 #if LSM303DLHC_SHARED_I2C
153  i2cReleaseBus(devp->config->i2cp);
154 #endif /* LSM303DLHC_SHARED_I2C */
155 
156  if(msg == MSG_OK)
157  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++) {
158  tmp = buff[2 * i] + (buff[2 * i + 1] << 8);
159  axes[i] = (int32_t)tmp;
160  }
161  return msg;
162 }
163 
164 /**
165  * @brief Retrieves cooked data from the BaseAccelerometer.
166  * @note This data is manipulated according to the formula
167  * cooked = (raw * sensitivity) - bias.
168  * @note Final data is expressed as milli-G.
169  * @note The axes array must be at least the same size of the
170  * BaseAccelerometer axes number.
171  *
172  * @param[in] ip pointer to @p BaseAccelerometer interface.
173  * @param[out] axes a buffer which would be filled with cooked data.
174  *
175  * @return The operation status.
176  * @retval MSG_OK if the function succeeded.
177  * @retval MSG_RESET if one or more I2C errors occurred, the errors can
178  * be retrieved using @p i2cGetErrors().
179  * @retval MSG_TIMEOUT if a timeout occurred before operation end.
180  */
181 static msg_t acc_read_cooked(void *ip, float axes[]) {
182  LSM303DLHCDriver* devp;
183  uint32_t i;
184  int32_t raw[LSM303DLHC_ACC_NUMBER_OF_AXES];
185  msg_t msg;
186 
187  osalDbgCheck((ip != NULL) && (axes != NULL));
188 
189  /* Getting parent instance pointer.*/
191 
192  osalDbgAssert((devp->state == LSM303DLHC_READY),
193  "acc_read_cooked(), invalid state");
194 
195  msg = acc_read_raw(ip, raw);
196  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++) {
197  axes[i] = (raw[i] * devp->accsensitivity[i]) - devp->accbias[i];
198  }
199  return msg;
200 }
201 
202 /**
203  * @brief Set bias values for the BaseAccelerometer.
204  * @note Bias must be expressed as milli-G.
205  * @note The bias buffer must be at least the same size of the
206  * BaseAccelerometer axes number.
207  *
208  * @param[in] ip pointer to @p BaseAccelerometer interface.
209  * @param[in] bp a buffer which contains biases.
210  *
211  * @return The operation status.
212  * @retval MSG_OK if the function succeeded.
213  */
214 static msg_t acc_set_bias(void *ip, float *bp) {
215  LSM303DLHCDriver* devp;
216  uint32_t i;
217  msg_t msg = MSG_OK;
218 
219  osalDbgCheck((ip != NULL) && (bp != NULL));
220 
221  /* Getting parent instance pointer.*/
223 
224  osalDbgAssert((devp->state == LSM303DLHC_READY),
225  "acc_set_bias(), invalid state");
226 
227  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++) {
228  devp->accbias[i] = bp[i];
229  }
230  return msg;
231 }
232 
233 /**
234  * @brief Reset bias values for the BaseAccelerometer.
235  * @note Default biases value are obtained from device datasheet when
236  * available otherwise they are considered zero.
237  *
238  * @param[in] ip pointer to @p BaseAccelerometer interface.
239  *
240  * @return The operation status.
241  * @retval MSG_OK if the function succeeded.
242  */
243 static msg_t acc_reset_bias(void *ip) {
244  LSM303DLHCDriver* devp;
245  uint32_t i;
246  msg_t msg = MSG_OK;
247 
248  osalDbgCheck(ip != NULL);
249 
250  /* Getting parent instance pointer.*/
252 
253  osalDbgAssert((devp->state == LSM303DLHC_READY),
254  "acc_reset_bias(), invalid state");
255 
256  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++)
257  devp->accbias[i] = LSM303DLHC_ACC_BIAS;
258  return msg;
259 }
260 
261 /**
262  * @brief Set sensitivity values for the BaseAccelerometer.
263  * @note Sensitivity must be expressed as milli-G/LSB.
264  * @note The sensitivity buffer must be at least the same size of the
265  * BaseAccelerometer axes number.
266  *
267  * @param[in] ip pointer to @p BaseAccelerometer interface.
268  * @param[in] sp a buffer which contains sensitivities.
269  *
270  * @return The operation status.
271  * @retval MSG_OK if the function succeeded.
272  */
273 static msg_t acc_set_sensivity(void *ip, float *sp) {
274  LSM303DLHCDriver* devp;
275  uint32_t i;
276  msg_t msg = MSG_OK;
277 
278  /* Getting parent instance pointer.*/
280 
281  osalDbgCheck((ip != NULL) && (sp != NULL));
282 
283  osalDbgAssert((devp->state == LSM303DLHC_READY),
284  "acc_set_sensivity(), invalid state");
285 
286  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++) {
287  devp->accsensitivity[i] = sp[i];
288  }
289  return msg;
290 }
291 
292 /**
293  * @brief Reset sensitivity values for the BaseAccelerometer.
294  * @note Default sensitivities value are obtained from device datasheet.
295  *
296  * @param[in] ip pointer to @p BaseAccelerometer interface.
297  *
298  * @return The operation status.
299  * @retval MSG_OK if the function succeeded.
300  * @retval MSG_RESET otherwise.
301  */
302 static msg_t acc_reset_sensivity(void *ip) {
303  LSM303DLHCDriver* devp;
304  uint32_t i;
305  msg_t msg = MSG_OK;
306 
307  osalDbgCheck(ip != NULL);
308 
309  /* Getting parent instance pointer.*/
311 
312  osalDbgAssert((devp->state == LSM303DLHC_READY),
313  "acc_reset_sensivity(), invalid state");
314 
315  if(devp->config->accfullscale == LSM303DLHC_ACC_FS_2G)
316  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++)
317  devp->accsensitivity[i] = LSM303DLHC_ACC_SENS_2G;
318  else if(devp->config->accfullscale == LSM303DLHC_ACC_FS_4G)
319  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++)
320  devp->accsensitivity[i] = LSM303DLHC_ACC_SENS_4G;
321  else if(devp->config->accfullscale == LSM303DLHC_ACC_FS_8G)
322  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++)
323  devp->accsensitivity[i] = LSM303DLHC_ACC_SENS_8G;
324  else if(devp->config->accfullscale == LSM303DLHC_ACC_FS_16G)
325  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++)
326  devp->accsensitivity[i] = LSM303DLHC_ACC_SENS_16G;
327  else {
328  osalDbgAssert(FALSE, "acc_reset_sensivity(), accelerometer full scale issue");
329  msg = MSG_RESET;
330  }
331  return msg;
332 }
333 
334 /**
335  * @brief Changes the LSM303DLHCDriver accelerometer fullscale value.
336  * @note This function also rescale sensitivities and biases based on
337  * previous and next fullscale value.
338  * @note A recalibration is highly suggested after calling this function.
339  *
340  * @param[in] devp pointer to @p LSM303DLHCDriver interface.
341  * @param[in] fs new fullscale value.
342  *
343  * @return The operation status.
344  * @retval MSG_OK if the function succeeded.
345  * @retval MSG_RESET otherwise.
346  */
348  lsm303dlhc_acc_fs_t fs) {
349  float newfs, scale;
350  uint8_t i, buff[2];
351  msg_t msg;
352 
353  osalDbgCheck(devp != NULL);
354 
355  osalDbgAssert((devp->state == LSM303DLHC_READY),
356  "acc_set_full_scale(), invalid state");
357  osalDbgAssert((devp->config->i2cp->state == I2C_READY),
358  "acc_set_full_scale(), channel not ready");
359 
360  /* Computing new fullscale value.*/
361  if(fs == LSM303DLHC_ACC_FS_2G) {
362  newfs = LSM303DLHC_ACC_2G;
363  }
364  else if(fs == LSM303DLHC_ACC_FS_4G) {
365  newfs = LSM303DLHC_ACC_4G;
366  }
367  else if(fs == LSM303DLHC_ACC_FS_8G) {
368  newfs = LSM303DLHC_ACC_8G;
369  }
370  else if(fs == LSM303DLHC_ACC_FS_16G) {
371  newfs = LSM303DLHC_ACC_16G;
372  }
373  else {
374  msg = MSG_RESET;
375  return msg;
376  }
377 
378  if(newfs != devp->accfullscale) {
379  /* Computing scale value.*/
380  scale = newfs / devp->accfullscale;
381  devp->accfullscale = newfs;
382 
383 #if LSM303DLHC_SHARED_I2C
384  i2cAcquireBus(devp->config->i2cp);
385  i2cStart(devp->config->i2cp,
386  devp->config->i2ccfg);
387 #endif /* LSM303DLHC_SHARED_I2C */
388 
389  /* Updating register.*/
390  msg = lsm303dlhcI2CReadRegister(devp->config->i2cp,
392  LSM303DLHC_AD_ACC_CTRL_REG4,
393  &buff[1], 1);
394 
395 #if LSM303DLHC_SHARED_I2C
396  i2cReleaseBus(devp->config->i2cp);
397 #endif /* LSM303DLHC_SHARED_I2C */
398 
399  if(msg != MSG_OK)
400  return msg;
401 
402  buff[1] &= ~(LSM303DLHC_CTRL_REG4_A_FS_MASK);
403  buff[1] |= fs;
404  buff[0] = LSM303DLHC_AD_ACC_CTRL_REG4;
405 
406 #if LSM303DLHC_SHARED_I2C
407  i2cAcquireBus(devp->config->i2cp);
408  i2cStart(devp->config->i2cp, devp->config->i2ccfg);
409 #endif /* LSM303DLHC_SHARED_I2C */
410 
411  msg = lsm303dlhcI2CWriteRegister(devp->config->i2cp,
412  LSM303DLHC_SAD_ACC, buff, 1);
413 
414 #if LSM303DLHC_SHARED_I2C
415  i2cReleaseBus(devp->config->i2cp);
416 #endif /* LSM303DLHC_SHARED_I2C */
417 
418  if(msg != MSG_OK)
419  return msg;
420 
421  /* Scaling sensitivity and bias. Re-calibration is suggested anyway.*/
422  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++) {
423  devp->accsensitivity[i] *= scale;
424  devp->accbias[i] *= scale;
425  }
426  }
427  return msg;
428 }
429 
430 /**
431  * @brief Return the number of axes of the BaseCompass.
432  *
433  * @param[in] ip pointer to @p BaseCompass interface
434  *
435  * @return the number of axes.
436  */
437 static size_t comp_get_axes_number(void *ip) {
438 
439  osalDbgCheck(ip != NULL);
441 }
442 
443 /**
444  * @brief Retrieves raw data from the BaseCompass.
445  * @note This data is retrieved from MEMS register without any algebraical
446  * manipulation.
447  * @note The axes array must be at least the same size of the
448  * BaseCompass axes number.
449  *
450  * @param[in] ip pointer to @p BaseCompass interface.
451  * @param[out] axes a buffer which would be filled with raw data.
452  *
453  * @return The operation status.
454  * @retval MSG_OK if the function succeeded.
455  * @retval MSG_RESET if one or more I2C errors occurred, the errors can
456  * be retrieved using @p i2cGetErrors().
457  * @retval MSG_TIMEOUT if a timeout occurred before operation end.
458  */
459 static msg_t comp_read_raw(void *ip, int32_t axes[]) {
460  LSM303DLHCDriver* devp;
461  uint8_t buff [LSM303DLHC_COMP_NUMBER_OF_AXES * 2], i;
462  int16_t tmp;
463  msg_t msg;
464 
465  osalDbgCheck((ip != NULL) && (axes != NULL));
466 
467  /* Getting parent instance pointer.*/
469 
470  osalDbgAssert((devp->state == LSM303DLHC_READY),
471  "comp_read_raw(), invalid state");
472  osalDbgAssert((devp->config->i2cp->state == I2C_READY),
473  "comp_read_raw(), channel not ready");
474 
475 #if LSM303DLHC_SHARED_I2C
476  i2cAcquireBus(devp->config->i2cp);
477  i2cStart(devp->config->i2cp,
478  devp->config->i2ccfg);
479 #endif /* LSM303DLHC_SHARED_I2C */
480  msg = lsm303dlhcI2CReadRegister(devp->config->i2cp, LSM303DLHC_SAD_COMP,
481  LSM303DLHC_AD_COMP_OUT_X_L, buff,
483 
484 #if LSM303DLHC_SHARED_I2C
485  i2cReleaseBus(devp->config->i2cp);
486 #endif /* LSM303DLHC_SHARED_I2C */
487 
488  if(msg == MSG_OK)
489  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
490  tmp = buff[2 * i] + (buff[2 * i + 1] << 8);
491  axes[i] = (int32_t)tmp;
492  }
493  return msg;
494 }
495 
496 /**
497  * @brief Retrieves cooked data from the BaseCompass.
498  * @note This data is manipulated according to the formula
499  * cooked = (raw * sensitivity) - bias.
500  * @note Final data is expressed as G.
501  * @note The axes array must be at least the same size of the
502  * BaseCompass axes number.
503  *
504  * @param[in] ip pointer to @p BaseCompass interface.
505  * @param[out] axes a buffer which would be filled with cooked data.
506  *
507  * @return The operation status.
508  * @retval MSG_OK if the function succeeded.
509  * @retval MSG_RESET if one or more I2C errors occurred, the errors can
510  * be retrieved using @p i2cGetErrors().
511  * @retval MSG_TIMEOUT if a timeout occurred before operation end.
512  */
513 static msg_t comp_read_cooked(void *ip, float axes[]) {
514  LSM303DLHCDriver* devp;
515  uint32_t i;
516  int32_t raw[LSM303DLHC_COMP_NUMBER_OF_AXES];
517  msg_t msg;
518 
519  osalDbgCheck((ip != NULL) && (axes != NULL));
520 
521 
522  /* Getting parent instance pointer.*/
524 
525  osalDbgAssert((devp->state == LSM303DLHC_READY),
526  "comp_read_cooked(), invalid state");
527 
528  msg = comp_read_raw(ip, raw);
529  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES ; i++) {
530  axes[i] = (raw[i] * devp->compsensitivity[i]) - devp->compbias[i];
531  }
532  return msg;
533 }
534 
535 /**
536  * @brief Set bias values for the BaseCompass.
537  * @note Bias must be expressed as G.
538  * @note The bias buffer must be at least the same size of the
539  * BaseCompass axes number.
540  *
541  * @param[in] ip pointer to @p BaseCompass interface.
542  * @param[in] bp a buffer which contains biases.
543  *
544  * @return The operation status.
545  * @retval MSG_OK if the function succeeded.
546  */
547 static msg_t comp_set_bias(void *ip, float *bp) {
548  LSM303DLHCDriver* devp;
549  uint32_t i;
550  msg_t msg = MSG_OK;
551 
552  osalDbgCheck((ip != NULL) && (bp != NULL));
553 
554  /* Getting parent instance pointer.*/
556 
557  osalDbgAssert((devp->state == LSM303DLHC_READY),
558  "comp_set_bias(), invalid state");
559 
560  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
561  devp->compbias[i] = bp[i];
562  }
563  return msg;
564 }
565 
566 /**
567  * @brief Reset bias values for the BaseCompass.
568  * @note Default biases value are obtained from device datasheet when
569  * available otherwise they are considered zero.
570  *
571  * @param[in] ip pointer to @p BaseCompass interface.
572  *
573  * @return The operation status.
574  * @retval MSG_OK if the function succeeded.
575  */
576 static msg_t comp_reset_bias(void *ip) {
577  LSM303DLHCDriver* devp;
578  uint32_t i;
579  msg_t msg = MSG_OK;
580 
581  osalDbgCheck(ip != NULL);
582 
583  /* Getting parent instance pointer.*/
585 
586  osalDbgAssert((devp->state == LSM303DLHC_READY),
587  "comp_reset_bias(), invalid state");
588 
589  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++)
590  devp->compbias[i] = LSM303DLHC_COMP_BIAS;
591  return msg;
592 }
593 
594 /**
595  * @brief Set sensitivity values for the BaseCompass.
596  * @note Sensitivity must be expressed as G/LSB.
597  * @note The sensitivity buffer must be at least the same size of the
598  * BaseCompass axes number.
599  *
600  * @param[in] ip pointer to @p BaseCompass interface.
601  * @param[in] sp a buffer which contains sensitivities.
602  *
603  * @return The operation status.
604  * @retval MSG_OK if the function succeeded.
605  */
606 static msg_t comp_set_sensivity(void *ip, float *sp) {
607  LSM303DLHCDriver* devp;
608  uint32_t i;
609  msg_t msg = MSG_OK;
610 
611  /* Getting parent instance pointer.*/
613 
614  osalDbgCheck((ip != NULL) && (sp != NULL));
615 
616  osalDbgAssert((devp->state == LSM303DLHC_READY),
617  "comp_set_sensivity(), invalid state");
618 
619  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
620  devp->compsensitivity[i] = sp[i];
621  }
622  return msg;
623 }
624 
625 /**
626  * @brief Reset sensitivity values for the BaseCompass.
627  * @note Default sensitivities value are obtained from device datasheet.
628  *
629  * @param[in] ip pointer to @p BaseCompass interface.
630  *
631  * @return The operation status.
632  * @retval MSG_OK if the function succeeded.
633  * @retval MSG_RESET otherwise.
634  */
635 static msg_t comp_reset_sensivity(void *ip) {
636  LSM303DLHCDriver* devp;
637  uint32_t i;
638  msg_t msg = MSG_OK;
639 
640  osalDbgCheck(ip != NULL);
641 
642  /* Getting parent instance pointer.*/
644 
645  osalDbgAssert((devp->state == LSM303DLHC_READY),
646  "comp_reset_sensivity(), invalid state");
647 
648  if(devp->config->compfullscale == LSM303DLHC_COMP_FS_1P3GA)
649  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
650  if(i != 2) {
651  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_1P3GA;
652  }
653  else {
654  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_1P3GA;
655  }
656  }
657  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_1P9GA)
658  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
659  if(i != 2) {
660  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_1P9GA;
661  }
662  else {
663  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_1P9GA;
664  }
665  }
666  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_2P5GA)
667  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
668  if(i != 2) {
669  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_2P5GA;
670  }
671  else {
672  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_2P5GA;
673  }
674  }
675  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_4P0GA)
676  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
677  if(i != 2) {
678  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_4P0GA;
679  }
680  else {
681  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_4P0GA;
682  }
683  }
684  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_4P7GA)
685  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
686  if(i != 2) {
687  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_4P7GA;
688  }
689  else {
690  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_4P7GA;
691  }
692  }
693  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_5P6GA)
694  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
695  if(i != 2) {
696  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_5P6GA;
697  }
698  else {
699  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_5P6GA;
700  }
701  }
702  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_8P1GA)
703  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
704  if(i != 2) {
705  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_8P1GA;
706  }
707  else {
708  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_8P1GA;
709  }
710  }
711  else {
712  osalDbgAssert(FALSE, "comp_reset_sensivity(), compass full scale issue");
713  msg = MSG_RESET;
714  }
715  return msg;
716 }
717 
718 /**
719  * @brief Changes the LSM303DLHCDriver compass fullscale value.
720  * @note This function also rescale sensitivities and biases based on
721  * previous and next fullscale value.
722  * @note A recalibration is highly suggested after calling this function.
723  *
724  * @param[in] devp pointer to @p LSM303DLHCDriver interface.
725  * @param[in] fs new fullscale value.
726  *
727  * @return The operation status.
728  * @retval MSG_OK if the function succeeded.
729  * @retval MSG_RESET otherwise.
730  */
733  float newfs, scale;
734  uint8_t i, buff[2];
735  msg_t msg;
736 
737  osalDbgCheck(devp != NULL);
738 
739  osalDbgAssert((devp->state == LSM303DLHC_READY),
740  "comp_set_full_scale(), invalid state");
741  osalDbgAssert((devp->config->i2cp->state == I2C_READY),
742  "comp_set_full_scale(), channel not ready");
743 
744  /* Computing new fullscale value.*/
745  if(fs == LSM303DLHC_COMP_FS_1P3GA) {
746  newfs = LSM303DLHC_COMP_1P3GA;
747  }
748  else if(fs == LSM303DLHC_COMP_FS_1P9GA) {
749  newfs = LSM303DLHC_COMP_1P9GA;
750  }
751  else if(fs == LSM303DLHC_COMP_FS_2P5GA) {
752  newfs = LSM303DLHC_COMP_2P5GA;
753  }
754  else if(fs == LSM303DLHC_COMP_FS_4P0GA) {
755  newfs = LSM303DLHC_COMP_4P0GA;
756  }
757  else if(fs == LSM303DLHC_COMP_FS_4P7GA) {
758  newfs = LSM303DLHC_COMP_4P7GA;
759  }
760  else if(fs == LSM303DLHC_COMP_FS_5P6GA) {
761  newfs = LSM303DLHC_COMP_5P6GA;
762  }
763  else if(fs == LSM303DLHC_COMP_FS_8P1GA) {
764  newfs = LSM303DLHC_COMP_8P1GA;
765  }
766  else {
767  msg = MSG_RESET;
768  return msg;
769  }
770 
771  if(newfs != devp->compfullscale) {
772  /* Computing scale value.*/
773  scale = newfs / devp->compfullscale;
774  devp->compfullscale = newfs;
775 
776 #if LSM303DLHC_SHARED_I2C
777  i2cAcquireBus(devp->config->i2cp);
778  i2cStart(devp->config->i2cp, devp->config->i2ccfg);
779 #endif /* LSM303DLHC_SHARED_I2C */
780 
781  /* Updating register.*/
782  msg = lsm303dlhcI2CReadRegister(devp->config->i2cp, LSM303DLHC_SAD_COMP,
783  LSM303DLHC_AD_COMP_CRB_REG, &buff[1], 1);
784 
785 #if LSM303DLHC_SHARED_I2C
786  i2cReleaseBus(devp->config->i2cp);
787 #endif /* LSM303DLHC_SHARED_I2C */
788 
789  if(msg != MSG_OK)
790  return msg;
791  buff[1] &= ~(LSM303DLHC_CRB_REG_M_GN_MASK);
792  buff[1] |= fs;
793  buff[0] = LSM303DLHC_AD_COMP_CRB_REG;
794 
795 #if LSM303DLHC_SHARED_I2C
796  i2cAcquireBus(devp->config->i2cp);
797  i2cStart(devp->config->i2cp, devp->config->i2ccfg);
798 #endif /* LSM303DLHC_SHARED_I2C */
799 
800  msg = lsm303dlhcI2CWriteRegister(devp->config->i2cp, LSM303DLHC_SAD_COMP,
801  buff, 1);
802 
803 #if LSM303DLHC_SHARED_I2C
804  i2cReleaseBus(devp->config->i2cp);
805 #endif /* LSM303DLHC_SHARED_I2C */
806 
807  if(msg != MSG_OK)
808  return msg;
809 
810  /* Scaling sensitivity and bias. Re-calibration is suggested anyway.*/
811  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
812  devp->compsensitivity[i] *= scale;
813  devp->compbias[i] *= scale;
814  }
815  }
816  return msg;
817 }
818 
819 static const struct LSM303DLHCVMT vmt_device = {
820  (size_t)0,
822 };
823 
824 static const struct BaseAccelerometerVMT vmt_accelerometer = {
825  sizeof(struct LSM303DLHCVMT*),
828 };
829 
830 static const struct BaseCompassVMT vmt_compass = {
831  sizeof(struct LSM303DLHCVMT*) + sizeof(BaseAccelerometer),
834 };
835 
836 /*===========================================================================*/
837 /* Driver exported functions. */
838 /*===========================================================================*/
839 
840 /**
841  * @brief Initializes an instance.
842  *
843  * @param[out] devp pointer to the @p LSM303DLHCDriver object
844  *
845  * @init
846  */
848  devp->vmt = &vmt_device;
849  devp->acc_if.vmt = &vmt_accelerometer;
850  devp->comp_if.vmt = &vmt_compass;
851 
852  devp->config = NULL;
853 
854  devp->accaxes = LSM303DLHC_ACC_NUMBER_OF_AXES;
855  devp->compaxes = LSM303DLHC_COMP_NUMBER_OF_AXES;
856 
857  devp->state = LSM303DLHC_STOP;
858 }
859 
860 /**
861  * @brief Configures and activates LSM303DLHC Complex Driver peripheral.
862  *
863  * @param[in] devp pointer to the @p LSM303DLHCDriver object
864  * @param[in] config pointer to the @p LSM303DLHCConfig object
865  *
866  * @api
867  */
869  uint32_t i;
870  uint8_t cr[6];
871  osalDbgCheck((devp != NULL) && (config != NULL));
872 
873  osalDbgAssert((devp->state == LSM303DLHC_STOP) ||
874  (devp->state == LSM303DLHC_READY),
875  "lsm303dlhcStart(), invalid state");
876 
877  devp->config = config;
878 
879  /* Configuring Accelerometer subsystem.*/
880 
881  /* Multiple write starting address.*/
882  cr[0] = LSM303DLHC_AD_ACC_CTRL_REG1;
883 
884  /* Control register 1 configuration block.*/
885  {
886  cr[1] = LSM303DLHC_CTRL_REG1_A_XEN | LSM303DLHC_CTRL_REG1_A_YEN |
887  LSM303DLHC_CTRL_REG1_A_ZEN | devp->config->accoutdatarate;
888 #if LSM303DLHC_ACC_USE_ADVANCED || defined(__DOXYGEN__)
889  cr[1] |= devp->config->acclowpower;
890 #endif
891  }
892 
893  /* Control register 2 configuration block.*/
894  {
895  cr[2] = 0;
896  }
897 
898  /* Control register 3 configuration block.*/
899  {
900  cr[3] = 0;
901  }
902 
903  /* Control register 4 configuration block.*/
904  {
905  cr[4] = devp->config->accfullscale;
906 #if LSM303DLHC_ACC_USE_ADVANCED || defined(__DOXYGEN__)
907  cr[4] |= devp->config->accendianess |
908  devp->config->accblockdataupdate |
909  devp->config->acchighresmode;
910 #endif
911  }
912 
913 #if LSM303DLHC_SHARED_I2C
914  i2cAcquireBus((devp)->config->i2cp);
915 #endif /* LSM303DLHC_SHARED_I2C */
916  i2cStart((devp)->config->i2cp, (devp)->config->i2ccfg);
917 
918  lsm303dlhcI2CWriteRegister(devp->config->i2cp, LSM303DLHC_SAD_ACC, cr, 4);
919 
920 #if LSM303DLHC_SHARED_I2C
921  i2cReleaseBus((devp)->config->i2cp);
922 #endif /* LSM303DLHC_SHARED_I2C */
923 
924  /* Storing sensitivity according to user settings */
925  if(devp->config->accfullscale == LSM303DLHC_ACC_FS_2G) {
926  devp->accfullscale = LSM303DLHC_ACC_2G;
927  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++) {
928  if(devp->config->accsensitivity == NULL)
929  devp->accsensitivity[i] = LSM303DLHC_ACC_SENS_2G;
930  else
931  devp->accsensitivity[i] = devp->config->accsensitivity[i];
932  }
933  }
934  else if(devp->config->accfullscale == LSM303DLHC_ACC_FS_4G) {
935  devp->accfullscale = LSM303DLHC_ACC_4G;
936  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++) {
937  if(devp->config->accsensitivity == NULL)
938  devp->accsensitivity[i] = LSM303DLHC_ACC_SENS_4G;
939  else
940  devp->accsensitivity[i] = devp->config->accsensitivity[i];
941  }
942  }
943  else if(devp->config->accfullscale == LSM303DLHC_ACC_FS_8G) {
944  devp->accfullscale = LSM303DLHC_ACC_8G;
945  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++) {
946  if(devp->config->accsensitivity == NULL)
947  devp->accsensitivity[i] = LSM303DLHC_ACC_SENS_8G;
948  else
949  devp->accsensitivity[i] = devp->config->accsensitivity[i];
950  }
951  }
952  else if(devp->config->accfullscale == LSM303DLHC_ACC_FS_16G) {
953  devp->accfullscale = LSM303DLHC_ACC_16G;
954  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++) {
955  if(devp->config->accsensitivity == NULL)
956  devp->accsensitivity[i] = LSM303DLHC_ACC_SENS_16G;
957  else
958  devp->accsensitivity[i] = devp->config->accsensitivity[i];
959  }
960  }
961  else
962  osalDbgAssert(FALSE, "lsm303dlhcStart(), accelerometer full scale issue");
963 
964  /* Storing bias information */
965  if(devp->config->accbias != NULL)
966  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++)
967  devp->accbias[i] = devp->config->accbias[i];
968  else
969  for(i = 0; i < LSM303DLHC_ACC_NUMBER_OF_AXES; i++)
970  devp->accbias[i] = LSM303DLHC_ACC_BIAS;
971 
972  /* Configuring Compass subsystem */
973  /* Multiple write starting address.*/
974  cr[0] = LSM303DLHC_AD_COMP_CRA_REG;
975 
976  /* Control register A configuration block.*/
977  {
978  cr[1] = devp->config->compoutputdatarate;
979  }
980 
981  /* Control register B configuration block.*/
982  {
983  cr[2] = devp->config->compfullscale;
984  }
985 
986  /* Mode register configuration block.*/
987  {
988  cr[3] = 0;
989 #if LSM303DLHC_COMP_USE_ADVANCED || defined(__DOXYGEN__)
990  cr[3] |= devp->config->compmode;
991 #endif
992  }
993 
994 #if LSM303DLHC_SHARED_I2C
995  i2cAcquireBus((devp)->config->i2cp);
996  i2cStart((devp)->config->i2cp, (devp)->config->i2ccfg);
997 #endif /* LSM303DLHC_SHARED_I2C */
998 
1000  cr, 3);
1001 
1002 #if LSM303DLHC_SHARED_I2C
1003  i2cReleaseBus((devp)->config->i2cp);
1004 #endif /* LSM303DLHC_SHARED_I2C */
1005 
1006  if(devp->config->compfullscale == LSM303DLHC_COMP_FS_1P3GA) {
1007  devp->compfullscale = LSM303DLHC_COMP_1P3GA;
1008  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
1009  if(devp->config->compsensitivity == NULL) {
1010  if(i != 2) {
1011  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_1P3GA;
1012  }
1013  else {
1014  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_1P3GA;
1015  }
1016  }
1017  else {
1018  devp->compsensitivity[i] = devp->config->compsensitivity[i];
1019  }
1020  }
1021  }
1022  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_1P9GA) {
1023  devp->compfullscale = LSM303DLHC_COMP_1P9GA;
1024  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
1025  if(devp->config->compsensitivity == NULL) {
1026  if(i != 2) {
1027  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_1P9GA;
1028  }
1029  else {
1030  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_1P9GA;
1031  }
1032  }
1033  else {
1034  devp->compsensitivity[i] = devp->config->compsensitivity[i];
1035  }
1036  }
1037  }
1038  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_2P5GA) {
1039  devp->compfullscale = LSM303DLHC_COMP_2P5GA;
1040  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
1041  if(devp->config->compsensitivity == NULL) {
1042  if(i != 2) {
1043  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_2P5GA;
1044  }
1045  else {
1046  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_2P5GA;
1047  }
1048  }
1049  else {
1050  devp->compsensitivity[i] = devp->config->compsensitivity[i];
1051  }
1052  }
1053  }
1054  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_4P0GA) {
1055  devp->compfullscale = LSM303DLHC_COMP_4P0GA;
1056  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
1057  if(devp->config->compsensitivity == NULL) {
1058  if(i != 2) {
1059  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_4P0GA;
1060  }
1061  else {
1062  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_4P0GA;
1063  }
1064  }
1065  else {
1066  devp->compsensitivity[i] = devp->config->compsensitivity[i];
1067  }
1068  }
1069  }
1070  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_4P7GA) {
1071  devp->compfullscale = LSM303DLHC_COMP_4P7GA;
1072  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
1073  if(devp->config->compsensitivity == NULL) {
1074  if(i != 2) {
1075  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_4P7GA;
1076  }
1077  else {
1078  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_4P7GA;
1079  }
1080  }
1081  else {
1082  devp->compsensitivity[i] = devp->config->compsensitivity[i];
1083  }
1084  }
1085  }
1086  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_5P6GA) {
1087  devp->compfullscale = LSM303DLHC_COMP_5P6GA;
1088  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
1089  if(devp->config->compsensitivity == NULL) {
1090  if(i != 2) {
1091  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_5P6GA;
1092  }
1093  else {
1094  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_5P6GA;
1095  }
1096  }
1097  else {
1098  devp->compsensitivity[i] = devp->config->compsensitivity[i];
1099  }
1100  }
1101  }
1102  else if(devp->config->compfullscale == LSM303DLHC_COMP_FS_8P1GA) {
1103  devp->compfullscale = LSM303DLHC_COMP_8P1GA;
1104  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++) {
1105  if(devp->config->compsensitivity == NULL) {
1106  if(i != 2) {
1107  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_XY_8P1GA;
1108  }
1109  else {
1110  devp->compsensitivity[i] = LSM303DLHC_COMP_SENS_Z_8P1GA;
1111  }
1112  }
1113  else {
1114  devp->compsensitivity[i] = devp->config->compsensitivity[i];
1115  }
1116  }
1117  }
1118  else
1119  osalDbgAssert(FALSE, "lsm303dlhcStart(), compass full scale issue");
1120 
1121  /* Storing bias information */
1122  if(devp->config->compbias != NULL)
1123  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++)
1124  devp->compbias[i] = devp->config->compbias[i];
1125  else
1126  for(i = 0; i < LSM303DLHC_COMP_NUMBER_OF_AXES; i++)
1127  devp->compbias[i] = LSM303DLHC_COMP_BIAS;
1128 
1129  /* This is the MEMS transient recovery time */
1131 
1132  devp->state = LSM303DLHC_READY;
1133 }
1134 
1135 /**
1136  * @brief Deactivates the LSM303DLHC Complex Driver peripheral.
1137  *
1138  * @param[in] devp pointer to the @p LSM303DLHCDriver object
1139  *
1140  * @api
1141  */
1143  uint8_t cr[2];
1144  osalDbgCheck(devp != NULL);
1145 
1146  osalDbgAssert((devp->state == LSM303DLHC_STOP) ||
1147  (devp->state == LSM303DLHC_READY),
1148  "lsm303dlhcStop(), invalid state");
1149 
1150  if (devp->state == LSM303DLHC_READY) {
1151 #if LSM303DLHC_SHARED_I2C
1152  i2cAcquireBus((devp)->config->i2cp);
1153  i2cStart((devp)->config->i2cp, (devp)->config->i2ccfg);
1154 #endif /* LSM303DLHC_SHARED_I2C */
1155 
1156  /* Disabling accelerometer. */
1157  cr[0] = LSM303DLHC_AD_ACC_CTRL_REG1;
1159  lsm303dlhcI2CWriteRegister(devp->config->i2cp, LSM303DLHC_SAD_ACC,
1160  cr, 1);
1161 
1162  /* Disabling compass. */
1163  cr[0] = LSM303DLHC_AD_COMP_MR_REG;
1164  cr[1] = LSM303DLHC_COMP_MD_SLEEP;
1165  lsm303dlhcI2CWriteRegister(devp->config->i2cp, LSM303DLHC_SAD_COMP,
1166  cr, 1);
1167 
1168  i2cStop((devp)->config->i2cp);
1169 #if LSM303DLHC_SHARED_I2C
1170  i2cReleaseBus((devp)->config->i2cp);
1171 #endif /* LSM303DLHC_SHARED_I2C */
1172  }
1173  devp->state = LSM303DLHC_STOP;
1174 }
1175 /** @} */
msg_t i2cMasterTransmitTimeout(I2CDriver *i2cp, i2caddr_t addr, const uint8_t *txbuf, size_t txbytes, uint8_t *rxbuf, size_t rxbytes, sysinterval_t timeout)
Sends data via the I2C bus.
Definition: hal_i2c.c:170
void i2cStart(I2CDriver *i2cp, const I2CConfig *config)
Configures and activates the I2C peripheral.
Definition: hal_i2c.c:93
BaseCompass virtual methods table.
Definition: hal_compass.h:70
static msg_t lsm303dlhcI2CReadRegister(I2CDriver *i2cp, lsm303dlhc_sad_t sad, uint8_t reg, uint8_t *rxbuf, size_t n)
Reads registers value using I2C.
Definition: lsm303dlhc.c:69
Base compass class.
Definition: hal_compass.h:86
static msg_t lsm303dlhcI2CWriteRegister(I2CDriver *i2cp, lsm303dlhc_sad_t sad, uint8_t *txbuf, size_t n)
Writes a value into a register using I2C.
Definition: lsm303dlhc.c:89
static msg_t comp_set_full_scale(LSM303DLHCDriver *devp, lsm303dlhc_comp_fs_t fs)
Changes the LSM303DLHCDriver compass fullscale value.
Definition: lsm303dlhc.c:731
static msg_t comp_read_raw(void *ip, int32_t axes[])
Retrieves raw data from the BaseCompass.
Definition: lsm303dlhc.c:459
static msg_t comp_set_bias(void *ip, float *bp)
Set bias values for the BaseCompass.
Definition: lsm303dlhc.c:547
HAL subsystem header.
static msg_t acc_set_bias(void *ip, float *bp)
Set bias values for the BaseAccelerometer.
Definition: lsm303dlhc.c:214
void i2cAcquireBus(I2CDriver *i2cp)
Gains exclusive access to the I2C bus.
Definition: hal_i2c.c:261
void i2cReleaseBus(I2CDriver *i2cp)
Releases exclusive access to the I2C bus.
Definition: hal_i2c.c:277
static msg_t acc_read_cooked(void *ip, float axes[])
Retrieves cooked data from the BaseAccelerometer.
Definition: lsm303dlhc.c:181
#define LSM303DLHC_ACC_NUMBER_OF_AXES
LSM303DLHC accelerometer subsystem characteristics.
Definition: lsm303dlhc.h:72
lsm303dlhc_sad_t
Accelerometer and Compass Slave Address.
Definition: lsm303dlhc.c:48
static msg_t comp_read_cooked(void *ip, float axes[])
Retrieves cooked data from the BaseCompass.
Definition: lsm303dlhc.c:513
void lsm303dlhcStop(LSM303DLHCDriver *devp)
Deactivates the LSM303DLHC Complex Driver peripheral.
Definition: lsm303dlhc.c:1142
I2CDriver * i2cp
I2C driver associated to this LSM303DLHC.
Definition: lsm303dlhc.h:542
static msg_t comp_set_sensivity(void *ip, float *sp)
Set sensitivity values for the BaseCompass.
Definition: lsm303dlhc.c:606
#define objGetInstance(type, ip)
Returns the instance pointer starting from an interface pointer.
Definition: hal_objects.h:80
const struct BaseCompassVMT * vmt
Virtual Methods Table.
Definition: hal_compass.h:88
static msg_t acc_reset_sensivity(void *ip)
Reset sensitivity values for the BaseAccelerometer.
Definition: lsm303dlhc.c:302
#define osalThreadSleepMilliseconds(msecs)
Delays the invoking thread for the specified number of milliseconds.
Definition: osal.h:451
void i2cStop(I2CDriver *i2cp)
Deactivates the I2C peripheral.
Definition: hal_i2c.c:113
BaseCompass comp_if
Base compass interface.
Definition: lsm303dlhc.h:667
static size_t acc_get_axes_number(void *ip)
Return the number of axes of the BaseAccelerometer.
Definition: lsm303dlhc.c:104
BaseAccelerometer acc_if
Base accelerometer interface.
Definition: lsm303dlhc.h:665
Structure representing an I2C driver.
Definition: hal_i2c_lld.h:88
#define TIME_INFINITE
Infinite interval specification for all functions with a timeout specification.
Definition: chtime.h:55
LSM303DLHC configuration structure.
Definition: lsm303dlhc.h:538
#define osalDbgCheck(c)
Function parameters check.
Definition: osal.h:278
static msg_t comp_reset_sensivity(void *ip)
Reset sensitivity values for the BaseCompass.
Definition: lsm303dlhc.c:635
static msg_t comp_reset_bias(void *ip)
Reset bias values for the BaseCompass.
Definition: lsm303dlhc.c:576
#define MSG_OK
Normal wakeup message.
Definition: chschd.h:39
#define LSM303DLHC_COMP_NUMBER_OF_AXES
LSM303DLHC compass subsystem characteristics.
Definition: lsm303dlhc.h:94
static msg_t acc_read_raw(void *ip, int32_t axes[])
Retrieves raw data from the BaseAccelerometer.
Definition: lsm303dlhc.c:126
static msg_t acc_set_sensivity(void *ip, float *sp)
Set sensitivity values for the BaseAccelerometer.
Definition: lsm303dlhc.c:273
static msg_t acc_set_full_scale(LSM303DLHCDriver *devp, lsm303dlhc_acc_fs_t fs)
Changes the LSM303DLHCDriver accelerometer fullscale value.
Definition: lsm303dlhc.c:347
const struct LSM303DLHCVMT * vmt
Virtual Methods Table.
Definition: lsm303dlhc.h:663
void lsm303dlhcStart(LSM303DLHCDriver *devp, const LSM303DLHCConfig *config)
Configures and activates LSM303DLHC Complex Driver peripheral.
Definition: lsm303dlhc.c:868
void lsm303dlhcObjectInit(LSM303DLHCDriver *devp)
Initializes an instance.
Definition: lsm303dlhc.c:847
LSM303DLHC 6-axis accelerometer/compass class.
Definition: lsm303dlhc.h:661
lsm303dlhc_acc_fs_t
LSM303DLHC accelerometer subsystem full scale.
Definition: lsm303dlhc.h:413
#define osalDbgAssert(c, remark)
Condition assertion.
Definition: osal.h:258
LSM303DLHC virtual methods table.
Definition: lsm303dlhc.h:628
const I2CConfig * config
Current configuration data.
Definition: hal_i2c_lld.h:96
static size_t comp_get_axes_number(void *ip)
Return the number of axes of the BaseCompass.
Definition: lsm303dlhc.c:437
BaseAccelerometer virtual methods table.
Base accelerometer class.
const struct BaseAccelerometerVMT * vmt
Virtual Methods Table.
lsm303dlhc_comp_fs_t
LSM303DLHC compass subsystem full scale.
Definition: lsm303dlhc.h:489
int32_t msg_t
Definition: chtypes.h:51
#define FALSE
Generic &#39;false&#39; preprocessor boolean constant.
Definition: rt/include/ch.h:77
#define MSG_RESET
Wakeup caused by a reset condition.
Definition: chschd.h:43
static msg_t acc_reset_bias(void *ip)
Reset bias values for the BaseAccelerometer.
Definition: lsm303dlhc.c:243
LSM303DLHC MEMS interface module header.