Skip to content

feat: PROVES USP radio integration (collapses PRs #1-#2) - #3

Closed
Mikefly123 wants to merge 4 commits into
mainfrom
feat/proves-usp-radio
Closed

feat: PROVES USP radio integration (collapses PRs #1-#2)#3
Mikefly123 wants to merge 4 commits into
mainfrom
feat/proves-usp-radio

Conversation

@Mikefly123

Copy link
Copy Markdown

Purpose

Single integration branch carrying both open radio_planner.c changes, so the proves-core-reference superproject can pin USP to one commit instead of tracking two separate branches. Both source PRs stay open for traceability/review history; nothing here is merged or closed.

Included changes

  • fix(radio_planner): exempt UNLOCK_RADIO_ACCESS from the failsafe panic #1 fix/radio-planner-failsafe-exempt-unlock — exempts UNLOCK_RADIO_ACCESS from the failsafe panic check in rp_callback. A lock task held open past the failsafe window (e.g. continuous RX under the raw RAC) keeps its original start_time_ms; unlock_radio_access retypes the still-RUNNING task to UNLOCK before the engine processes it, so without this exemption the next rp_callback evaluates the failsafe against the stale start time and panics at the moment the client releases the lock.
  • feat(radio_planner): lazy-sleep hysteresis via STDBY_XOSC fallback mode #2 feat/rp-lazy-sleep-hysteresis — adds an STDBY_XOSC fallback mode with hysteresis for lazy radio sleep. HWIL: downlink time 41.65s → 36.08s (1.15x), 24h soak green (2026-07-26).

Merge method

git merge --no-ff of each PR branch into feat/proves-usp-radio off main (351b201), in order #1 then #2, with per-PR merge commit messages. Both merges were clean (no conflicts) since the two changes touch disjoint regions of radio_planner.c (failsafe check vs. sleep-state machine).

Verification

  • git diff main feat/proves-usp-radio -- smtc_rac_lib/radio_planner/ == union of git diff main <PR#1 branch> and git diff main <PR#2 branch> (143 = 7 + 136 lines added, same 3 files).
  • Local pcr-usp-merge patch 0009-fix-radio-planner-failsafe-exempt-unlock-radio-access.patch (applied against 351b201) is byte-identical to the failsafe hunk landed here.
  • No changes made to any vendored patch file.

Related

Mikefly123 and others added 4 commits July 23, 2026 18:40
The rp_callback() failsafe panics/reboots any task that has been
RUNNING for more than 128 s, with an explicit exemption for
RP_TASK_TYPE_LOCK_RADIO_ACCESS so a client holding the radio lock
open indefinitely doesn't trip it. RP_TASK_TYPE_UNLOCK_RADIO_ACCESS
was missing the same exemption.

A lock task held open longer than the failsafe window (e.g.
continuous RX under the raw RAC) keeps its original start_time_ms.
When the client releases the lock, unlock_radio_access() retypes the
still-RUNNING task from LOCK to UNLOCK before the engine processes
it. The very next rp_callback() then evaluates the failsafe against
that stale start_time_ms and panics at the exact moment the client
releases the lock, causing a silent reboot after any lock held past
128 s.

Add the same task-type exemption for RP_TASK_TYPE_UNLOCK_RADIO_ACCESS
so the retype-on-release path is no longer misclassified as a hung
task.
Hold the radio in STDBY_XOSC for RP_LAZY_SLEEP_DELAY_MS (default 200 ms)
after a task completes instead of sleeping it immediately, so back-to-back
tasks (e.g. sustained file downlink) skip the sleep-wakeup sequence and
the TCXO startup delay on every frame.

The SX1262 drops to STDBY_RC by itself on TX_DONE, so a synchronous
SetStandby(XOSC) after task-free would just re-pay the TCXO startup on
the critical path. Instead, configure the transceiver's RX/TX fallback
mode to STDBY_XOSC once per hold cycle (ral_set_rx_tx_fallback_mode),
so the oscillator never stops between frames.

Hysteresis expiry rides the planner's own rp_set_alarm: on expiry with
no task launched, the radio sleeps exactly as before. Scheduled future
tasks flush the hold immediately (the future launch pays the wakeup, as
legacy). Defining RP_LAZY_SLEEP_DELAY_MS=0 compiles the exact legacy
immediate-sleep behavior.

Measured on RP2350 + SX1262 (E22-400M30S) at GFSK-75k, 178,704 B file
downlink: 41.65 s -> 36.08 s (4290 -> 4953 B/s, 1.15x). Regressions:
true-sleep wakeup path, RX, and 150 s idle (no failsafe trip) all pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added configurable lazy-sleep behavior for the radio planner, keeping the radio in standby briefly when new work is expected.
    • Added a configurable delay window, with an option to retain immediate-sleep behavior.
    • Preserved scheduled task timing while managing radio sleep transitions.
  • Bug Fixes

    • Improved handling of radio access locks and sleep transitions to prevent premature sleep or delayed task launches.

Walkthrough

The radio planner adds configurable lazy-sleep hysteresis, tracks pending sleep state, defers post-IRQ sleep, and coordinates sleep flushing with task scheduling and launch. UNLOCK_RADIO_ACCESS is also exempted from the failsafe timeout check.

Changes

Radio planner lazy sleep

Layer / File(s) Summary
Lazy-sleep configuration and state
smtc_rac_lib/radio_planner/src/radio_planner_types.h, smtc_rac_lib/radio_planner/src/radio_planner.h, smtc_rac_lib/radio_planner/src/radio_planner.c
Adds the configurable RP_LAZY_SLEEP_DELAY_MS setting, planner state fields, and initialization for lazy-sleep tracking.
Callback sleep deferral
smtc_rac_lib/radio_planner/src/radio_planner.c
Updates failsafe handling for UNLOCK_RADIO_ACCESS and defers post-IRQ sleep while configuring an optional RX/TX fallback.
Arbiter and launch coordination
smtc_rac_lib/radio_planner/src/radio_planner.c
Coordinates timer deadlines, task launches, pending-hold cancellation, and final radio sleep through rp_lazy_sleep_flush().
Estimated code review effort: 4 (Complex) ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RadioPlanner
  participant RALF
  participant TaskArbiter
  RadioPlanner->>RALF: Configure RX/TX fallback after IRQ
  RadioPlanner->>TaskArbiter: Record lazy-sleep deadline
  TaskArbiter->>RadioPlanner: Launch task or expire hysteresis
  RadioPlanner->>RALF: Call ral_set_sleep when hold is flushed
Loading

Possibly related PRs

Poem

A bunny naps while timers glow,
The radio waits before the snow.
If tasks arrive, it stays awake;
If silence comes, sleep plans take.
With fallback paws and deadlines bright,
The planner tucks the radio goodnight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly reflects the main change: integrating USP radio changes and collapsing two PRs into one branch.
Description check ✅ Passed The description accurately describes the integrated radio planner changes and the merge intent.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@smtc_rac_lib/radio_planner/src/radio_planner.c`:
- Around line 1279-1285: Defer TCXO shutdown from the unconditional stop in
rp_callback until the lazy-sleep flush: skip stopping it while the STDBY_XOSC
hold or replacement task is active, and in the lazy_sleep_pending branch after
ral_set_sleep succeeds, stop the TCXO. Update the relevant rp_callback logic and
this lazy-sleep handling without changing the existing sleep and fallback-state
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 10f48b94-49a0-4f61-8277-9e98eb92eb8b

📥 Commits

Reviewing files that changed from the base of the PR and between 351b201 and 8a60e4a.

📒 Files selected for processing (3)
  • smtc_rac_lib/radio_planner/src/radio_planner.c
  • smtc_rac_lib/radio_planner/src/radio_planner.h
  • smtc_rac_lib/radio_planner/src/radio_planner_types.h

Comment on lines +1279 to +1285
if( rp->lazy_sleep_pending == true )
{
rp->lazy_sleep_pending = false;
// Re-apply the fallback mode on the first hold after the next wakeup:
// it is not guaranteed to survive the sleep period on all radios.
rp->lazy_fallback_configured = false;
SMTC_MODEM_HAL_PANIC_ON_FAILURE( ral_set_sleep( &( rp->lazy_sleep_target->ral ), true ) == RAL_STATUS_OK );

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Defer TCXO shutdown until the lazy-sleep flush.

After Lines 567-569 arm the STDBY_XOSC hold, rp_callback still unconditionally stops the TCXO at Lines 597-599. The eventual flush here only sleeps the radio, so the TCXO is stopped too early and the next task cannot benefit from the hysteresis window. Skip TCXO shutdown while a hold or replacement task is active, and stop it here after ral_set_sleep.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@smtc_rac_lib/radio_planner/src/radio_planner.c` around lines 1279 - 1285,
Defer TCXO shutdown from the unconditional stop in rp_callback until the
lazy-sleep flush: skip stopping it while the STDBY_XOSC hold or replacement task
is active, and in the lazy_sleep_pending branch after ral_set_sleep succeeds,
stop the TCXO. Update the relevant rp_callback logic and this lazy-sleep
handling without changing the existing sleep and fallback-state behavior.

@Mikefly123

Copy link
Copy Markdown
Author

Superseded by native GitHub stacked PRs: #1 (fix/radio-planner-failsafe-exempt-unlock) -> #2 (feat/rp-lazy-sleep-hysteresis), stack Lora-net#4 (main <- #1 <- #2). Stack-top tree verified identical to this branch's 8a60e4a (empty diff).

The feat/proves-usp-radio branch is retained (not deleted) — proves-core-reference's west.yml still pins it at 8a60e4a. It stays until the stack cascade-merges and the pcr pin is updated to track the merged main.

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.

1 participant