Skip to content

Treat the GPS enable pin as a pin number, not a truth value (iteration branch) - #4

Open
ptr727 wants to merge 1 commit into
devfrom
work/gps-enable-pin
Open

ptr727 wants to merge 1 commit into
devfrom
work/gps-enable-pin

Conversation

@ptr727

@ptr727 ptr727 commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Iteration branch for the GPS enable-pin fix. Targets my own fork's dev for review
before a squashed version goes upstream as a draft. Not intended to merge here.

Raised by a reviewer on meshcore-dev#3423 (upstream). Kept separate because it changes pin
handling rather than reporting.

Problem

static uint32_t gpsResetPin = 0;
...
if(PIN_GPS_EN){ gpsResetPin = PIN_GPS_EN; }

A truth test on a pin number, assigned into an unsigned variable. Two defects:

  1. PIN_GPS_EN is -1 on boards with no enable pin. if(-1) passes, so
    gpsResetPin becomes 4294967295. start_gps() / stop_gps() then call
    pinMode() and digitalWrite() with that on every gps on / gps off.
  2. 0 is a legitimate pin number that the same test rejects, so a board wiring
    the enable line to pin 0 would silently never store it.

Case 1 is harmless today only because the core drops it
(cores/nRF5/wiring_digital.c:28-32):

