diff --git a/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.cpp b/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.cpp index 002d8b6e..094cd976 100644 --- a/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.cpp +++ b/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.cpp @@ -22,12 +22,6 @@ LoadSwitch ::~LoadSwitch() {} // Handler implementations for typed input ports // ---------------------------------------------------------------------- -void LoadSwitch ::Reset_handler(FwIndexType portNum) { - this->setLoadSwitchState(Fw::On::OFF); - k_sleep(K_MSEC(100)); - this->setLoadSwitchState(Fw::On::ON); -} - void LoadSwitch ::turnOn_handler(FwIndexType portNum) { this->setLoadSwitchState(Fw::On::ON); } @@ -55,10 +49,27 @@ void LoadSwitch ::TURN_OFF_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { // ---------------------------------------------------------------------- void LoadSwitch ::setLoadSwitchState(Fw::On state) { - Fw::Logic gpioValue = (state == Fw::On::ON) ? Fw::Logic::HIGH : Fw::Logic::LOW; + // Check if the state is changing + if (this->getLoadSwitchState() == state) { + return; + } + + // Set the load switch state + Fw::Logic gpioValue = state ? Fw::Logic::HIGH : Fw::Logic::LOW; this->gpioSet_out(0, gpioValue); + + // Inform downstream components of the state change + for (FwIndexType i = 0; i < this->getNum_loadSwitchStateChanged_OutputPorts(); i++) { + this->loadSwitchStateChanged_out(i, state); + } this->log_ACTIVITY_HI_StatusChanged(state); this->tlmWrite_IsOn(state); } +Fw::On LoadSwitch ::getLoadSwitchState() { + Fw::Logic state; + this->gpioGet_out(0, state); + return state ? Fw::On::ON : Fw::On::OFF; +} + } // namespace Components diff --git a/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.fpp b/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.fpp index 33540ad0..c2f7339d 100644 --- a/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.fpp +++ b/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.fpp @@ -1,39 +1,32 @@ +module Components { + port loadSwitchStateGet -> Fw.On + port loadSwitchStateChanged($state: Fw.On) -> Fw.Success +} + module Components { @ A generic load switch for controlling power to components passive component LoadSwitch { - # One async command/port is required for active components - # This should be overridden by the developers with a useful command/port - - ############################################################################## - #### Uncomment the following examples to start customizing your component #### - ############################################################################## - - # @ Example async command - # async command COMMAND_NAME(param_name: U32) + @ Command to turn the load switch on sync command TURN_ON() + + @ Command to turn the load switch off sync command TURN_OFF() - # @ Example telemetry counter - # telemetry ExampleCounter: U64 + @ Telemetry channel for load switch state telemetry IsOn: Fw.On - # @ Example event - # event ExampleStateEvent(example_state: Fw.On) severity activity high id 0 format "State set to {}" + @ Event for reporting load switch state change event StatusChanged($state: Fw.On) severity activity high id 1 format "Load switch state changed to {}" - # @ Example port: receiving calls from the rate group - # sync input port run: Svc.Sched - #output port Status: Drv.GpioRead - #We will not be putting a Drv.GpioRead port here, we are using the Gpio Driver component which has this already! - @ Port sending calls to the GPIO driver output port gpioSet: Drv.GpioWrite + @ Port sending calls to the GPIO driver to read state + output port gpioGet: Drv.GpioRead - # Input that will be used by other components if they want to force a reset - # (off and on again) of the load switch - sync input port Reset: Fw.Signal + @ Port to indicate a change in load switch state + output port loadSwitchStateChanged: [2] loadSwitchStateChanged @ Input port to turn on the load switch (called by other components) sync input port turnOn: Fw.Signal @@ -41,9 +34,6 @@ module Components { @ Input port to turn off the load switch (called by other components) sync input port turnOff: Fw.Signal - # @ Example parameter - # param PARAMETER_NAME: U32 - ############################################################################### # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # ############################################################################### diff --git a/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.hpp b/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.hpp index 7e2862e2..8d89265d 100644 --- a/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.hpp +++ b/FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.hpp @@ -43,14 +43,6 @@ class LoadSwitch final : public LoadSwitchComponentBase { U32 cmdSeq //!< The command sequence number ) override; - // ---------------------------------------------------------------------- - // Handler implementations for typed input ports - // ---------------------------------------------------------------------- - - //! Handler implementation for Reset - void Reset_handler(FwIndexType portNum //!< The port number - ) override; - //! Handler implementation for turnOn void turnOn_handler(FwIndexType portNum //!< The port number ) override; @@ -66,6 +58,9 @@ class LoadSwitch final : public LoadSwitchComponentBase { //! Set the load switch state (common implementation for commands and ports) void setLoadSwitchState(Fw::On state //!< The desired state (ON or OFF) ); + + //! Get current load switch state + Fw::On getLoadSwitchState(); //> + } + class LoadSwitch { + + LoadSwitch(const char* compName) + + ~LoadSwitch() + - TURN_ON_cmdHandler(FwOpcodeType opCode, U32 cmdSeq): void + - TURN_OFF_cmdHandler(FwOpcodeType opCode, U32 cmdSeq): void + - turnOn_handler(FwIndexType portNum): void + - turnOff_handler(FwIndexType portNum): void + } + } + LoadSwitchComponentBase <|-- LoadSwitch : inherits +``` ## External interface @@ -27,7 +45,7 @@ async `Reset` input which toggles the switch (off, short delay, on). | Name | Type | Description | |---|---:|---| -| IsOn | Fw.On | Current power state; written after commands and on Reset handling. | +| IsOn | Fw.On | Current power state; written after commands. Note: Reports ON only after a stabilization delay (default 1s) following the turn-on command. | ### Events @@ -35,15 +53,28 @@ async `Reset` input which toggles the switch (off, short delay, on). |---|---|---:|---| | StatusChanged | activity high | 1 | "Load switch state changed to {}" | -The component logs the `StatusChanged` event whenever the switch transitions due to a command or a Reset. +The component logs the `StatusChanged` event whenever the switch transitions due to a command. ### Ports | Port name | Direction | Port type | Notes | |---|---|---|---| | gpioSet | output | Drv.GpioWrite | Used to write the physical GPIO. Implementation always uses index 0 (`gpioSet_out(0, ...)`). | -| Reset | input (async) | Fw.Signal | Causes the component to perform a hardware reset sequence: LOW -> wait 100ms -> HIGH. | +| gpioGet | output | Drv.GpioRead | Used to read the physical GPIO state. | +| turnOn | input (sync) | Fw.Signal | Turns on the load switch. | +| turnOff | input (sync) | Fw.Signal | Turns off the load switch. | +| loadSwitchStateChanged | output | loadSwitchStateChanged | Notifies connected components when the load switch state changes | + +## Requirements +| Name | Description | Validation | +|---|---|---| +| Control via Command | The component shall allow turning the load switch on and off via ground commands `TURN_ON` and `TURN_OFF`. | Integration test | +| Control via Port | The component shall allow turning the load switch on and off via input ports `turnOn` and `turnOff`. | Verify `turnOn` and `turnOff` port calls change the GPIO state and telemetry. | +| State Telemetry | The component shall report the current state of the load switch via the `IsOn` telemetry channel. | Integration test | +| State Event | The component shall emit a `StatusChanged` event when the load switch state changes. | Verify `StatusChanged` event is emitted upon state transitions. | +| State Notification | The component shall notify connected components of state changes via the `loadSwitchStateChanged` port. | Downstream component testing | +| GPIO Control | The component shall control the physical GPIO pin corresponding to the load switch using the `gpioSet` port. | Downstream component testing | ## Change Log @@ -51,3 +82,4 @@ The component logs the `StatusChanged` event whenever the switch transitions due |---|---| | 10-22-2025 | Sarah, Kevin, and MoMata's first commit | | 11-07-2025 | Updated SDD to match implementation in `LoadSwitch.cpp/.hpp/.fpp` (commands, telemetry, event, ports, reset behavior). | +| 11-30-2025 | Removed Reset capability. Added `loadSwitchStateChanged` output port for state notifications. | diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp index 0390534e..20aa7dac 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp @@ -183,13 +183,28 @@ module ReferenceDeployment { connections LoadSwitches { face4LoadSwitch.gpioSet -> gpioface4LS.gpioWrite + face4LoadSwitch.gpioGet -> gpioface4LS.gpioRead + face0LoadSwitch.gpioSet -> gpioface0LS.gpioWrite + face0LoadSwitch.gpioGet -> gpioface0LS.gpioRead + face1LoadSwitch.gpioSet -> gpioface1LS.gpioWrite + face1LoadSwitch.gpioGet -> gpioface1LS.gpioRead + face2LoadSwitch.gpioSet -> gpioface2LS.gpioWrite + face2LoadSwitch.gpioGet -> gpioface2LS.gpioRead + face3LoadSwitch.gpioSet -> gpioface3LS.gpioWrite + face3LoadSwitch.gpioGet -> gpioface3LS.gpioRead + face5LoadSwitch.gpioSet -> gpioface5LS.gpioWrite + face5LoadSwitch.gpioGet -> gpioface5LS.gpioRead + payloadPowerLoadSwitch.gpioSet -> gpioPayloadPowerLS.gpioWrite + payloadPowerLoadSwitch.gpioGet -> gpioPayloadPowerLS.gpioRead + payloadBatteryLoadSwitch.gpioSet -> gpioPayloadBatteryLS.gpioWrite + payloadBatteryLoadSwitch.gpioGet -> gpioPayloadBatteryLS.gpioRead } connections BurnwireGpio {