PCDU switch callback #128

Merged
meierj merged 24 commits from mueller/pcdu-switch-callback into develop 2022-01-19 19:46:57 +01:00
24 changed files with 276 additions and 49 deletions

View File

@ -37,7 +37,7 @@ Target systems:
relevant pages. The most recent datasheet can be found relevant pages. The most recent datasheet can be found
[here](https://trac2.xiphos.ca/manual/wiki/Q7RevB/UserManual). [here](https://trac2.xiphos.ca/manual/wiki/Q7RevB/UserManual).
* Linux OS built with Yocto 2.5 * Linux OS built with Yocto 2.5
* Linux Kernel https://github.com/XiphosSystemsCorp/linux-xlnx.git . EIVE version can be found * [Linux Kernel](https://github.com/XiphosSystemsCorp/linux-xlnx.git) . EIVE version can be found
[here](https://github.com/spacefisch/linux-xlnx) . Pre-compiled files can be [here](https://github.com/spacefisch/linux-xlnx) . Pre-compiled files can be
found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/q7s-linux-components&fileid=777299). found [here](https://eive-cloud.irs.uni-stuttgart.de/index.php/apps/files/?dir=/EIVE_IRS/Software/q7s-linux-components&fileid=777299).
* Q7S base project can be found [here](https://egit.irs.uni-stuttgart.de/eive/q7s-base) * Q7S base project can be found [here](https://egit.irs.uni-stuttgart.de/eive/q7s-base)
@ -1093,7 +1093,7 @@ The [TCF agent](https://wiki.eclipse.org/TCF) can be used to perform remote debu
1. Install the TCF agent plugin in Eclipse from 1. Install the TCF agent plugin in Eclipse from
the [releases](https://www.eclipse.org/tcf/downloads.php). Go to the [releases](https://www.eclipse.org/tcf/downloads.php). Go to
Help → Install New Software and use the download page, for Help → Install New Software and use the download page, for
example https://download.eclipse.org/tools/tcf/releases/1.6/1.6.2/ to search for the plugin and install it. example https://download.eclipse.org/tools/tcf/releases/1.7/1.7.0/ to search for the plugin and install it. You can find the newest version [here](https://www.eclipse.org/tcf/downloads.php)
2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**. 2. Go to Window → Perspective → Open Perspective and open the **Target Explorer Perspective**.
Here, the Q7S should show up if the local port forwarding was set up as explained previously. Here, the Q7S should show up if the local port forwarding was set up as explained previously.

View File

@ -1,4 +1,5 @@
target_sources(${TARGET_NAME} PRIVATE target_sources(${TARGET_NAME} PRIVATE
rwSpiCallback.cpp rwSpiCallback.cpp
gnssCallback.cpp gnssCallback.cpp
pcduSwitchCb.cpp
) )

View File

@ -0,0 +1,32 @@
#include "pcduSwitchCb.h"
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
#include "devices/gpioIds.h"
void pcdu::switchCallback(GOMSPACE::Pdu pdu, uint8_t channel, bool state, void* args) {
LinuxLibgpioIF* gpioComIF = reinterpret_cast<LinuxLibgpioIF*>(args);
if (gpioComIF == nullptr) {
return;
}
if (pdu == GOMSPACE::Pdu::PDU1) {
PDU1::SwitchChannels typedChannel = static_cast<PDU1::SwitchChannels>(channel);
if (typedChannel == PDU1::SwitchChannels::ACS_A_SIDE) {
if (state) {
gpioComIF->pullHigh(gpioIds::GNSS_0_NRESET);
} else {
gpioComIF->pullLow(gpioIds::GNSS_0_NRESET);
}
}
} else if (pdu == GOMSPACE::Pdu::PDU2) {
PDU2::SwitchChannels typedChannel = static_cast<PDU2::SwitchChannels>(channel);
if (typedChannel == PDU2::SwitchChannels::ACS_B_SIDE) {
if (state) {
gpioComIF->pullHigh(gpioIds::GNSS_1_NRESET);
} else {
gpioComIF->pullLow(gpioIds::GNSS_1_NRESET);
}
}
}
}

View File

@ -0,0 +1,14 @@
#ifndef BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_
#define BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_
#include <cstdint>
#include "mission/devices/devicedefinitions/GomspaceDefinitions.h"
namespace pcdu {
void switchCallback(GOMSPACE::Pdu pdu, uint8_t channel, bool state, void* args);
}
#endif /* BSP_Q7S_CALLBACKS_PCDUSWITCHCB_H_ */

View File

@ -206,7 +206,7 @@ void initmission::initTasks() {
#endif /* OBSW_ADD_STAR_TRACKER == 1 */ #endif /* OBSW_ADD_STAR_TRACKER == 1 */
#endif #endif
acsCtrl->startTask(); // acsCtrl->startTask();
sif::info << "Tasks started.." << std::endl; sif::info << "Tasks started.." << std::endl;
} }

View File

@ -5,6 +5,7 @@
#include "OBSWConfig.h" #include "OBSWConfig.h"
#include "bsp_q7s/boardtest/Q7STestTask.h" #include "bsp_q7s/boardtest/Q7STestTask.h"
#include "bsp_q7s/callbacks/gnssCallback.h" #include "bsp_q7s/callbacks/gnssCallback.h"
#include "bsp_q7s/callbacks/pcduSwitchCb.h"
#include "bsp_q7s/callbacks/rwSpiCallback.h" #include "bsp_q7s/callbacks/rwSpiCallback.h"
#include "bsp_q7s/core/CoreController.h" #include "bsp_q7s/core/CoreController.h"
#include "bsp_q7s/devices/PlocMemoryDumper.h" #include "bsp_q7s/devices/PlocMemoryDumper.h"
@ -122,13 +123,14 @@ void ObjectFactory::produce(void* args) {
#if BOARD_TE0720 == 0 #if BOARD_TE0720 == 0
new CoreController(objects::CORE_CONTROLLER); new CoreController(objects::CORE_CONTROLLER);
createPcduComponents(); createPcduComponents(gpioComIF);
createRadSensorComponent(gpioComIF); createRadSensorComponent(gpioComIF);
createSunSensorComponents(gpioComIF, spiComIF); createSunSensorComponents(gpioComIF, spiComIF);
#if OBSW_ADD_ACS_BOARD == 1 #if OBSW_ADD_ACS_BOARD == 1
createAcsBoardComponents(gpioComIF, uartComIF); createAcsBoardComponents(gpioComIF, uartComIF);
#endif /* OBSW_ADD_ACS_BOARD == 1 */ #endif
createHeaterComponents(); createHeaterComponents();
createSolarArrayDeploymentComponents(); createSolarArrayDeploymentComponents();
#if OBSW_ADD_SYRLINKS == 1 #if OBSW_ADD_SYRLINKS == 1
@ -234,7 +236,7 @@ void ObjectFactory::createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, Ua
#endif #endif
} }
void ObjectFactory::createPcduComponents() { void ObjectFactory::createPcduComponents(LinuxLibgpioIF* gpioComIF) {
CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, addresses::P60DOCK); CspCookie* p60DockCspCookie = new CspCookie(P60Dock::MAX_REPLY_LENGTH, addresses::P60DOCK);
CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU1); CspCookie* pdu1CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU1);
CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU2); CspCookie* pdu2CspCookie = new CspCookie(PDU::MAX_REPLY_LENGTH, addresses::PDU2);
@ -244,8 +246,10 @@ void ObjectFactory::createPcduComponents() {
new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie); new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF, p60DockCspCookie);
PDU1Handler* pdu1handler = PDU1Handler* pdu1handler =
new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie); new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF, pdu1CspCookie);
pdu1handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF);
PDU2Handler* pdu2handler = PDU2Handler* pdu2handler =
new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie); new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF, pdu2CspCookie);
pdu2handler->assignChannelHookFunction(&pcdu::switchCallback, gpioComIF);
ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie); ACUHandler* acuhandler = new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF, acuCspCookie);
new PCDUHandler(objects::PCDU_HANDLER, 50); new PCDUHandler(objects::PCDU_HANDLER, 50);
@ -472,6 +476,7 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI
gpioComIF->addGpios(gpioCookieAcsBoard); gpioComIF->addGpios(gpioCookieAcsBoard);
#if OBSW_ADD_ACS_HANDLERS == 1
std::string spiDev = q7s::SPI_DEFAULT_DEV; std::string spiDev = q7s::SPI_DEFAULT_DEV;
SpiCookie* spiCookie = SpiCookie* spiCookie =
new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev, new SpiCookie(addresses::MGM_0_LIS3, gpioIds::MGM_0_LIS3_CS, spiDev,
@ -561,6 +566,7 @@ void ObjectFactory::createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComI
resetArgsGnss0.waitPeriodMs = 100; resetArgsGnss0.waitPeriodMs = 100;
auto gpsHandler0 = new GPSHyperionHandler(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps); auto gpsHandler0 = new GPSHyperionHandler(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps);
gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0); gpsHandler0->setResetPinTriggerFunction(gps::triggerGpioResetPin, &resetArgsGnss0);
#endif /* OBSW_ADD_ACS_HANDLERS == 1 */
} }
void ObjectFactory::createHeaterComponents() { void ObjectFactory::createHeaterComponents() {
@ -857,6 +863,7 @@ void ObjectFactory::createReactionWheelComponents(LinuxLibgpioIF* gpioComIF) {
rwHandler1->setStartUpImmediately(); rwHandler1->setStartUpImmediately();
#endif #endif
rw1SpiCookie->setCallbackArgs(rwHandler1); rw1SpiCookie->setCallbackArgs(rwHandler1);
rwHandler1->setStartUpImmediately();
auto rwHandler2 = auto rwHandler2 =
new RwHandler(objects::RW2, objects::SPI_COM_IF, rw2SpiCookie, gpioComIF, gpioIds::EN_RW2); new RwHandler(objects::RW2, objects::SPI_COM_IF, rw2SpiCookie, gpioComIF, gpioIds::EN_RW2);

View File

@ -13,7 +13,7 @@ void produce(void* args);
void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF, void createCommunicationInterfaces(LinuxLibgpioIF** gpioComIF, UartComIF** uartComIF,
SpiComIF** spiComIF); SpiComIF** spiComIF);
void createTmpComponents(); void createTmpComponents();
void createPcduComponents(); void createPcduComponents(LinuxLibgpioIF* gpioComIF);
void createRadSensorComponent(LinuxLibgpioIF* gpioComIF); void createRadSensorComponent(LinuxLibgpioIF* gpioComIF);
void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF); void createSunSensorComponents(LinuxLibgpioIF* gpioComIF, SpiComIF* spiComIF);
void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF); void createAcsBoardComponents(LinuxLibgpioIF* gpioComIF, UartComIF* uartComIF);

