heater handler wip

This commit is contained in:
Jakob Meier 2021-01-28 14:55:21 +01:00
commit 560e538f62
60 changed files with 1934 additions and 774 deletions

View File

@ -44,7 +44,7 @@ set(FSFW_PATH fsfw)
set(MISSION_PATH mission)
set(CSPLIB_PATH libcsp)
set(WARNING_SHADOW_LOCAL FALSE)
set(FSFW_WARNING_SHADOW_LOCAL_GCC OFF)
# Analyse different OS and architecture/target options, determine BSP_PATH,
# display information about compiler etc.
@ -165,11 +165,13 @@ endif()
add_custom_command(
TARGET ${TARGET_NAME}
POST_BUILD
COMMAND echo "Build directory: ${CMAKE_BINARY_DIR}"
COMMAND echo "Target OSAL: ${OS_FSFW}"
COMMAND echo "Target Build Type: ${CMAKE_BUILD_TYPE}"
COMMAND echo "${TARGET_STRING}"
#COMMAND echo "Build directory: ${CMAKE_BINARY_DIR}"
#COMMAND echo "Target OSAL: ${OS_FSFW}"
#COMMAND echo "Target Build Type: ${CMAKE_BUILD_TYPE}"
#COMMAND echo "${TARGET_STRING}"
COMMAND ${CMAKE_SIZE} ${TARGET_NAME}${FILE_SUFFIX}
COMMENT "Build directory: ${CMAKE_BINARY_DIR}\nTarget OSAL: ${OS_FSFW}\n"
"Target Build Type: ${CMAKE_BUILD_TYPE}\n${TARGET_STRING}"
)
include (${CMAKE_SCRIPT_PATH}/BuildType.cmake)

View File

@ -7,19 +7,18 @@
//! Used to determine whether C++ ostreams are used which can increase
//! the binary size significantly. If this is disabled,
//! the C stdio functions can be used alternatively
#define FSFW_CPP_OSTREAM_ENABLED 1
#define FSFW_CPP_OSTREAM_ENABLED 1
//! More FSFW related printouts.
//! Be careful, this also turns off most diagnostic prinouts!
#define FSFW_ENHANCED_PRINTOUT 0
//! More FSFW related printouts depending on level. Useful for development.
#define FSFW_VERBOSE_LEVEL 1
//! Can be used to completely disable printouts, even the C stdio ones.
#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_ENHANCED_PRINTOUT == 0
#define FSFW_DISABLE_PRINTOUT 0
#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0
#define FSFW_DISABLE_PRINTOUT 0
#endif
//! Can be used to enable additional debugging printouts for developing the FSFW
#define FSFW_PRINT_VERBOSITY_LEVEL 0
//! Can be used to disable the ANSI color sequences for C stdio.
#define FSFW_COLORED_OUTPUT 1
//! Can be used to disable the ANSI color sequences for C stdio.
#define FSFW_COLORED_OUTPUT 1

View File

