lis3mdl.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. /*
  2. ChibiOS - Copyright (C) 2016..2018 Rocco Marco Guglielmi
  3. This file is part of ChibiOS.
  4. ChibiOS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. ChibiOS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. /**
  16. * @file lis3mdl.c
  17. * @brief LIS3MDL MEMS interface module code.
  18. *
  19. * @addtogroup LIS3MDL
  20. * @ingroup EX_ST
  21. * @{
  22. */
  23. #include "hal.h"
  24. #include "lis3mdl.h"
  25. /*===========================================================================*/
  26. /* Driver local definitions. */
  27. /*===========================================================================*/
  28. /*===========================================================================*/
  29. /* Driver exported variables. */
  30. /*===========================================================================*/
  31. /*===========================================================================*/
  32. /* Driver local variables and types. */
  33. /*===========================================================================*/
  34. /*===========================================================================*/
  35. /* Driver local functions. */
  36. /*===========================================================================*/
  37. #if (LIS3MDL_USE_I2C) || defined(__DOXYGEN__)
  38. /**
  39. * @brief Reads registers value using I2C.
  40. * @pre The I2C interface must be initialized and the driver started.
  41. *
  42. * @param[in] i2cp pointer to the I2C interface
  43. * @param[in] sad slave address without R bit
  44. * @param[in] reg first sub-register address
  45. * @param[out] rxbuf pointer to an output buffer
  46. * @param[in] n number of consecutive register to read
  47. * @return the operation status.
  48. * @notapi
  49. */
  50. msg_t lis3mdlI2CReadRegister(I2CDriver *i2cp, lis3mdl_sad_t sad, uint8_t reg,
  51. uint8_t* rxbuf, size_t n) {
  52. uint8_t txbuf = reg;
  53. if(n > 1)
  54. txbuf |= LIS3MDL_SUB_MS;
  55. return i2cMasterTransmitTimeout(i2cp, sad, &txbuf, 1, rxbuf, n,
  56. TIME_INFINITE);
  57. }
  58. /**
  59. * @brief Writes a value into a register using I2C.
  60. * @pre The I2C interface must be initialized and the driver started.
  61. *
  62. * @param[in] i2cp pointer to the I2C interface
  63. * @param[in] sad slave address without R bit
  64. * @param[in] txbuf buffer containing sub-address value in first position
  65. * and values to write
  66. * @param[in] n size of txbuf less one (not considering the first
  67. * element)
  68. * @return the operation status.
  69. * @notapi
  70. */
  71. msg_t lis3mdlI2CWriteRegister(I2CDriver *i2cp, lis3mdl_sad_t sad, uint8_t* txbuf,
  72. uint8_t n) {
  73. if (n > 1)
  74. (*txbuf) |= LIS3MDL_SUB_MS;
  75. return i2cMasterTransmitTimeout(i2cp, sad, txbuf, n + 1, NULL, 0,
  76. TIME_INFINITE);
  77. }
  78. #endif /* LIS3MDL_USE_I2C */
  79. /**
  80. * @brief Return the number of axes of the BaseCompass.
  81. *
  82. * @param[in] ip pointer to @p BaseCompass interface
  83. *
  84. * @return the number of axes.
  85. */
  86. static size_t comp_get_axes_number(void *ip) {
  87. osalDbgCheck(ip != NULL);
  88. return LIS3MDL_COMP_NUMBER_OF_AXES;
  89. }
  90. /**
  91. * @brief Retrieves raw data from the BaseCompass.
  92. * @note This data is retrieved from MEMS register without any algebraical
  93. * manipulation.
  94. * @note The axes array must be at least the same size of the
  95. * BaseCompass axes number.
  96. *
  97. * @param[in] ip pointer to @p BaseCompass interface.
  98. * @param[out] axes a buffer which would be filled with raw data.
  99. *
  100. * @return The operation status.
  101. * @retval MSG_OK if the function succeeded.
  102. * @retval MSG_RESET if one or more I2C errors occurred, the errors can
  103. * be retrieved using @p i2cGetErrors().
  104. * @retval MSG_TIMEOUT if a timeout occurred before operation end.
  105. */
  106. static msg_t comp_read_raw(void *ip, int32_t axes[]) {
  107. LIS3MDLDriver* devp;
  108. uint8_t buff [LIS3MDL_COMP_NUMBER_OF_AXES * 2], i;
  109. int16_t tmp;
  110. msg_t msg;
  111. osalDbgCheck((ip != NULL) && (axes != NULL));
  112. /* Getting parent instance pointer.*/
  113. devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip);
  114. osalDbgAssert((devp->state == LIS3MDL_READY),
  115. "comp_read_raw(), invalid state");
  116. osalDbgAssert((devp->config->i2cp->state == I2C_READY),
  117. "comp_read_raw(), channel not ready");
  118. #if LIS3MDL_SHARED_I2C
  119. i2cAcquireBus(devp->config->i2cp);
  120. i2cStart(devp->config->i2cp,
  121. devp->config->i2ccfg);
  122. #endif /* LIS3MDL_SHARED_I2C */
  123. msg = lis3mdlI2CReadRegister(devp->config->i2cp, devp->config->slaveaddress,
  124. LIS3MDL_AD_OUT_X_L, buff,
  125. LIS3MDL_COMP_NUMBER_OF_AXES * 2);
  126. #if LIS3MDL_SHARED_I2C
  127. i2cReleaseBus(devp->config->i2cp);
  128. #endif /* LIS3MDL_SHARED_I2C */
  129. if(msg == MSG_OK)
  130. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) {
  131. tmp = buff[2 * i] + (buff[2 * i + 1] << 8);
  132. axes[i] = (int32_t)tmp;
  133. }
  134. return msg;
  135. }
  136. /**
  137. * @brief Retrieves cooked data from the BaseCompass.
  138. * @note This data is manipulated according to the formula
  139. * cooked = (raw * sensitivity) - bias.
  140. * @note Final data is expressed as G.
  141. * @note The axes array must be at least the same size of the
  142. * BaseCompass axes number.
  143. *
  144. * @param[in] ip pointer to @p BaseCompass interface.
  145. * @param[out] axes a buffer which would be filled with cooked data.
  146. *
  147. * @return The operation status.
  148. * @retval MSG_OK if the function succeeded.
  149. * @retval MSG_RESET if one or more I2C errors occurred, the errors can
  150. * be retrieved using @p i2cGetErrors().
  151. * @retval MSG_TIMEOUT if a timeout occurred before operation end.
  152. */
  153. static msg_t comp_read_cooked(void *ip, float axes[]) {
  154. LIS3MDLDriver* devp;
  155. uint32_t i;
  156. int32_t raw[LIS3MDL_COMP_NUMBER_OF_AXES];
  157. msg_t msg;
  158. osalDbgCheck((ip != NULL) && (axes != NULL));
  159. /* Getting parent instance pointer.*/
  160. devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip);
  161. osalDbgAssert((devp->state == LIS3MDL_READY),
  162. "comp_read_cooked(), invalid state");
  163. msg = comp_read_raw(ip, raw);
  164. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES ; i++) {
  165. axes[i] = (raw[i] * devp->compsensitivity[i]) - devp->compbias[i];
  166. }
  167. return msg;
  168. }
  169. /**
  170. * @brief Set bias values for the BaseCompass.
  171. * @note Bias must be expressed as G.
  172. * @note The bias buffer must be at least the same size of the
  173. * BaseCompass axes number.
  174. *
  175. * @param[in] ip pointer to @p BaseCompass interface.
  176. * @param[in] bp a buffer which contains biases.
  177. *
  178. * @return The operation status.
  179. * @retval MSG_OK if the function succeeded.
  180. */
  181. static msg_t comp_set_bias(void *ip, float *bp) {
  182. LIS3MDLDriver* devp;
  183. uint32_t i;
  184. msg_t msg = MSG_OK;
  185. osalDbgCheck((ip != NULL) && (bp != NULL));
  186. /* Getting parent instance pointer.*/
  187. devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip);
  188. osalDbgAssert((devp->state == LIS3MDL_READY),
  189. "comp_set_bias(), invalid state");
  190. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) {
  191. devp->compbias[i] = bp[i];
  192. }
  193. return msg;
  194. }
  195. /**
  196. * @brief Reset bias values for the BaseCompass.
  197. * @note Default biases value are obtained from device datasheet when
  198. * available otherwise they are considered zero.
  199. *
  200. * @param[in] ip pointer to @p BaseCompass interface.
  201. *
  202. * @return The operation status.
  203. * @retval MSG_OK if the function succeeded.
  204. */
  205. static msg_t comp_reset_bias(void *ip) {
  206. LIS3MDLDriver* devp;
  207. uint32_t i;
  208. msg_t msg = MSG_OK;
  209. osalDbgCheck(ip != NULL);
  210. /* Getting parent instance pointer.*/
  211. devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip);
  212. osalDbgAssert((devp->state == LIS3MDL_READY),
  213. "comp_reset_bias(), invalid state");
  214. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++)
  215. devp->compbias[i] = LIS3MDL_COMP_BIAS;
  216. return msg;
  217. }
  218. /**
  219. * @brief Set sensitivity values for the BaseCompass.
  220. * @note Sensitivity must be expressed as G/LSB.
  221. * @note The sensitivity buffer must be at least the same size of the
  222. * BaseCompass axes number.
  223. *
  224. * @param[in] ip pointer to @p BaseCompass interface.
  225. * @param[in] sp a buffer which contains sensitivities.
  226. *
  227. * @return The operation status.
  228. * @retval MSG_OK if the function succeeded.
  229. */
  230. static msg_t comp_set_sensivity(void *ip, float *sp) {
  231. LIS3MDLDriver* devp;
  232. uint32_t i;
  233. msg_t msg = MSG_OK;
  234. /* Getting parent instance pointer.*/
  235. devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip);
  236. osalDbgCheck((ip != NULL) && (sp != NULL));
  237. osalDbgAssert((devp->state == LIS3MDL_READY),
  238. "comp_set_sensivity(), invalid state");
  239. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) {
  240. devp->compsensitivity[i] = sp[i];
  241. }
  242. return msg;
  243. }
  244. /**
  245. * @brief Reset sensitivity values for the BaseCompass.
  246. * @note Default sensitivities value are obtained from device datasheet.
  247. *
  248. * @param[in] ip pointer to @p BaseCompass interface.
  249. *
  250. * @return The operation status.
  251. * @retval MSG_OK if the function succeeded.
  252. * @retval MSG_RESET otherwise.
  253. */
  254. static msg_t comp_reset_sensivity(void *ip) {
  255. LIS3MDLDriver* devp;
  256. uint32_t i;
  257. msg_t msg = MSG_OK;
  258. osalDbgCheck(ip != NULL);
  259. /* Getting parent instance pointer.*/
  260. devp = objGetInstance(LIS3MDLDriver*, (BaseCompass*)ip);
  261. osalDbgAssert((devp->state == LIS3MDL_READY),
  262. "comp_reset_sensivity(), invalid state");
  263. if(devp->config->compfullscale == LIS3MDL_COMP_FS_4GA)
  264. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++)
  265. devp->compsensitivity[i] = LIS3MDL_COMP_SENS_4GA;
  266. else if(devp->config->compfullscale == LIS3MDL_COMP_FS_8GA)
  267. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++)
  268. devp->compsensitivity[i] = LIS3MDL_COMP_SENS_8GA;
  269. else if(devp->config->compfullscale == LIS3MDL_COMP_FS_12GA)
  270. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++)
  271. devp->compsensitivity[i] = LIS3MDL_COMP_SENS_12GA;
  272. else if(devp->config->compfullscale == LIS3MDL_COMP_FS_16GA)
  273. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++)
  274. devp->compsensitivity[i] = LIS3MDL_COMP_SENS_16GA;
  275. else {
  276. osalDbgAssert(FALSE, "comp_reset_sensivity(), compass full scale issue");
  277. msg = MSG_RESET;
  278. }
  279. return msg;
  280. }
  281. /**
  282. * @brief Changes the LIS3MDLDriver compass fullscale value.
  283. * @note This function also rescale sensitivities and biases based on
  284. * previous and next fullscale value.
  285. * @note A recalibration is highly suggested after calling this function.
  286. *
  287. * @param[in] devp pointer to @p LIS3MDLDriver interface.
  288. * @param[in] fs new fullscale value.
  289. *
  290. * @return The operation status.
  291. * @retval MSG_OK if the function succeeded.
  292. * @retval MSG_RESET otherwise.
  293. */
  294. static msg_t comp_set_full_scale(LIS3MDLDriver *devp, lis3mdl_comp_fs_t fs) {
  295. float newfs, scale;
  296. uint8_t i, buff[2];
  297. msg_t msg;
  298. osalDbgCheck(devp != NULL);
  299. osalDbgAssert((devp->state == LIS3MDL_READY),
  300. "comp_set_full_scale(), invalid state");
  301. osalDbgAssert((devp->config->i2cp->state == I2C_READY),
  302. "comp_set_full_scale(), channel not ready");
  303. /* Computing new fullscale value.*/
  304. if(fs == LIS3MDL_COMP_FS_4GA) {
  305. newfs = LIS3MDL_COMP_4GA;
  306. }
  307. else if(fs == LIS3MDL_COMP_FS_8GA) {
  308. newfs = LIS3MDL_COMP_8GA;
  309. }
  310. else if(fs == LIS3MDL_COMP_FS_12GA) {
  311. newfs = LIS3MDL_COMP_12GA;
  312. }
  313. else if(fs == LIS3MDL_COMP_FS_16GA) {
  314. newfs = LIS3MDL_COMP_16GA;
  315. }
  316. else {
  317. msg = MSG_RESET;
  318. return msg;
  319. }
  320. if(newfs != devp->compfullscale) {
  321. /* Computing scale value.*/
  322. scale = newfs / devp->compfullscale;
  323. devp->compfullscale = newfs;
  324. #if LIS3MDL_SHARED_I2C
  325. i2cAcquireBus(devp->config->i2cp);
  326. i2cStart(devp->config->i2cp, devp->config->i2ccfg);
  327. #endif /* LIS3MDL_SHARED_I2C */
  328. /* Updating register.*/
  329. msg = lis3mdlI2CReadRegister(devp->config->i2cp, devp->config->slaveaddress,
  330. LIS3MDL_AD_CTRL_REG2, &buff[1], 1);
  331. #if LIS3MDL_SHARED_I2C
  332. i2cReleaseBus(devp->config->i2cp);
  333. #endif /* LIS3MDL_SHARED_I2C */
  334. if(msg != MSG_OK)
  335. return msg;
  336. buff[1] &= ~(LIS3MDL_CTRL_REG2_FS_MASK);
  337. buff[1] |= fs;
  338. buff[0] = LIS3MDL_AD_CTRL_REG2;
  339. #if LIS3MDL_SHARED_I2C
  340. i2cAcquireBus(devp->config->i2cp);
  341. i2cStart(devp->config->i2cp, devp->config->i2ccfg);
  342. #endif /* LIS3MDL_SHARED_I2C */
  343. msg = lis3mdlI2CWriteRegister(devp->config->i2cp,
  344. devp->config->slaveaddress,
  345. buff, 1);
  346. #if LIS3MDL_SHARED_I2C
  347. i2cReleaseBus(devp->config->i2cp);
  348. #endif /* LIS3MDL_SHARED_I2C */
  349. if(msg != MSG_OK)
  350. return msg;
  351. /* Scaling sensitivity and bias. Re-calibration is suggested anyway.*/
  352. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) {
  353. devp->compsensitivity[i] *= scale;
  354. devp->compbias[i] *= scale;
  355. }
  356. }
  357. return msg;
  358. }
  359. static const struct LIS3MDLVMT vmt_device = {
  360. (size_t)0,
  361. comp_set_full_scale
  362. };
  363. static const struct BaseCompassVMT vmt_compass = {
  364. sizeof(struct LIS3MDLVMT*),
  365. comp_get_axes_number, comp_read_raw, comp_read_cooked,
  366. comp_set_bias, comp_reset_bias, comp_set_sensivity, comp_reset_sensivity
  367. };
  368. /*===========================================================================*/
  369. /* Driver exported functions. */
  370. /*===========================================================================*/
  371. /**
  372. * @brief Initializes an instance.
  373. *
  374. * @param[out] devp pointer to the @p LIS3MDLDriver object
  375. *
  376. * @init
  377. */
  378. void lis3mdlObjectInit(LIS3MDLDriver *devp) {
  379. devp->vmt = &vmt_device;
  380. devp->comp_if.vmt = &vmt_compass;
  381. devp->config = NULL;
  382. devp->compaxes = LIS3MDL_COMP_NUMBER_OF_AXES;
  383. devp->state = LIS3MDL_STOP;
  384. }
  385. /**
  386. * @brief Configures and activates LIS3MDL Complex Driver peripheral.
  387. *
  388. * @param[in] devp pointer to the @p LIS3MDLDriver object
  389. * @param[in] config pointer to the @p LIS3MDLConfig object
  390. *
  391. * @api
  392. */
  393. void lis3mdlStart(LIS3MDLDriver *devp, const LIS3MDLConfig *config) {
  394. uint32_t i;
  395. uint8_t cr[6];
  396. osalDbgCheck((devp != NULL) && (config != NULL));
  397. osalDbgAssert((devp->state == LIS3MDL_STOP) || (devp->state == LIS3MDL_READY),
  398. "lis3mdlStart(), invalid state");
  399. devp->config = config;
  400. /* Control register 1 configuration block.*/
  401. {
  402. cr[0] = LIS3MDL_AD_CTRL_REG1;
  403. cr[1] = devp->config->compoutputdatarate;
  404. #if LIS3MDL_USE_ADVANCED || defined(__DOXYGEN__)
  405. cr[1] |= devp->config->compoperationmodexy;
  406. #else
  407. cr[1] |= LIS3MDL_CTRL_REG1_OM0 | LIS3MDL_CTRL_REG1_OM1;
  408. #endif
  409. }
  410. /* Control register 2 configuration block.*/
  411. {
  412. cr[2] = devp->config->compfullscale;
  413. }
  414. /* Control register 3 configuration block.*/
  415. {
  416. cr[3] = 0;
  417. #if LIS3MDL_USE_ADVANCED || defined(__DOXYGEN__)
  418. cr[3] = devp->config->compconversionmode;
  419. #endif
  420. }
  421. /* Control register 4 configuration block.*/
  422. {
  423. cr[4] = 0;
  424. #if LIS3MDL_USE_ADVANCED || defined(__DOXYGEN__)
  425. cr[4] = devp->config->compoperationmodez | devp->config->endianness;
  426. #endif
  427. }
  428. /* Control register 5 configuration block.*/
  429. {
  430. cr[5] = 0;
  431. #if LIS3MDL_USE_ADVANCED || defined(__DOXYGEN__)
  432. cr[5] = devp->config->blockdataupdate;
  433. #endif
  434. }
  435. #if LIS3MDL_USE_I2C
  436. #if LIS3MDL_SHARED_I2C
  437. i2cAcquireBus((devp)->config->i2cp);
  438. #endif /* LIS3MDL_SHARED_I2C */
  439. i2cStart((devp)->config->i2cp,
  440. (devp)->config->i2ccfg);
  441. lis3mdlI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
  442. cr, 5);
  443. #if LIS3MDL_SHARED_I2C
  444. i2cReleaseBus((devp)->config->i2cp);
  445. #endif /* LIS3MDL_SHARED_I2C */
  446. #endif /* LIS3MDL_USE_I2C */
  447. if(devp->config->compfullscale == LIS3MDL_COMP_FS_4GA) {
  448. devp->compfullscale = LIS3MDL_COMP_4GA;
  449. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) {
  450. if(devp->config->compsensitivity == NULL) {
  451. devp->compsensitivity[i] = LIS3MDL_COMP_SENS_4GA;
  452. }
  453. else {
  454. devp->compsensitivity[i] = devp->config->compsensitivity[i];
  455. }
  456. }
  457. }
  458. else if(devp->config->compfullscale == LIS3MDL_COMP_FS_8GA) {
  459. devp->compfullscale = LIS3MDL_COMP_8GA;
  460. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) {
  461. if(devp->config->compsensitivity == NULL) {
  462. devp->compsensitivity[i] = LIS3MDL_COMP_SENS_8GA;
  463. }
  464. else {
  465. devp->compsensitivity[i] = devp->config->compsensitivity[i];
  466. }
  467. }
  468. }
  469. else if(devp->config->compfullscale == LIS3MDL_COMP_FS_12GA) {
  470. devp->compfullscale = LIS3MDL_COMP_12GA;
  471. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) {
  472. if(devp->config->compsensitivity == NULL) {
  473. devp->compsensitivity[i] = LIS3MDL_COMP_SENS_12GA;
  474. }
  475. else {
  476. devp->compsensitivity[i] = devp->config->compsensitivity[i];
  477. }
  478. }
  479. }
  480. else if(devp->config->compfullscale == LIS3MDL_COMP_FS_16GA) {
  481. devp->compfullscale = LIS3MDL_COMP_16GA;
  482. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++) {
  483. if(devp->config->compsensitivity == NULL) {
  484. devp->compsensitivity[i] = LIS3MDL_COMP_SENS_16GA;
  485. }
  486. else {
  487. devp->compsensitivity[i] = devp->config->compsensitivity[i];
  488. }
  489. }
  490. }
  491. else
  492. osalDbgAssert(FALSE, "lis3mdlStart(), compass full scale issue");
  493. /* Storing bias information */
  494. if(devp->config->compbias != NULL)
  495. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++)
  496. devp->compbias[i] = devp->config->compbias[i];
  497. else
  498. for(i = 0; i < LIS3MDL_COMP_NUMBER_OF_AXES; i++)
  499. devp->compbias[i] = LIS3MDL_COMP_BIAS;
  500. /* This is the MEMS transient recovery time */
  501. osalThreadSleepMilliseconds(5);
  502. devp->state = LIS3MDL_READY;
  503. }
  504. /**
  505. * @brief Deactivates the LIS3MDL Complex Driver peripheral.
  506. *
  507. * @param[in] devp pointer to the @p LIS3MDLDriver object
  508. *
  509. * @api
  510. */
  511. void lis3mdlStop(LIS3MDLDriver *devp) {
  512. uint8_t cr[2];
  513. osalDbgCheck(devp != NULL);
  514. osalDbgAssert((devp->state == LIS3MDL_STOP) || (devp->state == LIS3MDL_READY),
  515. "lis3mdlStop(), invalid state");
  516. if (devp->state == LIS3MDL_READY) {
  517. #if (LIS3MDL_USE_I2C)
  518. #if LIS3MDL_SHARED_I2C
  519. i2cAcquireBus((devp)->config->i2cp);
  520. i2cStart((devp)->config->i2cp,
  521. (devp)->config->i2ccfg);
  522. #endif /* LIS3MDL_SHARED_I2C */
  523. /* Disabling compass. */
  524. cr[0] = LIS3MDL_AD_CTRL_REG3;
  525. cr[1] = LIS3MDL_CTRL_REG3_MD0 | LIS3MDL_CTRL_REG3_MD1;
  526. lis3mdlI2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
  527. cr, 1);
  528. i2cStop((devp)->config->i2cp);
  529. #if LIS3MDL_SHARED_I2C
  530. i2cReleaseBus((devp)->config->i2cp);
  531. #endif /* LIS3MDL_SHARED_I2C */
  532. #endif /* LIS3MDL_USE_I2C */
  533. }
  534. devp->state = LIS3MDL_STOP;
  535. }
  536. /** @} */