lsm6dso.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include <furi_hal.h>
  2. #include "imu.h"
  3. #include "../../lib/lsm6dso-api/lsm6dso_reg.h"
  4. #define LSM6DSO_TAG "LSM6DO"
  5. #define LSM6DSO_DEV_ADDRESS (0x6B << 1)
  6. stmdev_ctx_t lsm6dso_ctx;
  7. int32_t lsm6dso_write_i2c(void* handle, uint8_t reg_addr, uint8_t* data, uint16_t len) {
  8. if(furi_hal_i2c_write_mem(handle, LSM6DSO_DEV_ADDRESS, reg_addr, data, len, 50))
  9. return 0;
  10. return -2;
  11. }
  12. int32_t lsm6dso_read_i2c(void* handle, uint8_t reg_addr, uint8_t* read_data, uint16_t len) {
  13. if(furi_hal_i2c_read_mem(handle, LSM6DSO_DEV_ADDRESS, reg_addr, read_data, len, 50))
  14. return 0;
  15. return -2;
  16. }
  17. bool lsm6dso_begin() {
  18. FURI_LOG_I(LSM6DSO_TAG, "Init LSM6DSOTR-C");
  19. if(!furi_hal_i2c_is_device_ready(&furi_hal_i2c_handle_external, LSM6DSO_DEV_ADDRESS, 50)) {
  20. FURI_LOG_E(LSM6DSO_TAG, "Not ready");
  21. return false;
  22. }
  23. lsm6dso_ctx.write_reg = lsm6dso_write_i2c;
  24. lsm6dso_ctx.read_reg = lsm6dso_read_i2c;
  25. lsm6dso_ctx.mdelay = furi_delay_ms;
  26. lsm6dso_ctx.handle = &furi_hal_i2c_handle_external;
  27. uint8_t whoami;
  28. lsm6dso_device_id_get(&lsm6dso_ctx, &whoami);
  29. if(whoami != LSM6DSO_ID) {
  30. FURI_LOG_I(LSM6DSO_TAG, "Unknown model: %x", (int)whoami);
  31. return false;
  32. }
  33. lsm6dso_reset_set(&lsm6dso_ctx, PROPERTY_ENABLE);
  34. uint8_t rst = PROPERTY_ENABLE;
  35. while(rst) lsm6dso_reset_get(&lsm6dso_ctx, &rst);
  36. lsm6dso_block_data_update_set(&lsm6dso_ctx, PROPERTY_ENABLE);
  37. lsm6dso_fifo_mode_set(&lsm6dso_ctx, LSM6DSO_BYPASS_MODE);
  38. lsm6dso_xl_data_rate_set(&lsm6dso_ctx, LSM6DSO_XL_ODR_104Hz);
  39. lsm6dso_xl_full_scale_set(&lsm6dso_ctx, LSM6DSO_4g);
  40. //lsm6dso_xl_lp1_bandwidth_set(&lsm6dso_ctx, LSM6DSO_XL_LP1_ODR_DIV_4);
  41. //lsm6dso_aux_gy_lp1_bandwidth_set() ???
  42. lsm6dso_gy_data_rate_set(&lsm6dso_ctx, LSM6DSO_GY_ODR_104Hz);
  43. lsm6dso_gy_full_scale_set(&lsm6dso_ctx, LSM6DSO_2000dps);
  44. lsm6dso_gy_power_mode_set(&lsm6dso_ctx, LSM6DSO_GY_HIGH_PERFORMANCE);
  45. //lsm6dso_gy_band_pass_set(&lsm6dso_ctx, LSM6DSO_LP2_ONLY);
  46. FURI_LOG_I(LSM6DSO_TAG, "Init OK");
  47. return true;
  48. }
  49. void lsm6dso_end() {
  50. lsm6dso_xl_data_rate_set(&lsm6dso_ctx, LSM6DSO_XL_ODR_OFF);
  51. lsm6dso_gy_data_rate_set(&lsm6dso_ctx, LSM6DSO_GY_ODR_OFF);
  52. }
  53. int lsm6dso_read(double* vec) {
  54. int ret = 0;
  55. int16_t data[3];
  56. lsm6dso_reg_t reg;
  57. lsm6dso_status_reg_get(&lsm6dso_ctx, &reg.status_reg);
  58. if(reg.status_reg.xlda) {
  59. lsm6dso_acceleration_raw_get(&lsm6dso_ctx, data);
  60. vec[2] = (double)lsm6dso_from_fs2_to_mg(data[0]) / 1000;
  61. vec[0] = (double)lsm6dso_from_fs2_to_mg(data[1]) / 1000;
  62. vec[1] = (double)lsm6dso_from_fs2_to_mg(data[2]) / 1000;
  63. ret |= ACC_DATA_READY;
  64. }
  65. if(reg.status_reg.gda) {
  66. lsm6dso_angular_rate_raw_get(&lsm6dso_ctx, data);
  67. vec[5] = (double)lsm6dso_from_fs2000_to_mdps(data[0]) * DEG_TO_RAD / 1000;
  68. vec[3] = (double)lsm6dso_from_fs2000_to_mdps(data[1]) * DEG_TO_RAD / 1000;
  69. vec[4] = (double)lsm6dso_from_fs2000_to_mdps(data[2]) * DEG_TO_RAD / 1000;
  70. ret |= GYR_DATA_READY;
  71. }
  72. return ret;
  73. }
  74. struct imu_t imu_lsm6dso = {
  75. LSM6DSO_DEV_ADDRESS,
  76. lsm6dso_begin,
  77. lsm6dso_end,
  78. lsm6dso_read,
  79. LSM6DSO_TAG
  80. };