lsm6dso.c 3.1 KB

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