make gps standby command universal

This commit is contained in:
liquidraver
2026-10-05 14:00:13 +02:00
parent d5bb275e01
commit 52644a80a4
12 changed files with 150 additions and 73 deletions
+8 -2
View File
@@ -795,6 +795,10 @@ Loading also range-checks `freq`/`sf`/`bw` and falls back to the compile-time de
- Multi-constellation: GPS+GLONASS+Galileo+BeiDou with fallback
- T1000-E / MeshTracker X1 (AG3335): multi-GPIO power sequencing; standby is the module's RTC backup sleep
(`$PAIR650,0` before `GPS_EN` is cut, VRTC kept, a `GPS_RTC_INT` pulse wakes it)
- Standby depth is decided from the duty interval alone, on every board: up to `prefs.gps_standby_max`
(`set gps standby`, default 3600 s) the module keeps its state (backup sleep, standby pin, VRTC), beyond it the
board's full power-off is used, as it is for `gps off`. `gps_power.cpp` maps the two onto the pins a board
declares; a board with one off state uses it for both
- GPS time blocks phone time sync for 2 hours after last fix
- Three files: `ZephyrGPSManager.cpp` (states, fix validation, public API), `gps_power.cpp` (power line / PMU rail / UART sleep commands, UARTE PM), `gps_module_cfg.cpp` (GNSS-API or PMTK/PCAS/UBX configuration, `get gps diag`); `gps_internal.h` carries the feature detection
- **Main thread only.** The GNSS callbacks (system work queue) only validate and post: a validated fix is snapshotted and handed to the fix callback by `gps_process_event()` on the main thread, so the callback sets the clock and the node position directly. The UI's GPS toggles post an action too.
@@ -814,8 +818,10 @@ Loading also range-checks `freq`/`sf`/`bw` and falls back to the compile-time de
Two separate timeouts apply to acquisition:
- `CONFIG_ZEPHCORE_GPS_FIRST_FIX_TIMEOUT_SEC` (default 300s): the cold-start window used for the very first acquisition after `gps_enable()`. Longer to allow almanac download.
- `CONFIG_ZEPHCORE_GPS_FIX_TIMEOUT_SEC` (default 120s): the normal per-wake timeout for all subsequent acquisitions (warm start).
- `CONFIG_ZEPHCORE_GPS_FIRST_FIX_TIMEOUT_SEC` (default 300s): the cold-start window, used for every acquisition that follows a full power-off: the first one after `gps_enable()` (boot, `gps on`; `gps off` is a full power-off on every board) and every wake from a standby longer than `prefs.gps_standby_max`. Longer to allow almanac download and poor reception.
- `CONFIG_ZEPHCORE_GPS_FIX_TIMEOUT_SEC` (default 120s): the normal per-wake timeout for all other acquisitions (warm start).
Like the standby depth, the choice follows from the duty interval alone, never from the board.
**Repeater mode**
+1 -1
View File
@@ -134,7 +134,7 @@ Set them in a board conf or with `-DCONFIG_...=`. The full list with help texts
| `ZEPHCORE_OFFLINE_QUEUE_SIZE` | 256 | Companion offline message queue |
| `ZEPHCORE_BLE_PASSKEY` | 123456 | BLE pairing PIN |
| `ZEPHCORE_GPS_POLL_INTERVAL_SEC` | 300 | Companion GPS interval between fixes (10 to 86400); the runtime setting is `set gps duty` |
| `ZEPHCORE_GPS_FIRST_FIX_TIMEOUT_SEC` | 300 | Window for the very first fix after a cold start |
| `ZEPHCORE_GPS_FIRST_FIX_TIMEOUT_SEC` | 300 | Window for a fix after a full GPS power-off: boot, `gps on`, and every wake when the GPS interval is above `gps standby` |
| `ZEPHCORE_REPEATER_GPS_INTERVAL_SEC` | 172800 | Repeater and room server GPS interval (48 h); 0 = always on |
| `ZEPHCORE_PACKET_LOGGING` | n | Upstream-format packet log lines (`packet_logging.conf`) |
| `ZEPHCORE_WIFI_OTA` | n | WiFi AP + HTTP firmware update (ESP32 repeaters) |
+3 -3
View File
@@ -154,7 +154,7 @@ Regions control which flood packets the repeater forwards. The region tree is hi
| `gps diag` | Receiver liveness, in upstream's key form: `req:<0\|1> en:<0\|1> ok:<n> sat:<n> fix:<0\|1> fa:<ms\|never> bc:<n> sc:<n>`. `req` is the requested setting, `en` the module powered and searching (0 in duty-cycle standby), `ok` NMEA sentences the driver has parsed since boot (a count that stops rising means the module or its UART went silent, whatever `sat` says), `fa` the age of the last validated fix, `bc`/`sc` module power-on/off counts. Upstream's UART byte and bad-checksum counters are absent: the GNSS driver only passes valid sentences. Module configuration results are `get gps diag` |
| `gps sync` | Take a fresh fix now (wake the GPS or extend its window); the fix sets the clock. `gps is off` / `gps provider not found` otherwise |
| `gps on` | Enable GPS module |
| `gps off` | Disable GPS module. Persisted: a repeater or room server with GPS off stays off across reboots. Boards whose GPS has no power line (RAK4631, RAK3401 1W, Station G2) put the module to sleep over UART |
| `gps off` | Disable GPS module. Persisted: a repeater or room server with GPS off stays off across reboots. A full power-off on every board (nothing is kept powered for a fast restart, so the fix after `gps on` is a cold start with the long acquire window). Boards whose GPS has no power line (RAK4631, RAK3401 1W, Station G2) put the module to sleep over UART |
| `gps setloc` | Update stored latitude/longitude from the last GPS fix (unchanged if there has been none since boot) |
| `gps advert` | Show current location advertising policy |
| `gps advert none` | Do not include location in advertisements |
@@ -162,7 +162,7 @@ Regions control which flood packets the repeater forwards. The region tree is hi
| `gps advert prefs` | Include stored lat/lon from prefs in advertisements |
| `set gps duty <sec>` | GPS duty interval (standby seconds between fixes). `0` = always-on (continuous; streams fresh fixes, can download a full almanac). Floor 10s, cap 604800 (1 week). Persists to flash, applied live. |
| `set gps duty default` | Reset GPS duty to the role default (repeater/room 48h, companion 300s) |
| `set gps standby <sec>` | Only on boards with a GPS standby pin beside a supply switch (SenseCAP Solar). Duty intervals up to `<sec>` keep the module powered in standby between fixes (hot start, a fix in seconds); longer intervals cut its supply (cold start, minutes, but no draw in between). `0` = always cut the supply. Default 3600. Cap 604800. Persists to flash; applies at the next standby. `gps off` always cuts the supply. Other boards answer `Error: no GPS standby pin on this board`. |
| `set gps standby <sec>` | Every board. Duty intervals up to `<sec>` keep the GPS module's state between fixes (a fix in seconds on wake); longer intervals power it off fully (cold start, minutes, but no draw in between) and give each wake the long acquire window (300 s on a companion instead of 120 s; servers always use 300 s). `0` = always power off fully. Default 3600. Cap 604800. Persists to flash; applies at the next standby. What "keeps its state" means depends on the board: backup sleep with the RTC supply kept (T1000-E, MeshTracker X1), the module's standby pin with the supply kept (SenseCAP Solar). A board with a single way to switch its GPS off (a bare supply switch, a bare standby pin such as the Wio Tracker L1, or the UART sleep command) does the same on both sides of the limit. |
| `set gps standby default` | Reset the standby threshold to 3600 s |
| `set gps diag <0\|1\|on\|off>` | Arm GPS module-configuration diagnostics (see below). Not persisted — clears on reboot |
@@ -303,7 +303,7 @@ Companion builds of boards whose `zephcore.yml` declares `capabilities: wifi: tr
| `get input.rotate` | Joystick/D-pad axis swap: `0` or `1` |
| `get tz.offset` | Display timezone: whole hours from UTC, `-12`..`14` (`0` = UTC) |
| `get gps duty` | Now-effective GPS duty interval in seconds (`always on (0)` when continuous) |
| `get gps standby` | GPS standby threshold in seconds (see `set gps standby`); `n/a` on a board without a GPS standby pin |
| `get gps standby` | GPS standby threshold in seconds (see `set gps standby`) |
| `get gps diag` | What the last GPS module-configuration attempt did — which path ran, bytes sent, and tracked satellites per constellation. See **GPS configuration diagnostics** in the GPS section for the field reference |
| `get meshtimesync` | Mesh time-sync state + live dry-run: on/off, eligible voter count, votes for/against, consensus skew and radius, would-be verdict (`ok`/`in-band`/`step±N`/`abstain (reason)`/`hold (reason)`; a recent clock set — manual or GPS — shows as `hold (suppressed)`, and a backward step a forward-only role would refuse is annotated `(skipped: forward-only)`), step counters, suppression countdown, and a per-sender evidence table (`prefix hops count skew E`, `E` = counted toward the verdict above). Entries that count print first, so a size-capped reply never hides the ones that explain the summary; if the table doesn't fully fit, a trailing `+N more` shows how many were left out. Sensing runs even while off, so this works as a dry-run before enabling. Over remote admin the reply is truncated to the packet size (summary always fits); the full table needs the USB CLI. |
| `get probe.interval` | Seconds between periodic radio measurements (noise-floor sample + CAD probe). 0 = CAD probing off |
+69 -7
View File
@@ -1,7 +1,8 @@
# ZephCore 1.17.7-zephcore
Faster GPS fixes on three trackers, a clock that survives a reboot, and a few fixes ported from
upstream MeshCore.
Faster GPS fixes on three trackers, a clock that survives a reboot, a fix for USB companions that
could stop responding right after boot, more reliable detection of clock chips, and a few fixes ported
from upstream MeshCore.
> [!NOTE]
> A normal upgrade keeps your identity, settings, contacts and phone pairing.
@@ -18,22 +19,83 @@ a search from scratch. Three boards now keep that data:
- **SenseCAP Solar**: the receiver stays in standby between fixes instead of being switched off. In
marginal reception it got a fix on 5 of 6 wakes, against 2 of 6 before.
On the SenseCAP Solar, standby uses a little power all the time, so it is only used when the GPS
interval is one hour or less. Longer intervals (a repeater's default is 48 hours) and `gps off` switch
the receiver off completely, as before. The limit can be changed with `set gps standby <seconds>`
Keeping that data uses a little power all the time, so it is only done when the GPS interval is one
hour or less. Longer intervals (a repeater's default is 48 hours) switch the receiver off completely,
and the next fix is a search from scratch. The limit can be changed with `set gps standby <seconds>`
(`0` = always switch off, `default` = one hour); `get gps standby` shows it.
`gps off` also switches the receiver off completely, on every board.
A fix that starts from scratch needs more time, most of all in poor reception. So whenever the
receiver was switched off completely (a GPS interval above the limit, `gps off` then `gps on`, a
boot), a companion gives the next fix 5 minutes instead of 2 before it gives up until the next
interval. Repeaters and room servers already allow 5 minutes every time.
These rules are the same on every board, and a board added later follows them without any extra
work. A board with only one way to switch its GPS off uses that way on both sides of the limit.
> [!NOTE]
> **T1000-E and MeshTracker X1:** until now the receiver kept its clock supply through every sleep,
> whatever the interval, and through `gps off`. With a GPS interval above one hour, and after
> `gps off`, it is now switched off completely, so the next fix takes longer.
> `set gps standby 604800` keeps the old behaviour for intervals up to a week.
## The clock survives a reboot
A reboot no longer sends the clock back to 1970 on boards without a clock chip. The time is restored
at boot and is at most a few seconds behind. A full power loss still resets it until the next GPS fix
or phone sync.
## Clock chips are recognised more reliably
Some boards carry a battery-backed clock chip (DS3231/DS3232/DS1307, PCF8563, RV-3028, RX8130CE). At
boot the firmware checks that the device answering at the chip's address really is that chip, because
other parts can share the address. That check had two faults:
- **A real clock chip could be skipped.** If another firmware had left it in 12-hour mode, or with a
year out of range, it was treated as "not a clock": no time was read from it and none was ever
written back, so it stayed that way.
- **An erased memory chip at the same address could be taken for a clock.**
The check now uses the bits each chip's data sheet defines as always zero, and a device is passed over
only when two reads both rule it out. A time is restored only from a read in which every field is
valid.
Thanks to **ptr727** for finding and fixing this
([PR #99](https://github.com/liquidraver/ZephCore/pull/99)).
## USB companion: a hang right after boot
A companion on USB could stop responding when the host sent it a command straight after opening the
port following a boot: nothing more came out of the USB port and the node stopped handling mesh
traffic, while Bluetooth kept advertising. Only a reset recovered it.
The cause is in the USB serial driver of the Zephyr version 1.17.6 moved to: with its first 64-byte
buffer already full, it reported free space but accepted no data, and the firmware retried forever.
On a Wio Tracker L1 debug build, where the boot log fills that buffer, it happened on every such boot.
It was not reproduced on a release build, but the boot banner left only 3 bytes of margin there.
The driver is patched. On the Wio Tracker L1, 6 of 6 debug boots and 3 of 3 release boots now respond,
and the companion protocol test gives the same replies as 1.17.6.
The same patch covers a second way into the same loop: a host computer going to sleep with the port
open. That one is fixed from reading the code and has not been reproduced on hardware.
## Also in this release
- **Malformed encrypted packets are rejected earlier**, before any cryptography runs.
- **Large contact lists**: up to 24 contacts can share the same one-byte hash, up from 8.
- **T1000-E**: a pin that was wrongly driven as a sensor enable is left alone. Sensor readings are
unchanged.
- **New board**: Seeed LR2021 LoRa Plus EVK with a XIAO nRF54LM20A.
- **Zephyr** updated to `ac03a4a9085`.
- **LR2021 with `rxduty` on** (MeshTracker X1, both LR2021 EVK kits): after every noise-floor
measurement the chip rejected the command that puts it back into its duty cycle. The next channel
check recovered it and no packets were lost; the driver now returns the chip to standby first, and
the command is accepted.
- **New board**: Seeed LR2021 LoRa Plus EVK with a XIAO nRF54LM20A. Build it from source; there is no
published firmware for it yet.
- **Zephyr** updated to `ac03a4a9085`. One change in it would have been visible and is handled:
e-paper displays would have drawn white text on a black page. The RAK4631's LEDs are now declared
by ZephCore, since Zephyr's board file no longer describes them; nothing changes on the board.
- **Documentation**: the README was reorganised, build and flashing instructions moved to
`docs/BUILDING.md`, and the example board and porting guide were rewritten for the current board
layout.
+11 -7
View File
@@ -925,19 +925,23 @@ config ZEPHCORE_GPS_FIX_TIMEOUT_SEC
GPS will be powered off after this timeout.
Default 120s — 30s was too aggressive for Air530Z / MAX-7Q warm
starts in marginal sky conditions; the acquire loop would time out
before the 3-consecutive-good-fix gate could promote. Only applies
to wake cycles after the first successful fix since enable.
before the 3-consecutive-good-fix gate could promote. Applies to
wake cycles where the module kept its state; the first acquisition
and every wake after a full power-off use
ZEPHCORE_GPS_FIRST_FIX_TIMEOUT_SEC.
config ZEPHCORE_GPS_FIRST_FIX_TIMEOUT_SEC
int "GPS first-acquisition timeout in seconds"
default 300
range 30 1800
help
Bounded window for the FIRST position fix after GPS is enabled
(cold start). Longer than the normal fix timeout because a cold
start may need to download almanac data. If no fix is acquired in
this window the node drops into the normal duty cycle anyway, so
the GPS can never stay powered indefinitely with no sky view.
Bounded window for a position fix that follows a full power-off
(cold start): the first one after GPS is enabled, and every wake
when the duty interval is above the `gps standby` limit, on every
board. Longer than the normal fix timeout because a cold start may
need to download almanac data. If no fix is acquired in this
window the node drops into the normal duty cycle anyway, so the
GPS can never stay powered indefinitely with no sky view.
Default 300s (5 minutes). Companion mode only; repeaters use a
fixed 5-minute time-sync window.
+28 -28
View File
@@ -13,7 +13,10 @@
* stays powered, see gps_power.cpp) for fast re-acquisition
* - GNSS UARTE suspended (device PM) while GPS is off/standby — releases
* HFCLK on nRF52840 (~0.5-1 mA), resumed before every wake
* - Full power-off only on user-disable or System OFF
* - Every board: a standby longer than prefs.gps_standby_max is the board's
* full power-off instead of its state-keeping one (see gps_go_to_standby)
* - Full power-off also on user-disable, on boot with the GPS disabled and on
* System OFF; the acquisition after any full power-off gets the long window
*/
#include "gps_internal.h"
@@ -70,6 +73,7 @@ static enum gps_state gps_current_state = GPS_STATE_OFF;
static uint8_t consecutive_good_fixes = 0;
static bool first_fix_acquired = false; /* True after first 3-good-fix cycle since enable. Cleared on gps_enable(false) and at boot. */
static bool first_acquire_used = false; /* True once the one-time long cold-start window has ended (fix or timeout). Cleared on gps_enable(false) and at boot. */
static bool standby_powered_off = false; /* The last standby was the full power-off (interval past gps_standby_max_sec), so the wake after it is a cold start. Set on every standby, cleared on gps_enable(false). */
static bool gps_time_synced = false; /* True after GPS syncs RTC. Starts false at boot (RTC reset),
* set true after 3 good fixes, cleared when GPS disabled. */
static int64_t last_fix_uptime_ms = 0; /* k_uptime when last validated fix was acquired */
@@ -488,13 +492,17 @@ static void gps_hold_sleep_lock(bool hold)
* on forever when there's no sky. Spent once (first_acquire_used set on the
* first standby), after which the node uses the normal duty cycle regardless
* of whether a fix was obtained.
* - All later windows: the normal (warm) acquire timeout. */
* - A wake from a standby that was the full power-off: the same long window,
* every time. The module lost its state, so this is a cold start again, and
* in poor reception that does not fit the warm window. Decided from the
* interval like the power-off itself, never from the board.
* - All other windows: the normal (warm) acquire timeout. */
static uint32_t gps_acquire_window_ms(void)
{
if (gps_repeater_mode) {
return GPS_REPEATER_SYNC_TIMEOUT_MS;
}
if (!first_fix_acquired && !first_acquire_used) {
if (standby_powered_off || (!first_fix_acquired && !first_acquire_used)) {
return gps_first_fix_timeout_ms;
}
return gps_acquire_timeout_ms;
@@ -530,11 +538,16 @@ static void gps_go_to_standby(void)
* RTC survive the cut and re-acquisition is a warm/hot start, not cold.
* Other non-GPIO boards: software sleep via UART commands (PMTK + UBX). */
gps_reapply_cancel();
/* A standby-pin board keeps the supply only for a short interval: its
* Standby draws all the time, a cold start only for a few minutes, so
* past gps_standby_max_sec the supply cut is the cheaper one. */
gps_module_power(false, !HAS_GPS_WAKEUP ||
wake_interval / 1000U <= gps_standby_max_sec);
/* The module keeps its state (backup sleep, standby pin, VRTC) only for
* a short interval: that draws all the time, a cold start only for a
* few minutes, so past gps_standby_max_sec the full power-off is the
* cheaper one. Not a board property: every board takes the same
* decision, and gps_power_control() turns it into whatever the board's
* pins can do. Where they give one off state only (a bare supply
* switch, a bare standby pin, the UART sleep commands) both sides of
* the limit are that state. */
standby_powered_off = wake_interval / 1000U > gps_standby_max_sec;
gps_module_power(false, !standby_powered_off);
/* Module is off/asleep — release the UART until the next wake
* (nRF: drops the HFCLK request held by the armed RX). */
@@ -884,12 +897,12 @@ void gps_enable(bool enable)
k_work_cancel_delayable(&gps_timeout_work);
gps_reapply_cancel();
/* Power off GPS — AG3335 RTC backup sleep where the board has it
* (Arduino stop_gps), full power off otherwise.
* Boards with no power line get the UART sleep commands, as in
* the duty cycle's standby. A standby-pin board cuts the supply
* here: its Standby still draws, and this off has no end. */
gps_module_power(false, !HAS_GPS_WAKEUP);
/* Full power-off on every board: this off has no end, and any
* state-keeping one (backup sleep, standby pin, VRTC) draws all
* the time. Boards with no power line get the UART sleep
* commands, as in the duty cycle's standby. The next enable is
* a cold start and gets the long window (flags below). */
gps_module_power(false, false);
/* GPS is off until re-enabled — release the UART. */
gps_uart_set_power(false);
@@ -913,6 +926,7 @@ void gps_enable(bool enable)
* expecting it to try hard for a fix. */
first_fix_acquired = false;
first_acquire_used = false;
standby_powered_off = false;
/* Clear time sync flag - time will drift, allow phone sync again */
gps_time_synced = false;
@@ -947,20 +961,6 @@ uint32_t gps_get_poll_interval_sec(void)
#endif
}
bool gps_has_standby_pin(void)
{
return HAS_GPS_WAKEUP;
}
uint32_t gps_get_standby_max_sec(void)
{
#if HAS_GNSS
return gps_standby_max_sec;
#else
return 0;
#endif
}
void gps_set_standby_max_sec(uint32_t sec)
{
#if HAS_GNSS
+4 -6
View File
@@ -105,12 +105,10 @@ void gps_ensure_power_state(bool should_be_enabled);
void gps_get_position(struct gps_position *pos);
uint32_t gps_get_poll_interval_sec(void);
void gps_set_poll_interval_sec(uint32_t interval);
/* Boards with a module standby pin beside a supply switch (gps-wakeup alias):
* duty intervals up to this many seconds use the pin (supply kept, hot start
* on wake), longer ones cut the supply. 0 = always cut. Takes effect at the
* next standby. */
bool gps_has_standby_pin(void);
uint32_t gps_get_standby_max_sec(void);
/* Every board: duty intervals up to this many seconds keep the module's state
* between fixes (backup sleep, standby pin, VRTC: a fast fix on wake), longer
* ones take the board's full power-off. 0 = always the full power-off. Takes
* effect at the next standby. */
void gps_set_standby_max_sec(uint32_t sec);
/* Get RTC time from GPS (returns Unix timestamp, 0 if no valid time) */
+1 -1
View File
@@ -87,7 +87,7 @@ void gps_sat_tally(uint8_t out[5]);
#endif
/* ---- gps_power.cpp ---- */
/* keep_vrtc (off only): T1000-E warm standby. */
/* keep_vrtc (off only): the board's state-keeping off, if it has one. */
void gps_power_control(bool on, bool keep_vrtc = false);
/* The power line or rail if the board has one, else the UART sleep commands. */
void gps_module_power(bool on, bool keep_vrtc = true);
+14 -9
View File
@@ -147,9 +147,10 @@ static const struct gpio_dt_spec gps_resetb_gpio = GPIO_DT_SPEC_GET(DT_ALIAS(gps
/* Module standby pin (L76K WAKEUP: asserted = run, de-asserted = Standby, RF
* off with the core powered) on a board that ALSO has a supply switch
* (gps-enable): standby uses this pin and keeps the supply, so a wake is a
* hot start; a full off (`gps off`, boot with GPS disabled, System OFF) cuts
* the supply, since Standby still draws. A board whose only control is the
* standby pin (Wio Tracker L1) declares it as gps-enable instead. */
* hot start; a full off (`gps off`, a standby past prefs.gps_standby_max,
* boot with GPS disabled, System OFF) cuts the supply, since Standby still
* draws. A board whose only control is the standby pin (Wio Tracker L1)
* declares it as gps-enable instead. */
#if HAS_GPS_WAKEUP
static const struct gpio_dt_spec gps_wakeup_gpio = GPIO_DT_SPEC_GET(DT_ALIAS(gps_wakeup), gpios);
#endif
@@ -250,10 +251,13 @@ static void gps_drive_off_levels(bool keep_vrtc, bool system_off)
/* GPS power control with warm standby support.
* @param on true = power on, false = power off
* @param keep_vrtc When powering off: true = keep VRTC alive (warm standby,
* preserves ephemeris/almanac/RTC for fast re-acquisition),
* false = full power-off (cold start on next wake).
* Only relevant on T1000-E (HAS_GPS_VRTC); ignored on other boards. */
* @param keep_vrtc When powering off: true = the state-keeping off this board
* has (AG3335 backup sleep, the gps-wakeup standby pin, VRTC
* left on: ephemeris/almanac/RTC survive for a fast
* re-acquisition), false = full power-off (cold start on
* next wake). The caller decides from the standby length
* alone (prefs.gps_standby_max), never from the board; a
* board with one off state lands in it either way. */
void gps_power_control(bool on, bool keep_vrtc)
{
#if HAS_GPS_POWER_REGULATOR
@@ -276,8 +280,9 @@ void gps_power_control(bool on, bool keep_vrtc)
* (driver PM can hang on modem_pipe_close / modem_chat_run_script).
* The GNSS driver's modem pipe stays open.
*
* T1000-E / X1 (HAS_GPS_BACKUP_SLEEP): standby and app toggle use the
* AG3335 RTC backup sleep, as Arduino stop_gps().
* T1000-E / X1 (HAS_GPS_BACKUP_SLEEP): standby up to
* prefs.gps_standby_max uses the AG3335 RTC backup sleep, as Arduino
* stop_gps(); a longer standby and `gps off` cut VRTC too.
* Simple boards (Wio etc.): Full power off/on via GPS_EN. */
if (on) {
#if HAS_GPS_WAKEUP
@@ -755,6 +755,11 @@ zephyr_udc0: &usbd {
* gps-vrtc-enable backup (VRTC) supply, kept on for warm starts
* gps-sleep-int, gps-rtc-int AG3335 sleep / RTC interrupt pins (t1000_e)
*
* Nothing else is needed for `set gps standby`: on every board a standby
* longer than that limit (default one hour) is a full power-off, a shorter
* one keeps the module's state if the pins above give a way to (gps-wakeup,
* or gps-vrtc-enable). With gps-enable alone the two are the same.
*
* chosen zephcore,gps-power a regulator instead of a pin: a
* regulator-fixed node, or a PMU rail (heltec_t096,
* ttgo_tbeam)
+4 -7
View File
@@ -1202,8 +1202,7 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, const char* command, cha
reply[0] = '>'; reply[1] = ' ';
gps_get_diag_report(reply + 2, cap - 2);
} else if (memcmp(config, "gps standby", 11) == 0) {
if (!gps_has_standby_pin()) strcpy(reply, "> n/a (no GPS standby pin on this board)");
else snprintf(reply, CLI_REPLY_SIZE, "> %u", (unsigned)gps_get_standby_max_sec());
snprintf(reply, CLI_REPLY_SIZE, "> %u", (unsigned)_prefs->gps_standby_max);
} else if (memcmp(config, "gps duty", 8) == 0) {
uint32_t s = gps_get_poll_interval_sec(); // now-effective value
if (s == 0) strcpy(reply, "> always on (0)");
@@ -1807,16 +1806,14 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, const char* command, cha
strcpy(reply, "usage: set gps diag <0|1|on|off>");
}
} else if (memcmp(config, "gps standby", 11) == 0) {
// set gps standby <seconds> | default (0 = always cut the supply)
// set gps standby <seconds> | default (0 = always the full power-off)
const char* arg = config + 11;
while (*arg == ' ') arg++;
char* end = NULL;
unsigned long parsed = strtoul(arg, &end, 10);
bool is_default = strcmp(arg, "default") == 0;
if (!gps_has_standby_pin()) {
strcpy(reply, "Error: no GPS standby pin on this board");
} else if (!is_default && (*arg == '\0' || end == arg || *end != '\0' || parsed > GPS_INTERVAL_MAX_SEC)) {
strcpy(reply, "usage: set gps standby <seconds> | default (0 = always cut the supply)");
if (!is_default && (*arg == '\0' || end == arg || *end != '\0' || parsed > GPS_INTERVAL_MAX_SEC)) {
strcpy(reply, "usage: set gps standby <seconds> | default (0 = always power off)");
} else {
uint32_t val = is_default ? GPS_STANDBY_MAX_DEFAULT_SEC : (uint32_t)parsed;
_prefs->gps_standby_max = val;
+2 -2
View File
@@ -142,8 +142,8 @@ struct NodePrefs {
* without this marker is upgraded to gps_enabled = 1 once. */
uint8_t gps_enabled_set;
uint32_t gps_interval; // in seconds
/* Standby-pin boards: duty intervals up to this (seconds) keep the GPS
* supply and use the standby pin, longer ones cut it. 0 = always cut. */
/* Every board: duty intervals up to this (seconds) keep the GPS module's
* state between fixes, longer ones power it off fully. 0 = always off. */
uint32_t gps_standby_max;
uint8_t advert_loc_policy;
uint32_t discovery_mod_timestamp;