@@ -18,11 +18,6 @@ ICM_20948_AGMT_t ICM_20948::getAGMT(void)
18
18
{
19
19
status = ICM_20948_get_agmt (&_device, &agmt);
20
20
21
- if (_has_magnetometer)
22
- {
23
- getMagnetometerData (&agmt);
24
- }
25
-
26
21
return agmt;
27
22
}
28
23
@@ -527,7 +522,6 @@ ICM_20948_Status_e ICM_20948::intEnableRawDataReady(bool enable)
527
522
}
528
523
if (en.RAW_DATA_0_RDY_EN != enable)
529
524
{
530
- Serial.println (" mismatch error" );
531
525
status = ICM_20948_Stat_Err;
532
526
return status;
533
527
}
@@ -589,6 +583,12 @@ ICM_20948_Status_e ICM_20948::i2cMasterEnable(bool enable)
589
583
return status;
590
584
}
591
585
586
+ ICM_20948_Status_e ICM_20948::i2cMasterReset ()
587
+ {
588
+ status = ICM_20948_i2c_master_reset (&_device);
589
+ return status;
590
+ }
591
+
592
592
ICM_20948_Status_e ICM_20948::i2cMasterConfigureSlave (uint8_t slave, uint8_t addr, uint8_t reg, uint8_t len, bool Rw, bool enable, bool data_only, bool grp, bool swap)
593
593
{
594
594
status = ICM_20948_i2c_master_configure_slave (&_device, slave, addr, reg, len, Rw, enable, data_only, grp, swap);
@@ -600,6 +600,7 @@ ICM_20948_Status_e ICM_20948::i2cMasterSLV4Transaction(uint8_t addr, uint8_t reg
600
600
status = ICM_20948_i2c_master_slv4_txn (&_device, addr, reg, data, len, Rw, send_reg_addr);
601
601
return status;
602
602
}
603
+
603
604
ICM_20948_Status_e ICM_20948::i2cMasterSingleW (uint8_t addr, uint8_t reg, uint8_t data)
604
605
{
605
606
status = ICM_20948_i2c_master_single_w (&_device, addr, reg, &data);
@@ -684,49 +685,39 @@ ICM_20948_Status_e ICM_20948::startupDefault(void)
684
685
status = retval;
685
686
return status;
686
687
}
687
-
688
- _has_magnetometer = true ;
689
688
retval = startupMagnetometer ();
690
- if (( retval != ICM_20948_Stat_Ok) && (retval != ICM_20948_Stat_NotImpl) )
689
+ if (retval != ICM_20948_Stat_Ok)
691
690
{
692
691
status = retval;
693
692
return status;
694
693
}
695
- if (retval == ICM_20948_Stat_NotImpl)
696
- {
697
- // This is a temporary fix.
698
- // Ultimately we *should* be able to configure the I2C master to handle the
699
- // magnetometer no matter what interface (SPI / I2C) we are using.
700
-
701
- // Should try testing I2C master functionality on a bare ICM chip w/o TXS0108 level shifter...
702
-
703
- _has_magnetometer = false ;
704
- retval = ICM_20948_Stat_Ok; // reset the retval because we handled it in this cases
705
- }
706
694
707
- status = retval;
708
695
return status;
709
696
}
710
697
711
- ICM_20948_Status_e ICM_20948::startupMagnetometer (void )
698
+ // direct read/write
699
+ ICM_20948_Status_e ICM_20948::read (uint8_t reg, uint8_t *pdata, uint32_t len)
712
700
{
713
- return ICM_20948_Stat_NotImpl; // By default we assume that we cannot access the magnetometer
701
+ status = ICM_20948_execute_r (&_device, reg, pdata, len);
702
+ return (status);
714
703
}
715
704
716
- ICM_20948_Status_e ICM_20948::getMagnetometerData (ICM_20948_AGMT_t *pagmt )
705
+ ICM_20948_Status_e ICM_20948::write ( uint8_t reg, uint8_t *pdata, uint32_t len )
717
706
{
718
- return ICM_20948_Stat_NotImpl; // By default we assume that we cannot access the magnetometer
707
+ status = ICM_20948_execute_w (&_device, reg, pdata, len);
708
+ return (status);
719
709
}
720
710
721
- // direct read/write
722
- ICM_20948_Status_e ICM_20948::read (uint8_t reg, uint8_t *pdata, uint32_t len)
711
+ uint8_t ICM_20948::readMag (AK09916_Reg_Addr_e reg)
723
712
{
724
- status = ICM_20948_execute_r (&_device, reg, pdata, len);
713
+ uint8_t data = i2cMasterSingleR (MAG_AK09916_I2C_ADDR, reg);
714
+ return data;
725
715
}
726
716
727
- ICM_20948_Status_e ICM_20948::write ( uint8_t reg, uint8_t *pdata, uint32_t len )
717
+ ICM_20948_Status_e ICM_20948::writeMag (AK09916_Reg_Addr_e reg, uint8_t *pdata)
728
718
{
729
- status = ICM_20948_execute_w (&_device, reg, pdata, len);
719
+ status = i2cMasterSingleW (MAG_AK09916_I2C_ADDR, reg, pdata);
720
+ return status;
730
721
}
731
722
732
723
// I2C
@@ -778,103 +769,78 @@ ICM_20948_Status_e ICM_20948_I2C::begin(TwoWire &wirePort, bool ad0val, uint8_t
778
769
return status;
779
770
}
780
771
781
- ICM_20948_Status_e ICM_20948_I2C ::startupMagnetometer (void )
772
+ ICM_20948_Status_e ICM_20948 ::startupMagnetometer (void )
782
773
{
783
- // If using the magnetometer through passthrough:
784
- i2cMasterPassthrough (true ); // Set passthrough mode to try to access the magnetometer (by default I2C master is disabled but you still have to enable the passthrough)
774
+ ICM_20948_Status_e retval = ICM_20948_Stat_Ok;
785
775
786
- // Try to set up magnetometer
787
- AK09916_CNTL2_Reg_t reg;
788
- reg.MODE = AK09916_mode_cont_100hz;
776
+ i2cMasterPassthrough (false ); // Do not connect the SDA/SCL pins to AUX_DA/AUX_CL
777
+ i2cMasterEnable (true );
789
778
790
- ICM_20948_Status_e retval = writeMag (AK09916_REG_CNTL2, (uint8_t *)®, sizeof (AK09916_CNTL2_Reg_t));
791
- status = retval;
792
- if (status == ICM_20948_Stat_Ok)
779
+ // After a ICM reset the Mag sensor may stop responding over the I2C master
780
+ // Reset the Master I2C until it responds
781
+ uint8_t tries = 0 ;
782
+ uint8_t maxTries = 5 ;
783
+ while (tries < maxTries)
793
784
{
794
- _has_magnetometer = true ;
795
- }
796
- return status;
797
- }
798
-
799
- ICM_20948_Status_e ICM_20948_I2C::magWhoIAm (void )
800
- {
801
- ICM_20948_Status_e retval = ICM_20948_Stat_Ok;
785
+ // See if we can read the WhoIAm register correctly
786
+ retval = magWhoIAm ();
787
+ if (retval == ICM_20948_Stat_Ok)
788
+ break ; // WIA matched!
802
789
803
- const uint8_t len = 2 ;
804
- uint8_t whoiam[len];
805
- retval = readMag (AK09916_REG_WIA1, whoiam, len);
806
- status = retval;
807
- if (retval != ICM_20948_Stat_Ok)
808
- {
809
- return retval;
790
+ i2cMasterReset (); // Otherwise, reset the master I2C and try again
791
+ tries++;
810
792
}
811
793
812
- if ((whoiam[ 0 ] == (MAG_AK09916_WHO_AM_I >> 8 )) && (whoiam[ 1 ] == (MAG_AK09916_WHO_AM_I & 0xFF )) )
794
+ if (tries == maxTries )
813
795
{
814
- retval = ICM_20948_Stat_Ok;
815
- status = retval;
796
+ status = ICM_20948_Stat_WrongID;
816
797
return status;
817
798
}
818
- retval = ICM_20948_Stat_WrongID;
819
- status = retval;
820
- return status;
821
- }
822
799
823
- bool ICM_20948_I2C::magIsConnected (void )
824
- {
825
- if (magWhoIAm () != ICM_20948_Stat_Ok)
800
+ // Serial.printf("Mag connected tries: %d\n", tries);
801
+
802
+ // Set up magnetometer
803
+ AK09916_CNTL2_Reg_t reg;
804
+ reg.MODE = AK09916_mode_cont_100hz;
805
+ retval = writeMag (AK09916_REG_CNTL2, (uint8_t *)®);
806
+ if (retval != ICM_20948_Stat_Ok)
826
807
{
827
- return false ;
808
+ status = retval;
809
+ return status;
828
810
}
829
- return true ;
830
- }
831
-
832
- ICM_20948_Status_e ICM_20948_I2C::getMagnetometerData (ICM_20948_AGMT_t *pagmt)
833
- {
834
-
835
- const uint8_t reqd_len = 9 ; // you must read all the way through the status2 register to re-enable the next measurement
836
- uint8_t buff[reqd_len];
837
811
838
- status = readMag ( AK09916_REG_ST1, buff, reqd_len );
839
- if (status != ICM_20948_Stat_Ok)
812
+ retval = i2cMasterConfigureSlave ( 0 , MAG_AK09916_I2C_ADDR, AK09916_REG_ST1, 9 , true , true , false , false , false );
813
+ if (retval != ICM_20948_Stat_Ok)
840
814
{
815
+ status = retval;
841
816
return status;
842
817
}
843
818
844
- pagmt->mag .axes .x = ((buff[2 ] << 8 ) | (buff[1 ] & 0xFF ));
845
- pagmt->mag .axes .y = ((buff[4 ] << 8 ) | (buff[3 ] & 0xFF ));
846
- pagmt->mag .axes .z = ((buff[6 ] << 8 ) | (buff[5 ] & 0xFF ));
847
-
848
819
return status;
849
820
}
850
821
851
- ICM_20948_Status_e ICM_20948_I2C::readMag ( uint8_t reg, uint8_t *pdata, uint8_t len )
822
+ ICM_20948_Status_e ICM_20948::magWhoIAm ( void )
852
823
{
853
- _i2c->beginTransmission (MAG_AK09916_I2C_ADDR);
854
- _i2c->write (reg);
855
- _i2c->endTransmission (false );
824
+ ICM_20948_Status_e retval = ICM_20948_Stat_Ok;
856
825
857
- uint8_t num_received = _i2c->requestFrom ((uint8_t )MAG_AK09916_I2C_ADDR, (uint8_t )len);
858
- if (num_received != len)
826
+ uint8_t whoiam1, whoiam2;
827
+ whoiam1 = readMag (AK09916_REG_WIA1);
828
+ whoiam2 = readMag (AK09916_REG_WIA2);
829
+ status = retval;
830
+ if (retval != ICM_20948_Stat_Ok)
859
831
{
860
- return ICM_20948_Stat_NoData ;
832
+ return retval ;
861
833
}
862
834
863
- for ( uint8_t indi = 0 ; indi < len; indi++ )
835
+ if ((whoiam1 == (MAG_AK09916_WHO_AM_I >> 8 )) && (whoiam2 == (MAG_AK09916_WHO_AM_I & 0xFF )) )
864
836
{
865
- *(pdata + indi) = _i2c->read ();
837
+ retval = ICM_20948_Stat_Ok;
838
+ status = retval;
839
+ return status;
866
840
}
867
-
868
- return ICM_20948_Stat_Ok;
869
- }
870
-
871
- ICM_20948_Status_e ICM_20948_I2C::writeMag (uint8_t reg, uint8_t *pdata, uint8_t len)
872
- {
873
- _i2c->beginTransmission (MAG_AK09916_I2C_ADDR);
874
- _i2c->write (reg);
875
- _i2c->write (pdata, len);
876
- _i2c->endTransmission ();
877
- return ICM_20948_Stat_Ok; // todo: check return of 'endTransmission' to verify all bytes sent w/ ACK
841
+ retval = ICM_20948_Stat_WrongID;
842
+ status = retval;
843
+ return status;
878
844
}
879
845
880
846
// SPI
@@ -923,8 +889,6 @@ ICM_20948_Status_e ICM_20948_SPI::begin(uint8_t csPin, SPIClass &spiPort, uint32
923
889
return status;
924
890
}
925
891
926
- // todo: disable I2C interface to prevent accidents
927
-
928
892
return ICM_20948_Stat_Ok;
929
893
}
930
894
0 commit comments