Add SDK RTC and IMU hardware abstraction support
Integrate SDK-based RTC and IMU backends as alternatives to direct hardware access. HalClock now attempts SDK RTC initialization and caches time values for reliability. HalTiltSensor adds SDK IMU backend with fallback logic. ClockOffsetActivity gains touch and swipe gesture support for field navigation.
This commit is contained in:
+62
-1
@@ -18,8 +18,11 @@ static uint8_t bcdToDec(uint8_t bcd) { return ((bcd >> 4) * 10) + (bcd & 0x0F);
|
||||
static uint8_t decToBcd(uint8_t dec) { return ((dec / 10) << 4) | (dec % 10); }
|
||||
|
||||
void HalClock::begin() {
|
||||
_usesSdkRtc = false;
|
||||
if (!gpio.deviceIsX3()) {
|
||||
_available = false;
|
||||
_available = _sdkRtc.begin();
|
||||
_usesSdkRtc = _available;
|
||||
LOG_INF("CLK", _available ? "SDK RTC found" : "RTC not found");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -57,6 +60,24 @@ bool HalClock::getTime(uint8_t& hour, uint8_t& minute) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_usesSdkRtc) {
|
||||
Rtc::DateTime dt;
|
||||
if (!_sdkRtc.now(dt)) {
|
||||
if (!_hasCachedTime) return false;
|
||||
_lastPollMs = now;
|
||||
hour = _cachedHour;
|
||||
minute = _cachedMinute;
|
||||
return true;
|
||||
}
|
||||
_cachedHour = dt.hour;
|
||||
_cachedMinute = dt.minute;
|
||||
_lastPollMs = now;
|
||||
_hasCachedTime = true;
|
||||
hour = _cachedHour;
|
||||
minute = _cachedMinute;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read 3 bytes starting at register 0x00: seconds, minutes, hours
|
||||
Wire.beginTransmission(I2C_ADDR_DS3231);
|
||||
Wire.write(DS3231_SEC_REG);
|
||||
@@ -131,6 +152,25 @@ bool HalClock::writeTimeToRTC(uint8_t hour, uint8_t minute, uint8_t second) {
|
||||
assert(hour < 24);
|
||||
assert(minute < 60);
|
||||
assert(second < 60);
|
||||
if (_usesSdkRtc) {
|
||||
Rtc::DateTime dt;
|
||||
dt.hour = hour;
|
||||
dt.minute = minute;
|
||||
dt.second = second;
|
||||
dt.year = 2000;
|
||||
dt.month = 1;
|
||||
dt.day = 1;
|
||||
if (!_sdkRtc.set(dt)) {
|
||||
LOG_ERR("CLK", "Failed to write time to SDK RTC");
|
||||
return false;
|
||||
}
|
||||
_lastPollMs = 0;
|
||||
_cachedHour = hour;
|
||||
_cachedMinute = minute;
|
||||
_hasCachedTime = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
Wire.beginTransmission(I2C_ADDR_DS3231);
|
||||
Wire.write(DS3231_SEC_REG); // Start at register 0x00
|
||||
Wire.write(decToBcd(second)); // 0x00: Seconds
|
||||
@@ -168,6 +208,27 @@ bool HalClock::syncFromNTP() {
|
||||
struct tm timeinfo;
|
||||
gmtime_r(&now, &timeinfo);
|
||||
|
||||
if (_usesSdkRtc) {
|
||||
Rtc::DateTime dt;
|
||||
dt.year = static_cast<uint16_t>(timeinfo.tm_year + 1900);
|
||||
dt.month = static_cast<uint8_t>(timeinfo.tm_mon + 1);
|
||||
dt.day = static_cast<uint8_t>(timeinfo.tm_mday);
|
||||
dt.hour = static_cast<uint8_t>(timeinfo.tm_hour);
|
||||
dt.minute = static_cast<uint8_t>(timeinfo.tm_min);
|
||||
dt.second = static_cast<uint8_t>(timeinfo.tm_sec);
|
||||
dt.weekday = static_cast<uint8_t>(timeinfo.tm_wday);
|
||||
if (_sdkRtc.set(dt)) {
|
||||
_lastPollMs = 0;
|
||||
_cachedHour = dt.hour;
|
||||
_cachedMinute = dt.minute;
|
||||
_hasCachedTime = true;
|
||||
LOG_INF("CLK", "RTC set to %04u-%02u-%02u %02u:%02u:%02u UTC", dt.year, dt.month, dt.day, dt.hour,
|
||||
dt.minute, dt.second);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (writeTimeToRTC(timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec)) {
|
||||
LOG_INF("CLK", "RTC set to %02d:%02d:%02d UTC", timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Rtc.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#include "HalGPIO.h"
|
||||
@@ -10,6 +11,8 @@ extern HalClock halClock; // Singleton
|
||||
|
||||
class HalClock {
|
||||
bool _available = false;
|
||||
bool _usesSdkRtc = false;
|
||||
mutable Rtc _sdkRtc;
|
||||
mutable uint8_t _cachedHour = 0;
|
||||
mutable uint8_t _cachedMinute = 0;
|
||||
mutable bool _hasCachedTime = false;
|
||||
|
||||
@@ -26,6 +26,15 @@ bool HalTiltSensor::readReg(uint8_t reg, uint8_t* val) const {
|
||||
}
|
||||
|
||||
bool HalTiltSensor::readGyro(float& gx, float& gy, float& gz) const {
|
||||
if (_backend == Backend::SdkImu) {
|
||||
Imu::Sample sample;
|
||||
if (!_sdkImu.read(sample)) return false;
|
||||
gx = sample.gx;
|
||||
gy = sample.gy;
|
||||
gz = sample.gz;
|
||||
return true;
|
||||
}
|
||||
|
||||
Wire.beginTransmission(_i2cAddr);
|
||||
Wire.write(REG_GX_L); // Start reading at Gyro X Low
|
||||
if (Wire.endTransmission(false) != 0) {
|
||||
@@ -52,11 +61,22 @@ bool HalTiltSensor::readGyro(float& gx, float& gy, float& gz) const {
|
||||
}
|
||||
|
||||
void HalTiltSensor::begin() {
|
||||
_backend = Backend::None;
|
||||
if (!gpio.deviceIsX3()) {
|
||||
_available = false;
|
||||
_available = _sdkImu.begin();
|
||||
if (!_available) {
|
||||
LOG_ERR("GYR", "SDK IMU not found");
|
||||
return;
|
||||
}
|
||||
_backend = Backend::SdkImu;
|
||||
_initMs = millis();
|
||||
_lastPollMs = millis();
|
||||
LOG_INF("GYR", "SDK IMU initialized");
|
||||
return;
|
||||
}
|
||||
|
||||
_backend = Backend::Qmi8658;
|
||||
|
||||
// Try primary address, then alternate
|
||||
uint8_t whoami = 0;
|
||||
_i2cAddr = I2C_ADDR_QMI8658;
|
||||
@@ -89,6 +109,14 @@ bool HalTiltSensor::wake() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_backend == Backend::SdkImu) {
|
||||
_lastPollMs = millis();
|
||||
_lastTiltMs = millis();
|
||||
_wakeMs = millis();
|
||||
_isAwake = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Wait for init to complete before waking
|
||||
if ((millis() - _initMs) < SLEEP_STABILIZE_MS) {
|
||||
return false;
|
||||
@@ -111,6 +139,13 @@ bool HalTiltSensor::deepSleep() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_backend == Backend::SdkImu) {
|
||||
clearPendingEvents();
|
||||
_inTilt = false;
|
||||
_isAwake = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((millis() - _wakeMs) < SLEEP_STABILIZE_MS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <Imu.h>
|
||||
#include <Wire.h>
|
||||
|
||||
#include "HalGPIO.h"
|
||||
@@ -18,8 +19,12 @@ class HalTiltSensor;
|
||||
extern HalTiltSensor halTiltSensor; // Singleton
|
||||
|
||||
class HalTiltSensor {
|
||||
enum class Backend : uint8_t { None, Qmi8658, SdkImu };
|
||||
|
||||
bool _available = false;
|
||||
Backend _backend = Backend::None;
|
||||
uint8_t _i2cAddr = 0;
|
||||
mutable Imu _sdkImu;
|
||||
|
||||
// Tilt gesture state machine
|
||||
bool _tiltForwardEvent = false; // Consumed by wasTiltedForward()
|
||||
|
||||
Reference in New Issue
Block a user