Currently the magnetometer can only be used in bypass mode. This means you can't use two MPUs on the same bus - even though you can change the address of one of them using AD0, their magnetometers still have the same address. Learned this the hard and long way.
The InvenSense driver (which I finally found inside a SparkFun library, lol) does this by setting the magnetometer to single read mode (not continuous 8 Hz or 100Hz), and using SLV0 to read, and SLV1 to trigger the next measurement. I guess it should be possible to do it using only SLV0 and continuous read mode, but I couldn't make it work and didn't need to, because the InvenSense solution already runs at slightly over 100 Hz.
Now that requires some work:
- Slave configuration (why are SLV1-3 registers missing..?)
- Bypass toggle
- Configurable magnetometer read mode (not hardcoded)
- Magnetometer read function (for setup the current magnetometer setup function should be enough)
- Probably a new type to differentiate it from the current bypass mode? (
Marg)
- Setup functions will only work in bypass mode, and reading functions in master mode, so some way to differentiate that
Maybe like this?
// types.rs
pub(crate) trait Marg {}
impl<T: Marg> MpuMode for T {}
pub struct MargBypass;
impl Marg for MargBypass {}
pub struct MargMaster;
impl Marg for MargMaster {}
// lib.rs
// omitted all the I2C-related type parameters for readability
impl<Mode: Marg> Mpu9250<Mode> {
// most of the current functions except for magnetometer reading
}
impl Mpu9250<MargBypass> {
pub fn disable_bypass(self) -> Mpu9250<MargMaster>;
// the current magnetometer reading function
}
impl Mpu9250<MargMaster> {
pub fn enable_bypass(self) -> Mpu9250<Marg>;
// a special function for reading magnetometer from the configured SLV register
// and/or a generic function for reading any SLV register
}
- A different implementation of
NineDOFDevice - it can't be implemented for I2cDevice, because it depends on bypass state, which I2cDevice doesn't know about
What do you think?
Currently the magnetometer can only be used in bypass mode. This means you can't use two MPUs on the same bus - even though you can change the address of one of them using AD0, their magnetometers still have the same address. Learned this the hard and long way.
The InvenSense driver (which I finally found inside a SparkFun library, lol) does this by setting the magnetometer to single read mode (not continuous 8 Hz or 100Hz), and using
SLV0to read, andSLV1to trigger the next measurement. I guess it should be possible to do it using onlySLV0and continuous read mode, but I couldn't make it work and didn't need to, because the InvenSense solution already runs at slightly over 100 Hz.Now that requires some work:
Marg)Maybe like this?
NineDOFDevice- it can't be implemented forI2cDevice, because it depends on bypass state, whichI2cDevicedoesn't know aboutWhat do you think?