@ -6,6 +6,7 @@ target_sources(${TARGET_NAME} PUBLIC
add_subdirectory(boardconfig)
add_subdirectory(comIF)
add_subdirectory(gpio)

View File

@ -13,7 +13,11 @@
#include <fsfw/osal/linux/TcUnixUdpPollingTask.h>
#include <mission/core/GenericFactory.h>
#include <mission/devices/GomspaceDeviceHandler.h>
#include <mission/devices/PDU1Handler.h>
#include <mission/devices/PDU2Handler.h>
#include <mission/devices/ACUHandler.h>
#include <mission/devices/PCDUHandler.h>
#include <mission/devices/P60DockHandler.h>
#include <mission/devices/Tmp1075Handler.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
@ -58,28 +62,35 @@ void ObjectFactory::produce(){
addresses::PDU2);
CspCookie* acuCspCookie = new CspCookie(ACU::MAX_REPLY_LENGTH,
addresses::ACU);
#if TE0720 == 1
I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0"));
I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-0"));
#else
I2cCookie* i2cCookieTmp1075tcs1 = new I2cCookie(addresses::TMP1075_TCS_1,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-1"));
I2cCookie* i2cCookieTmp1075tcs2 = new I2cCookie(addresses::TMP1075_TCS_2,
TMP1075::MAX_REPLY_LENGTH, std::string("/dev/i2c-1"));
#endif
/* Communication interfaces */
new CspComIF(objects::CSP_COM_IF);
new I2cComIF(objects::I2C_COM_IF);
/* Device Handler */
new GomspaceDeviceHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF,
new P60DockHandler(objects::P60DOCK_HANDLER, objects::CSP_COM_IF,
p60DockCspCookie, P60Dock::MAX_CONFIGTABLE_ADDRESS,
P60Dock::MAX_HKTABLE_ADDRESS);
new GomspaceDeviceHandler(objects::PDU1_HANDLER, objects::CSP_COM_IF,
P60Dock::MAX_HKTABLE_ADDRESS, P60Dock::HK_TABLE_SIZE);
new PDU1Handler(objects::PDU1_HANDLER, objects::CSP_COM_IF,
pdu1CspCookie, PDU::MAX_CONFIGTABLE_ADDRESS,
PDU::MAX_HKTABLE_ADDRESS);
new GomspaceDeviceHandler(objects::PDU2_HANDLER, objects::CSP_COM_IF,
PDU::MAX_HKTABLE_ADDRESS, PDU::HK_TABLE_SIZE);
new PDU2Handler(objects::PDU2_HANDLER, objects::CSP_COM_IF,
pdu2CspCookie, PDU::MAX_CONFIGTABLE_ADDRESS,
PDU::MAX_HKTABLE_ADDRESS);
new GomspaceDeviceHandler(objects::ACU_HANDLER, objects::CSP_COM_IF,
PDU::MAX_HKTABLE_ADDRESS, PDU::HK_TABLE_SIZE);
new ACUHandler(objects::ACU_HANDLER, objects::CSP_COM_IF,
acuCspCookie, ACU::MAX_CONFIGTABLE_ADDRESS,
ACU::MAX_HKTABLE_ADDRESS);
ACU::MAX_HKTABLE_ADDRESS, ACU::HK_TABLE_SIZE);
new PCDUHandler(objects::PCDU_HANDLER);
/* Temperature sensors */
Tmp1075Handler* tmp1075Handler_1 = new Tmp1075Handler(
objects::TMP1075_HANDLER_1, objects::I2C_COM_IF,
@ -95,13 +106,15 @@ void ObjectFactory::produce(){
#if TE0720 == 1
// Configuration for MIO0 on TE0720-03-1CFA
GpioConfig_t gpioConfigForDummyHeater(std::string("gpiochip0"), 0,
std::string("Heater1"), Gpio::OUT);
gpioCookie.add(gpioIds::HEATER_1, gpioConfigForDummyHeater);
std::string("Heater0"), Gpio::OUT);
gpioCookie.add(gpioIds::HEATER_0, gpioConfigForDummyHeater);
#else
GpioConfig_t gpioConfigHeater0(std::string("gpiochip5"), 6,
std::string("Heater0"), Gpio::OUT);
gpioCookie.add(gpioIds::HEATER_0, gpioConfigHeater0);
#endif
LinuxLibgpioIF linuxLibgpioIF = new LinuxLibgpioIF(objects::GPIO_IF);
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, );
new HeaterHandler(objects::HEATER_HANDLER, objects::GPIO_IF, gpioCookie);
new TmTcUnixUdpBridge(objects::UDP_BRIDGE,
objects::CCSDS_PACKET_DISTRIBUTOR,

View File

@ -1,268 +0,0 @@
#include <bsp_q7s/comIF/GpioComIF.h>
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fcntl.h>
#include <string.h>
GpioComIF::GpioComIF(object_id_t objectId): SystemObject(objectId){
}
GpioComIF::~GpioComIF() {}
ReturnValue_t GpioComIF::initializeInterface(CookieIF * cookie) {
ReturnValue_t result;
GpioMap mapToAdd;
if(cookie == nullptr) {
return NULLPOINTER;
}
GpioCookie* GpioCookie = dynamic_cast<GpioCookie*>(cookie);
if(GpioCookie == nullptr) {
sif::error << "GpioComIF: Invalid Gpio Cookie!"
<< std::endl;
return NULLPOINTER;
}
mapToAdd = GpioCookie->getGpioMap();
result = checkForConflicts(mapToAdd);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
/* Register new GPIOs in gpioMap*/
std::pair insertionResult = gpioMap.insert(mapToAdd.begin(),
mapToAdd.end());
if (insertionResult.second() != true) {
sif::error << "GpioComIF::initializeAndConfigure: Failed to add "
<< "GPIO " << gpioStr.c_st() << " to gpioMap" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::sendMessage(CookieIF *cookie,
const uint8_t *sendData, size_t sendLen) {
ReturnValue_t result;
int fd;
std::string deviceFile;
if(sendData == nullptr) {
sif::error << "GpioComIF::sendMessage: Send Data is nullptr"
<< std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
if(sendLen == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
I2cCookie* i2cCookie = dynamic_cast<I2cCookie*>(cookie);
if(i2cCookie == nullptr) {
sif::error << "GpioComIF::sendMessasge: Invalid I2C Cookie!"
<< std::endl;
return NULLPOINTER;
}
address_t i2cAddress = i2cCookie->getAddress();
i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
sif::error << "GpioComIF::sendMessage: i2cAddress of Cookie not "
<< "registered in i2cDeviceMap" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
deviceFile = i2cCookie->getDeviceFile();
result = openDevice(deviceFile, i2cAddress, &fd);
if (result != HasReturnvaluesIF::RETURN_OK){
return result;
}
if (write(fd, sendData, sendLen) != (int)sendLen) {
sif::error << "GpioComIF::sendMessage: Failed to send data to I2C "
"device with error code " << errno << ". Error description: "
<< strerror(errno) << std::endl;
close(fd);
return HasReturnvaluesIF::RETURN_FAILED;
}
close(fd);
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::getSendSuccess(CookieIF *cookie) {
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::requestReceiveMessage(CookieIF *cookie,
size_t requestLen) {
ReturnValue_t result;
int fd;
std::string deviceFile;
if (requestLen == 0) {
return HasReturnvaluesIF::RETURN_OK;
}
I2cCookie* i2cCookie = dynamic_cast<I2cCookie*>(cookie);
if(i2cCookie == nullptr) {
sif::error << "GpioComIF::requestReceiveMessage: Invalid I2C Cookie!"
<< std::endl;
i2cDeviceMapIter->second.replyLen = 0;
return NULLPOINTER;
}
address_t i2cAddress = i2cCookie->getAddress();
i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
sif::error << "GpioComIF::requestReceiveMessage: i2cAddress of Cookie not "
<< "registered in i2cDeviceMap" << std::endl;
i2cDeviceMapIter->second.replyLen = 0;
return HasReturnvaluesIF::RETURN_FAILED;
}
deviceFile = i2cCookie->getDeviceFile();
result = openDevice(deviceFile, i2cAddress, &fd);
if (result != HasReturnvaluesIF::RETURN_OK){
i2cDeviceMapIter->second.replyLen = 0;
return result;
}
uint8_t* replyBuffer = i2cDeviceMapIter->second.replyBuffer.data();
if (read(fd, replyBuffer, requestLen) != (int)requestLen) {
sif::error << "GpioComIF::requestReceiveMessage: Reading from I2C "
<< "device failed with error code " << errno <<". Description"
<< " of error: " << strerror(errno) << std::endl;
close(fd);
i2cDeviceMapIter->second.replyLen = 0;
return HasReturnvaluesIF::RETURN_FAILED;
}
i2cDeviceMapIter->second.replyLen = requestLen;
close(fd);
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::readReceivedMessage(CookieIF *cookie,
uint8_t **buffer, size_t* size) {
I2cCookie* i2cCookie = dynamic_cast<I2cCookie*>(cookie);
if(i2cCookie == nullptr) {
sif::error << "GpioComIF::readReceivedMessage: Invalid I2C Cookie!"
<< std::endl;
return NULLPOINTER;
}
address_t i2cAddress = i2cCookie->getAddress();
i2cDeviceMapIter = i2cDeviceMap.find(i2cAddress);
if (i2cDeviceMapIter == i2cDeviceMap.end()) {
sif::error << "GpioComIF::readReceivedMessage: i2cAddress of Cookie not "
<< "found in i2cDeviceMap" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
*buffer = i2cDeviceMapIter->second.replyBuffer.data();
*size = i2cDeviceMapIter->second.replyLen;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::openDevice(std::string deviceFile,
address_t i2cAddress, int* fileDescriptor) {
*fileDescriptor = open(deviceFile.c_str(), O_RDWR);
if (*fileDescriptor < 0) {
sif::error << "GpioComIF: Opening i2c device failed with error code "
<< errno << ". Error description: " << strerror(errno)
<< std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
if (ioctl(*fileDescriptor, I2C_SLAVE, i2cAddress) < 0) {
sif::error << "GpioComIF: Specifying target device failed with error "
<< "code " << errno << ". Error description "
<< strerror(errno) << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::checkForConflicts(GpioMap mapToAdd){
gpioId_t gpioId;
GpioMapIter mapToAddIter = mapToAdd.begin();
for(; mapToAddIter != mapToAdd.end(); mapToAddIter++){
gpio = mapToAddIter.first();
if(gpioMapIter.find(gpioId) != mapToAdd.end()){
/* An entry for this GPIO already exists. Check if configuration
* of direction is equivalent */
if (mapToAddIter.second.direction != gpioMapIter.second.direction){
sif::error << "GpioComIF::checkForConflicts: Detected conflict "
<< "for GPIO " << mapToAddIter.first() << std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
/* Remove element from map to add because a entry for this GPIO
* already exists */
mapToAdd.erase(mapToAddIter);
}
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GpioComIF::initializeAndConfigure(GpioMap mapToAdd){
int exportfd;
int directionfd;
std::string gpioStr;
GpioMapIter mapToAddItr;
mapToAddItr = mapToAdd.begin();
/* Perform initialization for all GPIOs in map */
for(; mapToAddItr != mapToAdd.end(); mapToAddItr++){
/* The GPIO has to be exported to be able to see it in sysfs */
exportfd = open("/sys/class/gpio/export", O_WRONLY);
if (exportfd < 0)
{
sif::error << "GpioComIF::initializeAndConfigure: Cannot open GPIO "
<< mapToAddItr.first() << " to export it" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
gpioStr = std::to_string(mapToAddItr.first());
write(exportfd, gpioStr.c_str(), gpioStr.length() + 1);
close(exportfd);
/* Set direction of the GPIO */
std::string directionPath = "/sys/class/gpio/" + gpioStr +
"/direction";
directionfd = open(directionPath.c_str(), O_RDWR);
if (directionfd < 0)
{
sif::error << "Cannot open " << directionPath.c_str() << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
if (mapToAdd.second() == Gpio::IN) {
write(directionfd, "in", 3);
}
else if (mapToAdd.second() == Gpio::OUT) {
write(directionfd, "out", 4);
}
else {
sif::error << "GpioComIF::initializeAndConfigure: Invalid direction"
<< " specified" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
close(directionfd);
/* Add GPIO to GpioMap of GpioComIF */
std::pair insertionResult = gpioMap.insert(mapToAddItr);
if (insertionResult.second() != true) {
sif::error << "GpioComIF::initializeAndConfigure: Failed to add "
<< "GPIO " << gpioStr.c_st() << " to gpioMap" << std::endl;
return HasReturnvaluesIF::RETURN_FAILED;
}
}
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,57 +0,0 @@
#ifndef BSP_Q7S_COMIF_I2s COMIF_H_
#define BSP_Q7S_COMIF_I2COMIF_H_
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <bsp_q7s/comIF/cookies/GpioCookie.h>
/**
* @brief This is the communication interface to drive GPIOs by using the
* the linux sysfs.
*
* @author J. Meier
*/
class GpioComIF: public DeviceCommunicationIF, public SystemObject {
public:
GpioComIF(object_id_t objectId);
virtual ~GpioComIF();
ReturnValue_t initializeInterface(CookieIF * cookie) override;
ReturnValue_t sendMessage(CookieIF *cookie,const uint8_t *sendData,
size_t sendLen) override;
ReturnValue_t getSendSuccess(CookieIF *cookie) override;
ReturnValue_t requestReceiveMessage(CookieIF *cookie,
size_t requestLen) override;
ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer,
size_t *size) override;
private:
/* All GPIOs will be stored in this map after successful initialization */
GpioMap gpioMap;
GpioMapIter gpioMapIter;
/**
* @brief This function checks if GPIOs are already registered and whether
* there exists a conflict in the GPIO configuration. E.g. the
* direction.
*
* @param mapToAdd The GPIOs which shall be added to the gpioMap
*
* @return RETURN_OK if successful, otherwise RETURN_FAILED
*/
ReturnValue_t checkForConflicts(GpioMap mapToAdd);
/**
* @brief This function initializes all GPIOs specified in the mapToAdd.
*
* @param Map with the GPIOs to initialize.
*
* @return RETURN_OK if successful, otherwise RETURN_FAILED
*/
ReturnValue_t GpioComIF::initializeAndConfigure(GpioMap mapToAdd);
};
#endif /* BSP_Q7S_COMIF_I2COMIF_H_ */

View File

@ -0,0 +1,6 @@
target_sources(${TARGET_NAME} PUBLIC
cookies/GpioCookie.cpp
LinuxLibgpioIF.cpp
)

View File

@ -1,18 +0,0 @@
/*
* GpioIF.cpp
*
* Created on: 16.01.2021
* Author: jakob
*/
#include "GpioIF.h"
GpioIF::GpioIF() {
// TODO Auto-generated constructor stub
}
GpioIF::~GpioIF() {
// TODO Auto-generated destructor stub
}

View File

@ -13,7 +13,7 @@ typedef uint16_t gpioId_t;
*/
class GpioIF : public HasReturnvaluesIF{
public:
GpioIF();
virtual ~GpioIF();
/**

View File

@ -3,6 +3,7 @@
#include <bsp_q7s/gpio/GpioIF.h>
#include <fsfwconfig/returnvalues/classIds.h>
#include <bsp_q7s/gpio/cookies/GpioCookie.h>
/**
* @brief This class implements the GpioIF for a linux based system. The

View File

@ -10,7 +10,6 @@ void GpioCookie::addGpio(GpioMap newEntry){
if (status.second == false) {
sif::error << "GpioCookie::addGpio: Failed to add GPIO "
<< newEntry.first << "to GPIO map" << std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
}
else {

View File

@ -1,8 +1,9 @@
#ifndef SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_
#define SAM9G20_COMIF_COOKIES_I2C_COOKIE_H_
#ifndef SAM9G20_COMIF_COOKIES_GPIO_COOKIE_H_
#define SAM9G20_COMIF_COOKIES_GPIO_COOKIE_H_
#include <fsfw/devicehandlers/CookieIF.h>
#include <bsp_q7s/gpio/GpioIF.h>
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
#include <string>
namespace Gpio {

View File

@ -7,6 +7,11 @@ target_sources(${TARGET_NAME} PUBLIC
add_subdirectory(boardconfig)
add_subdirectory(boardtest)
# wiringPi is deprecated unfortunately..
#target_link_libraries(${TARGET_NAME} PRIVATE
# wiringPi
#)

View File

@ -14,18 +14,10 @@
#include <iostream>
// This is configured for linux without \cr
#ifdef LINUX
ServiceInterfaceStream sif::debug("DEBUG");
ServiceInterfaceStream sif::info("INFO");
ServiceInterfaceStream sif::warning("WARNING");
ServiceInterfaceStream sif::error("ERROR", false, false, true);
#else
ServiceInterfaceStream sif::debug("DEBUG", true);
ServiceInterfaceStream sif::info("INFO", true);
ServiceInterfaceStream sif::warning("WARNING", true);
ServiceInterfaceStream sif::error("ERROR", true, false, true);
#endif
ServiceInterfaceStream sif::error("ERROR");
ObjectManagerIF *objectManager = nullptr;
@ -47,11 +39,11 @@ void InitMission::initTasks(){
0.100, nullptr);
ReturnValue_t result = TmTcDistributor->addComponent(
objects::CCSDS_PACKET_DISTRIBUTOR);
if(result!=HasReturnvaluesIF::RETURN_OK){
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = TmTcDistributor->addComponent(objects::PUS_PACKET_DISTRIBUTOR);
if(result!=HasReturnvaluesIF::RETURN_OK){
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = TmTcDistributor->addComponent(objects::TM_FUNNEL);
@ -97,11 +89,11 @@ void InitMission::initTasks(){
PeriodicTaskIF::MINIMUM_STACK_SIZE,
0.200, nullptr);
result = PusHighPrio->addComponent(objects::PUS_SERVICE_2_DEVICE_ACCESS);
if(result!=HasReturnvaluesIF::RETURN_OK){
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = PusHighPrio->addComponent(objects::PUS_SERVICE_9_TIME_MGMT);
if(result!=HasReturnvaluesIF::RETURN_OK){
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
@ -110,11 +102,11 @@ void InitMission::initTasks(){
PeriodicTaskIF::MINIMUM_STACK_SIZE,
0.8, nullptr);
result = PusMedPrio->addComponent(objects::PUS_SERVICE_8_FUNCTION_MGMT);
if(result!=HasReturnvaluesIF::RETURN_OK){
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
result = PusMedPrio->addComponent(objects::PUS_SERVICE_200_MODE_MGMT);
if(result!=HasReturnvaluesIF::RETURN_OK){
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
@ -122,7 +114,7 @@ void InitMission::initTasks(){
createPeriodicTask("PUSB", 30, PeriodicTaskIF::MINIMUM_STACK_SIZE,
1.6, nullptr);
result = PusLowPrio->addComponent(objects::PUS_SERVICE_17_TEST);
if(result!=HasReturnvaluesIF::RETURN_OK){
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add component failed" << std::endl;
}
@ -139,6 +131,14 @@ void InitMission::initTasks(){
#endif
PeriodicTaskIF* SpiTestTask = TaskFactory::instance()->
createPeriodicTask("SPI_TEST", 40, PeriodicTaskIF::MINIMUM_STACK_SIZE,
2.0, nullptr);
result = SpiTestTask->addComponent(objects::SPI_TEST);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "Object add SPI test failed" << std::endl;
}
//Main thread sleep
sif::info << "Starting tasks.." << std::endl;
TmTcDistributor->startTask();
@ -151,6 +151,8 @@ void InitMission::initTasks(){
PusMedPrio->startTask();
PusLowPrio->startTask();
SpiTestTask->startTask();
#if OBSW_ADD_TEST_CODE == 1
TestTimeslotTask->startTask();
#endif

View File

@ -1,5 +1,6 @@
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
#include "ObjectFactory.h"
#include <bsp_rpi/boardtest/SpiTest.h>
#include <fsfw/datapoollocal/LocalDataPoolManager.h>
#include <objects/systemObjectList.h>
#include <OBSWConfig.h>
@ -42,4 +43,6 @@ void ObjectFactory::produce(){
objects::CCSDS_PACKET_DISTRIBUTOR,
objects::TM_STORE, objects::TC_STORE);
new TcUnixUdpPollingTask(objects::UDP_POLLING_TASK, objects::UDP_BRIDGE);
new SpiTest(objects::SPI_TEST);
}

View File

@ -1,5 +1,6 @@
target_sources(${TARGET_NAME} PRIVATE
SpiTest.cpp
RPiGPIO.cpp
)

View File

@ -0,0 +1,123 @@
#include "RPiGPIO.h"
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <cstdint>
int RPiGPIO::enablePin(int pin) {
char buffer[BUFFER_MAX];
ssize_t bytes_written;
int fd;
fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd == -1) {
sif::error << "Failed to open export of pin " << pin << " for writing!" << std::endl;
return -1;
}
bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
write(fd, buffer, bytes_written);
close(fd);
return 0;
}
int RPiGPIO::disablePin(int pin) {
char buffer[BUFFER_MAX];
ssize_t bytes_written;
int fd;
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (fd == -1) {
sif::error << "Failed to open unexport of pin " << pin << " for writing!" << std::endl;
return -1;
}
bytes_written = snprintf(buffer, BUFFER_MAX, "%d", pin);
write(fd, buffer, bytes_written);
close(fd);
return(0);
}
int RPiGPIO::pinDirection(int pin, Directions dir) {
char path[DIRECTION_MAX];
snprintf(path, DIRECTION_MAX, "/sys/class/gpio/gpio%d/direction", pin);
int fd = open(path, O_WRONLY);
if (fd == -1) {
sif::error << "Failed to open gpio " << pin << " direction for writing!" << std::endl;
return -1;
}
int result = 0;
if(dir == Directions::IN) {
result = write(fd, "in", IN_WRITE_SIZE);
}
else {
result = write(fd, "out", OUT_WRITE_SIZE);
}
if (result != 0) {
sif::error << "Failed to set direction!" << std::endl;
return -2;
}
close(fd);
return 0;
}
int RPiGPIO::readPin(int pin) {
char path[VALUE_MAX];
char value_str[3];
snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
int fd = open(path, O_RDONLY);
if (fd == -1) {
sif::error << "RPiGPIO::readPin: Failed to open GPIO pin " << pin << "!" << std::endl;
return -1;
}
if (read(fd, value_str, 3) == -1) {
sif::error << "Failed to read value!" << std::endl;
return -1;
}
close(fd);
char* endPtr = nullptr;
return strtol(value_str, &endPtr, 10);
}
int RPiGPIO::writePin(int pin, States state) {
char path[VALUE_MAX];
int fd;
snprintf(path, VALUE_MAX, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_WRONLY);
if (fd == -1) {
sif::error << "RPiGPIO::writePin: Failed to open GPIO pin " << pin << "!" << std::endl;
return -1;
}
int result = 0;
if(state == States::LOW) {
result = write(fd, "0", 1);
}
else {
result = write(fd, "1", 1);
}
if (result != 0) {
sif::error << "Failed to write pin " << pin << " value to " << static_cast<int>(state)
<< "!" << std::endl;
return -1;
}
close(fd);
return 0;
}

View File

@ -0,0 +1,41 @@
#ifndef BSP_RPI_BOARDTEST_RPIGPIO_H_
#define BSP_RPI_BOARDTEST_RPIGPIO_H_
#include <cstdint>
/**
* @brief Really simple C++ GPIO wrapper for the Raspberry Pi, using the sysfs interface.
* Use BCM pins notation (https://pinout.xyz/#)
*
*/
class RPiGPIO {
public:
enum Directions {
IN = 0,
OUT = 1
};
enum States {
LOW = 0,
HIGH = 1
};
static int enablePin(int pin);
static int disablePin(int pin);
static int pinDirection(int pin, Directions dir);
static int readPin(int pin);
static int writePin(int pin, States state);
private:
static constexpr uint8_t BUFFER_MAX = 3;
static constexpr uint8_t DIRECTION_MAX = 35;
static constexpr uint8_t VALUE_MAX = 30;
static constexpr uint8_t IN_WRITE_SIZE = 3;
static constexpr uint8_t OUT_WRITE_SIZE = 4;
};
#endif /* BSP_RPI_BOARDTEST_RPIGPIO_H_ */

View File

@ -1,13 +1,31 @@
#include "SpiTest.h"
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
#include <fsfw/serviceinterface/ServiceInterface.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <wiringPi.h>
SpiTest::SpiTest(object_id_t objectId): SystemObject(objectId) {
wiringPiSetupGpio();
sif::info << "Setting up Raspberry Pi WiringPi library." << std::endl;
// wiringPiSetupGpio();
// pinMode(SS_MGM_0_LIS3, OUTPUT);
// pinMode(SS_MGM_1_RM, OUTPUT);
// pinMode(SS_GYRO_0_ADIS, OUTPUT);
// pinMode(SS_GYRO_1_L3G, OUTPUT);
// pinMode(SS_GYRO_2_L3G, OUTPUT);
// pinMode(SS_MGM_2_LIS3, OUTPUT);
// pinMode(SS_MGM_3_RM, OUTPUT);
//
// digitalWrite(SS_MGM_0_LIS3, HIGH);
// digitalWrite(SS_MGM_1_RM, HIGH);
// digitalWrite(SS_GYRO_0_ADIS, HIGH);
// digitalWrite(SS_GYRO_1_L3G, HIGH);
// digitalWrite(SS_GYRO_2_L3G, HIGH);
// digitalWrite(SS_MGM_2_LIS3, HIGH);
// digitalWrite(SS_MGM_3_RM, HIGH);
int spiFd = open(spiDeviceName.c_str(), O_RDWR);
if (spiFd < 0){

View File

@ -6,13 +6,27 @@
#include <linux/spi/spidev.h>
#include <string>
class SpiTest: public ExecutableObjectIF, SystemObject {
class SpiTest:
public SystemObject,
public ExecutableObjectIF {
public:
SpiTest(object_id_t objectId);
ReturnValue_t performOperation(uint8_t opCode) override;
ReturnValue_t initialize() override;
private:
// These chip selects (BCM number) will be pulled high if not used
// ACS board specific.
enum SpiChipSelects {
SS_MGM_0_LIS3 = 0, //!< MGM 0, LIS3MDLTR, U6, A side
SS_MGM_1_RM = 1, //!< MGM 1, RM3100, U7, A side
SS_GYRO_0_ADIS = 2, //!< Gyro 0, ADIS16485, U3, A side
SS_GYRO_1_L3G = 3, //!< Gyro 1, L3GD20H, U4, A side
SS_GYRO_2_L3G = 4, //!< Gyro 2, L3GD20h, U5, B side
SS_MGM_2_LIS3 = 17, //!< MGM 2, LIS3MDLTR, U8, B side
SS_MGM_3_RM = 27, //!< MGM 3, RM3100, U9, B side
};
const std::string spiDeviceName = "/dev/spidev0.0";
int spiFd = 0;

View File

@ -55,8 +55,8 @@ target_compile_options(${TARGET_NAME} PRIVATE
add_custom_command(
TARGET ${TARGET_NAME}
POST_BUILD
COMMAND echo Generating binary file ${CMAKE_PROJECT_NAME}.bin..
COMMAND ${CMAKE_OBJCOPY} -O binary ${TARGET_NAME} ${TARGET_NAME}.bin
COMMENT "Generating binary file ${CMAKE_PROJECT_NAME}.bin.."
)
endfunction()

View File

@ -19,15 +19,15 @@ if(${OS_FSFW} STREQUAL linux AND TGT_BSP)
)
elseif (${TGT_BSP} MATCHES "arm/raspberrypi")
if(NOT DEFINED ENV{RASPBIAN_ROOTFS})
if(NOT RASPBIAN_ROOTFS)
if(NOT DEFINED RASPBIAN_ROOTFS)
message(WARNING "No RASPBIAN_ROOTFS environmental or CMake variable set!")
set(ENV{RASPBIAN_ROOTFS} "$ENV{HOME}/raspberrypi/rootfs")
else()
set(ENV{RASPBIAN_ROOTFS} "${RASPBIAN_ROOTFS}")
endif()
else()
message(STATUS
"RASPBIAN_ROOTFS from environmental variables used: "
"$ENV{RASPBIAN_ROOTFS}"
"RASPBIAN_ROOTFS from environmental variables used: $ENV{RASPBIAN_ROOTFS}"
)
endif()
@ -36,12 +36,8 @@ if(${OS_FSFW} STREQUAL linux AND TGT_BSP)
message(STATUS "No RASPBERRY_VERSION specified, setting to 4")
set(RASPBERRY_VERSION "4" CACHE STRING "Raspberry Pi version")
else()
message(STATUS
"Setting RASPBERRY_VERSION to ${RASPBERRY_VERSION}"
)
set(RASPBERRY_VERSION
${RASPBERRY_VERSION} CACHE STRING "Raspberry Pi version"
)
message(STATUS "Setting RASPBERRY_VERSION to ${RASPBERRY_VERSION}")
set(RASPBERRY_VERSION ${RASPBERRY_VERSION} CACHE STRING "Raspberry Pi version")
set(ENV{RASPBERRY_VERSION} ${RASPBERRY_VERSION})
endif()
else()

2
fsfw

@ -1 +1 @@
Subproject commit bd5cc7ae3ea53040cc832b5d756846d21613d91a
Subproject commit 41c0436e29f7a75f737f75e963dc2119a64a3921

View File

@ -7,19 +7,18 @@
//! Used to determine whether C++ ostreams are used which can increase
//! the binary size significantly. If this is disabled,
//! the C stdio functions can be used alternatively
#define FSFW_CPP_OSTREAM_ENABLED 1
#define FSFW_CPP_OSTREAM_ENABLED 1
//! More FSFW related printouts.
//! Be careful, this also turns off most diagnostic prinouts!
#define FSFW_ENHANCED_PRINTOUT 0
//! More FSFW related printouts depending on level. Useful for development.
#define FSFW_VERBOSE_LEVEL 1
//! Can be used to completely disable printouts, even the C stdio ones.
#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_ENHANCED_PRINTOUT == 0
#define FSFW_DISABLE_PRINTOUT 0
#if FSFW_CPP_OSTREAM_ENABLED == 0 && FSFW_VERBOSE_LEVEL == 0
#define FSFW_DISABLE_PRINTOUT 0
#endif
//! Can be used to enable additional debugging printouts for developing the FSFW
#define FSFW_PRINT_VERBOSITY_LEVEL 0
//! Can be used to disable the ANSI color sequences for C stdio.
#define FSFW_COLORED_OUTPUT 1
//! Can be used to disable the ANSI color sequences for C stdio.
#define FSFW_COLORED_OUTPUT 1

View File

@ -12,7 +12,7 @@
// debugging.
#define OBSW_ENHANCED_PRINTOUT 1
#define TE0720 1
#define TE0720 0
#include "OBSWVersion.h"

View File

@ -5,7 +5,7 @@
namespace gpioIds {
enum gpioId_t {
HEATER_1
HEATER_0
};
}

View File

@ -0,0 +1,13 @@
#ifndef FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_
#define FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_
namespace heaterSwitches {
enum switcherList {
PAYLOAD_CAMERA,
NUMBER_OF_SWITCHES
};
}
#endif /* FSFWCONFIG_DEVICES_HEATERSWITCHERLIST_H_ */

View File

@ -1,4 +0,0 @@
#include <fsfwconfig/devices/powerSwitcherList.h>

View File

@ -18,7 +18,8 @@ enum: uint8_t {
PUS_SERVICE_8,
PUS_SERVICE_23,
MGM_LIS3MDL,
MGM_RM3100
MGM_RM3100,
PCDU_HANDLER
};
}

View File

@ -2,10 +2,15 @@
#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
#include <cstdint>
#include <fsfw/objectmanager/frameworkObjects.h>
// The objects will be instantiated in the ID order
namespace objects {
enum sourceObjects: uint32_t {
/* 0x53 reserved for FSFW */
FW_ADDRESS_START = PUS_SERVICE_1_VERIFICATION,
FW_ADDRESS_END = TIME_STAMPER,
/* First Byte 0x50-0x52 reserved for PUS Services **/
CCSDS_PACKET_DISTRIBUTOR = 0x50000100,
PUS_PACKET_DISTRIBUTOR = 0x50000200,
@ -21,19 +26,13 @@ namespace objects {
TM_FUNNEL = 0x52000002,
/* Test Task */
TEST_TASK = 0x42694269,
DUMMY_INTERFACE = 0xCAFECAFE,
DUMMY_HANDLER = 0x4400AFFE,
P60DOCK_TEST_TASK = 0x00005060,
/* 0x49 ('I') for Communication Interfaces **/
ARDUINO_COM_IF = 0x49000001,
CSP_COM_IF = 0x49000002,
I2C_COM_IF = 0x49000003,
/* 0x47 ('G') for Gpio Interfaces */
GPIO_IF = 0x470000001,
GPIO_IF = 0x47000001,
/* 0x44 ('D') for device handlers */
P60DOCK_HANDLER = 0x44000001,
@ -43,8 +42,18 @@ namespace objects {
TMP1075_HANDLER_1 = 0x44000005,
TMP1075_HANDLER_2 = 0x44000006,
/* Custom device handler */
PCDU_HANDLER = 0x45000001,
/* 0x54 ('T') for thermal objects */
HEATER_HANDLER = 0x54000001
HEATER_HANDLER = 0x54000001,
/* 0x54 ('T') for test handlers */
TEST_TASK = 0x54694269,
SPI_TEST = 0x54000010,
DUMMY_INTERFACE = 0x5400CAFE,
DUMMY_HANDLER = 0x5400AFFE,
P60DOCK_TEST_TASK = 0x00005060
};
}

View File

@ -10,26 +10,24 @@ ReturnValue_t pst::pollingSequenceInitDefault(FixedTimeslotTaskIF *thisSequence)
/* Length of a communication cycle */
uint32_t length = thisSequence->getPeriodMs();
thisSequence->addSlot(objects::TMP1075_HANDLER_1,
length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TMP1075_HANDLER_2,
length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TMP1075_HANDLER_1,
length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_2,
length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_1,
length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_2,
length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_1,
length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_2,
length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_1,
length * 0.8, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_2,
length * 0.8, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0,
DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::PCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::HEATER_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::SEND_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.4, DeviceHandlerIF::GET_WRITE);
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.6, DeviceHandlerIF::SEND_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.8, DeviceHandlerIF::GET_READ);
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.8, DeviceHandlerIF::GET_READ);
if (thisSequence->checkSequence() == HasReturnvaluesIF::RETURN_OK) {
return HasReturnvaluesIF::RETURN_OK;

View File

@ -13,7 +13,8 @@ enum {
MISSION_CLASS_ID_START = FW_CLASS_ID_COUNT,
MGM_LIS3MDL,
MGM_RM3100,
LINUX_LIBGPIO_IF
LINUX_LIBGPIO_IF,
PCDU_HANDLER
};
}

View File

@ -795,69 +795,51 @@
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="eive_obsw.null.1109622296" name="eive_obsw"/>
<project id="eive_obsw.null.1062489770" name="eive_obsw"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="refreshScope" versionNumber="2">
<configuration configurationName="eive-linux-host-debug"/>
<configuration configurationName="eive-q7s-release-win">
<configuration configurationName="eive-linux-host-debug">
<resource resourceType="PROJECT" workspacePath="/eive_obsw"/>
</configuration>
<configuration configurationName="eive-mingw-release"/>
<configuration configurationName="eive-rpi-release-win"/>
<configuration configurationName="eive-linux-host-release"/>
<configuration configurationName="eive-mingw-debug">
<resource resourceType="PROJECT" workspacePath="/eive_obsw"/>
</configuration>
<configuration configurationName="Default">
<resource resourceType="PROJECT" workspacePath="/eive_obsw"/>
</configuration>
<configuration configurationName="eive-rpi-debug-win"/>
<configuration configurationName="eive-q7s-debug-win"/>
<configuration configurationName="eive-rpi-debug"/>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings">
<doc-comment-owner id="org.eclipse.cdt.ui.doxygen">
<path value=""/>
</doc-comment-owner>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j16</buildArguments>
<buildTarget>clean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="hardclean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments>-j16</buildArguments>
<buildTarget>hardclean</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.646655988;cdt.managedbuild.tool.gnu.cpp.compiler.input.1437856797">
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.2047596104;cdt.managedbuild.toolchain.gnu.base.2047596104.1629235648;cdt.managedbuild.tool.gnu.c.compiler.base.1751527394;cdt.managedbuild.tool.gnu.c.compiler.input.72239787">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.688890851;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.688890851.;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.2065184927;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.920837857">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.447898075;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.447898075.;cdt.managedbuild.tool.gnu.c.compiler.base.623389075;cdt.managedbuild.tool.gnu.c.compiler.input.1382191457">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.688890851.1707795689;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.688890851.1707795689.;ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.1535302916;ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input.96000231">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.1043649249;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.1043649249.;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.473677411;cdt.managedbuild.tool.gnu.c.compiler.input.2060052812">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.688890851;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.688890851.;ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.1595165802;ilg.gnuarmeclipse.managedbuild.cross.tool.cpp.compiler.input.1925043110">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.1043649249;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.1043649249.;cdt.managedbuild.tool.gnu.cpp.compiler.mingw.base.539225324;cdt.managedbuild.tool.gnu.cpp.compiler.input.1848997248">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.;cdt.managedbuild.tool.gnu.cpp.compiler.base.1405808772;cdt.managedbuild.tool.gnu.cpp.compiler.input.1960112549">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.688890851.1707795689;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.688890851.1707795689.;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.628631287;ilg.gnuarmeclipse.managedbuild.cross.tool.c.compiler.input.216437361">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.447898075;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.447898075.;cdt.managedbuild.tool.gnu.cpp.compiler.base.1522927967;cdt.managedbuild.tool.gnu.cpp.compiler.input.305765911">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.2117915473.;cdt.managedbuild.tool.gnu.c.compiler.base.1946711528;cdt.managedbuild.tool.gnu.c.compiler.input.584209663">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443;cdt.managedbuild.toolchain.gnu.mingw.base.1455833186.1840876443.;cdt.managedbuild.tool.gnu.c.compiler.mingw.base.397223006;cdt.managedbuild.tool.gnu.c.compiler.input.1482659499">
<scannerConfigBuildInfo instanceId="cdt.managedbuild.toolchain.gnu.base.2047596104;cdt.managedbuild.toolchain.gnu.base.2047596104.1629235648;cdt.managedbuild.tool.gnu.cpp.compiler.base.1852610587;cdt.managedbuild.tool.gnu.cpp.compiler.input.1985567520">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</scannerConfigBuildInfo>
</storageModule>

View File

@ -0,0 +1,14 @@
#include "ACUHandler.h"
ACUHandler::ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie,
uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16 hkTableSize) :
GomspaceDeviceHandler(objectId, comIF, comCookie, maxConfigTableAddress, maxHkTableAddress,
hkTableSize) {
}
ACUHandler::~ACUHandler() {
}
void ACUHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
}

View File

@ -0,0 +1,24 @@
#ifndef MISSION_DEVICES_ACUHANDLER_H_
#define MISSION_DEVICES_ACUHANDLER_H_
#include "GomspaceDeviceHandler.h"
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
/**
* @brief Handler for the ACU of Gomspace. Monitors and controls the battery charging via
* the solar pannels.
*/
class ACUHandler: public GomspaceDeviceHandler {
public:
ACUHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie,
uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16_t hkTableSize);
virtual ~ACUHandler();
protected:
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) override;
private:
};
#endif /* MISSION_DEVICES_ACUHANDLER_H_ */

View File

@ -5,6 +5,12 @@ target_sources(${TARGET_NAME} PUBLIC
MGMHandlerRM3100.cpp
GomspaceDeviceHandler.cpp
Tmp1075Handler.cpp
PCDUHandler.cpp
P60DockHandler.cpp
PDU1Handler.cpp
PDU2Handler.cpp
ACUHandler.cpp
HeaterHandler.cpp
)

View File

@ -44,7 +44,7 @@ uint32_t GPSHandler::getTransitionDelayMs(Mode_t from, Mode_t to) {
}
ReturnValue_t GPSHandler::initializeLocalDataPool(
LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -29,7 +29,7 @@ protected:
void fillCommandAndReplyMap() override;
void modeChanged() override;
uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
ReturnValue_t initializeLocalDataPool(LocalDataPool &localDataPoolMap,
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
private:

View File

@ -2,14 +2,14 @@
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
GomspaceDeviceHandler::GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie, uint16_t maxConfigTableAddress,
uint16_t maxHkTableAddress) :
DeviceHandlerBase(objectId, comIF, comCookie), maxConfigTableAddress(
maxConfigTableAddress), maxHkTableAddress(maxHkTableAddress) {
mode = MODE_NORMAL;
if (comCookie == NULL) {
sif::error << "GomspaceDeviceHandler invalid com cookie" << std::endl;
}
CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress,
uint16_t hkTableSize) :
DeviceHandlerBase(objectId, comIF, comCookie), maxConfigTableAddress(maxConfigTableAddress), maxHkTableAddress(
maxHkTableAddress), hkTableSize(hkTableSize) {
mode = MODE_NORMAL;
if (comCookie == NULL) {
sif::error << "GomspaceDeviceHandler invalid com cookie" << std::endl;
}
}
GomspaceDeviceHandler::~GomspaceDeviceHandler() {
@ -38,38 +38,41 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(
size_t commandDataLen) {
ReturnValue_t result;
switch(deviceCommand) {
case(PING): {
case(GOMSPACE::PING): {
result = generatePingCommand(commandData, commandDataLen);
if(result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
break;
}
case(REBOOT): {
case(GOMSPACE::REBOOT): {
generateRebootCommand();
break;
}
case(PARAM_SET):{
case(GOMSPACE::PARAM_SET):{
result = generateSetParamCommand(commandData, commandDataLen);
if(result != HasReturnvaluesIF::RETURN_OK){
return result;
}
break;
}
case(PARAM_GET):{
case(GOMSPACE::PARAM_GET):{
result = generateGetParamCommand(commandData, commandDataLen);
if(result != HasReturnvaluesIF::RETURN_OK){
return result;
}
break;
}
case(GNDWDT_RESET): {
case(GOMSPACE::GNDWDT_RESET): {
result = generateResetWatchdogCmd();
if(result != HasReturnvaluesIF::RETURN_OK){
return result;
}
break;
}
case(GOMSPACE::REQUEST_HK_TABLE): {
generateRequestFullHkTableCmd(hkTableSize);
}
default:
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
@ -77,31 +80,38 @@ ReturnValue_t GomspaceDeviceHandler::buildCommandFromCommand(
}
void GomspaceDeviceHandler::fillCommandAndReplyMap(){
this->insertInCommandAndReplyMap(PING, 3);
this->insertInCommandMap(REBOOT);
this->insertInCommandAndReplyMap(PARAM_SET, 3);
this->insertInCommandAndReplyMap(PARAM_GET, 3);
this->insertInCommandMap(GNDWDT_RESET);
this->insertInCommandAndReplyMap(GOMSPACE::PING, 3);
this->insertInCommandMap(GOMSPACE::REBOOT);
this->insertInCommandAndReplyMap(GOMSPACE::PARAM_SET, 3);
this->insertInCommandAndReplyMap(GOMSPACE::PARAM_GET, 3);
this->insertInCommandAndReplyMap(GOMSPACE::REQUEST_HK_TABLE, 3);
this->insertInCommandMap(GOMSPACE::GNDWDT_RESET);
}
ReturnValue_t GomspaceDeviceHandler::scanForReply(const uint8_t *start,
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
switch(rememberCommandId) {
case(PING):
*foundId = PING;
case(GOMSPACE::PING):
*foundId = GOMSPACE::PING;
*foundLen = PING_REPLY_SIZE;
rememberCommandId = NONE;
rememberCommandId = GOMSPACE::NONE;
break;
case(PARAM_GET): {
*foundId = PARAM_GET;
*foundLen = rememberRequestedSize + CspGetParamReply::GS_HDR_LENGTH;
rememberCommandId = NONE;
case(GOMSPACE::PARAM_GET): {
*foundId = GOMSPACE::PARAM_GET;
*foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH;
rememberCommandId = GOMSPACE::NONE;
break;
}
case(PARAM_SET): {
*foundId = PARAM_SET;
case(GOMSPACE::PARAM_SET): {
*foundId = GOMSPACE::PARAM_SET;
*foundLen = rememberRequestedSize;
rememberCommandId = NONE;
rememberCommandId = GOMSPACE::NONE;
break;
}
case(GOMSPACE::REQUEST_HK_TABLE): {
*foundId = GOMSPACE::REQUEST_HK_TABLE;
*foundLen = rememberRequestedSize + GOMSPACE::GS_HDR_LENGTH;
rememberCommandId = GOMSPACE::NONE;
break;
}
default:
@ -113,12 +123,12 @@ ReturnValue_t GomspaceDeviceHandler::scanForReply(const uint8_t *start,
ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) {
switch(id) {
case(PING): {
case(GOMSPACE::PING): {
SerializeElement<uint32_t> replyTime = *packet;
handleDeviceTM(&replyTime, id, true);
break;
}
case(PARAM_GET): {
case(GOMSPACE::PARAM_GET): {
// -2 to subtract address size from gomspace parameter reply packet
uint16_t payloadLength = (*(packet + 2) << 8 | *(packet + 3)) - 2;
if(payloadLength > sizeof(uint32_t)){
@ -129,7 +139,7 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
uint8_t tempPayloadBuffer[payloadLength];
/* Extract information from received data */
CspGetParamReply cspGetParamReply(tempPayloadBuffer, payloadLength);
size_t size = CspGetParamReply::GS_HDR_LENGTH + payloadLength;
size_t size = GOMSPACE::GS_HDR_LENGTH + payloadLength;
ReturnValue_t result = cspGetParamReply.deSerialize(&packet, &size,
SerializeIF::Endianness::BIG);
if(result != HasReturnvaluesIF::RETURN_OK){
@ -146,7 +156,7 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
handleDeviceTM(&paramReply, id, true);
break;
}
case(PARAM_SET): {
case(GOMSPACE::PARAM_SET): {
/* When setting a parameter, the p60dock sends back the state of the
* operation */
if(*packet != PARAM_SET_OK){
@ -154,6 +164,10 @@ ReturnValue_t GomspaceDeviceHandler::interpretDeviceReply(DeviceCommandId_t id,
}
break;
}
case(GOMSPACE::REQUEST_HK_TABLE): {
letChildHandleHkReply(id, packet);
break;
}
default:
break;
}
@ -211,7 +225,7 @@ ReturnValue_t GomspaceDeviceHandler::generateSetParamCommand(
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
rememberRequestedSize = querySize;
rememberCommandId = PARAM_SET;
rememberCommandId = GOMSPACE::PARAM_SET;
return HasReturnvaluesIF::RETURN_OK;
}
@ -256,7 +270,7 @@ ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(
<< "size" << std::endl;
return INVALID_PARAM_SIZE;
}
uint16_t querySize = parameterSize + CspGetParamCommand::GS_HDR_LENGTH;
uint16_t querySize = parameterSize + GOMSPACE::GS_HDR_LENGTH;
/* Generate the CSP command to send to the P60 Dock */
CspGetParamCommand getParamCmd(querySize, tableId, length,
@ -277,7 +291,7 @@ ReturnValue_t GomspaceDeviceHandler::generateGetParamCommand(
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
rememberRequestedSize = querySize;
rememberCommandId = PARAM_GET;
rememberCommandId = GOMSPACE::PARAM_GET;
return HasReturnvaluesIF::RETURN_OK;
}
@ -301,7 +315,7 @@ ReturnValue_t GomspaceDeviceHandler::generatePingCommand(
}
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
rememberCommandId = PING;
rememberCommandId = GOMSPACE::PING;
return HasReturnvaluesIF::RETURN_OK;
}
@ -330,10 +344,32 @@ ReturnValue_t GomspaceDeviceHandler::generateResetWatchdogCmd(){
rawPacketLen = cspPacketLen;
rememberRequestedSize = 0; // No bytes will be queried with the ground
// watchdog command.
rememberCommandId = GNDWDT_RESET;
rememberCommandId = GOMSPACE::GNDWDT_RESET;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t GomspaceDeviceHandler::generateRequestFullHkTableCmd(uint16_t hkTableSize) {
uint16_t querySize = hkTableSize + GOMSPACE::GS_HDR_LENGTH;
uint8_t tableId = HK_TABLE_ID;
RequestFullTableCommand requestFullTableCommand(querySize, tableId);
size_t cspPacketLen = 0;
uint8_t* buffer = cspPacket;
ReturnValue_t result = requestFullTableCommand.serialize(&buffer,
&cspPacketLen, sizeof(cspPacket), SerializeIF::Endianness::BIG);
if(result != HasReturnvaluesIF::RETURN_OK){
sif::error << "GomspaceDeviceHandler::generateRequestFullHkTableCmd Failed to serialize "
"full table request command " << std::endl;
return result;
}
rawPacket = cspPacket;
rawPacketLen = cspPacketLen;
rememberRequestedSize = querySize;
rememberCommandId = GOMSPACE::REQUEST_HK_TABLE;
return RETURN_OK;
}
uint32_t GomspaceDeviceHandler::getTransitionDelayMs(Mode_t modeFrom,
Mode_t modeTo) {
return 0;

View File

@ -2,6 +2,7 @@
#define MISSION_DEVICES_GOMSPACEDEVICEHANDLER_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
/**
* @brief This is the device handler class for all gomspace devices.
@ -19,6 +20,7 @@ public:
static const ReturnValue_t INVALID_ADDRESS = MAKE_RETURN_CODE(0xE2);
static const ReturnValue_t INVALID_PARAM_SIZE = MAKE_RETURN_CODE(0xE3);
static const ReturnValue_t INVALID_PAYLOAD_SIZE = MAKE_RETURN_CODE(0xE4);
static const ReturnValue_t UNKNOWN_REPLY_ID = MAKE_RETURN_CODE(0xE5);
/**
* @brief Constructor
@ -30,11 +32,28 @@ public:
* device.
*/
GomspaceDeviceHandler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie, uint16_t maxConfigTableAddress,
uint16_t maxHkTableAddress);
CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress,
uint16_t hkTableSize);
virtual ~GomspaceDeviceHandler();
protected:
static const uint8_t MAX_PACKET_LEN = 36;
static const uint8_t PARAM_SET_OK = 1;
static const uint8_t PING_REPLY_SIZE = 2;
static const uint8_t CONFIG_TABLE_ID = 1;
static const uint8_t HK_TABLE_ID = 4;
uint8_t rememberRequestedSize = 0;
uint8_t rememberCommandId = GOMSPACE::NONE;
uint8_t cspPacket[MAX_PACKET_LEN];
uint16_t maxConfigTableAddress;
uint16_t maxHkTableAddress;
/** The size of the housekeeping table (table id 4) */
uint16_t hkTableSize;
void doStartUp() override;
void doShutDown() override;
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id)
@ -49,29 +68,22 @@ protected:
const uint8_t *packet) override;
void setNormalDatapoolEntriesInvalid() override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
/**
* @brief The command to generate a request to receive the full housekeeping table is device
* specific. Thus the child has to build this command.
*/
virtual ReturnValue_t generateRequestFullHkTableCmd(uint16_t hkTableSize);
/**
* @brief Because housekeeping tables are device specific the handling of the reply is
* given to the child class.
* @param id The id of the command which initiates the full table request.
* @param packet Pointer to the reply containing the hk table.
*/
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) = 0;
private:
static const uint8_t MAX_PACKET_LEN = 36;
static const uint8_t PARAM_SET_OK = 1;
static const uint8_t PING_REPLY_SIZE = 2;
static const uint8_t CONFIG_TABLE_ID = 1;
static const uint8_t HK_TABLE_ID = 4;
/* Device commands are derived from the rparam.h of the gomspace lib */
static const DeviceCommandId_t PING = 0x1; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t NONE = 0x2; // Set when no command is pending
static const DeviceCommandId_t REBOOT = 0x4; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t GNDWDT_RESET = 0x9; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t PARAM_GET = 0x00; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t PARAM_SET = 0xFF; //!< [EXPORT] : [COMMAND]
uint8_t rememberRequestedSize = 0;
uint8_t rememberCommandId = NONE;
uint8_t cspPacket[MAX_PACKET_LEN];
uint16_t maxConfigTableAddress;
uint16_t maxHkTableAddress;
/**
* @brief Function to generate the command to set a parameter. Command
* will be sent to the ComIF over the rawPacket buffer.

View File

@ -1,4 +1,5 @@
#include <mission/devices/GyroL3GD20Handler.h>
#include <fsfw/datapool/PoolReadHelper.h>
GyroHandler::GyroHandler(object_id_t objectId, object_id_t deviceCommunication,
CookieIF *comCookie):
@ -171,14 +172,13 @@ ReturnValue_t GyroHandler::interpretDeviceReply(DeviceCommandId_t id,
int8_t temperaturOffset = (-1) * packet[L3GD20H::TEMPERATURE_IDX];
float temperature = 25.0 + temperaturOffset;
result = dataset.read();
if(result == HasReturnvaluesIF::RETURN_OK) {
PoolReadHelper readSet(&dataset);
if(readSet.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
dataset.angVelocX = angVelocX;
dataset.angVelocY = angVelocY;
dataset.angVelocZ = angVelocZ;
dataset.temperature = temperature;
dataset.setValidity(true, true);
result = dataset.commit();
}
break;
}
@ -194,7 +194,7 @@ uint32_t GyroHandler::getTransitionDelayMs(Mode_t from, Mode_t to) {
}
ReturnValue_t GyroHandler::initializeLocalDataPool(
LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_X,
new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y,

View File

@ -37,7 +37,7 @@ protected:
void fillCommandAndReplyMap() override;
void modeChanged() override;
uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
ReturnValue_t initializeLocalDataPool(LocalDataPool &localDataPoolMap,
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
private:

View File

@ -1,121 +1,101 @@
#include <mission/devices/HeaterHandler.h>
#include <fsfwconfig/devices/powerSwitcherList.h>
HeaterHandler::HeaterHandler(object_id_t setObjectId,
object_id_t gpioDriverId, CookieIF * gpioCookie, object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch) :
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE),
gpioDriverId(gpioDriver), gpioCookie(gpioCookie), mainLineSwitcherObjectId(mainLineSwitcherObjectId), mainLineSwitch(mainLineSwitch),
healthHelper(this,setObjectId), modeHelper(this), parameterHelper(this),
actionHelper(this, nullptr), hkManager(this, nullptr),
childTransitionFailure(RETURN_OK), fdirInstance(fdirInstance),
hkSwitcher(this), defaultFDIRUsed(fdirInstance == nullptr),
switchOffWasReported(false), childTransitionDelay(5000),
transitionSourceMode(_MODE_POWER_DOWN),
transitionSourceSubMode(SUBMODE_NONE) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
powerSwitcher = objectManager->get<PowerSwitcherIF>(
mainLineSwitcherObjectId);
HeaterHandler::HeaterHandler(object_id_t setObjectId, object_id_t gpioDriverId,
CookieIF * gpioCookie, object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch) :
SystemObject(setObjectId), mode(MODE_OFF), submode(SUBMODE_NONE), gpioDriverId(gpioDriver),
gpioCookie(gpioCookie), mainLineSwitcherObjectId(mainLineSwitcherObjectId), mainLineSwitch(
mainLineSwitch), actionHelper(this, nullptr) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
}
HeaterHandler::~HeaterHandler() {
}
ReturnValue_t performOperation(uint8_t operationCode) {
ReturnValue_t HeaterHandler::performOperation(uint8_t operationCode) {
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
readCommandQueue();
handlePendingCommand();
doStateMachine();
checkSwitchState();
decrementDeviceReplyMap();
fdirInstance->checkForFailures();
hkSwitcher.performOperation();
performOperationHook();
handleActiveCommands();
return RETURN_OK;
}
}
ReturnValue_t DeviceHandlerBase::initialize() {
ReturnValue_t HeaterHandler::initialize() {
ReturnValue_t result = SystemObject::initialize();
if (result != RETURN_OK) {
return result;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = initializeHeaterMap();
if (result != RETURN_OK) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
gpioInterface = objectManager->get<GpioIF>(gpioDriverId);
if (gpioInterface == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "HeaterHandler::initialize: Invalid Gpio interface."
<< std::endl;
#endif
sif::error << "HeaterHandler::initialize: Invalid Gpio interface." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = gpioInterface->initializeInterface(gpioCookie);
if (result != RETURN_OK) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "HeaterHandler::initialize: Failed to initialize Gpio "
<< "interface"<< std::endl;
#endif
return result;
sif::error << "HeaterHandler::initialize: Failed to initialize Gpio interface" << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "HeaterHandler::initialize: IPC store not set up in "
"factory." << std::endl;
#endif
sif::error << "HeaterHandler::initialize: IPC store not set up in factory." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
if(powerSwitcherId != objects::NO_OBJECT) {
powerSwitcher = objectManager->get<PowerSwitchIF>(powerSwitcherId);
if (powerSwitcher == nullptr) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::error << "HeaterHandler::initialize: Power switcher "
<< "object ID set but no valid object found." << std::endl;
#endif
if(mainLineSwitcherObjectId != objects::NO_OBJECT) {
mainLineSwitcher = objectManager->get<PowerSwitchIF>(mainLineSwitcherObjectId);
if (mainLineSwitcher == nullptr) {
sif::error << "HeaterHandler::initialize: Main line switcher failed to fetch object"
<< "from object ID." << std::endl;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
}
result = healthHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = modeHelper.initialize();
if (result != RETURN_OK) {
return result;
}
result = actionHelper.initialize(commandQueue);
if (result != RETURN_OK) {
return result;
return ObjectManagerIF::CHILD_INIT_FAILED;
}
fillCommandAndReplyMap();
return RETURN_OK;
}
void DeviceHandlerBase::readCommandQueue() {
if (dontCheckQueue()) {
return;
ReturnValue_t HeaterHandler::initializeHeaterMap(){
heaterMapIter = heaterMap.begin();
HeaterCommandInfo_t heaterCommandInfo;
for(int switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
std::pair status = heaterMap.emplace(switchNr, heaterCommandInfo);
if (status.second == false) {
sif::error << "HeaterHandler::initializeHeaterMap: Failed to initialize heater map"
<< std::endl;
return RETURN_FAILED;
}
}
return RETURN_OK;
}
void HeaterHandler::setInitialSwitchStates() {
for (int switchNr = 0; switchNr < heaterSwitches::NUMBER_OF_SWITCHES; switchNr++) {
switchStates[switchNr] = OFF;
}
}
void HeaterHandler::readCommandQueue() {
CommandMessage command;
ReturnValue_t result = commandQueue->receiveMessage(&command);
if (result != RETURN_OK) {
return;
}
result = modeHelper.handleModeCommand(&command);
if (result == RETURN_OK) {
return;
}
result = actionHelper.handleActionMessage(&command);
if (result == RETURN_OK) {
return;
@ -124,56 +104,51 @@ void DeviceHandlerBase::readCommandQueue() {
ReturnValue_t HeaterHandler::executeAction(ActionId_t actionId,
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
ReturnValue_t result = acceptExternalDeviceCommands();
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
heaterCommandMap::iterator iter = HeaterCommandMap.find(actionId);
if (iter == heaterCommandMap.end()) {
if (actionId != SWITCH_ON && actionId != SWITCH_OFF) {
result = COMMAND_NOT_SUPPORTED;
} else {
if (commandedBy == commandQueue){
heaterCommand(*(data), *(data + 1), NO_COMMANDER);
commandPending = true;
heaterMapIter = heaterMap.find(*data);
if (heaterMapIter != heaterMap.end()) {
heaterMapIter.second.action = *(data + 1);
heaterMapIter.second.active = true;
}
else {
heaterCommand(*(data), *(data + 1), commandedBy);
commandPending = true;
sif::error << "HeaterHandler::executeAction: Invalid switchNr" << std::endl;
return INVALID_SWITCH_NR;
}
result = RETURN_OK;
}
return result;
}
ReturnValue_t DeviceHandlerBase::acceptExternalDeviceCommands() {
if (mode != MODE_ON) {
return WRONG_MODE_FOR_COMMAND;
}
return RETURN_OK;
}
void HeaterHandler::sendSwitchCommand(uint8_t switchNr,
ReturnValue_t onOff) const {
ReturnValue_t result;
store_address_t address;
HeaterCommand_t command;
store_address_t storeAddress;
uint8_t commandData[2];
switch(onOff) {
case PowerSwitchIF::SWITCH_ON:
command(SWITCH_ON, switchNr);
commandData[0] = switchNr;
commandData[1] = SET_SWITCH_ON;
case PowerSwitchIF::SWITCH_OFF:
command(SWITCH_OFF, switchNr);
commandData[0] = switchNr;
commandData[1] = SET_SWITCH_OFF;
default:
sif::error << "HeaterHandler::sendSwitchCommand: Invalid switch request"
<< std::endl;
}
result = IPCStore->addData(&address, &command, sizeof(command));
result = IPCStore->addData(&storeAddress, commandData, sizeof(commandData));
if (result == RETURN_OK) {
CommandMessage message;
ActionMessage::setCommand(&message,
HeaterHandler::SWITCH_HEATER, address);
HeaterHandler::SWITCH_HEATER, storeAddress);
/* Send heater command to own command queue */
result = commandQueue->sendMessage(commandQueue, &message, 0);
if (result != RETURN_OK) {
@ -183,32 +158,79 @@ void HeaterHandler::sendSwitchCommand(uint8_t switchNr,
}
}
void HeaterHandler::handlePendingCommand(){
void HeaterHandler::handleActiveCommands(){
ReturnValue_t result;
if (!commandPending) {
return;
}
switch(heaterCommand.action) {
case SET_SWITCH_ON:
result = gpioInterface->pullHigh(heaterCommand.heaterSwitchNr);
if (result != RETURN_OK) {
triggerEvent()
heaterMapIter = heaterMap.begin();
for (; heaterMapIter != mapToAdd.end(); heaterMapIter++) {
if (heaterMapIter.second.active) {
switch(heaterMapIter.second.action) {
case SET_SWITCH_ON:
int switchNr = heaterMapIter.first();
/* Check state of main line switch */
if (mainLineSwitcher->getSwitchState(pcduSwitches::TCS_BOARD_8V_HEATER_IN)
== SWITCH_ON) {
if (!checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullHigh(gpioId);
if (result != RETURN_OK) {
triggerEvent(GPIO_PULL_HIGH_FAILED, result);
}
}
else {
triggerEvent(SWITCH_ALREADY_ON, switchNr);
}
/* There is no need to send action finish replies if the sender was the
* HeaterHandler itself. */
if (heaterMapIter.second.replyQueue != commandQueue) {
actionHelper.finish(heaterMapIter.second.replyQueue,
heaterMapIter.second.action, result);
}
heaterMapIter.second.active = false;
}
else {
mainLineSwitcher->sendSwitchCommand(pcduSwitches::TCS_BOARD_8V_HEATER_IN);
}
break;
case SET_SWITCH_OFF:
int switchNr = heaterMapIter.first();
if (checkSwitchState(switchNr)) {
gpioId_t gpioId = getGpioIdFromSwitchNr(switchNr);
result = gpioInterface->pullLow(gpioId);
triggerEvent(GPIO_PULL_LOW_FAILED, result);
}
else {
triggerEvent(SWITCH_ALREADY_OFF, switchNr);
}
if (heaterCommand.replyQueue != NO_COMMANDER) {
actionHelper.finish(heaterMapIter.second.replyQueue,
heaterMapIter.second.action, result);
}
break;
default:
sif::error << "HeaterHandler::handleActiveCommands: Invalid action commanded"
<< std::endl;
break;
}
}
if (heaterCommand.replyQueue != NO_COMMANDER) {
actionHelper.finish(heaterCommand.replyQueue, heaterCommand.action,
result);
}
commandPending = false;
break;
case SET_SWITCH_OFF:
result = gpioInterface->pullLow(heaterCommand.heaterSwitchNr);
if (heaterCommand.replyQueue != NO_COMMANDER) {
actionHelper.finish(heaterCommand.replyQueue, heaterCommand.action,
result);
}
commandPending = false;
break;
}
}
bool HeaterHandler::checkSwitchState(int switchNr) {
return switchStates[switchNr];
}
gpioId_t HeaterHandler::getGpioIdFromSwitchNr(switchNr) {
gpioId_t gpioId = 0xFFFF;
switch(switchNr) {
case heaterSwitches::PAYLOAD_CAMERA:
gpioId = gpioIds::HEATER_0;
break;
default:
sif::error << "HeaterHandler::getGpioIdFromSwitchNr: Unknown heater switch number"
<< std::endl;
break;
}
return gpioId;
}

View File

@ -7,6 +7,7 @@
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/modes/HasModesIF.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <fsfwconfig/devices/heaterSwitcherList.h>
/**
* @brief This class intends the control of heaters.
@ -21,15 +22,14 @@ class HeaterHandler: public ExecutableObjectIF,
public HasReturnvaluesIF {
public:
/** Command not in heaterCommandMap */
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1);
/** Heater mode is MODE_OFF */
static const ReturnValue_t WRONG_MODE_FOR_COMMAND = MAKE_RETURN_CODE(0xA5);
/** Device command IDs */
static const DeviceCommandId_t SWITCH_HEATER;
HeaterHandler(object_id_t setObjectId, object_id_t gpioDriverId, CookieIF * gpioCookie,
object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch);
virtual ~HeaterHandler();
virtual ReturnValue_t performOperation(uint8_t operationCode = 0);
void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) override;
@ -47,67 +47,82 @@ public:
private:
static const MessageQueueId_t NO_COMMANDER = 0;
static const uint8_t INTERFACE_ID = CLASS_ID::PCDU_HANDLER;
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA1);
static const ReturnValue_t INIT_FAILED = MAKE_RETURN_CODE(0xA2);
static const ReturnValue_t INVALID_SWITCH_NR = MAKE_RETURN_CODE(0xA3);
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PCDU_HANDLER;
static const Event GPIO_PULL_HIGH_FAILED = MAKE_EVENT(0, severity::LOW);
static const Event GPIO_PULL_LOW_FAILED = MAKE_EVENT(1, severity::LOW);
static const Event SWITCH_ALREADY_ON = MAKE_EVENT(2, severity::LOW);
static const Event SWITCH_ALREADY_OFF = MAKE_EVENT(3, severity::LOW);
ReturnValue_t buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
size_t commandDataLen);
ReturnValue_t acceptExternalDeviceCommands();
/**
* @brief Returns the state of a switch (ON - true, or OFF - false).
* @param switchNr The number of the switch to check.
*/
bool checkSwitchState(int switchNr);
/**
* @brief Returns the ID of the GPIO related to a heater identified by the switch number
* which is defined in the heaterSwitches list.
*/
gpioId_t getGpioIdFromSwitchNr(switchNr);
/**
* @brief This function runs commands waiting for execution.
*/
void handlePendingCommand();
void handleActiveCommands();
ReturnValue_t initializeHeaterMap();
/**
* @brief Sets all switches to OFF.
*/
void setInitialSwitchStates();
enum SwitchState : bool {
ON = true,
OFF = false
};
/**
* @brief Struct holding information about a heater command to execute.
*
* @param action The action to perform.
* @param heaterSwitchNr The number of a switch which correlates with the
* GPIO to drive.
* @param replyQueue The queue of the commander to which status replies
* will be sent.
* @param active True if command is waiting for execution, otherwise false.
*/
typedef struct HeaterCommand {
HeaterCommand(uint8_t action_, uint8_t heaterSwitchNr,
MessageQueueId_t replyQueue_) {
action = action_;
heaterSwitchNr = heaterSwitchNr_;
replyQueue = replyQueue_;
}
typedef struct HeaterCommandInfo {
uint8_t action;
uint8_t heaterSwitchNr;
MessageQueueId_t replyQueue;
} HeaterCommand_t;
bool active = false;
} HeaterCommandInfo_t;
enum SwitchAction {
SET_SWITCH_ON,
SET_SWITCH_OFF
};
/** This HeaterCommand instance holds the next heater command to execute */
HeaterCommand_t heaterCommand;
using switchNr_t = int;
using HeaterMap = std::unordered_map<switchNr_t, HeaterCommandInfo_t>;
using HeaterMapIter = HeaterMap::iterator;
/**
* This variable is set when the command stored in heaterCommand shall be
* executed.
*/
bool commandPending;
HeateerMap heaterMap;
HeaterMapIter heaterMapIter;
bool switchStates[heaterSwitches::NUMBER_OF_SWITCHES];
/** Size of command queue */
size_t cmdQueueSize = 20;
/**
* Current mode of the HeaterHandler. Should only be changed with setMode().
*/
Mode_t mode;
/**
* Current submode of the HeaterHandler. Should only be change with
* setMode().
*/
Submode_t submode;
/**
* The object ID of the GPIO driver which enables and disables the
* heaters.
@ -119,14 +134,20 @@ private:
/** Queue to receive messages from other objects. */
MessageQueueIF* commandQueue = nullptr;
object_id_t mainLineSwitcherObjectId;
/** Switch number of the heater power supply switch */
uint8_t mainLineSwitch;
/**
* Power switcher object which controls the 8V main line of the heater
* logic on the TCS board.
*/
PowerSwitchIF *powerSwitcher;
PowerSwitchIF *mainLineSwitcher = nullptr;
HeaterHandler();
virtual ~HeaterHandler();
ActionHelper actionHelper;
StorageManagerIF *IPCStore = nullptr;
};
#endif /* MISSION_DEVICES_HEATERHANDLER_H_ */

View File

@ -423,7 +423,7 @@ void MGMHandlerLIS3MDL::modeChanged(void) {
}
ReturnValue_t MGMHandlerLIS3MDL::initializeLocalDataPool(
LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_X,
new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(MGMLIS3MDL::FIELD_STRENGTH_Y,

View File

@ -52,7 +52,7 @@ protected:
const uint8_t *packet) override;
void fillCommandAndReplyMap() override;
void modeChanged(void) override;
ReturnValue_t initializeLocalDataPool(LocalDataPool &localDataPoolMap,
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
private:

View File

@ -304,7 +304,7 @@ void MGMHandlerRM3100::modeChanged(void) {
}
ReturnValue_t MGMHandlerRM3100::initializeLocalDataPool(
LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_X,
new PoolEntry<float>({0.0}));
localDataPoolMap.emplace(RM3100::FIELD_STRENGTH_Y,

View File

@ -55,7 +55,7 @@ protected:
void fillCommandAndReplyMap() override;
void modeChanged(void) override;
uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
ReturnValue_t initializeLocalDataPool(LocalDataPool &localDataPoolMap,
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
private:

View File

@ -0,0 +1,14 @@
#include "P60DockHandler.h"
P60DockHandler::P60DockHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie,
uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16_t hkTableSize) :
GomspaceDeviceHandler(objectId, comIF, comCookie, maxConfigTableAddress, maxHkTableAddress,
hkTableSize) {
}
P60DockHandler::~P60DockHandler() {
}
void P60DockHandler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
}

View File

@ -0,0 +1,21 @@
#ifndef MISSION_DEVICES_P60DOCKHANDLER_H_
#define MISSION_DEVICES_P60DOCKHANDLER_H_
#include "GomspaceDeviceHandler.h"
/**
* @brief Device handler for the P60Dock. The P60Dock serves as carrier for the ACU, PDU1 and
* PDU2. Via the P60Dock each of these modules can be turned on and off individually.
*/
class P60DockHandler: public GomspaceDeviceHandler {
public:
P60DockHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie,
uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16_t hkTableSize);
virtual ~P60DockHandler();
protected:
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) override;
};
#endif /* MISSION_DEVICES_P60DOCKHANDLER_H_ */

View File

@ -1,18 +1,289 @@
/*
* PCDUHandler.cpp
*
* Created on: 21.01.2021
* Author: jakob
*/
#include "PCDUHandler.h"
#include <fsfwconfig/objects/systemObjectList.h>
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
#include <fsfw/ipc/QueueFactory.h>
#include <fsfwconfig/devices/powerSwitcherList.h>
#include <fsfw/housekeeping/HousekeepingPacketUpdate.h>
PCDUHandler::PCDUHandler() {
// TODO Auto-generated constructor stub
PCDUHandler::PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize) :
SystemObject(setObjectId), poolManager(this, nullptr), pdu2HkTableDataset(this), cmdQueueSize(
cmdQueueSize) {
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
MessageQueueMessage::MAX_MESSAGE_SIZE);
}
PCDUHandler::~PCDUHandler() {
// TODO Auto-generated destructor stub
}
ReturnValue_t PCDUHandler::performOperation(uint8_t counter) {
if (counter == DeviceHandlerIF::PERFORM_OPERATION) {
readCommandQueue();
return RETURN_OK;
}
return RETURN_OK;
}
ReturnValue_t PCDUHandler::initialize() {
ReturnValue_t result;
IPCStore = objectManager->get<StorageManagerIF>(objects::IPC_STORE);
if (IPCStore == nullptr) {
return ObjectManagerIF::CHILD_INIT_FAILED;
}
result = poolManager.initialize(commandQueue);
if (result != HasReturnvaluesIF::RETURN_OK) {
return result;
}
HasLocalDataPoolIF* pdu2Handler = objectManager->get<HasLocalDataPoolIF>(objects::PDU2_HANDLER);
if(pdu2Handler == nullptr) {
sif::warning << "PCDUHandler::initialize: Invalid pdu2Handler" << std::endl;
return RETURN_FAILED;
}
result = pdu2Handler->getSubscriptionInterface()->subscribeForSetUpdateMessages(
PDU2::HK_TABLE_DATA_SET_ID, this->getObjectId(), commandQueue->getId(), true);
if (result != RETURN_OK) {
sif::error << "PCDUHandler::initialize: Failed to subscribe for set update messages from "
<< "PDU2Handler" << std::endl;
}
return RETURN_OK;
}
void PCDUHandler::readCommandQueue() {
ReturnValue_t result;
CommandMessage command;
result = poolManager.handleHousekeepingMessage(&command);
if (result == RETURN_OK) {
return;
}
}
MessageQueueId_t PCDUHandler::getCommandQueue() const {
return commandQueue->getId();
}
void PCDUHandler::handleChangedDataset(sid_t sid, store_address_t storeId) {
ReturnValue_t result;
if (sid == sid_t(objects::PCDU_HANDLER, PDU2::HK_TABLE_DATA_SET_ID)) {
HousekeepingPacketUpdate packetUpdate(reinterpret_cast<uint8_t*>(&timeStamp),
sizeof(timeStamp), &pdu2HkTableDataset);
const uint8_t** packet_ptr;
size_t size;
result = IPCStore->getData(storeId, packet_ptr, &size);
if (result != RETURN_OK) {
sif::error << "PCDUHandler::handleChangedDataset: Failed to get data from IPCStore."
<< std::endl;
//TODO: Is it necessary to trigger an Event here?
result = IPCStore->deleteData(storeId);
if (result != RETURN_OK) {
sif::error << "PCDUHandler::handleChangedDataset: Failed to delete data in IPCStore"
<< std::endl;
}
}
result = packetUpdate.deSerialize(packet_ptr, &size, SerializeIF::Endianness::BIG);
if (result != RETURN_OK) {
sif::error << "PCDUHandler::handleChangedDataset: Failed to deserialize packet in "
<< "pdu2HkTableDataset" << std::endl;
}
}
else {
sif::error << "PCDUHandler::handleChangedDataset: Invalid sid" << std::endl;
}
}
LocalDataPoolManager* PCDUHandler::getHkManagerHandle() {
return &poolManager;
}
void PCDUHandler::sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const {
ReturnValue_t result;
uint16_t memoryAddress;
size_t parameterValueSize = sizeof(uint8_t);
uint8_t parameterValue;
GomspaceDeviceHandler* pdu;
switch (switchNr) {
case pcduSwitches::TCS_BOARD_8V_HEATER_IN:
memoryAddress = PDU2::CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN;
pdu = objectManager->get<GomspaceDeviceHandler>(objects::PDU2_HANDLER);
break;
default:
sif::error << "PCDUHandler::sendSwitchCommand: Invalid switch number " << std::endl;
return;
}
switch (onOff) {
case PowerSwitchIF::SWITCH_ON:
parameterValue = 1;
break;
case PowerSwitchIF::SWITCH_OFF:
parameterValue = 0;
break;
default:
sif::error << "PCDUHandler::sendSwitchCommand: Invalid state commanded" << std::endl;
return;
}
size_t serializedLength = 0;
uint8_t command[4];
uint8_t* commandPtr = command;
size_t maxSize = sizeof(command);
GomspaceSetParamMessage setParamMessage(memoryAddress, &parameterValue, parameterValueSize);
setParamMessage.serialize(&commandPtr, &serializedLength, maxSize,
SerializeIF::Endianness::BIG);
store_address_t storeAddress;
result = IPCStore->addData(&storeAddress, command,sizeof(command));
CommandMessage message;
ActionMessage::setCommand(&message, GOMSPACE::PARAM_SET, storeAddress);
result = commandQueue->sendMessage(pdu->getCommandQueue(), &message, 0);
if (result != RETURN_OK) {
sif::debug << "PCDUHandler::sendSwitchCommand: Failed to send message to PDU Handler"
<< std::endl;
}
}
void PCDUHandler::sendFuseOnCommand(uint8_t fuseNr) const {
}
ReturnValue_t PCDUHandler::getSwitchState( uint8_t switchNr ) const {
switch (switchNr) {
case pcduSwitches::TCS_BOARD_8V_HEATER_IN:
if (pdu2HkTableDataset.outEnabledTCSBoardHeaterIn == 1) {
return PowerSwitchIF::SWITCH_ON;
}
else {
return PowerSwitchIF::SWITCH_OFF;
}
default:
sif::error << "PCDUHandler::getSwitchState: Invalid switchNr" << std::endl;
return RETURN_FAILED;
}
}
ReturnValue_t PCDUHandler::getFuseState( uint8_t fuseNr ) const {
return RETURN_OK;
}
uint32_t PCDUHandler::getSwitchDelayMs(void) const {
return 0;
}
object_id_t PCDUHandler::getObjectId() const {
return SystemObject::getObjectId();
}
ReturnValue_t PCDUHandler::initializeLocalDataPool(
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_Q7S, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_RW, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_TCS_BOARD_HEATER_IN, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_SUS_REDUNDANT, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_DEPLOYMENT_MECHANISM, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH6, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_ACS_BOARD_SIDE_B, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_CAMERA, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_Q7S, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_RW, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_SUS_REDUNDANT, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_ACS_BOARD_SIDE_B, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_CAMERA, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VCC, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VBAT, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_TEMPERATURE, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CONV_EN, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_Q7S, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_RW, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_SUS_REDUNDANT, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_ACS_BOARD_SIDE_B, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_CAMERA, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_BOOTCAUSE, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_BOOTCNT, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_UPTIME, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_RESETCAUSE, new PoolEntry<uint16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_BATT_MODE, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_0, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_1, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_2, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_3, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_4, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_5, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_6, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_7, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_0_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_1_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_2_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_3_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_4_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_5_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_6_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_7_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CNT_GND, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CNT_I2C, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CNT_CAN, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CNT_CSP, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_GND_LEFT, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_I2C_LEFT, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CAN_LEFT, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CSP_LEFT, new PoolEntry<uint32_t>( { 0 }));
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PCDUHandler::initializeAfterTaskCreation() {
if(executingTask != nullptr) {
pstIntervalMs = executingTask->getPeriodMs();
}
this->poolManager.initializeAfterTaskCreation();
return HasReturnvaluesIF::RETURN_OK;
}
uint32_t PCDUHandler::getPeriodicOperationFrequency() const {
return pstIntervalMs;
}
void PCDUHandler::setTaskIF(PeriodicTaskIF* task){
executingTask = task;
}
LocalPoolDataSetBase* PCDUHandler::getDataSetHandle(sid_t sid) {
switch (sid) {
case pdu2HkTableDataset.getSid():
return &pdu2HkTableDataset;
default:
sif::error << "PCDUHandler::getDataSetHandle: Invalid sid" << std::endl;
return nullptr;
break;
}
}

View File

@ -1,20 +1,83 @@
/*
* PCDUHandler.h
*
* Created on: 21.01.2021
* Author: jakob
*/
#ifndef MISSION_DEVICES_PCDUHANDLER_H_
#define MISSION_DEVICES_PCDUHANDLER_H_
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
#include <mission/devices/GomspaceDeviceHandler.h>
#include <fsfw/timemanager/CCSDSTime.h>
#include <fsfw/power/PowerSwitchIF.h>
#include <fsfw/datapoollocal/HasLocalDataPoolIF.h>
#include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/tasks/ExecutableObjectIF.h>
#include <fsfw/objectmanager/SystemObject.h>
/**
* @brief
* @brief The PCDUHandler provides a compact interface to handle all devices related to the
* control of power. This is necessary because the fsfw manages all power related
* functionalities via one power object. This includes for example the switch on and off
* of devices.
*/
class PCDUHandler: public PowerSwitchIF {
class PCDUHandler: public PowerSwitchIF,
public HasLocalDataPoolIF,
public SystemObject,
public ExecutableObjectIF {
public:
PCDUHandler();
PCDUHandler(object_id_t setObjectId, size_t cmdQueueSize = 20);
virtual ~PCDUHandler();
virtual ReturnValue_t initialize() override;
virtual ReturnValue_t performOperation(uint8_t counter) override;
virtual void handleChangedDataset(sid_t sid, store_address_t storeId =
storeId::INVALID_STORE_ADDRESS);
virtual void sendSwitchCommand(uint8_t switchNr, ReturnValue_t onOff) const override;
virtual void sendFuseOnCommand(uint8_t fuseNr) const override;
virtual ReturnValue_t getSwitchState( uint8_t switchNr ) const override;
virtual ReturnValue_t getFuseState( uint8_t fuseNr ) const override;
virtual uint32_t getSwitchDelayMs(void) const override;
virtual object_id_t getObjectId() const override;
virtual LocalDataPoolManager* getHkManagerHandle() override;
virtual MessageQueueId_t getCommandQueue() const override;
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
virtual uint32_t getPeriodicOperationFrequency() const override;
virtual ReturnValue_t initializeAfterTaskCreation() override;
virtual void setTaskIF(PeriodicTaskIF* task_);
private:
uint32_t pstIntervalMs = 0;
/**
* The dataset holding the hk table of PDU2. This dataset is a copy of the PDU2 HK dataset
* of the PDU2Handler. Each time the PDU2Handler updates his HK dataset, a copy is sent
* to this object via a HousekeepingMessage.
*/
PDU2::PDU2HkTableDataset pdu2HkTableDataset;
/** The timeStamp of the current pdu2HkTableDataset */
CCSDSTime::CDS_short timeStamp;
/**
* Pointer to the IPCStore.
* This caches the pointer received from the objectManager in the constructor.
*/
StorageManagerIF *IPCStore = nullptr;
/**
* Message queue to communicate with other objetcs. Used for example to receive
* local pool messages from ACU, PDU1 and PDU2.
*/
MessageQueueIF* commandQueue = nullptr;
size_t cmdQueueSize;
/** Housekeeping manager. Handles updates of local pool variables. */
LocalDataPoolManager poolManager;
PeriodicTaskIF* executingTask = nullptr;
void readCommandQueue();
};
#endif /* MISSION_DEVICES_PCDUHANDLER_H_ */

View File

@ -0,0 +1,25 @@
#include "PDU1Handler.h"
PDU1Handler::PDU1Handler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress,
uint16_t hkTableSize) : GomspaceDeviceHandler(objectId, comIF,
comCookie, maxConfigTableAddress, maxHkTableAddress, hkTableSize) {
}
PDU1Handler::~PDU1Handler() {
}
ReturnValue_t PDU1Handler::buildNormalDeviceCommand(
DeviceCommandId_t * id) {
*id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0);
}
void PDU1Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
const uint8_t* payloadPtr = packet + GOMSPACE::GS_HDR_LENGTH;
size_t size = (size_t)hkTableSize;
hkTableDataset.deSerialize(&payloadPtr, &size, SerializeIF::Endianness::BIG);
FullTableReply fullTableReply(id, HK_TABLE_ID, hkTableDataset);
handleDeviceTM(&fullTableReply, id, true);
}

View File

@ -0,0 +1,40 @@
#ifndef MISSION_DEVICES_PDU1Handler_H_
#define MISSION_DEVICES_PDU1Handler_H_
#include "GomspaceDeviceHandler.h"
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
/**
* @brief This is the device handler for the PDU1.
*
* @details The PDU1 controls the
* power supply of the following devices:
* TCS Board, 3.3V, channel 0
* Syrlinks, 12V, channel 1
* Star Tracker, 5V, channel 2
* MGT, 5V, channel 3
* SUS 1-6 Nominal, 3.3V, channel 4
* Solar cell experiment, 5V, channel 5
* PLOC, 12V, channel 6
* ACS 3.3V for Side A group, channel 7
* Unoccupied, 5V, channel 8
*/
class PDU1Handler: public GomspaceDeviceHandler {
public:
PDU1Handler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress,
uint16_t hkTableSize);
virtual ~PDU1Handler();
protected:
/**
* @brief In MODE_NORMAL, a command will be built periodically by this function.
*/
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) override;
private:
/** Dataset for the housekeeping table of the PDU1 */
PDU1::PDU1HkTableDataset hkTableDataset;
};
#endif /* MISSION_DEVICES_PDU1Handler_H_ */

View File

@ -1,18 +1,99 @@
/*
* PDU2Handler.cpp
*
* Created on: 23.01.2021
* Author: jakob
*/
#include "PDU2Handler.h"
#include <mission/devices/devicedefinitions/GomSpacePackets.h>
PDU2Handler::PDU2Handler() {
// TODO Auto-generated constructor stub
PDU2Handler::PDU2Handler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie, uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress,
uint16_t hkTableSize) : GomspaceDeviceHandler(objectId, comIF,
comCookie, maxConfigTableAddress, maxHkTableAddress, hkTableSize), hkTableDataset(this) {
}
PDU2Handler::~PDU2Handler() {
// TODO Auto-generated destructor stub
}
ReturnValue_t PDU2Handler::buildNormalDeviceCommand(
DeviceCommandId_t * id) {
*id = GOMSPACE::REQUEST_HK_TABLE;
return buildCommandFromCommand(*id, NULL, 0);
}
void PDU2Handler::letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) {
const uint8_t* payloadPtr = packet + GOMSPACE::GS_HDR_LENGTH;
size_t size = (size_t)hkTableSize;
hkTableDataset.deSerialize(&payloadPtr, &size, SerializeIF::Endianness::BIG);
FullTableReply fullTableReply(id, HK_TABLE_ID, &hkTableDataset);
handleDeviceTM(&fullTableReply, id, true);
}
ReturnValue_t PDU2Handler::initializeLocalDataPool(
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_Q7S, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_RW, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_TCS_BOARD_HEATER_IN, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_SUS_REDUNDANT, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_DEPLOYMENT_MECHANISM, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH6, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_ACS_BOARD_SIDE_B, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CURRENT_OUT_PAYLOAD_CAMERA, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_Q7S, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_RW, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_SUS_REDUNDANT, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_ACS_BOARD_SIDE_B, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VOLTAGE_OUT_PAYLOAD_CAMERA, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VCC, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_VBAT, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_TEMPERATURE, new PoolEntry<int16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_CONV_EN, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_Q7S, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_RW, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_SUS_REDUNDANT, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_ACS_BOARD_SIDE_B, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_OUT_EN_PAYLOAD_CAMERA, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_BOOTCAUSE, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_BOOTCNT, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_UPTIME, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_RESETCAUSE, new PoolEntry<uint16_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_BATT_MODE, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_0, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_1, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_2, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_3, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_4, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_5, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_6, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_7, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_0_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_1_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_2_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_3_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_4_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_5_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_6_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_DEVICE_7_STATUS, new PoolEntry<uint8_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CNT_GND, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CNT_I2C, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CNT_CAN, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CNT_CSP, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_GND_LEFT, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_I2C_LEFT, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CAN_LEFT, new PoolEntry<uint32_t>( { 0 }));
localDataPoolMap.emplace(PDU::PDU2_WDT_CSP_LEFT, new PoolEntry<uint32_t>( { 0 }));
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -2,6 +2,7 @@
#define MISSION_DEVICES_PDU2HANDLER_H_
#include "GomspaceDeviceHandler.h"
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
/**
* @brief This is the device handler for the PDU2.
@ -11,16 +12,31 @@
* Xiphos Q7S, 8V, channel 0
* Reaction wheels 5V, channel 2
* TCS Board heater input, 8V, channel 3
* SUS, 3,3V, channel 4
* SUS 8-12 Redundant, 3.3V, channel 4
* Deployment mechanism, 8V, channel 5
* P/L PCDU, 15,9V, channel 1 and channel 6
* ACS Board (Gyro, MGMs, GPS), 3,3V channel 7
* P/L PCDU, Battery voltage (Vnominal = 14.8V), channel 1 and channel 6
* ACS Board (Gyro, MGMs, GPS), 3.3V channel 7
* Payload Camera, 8V, channel 8
*/
class PDU2Handler: public GomspaceDeviceHandler {
public:
PDU2Handler();
PDU2Handler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie,
uint16_t maxConfigTableAddress, uint16_t maxHkTableAddress, uint16_t hkTableSize);
virtual ~PDU2Handler();
virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
protected:
/**
* @brief As soon as the device is in MODE_NORMAL, this function is executed periodically.
*/
virtual ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
virtual void letChildHandleHkReply(DeviceCommandId_t id, const uint8_t *packet) override;
private:
/** Dataset for the housekeeping table of the PDU2 */
PDU2::PDU2HkTableDataset hkTableDataset;
};
#endif /* MISSION_DEVICES_PDU2HANDLER_H_ */

View File

@ -137,10 +137,9 @@ uint32_t Tmp1075Handler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){
return 500;
}
ReturnValue_t Tmp1075Handler::initializeLocalDataPool(
LocalDataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
localDataPoolMap.emplace(TMP1075::TEMPERATURE_C_TMP1075_1,
new PoolEntry<float>({0.0}));
return HasReturnvaluesIF::RETURN_OK;
ReturnValue_t Tmp1075Handler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
localDataPoolMap.emplace(TMP1075::TEMPERATURE_C_TMP1075_1, new PoolEntry<float>( { 0.0 }));
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -36,8 +36,8 @@ protected:
const uint8_t *packet) override;
void setNormalDatapoolEntriesInvalid() override;
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
ReturnValue_t initializeLocalDataPool(LocalDataPool &localDataPoolMap,
LocalDataPoolManager &poolManager) override;
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) override;
private:

View File

@ -5,16 +5,7 @@
#include <fsfw/serialize/SerializeElement.h>
#include <fsfw/serialize/SerialLinkedListAdapter.h>
#include <fsfw/serialize/SerialFixedArrayListAdapter.h>
namespace GOMSPACE{
static const uint16_t IGNORE_CHECKSUM = 0xbb0;
/* CSP port to ping gomspace devices. */
static const uint8_t PING_PORT = 1;
static const uint8_t REBOOT_PORT = 4;
/* CSP port of gomspace devices to request or set parameters */
static const uint8_t PARAM_PORT = 7;
static const uint8_t P60_PORT_GNDWDT_RESET = 9;
}
#include <mission/devices/devicedefinitions/GomspaceDefinitions.h>
/**
@ -92,8 +83,6 @@ private:
class CspSetParamCommand : public SerialLinkedListAdapter<SerializeIF> {
public:
static const uint8_t GS_HDR_LENGTH = 12;
CspSetParamCommand(uint16_t querySize_, uint16_t payloadlength_,
uint16_t checksum_, uint16_t seq_, uint16_t total_, uint16_t addr_,
const uint8_t* parameter_, uint8_t parameterCount_) :
@ -178,7 +167,6 @@ private:
* device*/
SerializeElement<uint8_t> action = 0x00; // get param
SerializeElement<uint8_t> tableId;
/* Size of address. Set to 0 to get full table */
SerializeElement<uint16_t> addresslength;
SerializeElement<uint16_t> checksum;
SerializeElement<uint16_t> seq;
@ -187,14 +175,55 @@ private:
};
/**
* @brief This class can be used to generate a get param command for the
* gomspace devices which will be sent to the device communication
* interface object.
*
* @note cspPort and querySize only serve as information for the CspComIF
* and will not be transmitted physically to the target device.
*/
class RequestFullTableCommand : public SerialLinkedListAdapter<SerializeIF> {
public:
RequestFullTableCommand(uint16_t querySize_, uint8_t tableId) :
querySize(querySize_), tableId(tableId_) {
setLinks();
}
private:
RequestFullTableCommand(const RequestFullTableCommand &command);
void setLinks() {
setStart(&cspPort);
cspPort.setNext(&querySize);
querySize.setNext(&action);
action.setNext(&tableId);
tableId.setNext(&addresslength);
addresslength.setNext(&checksum);
checksum.setNext(&seq);
seq.setNext(&total);
}
SerializeElement<uint8_t> cspPort = GOMSPACE::PARAM_PORT;
/** Size of bytes to query (size of csp header + size of table) */
SerializeElement<uint16_t> querySize;
/* Following information will also be physically transmitted to the target
* device*/
SerializeElement<uint8_t> action = 0x00; // get param
SerializeElement<uint8_t> tableId;
/* Size of address. Set to 0 to get full table */
SerializeElement<uint16_t> addresslength = 0;
SerializeElement<uint16_t> checksum = GOMSPACE::IGNORE_CHECKSUM;
SerializeElement<uint16_t> seq = 0;
SerializeElement<uint16_t> total = 0;
};
/**
* @brief This class can be used to deserialize replies from gomspace devices
* and extract the relevant data.
*/
class CspGetParamReply : public SerialLinkedListAdapter<SerializeIF> {
public:
/* The size of the header of a gomspace CSP packet. */
static const uint8_t GS_HDR_LENGTH = 12;
/**
* @brief Constructor
*
@ -285,6 +314,38 @@ private:
SerializeElement<SerialBufferAdapter<uint16_t>> payload;
};
/**
* @brief This class generates the reply containing data from a full table request.
*/
class FullTableReply : public SerialLinkedListAdapter<SerializeIF> {
public:
/**
* @brief Constructor
*
* @param action_ The command which triggers the full table request.
* @param tableId_ The id of the requested table.
* @param tableDataset_ Pointer to the dataset holding the table data.
*/
FullTableReply(uint8_t action_, uint8_t tableId_, LocalPoolDataSetBase* tableDataset_) :
action(action_), tableId(tableId_), tableDataset(*tableDataset_) {
setLinks();
}
private:
FullTableReply(const FullTableReply &reply);
void setLinks() {
setStart(&action);
action.setNext(&tableId);
tableId.setNext(&tableLength);
tableLength.setNext(&tableDataset);
}
SerializeElement<uint8_t> action;
SerializeElement<uint8_t> tableId;
SerializeElement<LocalPoolDataSetBase> tableDataset;
};
/**
* @brief This class helps to unpack information from an action message
* to set a parameter in gomspace devices. The action message can be
@ -322,6 +383,46 @@ private:
};
/**
* @brief This class generates a message which can be sent to the GomspaceDeviceHandler to
* command a parameter change.
*
* @details Structure of set parameter command:
* | memory address | size of parameter value | parameter value |
*/
class GomspaceSetParamMessage : public SerialLinkedListAdapter<SerializeIF> {
public:
/* The size of the largest parameter */
static const uint32_t MAX_SIZE = 4;
/**
* @brief Constructor
*
* @param memoryAddress The address of the parameter to change in the configuration table.
* @param parameterValue Pointer to the parameter value to set.
* @param parameterSize The size of the parameter.
*
*/
GomspaceSetParamMessage(uint16_t memoryAddress, uint8_t* parameterValue, uint8_t parameterSize) :
memoryAddress(memoryAddress) {
const uint8_t** buffer;
*buffer = parameterValue;
parameterInfo.deserialize(buffer, parameterSize, SerializeIF::Endianness::BIG);
setLinks();
}
private:
GomspaceSetParamMessage(const FullTableReply &reply);
void setLinks() {
setStart(&memoryAddress);
memoryAddress.setNext(&parameter);
}
SerializeElement<uint16_t> memoryAddress;
SerializeElement<SerialFixedArrayListAdapter<uint8_t, MAX_SIZE, uint8_t>> parameterValueInfo;
};
/**
* @brief This class helps to unpack information from an action message
* to get a parameter from gomspace devices. The action message can be

View File

@ -9,8 +9,34 @@
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEDEFINITIONS_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEDEFINITIONS_H_
#include <stdint.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/datapoollocal/LocalPoolVariable.h>
namespace P60Dock{
namespace GOMSPACE{
static const uint16_t IGNORE_CHECKSUM = 0xbb0;
/** The size of the header of a gomspace CSP packet. */
static const uint8_t GS_HDR_LENGTH = 12;
/** CSP port to ping gomspace devices. */
static const uint8_t PING_PORT = 1;
static const uint8_t REBOOT_PORT = 4;
/** CSP port of gomspace devices to request or set parameters */
static const uint8_t PARAM_PORT = 7;
static const uint8_t P60_PORT_GNDWDT_RESET = 9;
/* Device commands are derived from the rparam.h of the gomspace lib */
static const DeviceCommandId_t PING = 0x1; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t NONE = 0x2; // Set when no command is pending
static const DeviceCommandId_t REBOOT = 0x4; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t GNDWDT_RESET = 0x9; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t PARAM_GET = 0x00; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t PARAM_SET = 0xFF; //!< [EXPORT] : [COMMAND]
static const DeviceCommandId_t REQUEST_HK_TABLE = 0x10; //!< [EXPORT] : [COMMAND]
}
namespace P60Dock {
/* The maximum size of a reply from the P60 dock. Maximum size is reached
* when retrieving the full parameter configuration table. 412 bytes of
* payload data and 12 bytes of CSP header data. */
@ -18,22 +44,509 @@ namespace P60Dock{
static const uint16_t MAX_CONFIGTABLE_ADDRESS = 408;
static const uint16_t MAX_HKTABLE_ADDRESS = 187;
static const uint16_t HK_TABLE_SIZE = 188;
}
/**
* @brief Constants common for both PDU1 and PDU2.
*/
namespace PDU{
/* When retrieving full configuration parameter table */
static const uint16_t MAX_REPLY_LENGTH = 318;
static const uint16_t MAX_CONFIGTABLE_ADDRESS = 316;
static const uint16_t MAX_HKTABLE_ADDRESS = 140;
static const uint16_t HK_TABLE_SIZE = 145;
static const uint8_t HK_TABLE_ENTRIES = 60;
enum PDUPoolIds: lp_id_t {
PDU1_CURRENT_OUT_TCS_BOARD_3V3,
PDU1_CURRENT_OUT_SYRLINKS,
PDU1_CURRENT_OUT_STAR_TRACKER,
PDU1_CURRENT_OUT_MGT,
PDU1_CURRENT_OUT_SUS_NOMINAL,
PDU1_CURRENT_OUT_SOLAR_CELL_EXP,
PDU1_CURRENT_OUT_PLOC,
PDU1_CURRENT_OUT_ACS_BOARD_SIDE_A,
PDU1_CURRENT_OUT_CHANNEL8,
PDU1_VOLTAGE_OUT_TCS_BOARD_3V3,
PDU1_VOLTAGE_OUT_SYRLINKS,
PDU1_VOLTAGE_OUT_STAR_TRACKER,
PDU1_VOLTAGE_OUT_MGT,
PDU1_VOLTAGE_OUT_SUS_NOMINAL,
PDU1_VOLTAGE_OUT_SOLAR_CELL_EXP,
PDU1_VOLTAGE_OUT_PLOC,
PDU1_VOLTAGE_OUT_ACS_BOARD_SIDE_A,
PDU1_VOLTAGE_OUT_CHANNEL8,
PDU1_VCC,
PDU1_VBAT,
PDU1_TEMPERATURE,
PDU1_CONV_EN,
PDU1_OUT_EN_TCS_BOARD_3V3,
PDU1_OUT_EN_SYRLINKS,
PDU1_OUT_EN_STAR_TRACKER,
PDU1_OUT_EN_MGT,
PDU1_OUT_EN_SUS_NOMINAL,
PDU1_OUT_EN_SOLAR_CELL_EXP,
PDU1_OUT_EN_PLOC,
PDU1_OUT_EN_ACS_BOARD_SIDE_A,
PDU1_OUT_EN_CHANNEL8,
PDU1_BOOTCAUSE,
PDU1_BOOTCNT,
PDU1_UPTIME,
PDU1_RESETCAUSE,
PDU1_BATT_MODE,
PDU1_LATCHUP,
PDU1_DEVICE_0,
PDU1_DEVICE_1,
PDU1_DEVICE_2,
PDU1_DEVICE_3,
PDU1_DEVICE_4,
PDU1_DEVICE_5,
PDU1_DEVICE_6,
PDU1_DEVICE_7,
PDU1_DEVICE_0_STATUS,
PDU1_DEVICE_1_STATUS,
PDU1_DEVICE_2_STATUS,
PDU1_DEVICE_3_STATUS,
PDU1_DEVICE_4_STATUS,
PDU1_DEVICE_5_STATUS,
PDU1_DEVICE_6_STATUS,
PDU1_DEVICE_7_STATUS,
PDU1_WDT_CNT_GND,
PDU1_WDT_CNT_I2C,
PDU1_WDT_CNT_CAN,
PDU1_WDT_CNT_CSP,
PDU1_WDT_GND_LEFT,
PDU1_WDT_I2C_LEFT,
PDU1_WDT_CAN_LEFT,
PDU1_WDT_CSP_LEFT,
PDU2_CURRENT_OUT_Q7S,
PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1,
PDU2_CURRENT_OUT_RW,
PDU2_CURRENT_OUT_TCS_BOARD_HEATER_IN,
PDU2_CURRENT_OUT_SUS_REDUNDANT,
PDU2_CURRENT_OUT_DEPLOYMENT_MECHANISM,
PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH6,
PDU2_CURRENT_OUT_ACS_BOARD_SIDE_B,
PDU2_CURRENT_OUT_PAYLOAD_CAMERA,
PDU2_VOLTAGE_OUT_Q7S,
PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1,
PDU2_VOLTAGE_OUT_RW,
PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN,
PDU2_VOLTAGE_OUT_SUS_REDUNDANT,
PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM,
PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6,
PDU2_VOLTAGE_OUT_ACS_BOARD_SIDE_B,
PDU2_VOLTAGE_OUT_PAYLOAD_CAMERA,
PDU2_VCC,
PDU2_VBAT,
PDU2_TEMPERATURE,
PDU2_CONV_EN,
PDU2_OUT_EN_Q7S,
PDU2_OUT_EN_PAYLOAD_PCDU_CH1,
PDU2_OUT_EN_RW,
PDU2_OUT_EN_TCS_BOARD_HEATER_IN,
PDU2_OUT_EN_SUS_REDUNDANT,
PDU2_OUT_EN_DEPLOYMENT_MECHANISM,
PDU2_OUT_EN_PAYLOAD_PCDU_CH6,
PDU2_OUT_EN_ACS_BOARD_SIDE_B,
PDU2_OUT_EN_PAYLOAD_CAMERA,
PDU2_BOOTCAUSE,
PDU2_BOOTCNT,
PDU2_UPTIME,
PDU2_RESETCAUSE,
PDU2_BATT_MODE,
PDU2_LATCHUP,
PDU2_DEVICE_0,
PDU2_DEVICE_1,
PDU2_DEVICE_2,
PDU2_DEVICE_3,
PDU2_DEVICE_4,
PDU2_DEVICE_5,
PDU2_DEVICE_6,
PDU2_DEVICE_7,
PDU2_DEVICE_0_STATUS,
PDU2_DEVICE_1_STATUS,
PDU2_DEVICE_2_STATUS,
PDU2_DEVICE_3_STATUS,
PDU2_DEVICE_4_STATUS,
PDU2_DEVICE_5_STATUS,
PDU2_DEVICE_6_STATUS,
PDU2_DEVICE_7_STATUS,
PDU2_WDT_CNT_GND,
PDU2_WDT_CNT_I2C,
PDU2_WDT_CNT_CAN,
PDU2_WDT_CNT_CSP,
PDU2_WDT_GND_LEFT,
PDU2_WDT_I2C_LEFT,
PDU2_WDT_CAN_LEFT,
PDU2_WDT_CSP_LEFT
};
}
namespace ACU{
/* When receiving full houskeeping (telemetry) table */
namespace PDU1 {
static const uint32_t HK_TABLE_DATA_SET_ID = 0x1; // hk table has table id 4
/**
* Addresses within configuration table to enable or disable output channels. Refer also to
* 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_SYRLINKS = 0x49;
static const uint16_t CONFIG_ADDRESS_OUT_EN_STAR_TRACKER = 0x50;
static const uint16_t CONFIG_ADDRESS_OUT_EN_MGT = 0x51;
static const uint16_t CONFIG_ADDRESS_OUT_EN_SUS_NOMINAL = 0x52;
static const uint16_t CONFIG_ADDRESS_OUT_EN_SOLAR_CELL_EXP = 0x53;
static const uint16_t CONFIG_ADDRESS_OUT_EN_PLOC = 0x54;
static const uint16_t CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_A = 0x55;
static const uint16_t CONFIG_ADDRESS_OUT_EN_CHANNEL8 = 0x56;
/**
* @brief This class defines a dataset for the hk table of the PDU1.
*/
class PDU1HkTableDataset :
public StaticLocalDataSet<PDU::HK_TABLE_ENTRIES> {
public:
PDU1HkTableDataset(HasLocalDataPoolIF* owner):
StaticLocalDataSet(owner, PDU1::HK_TABLE_DATA_SET_ID) {
}
PDU1HkTableDataset(object_id_t objectId):
StaticLocalDataSet(sid_t(objectId, PDU1::HK_TABLE_DATA_SET_ID)) {
}
/** Measured output currents */
lp_var_t<int16_t> currentOutTCSBoard3V3 = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_CURRENT_OUT_TCS_BOARD_3V3, this);
lp_var_t<int16_t> currentOutSyrlinks = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_CURRENT_OUT_SYRLINKS, this);
lp_var_t<int16_t> currentOutStarTracker = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_CURRENT_OUT_STAR_TRACKER, this);
lp_var_t<int16_t> currentOutMGT = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_CURRENT_OUT_MGT, this);
lp_var_t<int16_t> currentOutSUSNominal = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_CURRENT_OUT_SUS_NOMINAL, this);
lp_var_t<int16_t> currentOutSolarCellExp = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_CURRENT_OUT_SOLAR_CELL_EXP, this);
lp_var_t<int16_t> currentOutPLOC = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_CURRENT_OUT_PLOC, this);
lp_var_t<int16_t> currentOutACSBoardSideA = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_CURRENT_OUT_ACS_BOARD_SIDE_A, this);
lp_var_t<int16_t> currentOutChannel8 = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_CURRENT_OUT_CHANNEL8, this);
/** Measured voltage of output channels */
lp_var_t<int16_t> voltageOutTCSBoard3V3 = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VOLTAGE_OUT_TCS_BOARD_3V3, this);
lp_var_t<int16_t> voltageOutSyrlinks = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VOLTAGE_OUT_SYRLINKS, this);
lp_var_t<int16_t> voltageOutStarTracker = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VOLTAGE_OUT_STAR_TRACKER, this);
lp_var_t<int16_t> voltageOutMGT = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VOLTAGE_OUT_MGT, this);
lp_var_t<int16_t> voltageOutSUSNominal = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VOLTAGE_OUT_SUS_NOMINAL, this);
lp_var_t<int16_t> voltageOutSolarCellExp = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VOLTAGE_OUT_SOLAR_CELL_EXP, this);
lp_var_t<int16_t> voltageOutPLOC = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VOLTAGE_OUT_PLOC, this);
lp_var_t<int16_t> voltageOutACSBoardSideA = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VOLTAGE_OUT_ACS_BOARD_SIDE_A, this);
lp_var_t<int16_t> voltageOutChannel8 = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VOLTAGE_OUT_CHANNEL8, this);
/** Measured VCC */
lp_var_t<int16_t> vcc = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VCC, this);
/** Measured VBAT */
lp_var_t<int16_t> vbat = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_VBAT, this);
lp_var_t<int16_t> temperature = lp_var_t<int16_t>(sid.objectId,
PDU::PDU1_TEMPERATURE, this);
/** Output converter enable status */
lp_var_t<uint8_t> converterEnable = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_CONV_EN, this);
/** Output channels enable status */
lp_var_t<uint8_t> outEnabledTCSBoard3V3 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_OUT_EN_TCS_BOARD_3V3, this);
lp_var_t<uint8_t> outEnabledSyrlinks = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_OUT_EN_SYRLINKS, this);
lp_var_t<uint8_t> outEnabledStarTracker = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_OUT_EN_STAR_TRACKER, this);
lp_var_t<uint8_t> outEnabledMGT = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_OUT_EN_MGT, this);
lp_var_t<uint8_t> outEnabledSUSNominal = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_OUT_EN_SUS_NOMINAL, this);
lp_var_t<uint8_t> outEnabledSolarCellExp = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_OUT_EN_SOLAR_CELL_EXP, this);
lp_var_t<uint8_t> outEnabledPLOC = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_OUT_EN_PLOC, this);
lp_var_t<uint8_t> outEnabledAcsBoardSideA = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_OUT_EN_ACS_BOARD_SIDE_A, this);
lp_var_t<uint8_t> outEnabledChannel8 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_OUT_EN_CHANNEL8, this);
lp_var_t<uint32_t> bootcause = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_BOOTCAUSE, this);
/** Number of reboots */
lp_var_t<uint32_t> bootcount = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_BOOTCNT, this);
/** Uptime in seconds */
lp_var_t<uint32_t> uptime = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_UPTIME, this);
lp_var_t<uint16_t> resetcause = lp_var_t<uint16_t>(sid.objectId,
PDU::PDU1_RESETCAUSE, this);
/** Battery mode: 1 = Critical, 2 = Safe, 3 = Normal, 4 = Full */
lp_var_t<uint8_t> battMode = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_BATT_MODE, this);
/**
* There are 8 devices on the PDU. FRAM, ADCs, temperature sensor etc. Each device is
* identified by an ID. Refer also to gs-man-nanopower-p60-pdu-200-1.pdf on pages 17 and 18.
*/
lp_var_t<uint8_t> device0 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_0, this);
lp_var_t<uint8_t> device1 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_1, this);
lp_var_t<uint8_t> device2 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_2, this);
lp_var_t<uint8_t> device3 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_3, this);
lp_var_t<uint8_t> device4 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_4, this);
lp_var_t<uint8_t> device5 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_5, this);
lp_var_t<uint8_t> device6 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_6, this);
lp_var_t<uint8_t> device7 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_7, this);
/** The status of each device. 0 = None, 1 = Ok, 2 = Error, 3 = Not found */
lp_var_t<uint8_t> device0Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_0_STATUS, this);
lp_var_t<uint8_t> device1Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_1_STATUS, this);
lp_var_t<uint8_t> device2Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_2_STATUS, this);
lp_var_t<uint8_t> device3Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_3_STATUS, this);
lp_var_t<uint8_t> device4Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_4_STATUS, this);
lp_var_t<uint8_t> device5Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_5_STATUS, this);
lp_var_t<uint8_t> device6Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_6_STATUS, this);
lp_var_t<uint8_t> device7Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU1_DEVICE_7_STATUS, this);
/** Number of reboots triggered by the ground watchdog */
lp_var_t<uint32_t> gndWdtReboots = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_WDT_CNT_GND, this);
/** Number of reboots triggered through the I2C watchdog. Not relevant for EIVE. */
lp_var_t<uint32_t> i2cWdtReboots = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_WDT_CNT_I2C, this);
/** Number of reboots triggered through the CAN watchdog */
lp_var_t<uint32_t> canWdtReboots = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_WDT_CNT_CAN, this);
/** Number of reboots triggered through the CSP watchdog */
lp_var_t<uint32_t> cspWdtReboots = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_WDT_CNT_CSP, this);
/** Ground watchdog remaining seconds before rebooting */
lp_var_t<uint32_t> groundWatchdogSecondsLeft = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_WDT_GND_LEFT, this);
/** I2C watchdog remaining seconds before rebooting. Not relevant for EIVE. */
lp_var_t<uint32_t> i2cWatchdogSecondsLeft = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_WDT_I2C_LEFT, this);
/** CAN watchdog remaining seconds before rebooting. */
lp_var_t<uint32_t> canWatchdogSecondsLeft = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_WDT_CAN_LEFT, this);
/** CSP watchdog remaining seconds before rebooting. */
lp_var_t<uint32_t> cspWatchdogSecondsLeft = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU1_WDT_CSP_LEFT, this);
};
}
namespace PDU2 {
static const uint32_t HK_TABLE_DATA_SET_ID = 0x2;
/**
* Addresses within configuration table to enable or disable output channels. Refer also to
* gs-man-nanopower-p60-pdu-200.pdf on page 16.
*/
static const uint16_t CONFIG_ADDRESS_OUT_EN_Q7S = 0x48;
static const uint16_t CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH1 = 0x49;
static const uint16_t CONFIG_ADDRESS_OUT_EN_RW = 0x50;
static const uint16_t CONFIG_ADDRESS_OUT_EN_TCS_BOARD_HEATER_IN = 0x51;
static const uint16_t CONFIG_ADDRESS_OUT_EN_SUS_REDUNDANT = 0x52;
static const uint16_t CONFIG_ADDRESS_OUT_EN_DEPLOYMENT_MECHANISM = 0x53;
static const uint16_t CONFIG_ADDRESS_OUT_EN_PAYLOAD_PCDU_CH6PLOC = 0x54;
static const uint16_t CONFIG_ADDRESS_OUT_EN_ACS_BOARD_SIDE_B = 0x55;
static const uint16_t CONFIG_ADDRESS_OUT_EN_PAYLOAD_CAMERA = 0x56;
/**
* @brief This class defines a dataset for the hk table of the PDU2.
*/
class PDU2HkTableDataset:
public StaticLocalDataSet<PDU::HK_TABLE_ENTRIES> {
public:
PDU2HkTableDataset(HasLocalDataPoolIF* owner):
StaticLocalDataSet(owner, PDU2::HK_TABLE_DATA_SET_ID) {
}
PDU2HkTableDataset(object_id_t objectId):
StaticLocalDataSet(sid_t(objectId, PDU2::HK_TABLE_DATA_SET_ID)) {
}
/** Measured output currents */
lp_var_t<int16_t> currentOutQ7S = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_CURRENT_OUT_Q7S, this);
lp_var_t<int16_t> currentOutPayloadPCDUCh1 = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH1, this);
lp_var_t<int16_t> currentOutReactionWheels = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_CURRENT_OUT_RW, this);
lp_var_t<int16_t> currentOutTCSBoardHeaterIn = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_CURRENT_OUT_TCS_BOARD_HEATER_IN, this);
lp_var_t<int16_t> currentOutSUSRedundant = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_CURRENT_OUT_SUS_REDUNDANT, this);
lp_var_t<int16_t> currentOutDeplMechanism = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_CURRENT_OUT_DEPLOYMENT_MECHANISM, this);
lp_var_t<int16_t> currentOutPayloadPCDUCh6 = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_CURRENT_OUT_PAYLOAD_PCDU_CH6, this);
lp_var_t<int16_t> currentOutACSBoard = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_CURRENT_OUT_ACS_BOARD_SIDE_B, this);
lp_var_t<int16_t> currentOutPayloadCamera = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_CURRENT_OUT_PAYLOAD_CAMERA, this);
/** Measured voltage of output channels */
lp_var_t<int16_t> voltageOutQ7S = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VOLTAGE_OUT_Q7S, this);
lp_var_t<int16_t> voltageOutPayloadPCDUCh1 = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH1, this);
lp_var_t<int16_t> voltageOutReactionWheels = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VOLTAGE_OUT_RW, this);
lp_var_t<int16_t> voltageOutTCSBoardHeaterIn = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VOLTAGE_OUT_TCS_BOARD_HEATER_IN, this);
lp_var_t<int16_t> voltageOutSUS = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VOLTAGE_OUT_SUS_REDUNDANT, this);
lp_var_t<int16_t> voltageOutDeplMechanism = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VOLTAGE_OUT_DEPLOYMENT_MECHANISM, this);
lp_var_t<int16_t> voltageOutPayloadPCDUCh6 = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VOLTAGE_OUT_PAYLOAD_PCDU_CH6, this);
lp_var_t<int16_t> voltageOutACSBoard = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VOLTAGE_OUT_ACS_BOARD_SIDE_B, this);
lp_var_t<int16_t> voltageOutPayloadCamera = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VOLTAGE_OUT_PAYLOAD_CAMERA, this);
/** Measured VCC */
lp_var_t<int16_t> vcc = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VCC, this);
/** Measured VBAT */
lp_var_t<int16_t> vbat = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_VBAT, this);
lp_var_t<int16_t> temperature = lp_var_t<int16_t>(sid.objectId,
PDU::PDU2_TEMPERATURE, this);
/** Output converter enable status */
lp_var_t<uint8_t> converterEnable = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_CONV_EN, this);
/** Output channels enable status */
lp_var_t<uint8_t> outEnabledQ7S = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_OUT_EN_Q7S, this);
lp_var_t<uint8_t> outEnabledPlPCDUCh1 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH1, this);
lp_var_t<uint8_t> outEnabledReactionWheels = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_OUT_EN_RW, this);
lp_var_t<uint8_t> outEnabledTCSBoardHeaterIn = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_OUT_EN_TCS_BOARD_HEATER_IN, this);
lp_var_t<uint8_t> outEnabledSUS = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_OUT_EN_SUS_REDUNDANT, this);
lp_var_t<uint8_t> outEnabledDeplMechanism = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_OUT_EN_DEPLOYMENT_MECHANISM, this);
lp_var_t<uint8_t> outEnabledPlPCDUCh6 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_OUT_EN_PAYLOAD_PCDU_CH6, this);
lp_var_t<uint8_t> outEnabledAcsBoard = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_OUT_EN_ACS_BOARD_SIDE_B, this);
lp_var_t<uint8_t> outEnabledPayloadCamera = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_OUT_EN_PAYLOAD_CAMERA, this);
lp_var_t<uint32_t> bootcause = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_BOOTCAUSE, this);
/** Number of reboots */
lp_var_t<uint32_t> bootcount = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_BOOTCNT, this);
/** Uptime in seconds */
lp_var_t<uint32_t> uptime = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_UPTIME, this);
lp_var_t<uint16_t> resetcause = lp_var_t<uint16_t>(sid.objectId,
PDU::PDU2_RESETCAUSE, this);
/** Battery mode: 1 = Critical, 2 = Safe, 3 = Normal, 4 = Full */
lp_var_t<uint8_t> battMode = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_BATT_MODE, this);
/**
* There are 8 devices on the PDU. FRAM, ADCs, temperature sensor etc. Each device is
* identified by an ID. Refer also to gs-man-nanopower-p60-pdu-200-1.pdf on pages 17 and 18.
*/
lp_var_t<uint8_t> device0 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_0, this);
lp_var_t<uint8_t> device1 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_1, this);
lp_var_t<uint8_t> device2 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_2, this);
lp_var_t<uint8_t> device3 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_3, this);
lp_var_t<uint8_t> device4 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_4, this);
lp_var_t<uint8_t> device5 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_5, this);
lp_var_t<uint8_t> device6 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_6, this);
lp_var_t<uint8_t> device7 = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_7, this);
/** The status of each device. 0 = None, 1 = Ok, 2 = Error, 3 = Not found */
lp_var_t<uint8_t> device0Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_0_STATUS, this);
lp_var_t<uint8_t> device1Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_1_STATUS, this);
lp_var_t<uint8_t> device2Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_2_STATUS, this);
lp_var_t<uint8_t> device3Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_3_STATUS, this);
lp_var_t<uint8_t> device4Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_4_STATUS, this);
lp_var_t<uint8_t> device5Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_5_STATUS, this);
lp_var_t<uint8_t> device6Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_6_STATUS, this);
lp_var_t<uint8_t> device7Status = lp_var_t<uint8_t>(sid.objectId,
PDU::PDU2_DEVICE_7_STATUS, this);
/** Number of reboots triggered by the ground watchdog */
lp_var_t<uint32_t> gndWdtReboots = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_WDT_CNT_GND, this);
/** Number of reboots triggered through the I2C watchdog. Not relevant for EIVE. */
lp_var_t<uint32_t> i2cWdtReboots = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_WDT_CNT_I2C, this);
/** Number of reboots triggered through the CAN watchdog */
lp_var_t<uint32_t> canWdtReboots = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_WDT_CNT_CAN, this);
/** Number of reboots triggered through the CSP watchdog */
lp_var_t<uint32_t> cspWdtReboots = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_WDT_CNT_CSP, this);
/** Ground watchdog remaining seconds before rebooting */
lp_var_t<uint32_t> groundWatchdogSecondsLeft = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_WDT_GND_LEFT, this);
/** I2C watchdog remaining seconds before rebooting. Not relevant for EIVE. */
lp_var_t<uint32_t> i2cWatchdogSecondsLeft = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_WDT_I2C_LEFT, this);
/** CAN watchdog remaining seconds before rebooting. */
lp_var_t<uint32_t> canWatchdogSecondsLeft = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_WDT_CAN_LEFT, this);
/** CSP watchdog remaining seconds before rebooting. */
lp_var_t<uint32_t> cspWatchdogSecondsLeft = lp_var_t<uint32_t>(sid.objectId,
PDU::PDU2_WDT_CSP_LEFT, this);
};
}
namespace ACU {
/* When receiving full housekeeping (telemetry) table */
static const uint16_t MAX_REPLY_LENGTH = 124;
static const uint16_t MAX_CONFIGTABLE_ADDRESS = 26;
static const uint16_t MAX_HKTABLE_ADDRESS = 120;
static const uint16_t HK_TABLE_SIZE = 125;
}
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_GOMSPACEDEFINITIONS_H_ */