ChibiOS  0.0.0
lis3dsh.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 lis3dsh.c
23  * @brief LIS3DSH MEMS interface module code.
24  *
25  * @addtogroup LIS3DSH
26  * @ingroup EX_ST
27  * @{
28  */
29 
30 #include "hal.h"
31 #include "lis3dsh.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 /* Driver local functions. */
47 /*===========================================================================*/
48 
49 #if (LIS3DSH_USE_SPI) || defined(__DOXYGEN__)
50 /**
51  * @brief Reads a generic register value using SPI.
52  * @pre The SPI interface must be initialized and the driver started.
53  * @note Multiple write/read requires proper settings in CTRL_REG6.
54  *
55  * @param[in] spip pointer to the SPI interface
56  * @param[in] reg starting register address
57  * @param[in] n number of adjacent registers to write
58  * @param[in] b pointer to a buffer.
59  */
60 static void lis3dshSPIReadRegister(SPIDriver *spip, uint8_t reg, size_t n,
61  uint8_t* b) {
62  uint8_t cmd;
63  cmd = reg | LIS3DSH_RW;
64  spiSelect(spip);
65  spiSend(spip, 1, &cmd);
66  spiReceive(spip, n, b);
67  spiUnselect(spip);
68 }
69 
70 /**
71  * @brief Writes a value into a generic register using SPI.
72  * @pre The SPI interface must be initialized and the driver started.
73  * @note Multiple write/read requires proper settings in CTRL_REG6.
74  *
75  * @param[in] spip pointer to the SPI interface
76  * @param[in] reg starting register address
77  * @param[in] n number of adjacent registers to write
78  * @param[in] b pointer to a buffer of values.
79  */
80 static void lis3dshSPIWriteRegister(SPIDriver *spip, uint8_t reg, size_t n,
81  uint8_t* b) {
82  uint8_t cmd;
83  cmd = reg;
84  spiSelect(spip);
85  spiSend(spip, 1, &cmd);
86  spiSend(spip, n, b);
87  spiUnselect(spip);
88 }
89 #endif /* LIS3DSH_USE_SPI */
90 
91 /**
92  * @brief Return the number of axes of the BaseAccelerometer.
93  *
94  * @param[in] ip pointer to @p BaseAccelerometer interface.
95  *
96  * @return the number of axes.
97  */
98 static size_t acc_get_axes_number(void *ip) {
99  (void)ip;
100 
102 }
103 
104 /**
105  * @brief Retrieves raw data from the BaseAccelerometer.
106  * @note This data is retrieved from MEMS register without any algebraical
107  * manipulation.
108  * @note The axes array must be at least the same size of the
109  * BaseAccelerometer axes number.
110  *
111  * @param[in] ip pointer to @p BaseAccelerometer interface.
112  * @param[out] axes a buffer which would be filled with raw data.
113  *
114  * @return The operation status.
115  * @retval MSG_OK if the function succeeded.
116  * @retval MSG_RESET if one or more I2C errors occurred, the errors can
117  * be retrieved using @p i2cGetErrors().
118  * @retval MSG_TIMEOUT if a timeout occurred before operation end.
119  */
120 static msg_t acc_read_raw(void *ip, int32_t axes[]) {
121  LIS3DSHDriver* devp;
122  uint8_t buff [LIS3DSH_ACC_NUMBER_OF_AXES * 2], i;
123  int16_t tmp;
124  msg_t msg = MSG_OK;
125 
126  osalDbgCheck((ip != NULL) && (axes != NULL));
127 
128  /* Getting parent instance pointer.*/
130 
131  osalDbgAssert((devp->state == LIS3DSH_READY),
132  "acc_read_raw(), invalid state");
133 
134 #if LIS3DSH_USE_SPI
135 #if LIS3DSH_SHARED_SPI
136  osalDbgAssert((devp->config->spip->state == SPI_READY),
137  "acc_read_raw(), channel not ready");
138 
139  spiAcquireBus(devp->config->spip);
140  spiStart(devp->config->spip,
141  devp->config->spicfg);
142 #endif /* LIS3DSH_SHARED_SPI */
143 
144  lis3dshSPIReadRegister(devp->config->spip, LIS3DSH_AD_OUT_X_L,
145  LIS3DSH_ACC_NUMBER_OF_AXES * 2, buff);
146 
147 #if LIS3DSH_SHARED_SPI
148  spiReleaseBus(devp->config->spip);
149 #endif /* LIS3DSH_SHARED_SPI */
150 #endif /* LIS3DSH_USE_SPI */
151 
152  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
153  tmp = buff[2 * i] + (buff[2 * i + 1] << 8);
154  axes[i] = (int32_t)tmp;
155  }
156  return msg;
157 }
158 
159 /**
160  * @brief Retrieves cooked data from the BaseAccelerometer.
161  * @note This data is manipulated according to the formula
162  * cooked = (raw * sensitivity) - bias.
163  * @note Final data is expressed as milli-G.
164  * @note The axes array must be at least the same size of the
165  * BaseAccelerometer axes number.
166  *
167  * @param[in] ip pointer to @p BaseAccelerometer interface.
168  * @param[out] axes a buffer which would be filled with cooked data.
169  *
170  * @return The operation status.
171  * @retval MSG_OK if the function succeeded.
172  * @retval MSG_RESET if one or more I2C errors occurred, the errors can
173  * be retrieved using @p i2cGetErrors().
174  * @retval MSG_TIMEOUT if a timeout occurred before operation end.
175  */
176 static msg_t acc_read_cooked(void *ip, float axes[]) {
177  LIS3DSHDriver* devp;
178  uint32_t i;
179  int32_t raw[LIS3DSH_ACC_NUMBER_OF_AXES];
180  msg_t msg;
181 
182  osalDbgCheck((ip != NULL) && (axes != NULL));
183 
184  /* Getting parent instance pointer.*/
186 
187  osalDbgAssert((devp->state == LIS3DSH_READY),
188  "acc_read_cooked(), invalid state");
189 
190  msg = acc_read_raw(ip, raw);
191  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
192  axes[i] = (raw[i] * devp->accsensitivity[i]) - devp->accbias[i];
193  }
194  return msg;
195 }
196 
197 /**
198  * @brief Set bias values for the BaseAccelerometer.
199  * @note Bias must be expressed as milli-G.
200  * @note The bias buffer must be at least the same size of the
201  * BaseAccelerometer axes number.
202  *
203  * @param[in] ip pointer to @p BaseAccelerometer interface.
204  * @param[in] bp a buffer which contains biases.
205  *
206  * @return The operation status.
207  * @retval MSG_OK if the function succeeded.
208  */
209 static msg_t acc_set_bias(void *ip, float *bp) {
210  LIS3DSHDriver* devp;
211  uint32_t i;
212  msg_t msg = MSG_OK;
213 
214  osalDbgCheck((ip != NULL) && (bp != NULL));
215 
216  /* Getting parent instance pointer.*/
218 
219  osalDbgAssert((devp->state == LIS3DSH_READY),
220  "acc_set_bias(), invalid state");
221 
222  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
223  devp->accbias[i] = bp[i];
224  }
225  return msg;
226 }
227 
228 /**
229  * @brief Reset bias values for the BaseAccelerometer.
230  * @note Default biases value are obtained from device datasheet when
231  * available otherwise they are considered zero.
232  *
233  * @param[in] ip pointer to @p BaseAccelerometer interface.
234  *
235  * @return The operation status.
236  * @retval MSG_OK if the function succeeded.
237  */
238 static msg_t acc_reset_bias(void *ip) {
239  LIS3DSHDriver* devp;
240  uint32_t i;
241  msg_t msg = MSG_OK;
242 
243  osalDbgCheck(ip != NULL);
244 
245  /* Getting parent instance pointer.*/
247 
248  osalDbgAssert((devp->state == LIS3DSH_READY),
249  "acc_reset_bias(), invalid state");
250 
251  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
252  devp->accbias[i] = LIS3DSH_ACC_BIAS;
253  return msg;
254 }
255 
256 /**
257  * @brief Set sensitivity values for the BaseAccelerometer.
258  * @note Sensitivity must be expressed as milli-G/LSB.
259  * @note The sensitivity buffer must be at least the same size of the
260  * BaseAccelerometer axes number.
261  *
262  * @param[in] ip pointer to @p BaseAccelerometer interface.
263  * @param[in] sp a buffer which contains sensitivities.
264  *
265  * @return The operation status.
266  * @retval MSG_OK if the function succeeded.
267  */
268 static msg_t acc_set_sensivity(void *ip, float *sp) {
269  LIS3DSHDriver* devp;
270  uint32_t i;
271  msg_t msg = MSG_OK;
272 
273  /* Getting parent instance pointer.*/
275 
276  osalDbgCheck((ip != NULL) && (sp != NULL));
277 
278  osalDbgAssert((devp->state == LIS3DSH_READY),
279  "acc_set_sensivity(), invalid state");
280 
281  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
282  devp->accsensitivity[i] = sp[i];
283  }
284  return msg;
285 }
286 
287 /**
288  * @brief Reset sensitivity values for the BaseAccelerometer.
289  * @note Default sensitivities value are obtained from device datasheet.
290  *
291  * @param[in] ip pointer to @p BaseAccelerometer interface.
292  *
293  * @return The operation status.
294  * @retval MSG_OK if the function succeeded.
295  * @retval MSG_RESET otherwise.
296  */
297 static msg_t acc_reset_sensivity(void *ip) {
298  LIS3DSHDriver* devp;
299  uint32_t i;
300  msg_t msg = MSG_OK;
301 
302  osalDbgCheck(ip != NULL);
303 
304  /* Getting parent instance pointer.*/
306 
307  osalDbgAssert((devp->state == LIS3DSH_READY),
308  "acc_reset_sensivity(), invalid state");
309 
310  if(devp->config->accfullscale == LIS3DSH_ACC_FS_2G)
311  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
312  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_2G;
313  else if(devp->config->accfullscale == LIS3DSH_ACC_FS_4G)
314  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
315  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_4G;
316  else if(devp->config->accfullscale == LIS3DSH_ACC_FS_6G)
317  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
318  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_6G;
319  else if(devp->config->accfullscale == LIS3DSH_ACC_FS_8G)
320  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
321  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_8G;
322  else if(devp->config->accfullscale == LIS3DSH_ACC_FS_16G)
323  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
324  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_16G;
325  else {
327  "acc_reset_sensivity(), accelerometer full scale issue");
328  return MSG_RESET;
329  }
330  return msg;
331 }
332 
333 /**
334  * @brief Changes the LIS3DSHDriver accelerometer fullscale value.
335  * @note This function also rescale sensitivities and biases based on
336  * previous and next fullscale value.
337  * @note A recalibration is highly suggested after calling this function.
338  *
339  * @param[in] devp pointer to @p LIS3DSHDriver interface.
340  * @param[in] fs new fullscale value.
341  *
342  * @return The operation status.
343  * @retval MSG_OK if the function succeeded.
344  * @retval MSG_RESET otherwise.
345  */
347  float newfs, scale;
348  uint8_t i, cr;
349  msg_t msg;
350 
351  osalDbgCheck(devp != NULL);
352 
353  osalDbgAssert((devp->state == LIS3DSH_READY),
354  "acc_set_full_scale(), invalid state");
355  osalDbgAssert((devp->config->spip->state == SPI_READY),
356  "acc_set_full_scale(), channel not ready");
357 
358  /* Computing new fullscale value.*/
359  if(fs == LIS3DSH_ACC_FS_2G) {
360  newfs = LIS3DSH_ACC_2G;
361  }
362  else if(fs == LIS3DSH_ACC_FS_4G) {
363  newfs = LIS3DSH_ACC_4G;
364  }
365  else if(fs == LIS3DSH_ACC_FS_6G) {
366  newfs = LIS3DSH_ACC_6G;
367  }
368  else if(fs == LIS3DSH_ACC_FS_8G) {
369  newfs = LIS3DSH_ACC_8G;
370  }
371  else if(fs == LIS3DSH_ACC_FS_16G) {
372  newfs = LIS3DSH_ACC_16G;
373  }
374  else {
375  msg = MSG_RESET;
376  return msg;
377  }
378 
379  if(newfs != devp->accfullscale) {
380  /* Computing scale value.*/
381  scale = newfs / devp->accfullscale;
382  devp->accfullscale = newfs;
383 
384 #if LIS3DSH_USE_SPI
385 #if LIS3DSH_SHARED_SPI
386  spiAcquireBus(devp->config->spip);
387  spiStart(devp->config->spip,
388  devp->config->spicfg);
389 #endif /* LIS3DSH_SHARED_SPI */
390 
391  /* Getting data from register.*/
392  lis3dshSPIReadRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG5, 1, &cr);
393 
394 #if LIS3DSH_SHARED_SPI
395  spiReleaseBus(devp->config->spip);
396 #endif /* LIS3DSH_SHARED_SPI */
397 #endif /* LIS3DSH_USE_SPI */
398 
399  cr &= ~(LIS3DSH_CTRL_REG5_FS_MASK);
400  cr |= fs;
401 
402 #if LIS3DSH_USE_SPI
403 #if LIS3DSH_SHARED_SPI
404  spiAcquireBus(devp->config->spip);
405  spiStart(devp->config->spip,
406  devp->config->spicfg);
407 #endif /* LIS3DSH_SHARED_SPI */
408 
409  /* Getting data from register.*/
410  lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG5, 1, &cr);
411 
412 #if LIS3DSH_SHARED_SPI
413  spiReleaseBus(devp->config->spip);
414 #endif /* LIS3DSH_SHARED_SPI */
415 #endif /* LIS3DSH_USE_SPI */
416 
417  /* Scaling sensitivity and bias. Re-calibration is suggested anyway. */
418  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++) {
419  devp->accsensitivity[i] *= scale;
420  devp->accbias[i] *= scale;
421  }
422  }
423  return msg;
424 }
425 
426 static const struct LIS3DSHVMT vmt_device = {
427  (size_t)0,
429 };
430 
431 static const struct BaseAccelerometerVMT vmt_accelerometer = {
432  sizeof(struct LIS3DSHVMT*),
435 };
436 
437 /*===========================================================================*/
438 /* Driver exported functions. */
439 /*===========================================================================*/
440 
441 /**
442  * @brief Initializes an instance.
443  *
444  * @param[out] devp pointer to the @p LIS3DSHDriver object
445  *
446  * @init
447  */
449  devp->vmt = &vmt_device;
450  devp->acc_if.vmt = &vmt_accelerometer;
451 
452  devp->config = NULL;
453 
454  devp->accaxes = LIS3DSH_ACC_NUMBER_OF_AXES;
455 
456  devp->state = LIS3DSH_STOP;
457 }
458 
459 /**
460  * @brief Configures and activates LIS3DSH Complex Driver peripheral.
461  *
462  * @param[in] devp pointer to the @p LIS3DSHDriver object
463  * @param[in] config pointer to the @p LIS3DSHConfig object
464  *
465  * @api
466  */
467 void lis3dshStart(LIS3DSHDriver *devp, const LIS3DSHConfig *config) {
468  uint32_t i;
469  uint8_t cr;
470  osalDbgCheck((devp != NULL) && (config != NULL));
471 
472  osalDbgAssert((devp->state == LIS3DSH_STOP) ||
473  (devp->state == LIS3DSH_READY),
474  "lis3dshStart(), invalid state");
475 
476  devp->config = config;
477 
478  /* Control register 4 configuration block.*/
479  {
480  cr = LIS3DSH_CTRL_REG4_XEN | LIS3DSH_CTRL_REG4_YEN | LIS3DSH_CTRL_REG4_ZEN |
481  devp->config->accoutputdatarate;
482 #if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__)
483  cr |= devp->config->accblockdataupdate;
484 #endif
485  }
486 
487 #if LIS3DSH_USE_SPI
488 #if LIS3DSH_SHARED_SPI
489  spiAcquireBus(devp->config->spip);
490 #endif /* LIS3DSH_SHARED_SPI */
491  spiStart(devp->config->spip, devp->config->spicfg);
492 
493  lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG4, 1, &cr);
494 
495 #if LIS3DSH_SHARED_SPI
496  spiReleaseBus(devp->config->spip);
497 #endif /* LIS3DSH_SHARED_SPI */
498 #endif /* LIS3DSH_USE_SPI */
499 
500  /* Control register 5 configuration block.*/
501  {
502  cr = devp->config->accfullscale;
503 #if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__)
504  cr |= devp->config->accantialiasing;
505 #endif
506  }
507 
508 #if LIS3DSH_USE_SPI
509 #if LIS3DSH_SHARED_SPI
510  spiAcquireBus(devp->config->spip);
511  spiStart(devp->config->spip, devp->config->spicfg);
512 #endif /* LIS3DSH_SHARED_SPI */
513 
514  lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG5, 1, &cr);
515 
516 #if LIS3DSH_SHARED_SPI
517  spiReleaseBus(devp->config->spip);
518 #endif /* LIS3DSH_SHARED_SPI */
519 #endif /* LIS3DSH_USE_SPI */
520 
521  /* Control register 6 configuration block.*/
522  {
523  cr = LIS3DSH_CTRL_REG6_ADD_INC;
524 #if LIS3DSH_USE_ADVANCED || defined(__DOXYGEN__)
525  cr |= devp->config->accblockdataupdate;
526 #endif
527  }
528 
529 #if LIS3DSH_USE_SPI
530 #if LIS3DSH_SHARED_SPI
531  spiAcquireBus(devp->config->spip);
532  spiStart(devp->config->spip, devp->config->spicfg);
533 #endif /* LIS3DSH_SHARED_SPI */
534 
535  lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG6, 1, &cr);
536 
537 #if LIS3DSH_SHARED_SPI
538  spiReleaseBus(devp->config->spip);
539 #endif /* LIS3DSH_SHARED_SPI */
540 #endif /* LIS3DSH_USE_SPI */
541 
542  /* Storing sensitivity information according to user setting */
543  if(devp->config->accfullscale == LIS3DSH_ACC_FS_2G) {
544  devp->accfullscale = LIS3DSH_ACC_2G;
545  if(devp->config->accsensitivity == NULL)
546  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
547  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_2G;
548  else
549  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
550  devp->accsensitivity[i] = devp->config->accsensitivity[i];
551  }
552  else if(devp->config->accfullscale == LIS3DSH_ACC_FS_4G) {
553  devp->accfullscale = LIS3DSH_ACC_4G;
554  if(devp->config->accsensitivity == NULL)
555  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
556  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_4G;
557  else
558  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
559  devp->accsensitivity[i] = devp->config->accsensitivity[i];
560  }
561  else if(devp->config->accfullscale == LIS3DSH_ACC_FS_6G) {
562  devp->accfullscale = LIS3DSH_ACC_6G;
563  if(devp->config->accsensitivity == NULL)
564  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
565  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_6G;
566  else
567  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
568  devp->accsensitivity[i] = devp->config->accsensitivity[i];
569  }
570  else if(devp->config->accfullscale == LIS3DSH_ACC_FS_8G) {
571  devp->accfullscale = LIS3DSH_ACC_8G;
572  if(devp->config->accsensitivity == NULL)
573  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
574  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_8G;
575  else
576  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
577  devp->accsensitivity[i] = devp->config->accsensitivity[i];
578  }
579  else if(devp->config->accfullscale == LIS3DSH_ACC_FS_16G) {
580  devp->accfullscale = LIS3DSH_ACC_16G;
581  if(devp->config->accsensitivity == NULL)
582  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
583  devp->accsensitivity[i] = LIS3DSH_ACC_SENS_16G;
584  else
585  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
586  devp->accsensitivity[i] = devp->config->accsensitivity[i];
587  }
588  else {
589  osalDbgAssert(FALSE, "lis3dshStart(), accelerometer full scale issue");
590  }
591 
592  /* Storing bias information according to user setting */
593  if(devp->config->accbias != NULL)
594  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
595  devp->accbias[i] = devp->config->accbias[i];
596  else
597  for(i = 0; i < LIS3DSH_ACC_NUMBER_OF_AXES; i++)
598  devp->accbias[i] = LIS3DSH_ACC_BIAS;
599 
600  /* This is the Accelerometer transient recovery time */
602 
603  devp->state = LIS3DSH_READY;
604 }
605 
606 /**
607  * @brief Deactivates the LIS3DSH Complex Driver peripheral.
608  *
609  * @param[in] devp pointer to the @p LIS3DSHDriver object
610  *
611  * @api
612  */
614  uint8_t cr4;
615  osalDbgCheck(devp != NULL);
616 
617  osalDbgAssert((devp->state == LIS3DSH_STOP) ||
618  (devp->state == LIS3DSH_READY),
619  "lis3dshStop(), invalid state");
620 
621  if (devp->state == LIS3DSH_READY) {
622 #if (LIS3DSH_USE_SPI)
623 #if LIS3DSH_SHARED_SPI
624  spiAcquireBus(devp->config->spip);
625  spiStart(devp->config->spip,
626  devp->config->spicfg);
627 #endif /* LIS3DSH_SHARED_SPI */
628  /* Disabling all axes and enabling power down mode.*/
629  cr4 = 0;
630  lis3dshSPIWriteRegister(devp->config->spip, LIS3DSH_AD_CTRL_REG4,
631  1, &cr4);
632 
633  spiStop(devp->config->spip);
634 #if LIS3DSH_SHARED_SPI
635  spiReleaseBus(devp->config->spip);
636 #endif /* LIS3DSH_SHARED_SPI */
637 #endif /* LIS3DSH_USE_SPI */
638  }
639  devp->state = LIS3DSH_STOP;
640 }
641 /** @} */
#define LIS3DSH_ACC_NUMBER_OF_AXES
LIS3DSH accelerometer subsystem characteristics.
Definition: lis3dsh.h:72
void spiUnselect(SPIDriver *spip)
Deasserts the slave select signal.
Definition: hal_spi.c:154
const struct LIS3DSHVMT * vmt
Virtual Methods Table.
Definition: lis3dsh.h:544
void spiSelect(SPIDriver *spip)
Asserts the slave select signal and prepares for transfers.
Definition: hal_spi.c:136
void spiReceive(SPIDriver *spip, size_t n, void *rxbuf)
Receives data from the SPI bus.
Definition: hal_spi.c:418
void spiStart(SPIDriver *spip, const SPIConfig *config)
Configures and activates the SPI peripheral.
Definition: hal_spi.c:91
lis3dsh_acc_fs_t
LIS3DSH full scale.
Definition: lis3dsh.h:393
HAL subsystem header.
BaseAccelerometer acc_if
Base accelerometer interface.
Definition: lis3dsh.h:546
void spiReleaseBus(SPIDriver *spip)
Releases exclusive access to the SPI bus.
Definition: hal_spi.c:461
void lis3dshStart(LIS3DSHDriver *devp, const LIS3DSHConfig *config)
Configures and activates LIS3DSH Complex Driver peripheral.
Definition: lis3dsh.c:467
LIS3DSH 3-axis accelerometer class.
Definition: lis3dsh.h:542
#define objGetInstance(type, ip)
Returns the instance pointer starting from an interface pointer.
Definition: hal_objects.h:80
void lis3dshObjectInit(LIS3DSHDriver *devp)
Initializes an instance.
Definition: lis3dsh.c:448
void spiAcquireBus(SPIDriver *spip)
Gains exclusive access to the SPI bus.
Definition: hal_spi.c:445
#define osalThreadSleepMilliseconds(msecs)
Delays the invoking thread for the specified number of milliseconds.
Definition: osal.h:451
static void lis3dshSPIWriteRegister(SPIDriver *spip, uint8_t reg, size_t n, uint8_t *b)
Writes a value into a generic register using SPI.
Definition: lis3dsh.c:80
static msg_t acc_read_cooked(void *ip, float axes[])
Retrieves cooked data from the BaseAccelerometer.
Definition: lis3dsh.c:176
LIS3DSH MEMS interface module header.
#define osalDbgCheck(c)
Function parameters check.
Definition: osal.h:278
#define MSG_OK
Normal wakeup message.
Definition: chschd.h:39
static msg_t acc_set_sensivity(void *ip, float *sp)
Set sensitivity values for the BaseAccelerometer.
Definition: lis3dsh.c:268
static msg_t acc_reset_sensivity(void *ip)
Reset sensitivity values for the BaseAccelerometer.
Definition: lis3dsh.c:297
static void lis3dshSPIReadRegister(SPIDriver *spip, uint8_t reg, size_t n, uint8_t *b)
Reads a generic register value using SPI.
Definition: lis3dsh.c:60
void lis3dshStop(LIS3DSHDriver *devp)
Deactivates the LIS3DSH Complex Driver peripheral.
Definition: lis3dsh.c:613
void spiSend(SPIDriver *spip, size_t n, const void *txbuf)
Sends data over the SPI bus.
Definition: hal_spi.c:388
static msg_t acc_read_raw(void *ip, int32_t axes[])
Retrieves raw data from the BaseAccelerometer.
Definition: lis3dsh.c:120
static size_t acc_get_axes_number(void *ip)
Return the number of axes of the BaseAccelerometer.
Definition: lis3dsh.c:98
LIS3DSH virtual methods table.
Definition: lis3dsh.h:517
#define osalDbgAssert(c, remark)
Condition assertion.
Definition: osal.h:258
static msg_t acc_reset_bias(void *ip)
Reset bias values for the BaseAccelerometer.
Definition: lis3dsh.c:238
static msg_t acc_set_full_scale(LIS3DSHDriver *devp, lis3dsh_acc_fs_t fs)
Changes the LIS3DSHDriver accelerometer fullscale value.
Definition: lis3dsh.c:346
BaseAccelerometer virtual methods table.
Base accelerometer class.
const struct BaseAccelerometerVMT * vmt
Virtual Methods Table.
void spiStop(SPIDriver *spip)
Deactivates the SPI peripheral.
Definition: hal_spi.c:113
LIS3DSH configuration structure.
Definition: lis3dsh.h:447
Structure representing an SPI driver.
Definition: hal_spi_lld.h:128
static msg_t acc_set_bias(void *ip, float *bp)
Set bias values for the BaseAccelerometer.
Definition: lis3dsh.c:209
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