2424//! ```
2525//!
2626//! TODO:
27- //! * Allow configuring the unit of the readings (Gs vs m/s^2 , degrees vs. radians, C vs F)
27+ //! * Allow configuring the unit of the readings (Gs vs m/s² , degrees vs. radians, C vs F)
2828//! * Test/ensure support for SPI datagram devices (need to set r/w bit in register address)
2929//! * Add support for calibration/bias correction
3030//! * In the accelerometer
@@ -265,8 +265,10 @@ pub const ICM_20948 = struct {
265265
266266 // ODR (output data rate) is computed as: 1125Hz / (1 + ACCEL_SMPLRT_DIV)
267267 accel_odr_div : u12 = 0 ,
268- // ODR = 1100 / (1 + GYRO_SMPLRT_DIV)
268+ // ODR = 1100Hz / (1 + GYRO_SMPLRT_DIV)
269269 gyro_odr_div : u8 = 0 ,
270+ // ODR = 1.1kHz/2^(I2C_MST_ODR_CONFIG)
271+ mag_i2c_mst_odr_config : u8 = 2 ,
270272 };
271273
272274 const user_ctrl = packed struct (u8 ) {
@@ -500,7 +502,8 @@ pub const ICM_20948 = struct {
500502 try self .modify_register (.{ .bank0 = .lp_config }, lp_config , .{
501503 // Use I2C_MST_ODR_CONFIG, unless gyro or accel set their own data rate
502504 .I2C_MST_CYCLE = 1 ,
503- .ACCEL_CYCLE = 1 , // Duty cycle mode, use ACCEL_SMPLRT_DIV
505+ // NOTE: We seem to need this set to 0?
506+ .ACCEL_CYCLE = 0 , // Duty cycle mode, use ACCEL_SMPLRT_DIV
504507 .GYRO_CYCLE = 1 , // Duty cycle mode, use GYRO_SMPLTR_DIV
505508 });
506509 }
@@ -680,6 +683,7 @@ pub const ICM_20948 = struct {
680683 const NineDofData = struct { accel : Accel_data , gyro : Gyro_data , temp : f32 , mag : Mag_data };
681684
682685 pub fn get_accel_gyro_mag_data (self : * Self ) Error ! NineDofData {
686+ try self .mag_set_sensor_read ();
683687 var raw_data = packed struct {
684688 accel : Accel_data_unscaled = .{},
685689 gyro : Gyro_data_unscaled = .{},
@@ -733,12 +737,8 @@ pub const ICM_20948 = struct {
733737 }
734738
735739 pub fn configure_magnetometer (self : * Self , config : Config ) Error ! void {
736- _ = config ;
737-
738740 // Set master odr: 1.1kHz/2^(config)
739- // TODO: Add config, but if it's too high we need to wait longer for the device to fill the
740- // read registers
741- try self .write_byte (.{ .bank3 = .i2c_mst_odr_config }, 3 );
741+ try self .write_byte (.{ .bank3 = .i2c_mst_odr_config }, config .mag_i2c_mst_odr_config );
742742
743743 // Enable I2C master on this device
744744 try self .modify_register (.{ .bank0 = .user_ctrl }, user_ctrl , .{ .I2C_MST_EN = 1 });
@@ -839,9 +839,7 @@ pub const ICM_20948 = struct {
839839 status2 : u8 = 0 ,
840840 };
841841
842- pub fn get_mag_data_unscaled (self : * Self ) Error ! Mag_data_unscaled {
843- var raw_data : Mag_data_unscaled = .{};
844-
842+ fn mag_set_sensor_read (self : * Self ) Error ! void {
845843 // NOTE: We set the address to the byte before hxl, and set the length to 9 bytes so
846844 // that we read status1 which we can check, but more importantly, we read out
847845 // status2, which MUST BE READ between reads otherwise the values won't get updated.
@@ -853,6 +851,11 @@ pub const ICM_20948 = struct {
853851
854852 // Sleep long enough to give our device time to read from the mag
855853 self .clock .sleep_us (MAG_READ_DELAY_US );
854+ }
855+
856+ pub fn get_mag_data_unscaled (self : * Self ) Error ! Mag_data_unscaled {
857+ try self .mag_set_sensor_read ();
858+ var raw_data : Mag_data_unscaled = .{};
856859
857860 self .read_register (.{ .bank0 = .ext_slv_sens_data_00 }, std .mem .asBytes (& raw_data )) catch | err | {
858861 log .err ("Failed to read magnetometer data: {}" , .{err });
0 commit comments