diff --git a/BroncoDeployment/Top/BroncoDeploymentPackets.xml b/BroncoDeployment/Top/BroncoDeploymentPackets.xml
index 76445dc..44224b9 100644
--- a/BroncoDeployment/Top/BroncoDeploymentPackets.xml
+++ b/BroncoDeployment/Top/BroncoDeploymentPackets.xml
@@ -53,6 +53,12 @@
+
+
+
+
+
+
diff --git a/BroncoDeployment/Top/instances.fpp b/BroncoDeployment/Top/instances.fpp
index 336e878..1f36080 100644
--- a/BroncoDeployment/Top/instances.fpp
+++ b/BroncoDeployment/Top/instances.fpp
@@ -27,6 +27,11 @@ module BroncoDeployment {
queue size Default.QUEUE_SIZE \
stack size Default.STACK_SIZE \
priority 97
+
+ instance ledBlinker: Components.LedBlinker base id 0x0E00 \
+ queue size Default.QUEUE_SIZE \
+ stack size Default.STACK_SIZE \
+ priority 95
# ----------------------------------------------------------------------
# Queued component instances
@@ -60,6 +65,8 @@ module BroncoDeployment {
instance rateDriver: Arduino.HardwareRateDriver base id 0x4A00
+ instance neoPixelDriver: Drv.NeoPixelDriver base id 0x4C00
+
# Hub Connections
instance hub: Svc.GenericHub base id 0x5000
@@ -70,8 +77,6 @@ module BroncoDeployment {
instance hubComDriver: Radio.RFM69 base id 0x5300
-
-
# Custom Connections
instance broncoOreMessageHandler: Components.BroncoOreMessageHandler base id 0x6000
diff --git a/BroncoDeployment/Top/topology.fpp b/BroncoDeployment/Top/topology.fpp
index 0f6a974..a48a187 100644
--- a/BroncoDeployment/Top/topology.fpp
+++ b/BroncoDeployment/Top/topology.fpp
@@ -44,6 +44,8 @@ module BroncoDeployment {
#custom instances
instance broncoOreMessageHandler
+ instance ledBlinker
+ instance neoPixelDriver
# ----------------------------------------------------------------------
# Pattern graph specifiers
@@ -126,6 +128,15 @@ module BroncoDeployment {
hubDeframer.bufferOut -> hub.dataIn
hub.dataInDeallocate -> bufferManager.bufferSendIn
}
+
+ # Named connection group
+ connections LedConnections {
+ # Rate Group 1 (1Hz cycle) ouput is connected to led's run input
+ rateGroup1.RateGroupMemberOut[3] -> ledBlinker.run
+ # led's neopixel output is connected to neoPixelDriver's neoPixelOnOff input
+ ledBlinker.neoPixelSet -> neoPixelDriver.neoPixelSet
+ }
+
}
}
diff --git a/Components/CMakeLists.txt b/Components/CMakeLists.txt
index 40b944f..bedc4d2 100644
--- a/Components/CMakeLists.txt
+++ b/Components/CMakeLists.txt
@@ -4,5 +4,5 @@
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/BroncoOreMessageHandler/")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Radio/")
-
+add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/LedBlinker/")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Drv/")
diff --git a/Components/LedBlinker/CMakeLists.txt b/Components/LedBlinker/CMakeLists.txt
new file mode 100644
index 0000000..e9bc80f
--- /dev/null
+++ b/Components/LedBlinker/CMakeLists.txt
@@ -0,0 +1,14 @@
+####
+# F prime CMakeLists.txt:
+#
+# SOURCE_FILES: combined list of source and autocoding files
+# MOD_DEPS: (optional) module dependencies
+# UT_SOURCE_FILES: list of source files for unit tests
+#
+####
+set(SOURCE_FILES
+ "${CMAKE_CURRENT_LIST_DIR}/LedBlinker.fpp"
+ "${CMAKE_CURRENT_LIST_DIR}/LedBlinker.cpp"
+)
+
+register_fprime_module()
diff --git a/Components/LedBlinker/LedBlinker.cpp b/Components/LedBlinker/LedBlinker.cpp
new file mode 100644
index 0000000..ab8a87b
--- /dev/null
+++ b/Components/LedBlinker/LedBlinker.cpp
@@ -0,0 +1,143 @@
+// ======================================================================
+// \title LedBlinker.cpp
+// \author nateinaction
+// \brief cpp file for LedBlinker component implementation class
+// ======================================================================
+
+#include "Components/LedBlinker/LedBlinker.hpp"
+#include "FpConfig.hpp"
+
+namespace Components {
+
+// ----------------------------------------------------------------------
+// Component construction and destruction
+// ----------------------------------------------------------------------
+LedBlinker ::LedBlinker(const char* const compName) : LedBlinkerComponentBase(compName) {}
+
+LedBlinker ::~LedBlinker() {}
+
+// ----------------------------------------------------------------------
+// Handler implementations for user-defined typed input ports
+// ----------------------------------------------------------------------
+
+ void LedBlinker ::
+ run_handler(
+ const NATIVE_INT_TYPE portNum,
+ NATIVE_UINT_TYPE context)
+ {
+ // Only perform actions when set to blinking
+ if (this->blinkingState) {
+ // Blink the LED
+ blink();
+ } else {
+ // Turn off the LED
+ this->neoPixelSet_out(0, Drv::NeoPixelColor(0, 0, 0));
+ }
+
+ // Report the number of blinks via a telemetry channel
+ this->tlmWrite_LedBlinks(this->blinkCount);
+ }
+
+ void LedBlinker ::blink() {
+ // Get interval from parameter or use default
+ U32 interval = this->intervalParamOrDefault();
+
+ // Get color from parameter or use default
+ Drv::NeoPixelColor color = this->colorParamOrDefault();
+
+ // Set the LED color or turn it off based on cycle count
+ this->neoPixelSet_out(0, (this->cycleCount < (interval / 2)) ? color : Drv::NeoPixelColor(0, 0, 0));
+
+ // Increment blink count at the start of a cycle
+ this->blinkCount += (this->cycleCount == 0);
+
+ // Increment cycle count
+ this->cycleCount = (this->cycleCount + 1) % interval;
+ }
+
+ Drv::NeoPixelColor LedBlinker ::colorParamOrDefault() {
+ // Read back the parameter value
+ Fw::ParamValid isColorValid;
+ Drv::NeoPixelColor color = this->paramGet_BLINK_COLOR(isColorValid);
+
+ // Force color to be red when invalid or not set
+ return ((Fw::ParamValid::INVALID == isColorValid) || (Fw::ParamValid::UNINIT == isColorValid)) ? Drv::NeoPixelColor(50, 0, 0) : color;
+ }
+
+ U32 LedBlinker ::intervalParamOrDefault() {
+ // Read back the parameter value
+ Fw::ParamValid isIntervalValid;
+ U32 interval = this->paramGet_BLINK_INTERVAL(isIntervalValid);
+
+ // Force interval to be 10 when invalid or not set
+ return ((Fw::ParamValid::INVALID == isIntervalValid) || (Fw::ParamValid::UNINIT == isIntervalValid)) ? 10 : interval;
+ }
+
+ // ----------------------------------------------------------------------
+ // Handler implementations for commands
+ // ----------------------------------------------------------------------
+
+ void LedBlinker ::BLINKING_ON_OFF_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Fw::On blinking_state) {
+ // Create a variable to represent the command response
+ auto cmdResp = Fw::CmdResponse::OK;
+
+ // Set blinking state
+ this->blinkingState = blinking_state;
+
+ // Reset cycle count
+ this->cycleCount = 0;
+
+ // Reports the state as an event
+ this->log_ACTIVITY_HI_SetBlinkingState(blinking_state);
+
+ // Report the blinking state via a telemetry channel.
+ this->tlmWrite_BlinkingState(blinking_state);
+
+ // Provide command response
+ this->cmdResponse_out(opCode, cmdSeq, cmdResp);
+ }
+
+ void LedBlinker ::parameterUpdated(FwPrmIdType id) {
+ switch (id)
+ {
+ case PARAMID_BLINK_COLOR:
+ // Validate and set the color parameter on update
+ this->parameterValidateColor();
+ break;
+ case PARAMID_BLINK_INTERVAL:
+ // Validate and set the interval parameter on update
+ this->parameterValidateInterval();
+ break;
+ default:
+ FW_ASSERT(1, id); // Should never reach, invalid parameter ID
+ break;
+ }
+ }
+
+ void LedBlinker ::parameterValidateColor() {
+ // Read back the parameter value
+ Fw::ParamValid isValid;
+ Drv::NeoPixelColor color = this->paramGet_BLINK_COLOR(isValid);
+
+ // Fail if the color is invalid
+ FW_ASSERT(isValid == Fw::ParamValid::VALID, isValid);
+
+ // Log the color change
+ this->log_ACTIVITY_HI_BlinkColorSet(color);
+
+ // Report the color via a telemetry channel
+ this->tlmWrite_BlinkingColor(color);
+ }
+
+ void LedBlinker ::parameterValidateInterval() {
+ // Read back the parameter value
+ Fw::ParamValid isValid;
+ U32 interval = this->paramGet_BLINK_INTERVAL(isValid);
+
+ // Fail if the interval is invalid
+ FW_ASSERT(isValid == Fw::ParamValid::VALID, isValid);
+
+ // Log the interval change
+ this->log_ACTIVITY_HI_BlinkIntervalSet(interval);
+ }
+} // namespace Components
diff --git a/Components/LedBlinker/LedBlinker.fpp b/Components/LedBlinker/LedBlinker.fpp
new file mode 100644
index 0000000..579664c
--- /dev/null
+++ b/Components/LedBlinker/LedBlinker.fpp
@@ -0,0 +1,76 @@
+module Components {
+ @ Component to blink an LED driven by a rate group
+ active component LedBlinker {
+ @ Command to turn on or off the blinking LED
+ async command BLINKING_ON_OFF(
+ blinking_state: Fw.On @< Turn the LED blinking on or off.
+ )
+
+ @ Reports the state we set to blinking.
+ event SetBlinkingState(state: Fw.On) \
+ severity activity high \
+ format "Set blinking state to {}."
+
+ @ Reports the color that has been set
+ event BlinkColorSet(color: Drv.NeoPixelColor) \
+ severity activity high \
+ format "LED blink color set to {}"
+
+ @ Reports the interval that has been set
+ event BlinkIntervalSet(interval: U32) \
+ severity activity high \
+ format "LED blink interval set to {}"
+
+ @ Telemetry channel to report blinking state.
+ telemetry BlinkingState: Fw.On
+
+ @ Telemetry channel to report blinking state.
+ telemetry BlinkingColor: Drv.NeoPixelColor
+
+ @ Telemetry channel to report the LED state.
+ telemetry LedBlinks: U64
+
+ @ Blinking interval in rate group ticks
+ param BLINK_INTERVAL: U32
+
+ @ Blinking interval in rate group ticks
+ param BLINK_COLOR: Drv.NeoPixelColor
+
+ @ Port receiving calls from the rate group
+ sync input port run: Svc.Sched
+
+ @ Port sending calls to the GPIO driver
+ output port neoPixelSet: Drv.NeoPixelSet
+
+ ###############################################################################
+ # Standard AC Ports: Required for Channels, Events, Commands, and Parameters #
+ ###############################################################################
+ @ Port for requesting the current time
+ time get port timeCaller
+
+ @ Port for sending command registrations
+ command reg port cmdRegOut
+
+ @ Port for receiving commands
+ command recv port cmdIn
+
+ @ Port for sending command responses
+ command resp port cmdResponseOut
+
+ @ Port for sending textual representation of events
+ text event port logTextOut
+
+ @ Port for sending events to downlink
+ event port logOut
+
+ @ Port for sending telemetry channels to downlink
+ telemetry port tlmOut
+
+ @ Port to return the value of a parameter
+ param get port prmGetOut
+
+ @Port to set the value of a parameter
+ param set port prmSetOut
+
+ }
+}
diff --git a/Components/LedBlinker/LedBlinker.hpp b/Components/LedBlinker/LedBlinker.hpp
new file mode 100644
index 0000000..4e5bc9c
--- /dev/null
+++ b/Components/LedBlinker/LedBlinker.hpp
@@ -0,0 +1,88 @@
+// ======================================================================
+// \title LedBlinker.hpp
+// \author nateinaction
+// \brief hpp file for LedBlinker component implementation class
+// ======================================================================
+
+#ifndef Components_LedBlinker_HPP
+#define Components_LedBlinker_HPP
+
+#include "Components/LedBlinker/LedBlinkerComponentAc.hpp"
+
+namespace Components {
+
+class LedBlinker : public LedBlinkerComponentBase {
+ public:
+ // ----------------------------------------------------------------------
+ // Component construction and destruction
+ // ----------------------------------------------------------------------
+
+ //! Construct LedBlinker object
+ LedBlinker(const char* const compName //!< The component name
+ );
+
+ //! Destroy LedBlinker object
+ ~LedBlinker();
+
+ private:
+ // ----------------------------------------------------------------------
+ // Handler implementations for user-defined typed input ports
+ // ----------------------------------------------------------------------
+
+ //! Handler implementation for run
+ //!
+ //! Port receiving calls from the rate group
+ void run_handler(NATIVE_INT_TYPE portNum, //!< The port number
+ NATIVE_UINT_TYPE context //!< The call order
+ ) override;
+
+ // ----------------------------------------------------------------------
+ // Handler implementations for commands
+ // ----------------------------------------------------------------------
+
+ //! Implementation for BLINKING_ON_OFF command handler
+ //! Command to turn on or off the blinking LED
+ void BLINKING_ON_OFF_cmdHandler(FwOpcodeType opCode, //!< The opcode
+ U32 cmdSeq, //!< The command sequence number
+ Fw::On blinking_state //!< Color to blink
+ ) override;
+
+ //! Emit parameter updated EVR
+ //!
+ void parameterUpdated(FwPrmIdType id /*!< The parameter ID*/
+ );
+
+ //! Validate and set the color parameter on update
+ //!
+ void parameterValidateColor(
+ );
+
+ //! Validate and set the interval parameter on update
+ //!
+ void parameterValidateInterval(
+ );
+
+ //! Choose the color to blink
+ //!
+ Drv::NeoPixelColor colorParamOrDefault(
+ );
+
+ //! Choose the interval to blink
+ //!
+ U32 intervalParamOrDefault(
+ );
+
+ //! The LED blinker behavior
+ //!
+ void blink(
+ );
+
+ // Private member variables
+ Fw::On blinkingState; //!< Whether the LED is blinking or not
+ U64 blinkCount; //! The number of on/off transitions that have occurred from FSW boot up
+ U32 cycleCount; //! Keeps track of how many ticks the LED has been on for
+};
+
+} // namespace Components
+
+#endif