mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-15 02:49:54 +00:00
make gps standby command universal
This commit is contained in:
@@ -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
@@ -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) |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user