New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for ICM20789 IMU/Baro #6449
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a couple of comments.
@@ -922,9 +946,12 @@ bool AP_InertialSensor_Invensense::_hardware_init(void) | |||
/* bus-dependent initialization */ | |||
if ((_dev->bus_type() == AP_HAL::Device::BUS_TYPE_I2C) && (_mpu_type == Invensense_MPU9250)) { | |||
/* Enable I2C bypass to access internal AK8963 */ | |||
_register_write(MPUREG_INT_PIN_CFG, BIT_BYPASS_EN); | |||
if (_mpu_type != Invensense_ICM20789) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is always true (given the previous check). I'm a bit confused though because this bit is set on start just for this MPU type, why not do it here instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will be trying to do it here.
|
||
if (_mpu_type == Invensense_ICM20789) { | ||
// setup to allow for barometer | ||
user_ctrl &= ~BIT_USER_CTRL_I2C_MST_EN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to do this on every FIFO reset? Unless I'm missing something, user_ctrl should always have BIT_USER_CTRL_I2C_MST_EN
unset - it is only set when _configure_slaves is called, where you added a check so that it returns immediately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will remove this.
static struct { | ||
uint32_t Praw, Traw; | ||
float T, P; | ||
} dd; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not dramatic in terms of space, but we should probably ifdef this inside a debug macro.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will create BARO_ICM20789_DEBUG and also use it to define the Debug(..)
macro
return; | ||
} | ||
|
||
if (_sem->take(0)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use HAL_SEMAPHORE_BLOCK_FOREVER please? @peterbarker did a PR changing all places, I don't want to go back 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Easy enough :-)
} | ||
|
||
dev_icm->get_semaphore()->give(); | ||
#endif // HAL_INS_MPU60x0_NAME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this isn't defined, shouldn't we return false here? Or are you relying on the methods below to fail?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to add an early exit in an #else
|
||
private: | ||
AP_Baro_ICM20789(AP_Baro &baro, AP_HAL::OwnPtr<AP_HAL::Device> dev); | ||
virtual ~AP_Baro_ICM20789(void) {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason to define the destructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably because "that's how all the backends do it".
Will remove all the empty backend destructors.
return true; | ||
|
||
failed: | ||
dev_icm->get_semaphore()->give(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if HAL_INS_MPU60x0_NAME isn't defined? 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going to change things so we don't take the semaphore if the name isn't defined.
|
||
uint8_t instance; | ||
AP_HAL::OwnPtr<AP_HAL::Device> dev; | ||
AP_HAL::OwnPtr<AP_HAL::Device> dev_icm; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why keep dev_icm? Looks like it is only needed for initialization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will make it a stack variable.
#define BIT_PWR_MGMT_1_DEVICE_RESET 0x80 // reset entire device | ||
#define BIT_USER_CTRL_I2C_IF_DIS 0x10 // Disable primary I2C interface and enable hal.spi->interface | ||
#define BIT_PWR_MGMT_1_CLK_XGYRO 0x01 // PLL with X axis gyroscope reference | ||
#define BIT_PWR_MGMT_1_CLK_ZGYRO 0x03 // PLL with Z axis gyroscope reference |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So many beautiful macros you don't use anywhere 😛
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're cheap - and might be useful to someone in the future...
|
||
|
||
i2c_dev = std::move(hal.i2c_mgr->get_device(1, 0x63)); | ||
lidar_dev = std::move(hal.i2c_mgr->get_device(1, 0x29)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the VL53L0X doing in the middle of this example? 😜
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will generally fix the example.
Bypass Mode: Set register INT_PIN_CFG (Address: 55 (Decimal); 37 (Hex)) bit 1 to value 1 | ||
and I2C_MST_EN bit is 0 Address: 106 (Decimal); 6A (Hex)). | ||
Pressure sensor data can then be accessed using the procedure described in Section 10. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment should be on the function above. And it looks strange... Are you setting it to read in bypass mode so you have both the IMU on spi bus and baro on I2C bus (i.e. you have real access to both SPI pins and I2C pins and they are not the same)? This would be different from all the other Invensense sensors in which there's an I2C transaction over the SPI bus. By the name of this register (I2C_MST_EN) it looks like you are indeed enabling the I2C master engine on the sensor.
dev_icm->write_register(0x6B, 0x01); | ||
|
||
hal.scheduler->delay(1); | ||
dev_icm->write_register(0x6A, 0x10); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are setting an IMU register without reading whatever the INS set there... This will give us trouble if later we need to set something in this register there. It would be nice to keep this IMU part on the INS driver like it is when we have a mag rather than a baro.
And... now that we have access to the plain I2C/SPI dev, we can also simplify the AuxBus infra a little bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lucasdemarchi Should I move the initialisation into the IMU, or is it OK where it is for the time being?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
baro is initialised before ins, which is why we need to init here, as ins doesn't yet exist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
long ago I had this same problem when MS5611 was on the auxiliary bus of MPU6K... hence the infra for that. So if later on the INS drivers writes to this register, whatever we did here is lost. I think it's much safer to "keep INS registers on the INS driver and baro registers on the baro driver".
@lucasdemarchi Only @tridge can really answer, but my guess was that the current baro driver is that way because the INS driver isn't added to any board - so there is no init there and hence why everything is directly manipulated here. I should say though that the baro driver isn't added too and that, if that happens one day, it likely makes sense to add both the INS and baro drivers. |
@OXINARF isn't the imu support it exactly the other commit in this pr? |
Yes, what I meant is that maybe @tridge is using the baro driver on some board without using the INS driver. |
Closing this in favor of #7477. @lucasdemarchi Please comment there! |
The ICM20789 is an interesting variant of the invensense IMUs that has gyro, accel and barometer.