View File

@ -29,7 +29,7 @@ int obsw::obsw() {
if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) { if (std::filesystem::exists(watchdog::RUNNING_FILE_NAME)) {
sif::warning << "File " << watchdog::RUNNING_FILE_NAME sif::warning << "File " << watchdog::RUNNING_FILE_NAME
<< " exists so the software might " << " exists so the software might "
"already be running. Check if obsw systemd service has been stopped." "already be running. Aborting.."
<< std::endl; << std::endl;
return OBSW_ALREADY_RUNNING; return OBSW_ALREADY_RUNNING;
} }

7
cmake/scripts/Q7S/q7s-env.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash -i
export PATH=$PATH:"$HOME/EIVE/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin"
export CROSS_COMPILE="arm-linux-gnueabihf"
export Q7S_SYSROOT="$HOME/Xilinx/cortexa9hf-neon-xiphos-linux-gnueabi"
export CONSOLE_PREFIX="[Q7S ENV]"
/bin/bash

View File

@ -1,6 +0,0 @@
#!/bin/sh
export PATH=$PATH:"/opt/Xilinx/SDK/2018.2/gnu/aarch32/lin/gcc-arm-linux-gnueabi/bin"
export CROSS_COMPILE="arm-linux-gnueabihf"
export Q7S_SYSROOT="$HOME/Xilinx/cortexa9hf-neon-xiphos-linux-gnueabi"

