@@ -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,9 +600,10 @@ 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
- ICM_20948_Status_e ICM_20948::i2cMasterSingleW (uint8_t addr, uint8_t reg, uint8_t data)
603
+
604
+ ICM_20948_Status_e ICM_20948::i2cMasterSingleW (uint8_t addr, uint8_t reg, uint8_t *data)
604
605
{
605
- status = ICM_20948_i2c_master_single_w (&_device, addr, reg, & data);
606
+ status = ICM_20948_i2c_master_single_w (&_device, addr, reg, data);
606
607
return status;
607
608
}
608
609
uint8_t ICM_20948::i2cMasterSingleR (uint8_t addr, uint8_t reg)
@@ -684,40 +685,16 @@ 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 )
712
- {
713
- return ICM_20948_Stat_NotImpl; // By default we assume that we cannot access the magnetometer
714
- }
715
-
716
- ICM_20948_Status_e ICM_20948::getMagnetometerData (ICM_20948_AGMT_t *pagmt)
717
- {
718
- return ICM_20948_Stat_NotImpl; // By default we assume that we cannot access the magnetometer
719
- }
720
-
721
698
// direct read/write
722
699
ICM_20948_Status_e ICM_20948::read (uint8_t reg, uint8_t *pdata, uint32_t len)
723
700
{
@@ -731,6 +708,18 @@ ICM_20948_Status_e ICM_20948::write(uint8_t reg, uint8_t *pdata, uint32_t len)
731
708
return (status);
732
709
}
733
710
711
+ uint8_t ICM_20948::readMag (AK09916_Reg_Addr_e reg)
712
+ {
713
+ uint8_t data = i2cMasterSingleR (MAG_AK09916_I2C_ADDR, reg);
714
+ return data;
715
+ }
716
+
717
+ ICM_20948_Status_e ICM_20948::writeMag (AK09916_Reg_Addr_e reg, uint8_t *pdata)
718
+ {
719
+ status = i2cMasterSingleW (MAG_AK09916_I2C_ADDR, reg, pdata);
720
+ return status;
721
+ }
722
+
734
723
// I2C
735
724
ICM_20948_I2C::ICM_20948_I2C ()
736
725
{
@@ -780,103 +769,78 @@ ICM_20948_Status_e ICM_20948_I2C::begin(TwoWire &wirePort, bool ad0val, uint8_t
780
769
return status;
781
770
}
782
771
783
- ICM_20948_Status_e ICM_20948_I2C ::startupMagnetometer (void )
772
+ ICM_20948_Status_e ICM_20948 ::startupMagnetometer (void )
784
773
{
785
- // If using the magnetometer through passthrough:
786
- 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;
787
775
788
- // Try to set up magnetometer
789
- AK09916_CNTL2_Reg_t reg;
790
- reg.MODE = AK09916_mode_cont_100hz;
776
+ i2cMasterPassthrough (false ); // Do not connect the SDA/SCL pins to AUX_DA/AUX_CL
777
+ i2cMasterEnable (true );
791
778
792
- ICM_20948_Status_e retval = writeMag (AK09916_REG_CNTL2, (uint8_t *)®, sizeof (AK09916_CNTL2_Reg_t));
793
- status = retval;
794
- 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)
795
784
{
796
- _has_magnetometer = true ;
797
- }
798
- return status;
799
- }
785
+ // See if we can read the WhoIAm register correctly
786
+ retval = magWhoIAm ();
787
+ if (retval == ICM_20948_Stat_Ok)
788
+ break ; // WIA matched!
800
789
801
- ICM_20948_Status_e ICM_20948_I2C::magWhoIAm (void )
802
- {
803
- ICM_20948_Status_e retval = ICM_20948_Stat_Ok;
804
-
805
- const uint8_t len = 2 ;
806
- uint8_t whoiam[len];
807
- retval = readMag (AK09916_REG_WIA1, whoiam, len);
808
- status = retval;
809
- if (retval != ICM_20948_Stat_Ok)
810
- {
811
- return retval;
790
+ i2cMasterReset (); // Otherwise, reset the master I2C and try again
791
+ tries++;
812
792
}
813
793
814
- if ((whoiam[ 0 ] == (MAG_AK09916_WHO_AM_I >> 8 )) && (whoiam[ 1 ] == (MAG_AK09916_WHO_AM_I & 0xFF )) )
794
+ if (tries == maxTries )
815
795
{
816
- retval = ICM_20948_Stat_Ok;
817
- status = retval;
796
+ status = ICM_20948_Stat_WrongID;
818
797
return status;
819
798
}
820
- retval = ICM_20948_Stat_WrongID;
821
- status = retval;
822
- return status;
823
- }
824
799
825
- bool ICM_20948_I2C::magIsConnected (void )
826
- {
827
- 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)
828
807
{
829
- return false ;
808
+ status = retval;
809
+ return status;
830
810
}
831
- return true ;
832
- }
833
811
834
- ICM_20948_Status_e ICM_20948_I2C::getMagnetometerData (ICM_20948_AGMT_t *pagmt)
835
- {
836
-
837
- const uint8_t reqd_len = 9 ; // you must read all the way through the status2 register to re-enable the next measurement
838
- uint8_t buff[reqd_len];
839
-
840
- status = readMag (AK09916_REG_ST1, buff, reqd_len);
841
- 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)
842
814
{
815
+ status = retval;
843
816
return status;
844
817
}
845
818
846
- pagmt->mag .axes .x = ((buff[2 ] << 8 ) | (buff[1 ] & 0xFF ));
847
- pagmt->mag .axes .y = ((buff[4 ] << 8 ) | (buff[3 ] & 0xFF ));
848
- pagmt->mag .axes .z = ((buff[6 ] << 8 ) | (buff[5 ] & 0xFF ));
849
-
850
819
return status;
851
820
}
852
821
853
- 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 )
854
823
{
855
- _i2c->beginTransmission (MAG_AK09916_I2C_ADDR);
856
- _i2c->write (reg);
857
- _i2c->endTransmission (false );
824
+ ICM_20948_Status_e retval = ICM_20948_Stat_Ok;
858
825
859
- uint8_t num_received = _i2c->requestFrom ((uint8_t )MAG_AK09916_I2C_ADDR, (uint8_t )len);
860
- 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)
861
831
{
862
- return ICM_20948_Stat_NoData ;
832
+ return retval ;
863
833
}
864
834
865
- for ( uint8_t indi = 0 ; indi < len; indi++ )
835
+ if ((whoiam1 == (MAG_AK09916_WHO_AM_I >> 8 )) && (whoiam2 == (MAG_AK09916_WHO_AM_I & 0xFF )) )
866
836
{
867
- *(pdata + indi) = _i2c->read ();
837
+ retval = ICM_20948_Stat_Ok;
838
+ status = retval;
839
+ return status;
868
840
}
869
-
870
- return ICM_20948_Stat_Ok;
871
- }
872
-
873
- ICM_20948_Status_e ICM_20948_I2C::writeMag (uint8_t reg, uint8_t *pdata, uint8_t len)
874
- {
875
- _i2c->beginTransmission (MAG_AK09916_I2C_ADDR);
876
- _i2c->write (reg);
877
- _i2c->write (pdata, len);
878
- _i2c->endTransmission ();
879
- 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;
880
844
}
881
845
882
846
// SPI
@@ -925,8 +889,6 @@ ICM_20948_Status_e ICM_20948_SPI::begin(uint8_t csPin, SPIClass &spiPort, uint32
925
889
return status;
926
890
}
927
891
928
- // todo: disable I2C interface to prevent accidents
929
-
930
892
return ICM_20948_Stat_Ok;
931
893
}
932
894
0 commit comments