DMP_ICM20948.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. /*************************************************************************
  2. Includes
  3. *************************************************************************/
  4. #include "DMP_ICM20948.h"
  5. #include <math.h>
  6. // InvenSense drivers and utils
  7. #include "Icm20948.h"
  8. #include "SensorTypes.h"
  9. #include "Icm20948MPUFifoControl.h"
  10. /*************************************************************************
  11. Variables
  12. *************************************************************************/
  13. uint8_t I2C_Address = 0x69;
  14. float gyro[3];
  15. bool gyro_data_ready = false;
  16. float accel[3];
  17. bool accel_data_ready = false;
  18. float mag[3];
  19. bool mag_data_ready = false;
  20. float grav[3];
  21. bool grav_data_ready = false;
  22. float lAccel[3];
  23. bool linearAccel_data_ready = false;
  24. float quat6[4];
  25. bool quat6_data_ready = false;
  26. float euler6[3];
  27. bool euler6_data_ready = false;
  28. float quat9[4];
  29. bool quat9_data_ready = false;
  30. float euler9[3];
  31. bool euler9_data_ready = false;
  32. int har;
  33. bool har_data_ready = false;
  34. unsigned long steps;
  35. bool steps_data_ready = false;
  36. /*************************************************************************
  37. Invensense Variables
  38. *************************************************************************/
  39. inv_icm20948_t icm_device;
  40. static int unscaled_bias[THREE_AXES * 2];
  41. static const float cfg_mounting_matrix[9] = {
  42. 1.f, 0, 0,
  43. 0, 1.f, 0,
  44. 0, 0, 1.f
  45. };
  46. int32_t cfg_acc_fsr = 4; // Default = +/- 4g. Valid ranges: 2, 4, 8, 16
  47. int32_t cfg_gyr_fsr = 2000; // Default = +/- 2000dps. Valid ranges: 250, 500, 1000, 2000
  48. static const uint8_t dmp3_image[] = {
  49. #include "icm20948_img.dmp3a.h"
  50. };
  51. /*************************************************************************
  52. Invensense Functions
  53. *************************************************************************/
  54. void check_rc(int rc, const char * msg_context)
  55. {
  56. if (rc < 0) {
  57. ///Serial.println("ICM20948 ERROR!");
  58. while (1);
  59. }
  60. }
  61. int load_dmp3(void)
  62. {
  63. int rc = 0;
  64. rc = inv_icm20948_load(&icm_device, dmp3_image, sizeof(dmp3_image));
  65. return rc;
  66. }
  67. void inv_icm20948_sleep_us(int us)
  68. {
  69. // delayMicroseconds(us);
  70. while(us--) /// !!! very weak implementation
  71. __ASM volatile ("NOP");
  72. }
  73. void inv_icm20948_sleep(int ms)
  74. {
  75. HAL_Delay(ms);
  76. }
  77. uint64_t inv_icm20948_get_time_us(void)
  78. {
  79. return HAL_GetTick()*1000;
  80. }
  81. //bool is_interface_SPI = false;
  82. void set_comm_interface()
  83. {
  84. // is_interface_SPI = IS_SPI;
  85. if (IS_SPI)
  86. {
  87. initiliaze_SPI();
  88. }
  89. else
  90. {
  91. initiliaze_I2C();
  92. }
  93. }
  94. inv_bool_t interface_is_SPI(void)
  95. {
  96. return IS_SPI;
  97. }
  98. //---------------------------------------------------------------------
  99. int idd_io_hal_read_reg(void *context, uint8_t reg, uint8_t *rbuffer, uint32_t rlen)
  100. {
  101. if (IS_SPI)
  102. {
  103. return spi_master_read_register(reg, rbuffer, rlen);
  104. }
  105. return i2c_master_read_register(I2C_Address, reg, rlen, rbuffer);
  106. }
  107. //---------------------------------------------------------------------
  108. int idd_io_hal_write_reg(void *context, uint8_t reg, const uint8_t *wbuffer, uint32_t wlen)
  109. {
  110. if (IS_SPI)
  111. {
  112. return spi_master_write_register(reg, wbuffer, wlen);
  113. }
  114. return i2c_master_write_register(I2C_Address, reg, wlen, wbuffer);
  115. }
  116. static void icm20948_apply_mounting_matrix(void)
  117. {
  118. int ii;
  119. for (ii = 0; ii < INV_ICM20948_SENSOR_MAX; ii++) {
  120. inv_icm20948_set_matrix(&icm_device, cfg_mounting_matrix, (inv_icm20948_sensor)ii);
  121. }
  122. }
  123. static void icm20948_set_fsr(void)
  124. {
  125. inv_icm20948_set_fsr(&icm_device, INV_ICM20948_SENSOR_RAW_ACCELEROMETER, (const void *)&cfg_acc_fsr);
  126. inv_icm20948_set_fsr(&icm_device, INV_ICM20948_SENSOR_ACCELEROMETER, (const void *)&cfg_acc_fsr);
  127. inv_icm20948_set_fsr(&icm_device, INV_ICM20948_SENSOR_RAW_GYROSCOPE, (const void *)&cfg_gyr_fsr);
  128. inv_icm20948_set_fsr(&icm_device, INV_ICM20948_SENSOR_GYROSCOPE, (const void *)&cfg_gyr_fsr);
  129. inv_icm20948_set_fsr(&icm_device, INV_ICM20948_SENSOR_GYROSCOPE_UNCALIBRATED, (const void *)&cfg_gyr_fsr);
  130. }
  131. int icm20948_sensor_setup(void)
  132. {
  133. int rc;
  134. uint8_t i, whoami = 0xff;
  135. inv_icm20948_soft_reset(&icm_device);
  136. // Get whoami number
  137. rc = inv_icm20948_get_whoami(&icm_device, &whoami);
  138. // Check if WHOAMI value corresponds to any value from EXPECTED_WHOAMI array
  139. for (i = 0; i < sizeof(EXPECTED_WHOAMI) / sizeof(EXPECTED_WHOAMI[0]); ++i) {
  140. if (whoami == EXPECTED_WHOAMI[i]) {
  141. break;
  142. }
  143. }
  144. if (i == sizeof(EXPECTED_WHOAMI) / sizeof(EXPECTED_WHOAMI[0])) {
  145. //Serial.print("Bad WHOAMI value = 0x");
  146. //Serial.println(whoami, HEX);
  147. return rc;
  148. }
  149. // Setup accel and gyro mounting matrix and associated angle for current board
  150. inv_icm20948_init_matrix(&icm_device);
  151. // set default power mode
  152. rc = inv_icm20948_initialize(&icm_device, dmp3_image, sizeof(dmp3_image));
  153. if (rc != 0) {
  154. //Serial.println("Icm20948 Initialization failed.");
  155. return rc;
  156. }
  157. // Configure and initialize the ICM20948 for normal use
  158. // Initialize auxiliary sensors
  159. inv_icm20948_register_aux_compass( &icm_device, INV_ICM20948_COMPASS_ID_AK09916, AK0991x_DEFAULT_I2C_ADDR);
  160. rc = inv_icm20948_initialize_auxiliary(&icm_device);
  161. if (rc == -1) {
  162. //Serial.println("Compass not detected...");
  163. }
  164. icm20948_apply_mounting_matrix();
  165. icm20948_set_fsr();
  166. // re-initialize base state structure
  167. inv_icm20948_init_structure(&icm_device);
  168. return 0;
  169. }
  170. static uint8_t icm20948_get_grv_accuracy(void)
  171. {
  172. uint8_t accel_accuracy;
  173. uint8_t gyro_accuracy;
  174. accel_accuracy = (uint8_t)inv_icm20948_get_accel_accuracy();
  175. gyro_accuracy = (uint8_t)inv_icm20948_get_gyro_accuracy();
  176. return (min(accel_accuracy, gyro_accuracy));
  177. }
  178. static uint8_t convert_to_generic_ids[INV_ICM20948_SENSOR_MAX] = {
  179. INV_SENSOR_TYPE_ACCELEROMETER,
  180. INV_SENSOR_TYPE_GYROSCOPE,
  181. INV_SENSOR_TYPE_RAW_ACCELEROMETER,
  182. INV_SENSOR_TYPE_RAW_GYROSCOPE,
  183. INV_SENSOR_TYPE_UNCAL_MAGNETOMETER,
  184. INV_SENSOR_TYPE_UNCAL_GYROSCOPE,
  185. INV_SENSOR_TYPE_BAC,
  186. INV_SENSOR_TYPE_STEP_DETECTOR,
  187. INV_SENSOR_TYPE_STEP_COUNTER,
  188. INV_SENSOR_TYPE_GAME_ROTATION_VECTOR,
  189. INV_SENSOR_TYPE_ROTATION_VECTOR,
  190. INV_SENSOR_TYPE_GEOMAG_ROTATION_VECTOR,
  191. INV_SENSOR_TYPE_MAGNETOMETER,
  192. INV_SENSOR_TYPE_SMD,
  193. INV_SENSOR_TYPE_PICK_UP_GESTURE,
  194. INV_SENSOR_TYPE_TILT_DETECTOR,
  195. INV_SENSOR_TYPE_GRAVITY,
  196. INV_SENSOR_TYPE_LINEAR_ACCELERATION,
  197. INV_SENSOR_TYPE_ORIENTATION,
  198. INV_SENSOR_TYPE_B2S
  199. };
  200. void build_sensor_event_data(void * context, enum inv_icm20948_sensor sensortype, uint64_t timestamp, const void * data, const void *arg)
  201. {
  202. float raw_bias_data[6];
  203. inv_sensor_event_t event;
  204. (void)context;
  205. uint8_t sensor_id = convert_to_generic_ids[sensortype];
  206. memset((void *)&event, 0, sizeof(event));
  207. event.sensor = sensor_id;
  208. event.timestamp = timestamp;
  209. switch (sensor_id)
  210. {
  211. case INV_SENSOR_TYPE_UNCAL_GYROSCOPE:
  212. memcpy(raw_bias_data, data, sizeof(raw_bias_data));
  213. memcpy(event.data.gyr.vect, &raw_bias_data[0], sizeof(event.data.gyr.vect));
  214. memcpy(event.data.gyr.bias, &raw_bias_data[3], sizeof(event.data.gyr.bias));
  215. memcpy(&(event.data.gyr.accuracy_flag), arg, sizeof(event.data.gyr.accuracy_flag));
  216. break;
  217. case INV_SENSOR_TYPE_UNCAL_MAGNETOMETER:
  218. memcpy(raw_bias_data, data, sizeof(raw_bias_data));
  219. memcpy(event.data.mag.vect, &raw_bias_data[0], sizeof(event.data.mag.vect));
  220. memcpy(event.data.mag.bias, &raw_bias_data[3], sizeof(event.data.mag.bias));
  221. memcpy(&(event.data.gyr.accuracy_flag), arg, sizeof(event.data.gyr.accuracy_flag));
  222. break;
  223. case INV_SENSOR_TYPE_GYROSCOPE:
  224. memcpy(event.data.gyr.vect, data, sizeof(event.data.gyr.vect));
  225. memcpy(&(event.data.gyr.accuracy_flag), arg, sizeof(event.data.gyr.accuracy_flag));
  226. // WE WANT THIS
  227. gyro[0] = event.data.gyr.vect[0];
  228. gyro[1] = event.data.gyr.vect[1];
  229. gyro[2] = event.data.gyr.vect[2];
  230. gyro_data_ready = true;
  231. break;
  232. case INV_SENSOR_TYPE_GRAVITY:
  233. memcpy(event.data.grav.vect, data, sizeof(event.data.grav.vect));
  234. event.data.grav.accuracy_flag = inv_icm20948_get_accel_accuracy();
  235. grav[0] = event.data.grav.vect[0];
  236. grav[1] = event.data.grav.vect[1];
  237. grav[2] = event.data.grav.vect[2];
  238. grav_data_ready = true;
  239. //add gravity
  240. break;
  241. case INV_SENSOR_TYPE_LINEAR_ACCELERATION:
  242. memcpy(event.data.linAcc.vect, data, sizeof(event.data.linAcc.vect));
  243. memcpy(&(event.data.linAcc.accuracy_flag), arg, sizeof(event.data.linAcc.accuracy_flag));
  244. // WE WANT THIS
  245. lAccel[0] = event.data.linAcc.vect[0];
  246. lAccel[1] = event.data.linAcc.vect[1];
  247. lAccel[2] = event.data.linAcc.vect[2];
  248. linearAccel_data_ready = true;
  249. break;
  250. //add linear acceleration
  251. case INV_SENSOR_TYPE_ACCELEROMETER:
  252. memcpy(event.data.acc.vect, data, sizeof(event.data.acc.vect));
  253. memcpy(&(event.data.acc.accuracy_flag), arg, sizeof(event.data.acc.accuracy_flag));
  254. // WE WANT THIS
  255. accel[0] = event.data.acc.vect[0];
  256. accel[1] = event.data.acc.vect[1];
  257. accel[2] = event.data.acc.vect[2];
  258. accel_data_ready = true;
  259. break;
  260. case INV_SENSOR_TYPE_MAGNETOMETER:
  261. memcpy(event.data.mag.vect, data, sizeof(event.data.mag.vect));
  262. memcpy(&(event.data.mag.accuracy_flag), arg, sizeof(event.data.mag.accuracy_flag));
  263. // WE WANT THIS
  264. mag[0] = event.data.mag.vect[0];
  265. mag[1] = event.data.mag.vect[1];
  266. mag[2] = event.data.mag.vect[2];
  267. mag_data_ready = true;
  268. break;
  269. case INV_SENSOR_TYPE_GEOMAG_ROTATION_VECTOR:
  270. case INV_SENSOR_TYPE_ROTATION_VECTOR:
  271. memcpy(&(event.data.quaternion9DOF.accuracy), arg, sizeof(event.data.quaternion9DOF.accuracy));
  272. memcpy(event.data.quaternion9DOF.quat, data, sizeof(event.data.quaternion9DOF.quat));
  273. quat9[0] = event.data.quaternion9DOF.quat[0];
  274. quat9[1] = event.data.quaternion9DOF.quat[1];
  275. quat9[2] = event.data.quaternion9DOF.quat[2];
  276. quat9[3] = event.data.quaternion9DOF.quat[3];
  277. quat9_data_ready = true;
  278. euler9_data_ready = true;
  279. break;
  280. case INV_SENSOR_TYPE_GAME_ROTATION_VECTOR:
  281. memcpy(event.data.quaternion6DOF.quat, data, sizeof(event.data.quaternion6DOF.quat));
  282. event.data.quaternion6DOF.accuracy_flag = icm20948_get_grv_accuracy();
  283. // WE WANT THIS
  284. quat6[0] = event.data.quaternion6DOF.quat[0];
  285. quat6[1] = event.data.quaternion6DOF.quat[1];
  286. quat6[2] = event.data.quaternion6DOF.quat[2];
  287. quat6[3] = event.data.quaternion6DOF.quat[3];
  288. quat6_data_ready = true;
  289. euler6_data_ready = true;
  290. break;
  291. case INV_SENSOR_TYPE_BAC:
  292. memcpy(&(event.data.bac.event), data, sizeof(event.data.bac.event));
  293. har = event.data.bac.event;
  294. har_data_ready = true;
  295. break;
  296. case INV_SENSOR_TYPE_PICK_UP_GESTURE:
  297. case INV_SENSOR_TYPE_TILT_DETECTOR:
  298. case INV_SENSOR_TYPE_STEP_DETECTOR:
  299. case INV_SENSOR_TYPE_SMD:
  300. event.data.event = true;
  301. break;
  302. case INV_SENSOR_TYPE_B2S:
  303. event.data.event = true;
  304. memcpy(&(event.data.b2s.direction), data, sizeof(event.data.b2s.direction));
  305. break;
  306. case INV_SENSOR_TYPE_STEP_COUNTER:
  307. memcpy(&(event.data.step.count), data, sizeof(event.data.step.count));
  308. steps = event.data.step.count;
  309. steps_data_ready = true;
  310. break;
  311. case INV_SENSOR_TYPE_ORIENTATION:
  312. //we just want to copy x,y,z from orientation data
  313. memcpy(&(event.data.orientation), data, 3 * sizeof(float));
  314. break;
  315. case INV_SENSOR_TYPE_RAW_ACCELEROMETER:
  316. case INV_SENSOR_TYPE_RAW_GYROSCOPE:
  317. memcpy(event.data.raw3d.vect, data, sizeof(event.data.raw3d.vect));
  318. break;
  319. default:
  320. return;
  321. }
  322. }
  323. static enum inv_icm20948_sensor idd_sensortype_conversion(int sensor)
  324. {
  325. switch (sensor)
  326. {
  327. case INV_SENSOR_TYPE_RAW_ACCELEROMETER:
  328. return INV_ICM20948_SENSOR_RAW_ACCELEROMETER;
  329. case INV_SENSOR_TYPE_RAW_GYROSCOPE:
  330. return INV_ICM20948_SENSOR_RAW_GYROSCOPE;
  331. case INV_SENSOR_TYPE_ACCELEROMETER:
  332. return INV_ICM20948_SENSOR_ACCELEROMETER;
  333. case INV_SENSOR_TYPE_GYROSCOPE:
  334. return INV_ICM20948_SENSOR_GYROSCOPE;
  335. case INV_SENSOR_TYPE_UNCAL_MAGNETOMETER:
  336. return INV_ICM20948_SENSOR_MAGNETIC_FIELD_UNCALIBRATED;
  337. case INV_SENSOR_TYPE_UNCAL_GYROSCOPE:
  338. return INV_ICM20948_SENSOR_GYROSCOPE_UNCALIBRATED;
  339. case INV_SENSOR_TYPE_BAC:
  340. return INV_ICM20948_SENSOR_ACTIVITY_CLASSIFICATON;
  341. case INV_SENSOR_TYPE_STEP_DETECTOR:
  342. return INV_ICM20948_SENSOR_STEP_DETECTOR;
  343. case INV_SENSOR_TYPE_STEP_COUNTER:
  344. return INV_ICM20948_SENSOR_STEP_COUNTER;
  345. case INV_SENSOR_TYPE_GAME_ROTATION_VECTOR:
  346. return INV_ICM20948_SENSOR_GAME_ROTATION_VECTOR;
  347. case INV_SENSOR_TYPE_ROTATION_VECTOR:
  348. return INV_ICM20948_SENSOR_ROTATION_VECTOR;
  349. case INV_SENSOR_TYPE_GEOMAG_ROTATION_VECTOR:
  350. return INV_ICM20948_SENSOR_GEOMAGNETIC_ROTATION_VECTOR;
  351. case INV_SENSOR_TYPE_MAGNETOMETER:
  352. return INV_ICM20948_SENSOR_GEOMAGNETIC_FIELD;
  353. case INV_SENSOR_TYPE_SMD:
  354. return INV_ICM20948_SENSOR_WAKEUP_SIGNIFICANT_MOTION;
  355. case INV_SENSOR_TYPE_PICK_UP_GESTURE:
  356. return INV_ICM20948_SENSOR_FLIP_PICKUP;
  357. case INV_SENSOR_TYPE_TILT_DETECTOR:
  358. return INV_ICM20948_SENSOR_WAKEUP_TILT_DETECTOR;
  359. case INV_SENSOR_TYPE_GRAVITY:
  360. return INV_ICM20948_SENSOR_GRAVITY;
  361. case INV_SENSOR_TYPE_LINEAR_ACCELERATION:
  362. return INV_ICM20948_SENSOR_LINEAR_ACCELERATION;
  363. case INV_SENSOR_TYPE_ORIENTATION:
  364. return INV_ICM20948_SENSOR_ORIENTATION;
  365. case INV_SENSOR_TYPE_B2S:
  366. return INV_ICM20948_SENSOR_B2S;
  367. default:
  368. return INV_ICM20948_SENSOR_MAX;
  369. }
  370. }
  371. /*************************************************************************
  372. Class Functions
  373. *************************************************************************/
  374. DMP_ICM20948::DMP_ICM20948()
  375. {
  376. }
  377. void DMP_ICM20948::init(DMP_ICM20948Settings settings)
  378. {
  379. set_comm_interface();
  380. ///Serial.println("Initializing ICM-20948...");
  381. // Initialize icm20948 serif structure
  382. struct inv_icm20948_serif icm20948_serif;
  383. icm20948_serif.context = 0; // no need
  384. icm20948_serif.read_reg = idd_io_hal_read_reg;
  385. icm20948_serif.write_reg = idd_io_hal_write_reg;
  386. icm20948_serif.max_read = 1024 * 16; // maximum number of bytes allowed per serial read
  387. icm20948_serif.max_write = 1024 * 16; // maximum number of bytes allowed per serial write
  388. icm20948_serif.is_spi = interface_is_SPI();
  389. // Reset icm20948 driver states
  390. inv_icm20948_reset_states(&icm_device, &icm20948_serif);
  391. inv_icm20948_register_aux_compass(&icm_device, INV_ICM20948_COMPASS_ID_AK09916, AK0991x_DEFAULT_I2C_ADDR);
  392. // Setup the icm20948 device
  393. int rc = icm20948_sensor_setup();
  394. if (icm_device.selftest_done && !icm_device.offset_done)
  395. {
  396. // If we've run self test and not already set the offset.
  397. inv_icm20948_set_offset(&icm_device, unscaled_bias);
  398. icm_device.offset_done = 1;
  399. }
  400. // Now that Icm20948 device is initialized, we can proceed with DMP image loading
  401. // This step is mandatory as DMP image is not stored in non volatile memory
  402. rc += load_dmp3();
  403. check_rc(rc, "Error sensor_setup/DMP loading.");
  404. // Set mode
  405. inv_icm20948_set_lowpower_or_highperformance(&icm_device, settings.mode);
  406. // Set frequency
  407. rc = inv_icm20948_set_sensor_period(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_GYROSCOPE), 1000 / settings.gyroscope_frequency);
  408. rc = inv_icm20948_set_sensor_period(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_ACCELEROMETER), 1000 / settings.accelerometer_frequency);
  409. rc = inv_icm20948_set_sensor_period(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_MAGNETOMETER), 1000 / settings.magnetometer_frequency);
  410. rc = inv_icm20948_set_sensor_period(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_GAME_ROTATION_VECTOR), 1000 / settings.quaternion6_frequency);
  411. rc = inv_icm20948_set_sensor_period(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_ROTATION_VECTOR), 1000 / settings.quaternion9_frequency);
  412. rc = inv_icm20948_set_sensor_period(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_GRAVITY), 1000 / settings.gravity_frequency);
  413. rc = inv_icm20948_set_sensor_period(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_LINEAR_ACCELERATION), 1000 / settings.linearAcceleration_frequency);
  414. rc = inv_icm20948_set_sensor_period(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_BAC), 1000 / settings.har_frequency);
  415. rc = inv_icm20948_set_sensor_period(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_STEP_COUNTER), 1000 / settings.steps_frequency);
  416. // Enable / disable
  417. rc = inv_icm20948_enable_sensor(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_GYROSCOPE), settings.enable_gyroscope);
  418. rc = inv_icm20948_enable_sensor(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_ACCELEROMETER), settings.enable_accelerometer);
  419. rc = inv_icm20948_enable_sensor(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_MAGNETOMETER), settings.enable_magnetometer);
  420. rc = inv_icm20948_enable_sensor(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_GAME_ROTATION_VECTOR), settings.enable_quaternion6);
  421. rc = inv_icm20948_enable_sensor(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_ROTATION_VECTOR), settings.enable_quaternion9);
  422. rc = inv_icm20948_enable_sensor(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_GRAVITY), settings.enable_gravity);
  423. rc = inv_icm20948_enable_sensor(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_LINEAR_ACCELERATION), settings.enable_linearAcceleration);
  424. rc = inv_icm20948_enable_sensor(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_BAC), settings.enable_har);
  425. rc = inv_icm20948_enable_sensor(&icm_device, idd_sensortype_conversion(INV_SENSOR_TYPE_STEP_COUNTER), settings.enable_steps);
  426. }
  427. void DMP_ICM20948::task()
  428. {
  429. inv_icm20948_poll_sensor(&icm_device, (void*)0, build_sensor_event_data);
  430. }
  431. bool DMP_ICM20948::gyroDataIsReady()
  432. {
  433. return gyro_data_ready;
  434. }
  435. bool DMP_ICM20948::accelDataIsReady()
  436. {
  437. return accel_data_ready;
  438. }
  439. bool DMP_ICM20948::magDataIsReady()
  440. {
  441. return mag_data_ready;
  442. }
  443. bool DMP_ICM20948::linearAccelDataIsReady()
  444. {
  445. return linearAccel_data_ready;
  446. }
  447. bool DMP_ICM20948::gravDataIsReady()
  448. {
  449. return grav_data_ready;
  450. }
  451. bool DMP_ICM20948::quat6DataIsReady()
  452. {
  453. return quat6_data_ready;
  454. }
  455. bool DMP_ICM20948::euler6DataIsReady()
  456. {
  457. return euler6_data_ready;
  458. }
  459. bool DMP_ICM20948::quat9DataIsReady()
  460. {
  461. return quat9_data_ready;
  462. }
  463. bool DMP_ICM20948::euler9DataIsReady()
  464. {
  465. return euler9_data_ready;
  466. }
  467. bool DMP_ICM20948::harDataIsReady()
  468. {
  469. return har_data_ready;
  470. }
  471. bool DMP_ICM20948::stepsDataIsReady()
  472. {
  473. return steps_data_ready;
  474. }
  475. void DMP_ICM20948::readGyroData(float *x, float *y, float *z)
  476. {
  477. *x = gyro[0];
  478. *y = gyro[1];
  479. *z = gyro[2];
  480. gyro_data_ready = false;
  481. }
  482. void DMP_ICM20948::readAccelData(float *x, float *y, float *z)
  483. {
  484. *x = accel[0];
  485. *y = accel[1];
  486. *z = accel[2];
  487. accel_data_ready = false;
  488. }
  489. void DMP_ICM20948::readMagData(float *x, float *y, float *z)
  490. {
  491. *x = mag[0];
  492. *y = mag[1];
  493. *z = mag[2];
  494. mag_data_ready = false;
  495. }
  496. void DMP_ICM20948::readLinearAccelData(float* x, float* y, float* z)
  497. {
  498. *x = lAccel[0];
  499. *y = lAccel[1];
  500. *z = lAccel[2];
  501. linearAccel_data_ready = false;
  502. }
  503. void DMP_ICM20948::readGravData(float* x, float* y, float* z)
  504. {
  505. *x = grav[0];
  506. *y = grav[1];
  507. *z = grav[2];
  508. grav_data_ready = false;
  509. }
  510. void DMP_ICM20948::readQuat6Data(float *w, float *x, float *y, float *z)
  511. {
  512. *w = quat6[0];
  513. *x = quat6[1];
  514. *y = quat6[2];
  515. *z = quat6[3];
  516. quat6_data_ready = false;
  517. }
  518. void DMP_ICM20948::readEuler6Data(float *roll, float *pitch, float *yaw)
  519. {
  520. *roll = (atan2f(quat6[0]*quat6[1] + quat6[2]*quat6[3], 0.5f - quat6[1]*quat6[1] - quat6[2]*quat6[2]))* 57.29578f;
  521. *pitch = (asinf(-2.0f * (quat6[1]*quat6[3] - quat6[0]*quat6[2])))* 57.29578f;
  522. *yaw = (atan2f(quat6[1]*quat6[2] + quat6[0]*quat6[3], 0.5f - quat6[2]*quat6[2] - quat6[3]*quat6[3]))* 57.29578f + 180.0f;
  523. euler6_data_ready = false;
  524. }
  525. void DMP_ICM20948::readQuat9Data(float* w, float* x, float* y, float* z)
  526. {
  527. *w = quat9[0];
  528. *x = quat9[1];
  529. *y = quat9[2];
  530. *z = quat9[3];
  531. quat9_data_ready = false;
  532. }
  533. void DMP_ICM20948::readEuler9Data(float* roll, float* pitch, float* yaw)
  534. {
  535. *roll = (atan2f(quat9[0] * quat9[1] + quat9[2] * quat9[3], 0.5f - quat9[1] * quat9[1] - quat9[2] * quat9[2])) * 57.29578f;
  536. *pitch = (asinf(-2.0f * (quat9[1] * quat9[3] - quat9[0] * quat9[2]))) * 57.29578f;
  537. *yaw = (atan2f(quat9[1] * quat9[2] + quat9[0] * quat9[3], 0.5f - quat9[2] * quat9[2] - quat9[3] * quat9[3])) * 57.29578f + 180.0f;
  538. euler9_data_ready = false;
  539. }
  540. void DMP_ICM20948::readHarData(char* activity)
  541. {
  542. char temp = 'n';
  543. switch (har)
  544. {
  545. case 1:
  546. temp = 'd';
  547. break;
  548. case 2:
  549. temp = 'w';
  550. break;
  551. case 3:
  552. temp = 'r';
  553. break;
  554. case 4:
  555. temp = 'b';
  556. break;
  557. case 5:
  558. temp = 't';
  559. break;
  560. case 6:
  561. temp = 's';
  562. break;
  563. }
  564. *activity = temp;
  565. har_data_ready = false;
  566. }
  567. void DMP_ICM20948::readStepsData(unsigned long* step_count)
  568. {
  569. *step_count = steps;
  570. steps_data_ready = false;
  571. }