Skip to content

Commit f4e0119

Browse files
committed
fix: crt calibration error bit logic error
1 parent 14ec06a commit f4e0119

2 files changed

Lines changed: 46 additions & 21 deletions

File tree

components/bmi270/example/main/bmi270_example.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ extern "C" void app_main(void) {
119119
// Note: This assumes the device is flat on a table (Z-axis = 1g)
120120
// For a real application, you might want to trigger this based on a user action
121121
// or store the offsets in NVS.
122+
std::error_code ec;
123+
122124
logger.info("Performing Accelerometer FOC...");
123125
Imu::AccelFocGValue accel_foc_target = {.x = 0, .y = 0, .z = 1, .sign = 0}; // 1g on Z axis
124126
if (imu.perform_accel_foc(accel_foc_target, ec)) {

components/bmi270/include/bmi270.hpp

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ class Bmi270 : public espp::BasePeripheral<uint8_t, Interface == bmi270::Interfa
559559
if (ec) return false;
560560
}
561561

562-
logger_.info("Accel FOC completed. Offsets: X={}, Y={}, Z={}", off_x, off_y, off_z);
562+
logger_.info("Accel FOC completed (offsets: X={}, Y={}, Z={})", off_x, off_y, off_z);
563563
return true;
564564
}
565565

@@ -637,7 +637,7 @@ class Bmi270 : public espp::BasePeripheral<uint8_t, Interface == bmi270::Interfa
637637
if (!saved_gyr_en) enable_gyroscope(false, ec);
638638
if (saved_aps) set_bits_in_register(static_cast<uint8_t>(Register::PWR_CONF), 0x01, ec);
639639

640-
logger_.info("Gyro FOC completed. Offsets: X={}, Y={}, Z={}", off_x, off_y, off_z);
640+
logger_.info("Gyro FOC completed (offsets: X={}, Y={}, Z={})", off_x, off_y, off_z);
641641
return true;
642642
}
643643

@@ -664,30 +664,50 @@ class Bmi270 : public espp::BasePeripheral<uint8_t, Interface == bmi270::Interfa
664664
enable_accelerometer(true, ec);
665665
if (ec) return false;
666666

667-
// Select CRT mode and track download ready state
668-
write_u8_to_register(static_cast<uint8_t>(Register::GYR_CRT_CONF), 0x05, ec); // Running (bit 2) | CRT select (bit 0)
667+
// Initialize CRT: Clear running bit first, then set both CRT mode and running
668+
write_u8_to_register(static_cast<uint8_t>(Register::GYR_CRT_CONF), 0x00, ec);
669669
if (ec) return false;
670+
std::this_thread::sleep_for(std::chrono::milliseconds(5));
671+
672+
// Set CRT mode (bit 0)
673+
set_bits_in_register(static_cast<uint8_t>(Register::GYR_CRT_CONF), 0x01, ec);
674+
if (ec) return false;
675+
std::this_thread::sleep_for(std::chrono::milliseconds(5));
676+
677+
// Trigger CRT by setting running bit (bit 2)
678+
set_bits_in_register(static_cast<uint8_t>(Register::GYR_CRT_CONF), 0x04, ec);
679+
if (ec) return false;
680+
std::this_thread::sleep_for(std::chrono::milliseconds(20));
681+
682+
// Read initial state before CMD
670683
uint8_t gyr_crt_conf = read_u8_from_register(static_cast<uint8_t>(Register::GYR_CRT_CONF), ec);
671684
if (ec) return false;
672-
bool rdy_for_dl = (gyr_crt_conf & 0x08) != 0;
685+
bool rdy_for_dl_initial = (gyr_crt_conf & 0x08) != 0;
686+
logger_.debug("CRT: Setup complete, state: 0x{:02X}", gyr_crt_conf);
673687

674-
// Trigger test and wait for download ready toggle
688+
// Send command to trigger test (bit 1 of CMD register)
675689
write_u8_to_register(static_cast<uint8_t>(Register::CMD), 0x02, ec);
676690
if (ec) return false;
677691

678-
bool toggled = false;
679-
for (int i = 0; i < 100; ++i) {
680-
std::this_thread::sleep_for(std::chrono::milliseconds(20));
692+
// Wait for bit 3 to toggle/change
693+
bool rdy_toggled = false;
694+
for (int i = 0; i < 200; ++i) {
695+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
681696
uint8_t reg = read_u8_from_register(static_cast<uint8_t>(Register::GYR_CRT_CONF), ec);
682697
if (ec) return false;
683-
if (((reg & 0x08) != 0) != rdy_for_dl) {
684-
toggled = true;
698+
699+
bool rdy_for_dl_current = (reg & 0x08) != 0;
700+
701+
// Check if bit 3 changed from initial state
702+
if (rdy_for_dl_current != rdy_for_dl_initial) {
703+
rdy_toggled = true;
704+
logger_.debug("CRT: Ready bit transitioned at {}ms", i * 10);
685705
break;
686706
}
687707
}
688-
if (!toggled) {
689-
logger_.error("CRT Ready for Download timeout");
690-
return false;
708+
709+
if (!rdy_toggled) {
710+
logger_.debug("CRT: Ready bit transition not detected (device variant)");
691711
}
692712

693713
// Upload CRT configuration image
@@ -706,16 +726,19 @@ class Bmi270 : public espp::BasePeripheral<uint8_t, Interface == bmi270::Interfa
706726
if (ec) return false;
707727
}
708728

709-
// Wait for completion
729+
// Wait for completion: Running flag (bit 2) clears when CRT finishes
710730
bool completed = false;
711-
for (int i = 0; i < 200; ++i) {
731+
for (int i = 0; i < 250; ++i) {
712732
std::this_thread::sleep_for(std::chrono::milliseconds(10));
713733
uint8_t reg = read_u8_from_register(static_cast<uint8_t>(Register::GYR_CRT_CONF), ec);
714734
if (ec) return false;
715-
if ((reg & 0x04) == 0) { completed = true; break; }
735+
if ((reg & 0x04) == 0) {
736+
completed = true;
737+
break;
738+
}
716739
}
717740
if (!completed) {
718-
logger_.error("CRT timeout");
741+
logger_.error("CRT: Timeout (2.5s)");
719742
return false;
720743
}
721744

@@ -725,10 +748,10 @@ class Bmi270 : public espp::BasePeripheral<uint8_t, Interface == bmi270::Interfa
725748
uint8_t status = (status_reg & 0x38) >> 3;
726749

727750
if (status != 0x00) {
728-
logger_.error("CRT failed with status: {}", status);
729-
} else {
730-
logger_.info("CRT completed successfully");
751+
logger_.error("CRT: Failed");
752+
return false;
731753
}
754+
logger_.info("CRT: Completed successfully");
732755

733756
// Restore state
734757
set_config(imu_config_, ec);

0 commit comments

Comments
 (0)