2
fsfw

@ -1 +1 @@
Subproject commit c1e0bcee6db652d6c474c87a4099e61ecf86b694 Subproject commit 9b77060295c9c32ebfc2e7cf6517eb2e66216191

View File

@ -46,7 +46,8 @@ debugging. */
#define OBSW_ADD_PLOC_SUPERVISOR 0 #define OBSW_ADD_PLOC_SUPERVISOR 0
#define OBSW_ADD_PLOC_MPSOC 0 #define OBSW_ADD_PLOC_MPSOC 0
#define OBSW_ADD_SUN_SENSORS 0 #define OBSW_ADD_SUN_SENSORS 0
#define OBSW_ADD_ACS_BOARD 0 #define OBSW_ADD_ACS_BOARD 1
#define OBSW_ADD_ACS_HANDLERS 0
#define OBSW_ADD_RW 0 #define OBSW_ADD_RW 0
#define OBSW_ADD_RTD_DEVICES 0 #define OBSW_ADD_RTD_DEVICES 0
#define OBSW_ADD_TMP_DEVICES 0 #define OBSW_ADD_TMP_DEVICES 0

View File

@ -435,7 +435,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::RW4, length * 0.8, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::RW4, length * 0.8, DeviceHandlerIF::GET_READ);
#endif #endif
#if OBSW_ADD_ACS_BOARD == 1 #if OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1
bool enableAside = true; bool enableAside = true;
bool enableBside = false; bool enableBside = false;
if (enableAside) { if (enableAside) {
@ -501,7 +501,7 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) {
thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ); thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.75, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ); thisSequence->addSlot(objects::GYRO_3_L3G_HANDLER, length * 0.85, DeviceHandlerIF::GET_READ);
} }
#endif /* OBSW_ADD_ACS_BOARD == 1 */ #endif /* OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1 */
ReturnValue_t seqCheck = thisSequence->checkSequence(); ReturnValue_t seqCheck = thisSequence->checkSequence();
if (seqCheck != HasReturnvaluesIF::RETURN_OK) { if (seqCheck != HasReturnvaluesIF::RETURN_OK) {

View File

@ -273,7 +273,8 @@ ReturnValue_t ACUHandler::initializeLocalDataPool(localpool::DataPool &localData
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
ReturnValue_t ACUHandler::deviceSpecificCommand(DeviceCommandId_t cmd) { ReturnValue_t ACUHandler::childCommandHook(DeviceCommandId_t cmd, const uint8_t *commandData,
size_t commandDataLen) {
switch (cmd) { switch (cmd) {
case PRINT_CHANNEL_STATS: { case PRINT_CHANNEL_STATS: {
printChannelStats(); printChannelStats();

View File

@ -28,7 +28,8 @@ class ACUHandler : public GomspaceDeviceHandler {
virtual void fillCommandAndReplyMap() override; virtual void fillCommandAndReplyMap() override;
virtual ReturnValue_t deviceSpecificCommand(DeviceCommandId_t cmd) override; virtual ReturnValue_t childCommandHook(DeviceCommandId_t cmd, const uint8_t* commandData,
size_t commandDataLen) override;
private: private:
static const DeviceCommandId_t PRINT_CHANNEL_STATS = 51; static const DeviceCommandId_t PRINT_CHANNEL_STATS = 51;

View File

@ -36,7 +36,7 @@ ReturnValue_t GomspaceDeviceHandler::buildTransitionDeviceCommand(DeviceCommandI
ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand, ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData, const uint8_t* commandData,
size_t commandDataLen) { size_t commandDataLen) {
ReturnValue_t result; ReturnValue_t result = childCommandHook(deviceCommand, commandData, commandDataLen);
switch (deviceCommand) { switch (deviceCommand) {
case (GOMSPACE::PING): { case (GOMSPACE::PING): {
result = generatePingCommand(commandData, commandDataLen); result = generatePingCommand(commandData, commandDataLen);
@ -82,7 +82,7 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(DeviceCommandId_t d
break; break;
} }
default: default:
return deviceSpecificCommand(deviceCommand); return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
} }
return HasReturnvaluesIF::RETURN_OK; return HasReturnvaluesIF::RETURN_OK;
} }
@ -170,6 +170,7 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
if (*packet != PARAM_SET_OK) { if (*packet != PARAM_SET_OK) {
return HasReturnvaluesIF::RETURN_FAILED; return HasReturnvaluesIF::RETURN_FAILED;
} }
setParamCallback(setParamCacher, true);
break; break;
} }
case (GOMSPACE::REQUEST_HK_TABLE): { case (GOMSPACE::REQUEST_HK_TABLE): {
@ -186,8 +187,7 @@ void GomspaceDeviceHandler::setNormalDatapoolEntriesInvalid() {}
ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* commandData, ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* commandData,
size_t commandDataLen) { size_t commandDataLen) {
SetParamMessageUnpacker setParamMessageUnpacker; ReturnValue_t result = setParamCacher.deSerialize(&commandData, &commandDataLen,
ReturnValue_t result = setParamMessageUnpacker.deSerialize(&commandData, &commandDataLen,
SerializeIF::Endianness::BIG); SerializeIF::Endianness::BIG);
if (result != HasReturnvaluesIF::RETURN_OK) { if (result != HasReturnvaluesIF::RETURN_OK) {
sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter " sif::error << "GomspaceDeviceHandler: Failed to deserialize set parameter "
@ -195,8 +195,12 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm
<< std::endl; << std::endl;
return result; return result;
} }
result = setParamCallback(setParamCacher, false);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
/* Get and check address */ /* Get and check address */
uint16_t address = setParamMessageUnpacker.getAddress(); uint16_t address = setParamCacher.getAddress();
if (address > maxConfigTableAddress) { if (address > maxConfigTableAddress) {
sif::error << "GomspaceDeviceHandler: Invalid address for set parameter " sif::error << "GomspaceDeviceHandler: Invalid address for set parameter "
<< "action" << std::endl; << "action" << std::endl;
@ -207,8 +211,8 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(const uint8_t* comm
uint16_t total = 0; uint16_t total = 0;
/* CSP reply only contains the transaction state */ /* CSP reply only contains the transaction state */
uint16_t querySize = 1; uint16_t querySize = 1;
const uint8_t* parameterPtr = setParamMessageUnpacker.getParameter(); const uint8_t* parameterPtr = setParamCacher.getParameter();
uint8_t parameterSize = setParamMessageUnpacker.getParameterSize(); uint8_t parameterSize = setParamCacher.getParameterSize();
uint16_t payloadlength = sizeof(address) + parameterSize; uint16_t payloadlength = sizeof(address) + parameterSize;
/* Generate command for CspComIF */ /* Generate command for CspComIF */
@ -335,6 +339,17 @@ void GomspaceDeviceHandler::generateRebootCommand() {
rawPacketLen = cspPacketLen; rawPacketLen = cspPacketLen;
} }
ReturnValue_t GomspaceDeviceHandler::childCommandHook(DeviceCommandId_t cmd,
const uint8_t* commandData,
size_t commandDataLen) {
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
ReturnValue_t GomspaceDeviceHandler::setParamCallback(SetParamMessageUnpacker& unpacker,
bool afterExecution) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() { ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd() {
WatchdogResetCommand watchdogResetCommand; WatchdogResetCommand watchdogResetCommand;
size_t cspPacketLen = 0; size_t cspPacketLen = 0;
@ -386,10 +401,6 @@ LocalPoolDataSetBase* GomspaceDeviceHandler::getDataSetHandle(sid_t sid) {
} }
} }
ReturnValue_t GomspaceDeviceHandler::deviceSpecificCommand(DeviceCommandId_t cmd) {
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
void GomspaceDeviceHandler::setModeNormal() { mode = MODE_NORMAL; } void GomspaceDeviceHandler::setModeNormal() { mode = MODE_NORMAL; }
ReturnValue_t GomspaceDeviceHandler::printStatus(DeviceCommandId_t cmd) { ReturnValue_t GomspaceDeviceHandler::printStatus(DeviceCommandId_t cmd) {

View File

@ -1,6 +1,8 @@
#ifndef MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_ #ifndef MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_
#define MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_ #define MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include "fsfw/devicehandlers/DeviceHandlerBase.h" #include "fsfw/devicehandlers/DeviceHandlerBase.h"
#include "mission/devices/devicedefinitions/GomspaceDefinitions.h" #include "mission/devices/devicedefinitions/GomspaceDefinitions.h"
#include "returnvalues/classIds.h" #include "returnvalues/classIds.h"
@ -101,17 +103,31 @@ class GomspaceDeviceHandler : public DeviceHandlerBase {
virtual LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override; virtual LocalPoolDataSetBase *getDataSetHandle(sid_t sid) override;
/** /**
* @brief Can be used by gomspace devices to implement device specific commands. * @brief Can be overriden by child classes to implement device specific commands.
* @return Return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED to let this handler handle
* the command or RETURN_OK if the child handles the command
*/ */
virtual ReturnValue_t deviceSpecificCommand(DeviceCommandId_t cmd); virtual ReturnValue_t childCommandHook(DeviceCommandId_t cmd, const uint8_t *commandData,
size_t commandDataLen);
private: private:
SetParamMessageUnpacker setParamCacher;
/** /**
* @brief Function to generate the command to set a parameter. Command * @brief Function to generate the command to set a parameter. Command
* will be sent to the ComIF over the rawPacket buffer. * will be sent to the ComIF over the rawPacket buffer.
*/ */
ReturnValue_t generateSetParamCommand(const uint8_t *commandData, size_t commandDataLen); ReturnValue_t generateSetParamCommand(const uint8_t *commandData, size_t commandDataLen);
/**
* Callback is called on a parameter set command. It is called before executing it and after
* after successful execution
* @param unpacker Passed before
* @param beforeSet False for callback before execution, true if called after successful
* execution
* @return
*/
virtual ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExecution);
/** /**
* @brief Function to generate the command to get a parameter from a * @brief Function to generate the command to get a parameter from a
* gomspace device. Command will be sent to the ComIF over the * gomspace device. Command will be sent to the ComIF over the

View File

@ -1,6 +1,7 @@
#include "PDU1Handler.h" #include "PDU1Handler.h"
#include <fsfw/datapool/PoolReadGuard.h> #include <fsfw/datapool/PoolReadGuard.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include "OBSWConfig.h" #include "OBSWConfig.h"
@ -67,6 +68,60 @@ void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pac
#endif #endif
} }
void PDU1Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) {
this->channelSwitchHook = hook;
this->hookArgs = args;
}
ReturnValue_t PDU1Handler::setParamCallback(SetParamMessageUnpacker &unpacker, bool afterExecution) {
using namespace PDU1;
GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU1;
if(not afterExecution) {
return HasReturnvaluesIF::RETURN_OK;
}
if (channelSwitchHook != nullptr and unpacker.getParameterSize() == 1) {
switch (unpacker.getAddress()) {
case (CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3): {
channelSwitchHook(pdu, 0, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_SYRLINKS): {
channelSwitchHook(pdu, 1, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_STAR_TRACKER): {
channelSwitchHook(pdu, 2, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_MGT): {
channelSwitchHook(pdu, 3, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL): {
channelSwitchHook(pdu, 4, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP): {
channelSwitchHook(pdu, 5, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_PLOC): {
channelSwitchHook(pdu, 6, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A): {
channelSwitchHook(pdu, 7, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_CHANNEL8): {
channelSwitchHook(pdu, 8, unpacker.getParameter()[0], hookArgs);
break;
}
}
}
return HasReturnvaluesIF::RETURN_OK;
}
void PDU1Handler::parseHkTableReply(const uint8_t *packet) { void PDU1Handler::parseHkTableReply(const uint8_t *packet) {
uint16_t dataOffset = 0; uint16_t dataOffset = 0;
PoolReadGuard pg(&pdu1HkTableDataset); PoolReadGuard pg(&pdu1HkTableDataset);

View File

@ -27,6 +27,8 @@ class PDU1Handler : public GomspaceDeviceHandler {
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override; LocalDataPoolManager& poolManager) override;
void assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void* args);
protected: protected:
/** /**
* @brief In MODE_NORMAL, a command will be built periodically by this function. * @brief In MODE_NORMAL, a command will be built periodically by this function.
@ -35,9 +37,13 @@ class PDU1Handler : public GomspaceDeviceHandler {
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override; virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
ReturnValue_t printStatus(DeviceCommandId_t cmd) override; ReturnValue_t printStatus(DeviceCommandId_t cmd) override;
ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExectuion) override;
private: private:
/** Dataset for the housekeeping table of the PDU1 */ /** Dataset for the housekeeping table of the PDU1 */
PDU1::PDU1HkTableDataset pdu1HkTableDataset; PDU1::PDU1HkTableDataset pdu1HkTableDataset;
GOMSPACE::ChannelSwitchHook channelSwitchHook = nullptr;
void* hookArgs = nullptr;
void printHkTable(); void printHkTable();
void parseHkTableReply(const uint8_t* packet); void parseHkTableReply(const uint8_t* packet);

View File

@ -49,6 +49,11 @@ void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *pac
#endif #endif
} }
void PDU2Handler::assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void *args) {
this->channelSwitchHook = hook;
this->hookArgs = args;
}
void PDU2Handler::parseHkTableReply(const uint8_t *packet) { void PDU2Handler::parseHkTableReply(const uint8_t *packet) {
uint16_t dataOffset = 0; uint16_t dataOffset = 0;
pdu2HkTableDataset.read(); pdu2HkTableDataset.read();
@ -421,3 +426,52 @@ void PDU2Handler::printHkTable() {
<< std::setw(4) << pdu2HkTableDataset.voltageOutPayloadCamera.value << std::right << std::setw(4) << pdu2HkTableDataset.voltageOutPayloadCamera.value << std::right
<< std::endl; << std::endl;
} }
ReturnValue_t PDU2Handler::setParamCallback(SetParamMessageUnpacker &unpacker, bool afterExecution) {
using namespace PDU2;
GOMSPACE::Pdu pdu = GOMSPACE::Pdu::PDU2;
if(not afterExecution) {
return HasReturnvaluesIF::RETURN_OK;
}
if (channelSwitchHook != nullptr and unpacker.getParameterSize() == 1) {
switch (unpacker.getAddress()) {
case (CONFIG_ADDRESS_OUT_EN_Q7S): {
channelSwitchHook(pdu, 0, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH1): {
channelSwitchHook(pdu, 1, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_RW): {
channelSwitchHook(pdu, 2, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN): {
channelSwitchHook(pdu, 3, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_SUS_REDUNDANT): {
channelSwitchHook(pdu, 4, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM): {
channelSwitchHook(pdu, 5, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6PLOC): {
channelSwitchHook(pdu, 6, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_B): {
channelSwitchHook(pdu, 7, unpacker.getParameter()[0], hookArgs);
break;
}
case (CONFIG_ADDRESS_OUT_EN_PAYLOAD_CAMERA): {
channelSwitchHook(pdu, 8, unpacker.getParameter()[0], hookArgs);
break;
}
}
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -26,6 +26,7 @@ class PDU2Handler : public GomspaceDeviceHandler {
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap, virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override; LocalDataPoolManager& poolManager) override;
void assignChannelHookFunction(GOMSPACE::ChannelSwitchHook hook, void* args);
protected: protected:
/** /**
@ -34,10 +35,13 @@ class PDU2Handler : public GomspaceDeviceHandler {
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override; virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override; virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t* packet) override;
ReturnValue_t printStatus(DeviceCommandId_t cmd) override; ReturnValue_t printStatus(DeviceCommandId_t cmd) override;
ReturnValue_t setParamCallback(SetParamMessageUnpacker& unpacker, bool afterExecution) override;
private: private:
/** Dataset for the housekeeping table of the PDU2 */ /** Dataset for the housekeeping table of the PDU2 */
PDU2::PDU2HkTableDataset pdu2HkTableDataset; PDU2::PDU2HkTableDataset pdu2HkTableDataset;
GOMSPACE::ChannelSwitchHook channelSwitchHook = nullptr;
void* hookArgs = nullptr;
void printHkTable(); void printHkTable();

View File

@ -1,11 +1,3 @@
/*
* GomspaceDefinitions.h
*
* @brief This file holds all definitions specific for devices from gomspace.
* @date 20.12.2020
* @author J. Meier
*/
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEDEFINITIONS_H_ #ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEDEFINITIONS_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEDEFINITIONS_H_ #define MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEDEFINITIONS_H_
@ -16,6 +8,11 @@
#include <cstdint> #include <cstdint>
namespace GOMSPACE { namespace GOMSPACE {
enum class Pdu { PDU1, PDU2 };
using ChannelSwitchHook = void (*)(Pdu pdu, uint8_t channel, bool on, void* args);
static const uint16_t IGNORE_CHECKSUM = 0xbb0; static const uint16_t IGNORE_CHECKSUM = 0xbb0;
/** The size of the header of a gomspace CSP packet. */ /** The size of the header of a gomspace CSP packet. */
static const uint8_t GS_HDR_LENGTH = 12; static const uint8_t GS_HDR_LENGTH = 12;
@ -611,19 +608,32 @@ static const uint8_t HK_TABLE_ENTRIES = 73;
namespace PDU1 { namespace PDU1 {
static const uint32_t HK_TABLE_DATA_SET_ID = 0x1; // hk table has table id 4 static const uint32_t HK_TABLE_DATA_SET_ID = 0x1; // hk table has table id 4
enum SwitchChannels : uint8_t {
TCS_BOARD_3V3 = 0,
SYRLINKS = 1,
STR = 2,
MGT = 3,
SUS_NOMINAL = 4,
SOL_CELL_EXPERIMENT = 5,
PLOC = 6,
ACS_A_SIDE = 7,
UNUSED = 8
};
/** /**
* Addresses within configuration table to enable or disable output channels. Refer also to * Addresses within configuration table to enable or disable output channels. Refer also to
* gs-man-nanopower-p60-pdu-200.pdf on page 16. * gs-man-nanopower-p60-pdu-200.pdf on page 16.
*/ */
static const uint16_t CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3 = 0x48; static const uint16_t CONFIG_ADDRESS_OUT_EN_TCS_BOARD_3V3 = 0x48;
static const uint16_t CONFIG_ADDRESS_OUT_EN_SYRLINKS = 0x49; static const uint16_t CONFIG_ADDRESS_OUT_EN_SYRLINKS = 0x49;
static const uint16_t CONFIG_ADDRESS_OUT_EN_STAR_TRACKER = 0x50; static const uint16_t CONFIG_ADDRESS_OUT_EN_STAR_TRACKER = 0x4A;
static const uint16_t CONFIG_ADDRESS_OUT_EN_MGT = 0x51; static const uint16_t CONFIG_ADDRESS_OUT_EN_MGT = 0x4B;
static const uint16_t CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL = 0x52; static const uint16_t CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL = 0x4C;
static const uint16_t CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP = 0x53; static const uint16_t CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP = 0x4D;
static const uint16_t CONFIG_ADDRESS_OUT_EN_PLOC = 0x54; static const uint16_t CONFIG_ADDRESS_OUT_EN_PLOC = 0x4E;
static const uint16_t CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A = 0x55; static const uint16_t CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A = 0x4F;
static const uint16_t CONFIG_ADDRESS_OUT_EN_CHANNEL8 = 0x56; static const uint16_t CONFIG_ADDRESS_OUT_EN_CHANNEL8 = 0x50;
/** /**
* @brief This class defines a dataset for the hk table of the PDU1. * @brief This class defines a dataset for the hk table of the PDU1.
@ -799,6 +809,19 @@ class PDU1HkTableDataset : public StaticLocalDataSet<PDU::HK_TABLE_ENTRIES> {
namespace PDU2 { namespace PDU2 {
static const uint32_t HK_TABLE_DATA_SET_ID = 0x2; static const uint32_t HK_TABLE_DATA_SET_ID = 0x2;
enum SwitchChannels : uint8_t {
Q7S = 0,
PAYLOAD_PCDU_CH1 = 1,
RW = 2,
TCS_HEATER_IN = 3,
SUS_REDUNDANT = 4,
DEPY_MECHANISM = 5,
PAYLOAD_PCDU_CH6 = 6,
ACS_B_SIDE = 7,
PAYLOAD_CAMERA = 8
};
/** /**
* Addresses within configuration table to enable or disable output channels. Refer also to * Addresses within configuration table to enable or disable output channels. Refer also to
* gs-man-nanopower-p60-pdu-200.pdf on page 16. * gs-man-nanopower-p60-pdu-200.pdf on page 16.

2
tmtc

@ -1 +1 @@
Subproject commit 580ac8b2d7e73aa860f3de55066187d7684d2d64 Subproject commit 6f24d6a83995ca7a895c17a77a00bceac4d7f141