From 3010b856e4236ed34cac23dba96e2e3f1f1feda2 Mon Sep 17 00:00:00 2001 From: Michael Pham <61564344+Mikefly123@users.noreply.github.com> Date: Sun, 26 Jul 2026 11:39:46 -0700 Subject: [PATCH 1/2] chore(radio): collapse carried module patches into OSSF fork integration pins Re-pin usp_zephyr, usp, zephyr, fprime, and fprime-zephyr to the Open-Source-Space-Foundation fork integration branches (feat/proves-usp-radio) and delete the migrated carried-patch machinery (patches 0001-0003, 0005-0010, fprime-com-aggregator-bounded-timeout, fprime-sched-tick-drop; Makefile targets usp-patches / usp-core-patches / zephyr-patches and the fprime apply steps in 'submodules'; the CI 'Apply carried patches' step). fprime-yamcs-noapp-path.patch stays: it patches the pip-installed fprime-yamcs package, not a submodule. Co-Authored-By: Claude Fable 5 --- .github/workflows/ci.yaml | 9 - .gitmodules | 4 +- .pre-commit-config.yaml | 5 +- Makefile | 92 +------ lib/fprime | 2 +- lib/fprime-zephyr | 2 +- lib/zephyr-workspace/zephyr | 2 +- ...external-RF-switch-GPIO-support-tx-r.patch | 251 ------------------ ...emove-select-ZEPHYR_LORA_BASICS_MODE.patch | 36 --- ...5-fix-LR_FHSS_SRC_PATH-for-flattened.patch | 34 --- ...ck-tx-fifo-busy-on-disable-and-retry.patch | 65 ----- ...up-busy-race-add-t_woff-settle-delay.patch | 58 ---- ...acm-bound-poll-out-backpressure-wait.patch | 36 --- ...tc-modem-hal-implement-rac-api-mutex.patch | 39 --- ...-failsafe-exempt-unlock-radio-access.patch | 20 -- ...nrf54l15-full_name-zephyr-4.4-schema.patch | 24 -- patches/README.md | 61 ++--- ...prime-com-aggregator-bounded-timeout.patch | 35 --- patches/fprime-sched-tick-drop.patch | 250 ----------------- west.yml | 24 +- 20 files changed, 51 insertions(+), 998 deletions(-) delete mode 100644 patches/0001-feat-sx126x-add-external-RF-switch-GPIO-support-tx-r.patch delete mode 100644 patches/0002-fix-zephyr-4.3-remove-select-ZEPHYR_LORA_BASICS_MODE.patch delete mode 100644 patches/0003-fix-usp-main-2025-fix-LR_FHSS_SRC_PATH-for-flattened.patch delete mode 100644 patches/0005-fix-usbd-cdc-acm-stuck-tx-fifo-busy-on-disable-and-retry.patch delete mode 100644 patches/0006-fix-sx126x-wakeup-busy-race-add-t_woff-settle-delay.patch delete mode 100644 patches/0007-fix-usbd-cdc-acm-bound-poll-out-backpressure-wait.patch delete mode 100644 patches/0008-fix-smtc-modem-hal-implement-rac-api-mutex.patch delete mode 100644 patches/0009-fix-radio-planner-failsafe-exempt-unlock-radio-access.patch delete mode 100644 patches/0010-fix-boards-xiao-nrf54l15-full_name-zephyr-4.4-schema.patch delete mode 100644 patches/fprime-com-aggregator-bounded-timeout.patch delete mode 100644 patches/fprime-sched-tick-drop.patch diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 46b5cec9..335bd032 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -64,15 +64,6 @@ jobs: run: | make zephyr-workspace - - name: Apply carried patches - # west update fetches vanilla usp_zephyr/usp/zephyr modules; the USP - # radio port needs the RF-switch GPIO, Zephyr 4.3 compat, wakeup-race, - # radio-planner failsafe, and CDC-ACM fixes carried in patches/. - run: | - make usp-patches - make usp-core-patches - make zephyr-patches - - name: Setup Zephyr SDK if: steps.cache-zephyr-sdk.outputs.cache-hit != 'true' run: | diff --git a/.gitmodules b/.gitmodules index 5ea7e8a5..f3ae0fef 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ [submodule "lib/fprime"] path = lib/fprime - url = https://github.com/nasa/fprime.git + url = https://github.com/Open-Source-Space-Foundation/fprime.git [submodule "lib/zephyr-workspace/zephyr"] path = lib/zephyr-workspace/zephyr - url = https://github.com/zephyrproject-rtos/zephyr.git + url = https://github.com/Open-Source-Space-Foundation/zephyr.git [submodule "lib/fprime-zephyr"] path = lib/fprime-zephyr url = https://github.com/Open-Source-Space-Foundation/fprime-zephyr.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3e51e6d9..a405304c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,11 +3,10 @@ repos: rev: v5.0.0 hooks: - id: trailing-whitespace - # patches/*.patch are machine-generated diffs applied via `git apply`; + # patches/*.patch are machine-generated diffs applied via patch tooling; # their context/removed lines must byte-match the real upstream files, # which can legitimately have trailing whitespace. Stripping it here - # silently breaks patch application (see: 0001-feat-sx126x patch vs - # usp_zephyr's semtech,sx126x-new-common.yaml). + # silently breaks patch application. exclude: ^patches/ - id: end-of-file-fixer exclude: ^patches/ diff --git a/Makefile b/Makefile index f17f88c7..790f982e 100644 --- a/Makefile +++ b/Makefile @@ -11,28 +11,6 @@ help: ## Display this help. submodules: ## Initialize and update git submodules @git submodule foreach --recursive 'git checkout -- . && git clean -fd' || true @git submodule update --init --recursive - @echo "Applying fprime ComAggregator bounded-timeout patch (issue #432)..." - @cd lib/fprime && \ - if git apply --check ../../patches/fprime-com-aggregator-bounded-timeout.patch 2>/dev/null; then \ - git apply ../../patches/fprime-com-aggregator-bounded-timeout.patch && \ - echo "✓ Applied ComAggregator bounded-timeout patch"; \ - elif git apply --reverse --check ../../patches/fprime-com-aggregator-bounded-timeout.patch 2>/dev/null; then \ - echo "⚠ Patch already applied"; \ - else \ - echo "❌ Error: Unable to apply ComAggregator patch. Run 'cd lib/fprime && git status' to check."; \ - exit 1; \ - fi - @echo "Applying fprime sched-tick drop patch (issue #432 class)..." - @cd lib/fprime && \ - if git apply --check ../../patches/fprime-sched-tick-drop.patch 2>/dev/null; then \ - git apply ../../patches/fprime-sched-tick-drop.patch && \ - echo "✓ Applied sched-tick drop patch"; \ - elif git apply --reverse --check ../../patches/fprime-sched-tick-drop.patch 2>/dev/null; then \ - echo "⚠ Patch already applied"; \ - else \ - echo "❌ Error: Unable to apply sched-tick drop patch. Run 'cd lib/fprime && git status' to check."; \ - exit 1; \ - fi export VIRTUAL_ENV ?= $(shell pwd)/fprime-venv .PHONY: fprime-venv @@ -76,72 +54,10 @@ zephyr-setup: fprime-venv ## Set up Zephyr environment $(UV) pip install --prerelease=allow -r lib/zephyr-workspace/bootloader/mcuboot/zephyr/requirements.txt; \ } -# USP_ZEPHYR_DIR: west places usp_zephyr at this path (see west.yml). -USP_ZEPHYR_DIR ?= $(shell pwd)/lib/zephyr-workspace/modules/lib/usp_zephyr - -.PHONY: usp-patches -usp-patches: ## Apply usp_zephyr patches (RF-switch GPIO + Zephyr 4.3 compat + wakeup-busy race fix) - @if [ ! -d "$(USP_ZEPHYR_DIR)" ]; then \ - echo "❌ usp_zephyr not found at $(USP_ZEPHYR_DIR) — run 'west update usp_zephyr usp' first"; \ - exit 1; \ - fi - @echo "Applying usp_zephyr patches..." - @cd "$(USP_ZEPHYR_DIR)" && \ - for p in $(shell pwd)/patches/0001-feat-sx126x-add-external-RF-switch-GPIO-support-tx-r.patch \ - $(shell pwd)/patches/0002-fix-zephyr-4.3-remove-select-ZEPHYR_LORA_BASICS_MODE.patch \ - $(shell pwd)/patches/0003-fix-usp-main-2025-fix-LR_FHSS_SRC_PATH-for-flattened.patch \ - $(shell pwd)/patches/0006-fix-sx126x-wakeup-busy-race-add-t_woff-settle-delay.patch \ - $(shell pwd)/patches/0008-fix-smtc-modem-hal-implement-rac-api-mutex.patch \ - $(shell pwd)/patches/0010-fix-boards-xiao-nrf54l15-full_name-zephyr-4.4-schema.patch; do \ - name=$$(basename $$p); \ - if git apply --check "$$p" 2>/dev/null; then \ - git apply "$$p" && echo "✓ Applied $$name"; \ - elif git apply --reverse --check "$$p" 2>/dev/null; then \ - echo "⚠ Already applied: $$name"; \ - else \ - echo "❌ Cannot apply $$name — check usp_zephyr revision"; exit 1; \ - fi; \ - done - -# USP_DIR: the Semtech smtc_rac_lib west module (radio planner lives here). -USP_DIR ?= $(shell pwd)/lib/zephyr-workspace/modules/lib/usp - -.PHONY: usp-core-patches -usp-core-patches: ## Apply usp (smtc_rac_lib) patches (radio-planner failsafe unlock exemption) - @cd "$(USP_DIR)" && \ - for p in $(shell pwd)/patches/0009-fix-radio-planner-failsafe-exempt-unlock-radio-access.patch; do \ - name=$$(basename $$p); \ - if git apply --check "$$p" 2>/dev/null; then \ - git apply "$$p" && echo "✓ Applied $$name"; \ - elif git apply --reverse --check "$$p" 2>/dev/null; then \ - echo "⚠ Already applied: $$name"; \ - else \ - echo "❌ Cannot apply $$name — check usp revision"; exit 1; \ - fi; \ - done - -ZEPHYR_DIR ?= $(shell pwd)/lib/zephyr-workspace/zephyr - -.PHONY: zephyr-patches -zephyr-patches: ## Apply Zephyr tree patches (CDC-ACM TX fixes) - @if [ ! -d "$(ZEPHYR_DIR)" ]; then \ - echo "zephyr not found at $(ZEPHYR_DIR) — run 'west update' first"; \ - exit 1; \ - fi - @echo "Applying Zephyr patches..." - @cd "$(ZEPHYR_DIR)" && \ - for p in \ - $(shell pwd)/patches/0005-fix-usbd-cdc-acm-stuck-tx-fifo-busy-on-disable-and-retry.patch \ - $(shell pwd)/patches/0007-fix-usbd-cdc-acm-bound-poll-out-backpressure-wait.patch; do \ - name=$$(basename $$p); \ - if git apply --check "$$p" 2>/dev/null; then \ - git apply "$$p" && echo "OK Applied $$name"; \ - elif git apply --reverse --check "$$p" 2>/dev/null; then \ - echo "Already applied: $$name"; \ - else \ - echo "Cannot apply $$name — check Zephyr revision"; exit 1; \ - fi; \ - done +# Carried module patches (usp-patches / usp-core-patches / zephyr-patches and +# the fprime patch steps in `submodules`) were removed 2026-07-26: all module +# fixes now live on the Open-Source-Space-Foundation fork integration branches +# (feat/proves-usp-radio) pinned in west.yml / .gitmodules. See patches/README.md. ##@ Development diff --git a/lib/fprime b/lib/fprime index 8a62e455..baf163f3 160000 --- a/lib/fprime +++ b/lib/fprime @@ -1 +1 @@ -Subproject commit 8a62e455a90b6d4f498c332d45d65a2a819988d8 +Subproject commit baf163f3ba52ecfabaa39b4aa5847a3cecfb2ae6 diff --git a/lib/fprime-zephyr b/lib/fprime-zephyr index c997272b..4b8652e1 160000 --- a/lib/fprime-zephyr +++ b/lib/fprime-zephyr @@ -1 +1 @@ -Subproject commit c997272b4a1e404cb7a44071a17fb6dff1b535f4 +Subproject commit 4b8652e15849d21a3655943d30eda65c2dc886c0 diff --git a/lib/zephyr-workspace/zephyr b/lib/zephyr-workspace/zephyr index 1f6485ec..3838a280 160000 --- a/lib/zephyr-workspace/zephyr +++ b/lib/zephyr-workspace/zephyr @@ -1 +1 @@ -Subproject commit 1f6485eca25431b5ff27ce9a754218c9e559bbbb +Subproject commit 3838a2802c916accdfa671de77633ee45b69441c diff --git a/patches/0001-feat-sx126x-add-external-RF-switch-GPIO-support-tx-r.patch b/patches/0001-feat-sx126x-add-external-RF-switch-GPIO-support-tx-r.patch deleted file mode 100644 index 1a25b7b0..00000000 --- a/patches/0001-feat-sx126x-add-external-RF-switch-GPIO-support-tx-r.patch +++ /dev/null @@ -1,251 +0,0 @@ -From a23856a670226bb4e3e83acfc07106e47866c118 Mon Sep 17 00:00:00 2001 -From: Michael Pham <61564344+Mikefly123@users.noreply.github.com> -Date: Sat, 4 Jul 2026 09:59:41 -0700 -Subject: [PATCH 1/3] feat(sx126x): add external RF-switch GPIO support - (tx/rx-enable-gpios) - -The EBYTE E22-400M30S (SX1262) module drives its RF switch via two -dedicated GPIOs (TX-EN, RX-EN) rather than DIO2, so the existing -dio2-as-rf-switch mechanism is unusable on PROVES FCB v5e. - -Changes: -- dts/bindings/usp/semtech,sx126x-new-common.yaml: add optional - tx-enable-gpios and rx-enable-gpios phandle-array properties with - full description of operating-mode semantics. -- drivers/usp/sx126x/sx126x_hal_context.h: add tx_enable and - rx_enable gpio_dt_spec fields to sx126x_hal_context_cfg_t (both - zero-initialised / .port==NULL when absent in DT, so boards without - the properties compile and behave identically to before). -- drivers/usp/sx126x/sx126x_board.c: configure both pins as - OUTPUT_INACTIVE at init; wire them into SX126X_CONFIG via the - existing CONFIGURE_GPIO_IF_IN_DT helper. -- drivers/usp/sx126x/sx126x_hal.c: add sx126x_hal_update_rf_switch() - that intercepts the first byte of every sx126x_hal_write() command - buffer and drives the GPIOs before the SPI transaction: - TX-class (TX-EN=1, RX-EN=0): 0x83 SetTx, 0xD1 SetTxContinuousWave, - 0xD2 SetTxInfinitePreamble - RX-class (TX-EN=0, RX-EN=1): 0x82 SetRx, 0x94 SetRxDutyCycle, - 0xC5 SetCad - Inactive (TX-EN=0, RX-EN=0): 0x84 SetSleep, 0x80 SetStandby - All other opcodes leave switch state unchanged. - Deactivation of the leaving path always precedes activation of the - entering path to prevent simultaneous PA+LNA enable. - -Boards without tx-enable-gpios / rx-enable-gpios in DT are unaffected: -gpio_dt_spec.port is NULL and all branches are skipped at runtime. -Build verified: zephyr.elf + zephyr.uf2 compile clean on Zephyr 4.3 / -RP2350 with FLASH 104760 B / RAM 31564 B (ping_pong sample). - -Co-Authored-By: Claude Fable 5 ---- - drivers/usp/sx126x/sx126x_board.c | 22 +++++ - drivers/usp/sx126x/sx126x_hal.c | 87 +++++++++++++++++++ - drivers/usp/sx126x/sx126x_hal_context.h | 10 +++ - .../usp/semtech,sx126x-new-common.yaml | 26 +++++- - 4 files changed, 144 insertions(+), 1 deletion(-) - -diff --git a/drivers/usp/sx126x/sx126x_board.c b/drivers/usp/sx126x/sx126x_board.c -index 215801a..d119aba 100644 ---- a/drivers/usp/sx126x/sx126x_board.c -+++ b/drivers/usp/sx126x/sx126x_board.c -@@ -239,6 +239,26 @@ static int sx126x_init( const struct device* dev ) - } - } - -+ /* External RF-switch GPIOs — configure as outputs, inactive (both paths off) */ -+ if( config->tx_enable.port ) -+ { -+ ret = gpio_pin_configure_dt( &config->tx_enable, GPIO_OUTPUT_INACTIVE ); -+ if( ret < 0 ) -+ { -+ LOG_ERR( "Could not configure tx-enable gpio" ); -+ return ret; -+ } -+ } -+ if( config->rx_enable.port ) -+ { -+ ret = gpio_pin_configure_dt( &config->rx_enable, GPIO_OUTPUT_INACTIVE ); -+ if( ret < 0 ) -+ { -+ LOG_ERR( "Could not configure rx-enable gpio" ); -+ return ret; -+ } -+ } -+ - data->radio_status = RADIO_AWAKE; - data->tx_power_offset_db_current = config->tx_power_offset_db; - -@@ -366,6 +386,8 @@ static int sx126x_pm_action( const struct device* dev, enum pm_device_action act - CONFIGURE_GPIO_IF_IN_DT( node_id, dio1, dio1_gpios ) CONFIGURE_GPIO_IF_IN_DT( node_id, dio2, dio2_gpios ) \ - CONFIGURE_GPIO_IF_IN_DT( node_id, dio3, dio3_gpios ) \ - .dio2_as_rf_switch = DT_PROP( node_id, dio2_as_rf_switch ), \ -+ CONFIGURE_GPIO_IF_IN_DT( node_id, tx_enable, tx_enable_gpios ) \ -+ CONFIGURE_GPIO_IF_IN_DT( node_id, rx_enable, rx_enable_gpios ) \ - SX126X_CFG_TCXO( node_id ), .capa_xta = DT_PROP_OR( node_id, xtal_capacitor_value_xta, 0xFF ), \ - .capa_xtb = DT_PROP_OR( node_id, xtal_capacitor_value_xtb, 0xFF ), .reg_mode = DT_PROP( node_id, reg_mode ), \ - .tx_power_offset_db = DT_PROP_OR( node_id, tx_power_offset, 0 ), \ -diff --git a/drivers/usp/sx126x/sx126x_hal.c b/drivers/usp/sx126x/sx126x_hal.c -index a3215cc..1530077 100644 ---- a/drivers/usp/sx126x/sx126x_hal.c -+++ b/drivers/usp/sx126x/sx126x_hal.c -@@ -111,6 +111,86 @@ static void sx126x_hal_check_device_ready( const void* context ) - * --- PUBLIC FUNCTIONS DEFINITION --------------------------------------------- - */ - -+/* -+ * External RF-switch toggle helper. -+ * -+ * Called in sx126x_hal_write() before each SPI opcode transaction so the -+ * TX-EN / RX-EN lines track the radio mode without requiring a mode-callback -+ * hook (USP's SX126x HAL layer has none). -+ * -+ * Opcode table (SX126x datasheet §13.1): -+ * TX-class (TX-EN=1, RX-EN=0): -+ * 0x83 SetTx -+ * 0xD1 SetTxContinuousWave -+ * 0xD2 SetTxInfinitePreamble -+ * RX-class (TX-EN=0, RX-EN=1): -+ * 0x82 SetRx -+ * 0x94 SetRxDutyCycle -+ * 0xC5 SetCad -+ * Inactive (TX-EN=0, RX-EN=0): -+ * 0x84 SetSleep -+ * 0x80 SetStandby -+ * All other opcodes leave the switch state unchanged. -+ */ -+static void sx126x_hal_update_rf_switch( const struct sx126x_hal_context_cfg_t* config, uint8_t opcode ) -+{ -+ bool tx_active; -+ bool rx_active; -+ -+ switch( opcode ) -+ { -+ case 0x83: /* SetTx */ -+ case 0xD1: /* SetTxContinuousWave */ -+ case 0xD2: /* SetTxInfinitePreamble */ -+ tx_active = true; -+ rx_active = false; -+ break; -+ -+ case 0x82: /* SetRx */ -+ case 0x94: /* SetRxDutyCycle */ -+ case 0xC5: /* SetCad */ -+ tx_active = false; -+ rx_active = true; -+ break; -+ -+ case 0x84: /* SetSleep */ -+ case 0x80: /* SetStandby */ -+ tx_active = false; -+ rx_active = false; -+ break; -+ -+ default: -+ /* No switch change for config/status opcodes */ -+ return; -+ } -+ -+ /* Deassert the path we are leaving before asserting the new one to -+ * avoid momentarily enabling both PA and LNA simultaneously. -+ */ -+ if( config->tx_enable.port ) -+ { -+ if( !tx_active ) -+ { -+ gpio_pin_set_dt( &config->tx_enable, 0 ); -+ } -+ } -+ if( config->rx_enable.port ) -+ { -+ if( !rx_active ) -+ { -+ gpio_pin_set_dt( &config->rx_enable, 0 ); -+ } -+ } -+ if( config->tx_enable.port && tx_active ) -+ { -+ gpio_pin_set_dt( &config->tx_enable, 1 ); -+ } -+ if( config->rx_enable.port && rx_active ) -+ { -+ gpio_pin_set_dt( &config->rx_enable, 1 ); -+ } -+} -+ - sx126x_hal_status_t sx126x_hal_write( const void* context, const uint8_t* command, const uint16_t command_length, - const uint8_t* data, const uint16_t data_length ) - { -@@ -127,6 +207,13 @@ sx126x_hal_status_t sx126x_hal_write( const void* context, const uint8_t* comman - const struct spi_buf_set tx_buf_set = { tx_bufs, .count = ARRAY_SIZE( tx_bufs ) }; - - sx126x_hal_check_device_ready( context ); -+ -+ /* Toggle external RF switch before writing the mode-change opcode */ -+ if( command_length > 0 ) -+ { -+ sx126x_hal_update_rf_switch( config, command[0] ); -+ } -+ - ret = spi_write_dt( &config->spi, &tx_buf_set ); - if( ret ) - { -diff --git a/drivers/usp/sx126x/sx126x_hal_context.h b/drivers/usp/sx126x/sx126x_hal_context.h -index 228f883..0c56bef 100644 ---- a/drivers/usp/sx126x/sx126x_hal_context.h -+++ b/drivers/usp/sx126x/sx126x_hal_context.h -@@ -72,6 +72,16 @@ struct sx126x_hal_context_cfg_t - struct gpio_dt_spec dio3; /* DIO3 pin */ - - bool dio2_as_rf_switch; -+ -+ /* External RF-switch GPIOs (optional; absent when port == NULL). -+ * tx_enable is asserted during TX-class operations; rx_enable during RX. -+ * Both are deasserted on standby/sleep/init. -+ * These are mutually exclusive with dio2-as-rf-switch in hardware but -+ * the driver does not enforce that — user must not set both in DT. -+ */ -+ struct gpio_dt_spec tx_enable; /* TX-EN line, e.g. EBYTE E22-400M30S pin 12 */ -+ struct gpio_dt_spec rx_enable; /* RX-EN line, e.g. EBYTE E22-400M30S pin 11 */ -+ - struct sx126x_hal_context_tcxo_cfg_t tcxo_cfg; /* TCXO config, says if dio3-tcxo */ - uint8_t capa_xta; /* set to 0xFF if not configured*/ - uint8_t capa_xtb; /* set to 0xFF if not configured*/ -diff --git a/dts/bindings/usp/semtech,sx126x-new-common.yaml b/dts/bindings/usp/semtech,sx126x-new-common.yaml -index 72032bb..56a8e40 100644 ---- a/dts/bindings/usp/semtech,sx126x-new-common.yaml -+++ b/dts/bindings/usp/semtech,sx126x-new-common.yaml -@@ -128,6 +128,30 @@ properties: - required: false - enum: [0, 1, 2, 3, 4, 5, 6, 7] - description: | -- The ramp-up time for the radio PA, between 0x0 (10us) to 0x07 (3400us). -+ The ramp-up time for the radio PA, between 0x0 (10us) to 0x07 (3400us). - If not provided, the driver will use the default, recommended time (40us). - It is not recommended to modify this value. -+ -+ tx-enable-gpios: -+ type: phandle-array -+ required: false -+ description: | -+ External RF-switch TX-enable GPIO. -+ -+ When present, the driver asserts this pin active before any transmit-class -+ operation (SetTx / SetTxContinuousWave / SetTxInfinitePreamble) and -+ deasserts it on standby, sleep, and receive-class operations. Use this for -+ modules such as the EBYTE E22-400M30S (SX1262) that drive an external -+ RF switch with a dedicated TX-EN line instead of using DIO2. -+ -+ Must not be combined with dio2-as-rf-switch. -+ -+ rx-enable-gpios: -+ type: phandle-array -+ required: false -+ description: | -+ External RF-switch RX-enable GPIO. -+ -+ When present, the driver asserts this pin active before any receive-class -+ operation (SetRx / SetRxDutyCycle / SetCad) and deasserts it on standby, -+ sleep, and transmit-class operations. Pair with tx-enable-gpios. --- -2.50.1 (Apple Git-155) - diff --git a/patches/0002-fix-zephyr-4.3-remove-select-ZEPHYR_LORA_BASICS_MODE.patch b/patches/0002-fix-zephyr-4.3-remove-select-ZEPHYR_LORA_BASICS_MODE.patch deleted file mode 100644 index 57e34fdd..00000000 --- a/patches/0002-fix-zephyr-4.3-remove-select-ZEPHYR_LORA_BASICS_MODE.patch +++ /dev/null @@ -1,36 +0,0 @@ -From dcabc513f4c4d00be1370cbf986bca284eddff8d Mon Sep 17 00:00:00 2001 -From: Michael Pham <61564344+Mikefly123@users.noreply.github.com> -Date: Sat, 4 Jul 2026 14:30:01 -0700 -Subject: [PATCH 2/3] fix(zephyr-4.3): remove select - ZEPHYR_LORA_BASICS_MODEM_MODULE (internalized in 4.3) - -ZEPHYR_LORA_BASICS_MODEM_MODULE was an external-module auto-symbol in -Zephyr <=4.2. In 4.3 it became an internal Zephyr symbol and is not -exposed to external modules. Remove the select to avoid a fatal Kconfig -'direct dependencies 0' abort. - -Co-Authored-By: Claude Fable 5 ---- - drivers/usp/Kconfig | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/drivers/usp/Kconfig b/drivers/usp/Kconfig -index 5518a25..cc7940f 100644 ---- a/drivers/usp/Kconfig -+++ b/drivers/usp/Kconfig -@@ -9,7 +9,11 @@ menuconfig LORA_BASICS_MODEM_DRIVERS - bool "LoRa drivers from the new LoRa Basics Modem stack [EXPERIMENTAL]" - select POLL - select EXPERIMENTAL -- select ZEPHYR_LORA_BASICS_MODEM_MODULE -+ # PATCH(zephyr-4.3): ZEPHYR_LORA_BASICS_MODEM_MODULE was an external-module -+ # auto-symbol in Zephyr <=4.2. In 4.3 it became an internal Zephyr symbol -+ # (zephyr/modules/lora-basics-modem/Kconfig) that is NOT exposed in the -+ # auto-generated Kconfig.modules for external builds. Remove the select to -+ # avoid a fatal Kconfig "direct dependencies 0" abort. - depends on !LORA - help - Include LoRa drivers from the new LoRa Basics Modem stack in the system configuration. --- -2.50.1 (Apple Git-155) - diff --git a/patches/0003-fix-usp-main-2025-fix-LR_FHSS_SRC_PATH-for-flattened.patch b/patches/0003-fix-usp-main-2025-fix-LR_FHSS_SRC_PATH-for-flattened.patch deleted file mode 100644 index 2cb0baf3..00000000 --- a/patches/0003-fix-usp-main-2025-fix-LR_FHSS_SRC_PATH-for-flattened.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 79f38c6669106d8018755dd3b2a509eb5f1bc924 Mon Sep 17 00:00:00 2001 -From: Michael Pham <61564344+Mikefly123@users.noreply.github.com> -Date: Sat, 4 Jul 2026 14:30:08 -0700 -Subject: [PATCH 3/3] fix(usp-main-2025): fix LR_FHSS_SRC_PATH for flattened - lr_fhss_driver layout - -Upstream usp removed lr_fhss_driver/src/; lr_fhss_mac.c now lives flat -in sx126x_driver/src (same dir as LBM_SX126X_LIB_DIR). Drop the now- -invalid subdirectory suffix to fix the cmake path. - -Co-Authored-By: Claude Fable 5 ---- - modules/usp_drivers/dev_env.cmake | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/modules/usp_drivers/dev_env.cmake b/modules/usp_drivers/dev_env.cmake -index f92cafe..1e76230 100644 ---- a/modules/usp_drivers/dev_env.cmake -+++ b/modules/usp_drivers/dev_env.cmake -@@ -1,6 +1,10 @@ - # SPDX-License-Identifier: BSD-3-Clause-Clear - - if(SX126X_ENABLE_LR_FHSS) -- set(LR_FHSS_SRC_PATH "${LBM_SX126X_LIB_DIR}/lr_fhss_driver/src" -+ # PATCH(usp-main-2025): upstream usp repo removed the lr_fhss_driver/src -+ # subdirectory; lr_fhss_mac.c now lives flat in sx126x_driver/src/. -+ # Use the same directory as LBM_SX126X_LIB_DIR (already the default before -+ # dev_env.cmake was included). -+ set(LR_FHSS_SRC_PATH "${LBM_SX126X_LIB_DIR}" - CACHE PATH "Path to folder containing LR-FHSS driver" FORCE) - endif() --- -2.50.1 (Apple Git-155) - diff --git a/patches/0005-fix-usbd-cdc-acm-stuck-tx-fifo-busy-on-disable-and-retry.patch b/patches/0005-fix-usbd-cdc-acm-stuck-tx-fifo-busy-on-disable-and-retry.patch deleted file mode 100644 index 6bf8764e..00000000 --- a/patches/0005-fix-usbd-cdc-acm-stuck-tx-fifo-busy-on-disable-and-retry.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 0000000000000000000000000000000000000002 Mon Sep 17 00:00:00 2001 -From: Michael Pham -Date: Sat, 5 Jul 2026 00:00:00 -0700 -Subject: [PATCH] fix(usbd_cdc_acm): clear TX_FIFO_BUSY on disable; retry when stuck - -Two related fixes for secondary silence on USB CDC-ACM TX path: - -1. Clear CDC_ACM_TX_FIFO_BUSY in usbd_cdc_acm_disable(). - If the host stops issuing IN tokens while a transfer is in flight, - TX_FIFO_BUSY stays set indefinitely. The error completion path - (ECONNABORTED) clears it on USB disconnect/cancel, but a passive stall - where the host driver stops polling without disconnecting does not fire - any completion. Clearing on disable ensures the flag is reset on the - next enable/reconnect cycle. - -2. Self-reschedule tx_fifo_work with 10ms delay when BUSY is already set - and ring buffer is non-empty. - Provides a periodic drain retry when the USB IN transfer stalls. When - BUSY clears normally (completion fires), the retry fires once and is a - no-op (ring_buf_is_empty after drain). When BUSY is stuck, the handler - retries every 10ms without burning CPU. - -Root cause on FCB v5e (RP2350, macOS host): after the initial burst of -~34 AOS frames is delivered, the macOS USB CDC driver pauses issuing IN -tokens while the GDS Python process processes the burst. TX_FIFO_BUSY -stays set. Subsequent uart_poll_out() calls schedule tx_fifo_work but the -handler returns early on every invocation. The 10ms retry loop ensures -the IN endpoint is re-armed as soon as the host resumes polling. - -Applies on top of: - 0004-fix-usbd-cdc-acm-poll-mode-tx-drain-on-class-enable.patch - -Signed-off-by: Michael Pham ---- -diff --git a/subsys/usb/device_next/class/usbd_cdc_acm.c b/subsys/usb/device_next/class/usbd_cdc_acm.c -index a8241ad130e..704b41a5a14 100644 ---- a/subsys/usb/device_next/class/usbd_cdc_acm.c -+++ b/subsys/usb/device_next/class/usbd_cdc_acm.c -@@ -378,6 +378,10 @@ static void usbd_cdc_acm_disable(struct usbd_class_data *const c_data) - - atomic_clear_bit(&data->state, CDC_ACM_CLASS_ENABLED); - atomic_clear_bit(&data->state, CDC_ACM_CLASS_SUSPENDED); -+ /* Clear TX_FIFO_BUSY on disable so a stuck IN transfer does not block -+ * the TX path after the host reconnects and re-enables the class. -+ */ -+ atomic_clear_bit(&data->state, CDC_ACM_TX_FIFO_BUSY); - LOG_INF("Configuration disabled"); - } - -@@ -648,6 +652,13 @@ static void cdc_acm_tx_fifo_handler(struct k_work *work) - - if (atomic_test_and_set_bit(&data->state, CDC_ACM_TX_FIFO_BUSY)) { - LOG_DBG("TX transfer already in progress"); -+ /* Reschedule if data is waiting - guards against a stuck IN transfer -+ * where the host stops issuing IN tokens (e.g. macOS flow-control). -+ * The retry is a no-op once the completion fires and clears BUSY. -+ */ -+ if (!ring_buf_is_empty(data->tx_fifo.rb)) { -+ cdc_acm_work_schedule(&data->tx_fifo_work, K_MSEC(10)); -+ } - return; - } - --- -2.39.3 (Apple Git-146) diff --git a/patches/0006-fix-sx126x-wakeup-busy-race-add-t_woff-settle-delay.patch b/patches/0006-fix-sx126x-wakeup-busy-race-add-t_woff-settle-delay.patch deleted file mode 100644 index ce56db0c..00000000 --- a/patches/0006-fix-sx126x-wakeup-busy-race-add-t_woff-settle-delay.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000006 Mon Sep 17 00:00:00 2001 -From: Michael Pham -Date: Fri, 10 Jul 2026 00:00:00 -0700 -Subject: [PATCH] fix(sx126x_hal): add t_woff settle delay after wake-up NSS - glitch to close BUSY-poll race - -sx126x_hal_check_device_ready() wakes a sleeping SX126x with a glitch on -NSS and then immediately polls BUSY via sx126x_hal_wait_on_busy(). Per -the datasheet, the chip needs up to ~340us (t_woff, warm start) after -the wake-up NSS edge before it reliably asserts BUSY. Polling right away -can sample BUSY before the chip has driven it, so the caller believes -the radio is ready when it is still starting up; the very next SPI -command (frequently SET_FREQ) is then clocked into a device that isn't -listening yet and is silently dropped. This reproduces ~40% of the time -in release builds where the post-wake instruction path is fast enough -to win the race. - -Fix: insert a k_busy_wait(500) between the wake-up NSS toggle and the -BUSY poll to wait out the chip's startup window before trusting BUSY. - -Same root cause and fix as the loramac_node SX126xWakeup() path fixed -for the ground-radio-controller GRC firmware -(patches/zephyr-sx126x-wakeup-busy-delay.patch there); this patch is -the USP HAL (Semtech RAC-managed) equivalent for the flight stack. - -Preserves the existing external RF-switch GPIO patch (0001) in this -same file — this change only adds the delay inside -sx126x_hal_check_device_ready() and does not touch -sx126x_hal_update_rf_switch() or sx126x_hal_write(). - -Co-Authored-By: Claude Sonnet 5 ---- - drivers/usp/sx126x/sx126x_hal.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/drivers/usp/sx126x/sx126x_hal.c b/drivers/usp/sx126x/sx126x_hal.c -index 1530077..699d53b 100644 ---- a/drivers/usp/sx126x/sx126x_hal.c -+++ b/drivers/usp/sx126x/sx126x_hal.c -@@ -101,6 +101,15 @@ static void sx126x_hal_check_device_ready( const void* context ) - gpio_pin_set_dt( cs, 1 ); - k_usleep( 100 ); - gpio_pin_set_dt( cs, 0 ); -+ -+ /* The chip takes up to ~340us (datasheet t_woff, warm start) after -+ * the wake-up NSS edge before it is ready. Polling BUSY immediately -+ * can sample it before the chip has asserted it, in which case the -+ * next command is clocked into a device still starting up and is -+ * silently ignored. Wait out the startup window before polling. -+ */ -+ k_busy_wait( 500 ); -+ - sx126x_hal_wait_on_busy( context ); - data->radio_status = RADIO_AWAKE; - } --- -2.50.1 (Apple Git-155) - diff --git a/patches/0007-fix-usbd-cdc-acm-bound-poll-out-backpressure-wait.patch b/patches/0007-fix-usbd-cdc-acm-bound-poll-out-backpressure-wait.patch deleted file mode 100644 index 00137ffa..00000000 --- a/patches/0007-fix-usbd-cdc-acm-bound-poll-out-backpressure-wait.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: bench -Subject: [PATCH] fix(usbd-cdc-acm): bound poll_out sleep-retry to ~20ms, discard on sustained backpressure - -An attached-but-stalled host session (macOS ceases IN polling) makes the -unbounded 1ms sleep-retry loop take the full stall duration (minutes) per -console byte. Any logging thread then cascades into a com-stack livelock -(HWIL 2026-07-10). Bound the wait and fall back to the detached-case -discard behavior. ---- ---- a/subsys/usb/device_next/class/usbd_cdc_acm.c -+++ b/subsys/usb/device_next/class/usbd_cdc_acm.c -@@ -1007,6 +1007,7 @@ - struct cdc_acm_uart_data *const data = dev->data; - k_spinlock_key_t key; - uint32_t wrote; -+ int retries = 20; - - while (true) { - key = k_spin_lock(&data->lock); -@@ -1017,7 +1018,15 @@ - break; - } - -- if (k_is_in_isr() || !data->flow_ctrl) { -+ /* Bounded wait: with an attached-but-stalled host session (macOS -+ * ceases IN polling for minutes at a time), an unbounded sleep-retry -+ * here makes every console write take the full stall duration. Any -+ * thread that logs (event text loggers, assert reporting) then backs -+ * up its own queues and cascades into a system-wide com livelock. -+ * After ~20 ms of backpressure, treat the console as best-effort and -+ * discard, exactly like the detached (!flow_ctrl) case below. -+ */ -+ if (k_is_in_isr() || !data->flow_ctrl || retries-- <= 0) { - LOG_WRN_ONCE("Ring buffer full, discard data"); - break; - } diff --git a/patches/0008-fix-smtc-modem-hal-implement-rac-api-mutex.patch b/patches/0008-fix-smtc-modem-hal-implement-rac-api-mutex.patch deleted file mode 100644 index 04d66e5e..00000000 --- a/patches/0008-fix-smtc-modem-hal-implement-rac-api-mutex.patch +++ /dev/null @@ -1,39 +0,0 @@ -diff --git a/modules/smtc_modem_hal/smtc_modem_hal.c b/modules/smtc_modem_hal/smtc_modem_hal.c -index a08e7b9..a46c474 100644 ---- a/modules/smtc_modem_hal/smtc_modem_hal.c -+++ b/modules/smtc_modem_hal/smtc_modem_hal.c -@@ -176,14 +176,32 @@ struct k_sem* smtc_modem_hal_get_event_sem( void ) - return &lbm_main_loop_sem; - } - -+/* RAC API serialization (HWIL 2026-07-11): the RAC wraps every public entry -+ * point (engine pass included) in protect/unprotect and relies on it for -+ * mutual exclusion between the USP engine thread and API callers on other -+ * threads. The bare-metal stub provided none: a concurrent -+ * rp_task_enqueue()/abort against a running engine tears the radio planner's -+ * task structs (observed live on RP2350: RP_FAILSAFE panic on a -+ * LOCK_RADIO_ACCESS task whose type field read non-LOCK, and a TX launch -+ * taken through the LR-FHSS branch while on a LoRa profile). k_mutex allows -+ * recursive locking by the owner, which the RAC requires: post-transaction -+ * callbacks run inside the engine pass and may call -+ * smtc_rac_unlock_radio_access(), which re-enters protect. The radio/timer -+ * IRQ callbacks only set flags and never call protect, so ISR context is -+ * excluded by design; assert if a caller violates this. -+ */ -+K_MUTEX_DEFINE( prv_rac_api_mutex ); -+ - void smtc_modem_hal_protect_api_call( void ) - { -- // Do nothing in case implementation is bare metal -+ __ASSERT( !k_is_in_isr( ), "smtc_modem_hal_protect_api_call from ISR" ); -+ ( void ) k_mutex_lock( &prv_rac_api_mutex, K_FOREVER ); - } - - void smtc_modem_hal_unprotect_api_call( void ) - { -- // Do nothing in case implementation is bare metal -+ __ASSERT( !k_is_in_isr( ), "smtc_modem_hal_unprotect_api_call from ISR" ); -+ ( void ) k_mutex_unlock( &prv_rac_api_mutex ); - } - - /* ------------ Timer management ------------ */ diff --git a/patches/0009-fix-radio-planner-failsafe-exempt-unlock-radio-access.patch b/patches/0009-fix-radio-planner-failsafe-exempt-unlock-radio-access.patch deleted file mode 100644 index cc985ff2..00000000 --- a/patches/0009-fix-radio-planner-failsafe-exempt-unlock-radio-access.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff --git a/smtc_rac_lib/radio_planner/src/radio_planner.c b/smtc_rac_lib/radio_planner/src/radio_planner.c -index 2c44c68..a4c99d6 100644 ---- a/smtc_rac_lib/radio_planner/src/radio_planner.c -+++ b/smtc_rac_lib/radio_planner/src/radio_planner.c -@@ -444,8 +444,15 @@ rp_stats_t rp_get_stats( const radio_planner_t* rp ) - - void rp_callback( radio_planner_t* rp ) - { -+ // UNLOCK_RADIO_ACCESS must be exempt like LOCK_RADIO_ACCESS: a lock task -+ // held open longer than the failsafe window (e.g. continuous RX under the -+ // raw RAC) keeps its original start_time_ms, and unlock_radio_access -+ // retypes the still-RUNNING task to UNLOCK before the engine processes -+ // it — the very next rp_callback would evaluate the failsafe against the -+ // stale start time and panic at the moment the client releases the lock. - if( ( rp->tasks[rp->radio_task_id].state == RP_TASK_STATE_RUNNING ) && - ( rp->tasks[rp->radio_task_id].type != RP_TASK_TYPE_LOCK_RADIO_ACCESS ) && -+ ( rp->tasks[rp->radio_task_id].type != RP_TASK_TYPE_UNLOCK_RADIO_ACCESS ) && - ( rp->disable_failsafe != RP_DISABLE_FAILSAFE_KEY ) && - ( ( int32_t ) ( rp->tasks[rp->radio_task_id].start_time_ms + 128000 - smtc_modem_hal_get_time_in_ms( ) ) < 0 ) ) - { diff --git a/patches/0010-fix-boards-xiao-nrf54l15-full_name-zephyr-4.4-schema.patch b/patches/0010-fix-boards-xiao-nrf54l15-full_name-zephyr-4.4-schema.patch deleted file mode 100644 index 5b69c3c0..00000000 --- a/patches/0010-fix-boards-xiao-nrf54l15-full_name-zephyr-4.4-schema.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000010 Mon Sep 17 00:00:00 2001 -From: Michael Pham -Date: Tue, 21 Jul 2026 00:00:00 -0700 -Subject: [PATCH] fix(boards): add full_name to xiao_nrf54l15 board.yml for Zephyr 4.4 schema - -Zephyr 4.4 board-schema.yaml requires name+full_name (or extend). The -vendored xiao_nrf54l15 board.yml predates this; matches the in-tree -Zephyr 4.4.1 board metadata. - -Signed-off-by: Michael Pham ---- -diff --git a/boards/seeed/xiao_nrf54l15/board.yml b/boards/seeed/xiao_nrf54l15/board.yml -index 9ffc64f..8641807 100644 ---- a/boards/seeed/xiao_nrf54l15/board.yml -+++ b/boards/seeed/xiao_nrf54l15/board.yml -@@ -1,5 +1,6 @@ - board: - name: xiao_nrf54l15 -+ full_name: XIAO NRF54L15 - vendor: seeed - socs: - - name: nrf54l15 --- -2.39.3 (Apple Git-146) diff --git a/patches/README.md b/patches/README.md index 93921c87..fd774704 100644 --- a/patches/README.md +++ b/patches/README.md @@ -1,37 +1,28 @@ # Patches Directory -This directory contains patches that are automatically applied to git submodules during the build process. - -## fprime-gds-version.patch - -This patch updates the `fprime-gds` version requirement in `lib/fprime/requirements.txt` from 4.1.0 to 4.1.1a2. - -**Why:** The project requires fprime-gds 4.1.1a2 for specific features: -- file-uplink-cooldown argument -- file-uplink-chunk-size argument - -The patch is automatically applied by the `make submodules` target to ensure version consistency and eliminate the version mismatch warning. - -**Application:** This patch is applied automatically when running `make submodules` (or `make` which includes that target). - -**Note:** After applying this patch, `git status` will show `lib/fprime` as modified. This is expected and should **not** be committed. The patched state is reapplied automatically on each `make submodules` run. - -## fprime-com-aggregator-bounded-timeout.patch - -Fixes issue #432: `Svc::ComAggregator`'s 10 Hz timeout signal FW_ASSERTs (queue FULL) whenever the component's dispatch thread stalls for longer than `queue_depth / timeout_rate` (~1.5 s at depth 15 / 10 Hz). - -Upstream's `m_allow_timeout` guard (fprime #4402) only suppresses timeout signals in the WAIT_STATUS state. While the state machine sits in FILL, a stalled dispatch thread (downstream backpressure, thread starvation from CDC-ACM host stalls) still lets rate-group ticks fill the queue and trip the autocoded assert in `aggregationMachine_sendSignalFinish`. - -The patch bounds timeout-signal queue occupancy in the hand-coded `timeout_handler`: the signal is only enqueued when the queue retains headroom for it plus the (flow-controlled, at most one each) in-flight `fill` and `status` signals. Timeout ticks are periodic and idempotent, so a skipped tick is retried on the next cycle — behavior is unchanged except that the queue can no longer overflow. - -**Application:** Applied automatically by `make submodules`, same mechanism as the fprime-gds version patch. Candidate for upstreaming to nasa/fprime. - -## fprime-sched-tick-drop.patch - -Second instance of the issue-#432 defect class, captured by gdb tripwire during HWIL soak #5 (2026-07-10): `safeModeSeq` (Svc::CmdSequencer) hit the identical queue-full FW_ASSERT in its autocoded `schedIn_handlerBase` — rate-group sched ticks accumulate in any active component's queue whenever its dispatch thread stalls longer than `queue_depth / tick_rate`. - -The patch adds the `drop` queue-full annotation to the periodic `Svc.Sched` async inputs of all eight upstream Svc components that lacked it (CmdSequencer, CmdDispatcher, TlmChan, TlmPacketizer, FileDownlink, BufferLogger, DpManager, DpWriter). Dropping a periodic tick is safe by construction — the next tick retries — and upstream already uses `drop` for exactly this on `ComQueue.run` and `ActiveRateGroup.CycleIn`. - -A third capture (same soak: `Svc::Health` 1 Hz ping → `rateGroup50Hz.PingIn_handlerBase`, identical queue-full assert) showed pings are another unbounded periodic producer, so the patch also adds `drop` to the 14 async `PingIn`/`pingIn` ports in Svc (including `ActiveRateGroup` and `FpySequencer`, which was explicitly `assert`). Dropping a ping is the *designed* failure path: Health's ping-timeout policy exists precisely to catch a component that stops responding — an assert on the ping enqueue kills the board through the very mechanism meant to detect stuck components gracefully. - -**Application:** Applied automatically by `make submodules`. Candidate for upstreaming to nasa/fprime. +This directory once carried a stack of module patches (usp_zephyr, usp, zephyr, +fprime) applied at build time. As of 2026-07-26 all of those fixes have been +migrated to the `Open-Source-Space-Foundation` fork integration branches +(`feat/proves-usp-radio`), which are pinned directly in `west.yml` and +`.gitmodules`. The former patch-apply Makefile targets (`usp-patches`, +`usp-core-patches`, `zephyr-patches`, and the fprime steps in `submodules`) +were removed with them. + +Where the removed patches live now (integration PRs, each linking its +constituent PRs): + +| Former patch | Module | Integration PR | +|---|---|---| +| 0001 RF-switch GPIO, 0002 Zephyr-4.3 Kconfig, 0003 LR_FHSS path, 0006 wakeup settle, 0008 RAC mutex, 0010 board.yml schema | usp_zephyr | Open-Source-Space-Foundation/usp_zephyr#7 | +| 0009 radio-planner failsafe unlock exemption | usp | Open-Source-Space-Foundation/usp#3 | +| 0005 + 0007 CDC-ACM TX fixes | zephyr | Open-Source-Space-Foundation/zephyr#3 | +| fprime-com-aggregator-bounded-timeout, fprime-sched-tick-drop | fprime | Open-Source-Space-Foundation/fprime#5 | + +## fprime-yamcs-noapp-path.patch (the one remaining patch) + +Patches the *pip-installed* `fprime-yamcs` package (not a git submodule), so it +cannot move to a fork pin and remains a carried patch. It fixes the `--no-app` +path handling in `fprime_yamcs/__main__.py`. + +**Application:** applied automatically by `make fprime-venv` (and therefore by +`make`), alongside the scripted fprime-yamcs fixes in `tools/`. diff --git a/patches/fprime-com-aggregator-bounded-timeout.patch b/patches/fprime-com-aggregator-bounded-timeout.patch deleted file mode 100644 index 4215db86..00000000 --- a/patches/fprime-com-aggregator-bounded-timeout.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff --git a/Svc/ComAggregator/ComAggregator.cpp b/Svc/ComAggregator/ComAggregator.cpp -index dc6dd130d..6cfeecd6c 100644 ---- a/Svc/ComAggregator/ComAggregator.cpp -+++ b/Svc/ComAggregator/ComAggregator.cpp -@@ -8,6 +8,12 @@ - - namespace Svc { - -+namespace { -+//! Queue slots that must remain free for a timeout signal to be enqueued: the timeout itself plus one -+//! in-flight 'fill' and one in-flight 'status' signal (each bounded to one message by the com protocol). -+constexpr FwSizeType TIMEOUT_QUEUE_HEADROOM = 3; -+} // namespace -+ - // ---------------------------------------------------------------------- - // Component construction and destruction - // ---------------------------------------------------------------------- -@@ -55,7 +61,16 @@ void ComAggregator ::timeout_handler(FwIndexType portNum, U32 context) { - // - // Behaviorally, this solution will work exactly like the naive implementation with an infinite queue depth, but - // prevents queue overflow when using finite queues. -- if (this->m_allow_timeout) { -+ // -+ // Even so, timeout remains the only signal source without flow control: 'fill' and 'status' are each bounded -+ // to one in-flight message by the com protocol, but the rate group keeps delivering ticks while this -+ // component's dispatch thread is stalled (downstream backpressure, thread starvation). In the FILL state -+ // (m_allow_timeout true) such a stall would still fill the queue with timeout signals and trip the queue-full -+ // assertion in the autocoded signal send. Ticks are periodic and idempotent, so additionally skip the signal -+ // unless the queue has headroom for it plus the in-flight flow-controlled signals; a skipped tick is simply -+ // retried on the next cycle. -+ if (this->m_allow_timeout && -+ (this->m_queue.getMessagesAvailable() + TIMEOUT_QUEUE_HEADROOM <= this->m_queue.getDepth())) { - this->aggregationMachine_sendSignal_timeout(); - } - } diff --git a/patches/fprime-sched-tick-drop.patch b/patches/fprime-sched-tick-drop.patch deleted file mode 100644 index 587de513..00000000 --- a/patches/fprime-sched-tick-drop.patch +++ /dev/null @@ -1,250 +0,0 @@ -diff --git a/Svc/ActiveRateGroup/ActiveRateGroup.fpp b/Svc/ActiveRateGroup/ActiveRateGroup.fpp -index 3ee1488e3..c60ad6d0d 100644 ---- a/Svc/ActiveRateGroup/ActiveRateGroup.fpp -+++ b/Svc/ActiveRateGroup/ActiveRateGroup.fpp -@@ -15,7 +15,7 @@ module Svc { - output port RateGroupMemberOut: [ActiveRateGroupOutputPorts] Sched - - @ Ping input port for health -- async input port PingIn: Ping -+ async input port PingIn: Ping drop - - @ Ping output port for health - output port PingOut: Ping -diff --git a/Svc/BufferLogger/BufferLogger.fpp b/Svc/BufferLogger/BufferLogger.fpp -index 6da2ffd69..e045b1856 100644 ---- a/Svc/BufferLogger/BufferLogger.fpp -+++ b/Svc/BufferLogger/BufferLogger.fpp -@@ -16,12 +16,12 @@ module Svc { - async input port comIn: Fw.Com - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping output port - output port pingOut: Svc.Ping - -- async input port schedIn: Svc.Sched -+ async input port schedIn: Svc.Sched drop - - # ---------------------------------------------------------------------- - # Special ports -diff --git a/Svc/CmdDispatcher/CmdDispatcher.fpp b/Svc/CmdDispatcher/CmdDispatcher.fpp -index 66343b886..2f7732896 100644 ---- a/Svc/CmdDispatcher/CmdDispatcher.fpp -+++ b/Svc/CmdDispatcher/CmdDispatcher.fpp -@@ -24,10 +24,10 @@ module Svc { - async input port seqCmdBuff: [CmdDispatcherSequencePorts] Fw.Com hook - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Run port used to emit telemetry -- async input port run: Svc.Sched -+ async input port run: Svc.Sched drop - - @ Ping output port - output port pingOut: Svc.Ping -diff --git a/Svc/CmdSequencer/CmdSequencer.fpp b/Svc/CmdSequencer/CmdSequencer.fpp -index f1c401278..ebc381653 100644 ---- a/Svc/CmdSequencer/CmdSequencer.fpp -+++ b/Svc/CmdSequencer/CmdSequencer.fpp -@@ -68,7 +68,7 @@ module Svc { - async input port cmdResponseIn: Fw.CmdResponse - - @ Ping in port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping out port - output port pingOut: Svc.Ping -@@ -86,7 +86,7 @@ module Svc { - output port comCmdOut: Fw.Com - - @ Schedule in port -- async input port schedIn: Svc.Sched -+ async input port schedIn: Svc.Sched drop - - @ Notifies that a sequence has started running - output port seqStartOut: Svc.CmdSeqIn -diff --git a/Svc/ComLogger/ComLogger.fpp b/Svc/ComLogger/ComLogger.fpp -index c4327b7dd..cf4bc2238 100644 ---- a/Svc/ComLogger/ComLogger.fpp -+++ b/Svc/ComLogger/ComLogger.fpp -@@ -11,7 +11,7 @@ module Svc { - async input port comIn: Fw.Com - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping output port - output port pingOut: Svc.Ping -diff --git a/Svc/DpCatalog/DpCatalog.fpp b/Svc/DpCatalog/DpCatalog.fpp -index e1fd468dd..59ffc363f 100644 ---- a/Svc/DpCatalog/DpCatalog.fpp -+++ b/Svc/DpCatalog/DpCatalog.fpp -@@ -32,7 +32,7 @@ module Svc { - # Component specific ports - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping output port - output port pingOut: Svc.Ping -diff --git a/Svc/DpManager/DpManager.fpp b/Svc/DpManager/DpManager.fpp -index ebbf5a46f..74574f97f 100644 ---- a/Svc/DpManager/DpManager.fpp -+++ b/Svc/DpManager/DpManager.fpp -@@ -8,7 +8,7 @@ module Svc { - # ---------------------------------------------------------------------- - - @ Schedule in port -- async input port schedIn: Svc.Sched -+ async input port schedIn: Svc.Sched drop - - # ---------------------------------------------------------------------- - # Ports for handling buffer requests -diff --git a/Svc/DpWriter/DpWriter.fpp b/Svc/DpWriter/DpWriter.fpp -index f24594f09..152be91ba 100644 ---- a/Svc/DpWriter/DpWriter.fpp -+++ b/Svc/DpWriter/DpWriter.fpp -@@ -8,7 +8,7 @@ module Svc { - # ---------------------------------------------------------------------- - - @ Schedule in port -- async input port schedIn: Svc.Sched -+ async input port schedIn: Svc.Sched drop - - # ---------------------------------------------------------------------- - # Ports for handling data products -diff --git a/Svc/EventManager/EventManager.fpp b/Svc/EventManager/EventManager.fpp -index b97a8d807..2ea88960a 100644 ---- a/Svc/EventManager/EventManager.fpp -+++ b/Svc/EventManager/EventManager.fpp -@@ -53,7 +53,7 @@ module Svc { - output port FatalAnnounce: Svc.FatalEvent - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping output port - output port pingOut: Svc.Ping -diff --git a/Svc/FileDownlink/FileDownlink.fpp b/Svc/FileDownlink/FileDownlink.fpp -index eed9376aa..5e710a3f4 100644 ---- a/Svc/FileDownlink/FileDownlink.fpp -+++ b/Svc/FileDownlink/FileDownlink.fpp -@@ -8,7 +8,7 @@ module Svc { - # ---------------------------------------------------------------------- - - @ Run input port -- async input port Run: Svc.Sched -+ async input port Run: Svc.Sched drop - - @ Mutexed Sendfile input port - guarded input port SendFile: Svc.SendFileRequest -@@ -23,7 +23,7 @@ module Svc { - output port bufferSendOut: Fw.BufferSend - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping output port - output port pingOut: Svc.Ping -diff --git a/Svc/FileManager/FileManager.fpp b/Svc/FileManager/FileManager.fpp -index bef777c71..d85f42002 100644 ---- a/Svc/FileManager/FileManager.fpp -+++ b/Svc/FileManager/FileManager.fpp -@@ -8,7 +8,7 @@ module Svc { - # ---------------------------------------------------------------------- - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Scheduler input port for rate group operations - sync input port schedIn: Sched -diff --git a/Svc/FileUplink/FileUplink.fpp b/Svc/FileUplink/FileUplink.fpp -index 90ef4e9a8..b2b67bd5c 100644 ---- a/Svc/FileUplink/FileUplink.fpp -+++ b/Svc/FileUplink/FileUplink.fpp -@@ -14,7 +14,7 @@ module Svc { - output port bufferSendOut: Fw.BufferSend - - @ Ping in -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping out - output port pingOut: Svc.Ping -diff --git a/Svc/FpySequencer/FpySequencer.fpp b/Svc/FpySequencer/FpySequencer.fpp -index 8af40d3d7..b9e80e1af 100644 ---- a/Svc/FpySequencer/FpySequencer.fpp -+++ b/Svc/FpySequencer/FpySequencer.fpp -@@ -38,7 +38,7 @@ module Svc { - - @ Ping in port - # TODO should ping have highest prio? or lowest? -- async input port pingIn: Svc.Ping priority 10 assert -+ async input port pingIn: Svc.Ping priority 10 drop - - @ port to trigger a wakeup or timeout check. increase frequency - @ to increase temporal resolution of sequencer -diff --git a/Svc/PrmDb/PrmDb.fpp b/Svc/PrmDb/PrmDb.fpp -index bca4f172f..b2a4b95b1 100644 ---- a/Svc/PrmDb/PrmDb.fpp -+++ b/Svc/PrmDb/PrmDb.fpp -@@ -69,7 +69,7 @@ module Svc { - async input port setPrm: Fw.PrmSet - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping output port - output port pingOut: Svc.Ping -diff --git a/Svc/TlmChan/TlmChan.fpp b/Svc/TlmChan/TlmChan.fpp -index d15072ed0..52b73b2d8 100644 ---- a/Svc/TlmChan/TlmChan.fpp -+++ b/Svc/TlmChan/TlmChan.fpp -@@ -10,13 +10,13 @@ module Svc { - guarded input port TlmGet: Fw.TlmGet - - @ Run port for starting packet send cycle -- async input port Run: Svc.Sched -+ async input port Run: Svc.Sched drop - - @ Packet send port - output port PktSend: Fw.Com - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping output port - output port pingOut: Svc.Ping -diff --git a/Svc/TlmPacketizer/TlmPacketizer.fpp b/Svc/TlmPacketizer/TlmPacketizer.fpp -index 1655c3e2e..4125fdac9 100644 ---- a/Svc/TlmPacketizer/TlmPacketizer.fpp -+++ b/Svc/TlmPacketizer/TlmPacketizer.fpp -@@ -28,13 +28,13 @@ module Svc { - async input port controlIn: EnableSection - - @ Ping input port -- async input port pingIn: Svc.Ping -+ async input port pingIn: Svc.Ping drop - - @ Ping output port - output port pingOut: Svc.Ping - - @ Run port for starting packet send cycle -- async input port Run: Svc.Sched -+ async input port Run: Svc.Sched drop - - @ Input configuration port - async input port configureSectionGroupRate: ConfigureGroupRate diff --git a/west.yml b/west.yml index 412cfb85..3eb4c708 100644 --- a/west.yml +++ b/west.yml @@ -14,10 +14,12 @@ manifest: group-filter: [-babblesim, -optional] projects: - # Zephyr RTOS core + # Zephyr RTOS core — Open-Source-Space-Foundation fork, integration branch + # feat/proves-usp-radio (v4.4.1 + CDC-ACM fixes, formerly patches/0005+0007; + # constituent PRs tracked in OSSF/zephyr#3). - name: zephyr - repo-path: zephyr - revision: v4.4.1 + url: https://github.com/Open-Source-Space-Foundation/zephyr + revision: 3838a2802c916accdfa671de77633ee45b69441c path: lib/zephyr-workspace/zephyr west-commands: scripts/west-commands.yml import: @@ -89,19 +91,21 @@ manifest: path: lib/zephyr-workspace/modules/fatfs # USP radio stack (Semtech Unified Software Platform) — v5e+ boards only. - # usp_zephyr upstream is pinned at the commit immediately below our local - # RF-switch patch (commit a23856a in spikes/usp_zephyr). Two Zephyr-4.3 - # compat fixes are carried as patches (see patches/usp_zephyr-*.patch). + # Open-Source-Space-Foundation fork, integration branch feat/proves-usp-radio + # (RF-switch GPIO, Zephyr 4.3/4.4 compat, wakeup settle, RAC mutex — formerly + # patches/0001-0003,0006,0008,0010; constituent PRs tracked in OSSF/usp_zephyr#7). - name: usp_zephyr - url: https://github.com/Lora-net/usp_zephyr - revision: bfacd435f53935ebea1a0e95fb877f4ede119985 + url: https://github.com/Open-Source-Space-Foundation/usp_zephyr + revision: 0bf3e208124d43c55fcb7f91bae6a9ac9812ee71 path: lib/zephyr-workspace/modules/lib/usp_zephyr # USP core library (LBM + RAL) — pulled by usp_zephyr at runtime. # Path mirrors the usp_zephyr west.yml convention (modules/lib/usp). + # OSSF fork, integration branch feat/proves-usp-radio (radio-planner failsafe + # unlock exemption, formerly patches/0009; tracked in OSSF/usp#3). - name: usp - url: https://github.com/Lora-net/usp - revision: 351b2015350670eb4dfa3aec35eb04433e062654 + url: https://github.com/Open-Source-Space-Foundation/usp + revision: 8a60e4a16092f1bfa030b18494da267d8ca6a3ba path: lib/zephyr-workspace/modules/lib/usp self: From 1a805db1213dcc882187b8a3bfefdbc3de07de97 Mon Sep 17 00:00:00 2001 From: Michael Pham <61564344+Mikefly123@users.noreply.github.com> Date: Sun, 26 Jul 2026 14:02:23 -0700 Subject: [PATCH 2/2] chore: bump fprime-zephyr to c81485f (LinkProfiles UT updated for P5 table v2) The P5_GMSK_83K addition bumped LINK_PROFILE_COUNT/TABLE_VERSION but its host UT still asserted the v1 values, failing the unit-test job. UT fixed on the constituent P5 branch (fprime-zephyr PR #20, commit c874734) and merged into the integration branch (PR #22); this bumps the submodule pin to that head. make test-unit: 11/11 pass locally. Co-Authored-By: Claude Fable 5 --- lib/fprime-zephyr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fprime-zephyr b/lib/fprime-zephyr index 4b8652e1..c81485ff 160000 --- a/lib/fprime-zephyr +++ b/lib/fprime-zephyr @@ -1 +1 @@ -Subproject commit 4b8652e15849d21a3655943d30eda65c2dc886c0 +Subproject commit c81485ff8c73a76772ae85f3b388a2d57d0ec9fc