mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-10-09 03:06:39 +00:00
fix(wio-tracker-l2): USB power detection works - charge bolt, Power row, GPS hint
- The AW35615 USB-C controller (FUSB302-style registers, ID 0x91) only reports VBUSOK with its measure block on; POWER resets to bandgap only, so isExternalPowered() was always false. Board init turns it on - Status bar shows a charge bolt on the cable, Diagnostics > Live has a Power row, the GPS screen notes that charging disturbs GPS, and the low-battery warning is skipped on USB as intended - Roadmap: USB detection closed; GPS indoors still worse than the L1 even on battery, left open for later Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -196,13 +196,12 @@ this roadmap is done; the Cardputer follows whatever the spike shows.
|
||||
|
||||
## Backlog (found along the way)
|
||||
|
||||
- [ ] USB power detection: `WioTrackerL2Board::isExternalPowered()` reads
|
||||
STATUS0 (0x40) bit 7 of the chip at I2C 0x22 and always gets 0 with
|
||||
USB plugged in (0x40 reads 0x01). Needed for a charging indicator and
|
||||
for skipping the low-battery shutdown on the cable. Find the right
|
||||
chip / register (devices on the bus: 0x14, 0x18, 0x21, 0x22, 0x2c,
|
||||
0x34, 0x48, 0x5d). Found 2026-09-26. Also wanted for a hint on the
|
||||
GPS screen while on the cable (see below).
|
||||
- [x] USB power detection (fixed 2026-09-26): the AW35615 at 0x22 has a
|
||||
FUSB302-style register map (device ID 0x91); VBUSOK (STATUS0 bit 7)
|
||||
needs the measure block on, and POWER (0x0B) resets to 0x01. Board
|
||||
init sets PWR[1..2]; STATUS0 then reads 0x80 on USB. Used by the
|
||||
status bar (charge bolt), Diagnostics > Live "Power", the GPS screen
|
||||
hint and the low-battery warning (skipped on the cable).
|
||||
- [x] GPS screen (2026-09-26): Home > GPS and Settings > System > GPS
|
||||
details -- sky plot, C/N0 bar per satellite, fix / TTFF / DOPs,
|
||||
per-constellation counts (helpers/sensors/GpsSky.h, -D GPS_SKYVIEW;
|
||||
@@ -214,6 +213,11 @@ this roadmap is done; the Cardputer follows whatever the spike shows.
|
||||
seconds, first fix after 377 s. Screen, WiFi, Bluetooth and LoRa TX
|
||||
were ruled out. Cause: noise from USB power / the charger -- a board
|
||||
property, not fixable in firmware. Test GPS on battery.
|
||||
- [ ] GPS indoors, still open (user, 2026-09-26): even on battery the L2
|
||||
does worse than the L1 with the same L76K -- first fix after 377 s by
|
||||
a window, 4 of 22 satellites used, the fix drops and comes back.
|
||||
Something is still off (antenna / placement / another noise source);
|
||||
look again later with the GPS screen, e.g. side by side with the L1.
|
||||
|
||||
Ideas to come back to (2026-09-26):
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace diagview {
|
||||
enum : uint8_t { TAB_LIVE, TAB_SYSTEM, TAB_FONT, TAB_COUNT };
|
||||
static uint8_t s_tab = TAB_LIVE; // kept across visits
|
||||
static lv_obj_t* s_list = nullptr;
|
||||
static const int EXTRA = 3; // GPS, last reset, last crash (L2 only)
|
||||
static const int EXTRA = 4; // GPS, power, last reset, last crash (L2 only)
|
||||
static lv_obj_t* s_vals[diag::MAX_ROWS + EXTRA];
|
||||
static int s_rows = 0;
|
||||
|
||||
@@ -34,6 +34,7 @@ static int allRows(diag::Row* rows, bool gps_on) {
|
||||
if (!gps_on) extraRow(rows, n, "GPS", "off");
|
||||
else if (!data) extraRow(rows, n, "GPS", "no data (%lu B)", (unsigned long)c);
|
||||
else extraRow(rows, n, "GPS", "%s, %ld sats", gps.isValid() ? "fix" : "no fix", gps.satellitesCount());
|
||||
extraRow(rows, n, "Power", "%s", board.isExternalPowered() ? "USB" : "battery");
|
||||
#else
|
||||
(void)gps_on;
|
||||
#endif
|
||||
|
||||
@@ -348,7 +348,7 @@ void UITask::refreshGps() {
|
||||
if (off) lv_obj_remove_flag(s_on_btn, LV_OBJ_FLAG_HIDDEN);
|
||||
else lv_obj_add_flag(s_on_btn, LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
char used[48] = "", info[200] = "";
|
||||
char used[48] = "", info[240] = "";
|
||||
if (!g) {
|
||||
lv_label_set_text(s_status, "Not available");
|
||||
lv_obj_set_style_text_color(s_status, lv_color_hex(theme::TEXT_MUTED), 0);
|
||||
@@ -387,6 +387,10 @@ void UITask::refreshGps() {
|
||||
o += snprintf(info + o, sizeof(info) - o, "%.0f m - %.1f km/h\n", g->alt_m, g->speed_kmh);
|
||||
if (g->utc_valid) o += snprintf(info + o, sizeof(info) - o, "UTC %02u:%02u:%02u", g->utc_h, g->utc_m, g->utc_s);
|
||||
}
|
||||
if (g && !off && _board->isExternalPowered()) { // measured: on the cable the L76K never decodes indoors
|
||||
size_t o = strlen(info);
|
||||
snprintf(info + o, sizeof(info) - o, "%sOn USB power: charging disturbs GPS", o ? "\n" : "");
|
||||
}
|
||||
lv_label_set_text(s_used, used);
|
||||
lv_label_set_text(s_info, info);
|
||||
|
||||
|
||||
@@ -616,7 +616,7 @@ void UITask::refreshStatusBar() {
|
||||
case battery::VOLTAGE: snprintf(level, sizeof(level), " %u.%02u V", mv / 1000, (mv % 1000) / 10); break;
|
||||
default: break;
|
||||
}
|
||||
lv_label_set_text_fmt(_status_batt, "%s%s", batt, level);
|
||||
lv_label_set_text_fmt(_status_batt, "%s%s%s", _board->isExternalPowered() ? LV_SYMBOL_CHARGE " " : "", batt, level);
|
||||
|
||||
// Status icons, as the original's status bar (ui-new): Bluetooth (bright
|
||||
// when the app is connected), GPS (green with a fix), the alarm, mute, then
|
||||
|
||||
@@ -125,6 +125,20 @@ void WioTrackerL2Board::begin() {
|
||||
|
||||
Wire.beginTransmission(0x22);
|
||||
aw_ok = Wire.endTransmission() == 0;
|
||||
if (aw_ok) {
|
||||
// AW35615 = FUSB302-style register map. VBUSOK (STATUS0 bit 7) only
|
||||
// works with the measure block powered: POWER (0x0B) resets to 0x01
|
||||
// (bandgap only), which reads "no USB" forever. Add the receiver /
|
||||
// current references and the measure block (PWR[1..2]).
|
||||
// Verified on hardware: device ID 0x91; STATUS0 0x01 -> 0x80 on USB.
|
||||
int pw = awRead(0x0B);
|
||||
if (pw >= 0) {
|
||||
Wire.beginTransmission(0x22);
|
||||
Wire.write((uint8_t)0x0B);
|
||||
Wire.write((uint8_t)(pw | 0x07));
|
||||
Wire.endTransmission();
|
||||
}
|
||||
}
|
||||
MESH_DEBUG_PRINTLN("WioTrackerL2Board: init done");
|
||||
|
||||
esp_reset_reason_t reason = esp_reset_reason();
|
||||
@@ -156,13 +170,18 @@ int WioTrackerL2Board::expReadInputs() {
|
||||
return lo | (hi << 8);
|
||||
}
|
||||
|
||||
bool WioTrackerL2Board::isExternalPowered() {
|
||||
if (!aw_ok) return false;
|
||||
int WioTrackerL2Board::awRead(uint8_t reg) {
|
||||
if (!aw_ok) return -1;
|
||||
Wire.beginTransmission(0x22);
|
||||
Wire.write((uint8_t)0x40); // STATUS0
|
||||
if (Wire.endTransmission() != 0) return false;
|
||||
if (Wire.requestFrom(0x22, 1) != 1) return false;
|
||||
return (Wire.read() & 0x80) != 0; // VBUSOK bit
|
||||
Wire.write(reg);
|
||||
if (Wire.endTransmission() != 0) return -1;
|
||||
if (Wire.requestFrom(0x22, 1) != 1) return -1;
|
||||
return Wire.read();
|
||||
}
|
||||
|
||||
bool WioTrackerL2Board::isExternalPowered() {
|
||||
int st0 = awRead(0x40); // STATUS0
|
||||
return st0 >= 0 && (st0 & 0x80) != 0; // VBUSOK
|
||||
}
|
||||
|
||||
bool WioTrackerL2Board::readWakeButton() {
|
||||
|
||||
@@ -84,6 +84,7 @@ public:
|
||||
|
||||
// VBUS presence via the AW35615 USB-C controller (I2C 0x22)
|
||||
bool isExternalPowered() override;
|
||||
int awRead(uint8_t reg); // AW35615 register, -1 on error
|
||||
|
||||
bool expanderOK() const { return expander_ok; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user