diff options
Diffstat (limited to 'lib/chibios/os/ex/devices/ST/lis3dsh.c')
-rw-r--r-- | lib/chibios/os/ex/devices/ST/lis3dsh.c | 641 |
1 files changed, 641 insertions, 0 deletions
diff --git a/lib/chibios/os/ex/devices/ST/lis3dsh.c b/lib/chibios/os/ex/devices/ST/lis3dsh.c new file mode 100644 index 000000000..f8f34788e --- /dev/null +++ b/lib/chibios/os/ex/devices/ST/lis3dsh.c | |||
@@ -0,0 +1,641 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2016..2019 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 | |||
101 | return LIS3DSH_ACC_NUMBER_OF_AXES; | ||
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.*/ | ||
129 | devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip); | ||
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.*/ | ||
185 | devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip); | ||
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.*/ | ||
217 | devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip); | ||
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.*/ | ||
246 | devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip); | ||
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.*/ | ||
274 | devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip); | ||
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.*/ | ||
305 | devp = objGetInstance(LIS3DSHDriver*, (BaseAccelerometer*)ip); | ||
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 { | ||
326 | osalDbgAssert(FALSE, | ||
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 | */ | ||
346 | static msg_t acc_set_full_scale(LIS3DSHDriver *devp, lis3dsh_acc_fs_t fs) { | ||
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, | ||
428 | acc_set_full_scale | ||
429 | }; | ||
430 | |||
431 | static const struct BaseAccelerometerVMT vmt_accelerometer = { | ||
432 | sizeof(struct LIS3DSHVMT*), | ||
433 | acc_get_axes_number, acc_read_raw, acc_read_cooked, | ||
434 | acc_set_bias, acc_reset_bias, acc_set_sensivity, acc_reset_sensivity | ||
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 | */ | ||
448 | void lis3dshObjectInit(LIS3DSHDriver *devp) { | ||
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 */ | ||
601 | osalThreadSleepMilliseconds(10); | ||
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 | */ | ||
613 | void lis3dshStop(LIS3DSHDriver *devp) { | ||
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 | /** @} */ | ||