Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions FprimeZephyrReference/Components/ResetManager/ResetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ void ResetManager ::WARM_RESET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);
}

void ResetManager ::RESET_RADIO_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) {
this->handleRadioReset();
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK);
}

// ----------------------------------------------------------------------
// Private helper methods
// ----------------------------------------------------------------------
Expand All @@ -66,4 +71,18 @@ void ResetManager ::handleWarmReset() {
sys_reboot(SYS_REBOOT_WARM);
}

void ResetManager ::handleRadioReset() {
// Log the radio reset event
this->log_ACTIVITY_HI_INITIATE_RADIO_RESET();

// Pull radio reset line LOW (active low) to reset the radio
this->radioResetOut_out(0, Fw::Logic::LOW);

// Hold reset for a short time (implementation could add a delay if needed)
// For now, we'll just pulse it low then high

// Release reset line (set back to HIGH)
this->radioResetOut_out(0, Fw::Logic::HIGH);
}

} // namespace Components
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,27 @@ module Components {
@ Command to initiate a warm reset
sync command WARM_RESET()

@ Command to reset the radio module
sync command RESET_RADIO()

@ Event indicating that a cold reset has been initiated
event INITIATE_COLD_RESET() severity activity high id 0 format "Initiating cold reset"

@ Event indicating that a warm reset has been initiated
event INITIATE_WARM_RESET() severity activity high id 1 format "Initiating warm reset"

@ Event indicating that a radio reset has been initiated
event INITIATE_RADIO_RESET() severity activity high id 2 format "Initiating radio reset"

@ Port to invoke a cold reset
sync input port coldReset: Fw.Signal

@ Port to invoke a warm reset
sync input port warmReset: Fw.Signal

@ Port to control radio reset GPIO
output port radioResetOut: Drv.GpioWrite

###############################################################################
# Standard AC Ports: Required for Channels, Events, Commands, and Parameters #
###############################################################################
Expand Down
10 changes: 10 additions & 0 deletions FprimeZephyrReference/Components/ResetManager/ResetManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ class ResetManager final : public ResetManagerComponentBase {
U32 cmdSeq //!< The command sequence number
) override;

//! Handler implementation for command RESET_RADIO
//!
//! Command to reset the radio module
void RESET_RADIO_cmdHandler(FwOpcodeType opCode, //!< The opcode
U32 cmdSeq //!< The command sequence number
) override;

private:
// ----------------------------------------------------------------------
// Private helper methods
Expand All @@ -70,6 +77,9 @@ class ResetManager final : public ResetManagerComponentBase {

//! Handler for warm reset
void handleWarmReset();

//! Handler for radio reset
void handleRadioReset();
};

} // namespace Components
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
static const struct gpio_dt_spec ledGpio = GPIO_DT_SPEC_GET(DT_NODELABEL(led0), gpios);
static const struct gpio_dt_spec burnwire0Gpio = GPIO_DT_SPEC_GET(DT_NODELABEL(burnwire0), gpios);
static const struct gpio_dt_spec burnwire1Gpio = GPIO_DT_SPEC_GET(DT_NODELABEL(burnwire1), gpios);
static const struct gpio_dt_spec radioResetGpio = GPIO_DT_SPEC_GET(DT_NODELABEL(radio_reset), gpios);
static const struct gpio_dt_spec face0LoadSwitchGpio = GPIO_DT_SPEC_GET(DT_NODELABEL(face0_enable), gpios);
static const struct gpio_dt_spec face1LoadSwitchGpio = GPIO_DT_SPEC_GET(DT_NODELABEL(face1_enable), gpios);
static const struct gpio_dt_spec face2LoadSwitchGpio = GPIO_DT_SPEC_GET(DT_NODELABEL(face2_enable), gpios);
Expand Down Expand Up @@ -69,6 +70,7 @@ void configureTopology() {
gpioWatchdog.open(ledGpio, Zephyr::ZephyrGpioDriver::GpioConfiguration::OUT);
gpioBurnwire0.open(burnwire0Gpio, Zephyr::ZephyrGpioDriver::GpioConfiguration::OUT);
gpioBurnwire1.open(burnwire1Gpio, Zephyr::ZephyrGpioDriver::GpioConfiguration::OUT);
gpioRadioReset.open(radioResetGpio, Zephyr::ZephyrGpioDriver::GpioConfiguration::OUT);

cmdSeq.allocateBuffer(0, mallocator, 5 * 1024);
gpioface4LS.open(face4LoadSwitchGpio, Zephyr::ZephyrGpioDriver::GpioConfiguration::OUT);
Expand Down
2 changes: 2 additions & 0 deletions FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,4 +137,6 @@ module ReferenceDeployment {

instance startupManager: Components.StartupManager base id 0x1003F000

instance gpioRadioReset: Zephyr.ZephyrGpioDriver base id 0x10040000

}
5 changes: 5 additions & 0 deletions FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ module ReferenceDeployment {
instance gpioface5LS
instance gpioPayloadPowerLS
instance gpioPayloadBatteryLS
instance gpioRadioReset
instance watchdog
instance rtcManager
instance imuManager
Expand Down Expand Up @@ -179,6 +180,10 @@ module ReferenceDeployment {
watchdog.gpioSet -> gpioWatchdog.gpioWrite
}

connections RadioReset {
resetManager.radioResetOut -> gpioRadioReset.gpioWrite
}

connections LoadSwitches {
face4LoadSwitch.gpioSet -> gpioface4LS.gpioWrite
face0LoadSwitch.gpioSet -> gpioface0LS.gpioWrite
Expand Down
19 changes: 19 additions & 0 deletions FprimeZephyrReference/test/int/reset_manager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,22 @@ def test_02_warm_reset(fprime_test_api: IntegrationTestAPI, start_gds):

# Assert FPrime restarted by checking for FrameworkVersion event
fprime_test_api.assert_event("CdhCore.version.FrameworkVersion", timeout=10)


def test_03_radio_reset(fprime_test_api: IntegrationTestAPI, start_gds):
"""Test that we can initiate a radio reset without system reboot"""

# Clear event history before test
fprime_test_api.clear_histories()

# Send RESET_RADIO command
fprime_test_api.send_and_assert_command(f"{resetManager}.RESET_RADIO", timeout=5)

# Assert INITIATE_RADIO_RESET event was emitted
fprime_test_api.assert_event(
"ReferenceDeployment.resetManager.INITIATE_RADIO_RESET", timeout=2
)

# Verify system is still running (not rebooted like cold/warm reset)
# We can do this by sending another simple command
fprime_test_api.send_and_assert_command("CdhCore.cmdDisp.CMD_NO_OP", timeout=2)
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
gpios = <&gpio0 29 GPIO_ACTIVE_HIGH>;
label = "burnwire 1";
};
radio_reset: radio-reset {
gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
label = "Radio Reset";
};
};
};

Expand Down