Skip to content
Open
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
25 changes: 18 additions & 7 deletions FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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
38 changes: 14 additions & 24 deletions FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.fpp
Original file line number Diff line number Diff line change
@@ -1,49 +1,39 @@
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

@ 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 #
###############################################################################
Expand Down
11 changes: 3 additions & 8 deletions FprimeZephyrReference/Components/LoadSwitch/LoadSwitch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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(); //<! Get the current state (ON or OFF)
};

} // namespace Components
Expand Down
46 changes: 39 additions & 7 deletions FprimeZephyrReference/Components/LoadSwitch/docs/sdd.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
# Components::LoadSwitch

![LoadSwitch](LoadSwitch.svg)

## Overview

The `LoadSwitch` component is an active F' component that controls a single load switch output
through the `gpioSet` output port (connected to the platform's GPIO driver). It exposes two
async commands to turn the switch on and off, telemetry reporting the current state, and an
async `Reset` input which toggles the switch (off, short delay, on).
async commands to turn the switch on and off, telemetry reporting the current state. It also provides ports to control the switch and notify other components of state changes.

## Responsibility

- Control the power rail for a connected peripheral by asserting/deasserting a GPIO.
- Report state changes via an event and telemetry channel.
- Provide an interface for other components to control the switch and subscribe to state changes.

## Class Diagram

```mermaid
classDiagram
namespace Components {
class LoadSwitchComponentBase {
<<Auto-generated>>
}
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

Expand All @@ -27,27 +45,41 @@ 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

| Name | Severity | ID | Format |
|---|---|---:|---|
| 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

| Date | Description |
|---|---|
| 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. |
15 changes: 15 additions & 0 deletions FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading