ChibiOS  0.0.0
l3gd20.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 l3gd20.c
23  * @brief L3GD20 MEMS interface module code.
24  *
25  * @addtogroup L3GD20
26  * @ingroup EX_ST
27  * @{
28  */
29 
30 #include "hal.h"
31 #include "l3gd20.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 (L3GD20_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  *
54  * @param[in] spip pointer to the SPI interface
55  * @param[in] reg starting register address
56  * @param[in] n number of consecutive registers to read
57  * @param[in] b pointer to an output buffer.
58  */
59 static void l3gd20SPIReadRegister(SPIDriver *spip, uint8_t reg, size_t n,
60  uint8_t* b) {
61  uint8_t cmd;
62  (n == 1) ? (cmd = reg | L3GD20_RW) : (cmd = reg | L3GD20_RW | L3GD20_MS);
63  spiSelect(spip);
64  spiSend(spip, 1, &cmd);
65  spiReceive(spip, n, b);
66  spiUnselect(spip);
67 }
68 
69 /**
70  * @brief Writes a value into a generic register using SPI.
71  * @pre The SPI interface must be initialized and the driver started.
72  *
73  * @param[in] spip pointer to the SPI interface
74  * @param[in] reg starting register address
75  * @param[in] n number of adjacent registers to write
76  * @param[in] b pointer to a buffer of values.
77  */
78 static void l3gd20SPIWriteRegister(SPIDriver *spip, uint8_t reg, size_t n,
79  uint8_t* b) {
80  uint8_t cmd;
81  (n == 1) ? (cmd = reg) : (cmd = reg | L3GD20_MS);
82  spiSelect(spip);
83  spiSend(spip, 1, &cmd);
84  spiSend(spip, n, b);
85  spiUnselect(spip);
86 }
87 #endif /* L3GD20_USE_SPI */
88 
89 /**
90  * @brief Return the number of axes of the BaseGyroscope.
91  *
92  * @param[in] ip pointer to @p BaseGyroscope interface.
93  *
94  * @return the number of axes.
95  */
96 static size_t gyro_get_axes_number(void *ip) {
97  (void)ip;
98 
100 }
101 
102 /**
103  * @brief Retrieves raw data from the BaseGyroscope.
104  * @note This data is retrieved from MEMS register without any algebraical
105  * manipulation.
106  * @note The axes array must be at least the same size of the
107  * BaseGyroscope axes number.
108  *
109  * @param[in] ip pointer to @p BaseGyroscope interface.
110  * @param[out] axes a buffer which would be filled with raw data.
111  *
112  * @return The operation status.
113  * @retval MSG_OK if the function succeeded.
114  */
115 static msg_t gyro_read_raw(void *ip, int32_t axes[L3GD20_GYRO_NUMBER_OF_AXES]) {
116  L3GD20Driver* devp;
117  int16_t tmp;
118  uint8_t i, buff [2 * L3GD20_GYRO_NUMBER_OF_AXES];
119  msg_t msg = MSG_OK;
120 
121  osalDbgCheck((ip != NULL) && (axes != NULL));
122 
123  /* Getting parent instance pointer.*/
125 
126  osalDbgAssert((devp->state == L3GD20_READY),
127  "gyro_read_raw(), invalid state");
128 #if L3GD20_USE_SPI
129  osalDbgAssert((devp->config->spip->state == SPI_READY),
130  "gyro_read_raw(), channel not ready");
131 
132 #if L3GD20_SHARED_SPI
133  spiAcquireBus(devp->config->spip);
134  spiStart(devp->config->spip,
135  devp->config->spicfg);
136 #endif /* L3GD20_SHARED_SPI */
137 
138  l3gd20SPIReadRegister(devp->config->spip, L3GD20_AD_OUT_X_L,
139  L3GD20_GYRO_NUMBER_OF_AXES * 2, buff);
140 
141 #if L3GD20_SHARED_SPI
142  spiReleaseBus(devp->config->spip);
143 #endif /* L3GD20_SHARED_SPI */
144 #endif /* L3GD20_USE_SPI */
145 
146  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++) {
147  tmp = buff[2 * i] + (buff[2 * i + 1] << 8);
148  axes[i] = (int32_t)tmp;
149  }
150  return msg;
151 }
152 
153 /**
154  * @brief Retrieves cooked data from the BaseGyroscope.
155  * @note This data is manipulated according to the formula
156  * cooked = (raw * sensitivity) - bias.
157  * @note Final data is expressed as DPS.
158  * @note The axes array must be at least the same size of the
159  * BaseGyroscope axes number.
160  *
161  * @param[in] ip pointer to @p BaseGyroscope interface.
162  * @param[out] axes a buffer which would be filled with cooked data.
163  *
164  * @return The operation status.
165  * @retval MSG_OK if the function succeeded.
166  */
167 static msg_t gyro_read_cooked(void *ip, float axes[]) {
168  L3GD20Driver* devp;
169  uint32_t i;
170  int32_t raw[L3GD20_GYRO_NUMBER_OF_AXES];
171  msg_t msg;
172 
173  osalDbgCheck((ip != NULL) && (axes != NULL));
174 
175  /* Getting parent instance pointer.*/
177 
178  osalDbgAssert((devp->state == L3GD20_READY),
179  "gyro_read_cooked(), invalid state");
180 
181  msg = gyro_read_raw(ip, raw);
182  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++){
183  axes[i] = (raw[i] * devp->gyrosensitivity[i]) - devp->gyrobias[i];
184  }
185  return msg;
186 }
187 
188 /**
189  * @brief Samples bias values for the BaseGyroscope.
190  * @note The L3GD20 shall not be moved during the whole procedure.
191  * @note After this function internal bias is automatically updated.
192  * @note The behavior of this function depends on @p L3GD20_BIAS_ACQ_TIMES
193  * and @p L3GD20_BIAS_SETTLING_US.
194  *
195  * @param[in] ip pointer to @p BaseGyroscope interface.
196  *
197  * @return The operation status.
198  * @retval MSG_OK if the function succeeded.
199  */
200 static msg_t gyro_sample_bias(void *ip) {
201  L3GD20Driver* devp;
202  uint32_t i, j;
203  int32_t raw[L3GD20_GYRO_NUMBER_OF_AXES];
204  int32_t buff[L3GD20_GYRO_NUMBER_OF_AXES] = {0, 0, 0};
205  msg_t msg;
206 
207  osalDbgCheck(ip != NULL);
208 
209  /* Getting parent instance pointer.*/
211 
212  osalDbgAssert((devp->state == L3GD20_READY),
213  "gyro_sample_bias(), invalid state");
214 #if L3GD20_USE_SPI
215  osalDbgAssert((devp->config->spip->state == SPI_READY),
216  "gyro_sample_bias(), channel not ready");
217 #endif
218 
219  for(i = 0; i < L3GD20_BIAS_ACQ_TIMES; i++){
220  msg = gyro_read_raw(ip, raw);
221  if(msg != MSG_OK)
222  return msg;
223  for(j = 0; j < L3GD20_GYRO_NUMBER_OF_AXES; j++){
224  buff[j] += raw[j];
225  }
227  }
228 
229  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++){
230  devp->gyrobias[i] = (buff[i] / L3GD20_BIAS_ACQ_TIMES);
231  devp->gyrobias[i] *= devp->gyrosensitivity[i];
232  }
233  return msg;
234 }
235 
236 /**
237  * @brief Set bias values for the BaseGyroscope.
238  * @note Bias must be expressed as DPS.
239  * @note The bias buffer must be at least the same size of the BaseGyroscope
240  * axes number.
241  *
242  * @param[in] ip pointer to @p BaseGyroscope interface.
243  * @param[in] bp a buffer which contains biases.
244  *
245  * @return The operation status.
246  * @retval MSG_OK if the function succeeded.
247  */
248 static msg_t gyro_set_bias(void *ip, float *bp) {
249  L3GD20Driver* devp;
250  uint32_t i;
251  msg_t msg = MSG_OK;
252 
253  osalDbgCheck((ip != NULL) && (bp != NULL));
254 
255  /* Getting parent instance pointer.*/
257 
258  osalDbgAssert((devp->state == L3GD20_READY),
259  "gyro_set_bias(), invalid state");
260 
261  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++) {
262  devp->gyrobias[i] = bp[i];
263  }
264  return msg;
265 }
266 
267 /**
268  * @brief Reset bias values for the BaseGyroscope.
269  * @note Default biases value are obtained from device datasheet when
270  * available otherwise they are considered zero.
271  *
272  * @param[in] ip pointer to @p BaseGyroscope interface.
273  *
274  * @return The operation status.
275  * @retval MSG_OK if the function succeeded.
276  */
277 static msg_t gyro_reset_bias(void *ip) {
278  L3GD20Driver* devp;
279  uint32_t i;
280  msg_t msg = MSG_OK;
281 
282  osalDbgCheck(ip != NULL);
283 
284  /* Getting parent instance pointer.*/
286 
287  osalDbgAssert((devp->state == L3GD20_READY),
288  "gyro_reset_bias(), invalid state");
289 
290  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++)
291  devp->gyrobias[i] = L3GD20_GYRO_BIAS;
292  return msg;
293 }
294 
295 /**
296  * @brief Set sensitivity values for the BaseGyroscope.
297  * @note Sensitivity must be expressed as DPS/LSB.
298  * @note The sensitivity buffer must be at least the same size of the
299  * BaseGyroscope axes number.
300  *
301  * @param[in] ip pointer to @p BaseGyroscope interface.
302  * @param[in] sp a buffer which contains sensitivities.
303  *
304  * @return The operation status.
305  * @retval MSG_OK if the function succeeded.
306  */
307 static msg_t gyro_set_sensivity(void *ip, float *sp) {
308  L3GD20Driver* devp;
309  uint32_t i;
310  msg_t msg = MSG_OK;
311 
312  osalDbgCheck((ip != NULL) && (sp !=NULL));
313 
314  /* Getting parent instance pointer.*/
316 
317  osalDbgAssert((devp->state == L3GD20_READY),
318  "gyro_set_sensivity(), invalid state");
319 
320  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++) {
321  devp->gyrosensitivity[i] = sp[i];
322  }
323  return msg;
324 }
325 
326 /**
327  * @brief Reset sensitivity values for the BaseGyroscope.
328  * @note Default sensitivities value are obtained from device datasheet.
329  *
330  * @param[in] ip pointer to @p BaseGyroscope interface.
331  *
332  * @return The operation status.
333  * @retval MSG_OK if the function succeeded.
334  * @retval MSG_RESET otherwise.
335  */
336 static msg_t gyro_reset_sensivity(void *ip) {
337  L3GD20Driver* devp;
338  uint32_t i;
339  msg_t msg = MSG_OK;
340 
341  osalDbgCheck(ip != NULL);
342 
343  /* Getting parent instance pointer.*/
345 
346  osalDbgAssert((devp->state == L3GD20_READY),
347  "gyro_reset_sensivity(), invalid state");
348 
349  if(devp->config->gyrofullscale == L3GD20_FS_250DPS)
350  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++)
351  devp->gyrosensitivity[i] = L3GD20_GYRO_SENS_250DPS;
352  else if(devp->config->gyrofullscale == L3GD20_FS_500DPS)
353  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++)
354  devp->gyrosensitivity[i] = L3GD20_GYRO_SENS_500DPS;
355  else if(devp->config->gyrofullscale == L3GD20_FS_2000DPS)
356  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++)
357  devp->gyrosensitivity[i] = L3GD20_GYRO_SENS_2000DPS;
358  else {
359  osalDbgAssert(FALSE, "gyro_reset_sensivity(), full scale issue");
360  return MSG_RESET;
361  }
362  return msg;
363 }
364 
365 /**
366  * @brief Changes the L3GD20Driver gyroscope fullscale value.
367  * @note This function also rescale sensitivities and biases based on
368  * previous and next fullscale value.
369  * @note A recalibration is highly suggested after calling this function.
370  *
371  * @param[in] devp pointer to @p BaseGyroscope interface.
372  * @param[in] fs new fullscale value.
373  *
374  * @return The operation status.
375  * @retval MSG_OK if the function succeeded.
376  * @retval MSG_RESET otherwise.
377  */
379  float newfs, scale;
380  uint8_t i, cr;
381  msg_t msg = MSG_OK;
382 
383  osalDbgCheck(devp != NULL);
384 
385  osalDbgAssert((devp->state == L3GD20_READY),
386  "gyro_set_full_scale(), invalid state");
387 #if L3GD20_USE_SPI
388  osalDbgAssert((devp->config->spip->state == SPI_READY),
389  "gyro_set_full_scale(), channel not ready");
390 #endif
391 
392  if(fs == L3GD20_FS_250DPS) {
393  newfs = L3GD20_250DPS;
394  }
395  else if(fs == L3GD20_FS_500DPS) {
396  newfs = L3GD20_500DPS;
397  }
398  else if(fs == L3GD20_FS_2000DPS) {
399  newfs = L3GD20_2000DPS;
400  }
401  else {
402  return MSG_RESET;
403  }
404 
405  if(newfs != devp->gyrofullscale) {
406  scale = newfs / devp->gyrofullscale;
407  devp->gyrofullscale = newfs;
408 
409 #if L3GD20_USE_SPI
410 #if L3GD20_SHARED_SPI
411  spiAcquireBus(devp->config->spip);
412  spiStart(devp->config->spip,
413  devp->config->spicfg);
414 #endif /* L3GD20_SHARED_SPI */
415 
416  /* Updating register.*/
417  l3gd20SPIReadRegister(devp->config->spip,
418  L3GD20_AD_CTRL_REG4, 1, &cr);
419 
420 #if L3GD20_SHARED_SPI
421  spiReleaseBus(devp->config->spip);
422 #endif /* L3GD20_SHARED_SPI */
423 #endif /* L3GD20_USE_SPI */
424  cr &= ~(L3GD20_CTRL_REG4_FS_MASK);
425  cr |= fs;
426 
427 #if L3GD20_USE_SPI
428 #if L3GD20_SHARED_SPI
429  spiAcquireBus(devp->config->spip);
430  spiStart(devp->config->spip,
431  devp->config->spicfg);
432 #endif /* L3GD20_SHARED_SPI */
433 
434  l3gd20SPIWriteRegister(devp->config->spip,
435  L3GD20_AD_CTRL_REG4, 1, &cr);
436 #if L3GD20_SHARED_SPI
437  spiReleaseBus(devp->config->spip);
438 #endif /* L3GD20_SHARED_SPI */
439 #endif /* L3GD20_USE_SPI */
440 
441  /* Scaling sensitivity and bias. Re-calibration is suggested anyway. */
442  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++) {
443  devp->gyrosensitivity[i] *= scale;
444  devp->gyrobias[i] *= scale;
445  }
446  }
447  return msg;
448 }
449 
450 static const struct L3GD20VMT vmt_device = {
451  (size_t)0,
453 };
454 
455 static const struct BaseGyroscopeVMT vmt_gyroscope = {
456  sizeof(struct L3GD20VMT*),
460 };
461 
462 /*===========================================================================*/
463 /* Driver exported functions. */
464 /*===========================================================================*/
465 
466 /**
467  * @brief Initializes an instance.
468  *
469  * @param[out] devp pointer to the @p L3GD20Driver object
470  *
471  * @init
472  */
474  devp->vmt = &vmt_device;
475  devp->gyro_if.vmt = &vmt_gyroscope;
476 
477  devp->config = NULL;
478 
479  devp->state = L3GD20_STOP;
480 }
481 
482 /**
483  * @brief Configures and activates L3GD20 Complex Driver peripheral.
484  *
485  * @param[in] devp pointer to the @p L3GD20Driver object
486  * @param[in] config pointer to the @p L3GD20Config object
487  *
488  * @api
489  */
490 void l3gd20Start(L3GD20Driver *devp, const L3GD20Config *config) {
491  uint32_t i;
492  uint8_t cr[5] = {0, 0, 0, 0, 0};
493  osalDbgCheck((devp != NULL) && (config != NULL));
494 
495  osalDbgAssert((devp->state == L3GD20_STOP) || (devp->state == L3GD20_READY),
496  "l3gd20Start(), invalid state");
497 
498  devp->config = config;
499 
500  /* Control register 1 configuration block.*/
501  {
502  cr[0] = L3GD20_CTRL_REG1_XEN | L3GD20_CTRL_REG1_YEN |
503  L3GD20_CTRL_REG1_ZEN | L3GD20_CTRL_REG1_PD |
504  devp->config->gyrooutputdatarate;
505 #if L3GD20_GYRO_USE_ADVANCED || defined(__DOXYGEN__)
506  cr[0] |= devp->config->gyrobandwidth;
507 #endif
508  }
509 
510  /* Control register 2 configuration block.*/
511  {
512 #if L3GD20_GYRO_USE_ADVANCED || defined(__DOXYGEN__)
513  if(devp->config->gyrohpmode != L3GD20_HPM_BYPASSED)
514  cr[1] = devp->config->gyrohpmode | devp->config->gyrohpconfiguration;
515 #endif
516  }
517 
518  /* Control register 4 configuration block.*/
519  {
520  cr[3] = devp->config->gyrofullscale;
521 #if L3GD20_GYRO_USE_ADVANCED || defined(__DOXYGEN__)
522  cr[3] |= devp->config->gyroblockdataupdate |
523  devp->config->gyroendianness;
524 #endif
525  }
526 
527  /* Control register 5 configuration block.*/
528  {
529 #if L3GD20_GYRO_USE_ADVANCED || defined(__DOXYGEN__)
530  if((devp->config->gyrohpmode != L3GD20_HPM_BYPASSED)) {
531  cr[4] = L3GD20_CTRL_REG5_HPEN;
532  if(devp->config->gyrolp2mode != L3GD20_LP2M_BYPASSED) {
533  cr[4] |= L3GD20_CTRL_REG5_INT1_SEL1 |
534  L3GD20_CTRL_REG5_OUT_SEL1;
535  }
536  else {
537  cr[4] |= L3GD20_CTRL_REG5_INT1_SEL0 |
538  L3GD20_CTRL_REG5_OUT_SEL0;
539  }
540  }
541 #endif
542  }
543 
544 #if L3GD20_USE_SPI
545 #if L3GD20_SHARED_SPI
546  spiAcquireBus(devp->config->spip);
547 #endif /* L3GD20_SHARED_SPI */
548  spiStart(devp->config->spip,
549  devp->config->spicfg);
550 
551  l3gd20SPIWriteRegister(devp->config->spip, L3GD20_AD_CTRL_REG1,
552  5, cr);
553 #if L3GD20_SHARED_SPI
554  spiReleaseBus(devp->config->spip);
555 #endif /* L3GD20_SHARED_SPI */
556 #endif /* L3GD20_USE_SPI */
557 
558  /* Storing sensitivity information according to full scale.*/
559  if(devp->config->gyrofullscale == L3GD20_FS_250DPS) {
560  devp->gyrofullscale = L3GD20_250DPS;
561  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++) {
562  if (devp->config->gyrosensitivity == NULL)
563  devp->gyrosensitivity[i] = L3GD20_GYRO_SENS_250DPS;
564  else
565  devp->gyrosensitivity[i] = devp->config->gyrosensitivity[i];
566  }
567  }
568  else if(devp->config->gyrofullscale == L3GD20_FS_500DPS) {
569  devp->gyrofullscale = L3GD20_500DPS;
570  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++) {
571  if (devp->config->gyrosensitivity == NULL)
572  devp->gyrosensitivity[i] = L3GD20_GYRO_SENS_500DPS;
573  else
574  devp->gyrosensitivity[i] = devp->config->gyrosensitivity[i];
575  }
576  }
577  else if(devp->config->gyrofullscale == L3GD20_FS_2000DPS) {
578  devp->gyrofullscale = L3GD20_2000DPS;
579  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++) {
580  if (devp->config->gyrosensitivity == NULL)
581  devp->gyrosensitivity[i] = L3GD20_GYRO_SENS_2000DPS;
582  else
583  devp->gyrosensitivity[i] = devp->config->gyrosensitivity[i];
584  }
585  }
586  else
587  osalDbgAssert(FALSE, "l3gd20Start(), full scale issue");
588 
589  /* Storing bias information.*/
590  if(devp->config->gyrobias != NULL) {
591  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++) {
592  devp->gyrobias[i] = devp->config->gyrobias[i];
593  }
594  }
595  else {
596  for(i = 0; i < L3GD20_GYRO_NUMBER_OF_AXES; i++)
597  devp->gyrobias[i] = L3GD20_GYRO_BIAS;
598  }
599 
600  /* This is the Gyroscope transient recovery time.*/
602 
603  devp->state = L3GD20_READY;
604 }
605 
606 /**
607  * @brief Deactivates the L3GD20 Complex Driver peripheral.
608  *
609  * @param[in] devp pointer to the @p L3GD20Driver object
610  *
611  * @api
612  */
614  uint8_t cr1;
615  osalDbgCheck(devp != NULL);
616 
617  osalDbgAssert((devp->state == L3GD20_STOP) || (devp->state == L3GD20_READY),
618  "l3gd20Stop(), invalid state");
619 
620  if (devp->state == L3GD20_READY) {
621  /* Disabling all axes and enabling power down mode.*/
622  cr1 = 0;
623 
624 #if L3GD20_USE_SPI
625 #if L3GD20_SHARED_SPI
626  spiAcquireBus(devp->config->spip);
627  spiStart(devp->config->spip,
628  devp->config->spicfg);
629 #endif /* L3GD20_SHARED_SPI */
630 
631  l3gd20SPIWriteRegister(devp->config->spip, L3GD20_AD_CTRL_REG1,
632  1, &cr1);
633  spiStop(devp->config->spip);
634 
635 #if L3GD20_SHARED_SPI
636  spiReleaseBus(devp->config->spip);
637 #endif /* L3GD20_SHARED_SPI */
638 #endif /* L3GD20_USE_SPI */
639  }
640  devp->state = L3GD20_STOP;
641 }
642 /** @} */
void l3gd20ObjectInit(L3GD20Driver *devp)
Initializes an instance.
Definition: l3gd20.c:473
void spiUnselect(SPIDriver *spip)
Deasserts the slave select signal.
Definition: hal_spi.c:154
#define L3GD20_BIAS_SETTLING_US
Settling time for bias removal.
Definition: l3gd20.h:297
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
#define osalThreadSleepMicroseconds(usecs)
Delays the invoking thread for the specified number of microseconds.
Definition: osal.h:464
static msg_t gyro_set_full_scale(L3GD20Driver *devp, l3gd20_fs_t fs)
Changes the L3GD20Driver gyroscope fullscale value.
Definition: l3gd20.c:378
void spiStart(SPIDriver *spip, const SPIConfig *config)
Configures and activates the SPI peripheral.
Definition: hal_spi.c:91
L3GD20 MEMS interface module header.
HAL subsystem header.
L3GD20 virtual methods table.
Definition: l3gd20.h:523
BaseGyroscope virtual methods table.
Definition: hal_gyroscope.h:72
void spiReleaseBus(SPIDriver *spip)
Releases exclusive access to the SPI bus.
Definition: hal_spi.c:461
static size_t gyro_get_axes_number(void *ip)
Return the number of axes of the BaseGyroscope.
Definition: l3gd20.c:96
Base gyroscope class.
Definition: hal_gyroscope.h:88
BaseGyroscope gyro_if
Base gyroscope interface.
Definition: l3gd20.h:552
void l3gd20Start(L3GD20Driver *devp, const L3GD20Config *config)
Configures and activates L3GD20 Complex Driver peripheral.
Definition: l3gd20.c:490
L3GD20 3-axis gyroscope class.
Definition: l3gd20.h:548
#define objGetInstance(type, ip)
Returns the instance pointer starting from an interface pointer.
Definition: hal_objects.h:80
void spiAcquireBus(SPIDriver *spip)
Gains exclusive access to the SPI bus.
Definition: hal_spi.c:445
#define L3GD20_BIAS_ACQ_TIMES
Number of acquisitions for bias removal.
Definition: l3gd20.h:289
const struct L3GD20VMT * vmt
Virtual Methods Table.
Definition: l3gd20.h:550
static msg_t gyro_read_raw(void *ip, int32_t axes[L3GD20_GYRO_NUMBER_OF_AXES])
Retrieves raw data from the BaseGyroscope.
Definition: l3gd20.c:115
#define osalThreadSleepMilliseconds(msecs)
Delays the invoking thread for the specified number of milliseconds.
Definition: osal.h:451
l3gd20_fs_t
L3GD20 full scale.
Definition: l3gd20.h:348
static void l3gd20SPIReadRegister(SPIDriver *spip, uint8_t reg, size_t n, uint8_t *b)
Reads a generic register value using SPI.
Definition: l3gd20.c:59
const struct BaseGyroscopeVMT * vmt
Virtual Methods Table.
Definition: hal_gyroscope.h:90
static void l3gd20SPIWriteRegister(SPIDriver *spip, uint8_t reg, size_t n, uint8_t *b)
Writes a value into a generic register using SPI.
Definition: l3gd20.c:78
static msg_t gyro_sample_bias(void *ip)
Samples bias values for the BaseGyroscope.
Definition: l3gd20.c:200
static msg_t gyro_set_bias(void *ip, float *bp)
Set bias values for the BaseGyroscope.
Definition: l3gd20.c:248
static msg_t gyro_read_cooked(void *ip, float axes[])
Retrieves cooked data from the BaseGyroscope.
Definition: l3gd20.c:167
#define osalDbgCheck(c)
Function parameters check.
Definition: osal.h:278
static msg_t gyro_reset_sensivity(void *ip)
Reset sensitivity values for the BaseGyroscope.
Definition: l3gd20.c:336
#define MSG_OK
Normal wakeup message.
Definition: chschd.h:39
#define L3GD20_GYRO_NUMBER_OF_AXES
L3GD20 gyroscope system characteristics.
Definition: l3gd20.h:71
L3GD20 configuration structure.
Definition: l3gd20.h:437
void spiSend(SPIDriver *spip, size_t n, const void *txbuf)
Sends data over the SPI bus.
Definition: hal_spi.c:388
#define osalDbgAssert(c, remark)
Condition assertion.
Definition: osal.h:258
static msg_t gyro_set_sensivity(void *ip, float *sp)
Set sensitivity values for the BaseGyroscope.
Definition: l3gd20.c:307
static msg_t gyro_reset_bias(void *ip)
Reset bias values for the BaseGyroscope.
Definition: l3gd20.c:277
void l3gd20Stop(L3GD20Driver *devp)
Deactivates the L3GD20 Complex Driver peripheral.
Definition: l3gd20.c:613
void spiStop(SPIDriver *spip)
Deactivates the SPI peripheral.
Definition: hal_spi.c:113
Structure representing an SPI driver.
Definition: hal_spi_lld.h:128
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