driver: ist8310: add IST8310J device ID support (#26134)

* driver: ist8310: add IST8310J device ID support and cross-axis compensation

IST8310J shares the same register map and initialization sequence as IST8310.

This change extends the existing IST8310 driver to:
- Accept the IST8310J device ID during probe and reset
- Load factory cross-axis calibration data from OTP
- Apply cross-axis compensation to raw magnetometer samples

The cross-axis compensation corrects factory axis misalignment only and
does not replace PX4 runtime magnetometer calibration.

Tested on Raspberry Pi using I2C with both IST8310 and IST8310J devices.

Signed-off-by: webbyeh <webbyeh@isentek.com>

* driver: ist8310: add IST8310J device ID support

IST8310J shares the same register map and initialization sequence as IST8310.

Factory cross-axis compensation support was evaluated but has been removed
in this revision due to flash size constraints on embedded targets. The
driver now focuses on device identification and stability, while relying on
the existing PX4 magnetometer calibration framework.

This commit also addresses review feedback by caching the WAI register value
to avoid redundant I2C reads during the reset wait state.

Tested on Raspberry Pi using I2C with both IST8310 and IST8310J devices.

Signed-off-by: webbyeh <webbyeh@isentek.com>

* Fix formatting issues in IST8310.cpp

---------

Signed-off-by: webbyeh <webbyeh@isentek.com>
Co-authored-by: Jacob Dahl <37091262+dakejahl@users.noreply.github.com>
This commit is contained in:
isentek-webbyeh 2025-12-18 10:14:17 +08:00 committed by GitHub
parent e01c4b0692
commit b537601b7a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 23 deletions

View File

@ -94,9 +94,11 @@ int IST8310::probe()
while (hrt_elapsed_time(&start_time) < 50_ms) {
set_device_address(start_addr);
const int WAI = RegisterRead(Register::WAI);
if (WAI == Device_ID) {
const uint8_t wai = RegisterRead(Register::WAI);
if ((wai == IST8310_Device_ID) || (wai == IST8310J_Device_ID)) {
// Device has the right I2C address and register content
return PX4_OK;
}
@ -128,30 +130,31 @@ void IST8310::RunImpl()
ScheduleDelayed(50_ms); // Power On Reset: max 50ms
break;
case STATE::WAIT_FOR_RESET:
case STATE::WAIT_FOR_RESET: {
// SRST: This bit is automatically reset to zero after POR routine
const uint8_t wai = RegisterRead(Register::WAI);
// SRST: This bit is automatically reset to zero after POR routine
if ((RegisterRead(Register::WAI) == Device_ID)
&& ((RegisterRead(Register::CNTL2) & CNTL2_BIT::SRST) == 0)) {
// if reset succeeded then configure
_state = STATE::CONFIGURE;
ScheduleDelayed(10_ms);
} else {
// RESET not complete
if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) {
PX4_DEBUG("Reset failed, retrying");
_state = STATE::RESET;
ScheduleDelayed(100_ms);
if (((wai == IST8310_Device_ID) || (wai == IST8310J_Device_ID))
&& ((RegisterRead(Register::CNTL2) & CNTL2_BIT::SRST) == 0)) {
// if reset succeeded then configure
_state = STATE::CONFIGURE;
ScheduleDelayed(10_ms);
} else {
PX4_DEBUG("Reset not complete, check again in 10 ms");
ScheduleDelayed(10_ms);
}
}
// RESET not complete
if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) {
PX4_DEBUG("Reset failed, retrying");
_state = STATE::RESET;
ScheduleDelayed(100_ms);
break;
} else {
PX4_DEBUG("Reset not complete, check again in 10 ms");
ScheduleDelayed(10_ms);
}
}
break;
}
case STATE::CONFIGURE:
if (Configure()) {

View File

@ -57,7 +57,8 @@ namespace iSentek_IST8310
static constexpr uint32_t I2C_SPEED = 400 * 1000; // 400 kHz I2C serial interface
static constexpr uint8_t I2C_ADDRESS_DEFAULT = 0x0E;
static constexpr uint8_t Device_ID = 0x10;
static constexpr uint8_t IST8310_Device_ID = 0x10;
static constexpr uint8_t IST8310J_Device_ID = 0xA3;
enum class Register : uint8_t {
WAI = 0x00, // Who Am I Register