diff --git a/PROVESFlightControllerReference/Components/ComDelay/ComDelay.cpp b/PROVESFlightControllerReference/Components/ComDelay/ComDelay.cpp index 687aac929..30244cb3f 100644 --- a/PROVESFlightControllerReference/Components/ComDelay/ComDelay.cpp +++ b/PROVESFlightControllerReference/Components/ComDelay/ComDelay.cpp @@ -38,9 +38,38 @@ void ComDelay ::parameterUpdated(FwPrmIdType id) { // Handler implementations for typed input ports // ---------------------------------------------------------------------- +// Image-currency marker: grep-able via `strings zephyr.elf` to verify the flashed +// binary actually contains the divider-0 passthrough change (never trust "Verified OK"). +static volatile const char COMDELAY_DIV0_PASSTHROUGH_MARKER[] = "comdelay-div0-passthrough-20260723"; + void ComDelay ::comStatusIn_handler(FwIndexType portNum, Fw::Success& condition) { - this->m_last_status = condition; - this->m_last_status_valid = true; + // Read the divider; on invalid/uninit fall back to the default (matches run_handler). + Fw::ParamValid is_valid; + U16 current_divisor = this->paramGet_DIVIDER(is_valid); + if ((is_valid == Fw::ParamValid::INVALID) || (is_valid == Fw::ParamValid::UNINIT)) { + current_divisor = Components::DEFAULT_DIVIDER; + } + + if (current_divisor == 0) { + // DIVIDER == 0 means "no delay": forward the status immediately instead of + // latching it for the next rate tick. This removes the rate-group quantization + // (one status per tick) so downlink is paced purely by radio TX-done. + // + // Threading note: ComDelay is passive, so this executes on the CALLER's thread + // (the radio-side comStatus source). That is safe because comStatusOut feeds an + // async input (ComQueue), which only enqueues a message here. + // + // Coherence with run_handler: in passthrough mode we never set + // m_last_status_valid, so this status cannot ALSO be emitted by run_handler + // (no duplication). A status latched earlier under DIVIDER > 0 is still + // consumed by run_handler's compare_exchange as before (no loss) if the + // divider is changed to 0 at runtime. + static_cast(COMDELAY_DIV0_PASSTHROUGH_MARKER[0]); // volatile read keeps the marker in the image + this->comStatusOut_out(0, condition); + } else { + this->m_last_status = condition; + this->m_last_status_valid = true; + } } void ComDelay ::run_handler(FwIndexType portNum, U32 context) {