@@ -75,6 +75,14 @@ enum class GyroscopeODR : uint8_t {
75
75
ODR_12_5_HZ = 12 , // /< 12.5 Hz
76
76
};
77
77
78
+ // / Digital Motion Processor (DMP) output data rate
79
+ enum class DmpODR : uint8_t {
80
+ ODR_25_HZ = 0 , // /< 25 Hz
81
+ ODR_400_HZ = 1 , // /< 200 Hz
82
+ ODR_50_HZ = 2 , // /< 50 Hz
83
+ ODR_100_HZ = 3 , // /< 100 Hz
84
+ };
85
+
78
86
// / Temperature DLPF Bandwidth
79
87
enum class TemperatureFilterBandwidth : uint8_t {
80
88
FILTER_OFF = 0 , // /< Filter off
@@ -208,7 +216,10 @@ class Icm42607 : public espp::BasePeripheral<uint8_t, Interface == icm42607::Int
208
216
using BasePeripheral<uint8_t , Interface == icm42607::Interface::I2C>::read_u8_from_register;
209
217
using BasePeripheral<uint8_t , Interface == icm42607::Interface::I2C>::read_u16_from_register;
210
218
using BasePeripheral<uint8_t , Interface == icm42607::Interface::I2C>::read_many_from_register;
219
+ using BasePeripheral<uint8_t , Interface == icm42607::Interface::I2C>::clear_bits_in_register;
211
220
using BasePeripheral<uint8_t , Interface == icm42607::Interface::I2C>::set_bits_in_register;
221
+ using BasePeripheral<uint8_t ,
222
+ Interface == icm42607::Interface::I2C>::set_bits_in_register_by_mask;
212
223
using BasePeripheral<uint8_t , Interface == icm42607::Interface::I2C>::read;
213
224
using BasePeripheral<uint8_t , Interface == icm42607::Interface::I2C>::logger_;
214
225
@@ -225,14 +236,18 @@ class Icm42607 : public espp::BasePeripheral<uint8_t, Interface == icm42607::Int
225
236
using GyroscopeRange = icm42607::GyroscopeRange; // /< Gyroscope range
226
237
using GyroscopePowerMode = icm42607::GyroscopePowerMode; // /< Gyroscope power mode
227
238
using GyroscopeODR = icm42607::GyroscopeODR; // /< Gyroscope output data rate
228
- using ImuConfig = icm42607::ImuConfig; // /< IMU configuration
229
- using RawValue = icm42607::RawValue; // /< Raw IMU data
230
- using Value = icm42607::Value; // /< IMU data
231
- using ComplimentaryAngle = icm42607::ComplimentaryAngle; // /< Complimentary angle
232
- using InterruptDriveMode = icm42607::InterruptDriveMode; // /< Interrupt drive mode
233
- using InterruptPolarity = icm42607::InterruptPolarity; // /< Interrupt polarity
234
- using InterruptMode = icm42607::InterruptMode; // /< Interrupt mode
235
- using InterruptConfig = icm42607::InterruptConfig; // /< Interrupt configuration
239
+ using DmpODR = icm42607::DmpODR; // /< DMP output data rate
240
+ using TemperatureFilterBandwidth =
241
+ icm42607::TemperatureFilterBandwidth; // /< Temperature filter bandwidth
242
+ using SensorFilterBandwidth = icm42607::SensorFilterBandwidth; // /< Sensor filter bandwidth
243
+ using ImuConfig = icm42607::ImuConfig; // /< IMU configuration
244
+ using RawValue = icm42607::RawValue; // /< Raw IMU data
245
+ using Value = icm42607::Value; // /< IMU data
246
+ using ComplimentaryAngle = icm42607::ComplimentaryAngle; // /< Complimentary angle
247
+ using InterruptDriveMode = icm42607::InterruptDriveMode; // /< Interrupt drive mode
248
+ using InterruptPolarity = icm42607::InterruptPolarity; // /< Interrupt polarity
249
+ using InterruptMode = icm42607::InterruptMode; // /< Interrupt mode
250
+ using InterruptConfig = icm42607::InterruptConfig; // /< Interrupt configuration
236
251
237
252
// / Configuration struct for the ICM42607
238
253
struct Config {
@@ -328,8 +343,9 @@ class Icm42607 : public espp::BasePeripheral<uint8_t, Interface == icm42607::Int
328
343
// / @param ec The error code to set if an error occurs
329
344
// / @return True if the power mode was set successfully, false otherwise
330
345
bool set_accelerometer_power_mode (AccelerometerPowerMode power_mode, std::error_code &ec) {
331
- set_bits_in_register (static_cast <uint8_t >(Register::PWR_MGMT0),
332
- static_cast <uint8_t >(power_mode) & 0x03 , ec);
346
+ uint8_t bitmask = 0x03 ;
347
+ set_bits_in_register_by_mask (static_cast <uint8_t >(Register::PWR_MGMT0), bitmask,
348
+ static_cast <uint8_t >(power_mode) & bitmask, ec);
333
349
return !ec;
334
350
}
335
351
@@ -338,8 +354,69 @@ class Icm42607 : public espp::BasePeripheral<uint8_t, Interface == icm42607::Int
338
354
// / @param ec The error code to set if an error occurs
339
355
// / @return True if the power mode was set successfully, false otherwise
340
356
bool set_gyroscope_power_mode (GyroscopePowerMode power_mode, std::error_code &ec) {
341
- set_bits_in_register (static_cast <uint8_t >(Register::PWR_MGMT0),
342
- (static_cast <uint8_t >(power_mode) & 0x03 ) << 2 , ec);
357
+ uint8_t bitmask = 0x03 ;
358
+ set_bits_in_register_by_mask (static_cast <uint8_t >(Register::PWR_MGMT0), bitmask << 2 ,
359
+ (static_cast <uint8_t >(power_mode) & bitmask) << 2 , ec);
360
+ return !ec;
361
+ }
362
+
363
+ // / Set the Accelerometer filter bandwidth
364
+ // / @param bw The filter bandwidth
365
+ // / @param ec The error code to set if an error occurs
366
+ // / @return True if the filter bandwidth was set successfully, false otherwise
367
+ bool set_accelerometer_filter (SensorFilterBandwidth bw, std::error_code &ec) {
368
+ // ACCEL_FILT_BW is bits 2-0 in ACCEL_CONFIG1
369
+ uint8_t mask = 0x07 ;
370
+ uint8_t data = static_cast <uint8_t >(bw) & mask;
371
+ set_bits_in_register_by_mask (static_cast <uint8_t >(Register::ACCEL_CONFIG1), mask, data, ec);
372
+ return !ec;
373
+ }
374
+
375
+ // / Set the Gyroscope filter bandwidth
376
+ // / @param bw The filter bandwidth
377
+ // / @param ec The error code to set if an error occurs
378
+ // / @return True if the filter bandwidth was set successfully, false otherwise
379
+ bool set_gyroscope_filter (SensorFilterBandwidth bw, std::error_code &ec) {
380
+ // GYRO_FILT_BW is bits 2-0 in GYRO_CONFIG1
381
+ uint8_t mask = 0x07 ;
382
+ uint8_t data = static_cast <uint8_t >(bw) & mask;
383
+ set_bits_in_register_by_mask (static_cast <uint8_t >(Register::GYRO_CONFIG1), mask, data, ec);
384
+ return !ec;
385
+ }
386
+
387
+ // / Initialize the DMP
388
+ // / @param ec The error code to set if an error occurs
389
+ // / @return True if the DMP was initialized successfully, false otherwise
390
+ bool dmp_initialize (std::error_code &ec) {
391
+ // DMP INIT EN is bit 2 in APEX_CONFIG0
392
+ set_bits_in_register (static_cast <uint8_t >(Register::APEX_CONFIG0), 1 << 2 , ec);
393
+ return !ec;
394
+ }
395
+
396
+ // / Set the DMP power save mode
397
+ // / @param enable True to enable DMP power save mode, false to disable
398
+ // / @param ec The error code to set if an error occurs
399
+ // / @return True if the DMP power save mode was set successfully, false otherwise
400
+ bool set_dmp_power_save (bool enable, std::error_code &ec) {
401
+ // DMP POWER SAVE EN is bit 3 in APEX_CONFIG0
402
+ if (enable) {
403
+ set_bits_in_register (static_cast <uint8_t >(Register::APEX_CONFIG0), 1 << 3 , ec);
404
+ } else {
405
+ clear_bits_in_register (static_cast <uint8_t >(Register::APEX_CONFIG0), 1 << 3 , ec);
406
+ }
407
+ return !ec;
408
+ };
409
+
410
+ // / Set the DMP output data rate
411
+ // / @param odr The DMP output data rate
412
+ // / @param ec The error code to set if an error occurs
413
+ // / @return True if the DMP output data rate was set successfully, false
414
+ // / otherwise
415
+ bool set_dmp_odr (DmpODR odr, std::error_code &ec) {
416
+ // DMP ODR is bits 1-0 in APEX_CONFIG1
417
+ uint8_t mask = 0x03 ;
418
+ uint8_t data = static_cast <uint8_t >(odr) & mask;
419
+ set_bits_in_register_by_mask (static_cast <uint8_t >(Register::APEX_CONFIG1), mask, data, ec);
343
420
return !ec;
344
421
}
345
422
@@ -490,16 +567,42 @@ class Icm42607 : public espp::BasePeripheral<uint8_t, Interface == icm42607::Int
490
567
return read (static_cast <uint8_t >(Register::FIFO_DATA), data, size, ec);
491
568
}
492
569
570
+ std::vector<uint8_t > fifo_data (std::error_code &ec) {
571
+ // get the count
572
+ uint16_t count = fifo_count (ec);
573
+ if (ec) {
574
+ return {};
575
+ }
576
+
577
+ // allocate a buffer
578
+ std::vector<uint8_t > buffer (count);
579
+
580
+ // read the data
581
+ size_t read_count = fifo_data (buffer.data (), count, ec);
582
+ if (ec) {
583
+ return {};
584
+ }
585
+
586
+ // check if the number of bytes read is the same as the count
587
+ if (read_count != count) {
588
+ ec = make_error_code (std::errc::io_error);
589
+ return {};
590
+ }
591
+
592
+ return buffer;
593
+ }
594
+
493
595
// / Configure interrupt 1
494
596
// / @param config The interrupt configuration
495
597
// / @param ec The error code to set if an error occurs
496
598
// / @return True if the interrupt was configured successfully, false otherwise
497
599
bool configure_interrupt_1 (const InterruptConfig &config, std::error_code &ec) {
498
600
// interrupt 1 is bits 0-2 in INT_CONFIG (MODE << 2) | (POLARITY << 1) | DRIVE_MODE
601
+ uint8_t mask = 0b111 ;
499
602
uint8_t data = (static_cast <uint8_t >(config.mode ) << 2 ) |
500
603
(static_cast <uint8_t >(config.polarity ) << 1 ) |
501
604
static_cast <uint8_t >(config.drive_mode );
502
- set_bits_in_register (static_cast <uint8_t >(Register::INT_CONFIG), data, ec);
605
+ set_bits_in_register_by_mask (static_cast <uint8_t >(Register::INT_CONFIG), mask , data, ec);
503
606
return !ec;
504
607
}
505
608
@@ -509,10 +612,11 @@ class Icm42607 : public espp::BasePeripheral<uint8_t, Interface == icm42607::Int
509
612
// / @return True if the interrupt was configured successfully, false otherwise
510
613
bool configure_interrupt_2 (const InterruptConfig &config, std::error_code &ec) {
511
614
// interrupt 2 is bits 3-5 in INT_CONFIG (MODE << 5) | (POLARITY << 4) | (DRIVE_MODE << 3)
615
+ uint8_t mask = 0b111 << 3 ;
512
616
uint8_t data = (static_cast <uint8_t >(config.mode ) << 5 ) |
513
617
(static_cast <uint8_t >(config.polarity ) << 4 ) |
514
618
(static_cast <uint8_t >(config.drive_mode ) << 3 );
515
- set_bits_in_register (static_cast <uint8_t >(Register::INT_CONFIG), data, ec);
619
+ set_bits_in_register_by_mask (static_cast <uint8_t >(Register::INT_CONFIG), mask , data, ec);
516
620
return !ec;
517
621
}
518
622
@@ -674,6 +778,58 @@ class Icm42607 : public espp::BasePeripheral<uint8_t, Interface == icm42607::Int
674
778
ZG_ST_DATA = 0x05 , // /< Z-axis gyroscope self-test data register
675
779
};
676
780
781
+ // / @brief Structure for the ICM42607 FIFO header
782
+ struct FifoHeader {
783
+ uint8_t odr_gyro : 1 ; // /< 1: ODfor gyro is different fro this packet comapred to previous gyro
784
+ // /< packet
785
+ uint8_t odr_accel : 1 ; // /< 1: ODfor accel is different fro this packet comapred to previous
786
+ // /< accel packet
787
+ uint8_t timestamp_fsync : 2 ; // /< 0b00: no timestamp or fsync data, 0b01: reserved, 0b10: ODR
788
+ // /< timestamp, 0b11: FSYNC timestamp
789
+ uint8_t extended : 1 ; // /< 1: packet contains 20-bit data for gyro and/or accel
790
+ uint8_t has_gyro : 1 ; // /< 1: Packet is sized so that it contains gyroscope data
791
+ uint8_t has_accel : 1 ; // /< 1: Packet is sized so that it contains accelerometer data
792
+ uint8_t empty : 1 ; // /< 1: Packet is empty, 0: packet contains sensor data
793
+ } __attribute__((packed));
794
+
795
+ // / @brief Struct for the FIFO Packet 1 data
796
+ struct FifoPacket1 {
797
+ FifoHeader header; // /< FIFO header
798
+ std::array<uint16_t , 3 > accel; // /< Accelerometer data (x,y,z)
799
+ uint8_t temperature; // /< Temperature data
800
+ };
801
+
802
+ // / @brief Struct for the FIFO Packet 2 data
803
+ struct FifoPacket2 {
804
+ FifoHeader header; // /< FIFO header
805
+ std::array<uint16_t , 3 > gyro; // /< Gyroscope data (x,y,z)
806
+ uint8_t temperature; // /< Temperature data
807
+ };
808
+
809
+ // / @brief Struct for the FIFO Packet 3 data
810
+ struct FifoPacket3 {
811
+ FifoHeader header; // /< FIFO header
812
+ std::array<uint16_t , 3 > accel; // /< Accelerometer data (x,y,z)
813
+ std::array<uint16_t , 3 > gyro; // /< Gyroscope data (x,y,z)
814
+ uint8_t temperature; // /< Temperature data
815
+ uint16_t timestamp_us; // /< Timestamp in microseconds
816
+ };
817
+
818
+ // / @brief Struct for the FIFO Packet 4 data
819
+ struct FifoPacket4 {
820
+ FifoHeader header; // /< FIFO header
821
+ std::array<uint16_t , 3 > accel; // /< Accelerometer data (x,y,z) bits [19:4]
822
+ std::array<uint16_t , 3 > gyro; // /< Gyroscope data (x,y,z) bits [19:4]
823
+ uint16_t temperature; // /< Temperature data
824
+ uint16_t timestamp_us; // /< Timestamp in microseconds
825
+ uint8_t
826
+ x_extension; // /< X-axis extension data (accelx [3:0] high nibble + gyrox [3:0] low nibble)
827
+ uint8_t
828
+ y_extension; // /< Y-axis extension data (accely [3:0] high nibble + gyroy [3:0] low nibble)
829
+ uint8_t
830
+ z_extension; // /< Z-axis extension data (accelz [3:0] high nibble + gyroz [3:0] low nibble)
831
+ };
832
+
677
833
static float accelerometer_range_to_sensitivty (AccelerometerRange range) {
678
834
switch (range) {
679
835
case AccelerometerRange::RANGE_16G:
0 commit comments