diff options
Diffstat (limited to 'lib/chibios/os/ex/devices/ST/lis3mdl.c')
-rw-r--r-- | lib/chibios/os/ex/devices/ST/lis3mdl.c | 627 |
1 files changed, 627 insertions, 0 deletions
diff --git a/lib/chibios/os/ex/devices/ST/lis3mdl.c b/lib/chibios/os/ex/devices/ST/lis3mdl.c new file mode 100644 index 000000000..6f167e929 --- /dev/null +++ b/lib/chibios/os/ex/devices/ST/lis3mdl.c | |||
@@ -0,0 +1,627 @@ | |||
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 lis3mdl.c | ||
23 | * @brief LIS3MDL MEMS interface module code. | ||
24 | * | ||
25 | * @addtogroup LIS3MDL | ||
26 | * @ingroup EX_ST | ||
27 | * @{ | ||
28 | */ | ||
29 | |||
30 | #include "hal.h" | ||
31 | #include "lis3mdl.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 (LIS3MDL_USE_I2C) || defined(__DOXYGEN__) | ||
50 | /** | ||
51 | * @brief Reads registers value using I2C. | ||
52 | * @pre The I2C interface must be initialized and the driver started. | ||
53 | * | ||
54 | * @param[in] i2cp pointer to the I2C interface | ||
55 | * @param[in] sad slave address without R bit | ||
56 | * @param[in] reg first sub-register address | ||
57 | * @param[out] rxbuf pointer to an output buffer | ||
58 | * @param[in] n number of consecutive register to read | ||
59 | * @return the operation status. | ||
60 | * @notapi | ||
61 | */ | ||
62 | msg_t lis3mdlI2CReadRegister(I2CDriver *i2cp, lis3mdl_sad_t sad, uint8_t reg, | ||
63 | uint8_t* rxbuf, size_t n) { | ||
64 | uint8_t txbuf = reg; | ||
65 | if(n > 1) | ||
66 | txbuf |= LIS3MDL_SUB_MS; | ||
67 | |||
68 | return i2cMasterTransmitTimeout(i2cp, sad, &txbuf, 1, rxbuf, n, | ||
69 | TIME_INFINITE); | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * @brief Writes a value into a register using I2C. | ||
74 | * @pre The I2C interface must be initialized and the driver started. | ||
75 | * | ||
76 | * @param[in] i2cp pointer to the I2C interface | ||
77 | * @param[in] sad slave address without R bit | ||
78 | * @param[in] txbuf buffer containing sub-address value in first position | ||
79 | * and values to write | ||
80 | * @param[in] n size of txbuf less one (not considering the first | ||
81 | * element) | ||
82 | * @return the operation status. | ||
83 | * @notapi | ||
84 | */ | ||
85 | msg_t lis3mdlI2CWriteRegister(I2CDriver *i2cp, lis3mdl_sad_t sad, uint8_t* txbuf, | ||
86 | uint8_t n) { | ||
87 | if (n > 1) | ||
88 | (*txbuf) |= LIS3MDL_SUB_MS; | ||
89 | |||
90 | return i2cMasterTransmitTimeout(i2cp, sad, txbuf, n + 1, NULL, 0, | ||
91 | TIME_INFINITE); | ||
92 | } | ||
93 | #endif /* LIS3MDL_USE_I2C */ | ||
94 | |||
95 | /** | ||
96 | * @brief Return the number of axes of the BaseCompass. | ||
97 | * | ||
98 | * @param[in] ip pointer to @p BaseCompass interface | ||
99 | * | ||
100 | * @return the number of axes. | ||
101 | */ | ||
102 | static size_t comp_get_axes_number(void *ip) { | ||
103 | |||
104 | osalDbgCheck(ip != NULL); | ||
105 | return LIS3MDL_COMP_NUMBER_OF_AXES; | ||
106 | } | ||
107 | |||
108 | /** | ||
109 | * @brief Retrieves raw data from the BaseCompass. | ||
110 | * @note This data is retrieved from MEMS register without any algebraical | ||
111 | * manipulation. | ||
112 | * @note The axes array must be at least the same size of the | ||
113 | * BaseCompass axes number. | ||
114 | * | ||
115 | * @param[in] ip pointer to @p BaseCompass interface. | ||
116 | * @param[out] axes a buffer which would be filled with raw data. | ||
117 | * | ||
118 | * @return The operation status. | ||
119 | * @retval MSG_OK if the function succeeded. | ||
120 | * @retval MSG_RESET if one or more I2C errors occurred, the errors can | ||
121 | * be retrieved using @p i2cGetErrors(). | ||
122 | * @retval MSG_TIMEOUT if a timeout occurred before operation end. | ||
123 | */ | ||
124 | static msg_t comp_read_raw(void *ip, int32_t axes[]) { | ||
125 | LIS3MDLDriver* devp; | ||
126 | uint8_t buff [LIS3MDL_COMP_NUMBER_OF_AXES * 2], i; | ||
127 | int16_t tmp; | ||
128 | msg_t msg; | ||
129 | |||
130 | osalDbgCheck((ip != NULL) && (axes != NULL)); | ||
131 | |||
132 | /* Getting parent instance pointer.*/ | ||
133 | devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip); | ||
134 | |||
135 | osalDbgAssert((devp->state == LIS3MDL_READY), | ||
136 | "comp_read_raw(), invalid state"); | ||
137 | osalDbgAssert((devp->config->i2cp->state == I2C_READY), | ||
138 | "comp_read_raw(), channel not ready"); | ||
139 | |||
140 | #if LIS3MDL_SHARED_I2C | ||
141 | i2cAcquireBus(devp->config->i2cp); | ||
142 | i2cStart(devp->config->i2cp, | ||
143 | devp->config->i2ccfg); | ||
144 | #endif /* LIS3MDL_SHARED_I2C */ | ||
145 | msg = lis3mdlI2CReadRegister(devp->config->i2cp, devp->config->slaveaddress, | ||
146 | LIS3MDL_AD_OUT_X_L, buff, | ||
147 | LIS3MDL_COMP_NUMBER_OF_AXES * 2); | ||
148 | |||
149 | #if LIS3MDL_SHARED_I2C | ||
150 | i2cReleaseBus(devp->config->i2cp); | ||
151 | #endif /* LIS3MDL_SHARED_I2C */ | ||
152 | |||
153 | if(msg == MSG_OK) | ||
154 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) { | ||
155 | tmp = buff[2 * i] + (buff[2 * i + 1] << 8); | ||
156 | axes[i] = (int32_t)tmp; | ||
157 | } | ||
158 | return msg; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * @brief Retrieves cooked data from the BaseCompass. | ||
163 | * @note This data is manipulated according to the formula | ||
164 | * cooked = (raw * sensitivity) - bias. | ||
165 | * @note Final data is expressed as G. | ||
166 | * @note The axes array must be at least the same size of the | ||
167 | * BaseCompass axes number. | ||
168 | * | ||
169 | * @param[in] ip pointer to @p BaseCompass interface. | ||
170 | * @param[out] axes a buffer which would be filled with cooked data. | ||
171 | * | ||
172 | * @return The operation status. | ||
173 | * @retval MSG_OK if the function succeeded. | ||
174 | * @retval MSG_RESET if one or more I2C errors occurred, the errors can | ||
175 | * be retrieved using @p i2cGetErrors(). | ||
176 | * @retval MSG_TIMEOUT if a timeout occurred before operation end. | ||
177 | */ | ||
178 | static msg_t comp_read_cooked(void *ip, float axes[]) { | ||
179 | LIS3MDLDriver* devp; | ||
180 | uint32_t i; | ||
181 | int32_t raw[LIS3MDL_COMP_NUMBER_OF_AXES]; | ||
182 | msg_t msg; | ||
183 | |||
184 | osalDbgCheck((ip != NULL) && (axes != NULL)); | ||
185 | |||
186 | |||
187 | /* Getting parent instance pointer.*/ | ||
188 | devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip); | ||
189 | |||
190 | osalDbgAssert((devp->state == LIS3MDL_READY), | ||
191 | "comp_read_cooked(), invalid state"); | ||
192 | |||
193 | msg = comp_read_raw(ip, raw); | ||
194 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES ; i++) { | ||
195 | axes[i] = (raw[i] * devp->compsensitivity[i]) - devp->compbias[i]; | ||
196 | } | ||
197 | return msg; | ||
198 | } | ||
199 | |||
200 | /** | ||
201 | * @brief Set bias values for the BaseCompass. | ||
202 | * @note Bias must be expressed as G. | ||
203 | * @note The bias buffer must be at least the same size of the | ||
204 | * BaseCompass axes number. | ||
205 | * | ||
206 | * @param[in] ip pointer to @p BaseCompass interface. | ||
207 | * @param[in] bp a buffer which contains biases. | ||
208 | * | ||
209 | * @return The operation status. | ||
210 | * @retval MSG_OK if the function succeeded. | ||
211 | */ | ||
212 | static msg_t comp_set_bias(void *ip, float *bp) { | ||
213 | LIS3MDLDriver* devp; | ||
214 | uint32_t i; | ||
215 | msg_t msg = MSG_OK; | ||
216 | |||
217 | osalDbgCheck((ip != NULL) && (bp != NULL)); | ||
218 | |||
219 | /* Getting parent instance pointer.*/ | ||
220 | devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip); | ||
221 | |||
222 | osalDbgAssert((devp->state == LIS3MDL_READY), | ||
223 | "comp_set_bias(), invalid state"); | ||
224 | |||
225 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) { | ||
226 | devp->compbias[i] = bp[i]; | ||
227 | } | ||
228 | return msg; | ||
229 | } | ||
230 | |||
231 | /** | ||
232 | * @brief Reset bias values for the BaseCompass. | ||
233 | * @note Default biases value are obtained from device datasheet when | ||
234 | * available otherwise they are considered zero. | ||
235 | * | ||
236 | * @param[in] ip pointer to @p BaseCompass interface. | ||
237 | * | ||
238 | * @return The operation status. | ||
239 | * @retval MSG_OK if the function succeeded. | ||
240 | */ | ||
241 | static msg_t comp_reset_bias(void *ip) { | ||
242 | LIS3MDLDriver* devp; | ||
243 | uint32_t i; | ||
244 | msg_t msg = MSG_OK; | ||
245 | |||
246 | osalDbgCheck(ip != NULL); | ||
247 | |||
248 | /* Getting parent instance pointer.*/ | ||
249 | devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip); | ||
250 | |||
251 | osalDbgAssert((devp->state == LIS3MDL_READY), | ||
252 | "comp_reset_bias(), invalid state"); | ||
253 | |||
254 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) | ||
255 | devp->compbias[i] = LIS3MDL_COMP_BIAS; | ||
256 | return msg; | ||
257 | } | ||
258 | |||
259 | /** | ||
260 | * @brief Set sensitivity values for the BaseCompass. | ||
261 | * @note Sensitivity must be expressed as G/LSB. | ||
262 | * @note The sensitivity buffer must be at least the same size of the | ||
263 | * BaseCompass axes number. | ||
264 | * | ||
265 | * @param[in] ip pointer to @p BaseCompass interface. | ||
266 | * @param[in] sp a buffer which contains sensitivities. | ||
267 | * | ||
268 | * @return The operation status. | ||
269 | * @retval MSG_OK if the function succeeded. | ||
270 | */ | ||
271 | static msg_t comp_set_sensivity(void *ip, float *sp) { | ||
272 | LIS3MDLDriver* devp; | ||
273 | uint32_t i; | ||
274 | msg_t msg = MSG_OK; | ||
275 | |||
276 | /* Getting parent instance pointer.*/ | ||
277 | devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip); | ||
278 | |||
279 | osalDbgCheck((ip != NULL) && (sp != NULL)); | ||
280 | |||
281 | osalDbgAssert((devp->state == LIS3MDL_READY), | ||
282 | "comp_set_sensivity(), invalid state"); | ||
283 | |||
284 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) { | ||
285 | devp->compsensitivity[i] = sp[i]; | ||
286 | } | ||
287 | return msg; | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * @brief Reset sensitivity values for the BaseCompass. | ||
292 | * @note Default sensitivities value are obtained from device datasheet. | ||
293 | * | ||
294 | * @param[in] ip pointer to @p BaseCompass interface. | ||
295 | * | ||
296 | * @return The operation status. | ||
297 | * @retval MSG_OK if the function succeeded. | ||
298 | * @retval MSG_RESET otherwise. | ||
299 | */ | ||
300 | static msg_t comp_reset_sensivity(void *ip) { | ||
301 | LIS3MDLDriver* devp; | ||
302 | uint32_t i; | ||
303 | msg_t msg = MSG_OK; | ||
304 | |||
305 | osalDbgCheck(ip != NULL); | ||
306 | |||
307 | /* Getting parent instance pointer.*/ | ||
308 | devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip); | ||
309 | |||
310 | osalDbgAssert((devp->state == LIS3MDL_READY), | ||
311 | "comp_reset_sensivity(), invalid state"); | ||
312 | |||
313 | if(devp->config->compfullscale == LIS3MDL_COMP_FS_4GA) | ||
314 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) | ||
315 | devp->compsensitivity[i] = LIS3MDL_COMP_SENS_4GA; | ||
316 | else if(devp->config->compfullscale == LIS3MDL_COMP_FS_8GA) | ||
317 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) | ||
318 | devp->compsensitivity[i] = LIS3MDL_COMP_SENS_8GA; | ||
319 | else if(devp->config->compfullscale == LIS3MDL_COMP_FS_12GA) | ||
320 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) | ||
321 | devp->compsensitivity[i] = LIS3MDL_COMP_SENS_12GA; | ||
322 | else if(devp->config->compfullscale == LIS3MDL_COMP_FS_16GA) | ||
323 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) | ||
324 | devp->compsensitivity[i] = LIS3MDL_COMP_SENS_16GA; | ||
325 | else { | ||
326 | osalDbgAssert(FALSE, "comp_reset_sensivity(), compass full scale issue"); | ||
327 | msg = MSG_RESET; | ||
328 | } | ||
329 | return msg; | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * @brief Changes the LIS3MDLDriver compass fullscale value. | ||
334 | * @note This function also rescale sensitivities and biases based on | ||
335 | * previous and next fullscale value. | ||
336 | * @note A recalibration is highly suggested after calling this function. | ||
337 | * | ||
338 | * @param[in] devp pointer to @p LIS3MDLDriver interface. | ||
339 | * @param[in] fs new fullscale value. | ||
340 | * | ||
341 | * @return The operation status. | ||
342 | * @retval MSG_OK if the function succeeded. | ||
343 | * @retval MSG_RESET otherwise. | ||
344 | */ | ||
345 | static msg_t comp_set_full_scale(LIS3MDLDriver *devp, lis3mdl_comp_fs_t fs) { | ||
346 | float newfs, scale; | ||
347 | uint8_t i, buff[2]; | ||
348 | msg_t msg; | ||
349 | |||
350 | osalDbgCheck(devp != NULL); | ||
351 | |||
352 | osalDbgAssert((devp->state == LIS3MDL_READY), | ||
353 | "comp_set_full_scale(), invalid state"); | ||
354 | osalDbgAssert((devp->config->i2cp->state == I2C_READY), | ||
355 | "comp_set_full_scale(), channel not ready"); | ||
356 | |||
357 | /* Computing new fullscale value.*/ | ||
358 | if(fs == LIS3MDL_COMP_FS_4GA) { | ||
359 | newfs = LIS3MDL_COMP_4GA; | ||
360 | } | ||
361 | else if(fs == LIS3MDL_COMP_FS_8GA) { | ||
362 | newfs = LIS3MDL_COMP_8GA; | ||
363 | } | ||
364 | else if(fs == LIS3MDL_COMP_FS_12GA) { | ||
365 | newfs = LIS3MDL_COMP_12GA; | ||
366 | } | ||
367 | else if(fs == LIS3MDL_COMP_FS_16GA) { | ||
368 | newfs = LIS3MDL_COMP_16GA; | ||
369 | } | ||
370 | else { | ||
371 | msg = MSG_RESET; | ||
372 | return msg; | ||
373 | } | ||
374 | |||
375 | if(newfs != devp->compfullscale) { | ||
376 | /* Computing scale value.*/ | ||
377 | scale = newfs / devp->compfullscale; | ||
378 | devp->compfullscale = newfs; | ||
379 | |||
380 | #if LIS3MDL_SHARED_I2C | ||
381 | i2cAcquireBus(devp->config->i2cp); | ||
382 | i2cStart(devp->config->i2cp, devp->config->i2ccfg); | ||
383 | #endif /* LIS3MDL_SHARED_I2C */ | ||
384 | |||
385 | /* Updating register.*/ | ||
386 | msg = lis3mdlI2CReadRegister(devp->config->i2cp, devp->config->slaveaddress, | ||
387 | LIS3MDL_AD_CTRL_REG2, &buff[1], 1); | ||
388 | |||
389 | #if LIS3MDL_SHARED_I2C | ||
390 | i2cReleaseBus(devp->config->i2cp); | ||
391 | #endif /* LIS3MDL_SHARED_I2C */ | ||
392 | |||
393 | if(msg != MSG_OK) | ||
394 | return msg; | ||
395 | buff[1] &= ~(LIS3MDL_CTRL_REG2_FS_MASK); | ||
396 | buff[1] |= fs; | ||
397 | buff[0] = LIS3MDL_AD_CTRL_REG2; | ||
398 | |||
399 | #if LIS3MDL_SHARED_I2C | ||
400 | i2cAcquireBus(devp->config->i2cp); | ||
401 | i2cStart(devp->config->i2cp, devp->config->i2ccfg); | ||
402 | #endif /* LIS3MDL_SHARED_I2C */ | ||
403 | |||
404 | msg = lis3mdlI2CWriteRegister(devp->config->i2cp, | ||
405 | devp->config->slaveaddress, | ||
406 | buff, 1); | ||
407 | |||
408 | #if LIS3MDL_SHARED_I2C | ||
409 | i2cReleaseBus(devp->config->i2cp); | ||
410 | #endif /* LIS3MDL_SHARED_I2C */ | ||
411 | |||
412 | if(msg != MSG_OK) | ||
413 | return msg; | ||
414 | |||
415 | /* Scaling sensitivity and bias. Re-calibration is suggested anyway.*/ | ||
416 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) { | ||
417 | devp->compsensitivity[i] *= scale; | ||
418 | devp->compbias[i] *= scale; | ||
419 | } | ||
420 | } | ||
421 | return msg; | ||
422 | } | ||
423 | |||
424 | static const struct LIS3MDLVMT vmt_device = { | ||
425 | (size_t)0, | ||
426 | comp_set_full_scale | ||
427 | }; | ||
428 | |||
429 | static const struct BaseCompassVMT vmt_compass = { | ||
430 | sizeof(struct LIS3MDLVMT*), | ||
431 | comp_get_axes_number, comp_read_raw, comp_read_cooked, | ||
432 | comp_set_bias, comp_reset_bias, comp_set_sensivity, comp_reset_sensivity | ||
433 | }; | ||
434 | |||
435 | /*===========================================================================*/ | ||
436 | /* Driver exported functions. */ | ||
437 | /*===========================================================================*/ | ||
438 | |||
439 | /** | ||
440 | * @brief Initializes an instance. | ||
441 | * | ||
442 | * @param[out] devp pointer to the @p LIS3MDLDriver object | ||
443 | * | ||
444 | * @init | ||
445 | */ | ||
446 | void lis3mdlObjectInit(LIS3MDLDriver *devp) { | ||
447 | devp->vmt = &vmt_device; | ||
448 | devp->comp_if.vmt = &vmt_compass; | ||
449 | |||
450 | devp->config = NULL; | ||
451 | |||
452 | devp->compaxes = LIS3MDL_COMP_NUMBER_OF_AXES; | ||
453 | |||
454 | devp->state = LIS3MDL_STOP; | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * @brief Configures and activates LIS3MDL Complex Driver peripheral. | ||
459 | * | ||
460 | * @param[in] devp pointer to the @p LIS3MDLDriver object | ||
461 | * @param[in] config pointer to the @p LIS3MDLConfig object | ||
462 | * | ||
463 | * @api | ||
464 | */ | ||
465 | void lis3mdlStart(LIS3MDLDriver *devp, const LIS3MDLConfig *config) { | ||
466 | uint32_t i; | ||
467 | uint8_t cr[6]; | ||
468 | osalDbgCheck((devp != NULL) && (config != NULL)); | ||
469 | |||
470 | osalDbgAssert((devp->state == LIS3MDL_STOP) || (devp->state == LIS3MDL_READY), | ||
471 | "lis3mdlStart(), invalid state"); | ||
472 | |||
473 | devp->config = config; | ||
474 | |||
475 | /* Control register 1 configuration block.*/ | ||
476 | { | ||
477 | cr[0] = LIS3MDL_AD_CTRL_REG1; | ||
478 | cr[1] = devp->config->compoutputdatarate; | ||
479 | #if LIS3MDL_USE_ADVANCED || defined(__DOXYGEN__) | ||
480 | cr[1] |= devp->config->compoperationmodexy; | ||
481 | #else | ||
482 | cr[1] |= LIS3MDL_CTRL_REG1_OM0 | LIS3MDL_CTRL_REG1_OM1; | ||
483 | #endif | ||
484 | } | ||
485 | |||
486 | /* Control register 2 configuration block.*/ | ||
487 | { | ||
488 | cr[2] = devp->config->compfullscale; | ||
489 | } | ||
490 | |||
491 | /* Control register 3 configuration block.*/ | ||
492 | { | ||
493 | cr[3] = 0; | ||
494 | #if LIS3MDL_USE_ADVANCED || defined(__DOXYGEN__) | ||
495 | cr[3] = devp->config->compconversionmode; | ||
496 | #endif | ||
497 | } | ||
498 | |||
499 | /* Control register 4 configuration block.*/ | ||
500 | { | ||
501 | cr[4] = 0; | ||
502 | #if LIS3MDL_USE_ADVANCED || defined(__DOXYGEN__) | ||
503 | cr[4] = devp->config->compoperationmodez | devp->config->endianness; | ||
504 | #endif | ||
505 | } | ||
506 | |||
507 | /* Control register 5 configuration block.*/ | ||
508 | { | ||
509 | cr[5] = 0; | ||
510 | #if LIS3MDL_USE_ADVANCED || defined(__DOXYGEN__) | ||
511 | cr[5] = devp->config->blockdataupdate; | ||
512 | #endif | ||
513 | } | ||
514 | |||
515 | #if LIS3MDL_USE_I2C | ||
516 | #if LIS3MDL_SHARED_I2C | ||
517 | i2cAcquireBus((devp)->config->i2cp); | ||
518 | #endif /* LIS3MDL_SHARED_I2C */ | ||
519 | i2cStart((devp)->config->i2cp, | ||
520 | (devp)->config->i2ccfg); | ||
521 | |||
522 | lis3mdlI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress, | ||
523 | cr, 5); | ||
524 | |||
525 | #if LIS3MDL_SHARED_I2C | ||
526 | i2cReleaseBus((devp)->config->i2cp); | ||
527 | #endif /* LIS3MDL_SHARED_I2C */ | ||
528 | #endif /* LIS3MDL_USE_I2C */ | ||
529 | |||
530 | if(devp->config->compfullscale == LIS3MDL_COMP_FS_4GA) { | ||
531 | devp->compfullscale = LIS3MDL_COMP_4GA; | ||
532 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) { | ||
533 | if(devp->config->compsensitivity == NULL) { | ||
534 | devp->compsensitivity[i] = LIS3MDL_COMP_SENS_4GA; | ||
535 | } | ||
536 | else { | ||
537 | devp->compsensitivity[i] = devp->config->compsensitivity[i]; | ||
538 | } | ||
539 | } | ||
540 | } | ||
541 | else if(devp->config->compfullscale == LIS3MDL_COMP_FS_8GA) { | ||
542 | devp->compfullscale = LIS3MDL_COMP_8GA; | ||
543 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) { | ||
544 | if(devp->config->compsensitivity == NULL) { | ||
545 | devp->compsensitivity[i] = LIS3MDL_COMP_SENS_8GA; | ||
546 | } | ||
547 | else { | ||
548 | devp->compsensitivity[i] = devp->config->compsensitivity[i]; | ||
549 | } | ||
550 | } | ||
551 | } | ||
552 | else if(devp->config->compfullscale == LIS3MDL_COMP_FS_12GA) { | ||
553 | devp->compfullscale = LIS3MDL_COMP_12GA; | ||
554 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) { | ||
555 | if(devp->config->compsensitivity == NULL) { | ||
556 | devp->compsensitivity[i] = LIS3MDL_COMP_SENS_12GA; | ||
557 | } | ||
558 | else { | ||
559 | devp->compsensitivity[i] = devp->config->compsensitivity[i]; | ||
560 | } | ||
561 | } | ||
562 | } | ||
563 | else if(devp->config->compfullscale == LIS3MDL_COMP_FS_16GA) { | ||
564 | devp->compfullscale = LIS3MDL_COMP_16GA; | ||
565 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) { | ||
566 | if(devp->config->compsensitivity == NULL) { | ||
567 | devp->compsensitivity[i] = LIS3MDL_COMP_SENS_16GA; | ||
568 | } | ||
569 | else { | ||
570 | devp->compsensitivity[i] = devp->config->compsensitivity[i]; | ||
571 | } | ||
572 | } | ||
573 | } | ||
574 | else | ||
575 | osalDbgAssert(FALSE, "lis3mdlStart(), compass full scale issue"); | ||
576 | |||
577 | /* Storing bias information */ | ||
578 | if(devp->config->compbias != NULL) | ||
579 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) | ||
580 | devp->compbias[i] = devp->config->compbias[i]; | ||
581 | else | ||
582 | for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) | ||
583 | devp->compbias[i] = LIS3MDL_COMP_BIAS; | ||
584 | |||
585 | /* This is the MEMS transient recovery time */ | ||
586 | osalThreadSleepMilliseconds(5); | ||
587 | |||
588 | devp->state = LIS3MDL_READY; | ||
589 | } | ||
590 | |||
591 | /** | ||
592 | * @brief Deactivates the LIS3MDL Complex Driver peripheral. | ||
593 | * | ||
594 | * @param[in] devp pointer to the @p LIS3MDLDriver object | ||
595 | * | ||
596 | * @api | ||
597 | */ | ||
598 | void lis3mdlStop(LIS3MDLDriver *devp) { | ||
599 | uint8_t cr[2]; | ||
600 | osalDbgCheck(devp != NULL); | ||
601 | |||
602 | osalDbgAssert((devp->state == LIS3MDL_STOP) || (devp->state == LIS3MDL_READY), | ||
603 | "lis3mdlStop(), invalid state"); | ||
604 | |||
605 | if (devp->state == LIS3MDL_READY) { | ||
606 | #if (LIS3MDL_USE_I2C) | ||
607 | #if LIS3MDL_SHARED_I2C | ||
608 | i2cAcquireBus((devp)->config->i2cp); | ||
609 | i2cStart((devp)->config->i2cp, | ||
610 | (devp)->config->i2ccfg); | ||
611 | #endif /* LIS3MDL_SHARED_I2C */ | ||
612 | |||
613 | /* Disabling compass. */ | ||
614 | cr[0] = LIS3MDL_AD_CTRL_REG3; | ||
615 | cr[1] = LIS3MDL_CTRL_REG3_MD0 | LIS3MDL_CTRL_REG3_MD1; | ||
616 | lis3mdlI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress, | ||
617 | cr, 1); | ||
618 | |||
619 | i2cStop((devp)->config->i2cp); | ||
620 | #if LIS3MDL_SHARED_I2C | ||
621 | i2cReleaseBus((devp)->config->i2cp); | ||
622 | #endif /* LIS3MDL_SHARED_I2C */ | ||
623 | #endif /* LIS3MDL_USE_I2C */ | ||
624 | } | ||
625 | devp->state = LIS3MDL_STOP; | ||
626 | } | ||
627 | /** @} */ | ||