lsm6ds3.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /******************************************************************************
  2. * 2016 ideasX (Tyler Berezowsky and Marc Jurchak)
  3. *
  4. * FileName: LSM6DS3.c
  5. *
  6. * Description: SPIdriver for LSM6DS3
  7. * Modification history:
  8. * 2015/10/12, v1.0 created this file (Marc)
  9. * 2016/3/15, v1.1 added comments for Tyler.
  10. *******************************************************************************/
  11. #include "hal/lsm6ds3.h"
  12. #include "log/esp_log.h"
  13. static const char* TAG = "lsm6ds3.c";
  14. static int32_t ICACHE_FLASH_ATTR Sensor_IO_Write(uint16_t WriteAddr, uint8_t nBytesToWrite, uint32_t *pBuffer)
  15. {
  16. // Initalize HSPI Interface GPIO
  17. WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105);
  18. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);
  19. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);
  20. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);
  21. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);
  22. // Setup SPI Attributes Struct
  23. SpiAttr spiConfig;
  24. spiConfig.mode = SpiMode_Master;
  25. spiConfig.subMode = SpiSubMode_0;
  26. spiConfig.speed = SpiSpeed_8MHz;
  27. spiConfig.bitOrder = SpiBitOrder_MSBFirst;
  28. // Initalize SPI Interface
  29. SPIInit(SpiNum_HSPI, &spiConfig);
  30. // Setup SPI Data Struct
  31. SpiData spiData;
  32. uint32_t addr = (WriteAddr);
  33. spiData.cmd = addr;
  34. spiData.cmdLen = 1;
  35. spiData.addrLen = 0;
  36. spiData.addr = 0;
  37. spiData.data = pBuffer;
  38. spiData.dataLen = nBytesToWrite;
  39. // Write Data to SPI port
  40. return SPIMasterSendData(SpiNum_HSPI, &spiData);
  41. }
  42. static int32_t ICACHE_FLASH_ATTR Sensor_IO_Read(uint16_t ReadAddr, uint8_t nBytesToRead, uint32_t *pBuffer)
  43. {
  44. // Initalize HSPI Interface GPIO
  45. WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105);
  46. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);
  47. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);
  48. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);
  49. PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);
  50. // Setup SPI Attributes Struct
  51. SpiAttr spiConfig;
  52. spiConfig.mode = SpiMode_Master;
  53. spiConfig.subMode = SpiSubMode_0;
  54. spiConfig.speed = SpiSpeed_8MHz;
  55. spiConfig.bitOrder = SpiBitOrder_MSBFirst;
  56. // Initalize SPI Interface
  57. SPIInit(SpiNum_HSPI, &spiConfig);
  58. // Setup SPI Data Struct
  59. SpiData spiData;
  60. uint32_t addr = (ReadAddr | 0x80);
  61. spiData.cmd = addr;
  62. spiData.cmdLen = 1;
  63. spiData.addrLen = 0;
  64. spiData.addr = 0;
  65. spiData.data = pBuffer;
  66. spiData.dataLen = nBytesToRead;
  67. return SPIMasterRecvData(SpiNum_HSPI, &spiData);
  68. }
  69. static int32_t ICACHE_FLASH_ATTR Sensor_IO_Set_Register(uint16_t WriteAddr, uint32_t v0)
  70. {
  71. uint32_t v1;
  72. Sensor_IO_Write(WriteAddr, 1, &v0);
  73. Sensor_IO_Read(WriteAddr, 1, &v1);
  74. if (v0 == v1)
  75. return 0;
  76. else
  77. return -1;
  78. }
  79. /******************************************************************************
  80. * FunctionName : lsm6ds3_i2c_enable
  81. * Description : Setup LSM6DS3 registers for I2C sensor hub.
  82. * Parameters : uint8_t start
  83. 1: enable
  84. 0: disable
  85. * Returns : uint8_t 1: success 0: failed
  86. *******************************************************************************/
  87. int32_t ICACHE_FLASH_ATTR
  88. LSM6DS3_Enable_I2C_Pullups(uint8_t enable)
  89. {
  90. uint32_t ctrl10_c, master_config;
  91. Sensor_IO_Read(LSM6DS3_CTRL10_C, 1, &ctrl10_c);
  92. Sensor_IO_Read(LSM6DS3_MASTER_CONFIG, 1, &master_config);
  93. if (enable)
  94. {
  95. ctrl10_c |= LSM6DS3_FUNC_EN;
  96. //master_config |= (PULL_UP_EN + MASTER_ON);
  97. master_config |= LSM6DS3_PULL_UP_EN; // pull-ups on
  98. master_config &= ~LSM6DS3_MASTER_ON; // disable i2c master function?
  99. }
  100. else
  101. {
  102. ctrl10_c &= ~LSM6DS3_FUNC_EN;
  103. master_config &= ~(LSM6DS3_PULL_UP_EN + LSM6DS3_MASTER_ON);
  104. }
  105. return (Sensor_IO_Set_Register(LSM6DS3_CTRL10_C, ctrl10_c) & Sensor_IO_Set_Register(LSM6DS3_MASTER_CONFIG, master_config));
  106. }
  107. int32_t ICACHE_FLASH_ATTR
  108. LSM6DS3_Enable_I2C_Bridge(uint8_t enable)
  109. {
  110. LSM6DS3_Enable_I2C_Pullups(1);
  111. uint32_t master_config;
  112. Sensor_IO_Read(LSM6DS3_MASTER_CONFIG, 1, &master_config);
  113. if (enable)
  114. {
  115. master_config |= LSM6DS3_PASS_THROUGH_MODE;
  116. }
  117. else
  118. {
  119. master_config &= ~LSM6DS3_PASS_THROUGH_MODE;
  120. }
  121. ESP_LOGI(TAG, "Writing %x to LSM6DS3_MASTER_CONFIG", master_config);
  122. return Sensor_IO_Set_Register(LSM6DS3_MASTER_CONFIG, master_config);
  123. }
  124. // /******************************************************************************
  125. // * FunctionName : lsm6ds3_xl_config
  126. // * Description : Setup LSM6DS3 registers for accel. sample and other cool nonsense.
  127. // Note: 20ms is required from boot for the sensor to load some magic before you
  128. // can play.
  129. // * Parameters : bool en_hp_mode: Enable or Disable high performance mode. NOTE: HP mode is
  130. // is required for LP filter data and certain sampling rates.
  131. // odr_xl: Output data rate for XL. See .h file for available rates.
  132. // uint8_t scale_xl: Range of senstiviity selection. See .h file for available rates.
  133. // uint8_t bw_xl: Anti-aliasing LP filter selection. See .h file and datasheet.
  134. // * Returns : bool 1: success 0: failed
  135. // *******************************************************************************/
  136. // bool ICACHE_FLASH_ATTR
  137. // lsm6ds3_xl_config(bool en_hp_mode, uint8_t odr_xl, uint8_t scale_xl, uint8_t bw_xl)
  138. // {
  139. // uint8_t ctrl6_c = spi_rx8_address(HSPI, LSM6DS3_CTRL6_C);
  140. // uint8_t ctrl1_xl = odr_xl | scale_xl | bw_xl;
  141. //
  142. // if(en_hp_mode)
  143. // ctrl6_c &= ~LSM6DS3_XL_HM_MODE;
  144. // else
  145. // ctrl6_c |= LSM6DS3_XL_HM_MODE;
  146. // spi_tx8_address(HSPI, LSM6DS3_CTRL6_C, ctrl6_c);
  147. // spi_tx8_address(HSPI, LSM6DS3_CTRL1_XL, ctrl1_xl);
  148. // if ( (spi_rx8_address(HSPI, LSM6DS3_CTRL1_XL) == ctrl1_xl) & (spi_rx8_address(HSPI, LSM6DS3_CTRL6_C) == ctrl6_c) )
  149. // return 1;
  150. // else
  151. // return 0;
  152. // }
  153. // /******************************************************************************
  154. // * FunctionName : lsm6ds3_g_config
  155. // * Description : Setup LSM6DS3 registers for accel. sample and other cool nonsense.
  156. // Note: 20ms is required from boot for the sensor to load some magic before you
  157. // can play.
  158. // * Parameters : bool en_hp_mode: Enable or Disable high performance mode. NOTE: HP mode is
  159. // is required for LP filter data and certain sampling rates.
  160. // odr_xl: Output data rate for XL. See .h file for available rates.
  161. // uint8_t scale_xl: Range of senstiviity selection. See .h file for available rates.
  162. // uint8_t bw_xl: Anti-aliasing LP filter selection. See .h file and datasheet.
  163. // * Returns : bool 1: success 0: failed
  164. // *******************************************************************************/
  165. // bool ICACHE_FLASH_ATTR
  166. // lsm6ds3_g_config(bool en_hp_mode, bool hp_g_en, bool hp_g_rst,
  167. // uint8_t odr_g, uint8_t scale_g, uint8_t hpcf_g)
  168. // {
  169. // uint8_t ctrl7_g;
  170. // uint8_t ctrl2_g = odr_g | scale_g;
  171. //
  172. // if (en_hp_mode)
  173. // ctrl7_g = LSM6DS3_G_HM_MODE;
  174. // else
  175. // ctrl7_g &= ~LSM6DS3_G_HM_MODE;
  176. // if (hp_g_en)
  177. // ctrl7_g |= LSM6DS3_HP_G_EN | hpcf_g;
  178. // else
  179. // ctrl7_g &= ~LSM6DS3_HP_G_EN;
  180. // if (hp_g_rst)
  181. // ctrl7_g |= LSM6DS3_HP_G_RST;
  182. // else
  183. // ctrl7_g &= ~LSM6DS3_HP_G_RST;
  184. //
  185. // spi_tx8_address(HSPI, LSM6DS3_CTRL2_G, ctrl2_g);
  186. // spi_tx8_address(HSPI, LSM6DS3_CTRL7_G, ctrl7_g);
  187. // if ( (spi_rx8_address(HSPI, LSM6DS3_CTRL2_G) == ctrl2_g) & (spi_rx8_address(HSPI, LSM6DS3_CTRL7_G) == ctrl7_g))
  188. // return 1;
  189. // else
  190. // return 0;
  191. // }
  192. // /******************************************************************************
  193. // * FunctionName : lsm6ds3_fifo_config
  194. // * Description : Setup LSM6DS3 registers for FIFO. FIFO is automatically placed into continous mode.
  195. // Decimation is set to zero, and the ODR of the FIFO is set to match that max(XL_ODR, G_ODR)
  196. // INT1 is automatically enabled / disabled for FIFO overflow and threshold.
  197. // If FIFO is enable it will automatically disable the significant motion ISR.
  198. // * Parameters : bool enable: Enable or Disable FIFO
  199. // threshold: Set the threshold level of the FIFO
  200. // * Returns : bool 1: success 0: failed
  201. // *******************************************************************************/
  202. // bool ICACHE_FLASH_ATTR
  203. // lsm6ds3_fifo_config(uint16_t threshold)
  204. // {
  205. // uint8_t ctrl1_xl, ctrl2_g, max_odr, fifo_ctrl3;
  206. //
  207. // // read ODR rates
  208. // ctrl1_xl = spi_rx8_address(HSPI, LSM6DS3_CTRL1_XL) & 0xF0; // get ODR bits and clear the rest
  209. // ctrl2_g = spi_rx8_address(HSPI, LSM6DS3_CTRL2_G) & 0xF0; // get ODR bits and clear the rest
  210. // os_printf("CTRL1_XL, CTRL2_G: %x, %x\r\n", ctrl1_xl, ctrl2_g);
  211. // if (!(ctrl1_xl || ctrl2_g))
  212. // {
  213. // // disable FIFO
  214. // os_printf("LSM6DS3: XL and G disabled. FIFO disabled.\r\n");
  215. // lsm6ds3_set_register(LSM6DS3_FIFO_CTRL5, 0x00);
  216. // lsm6ds3_set_register(LSM6DS3_INT1_CTRL, 0x00); // disable INT1 for overflow and threshold
  217. //
  218. // }
  219. // else
  220. // {
  221. //
  222. // // set Decimation Factor to 1 if sensor is active
  223. // //lsm6ds3_set_register(FIFO_CTRL3, 0b00001001);
  224. //
  225. // // set threshold
  226. // lsm6ds3_set_register(LSM6DS3_FIFO_CTRL1, (uint8_t)(0xFF & threshold));
  227. // lsm6ds3_set_register(LSM6DS3_FIFO_CTRL2, (uint8_t)(0xFF & (threshold >> 8)));
  228. //
  229. // // set decimation factor to one if sensor ODR is not zero
  230. // fifo_ctrl3 = 0;
  231. // if (ctrl1_xl & 0xF0)
  232. // fifo_ctrl3 = BIT0;
  233. // if(ctrl2_g & 0xF0)
  234. // fifo_ctrl3 |= BIT3;
  235. // lsm6ds3_set_register(LSM6DS3_FIFO_CTRL3, fifo_ctrl3);
  236. // os_printf("FIFO_CTRL3: %x\r\n", fifo_ctrl3);
  237. //
  238. // // determine max ODR
  239. // if ( (ctrl1_xl) >= (ctrl2_g) )
  240. // max_odr = ctrl1_xl;
  241. // else
  242. // max_odr = ctrl2_g;
  243. // max_odr = max_odr >> 1; // format for fifo register
  244. // lsm6ds3_set_register(LSM6DS3_FIFO_CTRL5, max_odr | 0x06); // set FIFO ODR and mode to continously
  245. // lsm6ds3_set_register(LSM6DS3_INT1_CTRL, BIT3); // set INT1 for overflow and threshold
  246. // }
  247. // return 1;
  248. // }
  249. //
  250. // bool ICACHE_FLASH_ATTR lsm6ds3_reset(void)
  251. // {
  252. // lsm6ds3_set_register(LSM6DS3_CTRL3_C, BIT0);
  253. // os_delay_us(30000);
  254. // return !(bool)(spi_rx8_address(HSPI, LSM6DS3_CTRL3_C) & BIT7);
  255. // }
  256. //
  257. // uint16_t ICACHE_FLASH_ATTR lsm6ds3_fifo_dump(uint16_t *buf, uint16_t buf_len, uint16_t bufPos)
  258. // {
  259. // uint16_t samples = (uint16_t)spi_rx8_address(HSPI, LSM6DS3_FIFO_STATUS1);
  260. // samples |= (((uint16_t)spi_rx8_address(HSPI, LSM6DS3_FIFO_STATUS2) & 0x0F) << 8);
  261. //
  262. // // read and store into buff in multiples of 3
  263. // if (samples <= (buf_len - bufPos) && samples != 0)
  264. // {
  265. // uint16_t i;
  266. // for(i=bufPos; i<samples+bufPos; i++)
  267. // {
  268. // buf[i] = spi_rx16_address(HSPI, LSM6DS3_FIFO_DATA_OUT_L);
  269. // }
  270. // return samples;
  271. // }
  272. // else
  273. // return 0;
  274. //
  275. // }
  276. //
  277. //
  278. // uint8_t ICACHE_FLASH_ATTR lsm6ds3_fifo_getFlags(void)
  279. // {
  280. // /* There is (2) possible sources of interrupts caused by the IMU
  281. // that the ESP8266 actually cares about.
  282. // 1) The significant motion interrupt
  283. // 2) The FIFO interrupts
  284. //
  285. // LSM6DS3_FIFO_EMPTY
  286. // LSM6DS3_FIFO_FULL
  287. // LSM6DS3_FIFO_OVER_RUN
  288. // LSM6DS3_FIFO_THRESHOLD
  289. // */
  290. // return (uint8_t)spi_rx8_address(HSPI, LSM6DS3_FIFO_STATUS2);
  291. // }
  292. //
  293. // bool ICACHE_FLASH_ATTR lsm6ds3_read_motion(void)
  294. // {
  295. // uint8_t wake_up_src;
  296. // wake_up_src = SPIread(LSM6DS3_WAKE_UP_SRC);
  297. // //if (wake_up_src)
  298. // {
  299. // os_printf("WAKE_UP_SRC: %x\r\n", wake_up_src);
  300. // os_printf("Direction ");
  301. // if (wake_up_src & BIT2)
  302. // os_printf("x");
  303. // if (wake_up_src & BIT1)
  304. // os_printf("y");
  305. // if (wake_up_src & BIT0)
  306. // os_printf("z");
  307. //
  308. // os_printf("\r\n");
  309. // }
  310. // return wake_up_src & BIT3;
  311. // }
  312. //
  313. // bool ICACHE_FLASH_ATTR lsm6ds3_motion_enable(void)
  314. // {
  315. // SPIwrite(LSM6DS3_CTRL2_G, LSM6DS3_ODR_G_POWERDOWN); // disable gyro
  316. // SPIwrite(LSM6DS3_CTRL1_XL, (LSM6DS3_ODR_XL_13Hz + LSM6DS3_FS_XL_2G)); // 208Hz 2g scale
  317. // SPIwrite(LSM6DS3_TAP_CFG, LSM6DS3_LIR); // enable interuppt latch and slope filter
  318. // SPIwrite(LSM6DS3_WAKE_UP_THS, 0x01); // set thres 32/64*2G = 1G
  319. // SPIwrite(LSM6DS3_WAKE_UP_DUR, 0x02); // zero duration
  320. // SPIwrite(LSM6DS3_MD1_CFG, LSM6DS3_INT1_WU); // set interrupt for INTX (1 is connected to PBA)
  321. // SPIwrite(LSM6DS3_CTRL3_C, LSM6DS3_H_LACTIVE); // set int lines active low
  322. // os_printf("MOTION PROCESS: Setup IMU for motion detection\r\n");
  323. //
  324. // return 1;
  325. // }
  326. //
  327. // bool ICACHE_FLASH_ATTR lsm6ds3_motion_disable(void)
  328. // {
  329. // lsm6ds3_reset();
  330. // SPIwrite(LSM6DS3_CTRL2_G, LSM6DS3_ODR_G_POWERDOWN); // disable gyro
  331. // SPIwrite(LSM6DS3_CTRL1_XL, LSM6DS3_ODR_XL_POWERDOWN); // disable XL
  332. // SPIwrite(LSM6DS3_CTRL3_C, LSM6DS3_H_LACTIVE);
  333. // return 1;
  334. // }
  335. //
  336. // #if LSM6DS3_DEBUG
  337. // void ICACHE_FLASH_ATTR
  338. // lsm6ds3_xl_print(void)
  339. // {
  340. // os_printf("XL_X: %d\r\nXL_Y: %d\r\n XL_Z: %d\r\n",
  341. // (SPIread(LSM6DS3_OUTX_H_XL)<<8)+SPIread(LSM6DS3_OUTX_L_XL), (SPIread(LSM6DS3_OUTY_H_XL)<<8)+SPIread(LSM6DS3_OUTY_L_XL),
  342. // (SPIread(LSM6DS3_OUTZ_H_XL)<<8)+SPIread(LSM6DS3_OUTX_L_XL));
  343. // return;
  344. // }
  345. // #endif