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