lsm6ds0.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  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 lsm6ds0.c
  17. * @brief LSM6DS0 MEMS interface module code.
  18. *
  19. * @addtogroup LSM6DS0
  20. * @ingroup EX_ST
  21. * @{
  22. */
  23. #include "hal.h"
  24. #include "lsm6ds0.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 (LSM6DS0_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. * @note IF_ADD_INC bit must be 1 in CTRL_REG8
  42. *
  43. * @param[in] i2cp pointer to the I2C interface
  44. * @param[in] sad slave address without R bit
  45. * @param[in] reg first sub-register address
  46. * @param[out] rxbuf pointer to an output buffer
  47. * @param[in] n number of consecutive register to read
  48. * @return the operation status.
  49. * @notapi
  50. */
  51. msg_t lsm6ds0I2CReadRegister(I2CDriver *i2cp, lsm6ds0_sad_t sad, uint8_t reg,
  52. uint8_t* rxbuf, size_t n) {
  53. return i2cMasterTransmitTimeout(i2cp, sad, &reg, 1, rxbuf, n,
  54. TIME_INFINITE);
  55. }
  56. /**
  57. * @brief Writes a value into a register using I2C.
  58. * @pre The I2C interface must be initialized and the driver started.
  59. *
  60. * @param[in] i2cp pointer to the I2C interface
  61. * @param[in] sad slave address without R bit
  62. * @param[in] txbuf buffer containing sub-address value in first position
  63. * and values to write
  64. * @param[in] n size of txbuf less one (not considering the first
  65. * element)
  66. * @return the operation status.
  67. * @notapi
  68. */
  69. #define lsm6ds0I2CWriteRegister(i2cp, sad, txbuf, n) \
  70. i2cMasterTransmitTimeout(i2cp, sad, txbuf, n + 1, NULL, 0, \
  71. TIME_INFINITE)
  72. #endif /* LSM6DS0_USE_I2C */
  73. /**
  74. * @brief Return the number of axes of the BaseAccelerometer.
  75. *
  76. * @param[in] ip pointer to @p BaseAccelerometer interface.
  77. *
  78. * @return the number of axes.
  79. */
  80. static size_t acc_get_axes_number(void *ip) {
  81. (void)ip;
  82. return LSM6DS0_ACC_NUMBER_OF_AXES;
  83. }
  84. /**
  85. * @brief Retrieves raw data from the BaseAccelerometer.
  86. * @note This data is retrieved from MEMS register without any algebraical
  87. * manipulation.
  88. * @note The axes array must be at least the same size of the
  89. * BaseAccelerometer axes number.
  90. *
  91. * @param[in] ip pointer to @p BaseAccelerometer interface.
  92. * @param[out] axes a buffer which would be filled with raw data.
  93. *
  94. * @return The operation status.
  95. * @retval MSG_OK if the function succeeded.
  96. * @retval MSG_RESET if one or more I2C errors occurred, the errors can
  97. * be retrieved using @p i2cGetErrors().
  98. * @retval MSG_TIMEOUT if a timeout occurred before operation end.
  99. */
  100. static msg_t acc_read_raw(void *ip, int32_t axes[]) {
  101. LSM6DS0Driver* devp;
  102. uint8_t buff [LSM6DS0_ACC_NUMBER_OF_AXES * 2], i;
  103. int16_t tmp;
  104. msg_t msg;
  105. osalDbgCheck((ip != NULL) && (axes != NULL));
  106. /* Getting parent instance pointer.*/
  107. devp = objGetInstance(LSM6DS0Driver*, (BaseAccelerometer*)ip);
  108. osalDbgAssert((devp->state == LSM6DS0_READY),
  109. "acc_read_raw(), invalid state");
  110. #if LSM6DS0_USE_I2C
  111. osalDbgAssert((devp->config->i2cp->state == I2C_READY),
  112. "acc_read_raw(), channel not ready");
  113. #if LSM6DS0_SHARED_I2C
  114. i2cAcquireBus(devp->config->i2cp);
  115. i2cStart(devp->config->i2cp,
  116. devp->config->i2ccfg);
  117. #endif /* LSM6DS0_SHARED_I2C */
  118. msg = lsm6ds0I2CReadRegister(devp->config->i2cp, devp->config->slaveaddress,
  119. LSM6DS0_AD_OUT_X_L_XL, buff,
  120. LSM6DS0_ACC_NUMBER_OF_AXES * 2);
  121. #if LSM6DS0_SHARED_I2C
  122. i2cReleaseBus(devp->config->i2cp);
  123. #endif /* LSM6DS0_SHARED_I2C */
  124. #endif /* LSM6DS0_USE_I2C */
  125. if(msg == MSG_OK)
  126. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++) {
  127. tmp = buff[2 * i] + (buff[2 * i + 1] << 8);
  128. axes[i] = (int32_t)tmp;
  129. }
  130. return msg;
  131. }
  132. /**
  133. * @brief Retrieves cooked data from the BaseAccelerometer.
  134. * @note This data is manipulated according to the formula
  135. * cooked = (raw * sensitivity) - bias.
  136. * @note Final data is expressed as milli-G.
  137. * @note The axes array must be at least the same size of the
  138. * BaseAccelerometer axes number.
  139. *
  140. * @param[in] ip pointer to @p BaseAccelerometer interface.
  141. * @param[out] axes a buffer which would be filled with cooked data.
  142. *
  143. * @return The operation status.
  144. * @retval MSG_OK if the function succeeded.
  145. * @retval MSG_RESET if one or more I2C errors occurred, the errors can
  146. * be retrieved using @p i2cGetErrors().
  147. * @retval MSG_TIMEOUT if a timeout occurred before operation end.
  148. */
  149. static msg_t acc_read_cooked(void *ip, float axes[]) {
  150. LSM6DS0Driver* devp;
  151. uint32_t i;
  152. int32_t raw[LSM6DS0_ACC_NUMBER_OF_AXES];
  153. msg_t msg;
  154. osalDbgCheck((ip != NULL) && (axes != NULL));
  155. /* Getting parent instance pointer.*/
  156. devp = objGetInstance(LSM6DS0Driver*, (BaseAccelerometer*)ip);
  157. osalDbgAssert((devp->state == LSM6DS0_READY),
  158. "acc_read_cooked(), invalid state");
  159. msg = acc_read_raw(ip, raw);
  160. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++) {
  161. axes[i] = (raw[i] * devp->accsensitivity[i]) - devp->accbias[i];
  162. }
  163. return msg;
  164. }
  165. /**
  166. * @brief Set bias values for the BaseAccelerometer.
  167. * @note Bias must be expressed as milli-G.
  168. * @note The bias buffer must be at least the same size of the
  169. * BaseAccelerometer axes number.
  170. *
  171. * @param[in] ip pointer to @p BaseAccelerometer interface.
  172. * @param[in] bp a buffer which contains biases.
  173. *
  174. * @return The operation status.
  175. * @retval MSG_OK if the function succeeded.
  176. */
  177. static msg_t acc_set_bias(void *ip, float *bp) {
  178. LSM6DS0Driver* devp;
  179. uint32_t i;
  180. msg_t msg = MSG_OK;
  181. osalDbgCheck((ip != NULL) && (bp != NULL));
  182. /* Getting parent instance pointer.*/
  183. devp = objGetInstance(LSM6DS0Driver*, (BaseAccelerometer*)ip);
  184. osalDbgAssert((devp->state == LSM6DS0_READY),
  185. "acc_set_bias(), invalid state");
  186. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++) {
  187. devp->accbias[i] = bp[i];
  188. }
  189. return msg;
  190. }
  191. /**
  192. * @brief Reset bias values for the BaseAccelerometer.
  193. * @note Default biases value are obtained from device datasheet when
  194. * available otherwise they are considered zero.
  195. *
  196. * @param[in] ip pointer to @p BaseAccelerometer interface.
  197. *
  198. * @return The operation status.
  199. * @retval MSG_OK if the function succeeded.
  200. */
  201. static msg_t acc_reset_bias(void *ip) {
  202. LSM6DS0Driver* devp;
  203. uint32_t i;
  204. msg_t msg = MSG_OK;
  205. osalDbgCheck(ip != NULL);
  206. /* Getting parent instance pointer.*/
  207. devp = objGetInstance(LSM6DS0Driver*, (BaseAccelerometer*)ip);
  208. osalDbgAssert((devp->state == LSM6DS0_READY),
  209. "acc_reset_bias(), invalid state");
  210. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++)
  211. devp->accbias[i] = LSM6DS0_ACC_BIAS;
  212. return msg;
  213. }
  214. /**
  215. * @brief Set sensitivity values for the BaseAccelerometer.
  216. * @note Sensitivity must be expressed as milli-G/LSB.
  217. * @note The sensitivity buffer must be at least the same size of the
  218. * BaseAccelerometer axes number.
  219. *
  220. * @param[in] ip pointer to @p BaseAccelerometer interface.
  221. * @param[in] sp a buffer which contains sensitivities.
  222. *
  223. * @return The operation status.
  224. * @retval MSG_OK if the function succeeded.
  225. */
  226. static msg_t acc_set_sensivity(void *ip, float *sp) {
  227. LSM6DS0Driver* devp;
  228. uint32_t i;
  229. msg_t msg = MSG_OK;
  230. /* Getting parent instance pointer.*/
  231. devp = objGetInstance(LSM6DS0Driver*, (BaseAccelerometer*)ip);
  232. osalDbgCheck((ip != NULL) && (sp != NULL));
  233. osalDbgAssert((devp->state == LSM6DS0_READY),
  234. "acc_set_sensivity(), invalid state");
  235. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++) {
  236. devp->accsensitivity[i] = sp[i];
  237. }
  238. return msg;
  239. }
  240. /**
  241. * @brief Reset sensitivity values for the BaseAccelerometer.
  242. * @note Default sensitivities value are obtained from device datasheet.
  243. *
  244. * @param[in] ip pointer to @p BaseAccelerometer interface.
  245. *
  246. * @return The operation status.
  247. * @retval MSG_OK if the function succeeded.
  248. * @retval MSG_RESET otherwise.
  249. */
  250. static msg_t acc_reset_sensivity(void *ip) {
  251. LSM6DS0Driver* devp;
  252. uint32_t i;
  253. msg_t msg = MSG_OK;
  254. osalDbgCheck(ip != NULL);
  255. /* Getting parent instance pointer.*/
  256. devp = objGetInstance(LSM6DS0Driver*, (BaseAccelerometer*)ip);
  257. osalDbgAssert((devp->state == LSM6DS0_READY),
  258. "acc_reset_sensivity(), invalid state");
  259. if(devp->config->accfullscale == LSM6DS0_ACC_FS_2G)
  260. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++)
  261. devp->accsensitivity[i] = LSM6DS0_ACC_SENS_2G;
  262. else if(devp->config->accfullscale == LSM6DS0_ACC_FS_4G)
  263. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++)
  264. devp->accsensitivity[i] = LSM6DS0_ACC_SENS_4G;
  265. else if(devp->config->accfullscale == LSM6DS0_ACC_FS_8G)
  266. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++)
  267. devp->accsensitivity[i] = LSM6DS0_ACC_SENS_8G;
  268. else if(devp->config->accfullscale == LSM6DS0_ACC_FS_16G)
  269. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++)
  270. devp->accsensitivity[i] = LSM6DS0_ACC_SENS_16G;
  271. else {
  272. osalDbgAssert(FALSE, "reset_sensivity(), accelerometer full scale issue");
  273. msg = MSG_RESET;
  274. }
  275. return msg;
  276. }
  277. /**
  278. * @brief Changes the LSM6DS0Driver accelerometer fullscale value.
  279. * @note This function also rescale sensitivities and biases based on
  280. * previous and next fullscale value.
  281. * @note A recalibration is highly suggested after calling this function.
  282. *
  283. * @param[in] devp pointer to @p LSM6DS0Driver interface.
  284. * @param[in] fs new fullscale value.
  285. *
  286. * @return The operation status.
  287. * @retval MSG_OK if the function succeeded.
  288. * @retval MSG_RESET otherwise.
  289. */
  290. static msg_t acc_set_full_scale(LSM6DS0Driver *devp, lsm6ds0_acc_fs_t fs) {
  291. float newfs, scale;
  292. uint8_t i, buff[2];
  293. msg_t msg;
  294. osalDbgCheck(devp != NULL);
  295. osalDbgAssert((devp->state == LSM6DS0_READY),
  296. "acc_set_full_scale(), invalid state");
  297. osalDbgAssert((devp->config->i2cp->state == I2C_READY),
  298. "acc_set_full_scale(), channel not ready");
  299. /* Computing new fullscale value.*/
  300. if(fs == LSM6DS0_ACC_FS_2G) {
  301. newfs = LSM6DS0_ACC_2G;
  302. }
  303. else if(fs == LSM6DS0_ACC_FS_4G) {
  304. newfs = LSM6DS0_ACC_4G;
  305. }
  306. else if(fs == LSM6DS0_ACC_FS_8G) {
  307. newfs = LSM6DS0_ACC_8G;
  308. }
  309. else if(fs == LSM6DS0_ACC_FS_16G) {
  310. newfs = LSM6DS0_ACC_16G;
  311. }
  312. else {
  313. msg = MSG_RESET;
  314. return msg;
  315. }
  316. if(newfs != devp->accfullscale) {
  317. /* Computing scale value.*/
  318. scale = newfs / devp->accfullscale;
  319. devp->accfullscale = newfs;
  320. #if LSM6DS0_SHARED_I2C
  321. i2cAcquireBus(devp->config->i2cp);
  322. i2cStart(devp->config->i2cp,
  323. devp->config->i2ccfg);
  324. #endif /* LSM6DS0_SHARED_I2C */
  325. /* Updating register.*/
  326. msg = lsm6ds0I2CReadRegister(devp->config->i2cp,
  327. devp->config->slaveaddress,
  328. LSM6DS0_AD_CTRL_REG6_XL, &buff[1], 1);
  329. #if LSM6DS0_SHARED_I2C
  330. i2cReleaseBus(devp->config->i2cp);
  331. #endif /* LSM6DS0_SHARED_I2C */
  332. if(msg != MSG_OK)
  333. return msg;
  334. buff[1] &= ~(LSM6DS0_CTRL_REG6_XL_FS_MASK);
  335. buff[1] |= fs;
  336. buff[0] = LSM6DS0_AD_CTRL_REG6_XL;
  337. #if LSM6DS0_SHARED_I2C
  338. i2cAcquireBus(devp->config->i2cp);
  339. i2cStart(devp->config->i2cp, devp->config->i2ccfg);
  340. #endif /* LSM6DS0_SHARED_I2C */
  341. msg = lsm6ds0I2CWriteRegister(devp->config->i2cp,
  342. devp->config->slaveaddress, buff, 1);
  343. #if LSM6DS0_SHARED_I2C
  344. i2cReleaseBus(devp->config->i2cp);
  345. #endif /* LSM6DS0_SHARED_I2C */
  346. if(msg != MSG_OK)
  347. return msg;
  348. /* Scaling sensitivity and bias. Re-calibration is suggested anyway.*/
  349. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++) {
  350. devp->accsensitivity[i] *= scale;
  351. devp->accbias[i] *= scale;
  352. }
  353. }
  354. return msg;
  355. }
  356. /**
  357. * @brief Return the number of axes of the BaseGyroscope.
  358. *
  359. * @param[in] ip pointer to @p BaseGyroscope interface.
  360. *
  361. * @return the number of axes.
  362. */
  363. static size_t gyro_get_axes_number(void *ip) {
  364. (void)ip;
  365. return LSM6DS0_GYRO_NUMBER_OF_AXES;
  366. }
  367. /**
  368. * @brief Retrieves raw data from the BaseGyroscope.
  369. * @note This data is retrieved from MEMS register without any algebraical
  370. * manipulation.
  371. * @note The axes array must be at least the same size of the
  372. * BaseGyroscope axes number.
  373. *
  374. * @param[in] ip pointer to @p BaseGyroscope interface.
  375. * @param[out] axes a buffer which would be filled with raw data.
  376. *
  377. * @return The operation status.
  378. * @retval MSG_OK if the function succeeded.
  379. * @retval MSG_RESET if one or more I2C errors occurred, the errors can
  380. * be retrieved using @p i2cGetErrors().
  381. * @retval MSG_TIMEOUT if a timeout occurred before operation end.
  382. */
  383. static msg_t gyro_read_raw(void *ip, int32_t axes[LSM6DS0_GYRO_NUMBER_OF_AXES]) {
  384. LSM6DS0Driver* devp;
  385. int16_t tmp;
  386. uint8_t i, buff [2 * LSM6DS0_GYRO_NUMBER_OF_AXES];
  387. msg_t msg = MSG_OK;
  388. osalDbgCheck((ip != NULL) && (axes != NULL));
  389. /* Getting parent instance pointer.*/
  390. devp = objGetInstance(LSM6DS0Driver*, (BaseGyroscope*)ip);
  391. osalDbgAssert((devp->state == LSM6DS0_READY),
  392. "gyro_read_raw(), invalid state");
  393. #if LSM6DS0_USE_I2C
  394. osalDbgAssert((devp->config->i2cp->state == I2C_READY),
  395. "gyro_read_raw(), channel not ready");
  396. #if LSM6DS0_SHARED_I2C
  397. i2cAcquireBus(devp->config->i2cp);
  398. i2cStart(devp->config->i2cp,
  399. devp->config->i2ccfg);
  400. #endif /* LSM6DS0_SHARED_I2C */
  401. msg = lsm6ds0I2CReadRegister(devp->config->i2cp, devp->config->slaveaddress,
  402. LSM6DS0_AD_OUT_X_L_G, buff,
  403. LSM6DS0_GYRO_NUMBER_OF_AXES * 2);
  404. #if LSM6DS0_SHARED_I2C
  405. i2cReleaseBus(devp->config->i2cp);
  406. #endif /* LSM6DS0_SHARED_I2C */
  407. #endif /* LSM6DS0_USE_I2C */
  408. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++) {
  409. tmp = buff[2 * i] + (buff[2 * i + 1] << 8);
  410. axes[i] = (int32_t)tmp;
  411. }
  412. return msg;
  413. }
  414. /**
  415. * @brief Retrieves cooked data from the BaseGyroscope.
  416. * @note This data is manipulated according to the formula
  417. * cooked = (raw * sensitivity) - bias.
  418. * @note Final data is expressed as DPS.
  419. * @note The axes array must be at least the same size of the
  420. * BaseGyroscope axes number.
  421. *
  422. * @param[in] ip pointer to @p BaseGyroscope interface.
  423. * @param[out] axes a buffer which would be filled with cooked data.
  424. *
  425. * @return The operation status.
  426. * @retval MSG_OK if the function succeeded.
  427. * @retval MSG_RESET if one or more I2C errors occurred, the errors can
  428. * be retrieved using @p i2cGetErrors().
  429. * @retval MSG_TIMEOUT if a timeout occurred before operation end.
  430. */
  431. static msg_t gyro_read_cooked(void *ip, float axes[]) {
  432. LSM6DS0Driver* devp;
  433. uint32_t i;
  434. int32_t raw[LSM6DS0_GYRO_NUMBER_OF_AXES];
  435. msg_t msg;
  436. osalDbgCheck((ip != NULL) && (axes != NULL));
  437. /* Getting parent instance pointer.*/
  438. devp = objGetInstance(LSM6DS0Driver*, (BaseGyroscope*)ip);
  439. osalDbgAssert((devp->state == LSM6DS0_READY),
  440. "gyro_read_cooked(), invalid state");
  441. msg = gyro_read_raw(ip, raw);
  442. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++){
  443. axes[i] = (raw[i] * devp->gyrosensitivity[i]) - devp->gyrobias[i];
  444. }
  445. return msg;
  446. }
  447. /**
  448. * @brief Samples bias values for the BaseGyroscope.
  449. * @note The LSM6DS0 shall not be moved during the whole procedure.
  450. * @note After this function internal bias is automatically updated.
  451. * @note The behavior of this function depends on @p LSM6DS0_BIAS_ACQ_TIMES
  452. * and @p LSM6DS0_BIAS_SETTLING_US.
  453. *
  454. * @param[in] ip pointer to @p BaseGyroscope interface.
  455. *
  456. * @return The operation status.
  457. * @retval MSG_OK if the function succeeded.
  458. */
  459. static msg_t gyro_sample_bias(void *ip) {
  460. LSM6DS0Driver* devp;
  461. uint32_t i, j;
  462. int32_t raw[LSM6DS0_GYRO_NUMBER_OF_AXES];
  463. int32_t buff[LSM6DS0_GYRO_NUMBER_OF_AXES] = {0, 0, 0};
  464. msg_t msg;
  465. osalDbgCheck(ip != NULL);
  466. /* Getting parent instance pointer.*/
  467. devp = objGetInstance(LSM6DS0Driver*, (BaseGyroscope*)ip);
  468. osalDbgAssert((devp->state == LSM6DS0_READY),
  469. "gyro_sample_bias(), invalid state");
  470. #if LSM6DS0_USE_I2C
  471. osalDbgAssert((devp->config->i2cp->state == I2C_READY),
  472. "gyro_sample_bias(), channel not ready");
  473. #endif
  474. for(i = 0; i < LSM6DS0_GYRO_BIAS_ACQ_TIMES; i++){
  475. msg = gyro_read_raw(ip, raw);
  476. if(msg != MSG_OK)
  477. return msg;
  478. for(j = 0; j < LSM6DS0_GYRO_NUMBER_OF_AXES; j++){
  479. buff[j] += raw[j];
  480. }
  481. osalThreadSleepMicroseconds(LSM6DS0_GYRO_BIAS_SETTLING_US);
  482. }
  483. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++){
  484. devp->gyrobias[i] = (buff[i] / LSM6DS0_GYRO_BIAS_ACQ_TIMES);
  485. devp->gyrobias[i] *= devp->gyrosensitivity[i];
  486. }
  487. return msg;
  488. }
  489. /**
  490. * @brief Set bias values for the BaseGyroscope.
  491. * @note Bias must be expressed as DPS.
  492. * @note The bias buffer must be at least the same size of the BaseGyroscope
  493. * axes number.
  494. *
  495. * @param[in] ip pointer to @p BaseGyroscope interface.
  496. * @param[in] bp a buffer which contains biases.
  497. *
  498. * @return The operation status.
  499. * @retval MSG_OK if the function succeeded.
  500. */
  501. static msg_t gyro_set_bias(void *ip, float *bp) {
  502. LSM6DS0Driver* devp;
  503. uint32_t i;
  504. msg_t msg = MSG_OK;
  505. osalDbgCheck((ip != NULL) && (bp != NULL));
  506. /* Getting parent instance pointer.*/
  507. devp = objGetInstance(LSM6DS0Driver*, (BaseGyroscope*)ip);
  508. osalDbgAssert((devp->state == LSM6DS0_READY),
  509. "gyro_set_bias(), invalid state");
  510. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++) {
  511. devp->gyrobias[i] = bp[i];
  512. }
  513. return msg;
  514. }
  515. /**
  516. * @brief Reset bias values for the BaseGyroscope.
  517. * @note Default biases value are obtained from device datasheet when
  518. * available otherwise they are considered zero.
  519. *
  520. * @param[in] ip pointer to @p BaseGyroscope interface.
  521. *
  522. * @return The operation status.
  523. * @retval MSG_OK if the function succeeded.
  524. */
  525. static msg_t gyro_reset_bias(void *ip) {
  526. LSM6DS0Driver* devp;
  527. uint32_t i;
  528. msg_t msg = MSG_OK;
  529. osalDbgCheck(ip != NULL);
  530. /* Getting parent instance pointer.*/
  531. devp = objGetInstance(LSM6DS0Driver*, (BaseGyroscope*)ip);
  532. osalDbgAssert((devp->state == LSM6DS0_READY),
  533. "gyro_reset_bias(), invalid state");
  534. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++)
  535. devp->gyrobias[i] = LSM6DS0_GYRO_BIAS;
  536. return msg;
  537. }
  538. /**
  539. * @brief Set sensitivity values for the BaseGyroscope.
  540. * @note Sensitivity must be expressed as DPS/LSB.
  541. * @note The sensitivity buffer must be at least the same size of the
  542. * BaseGyroscope axes number.
  543. *
  544. * @param[in] ip pointer to @p BaseGyroscope interface.
  545. * @param[in] sp a buffer which contains sensitivities.
  546. *
  547. * @return The operation status.
  548. * @retval MSG_OK if the function succeeded.
  549. */
  550. static msg_t gyro_set_sensivity(void *ip, float *sp) {
  551. LSM6DS0Driver* devp;
  552. uint32_t i;
  553. msg_t msg = MSG_OK;
  554. osalDbgCheck((ip != NULL) && (sp !=NULL));
  555. /* Getting parent instance pointer.*/
  556. devp = objGetInstance(LSM6DS0Driver*, (BaseGyroscope*)ip);
  557. osalDbgAssert((devp->state == LSM6DS0_READY),
  558. "gyro_set_sensivity(), invalid state");
  559. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++) {
  560. devp->gyrosensitivity[i] = sp[i];
  561. }
  562. return msg;
  563. }
  564. /**
  565. * @brief Reset sensitivity values for the BaseGyroscope.
  566. * @note Default sensitivities value are obtained from device datasheet.
  567. *
  568. * @param[in] ip pointer to @p BaseGyroscope interface.
  569. *
  570. * @return The operation status.
  571. * @retval MSG_OK if the function succeeded.
  572. * @retval MSG_RESET otherwise.
  573. */
  574. static msg_t gyro_reset_sensivity(void *ip) {
  575. LSM6DS0Driver* devp;
  576. uint32_t i;
  577. msg_t msg = MSG_OK;
  578. osalDbgCheck(ip != NULL);
  579. /* Getting parent instance pointer.*/
  580. devp = objGetInstance(LSM6DS0Driver*, (BaseGyroscope*)ip);
  581. osalDbgAssert((devp->state == LSM6DS0_READY),
  582. "gyro_reset_sensivity(), invalid state");
  583. if(devp->config->gyrofullscale == LSM6DS0_GYRO_FS_245DPS)
  584. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++)
  585. devp->gyrosensitivity[i] = LSM6DS0_GYRO_SENS_245DPS;
  586. else if(devp->config->gyrofullscale == LSM6DS0_GYRO_FS_500DPS)
  587. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++)
  588. devp->gyrosensitivity[i] = LSM6DS0_GYRO_SENS_500DPS;
  589. else if(devp->config->gyrofullscale == LSM6DS0_GYRO_FS_2000DPS)
  590. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++)
  591. devp->gyrosensitivity[i] = LSM6DS0_GYRO_SENS_2000DPS;
  592. else {
  593. osalDbgAssert(FALSE, "gyro_reset_sensivity(), full scale issue");
  594. return MSG_RESET;
  595. }
  596. return msg;
  597. }
  598. /**
  599. * @brief Changes the LSM6DS0Driver gyroscope fullscale value.
  600. * @note This function also rescale sensitivities and biases based on
  601. * previous and next fullscale value.
  602. * @note A recalibration is highly suggested after calling this function.
  603. *
  604. * @param[in] devp pointer to @p BaseGyroscope interface.
  605. * @param[in] fs new fullscale value.
  606. *
  607. * @return The operation status.
  608. * @retval MSG_OK if the function succeeded.
  609. * @retval MSG_RESET otherwise.
  610. */
  611. static msg_t gyro_set_full_scale(LSM6DS0Driver *devp, lsm6ds0_gyro_fs_t fs) {
  612. float newfs, scale;
  613. uint8_t i, buff[2];
  614. msg_t msg = MSG_OK;
  615. osalDbgCheck(devp != NULL);
  616. osalDbgAssert((devp->state == LSM6DS0_READY),
  617. "gyro_set_full_scale(), invalid state");
  618. #if LSM6DS0_USE_I2C
  619. osalDbgAssert((devp->config->i2cp->state == I2C_READY),
  620. "gyro_set_full_scale(), channel not ready");
  621. #endif
  622. if(fs == LSM6DS0_GYRO_FS_245DPS) {
  623. newfs = LSM6DS0_GYRO_245DPS;
  624. }
  625. else if(fs == LSM6DS0_GYRO_FS_500DPS) {
  626. newfs = LSM6DS0_GYRO_500DPS;
  627. }
  628. else if(fs == LSM6DS0_GYRO_FS_2000DPS) {
  629. newfs = LSM6DS0_GYRO_2000DPS;
  630. }
  631. else {
  632. return MSG_RESET;
  633. }
  634. if(newfs != devp->gyrofullscale) {
  635. scale = newfs / devp->gyrofullscale;
  636. devp->gyrofullscale = newfs;
  637. #if LSM6DS0_USE_I2C
  638. #if LSM6DS0_SHARED_I2C
  639. i2cAcquireBus(devp->config->i2cp);
  640. i2cStart(devp->config->i2cp,
  641. devp->config->i2ccfg);
  642. #endif /* LSM6DS0_SHARED_I2C */
  643. /* Updating register.*/
  644. msg = lsm6ds0I2CReadRegister(devp->config->i2cp,
  645. devp->config->slaveaddress,
  646. LSM6DS0_AD_CTRL_REG1_G, &buff[1], 1);
  647. #if LSM6DS0_SHARED_I2C
  648. i2cReleaseBus(devp->config->i2cp);
  649. #endif /* LSM6DS0_SHARED_I2C */
  650. #endif /* LSM6DS0_USE_I2C */
  651. buff[1] &= ~(LSM6DS0_CTRL_REG1_G_FS_MASK);
  652. buff[1] |= fs;
  653. buff[0] = LSM6DS0_AD_CTRL_REG1_G;
  654. #if LSM6DS0_USE_I2C
  655. #if LSM6DS0_SHARED_I2C
  656. i2cAcquireBus(devp->config->i2cp);
  657. i2cStart(devp->config->i2cp,
  658. devp->config->i2ccfg);
  659. #endif /* LSM6DS0_SHARED_I2C */
  660. lsm6ds0I2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
  661. buff, 1);
  662. #if LSM6DS0_SHARED_I2C
  663. i2cReleaseBus(devp->config->i2cp);
  664. #endif /* LSM6DS0_SHARED_I2C */
  665. #endif /* LSM6DS0_USE_I2C */
  666. /* Scaling sensitivity and bias. Re-calibration is suggested anyway. */
  667. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++) {
  668. devp->gyrosensitivity[i] *= scale;
  669. devp->gyrobias[i] *= scale;
  670. }
  671. }
  672. return msg;
  673. }
  674. static const struct LSM6DS0VMT vmt_device = {
  675. (size_t)0,
  676. acc_set_full_scale, gyro_set_full_scale
  677. };
  678. static const struct BaseAccelerometerVMT vmt_accelerometer = {
  679. sizeof(struct LSM6DS0VMT*),
  680. acc_get_axes_number, acc_read_raw, acc_read_cooked,
  681. acc_set_bias, acc_reset_bias, acc_set_sensivity, acc_reset_sensivity
  682. };
  683. static const struct BaseGyroscopeVMT vmt_gyroscope = {
  684. sizeof(struct LSM6DS0VMT*) + sizeof(BaseAccelerometer),
  685. gyro_get_axes_number, gyro_read_raw, gyro_read_cooked,
  686. gyro_sample_bias, gyro_set_bias, gyro_reset_bias,
  687. gyro_set_sensivity, gyro_reset_sensivity
  688. };
  689. /*===========================================================================*/
  690. /* Driver exported functions. */
  691. /*===========================================================================*/
  692. /**
  693. * @brief Initializes an instance.
  694. *
  695. * @param[out] devp pointer to the @p LSM6DS0Driver object
  696. *
  697. * @init
  698. */
  699. void lsm6ds0ObjectInit(LSM6DS0Driver *devp) {
  700. devp->vmt = &vmt_device;
  701. devp->acc_if.vmt = &vmt_accelerometer;
  702. devp->gyro_if.vmt = &vmt_gyroscope;
  703. devp->config = NULL;
  704. devp->accaxes = LSM6DS0_ACC_NUMBER_OF_AXES;
  705. devp->gyroaxes = LSM6DS0_GYRO_NUMBER_OF_AXES;
  706. devp->state = LSM6DS0_STOP;
  707. }
  708. /**
  709. * @brief Configures and activates LSM6DS0 Complex Driver peripheral.
  710. *
  711. * @param[in] devp pointer to the @p LSM6DS0Driver object
  712. * @param[in] config pointer to the @p LSM6DS0Config object
  713. *
  714. * @api
  715. */
  716. void lsm6ds0Start(LSM6DS0Driver *devp, const LSM6DS0Config *config) {
  717. uint32_t i;
  718. uint8_t cr[5];
  719. osalDbgCheck((devp != NULL) && (config != NULL));
  720. osalDbgAssert((devp->state == LSM6DS0_STOP) ||
  721. (devp->state == LSM6DS0_READY),
  722. "lsm6ds0Start(), invalid state");
  723. devp->config = config;
  724. /* Configuring common registers.*/
  725. /* Control register 8 configuration block.*/
  726. {
  727. cr[0] = LSM6DS0_AD_CTRL_REG8;
  728. cr[1] = LSM6DS0_CTRL_REG8_IF_ADD_INC;
  729. #if LSM6DS0_USE_ADVANCED || defined(__DOXYGEN__)
  730. cr[1] |= devp->config->endianness | devp->config->blockdataupdate;
  731. #endif
  732. }
  733. #if LSM6DS0_USE_I2C
  734. #if LSM6DS0_SHARED_I2C
  735. i2cAcquireBus(devp->config->i2cp);
  736. #endif /* LSM6DS0_SHARED_I2C */
  737. i2cStart(devp->config->i2cp, devp->config->i2ccfg);
  738. lsm6ds0I2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
  739. cr, 1);
  740. #if LSM6DS0_SHARED_I2C
  741. i2cReleaseBus(devp->config->i2cp);
  742. #endif /* LSM6DS0_SHARED_I2C */
  743. #endif /* LSM6DS0_USE_I2C */
  744. /* Configuring Accelerometer subsystem.*/
  745. /* Multiple write starting address.*/
  746. cr[0] = LSM6DS0_AD_CTRL_REG5_XL;
  747. /* Control register 5 configuration block.*/
  748. {
  749. cr[1] = LSM6DS0_CTRL_REG5_XL_XEN_XL | LSM6DS0_CTRL_REG5_XL_YEN_XL |
  750. LSM6DS0_CTRL_REG5_XL_ZEN_XL;
  751. #if LSM6DS0_USE_ADVANCED || defined(__DOXYGEN__)
  752. cr[1] |= devp->config->accdecmode;
  753. #endif
  754. }
  755. /* Control register 6 configuration block.*/
  756. {
  757. cr[2] = devp->config->accoutdatarate |
  758. devp->config->accfullscale;
  759. }
  760. #if LSM6DS0_USE_I2C
  761. #if LSM6DS0_SHARED_I2C
  762. i2cAcquireBus(devp->config->i2cp);
  763. i2cStart(devp->config->i2cp, devp->config->i2ccfg);
  764. #endif /* LSM6DS0_SHARED_I2C */
  765. lsm6ds0I2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
  766. cr, 2);
  767. #if LSM6DS0_SHARED_I2C
  768. i2cReleaseBus(devp->config->i2cp);
  769. #endif /* LSM6DS0_SHARED_I2C */
  770. #endif /* LSM6DS0_USE_I2C */
  771. /* Storing sensitivity according to user settings */
  772. if(devp->config->accfullscale == LSM6DS0_ACC_FS_2G) {
  773. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++) {
  774. if(devp->config->accsensitivity == NULL)
  775. devp->accsensitivity[i] = LSM6DS0_ACC_SENS_2G;
  776. else
  777. devp->accsensitivity[i] = devp->config->accsensitivity[i];
  778. }
  779. devp->accfullscale = LSM6DS0_ACC_2G;
  780. }
  781. else if(devp->config->accfullscale == LSM6DS0_ACC_FS_4G) {
  782. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++) {
  783. if(devp->config->accsensitivity == NULL)
  784. devp->accsensitivity[i] = LSM6DS0_ACC_SENS_4G;
  785. else
  786. devp->accsensitivity[i] = devp->config->accsensitivity[i];
  787. }
  788. devp->accfullscale = LSM6DS0_ACC_4G;
  789. }
  790. else if(devp->config->accfullscale == LSM6DS0_ACC_FS_8G) {
  791. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++) {
  792. if(devp->config->accsensitivity == NULL)
  793. devp->accsensitivity[i] = LSM6DS0_ACC_SENS_8G;
  794. else
  795. devp->accsensitivity[i] = devp->config->accsensitivity[i];
  796. }
  797. devp->accfullscale = LSM6DS0_ACC_8G;
  798. }
  799. else if(devp->config->accfullscale == LSM6DS0_ACC_FS_16G) {
  800. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++) {
  801. if(devp->config->accsensitivity == NULL)
  802. devp->accsensitivity[i] = LSM6DS0_ACC_SENS_16G;
  803. else
  804. devp->accsensitivity[i] = devp->config->accsensitivity[i];
  805. }
  806. devp->accfullscale = LSM6DS0_ACC_16G;
  807. }
  808. else
  809. osalDbgAssert(FALSE, "lsm6ds0Start(), accelerometer full scale issue");
  810. /* Storing bias information */
  811. if(devp->config->accbias != NULL)
  812. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++)
  813. devp->accbias[i] = devp->config->accbias[i];
  814. else
  815. for(i = 0; i < LSM6DS0_ACC_NUMBER_OF_AXES; i++)
  816. devp->accbias[i] = LSM6DS0_ACC_BIAS;
  817. /* Configuring Gyroscope subsystem.*/
  818. /* Multiple write starting address.*/
  819. cr[0] = LSM6DS0_AD_CTRL_REG1_G;
  820. /* Control register 1 configuration block.*/
  821. {
  822. cr[1] = devp->config->gyrofullscale |
  823. devp->config->gyrooutdatarate;
  824. }
  825. /* Control register 2 configuration block.*/
  826. {
  827. cr[2] = 0;
  828. #if LSM6DS0_USE_ADVANCED || defined(__DOXYGEN__)
  829. cr[2] |= devp->config->gyrooutsel;
  830. #endif
  831. }
  832. /* Control register 3 configuration block.*/
  833. {
  834. cr[3] = 0;
  835. #if LSM6DS0_USE_ADVANCED || defined(__DOXYGEN__)
  836. cr[3] |= devp->config->gyrohpfenable |
  837. devp->config->gyrolowmodecfg |
  838. devp->config->gyrohpcfg;
  839. #endif
  840. }
  841. /* Control register 4 configuration block.*/
  842. {
  843. cr[4] = LSM6DS0_CTRL_REG4_XEN_G | LSM6DS0_CTRL_REG4_YEN_G |
  844. LSM6DS0_CTRL_REG4_ZEN_G;
  845. }
  846. #if LSM6DS0_USE_I2C
  847. #if LSM6DS0_SHARED_I2C
  848. i2cAcquireBus(devp->config->i2cp);
  849. i2cStart(devp->config->i2cp, devp->config->i2ccfg);
  850. #endif /* LSM6DS0_SHARED_I2C */
  851. lsm6ds0I2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
  852. cr, 4);
  853. #if LSM6DS0_SHARED_I2C
  854. i2cReleaseBus(devp->config->i2cp);
  855. #endif /* LSM6DS0_SHARED_I2C */
  856. #endif /* LSM6DS0_USE_I2C */
  857. cr[0] = LSM6DS0_AD_CTRL_REG9;
  858. /* Control register 9 configuration block.*/
  859. {
  860. cr[1] = 0;
  861. }
  862. #if LSM6DS0_USE_I2C
  863. #if LSM6DS0_SHARED_I2C
  864. i2cAcquireBus(devp->config->i2cp);
  865. i2cStart(devp->config->i2cp, devp->config->i2ccfg);
  866. #endif /* LSM6DS0_SHARED_I2C */
  867. lsm6ds0I2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
  868. cr, 1);
  869. #if LSM6DS0_SHARED_I2C
  870. i2cReleaseBus(devp->config->i2cp);
  871. #endif /* LSM6DS0_SHARED_I2C */
  872. #endif /* LSM6DS0_USE_I2C */
  873. if(devp->config->gyrofullscale == LSM6DS0_GYRO_FS_245DPS) {
  874. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++) {
  875. if(devp->config->gyrosensitivity == NULL)
  876. devp->gyrosensitivity[i] = LSM6DS0_GYRO_SENS_245DPS;
  877. else
  878. devp->gyrosensitivity[i] = devp->config->gyrosensitivity[i];
  879. }
  880. devp->gyrofullscale = LSM6DS0_GYRO_245DPS;
  881. }
  882. else if(devp->config->gyrofullscale == LSM6DS0_GYRO_FS_500DPS) {
  883. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++) {
  884. if(devp->config->gyrosensitivity == NULL)
  885. devp->gyrosensitivity[i] = LSM6DS0_GYRO_SENS_500DPS;
  886. else
  887. devp->gyrosensitivity[i] = devp->config->gyrosensitivity[i];
  888. }
  889. devp->gyrofullscale = LSM6DS0_GYRO_500DPS;
  890. }
  891. else if(devp->config->gyrofullscale == LSM6DS0_GYRO_FS_2000DPS) {
  892. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++) {
  893. if(devp->config->gyrosensitivity == NULL)
  894. devp->gyrosensitivity[i] = LSM6DS0_GYRO_SENS_2000DPS;
  895. else
  896. devp->gyrosensitivity[i] = devp->config->gyrosensitivity[i];
  897. }
  898. devp->gyrofullscale = LSM6DS0_GYRO_2000DPS;
  899. }
  900. else
  901. osalDbgAssert(FALSE, "lsm6ds0Start(), gyroscope full scale issue");
  902. /* Storing bias information */
  903. if(devp->config->gyrobias != NULL)
  904. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++)
  905. devp->gyrobias[i] = devp->config->gyrobias[i];
  906. else
  907. for(i = 0; i < LSM6DS0_GYRO_NUMBER_OF_AXES; i++)
  908. devp->gyrobias[i] = LSM6DS0_GYRO_BIAS;
  909. /* This is the MEMS transient recovery time */
  910. osalThreadSleepMilliseconds(5);
  911. devp->state = LSM6DS0_READY;
  912. }
  913. /**
  914. * @brief Deactivates the LSM6DS0 Complex Driver peripheral.
  915. *
  916. * @param[in] devp pointer to the @p LSM6DS0Driver object
  917. *
  918. * @api
  919. */
  920. void lsm6ds0Stop(LSM6DS0Driver *devp) {
  921. uint8_t cr[2];
  922. osalDbgCheck(devp != NULL);
  923. osalDbgAssert((devp->state == LSM6DS0_STOP) || (devp->state == LSM6DS0_READY),
  924. "lsm6ds0Stop(), invalid state");
  925. if (devp->state == LSM6DS0_READY) {
  926. #if LSM6DS0_USE_I2C
  927. #if LSM6DS0_SHARED_I2C
  928. i2cAcquireBus(devp->config->i2cp);
  929. i2cStart(devp->config->i2cp, devp->config->i2ccfg);
  930. #endif /* LSM6DS0_SHARED_I2C */
  931. /* Disabling accelerometer.*/
  932. cr[0] = LSM6DS0_AD_CTRL_REG6_XL;
  933. cr[1] = 0;
  934. lsm6ds0I2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
  935. cr, 1);
  936. /* Disabling gyroscope.*/
  937. cr[0] = LSM6DS0_AD_CTRL_REG9;
  938. cr[1] = LSM6DS0_CTRL_REG9_SLEEP_G;
  939. lsm6ds0I2CWriteRegister(devp->config->i2cp, devp->config->slaveaddress,
  940. cr, 1);
  941. i2cStop(devp->config->i2cp);
  942. #if LSM6DS0_SHARED_I2C
  943. i2cReleaseBus(devp->config->i2cp);
  944. #endif /* LSM6DS0_SHARED_I2C */
  945. #endif /* LSM6DS0_USE_I2C */
  946. }
  947. devp->state = LSM6DS0_STOP;
  948. }
  949. /** @} */