lsm6ds3.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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. void ICACHE_FLASH_ATTR LSM6DS3_Reset(void)
  125. {
  126. Sensor_IO_Set_Register(LSM6DS3_CTRL3_C, BIT0);
  127. os_delay_us(30000);
  128. }
  129. void ICACHE_FLASH_ATTR LSM6DS3_EnableMotion(void)
  130. {
  131. LSM6DS3_Reset();
  132. Sensor_IO_Set_Register(LSM6DS3_CTRL2_G, LSM6DS3_ODR_G_POWERDOWN); // disable gyro
  133. Sensor_IO_Set_Register(LSM6DS3_CTRL1_XL, (LSM6DS3_ODR_XL_13Hz + LSM6DS3_FS_XL_2G)); // 208Hz 2g scale
  134. Sensor_IO_Set_Register(LSM6DS3_CTRL3_C, (LSM6DS3_H_LACTIVE + LSM6DS3_PP_OD)); // set int lines active low and open drain
  135. Sensor_IO_Set_Register(LSM6DS3_TAP_CFG, LSM6DS3_LIR); // enable interuppt latch and slope filter
  136. Sensor_IO_Set_Register(LSM6DS3_WAKE_UP_THS, 0x01); // set thres 32/64*2G = 1G
  137. Sensor_IO_Set_Register(LSM6DS3_WAKE_UP_DUR, 0x02); // zero duration
  138. Sensor_IO_Set_Register(LSM6DS3_MD1_CFG, LSM6DS3_INT1_WU); // set interrupt for INTX (1 is connected to PBA)
  139. }
  140. void ICACHE_FLASH_ATTR LSM6DS3_DisableMotion(void)
  141. {
  142. LSM6DS3_Reset();
  143. Sensor_IO_Set_Register(LSM6DS3_CTRL2_G, LSM6DS3_ODR_G_POWERDOWN); // disable gyro
  144. Sensor_IO_Set_Register(LSM6DS3_CTRL1_XL, LSM6DS3_ODR_XL_POWERDOWN); // disable XL
  145. Sensor_IO_Set_Register(LSM6DS3_CTRL3_C, (LSM6DS3_H_LACTIVE + LSM6DS3_PP_OD)); // set int lines active low and open drain
  146. Sensor_IO_Set_Register(LSM6DS3_TAP_CFG, 0);
  147. Sensor_IO_Set_Register(LSM6DS3_MD1_CFG, 0); // clear all interrupt vectors (the reset registers aren't cleared on reset?)
  148. }
  149. // determine if there has been a FIFO or significant motion interrupt
  150. LSM6DS3_Interrupt_et ICACHE_FLASH_ATTR LSM6DS3_Get_Interrupts(void)
  151. {
  152. uint32_t fifo_status2, wake_up_src, md1_cfg;
  153. Sensor_IO_Read(LSM6DS3_FIFO_STATUS2, 1, &fifo_status2);
  154. Sensor_IO_Read(LSM6DS3_WAKE_UP_SRC, 1, &wake_up_src);
  155. Sensor_IO_Read(LSM6DS3_MD1_CFG, 1, &md1_cfg); // set interrupt for INTX (1 is connected to PBA)
  156. // ESP_LOGV(TAG, "WAKE_UP: %x", wake_up_src);
  157. // ESP_LOGV(TAG, "FIFO_STATUS: %x", fifo_status2);
  158. // ESP_LOGV(TAG, "MD1 CFG: %x", md1_cfg);
  159. if ((wake_up_src & 0x0F) && (md1_cfg & LSM6DS3_INT1_WU))
  160. {
  161. ESP_LOGV(TAG, "significant motion interrupt");
  162. return LSM6DS3_SIGN_MOTION_INT;
  163. }
  164. else if (fifo_status2 & LSM6DS3_FIFO_OVER_RUN)
  165. {
  166. ESP_LOGV(TAG, "FIFO overflow interrupt");
  167. return LSM6DS3_FIFO_OVERFLOW_INT;
  168. }
  169. else if (fifo_status2 & LSM6DS3_FIFO_FULL)
  170. {
  171. ESP_LOGV(TAG, "FIFO full interrupt");
  172. return LSM6DS3_FIFO_FULL_INT;
  173. }
  174. else
  175. {
  176. return LSM6DS3_NO_INT;
  177. }
  178. }