feat: Add touch coordinate mapping and RTOS task yielding (#2481)
Co-authored-by: Julia Nguyen <julia@uxj.io>
This commit is contained in:
co-authored by
Julia Nguyen
parent
c9188a7347
commit
f42fab1c66
+28
-93
@@ -4,84 +4,29 @@
|
||||
|
||||
HalTiltSensor halTiltSensor; // Singleton instance
|
||||
|
||||
bool HalTiltSensor::writeReg(uint8_t reg, uint8_t val) const {
|
||||
Wire.beginTransmission(_i2cAddr);
|
||||
Wire.write(reg);
|
||||
Wire.write(val);
|
||||
return Wire.endTransmission() == 0;
|
||||
}
|
||||
|
||||
bool HalTiltSensor::readReg(uint8_t reg, uint8_t* val) const {
|
||||
Wire.beginTransmission(_i2cAddr);
|
||||
Wire.write(reg);
|
||||
if (Wire.endTransmission(false) != 0) {
|
||||
return false;
|
||||
}
|
||||
Wire.requestFrom(_i2cAddr, (uint8_t)1);
|
||||
if (Wire.available() < 1) {
|
||||
return false;
|
||||
}
|
||||
*val = Wire.read();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HalTiltSensor::readGyro(float& gx, float& gy, float& gz) const {
|
||||
Wire.beginTransmission(_i2cAddr);
|
||||
Wire.write(REG_GX_L); // Start reading at Gyro X Low
|
||||
if (Wire.endTransmission(false) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Wire.requestFrom(_i2cAddr, (uint8_t)6);
|
||||
if (Wire.available() < 6) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto readInt16 = [&]() -> int16_t {
|
||||
const uint8_t lo = Wire.read();
|
||||
const uint8_t hi = Wire.read();
|
||||
return static_cast<int16_t>((hi << 8) | lo);
|
||||
};
|
||||
|
||||
// If Full Scale is ±512 dps, the scale factor is 32768 / 512 = 64 LSB/dps
|
||||
constexpr float SCALE = 1.0f / 64.0f;
|
||||
gx = readInt16() * SCALE;
|
||||
gy = readInt16() * SCALE;
|
||||
gz = readInt16() * SCALE;
|
||||
Imu::Sample sample;
|
||||
if (!_sdkImu.read(sample)) return false;
|
||||
gx = sample.gx;
|
||||
gy = sample.gy;
|
||||
gz = sample.gz;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HalTiltSensor::begin() {
|
||||
if (!gpio.deviceIsX3()) {
|
||||
_available = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Try primary address, then alternate
|
||||
uint8_t whoami = 0;
|
||||
_i2cAddr = I2C_ADDR_QMI8658;
|
||||
if (!readReg(QMI8658_WHO_AM_I_REG, &whoami) || whoami != QMI8658_WHO_AM_I_VALUE) {
|
||||
_i2cAddr = I2C_ADDR_QMI8658_ALT;
|
||||
if (!readReg(QMI8658_WHO_AM_I_REG, &whoami) || whoami != QMI8658_WHO_AM_I_VALUE) {
|
||||
LOG_ERR("GYR", "QMI8658 IMU not found");
|
||||
_available = false;
|
||||
return;
|
||||
_available = _sdkImu.begin();
|
||||
if (_available) {
|
||||
_initMs = millis();
|
||||
_lastPollMs = millis();
|
||||
// begin() leaves the sensors sampling; stand them by until tilt page turn
|
||||
// actually wakes them, so a disabled IMU doesn't drain the battery.
|
||||
if (!_sdkImu.sleep()) {
|
||||
LOG_ERR("GYR", "IMU standby failed");
|
||||
}
|
||||
}
|
||||
|
||||
LOG_INF("GYR", "QMI8658 IMU found at 0x%02X", _i2cAddr);
|
||||
|
||||
if (!writeReg(REG_CTRL7, CTRL7_DISABLE_ALL) || !writeReg(REG_CTRL3, CTRL3_FS_512DPS | CTRL3_ODR_28HZ) ||
|
||||
!writeReg(REG_CTRL1, CTRL1_BASE | CTRL1_SENSOR_DISABLE)) {
|
||||
LOG_ERR("GYR", "QMI8658 register configuration failed");
|
||||
_available = false;
|
||||
LOG_INF("GYR", "SDK IMU initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
_available = true;
|
||||
_initMs = millis();
|
||||
_lastPollMs = millis();
|
||||
LOG_INF("GYR", "QMI8658 gyro initialized and put to sleep");
|
||||
LOG_ERR("GYR", "SDK IMU not found");
|
||||
}
|
||||
|
||||
bool HalTiltSensor::wake() {
|
||||
@@ -89,21 +34,16 @@ bool HalTiltSensor::wake() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wait for init to complete before waking
|
||||
if ((millis() - _initMs) < SLEEP_STABILIZE_MS) {
|
||||
if (!_sdkImu.wake()) {
|
||||
LOG_ERR("GYR", "IMU wake failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (writeReg(REG_CTRL1, CTRL1_BASE) && writeReg(REG_CTRL7, CTRL7_GYRO_ENABLE)) {
|
||||
_lastPollMs = millis();
|
||||
_lastTiltMs = millis();
|
||||
_wakeMs = millis();
|
||||
LOG_INF("GYR", "QMI8658 woke up");
|
||||
return true;
|
||||
} else {
|
||||
LOG_ERR("GYR", "Failed to wake QMI8658");
|
||||
return false;
|
||||
}
|
||||
_lastPollMs = millis();
|
||||
_lastTiltMs = millis();
|
||||
_wakeMs = millis();
|
||||
_isAwake = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HalTiltSensor::deepSleep() {
|
||||
@@ -111,20 +51,15 @@ bool HalTiltSensor::deepSleep() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((millis() - _wakeMs) < SLEEP_STABILIZE_MS) {
|
||||
if (!_sdkImu.sleep()) {
|
||||
LOG_ERR("GYR", "IMU sleep failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (writeReg(REG_CTRL7, CTRL7_DISABLE_ALL) && writeReg(REG_CTRL1, CTRL1_BASE | CTRL1_SENSOR_DISABLE)) {
|
||||
// Clear any residual state so it doesn't immediately trigger upon waking
|
||||
clearPendingEvents();
|
||||
_inTilt = false;
|
||||
LOG_INF("GYR", "QMI8658 entered sleep mode");
|
||||
return true;
|
||||
} else {
|
||||
LOG_ERR("GYR", "Failed to put QMI8658 to sleep");
|
||||
return false;
|
||||
}
|
||||
clearPendingEvents();
|
||||
_inTilt = false;
|
||||
_isAwake = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void HalTiltSensor::update(const uint8_t mode, const uint8_t orientation, const bool inReader) {
|
||||
|
||||
Reference in New Issue
Block a user