void pinMode( uint32_t ulPin, uint32_t ulMode ) {
  if (ulPin >= PINS_COUNT) { return; }

Relying on that is fragile, and it leaves start_gps()/stop_gps() silently
ineffective on RAK4631 with nothing to say why.

Change

  • gpsResetPin becomes int, initialised to -1 meaning "no enable pin".
  • The macro is tested with >= 0, excluding -1 and accepting 0.
  • Both toggles are guarded, so the no-pin case is explicit and logged.

Behaviour is unchanged on every board in tree

Board family PIN_GPS_EN Before After
rak4631 -1 out-of-range write, dropped by the core explicit skip, logged
gat562_* 33 stores 33 stores 33
rak3401 n/a excluded by existing #ifndef RAK_3401 unchanged
hypothetical pin 0 0 never stored (bug) stored correctly

rak4631 is the only variant in the tree defining PIN_GPS_EN=-1, and no variant uses
pin 0, so that part is a latent fix.

Deliberately NOT changed

The reviewer on meshcore-dev#3423 suggested "always setting gpsResetPin to the tested ioPin,
and only overriding it when PIN_GPS_EN is present and not -1".

I did not do that, and I think it would be a regression. On RAK4631 the pin that wakes
the receiver is WB_IO2 (pin 34), the shared 3V3_S WisBlock slot rail, confirmed on
hardware:

DEBUG: Serial GPS: 63 byte(s) on Serial1 with IO pin 34 (not yet parsed)

stop_gps() drives gpsResetPin LOW, and it is called at boot on stock firmware via
the #ifndef FORCE_GPS_ALIVE path. So storing ioPin there would pull the slot rail
low on every boot, powering down the RAK12002 RTC and anything else in the slots.

Whether a GPS toggle should drive a shared rail is a design question for maintainers.
This PR keeps the current power behaviour exactly and only makes the pin handling
honest.

Testing

Hardware, RAK4631 + RAK12002:

clock     ->  20:37 - 16/9/2026 UTC
gps       ->  on, active, no fix, 0 sats
gps off   ->  DEBUG: GPS: no enable pin configured, power state unchanged
gps       ->  on, deactivated, no fix, 0 sats
gps on    ->  DEBUG: GPS: no enable pin configured, power state unchanged
clock     ->  20:38 - 16/9/2026 UTC

The clock still runs across both toggles, confirming the slot rail is untouched.

Builds: RAK_4631_repeater and GAT562_Mesh_Tracker_Pro_companion_radio_usb, the two
RAK_WISBLOCK_GPS families that differ in this code.

Review checklist

  • Is an explicit skip the right no-pin behaviour, or should start_gps()/
    stop_gps() fall through to _location->begin()/stop() as the non-RAK path
    does?
  • int vs int8_t for a pin number; int matches the -1 sentinel style used by
    GPS_EN elsewhere.
  • Textual proximity to Make GPS status reporting say what was actually checked 🤖🤖 meshcore-dev/MeshCore#3423, which edits the log line a few lines above. No
    overlapping hunks, but one will need a trivial rebase if the other merges first.

gpsResetPin was uint32_t and assigned from a truth test:

  static uint32_t gpsResetPin = 0;
  ...
  if(PIN_GPS_EN){ gpsResetPin = PIN_GPS_EN; }

Two defects fall out of that. PIN_GPS_EN is -1 on boards with no enable
pin, which passes the truth test and stores 4294967295 in an unsigned
pin variable; start_gps() and stop_gps() then call pinMode() and
digitalWrite() with it on every gps on/off. And 0 is a legitimate pin
number that the same test rejects, so a board wiring the enable line to
pin 0 would silently never store it.

Today the first case is harmless only because the core discards it:
cores/nRF5/wiring_digital.c checks 'if (ulPin >= PINS_COUNT) return;'
before use. Relying on that is fragile, and it leaves start_gps() and
stop_gps() silently doing nothing on RAK4631 with no indication why.

Make gpsResetPin signed with -1 meaning 'no enable pin', test the macro
with >= 0 so -1 is excluded and 0 is accepted, and guard both toggles so
the no-pin case is explicit and logged rather than relying on a bounds
check further down.

Behaviour is unchanged on every board in tree. rak4631 is the only
variant defining PIN_GPS_EN=-1, and it goes from an out-of-range write
that the core drops to an explicit skip. The gat562 boards define 33 and
are unaffected, rak3401 is excluded by the existing ifndef, and no
variant uses pin 0 today, so that part is a latent fix.

Deliberately not changed: the serial branch does not fall back to the
ioPin that woke the receiver, the way the I2C branch does. On RAK4631
that pin is WB_IO2, the shared 3V3_S slot rail, so reusing it would make
stop_gps() power down the RTC and every other slot module. Whether a GPS
toggle should drive a shared rail is a design question for maintainers,
not something to change here.

Verified on RAK4631 + RAK12002: 'gps off' and 'gps on' log the new
no-enable-pin line, the CLI reply is unchanged, and the clock keeps
running across both, confirming the slot rail is untouched. Build
checked on RAK_4631_repeater and
GAT562_Mesh_Tracker_Pro_companion_radio_usb, the two RAK_WISBLOCK_GPS
board families that differ here.
Copilot AI lite review requested due to automatic review settings September 16, 2026 20:39
@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 13 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 48e4a4ba-308b-4d30-8753-d573b89fff50

📥 Commits

Reviewing files that changed from the base of the PR and between 0ec5ed5 and 0ab168d.

📒 Files selected for processing (1)
  • src/helpers/sensors/EnvironmentSensorManager.cpp

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ptr727

ptr727 commented Sep 16, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The changes are small, well-scoped, and concretely prevent invalid pin operations without altering the intended GPS power behavior for the affected boards.

Pull request overview

This PR fixes GPS enable-pin handling on RAK WisBlock GPS builds by treating the enable pin as a pin number (with -1 meaning “no pin”) instead of relying on truthiness, which previously mis-handled PIN_GPS_EN == -1 and would also reject a legitimate pin 0.

Changes:

  • Change gpsResetPin from uint32_t to signed int and initialize it to -1 to represent “no enable pin”.
  • Replace the if (PIN_GPS_EN) truth test with if (PIN_GPS_EN >= 0) so -1 is excluded and 0 is accepted.
  • Guard start_gps() / stop_gps() pin toggling on gpsResetPin >= 0 and log an explicit message when no enable pin is configured.
File summaries
File Description
src/helpers/sensors/EnvironmentSensorManager.cpp Corrects GPS enable-pin storage and guards pin toggling to avoid invalid pin writes (notably when PIN_GPS_EN == -1).
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants