applied formatting
This commit is contained in:
@ -1,34 +1,32 @@
|
||||
#include "GpioCookie.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
|
||||
GpioCookie::GpioCookie() {
|
||||
}
|
||||
GpioCookie::GpioCookie() {}
|
||||
|
||||
ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioBase* gpioConfig){
|
||||
if (gpioConfig == nullptr) {
|
||||
sif::debug << "GpioCookie::addGpio: gpioConfig is nullpointer" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioBase* gpioConfig) {
|
||||
if (gpioConfig == nullptr) {
|
||||
sif::debug << "GpioCookie::addGpio: gpioConfig is nullpointer" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
auto gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
auto statusPair = gpioMap.emplace(gpioId, gpioConfig);
|
||||
if (statusPair.second == false) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << " to GPIO map"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
auto gpioMapIter = gpioMap.find(gpioId);
|
||||
if(gpioMapIter == gpioMap.end()) {
|
||||
auto statusPair = gpioMap.emplace(gpioId, gpioConfig);
|
||||
if (statusPair.second == false) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
sif::error << "GpioCookie::addGpio: Failed to add GPIO " << gpioId <<
|
||||
" to GPIO map" << std::endl;
|
||||
sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
sif::error << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl;
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
GpioMap GpioCookie::getGpioMap() const {
|
||||
return gpioMap;
|
||||
}
|
||||
GpioMap GpioCookie::getGpioMap() const { return gpioMap; }
|
||||
|
||||
GpioCookie::~GpioCookie() {}
|
||||
|
@ -1,11 +1,12 @@
|
||||
#ifndef LINUX_GPIO_GPIOCOOKIE_H_
|
||||
#define LINUX_GPIO_GPIOCOOKIE_H_
|
||||
|
||||
#include "GpioIF.h"
|
||||
#include "gpioDefinitions.h"
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include "GpioIF.h"
|
||||
#include "gpioDefinitions.h"
|
||||
|
||||
/**
|
||||
* @brief Cookie for the GpioIF. Allows the GpioIF to determine which
|
||||
* GPIOs to initialize and whether they should be configured as in- or
|
||||
@ -16,24 +17,23 @@
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class GpioCookie: public CookieIF {
|
||||
public:
|
||||
class GpioCookie : public CookieIF {
|
||||
public:
|
||||
GpioCookie();
|
||||
|
||||
GpioCookie();
|
||||
virtual ~GpioCookie();
|
||||
|
||||
virtual ~GpioCookie();
|
||||
ReturnValue_t addGpio(gpioId_t gpioId, GpioBase* gpioConfig);
|
||||
/**
|
||||
* @brief Get map with registered GPIOs.
|
||||
*/
|
||||
GpioMap getGpioMap() const;
|
||||
|
||||
ReturnValue_t addGpio(gpioId_t gpioId, GpioBase* gpioConfig);
|
||||
/**
|
||||
* @brief Get map with registered GPIOs.
|
||||
*/
|
||||
GpioMap getGpioMap() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Returns a copy of the internal GPIO map.
|
||||
*/
|
||||
GpioMap gpioMap;
|
||||
private:
|
||||
/**
|
||||
* Returns a copy of the internal GPIO map.
|
||||
*/
|
||||
GpioMap gpioMap;
|
||||
};
|
||||
|
||||
#endif /* LINUX_GPIO_GPIOCOOKIE_H_ */
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef LINUX_GPIO_GPIOIF_H_
|
||||
#define LINUX_GPIO_GPIOIF_H_
|
||||
|
||||
#include "gpioDefinitions.h"
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include "gpioDefinitions.h"
|
||||
|
||||
class GpioCookie;
|
||||
|
||||
@ -13,42 +14,41 @@ class GpioCookie;
|
||||
* @author J. Meier
|
||||
*/
|
||||
class GpioIF : public HasReturnvaluesIF {
|
||||
public:
|
||||
public:
|
||||
virtual ~GpioIF(){};
|
||||
|
||||
virtual ~GpioIF() {};
|
||||
/**
|
||||
* @brief Called by the GPIO using object.
|
||||
* @param cookie Cookie specifying informations of the GPIOs required
|
||||
* by a object.
|
||||
*/
|
||||
virtual ReturnValue_t addGpios(GpioCookie* cookie) = 0;
|
||||
|
||||
/**
|
||||
* @brief Called by the GPIO using object.
|
||||
* @param cookie Cookie specifying informations of the GPIOs required
|
||||
* by a object.
|
||||
*/
|
||||
virtual ReturnValue_t addGpios(GpioCookie* cookie) = 0;
|
||||
/**
|
||||
* @brief By implementing this function a child must provide the
|
||||
* functionality to pull a certain GPIO to high logic level.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||
* @return Returns RETURN_OK for success. This should never return RETURN_FAILED.
|
||||
*/
|
||||
virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0;
|
||||
|
||||
/**
|
||||
* @brief By implementing this function a child must provide the
|
||||
* functionality to pull a certain GPIO to high logic level.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||
* @return Returns RETURN_OK for success. This should never return RETURN_FAILED.
|
||||
*/
|
||||
virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0;
|
||||
/**
|
||||
* @brief By implementing this function a child must provide the
|
||||
* functionality to pull a certain GPIO to low logic level.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||
*/
|
||||
virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0;
|
||||
|
||||
/**
|
||||
* @brief By implementing this function a child must provide the
|
||||
* functionality to pull a certain GPIO to low logic level.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||
*/
|
||||
virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0;
|
||||
|
||||
/**
|
||||
* @brief This function requires a child to implement the functionality to read the state of
|
||||
* an ouput or input gpio.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to read.
|
||||
* @param gpioState State of GPIO will be written to this pointer.
|
||||
*/
|
||||
virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0;
|
||||
/**
|
||||
* @brief This function requires a child to implement the functionality to read the state of
|
||||
* an ouput or input gpio.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to read.
|
||||
* @param gpioState State of GPIO will be written to this pointer.
|
||||
*/
|
||||
virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0;
|
||||
};
|
||||
|
||||
#endif /* LINUX_GPIO_GPIOIF_H_ */
|
||||
|
@ -1,302 +1,295 @@
|
||||
#include "LinuxLibgpioIF.h"
|
||||
#include "GpioCookie.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
#include <gpiod.h>
|
||||
#include <linux/gpio/gpioDefinitions.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <utility>
|
||||
#include <unistd.h>
|
||||
#include <gpiod.h>
|
||||
|
||||
#include "GpioCookie.h"
|
||||
|
||||
LinuxLibgpioIF::LinuxLibgpioIF(object_id_t objectId) : SystemObject(objectId) {
|
||||
struct gpiod_chip* chip = gpiod_chip_open_by_label("/amba_pl/gpio@42030000");
|
||||
struct gpiod_chip* chip = gpiod_chip_open_by_label("/amba_pl/gpio@42030000");
|
||||
|
||||
sif::debug << chip->name << std::endl;
|
||||
sif::debug << chip->name << std::endl;
|
||||
}
|
||||
|
||||
LinuxLibgpioIF::~LinuxLibgpioIF() {
|
||||
}
|
||||
LinuxLibgpioIF::~LinuxLibgpioIF() {}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::addGpios(GpioCookie* gpioCookie) {
|
||||
ReturnValue_t result;
|
||||
if(gpioCookie == nullptr) {
|
||||
sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
ReturnValue_t result;
|
||||
if (gpioCookie == nullptr) {
|
||||
sif::error << "LinuxLibgpioIF::initialize: Invalid cookie" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
GpioMap mapToAdd = gpioCookie->getGpioMap();
|
||||
GpioMap mapToAdd = gpioCookie->getGpioMap();
|
||||
|
||||
/* Check whether this ID already exists in the map and remove duplicates */
|
||||
result = checkForConflicts(mapToAdd);
|
||||
if (result != RETURN_OK){
|
||||
return result;
|
||||
}
|
||||
/* Check whether this ID already exists in the map and remove duplicates */
|
||||
result = checkForConflicts(mapToAdd);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = configureGpios(mapToAdd);
|
||||
if (result != RETURN_OK) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
result = configureGpios(mapToAdd);
|
||||
if (result != RETURN_OK) {
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
/* Register new GPIOs in gpioMap */
|
||||
gpioMap.insert(mapToAdd.begin(), mapToAdd.end());
|
||||
/* Register new GPIOs in gpioMap */
|
||||
gpioMap.insert(mapToAdd.begin(), mapToAdd.end());
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::configureGpios(GpioMap& mapToAdd) {
|
||||
for(auto& gpioConfig: mapToAdd) {
|
||||
switch(gpioConfig.second->gpioType) {
|
||||
case(gpio::GpioTypes::NONE): {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
case(gpio::GpioTypes::GPIOD_REGULAR): {
|
||||
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
||||
if(regularGpio == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
configureRegularGpio(gpioConfig.first, regularGpio);
|
||||
break;
|
||||
}
|
||||
case(gpio::GpioTypes::CALLBACK): {
|
||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
||||
if(gpioCallback->callback == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
gpioCallback->callback(gpioConfig.first, gpio::GpioOperation::WRITE,
|
||||
gpioCallback->initValue, gpioCallback->callbackArgs);
|
||||
for (auto& gpioConfig : mapToAdd) {
|
||||
switch (gpioConfig.second->gpioType) {
|
||||
case (gpio::GpioTypes::NONE): {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
case (gpio::GpioTypes::GPIOD_REGULAR): {
|
||||
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
||||
if (regularGpio == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
configureRegularGpio(gpioConfig.first, regularGpio);
|
||||
break;
|
||||
}
|
||||
case (gpio::GpioTypes::CALLBACK): {
|
||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
||||
if (gpioCallback->callback == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
gpioCallback->callback(gpioConfig.first, gpio::GpioOperation::WRITE,
|
||||
gpioCallback->initValue, gpioCallback->callbackArgs);
|
||||
}
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular *regularGpio) {
|
||||
std::string chipname;
|
||||
unsigned int lineNum;
|
||||
struct gpiod_chip *chip;
|
||||
gpio::Direction direction;
|
||||
std::string consumer;
|
||||
struct gpiod_line *lineHandle;
|
||||
int result = 0;
|
||||
ReturnValue_t LinuxLibgpioIF::configureRegularGpio(gpioId_t gpioId, GpiodRegular* regularGpio) {
|
||||
std::string chipname;
|
||||
unsigned int lineNum;
|
||||
struct gpiod_chip* chip;
|
||||
gpio::Direction direction;
|
||||
std::string consumer;
|
||||
struct gpiod_line* lineHandle;
|
||||
int result = 0;
|
||||
|
||||
chipname = regularGpio->chipname;
|
||||
chip = gpiod_chip_open_by_name(chipname.c_str());
|
||||
if (!chip) {
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip "
|
||||
<< chipname << ". Gpio ID: " << gpioId << std::endl;
|
||||
chipname = regularGpio->chipname;
|
||||
chip = gpiod_chip_open_by_name(chipname.c_str());
|
||||
if (!chip) {
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open chip " << chipname
|
||||
<< ". Gpio ID: " << gpioId << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
lineNum = regularGpio->lineNum;
|
||||
lineHandle = gpiod_chip_get_line(chip, lineNum);
|
||||
if (!lineHandle) {
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line for GPIO with id " << gpioId
|
||||
<< std::endl;
|
||||
gpiod_chip_close(chip);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
direction = regularGpio->direction;
|
||||
consumer = regularGpio->consumer;
|
||||
/* Configure direction and add a description to the GPIO */
|
||||
switch (direction) {
|
||||
case (gpio::OUT): {
|
||||
result = gpiod_line_request_output(lineHandle, consumer.c_str(), regularGpio->initValue);
|
||||
if (result < 0) {
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum
|
||||
<< " from GPIO instance with ID: " << gpioId << std::endl;
|
||||
gpiod_line_release(lineHandle);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
lineNum = regularGpio->lineNum;
|
||||
lineHandle = gpiod_chip_get_line(chip, lineNum);
|
||||
if (!lineHandle) {
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to open line for GPIO with id "
|
||||
<< gpioId << std::endl;
|
||||
gpiod_chip_close(chip);
|
||||
case (gpio::IN): {
|
||||
result = gpiod_line_request_input(lineHandle, consumer.c_str());
|
||||
if (result < 0) {
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum
|
||||
<< " from GPIO instance with ID: " << gpioId << std::endl;
|
||||
gpiod_line_release(lineHandle);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
direction = regularGpio->direction;
|
||||
consumer = regularGpio->consumer;
|
||||
/* Configure direction and add a description to the GPIO */
|
||||
switch (direction) {
|
||||
case(gpio::OUT): {
|
||||
result = gpiod_line_request_output(lineHandle, consumer.c_str(),
|
||||
regularGpio->initValue);
|
||||
if (result < 0) {
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line " << lineNum <<
|
||||
" from GPIO instance with ID: " << gpioId << std::endl;
|
||||
gpiod_line_release(lineHandle);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(gpio::IN): {
|
||||
result = gpiod_line_request_input(lineHandle, consumer.c_str());
|
||||
if (result < 0) {
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Failed to request line "
|
||||
<< lineNum << " from GPIO instance with ID: " << gpioId << std::endl;
|
||||
gpiod_line_release(lineHandle);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified"
|
||||
<< std::endl;
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
sif::error << "LinuxLibgpioIF::configureGpios: Invalid direction specified" << std::endl;
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* Write line handle to GPIO configuration instance so it can later be used to set or
|
||||
* read states of GPIOs.
|
||||
*/
|
||||
regularGpio->lineHandle = lineHandle;
|
||||
return RETURN_OK;
|
||||
}
|
||||
/**
|
||||
* Write line handle to GPIO configuration instance so it can later be used to set or
|
||||
* read states of GPIOs.
|
||||
*/
|
||||
regularGpio->lineHandle = lineHandle;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::pullHigh(gpioId_t gpioId) {
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||
return UNKNOWN_GPIO_ID;
|
||||
}
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||
return UNKNOWN_GPIO_ID;
|
||||
}
|
||||
|
||||
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
||||
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 1);
|
||||
if (gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
||||
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 1);
|
||||
} else {
|
||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||
if (gpioCallback->callback == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
else {
|
||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||
if(gpioCallback->callback == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE,
|
||||
1, gpioCallback->callbackArgs);
|
||||
}
|
||||
return GPIO_TYPE_FAILURE;
|
||||
gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, 1,
|
||||
gpioCallback->callbackArgs);
|
||||
}
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::pullLow(gpioId_t gpioId) {
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||
return UNKNOWN_GPIO_ID;
|
||||
}
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
sif::warning << "LinuxLibgpioIF::driveGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||
return UNKNOWN_GPIO_ID;
|
||||
}
|
||||
|
||||
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
||||
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 0);
|
||||
if (gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
||||
return driveGpio(gpioId, dynamic_cast<GpiodRegular*>(gpioMapIter->second), 0);
|
||||
} else {
|
||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||
if (gpioCallback->callback == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
else {
|
||||
auto gpioCallback = dynamic_cast<GpioCallback*>(gpioMapIter->second);
|
||||
if(gpioCallback->callback == nullptr) {
|
||||
return GPIO_INVALID_INSTANCE;
|
||||
}
|
||||
gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE,
|
||||
0, gpioCallback->callbackArgs);
|
||||
}
|
||||
return GPIO_TYPE_FAILURE;
|
||||
gpioCallback->callback(gpioMapIter->first, gpio::GpioOperation::WRITE, 0,
|
||||
gpioCallback->callbackArgs);
|
||||
}
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId,
|
||||
GpiodRegular* regularGpio, unsigned int logicLevel) {
|
||||
if(regularGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
ReturnValue_t LinuxLibgpioIF::driveGpio(gpioId_t gpioId, GpiodRegular* regularGpio,
|
||||
unsigned int logicLevel) {
|
||||
if (regularGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
|
||||
int result = gpiod_line_set_value(regularGpio->lineHandle, logicLevel);
|
||||
if (result < 0) {
|
||||
sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId <<
|
||||
" to logic level " << logicLevel << std::endl;
|
||||
return DRIVE_GPIO_FAILURE;
|
||||
}
|
||||
int result = gpiod_line_set_value(regularGpio->lineHandle, logicLevel);
|
||||
if (result < 0) {
|
||||
sif::warning << "LinuxLibgpioIF::driveGpio: Failed to pull GPIO with ID " << gpioId
|
||||
<< " to logic level " << logicLevel << std::endl;
|
||||
return DRIVE_GPIO_FAILURE;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::readGpio(gpioId_t gpioId, int* gpioState) {
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()){
|
||||
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||
return UNKNOWN_GPIO_ID;
|
||||
gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
sif::warning << "LinuxLibgpioIF::readGpio: Unknown GPIOD ID " << gpioId << std::endl;
|
||||
return UNKNOWN_GPIO_ID;
|
||||
}
|
||||
|
||||
if (gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
||||
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
||||
if (regularGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
*gpioState = gpiod_line_get_value(regularGpio->lineHandle);
|
||||
} else {
|
||||
}
|
||||
|
||||
if(gpioMapIter->second->gpioType == gpio::GpioTypes::GPIOD_REGULAR) {
|
||||
GpiodRegular* regularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
||||
if(regularGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
*gpioState = gpiod_line_get_value(regularGpio->lineHandle);
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd){
|
||||
ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
for(auto& gpioConfig: mapToAdd) {
|
||||
switch(gpioConfig.second->gpioType) {
|
||||
case(gpio::GpioTypes::GPIOD_REGULAR): {
|
||||
auto regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
||||
if(regularGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
/* Check for conflicts and remove duplicates if necessary */
|
||||
result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio, mapToAdd);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = result;
|
||||
}
|
||||
break;
|
||||
ReturnValue_t LinuxLibgpioIF::checkForConflicts(GpioMap& mapToAdd) {
|
||||
ReturnValue_t status = HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
for (auto& gpioConfig : mapToAdd) {
|
||||
switch (gpioConfig.second->gpioType) {
|
||||
case (gpio::GpioTypes::GPIOD_REGULAR): {
|
||||
auto regularGpio = dynamic_cast<GpiodRegular*>(gpioConfig.second);
|
||||
if (regularGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
case(gpio::GpioTypes::CALLBACK): {
|
||||
auto callbackGpio = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
||||
if(callbackGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
/* Check for conflicts and remove duplicates if necessary */
|
||||
result = checkForConflictsCallbackGpio(gpioConfig.first, callbackGpio, mapToAdd);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = result;
|
||||
}
|
||||
break;
|
||||
/* Check for conflicts and remove duplicates if necessary */
|
||||
result = checkForConflictsRegularGpio(gpioConfig.first, regularGpio, mapToAdd);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = result;
|
||||
}
|
||||
default: {
|
||||
|
||||
break;
|
||||
}
|
||||
case (gpio::GpioTypes::CALLBACK): {
|
||||
auto callbackGpio = dynamic_cast<GpioCallback*>(gpioConfig.second);
|
||||
if (callbackGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
/* Check for conflicts and remove duplicates if necessary */
|
||||
result = checkForConflictsCallbackGpio(gpioConfig.first, callbackGpio, mapToAdd);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
status = result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::checkForConflictsRegularGpio(gpioId_t gpioIdToCheck,
|
||||
GpiodRegular* gpioToCheck, GpioMap& mapToAdd) {
|
||||
/* Cross check with private map */
|
||||
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||
if(gpioMapIter != gpioMap.end()) {
|
||||
if(gpioMapIter->second->gpioType != gpio::GpioTypes::GPIOD_REGULAR) {
|
||||
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
||||
"GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl;
|
||||
mapToAdd.erase(gpioIdToCheck);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
auto ownRegularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
||||
if(ownRegularGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
|
||||
/* Remove element from map to add because a entry for this GPIO
|
||||
already exists */
|
||||
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition"
|
||||
<< " detected. Duplicate will be removed from map to add." << std::endl;
|
||||
mapToAdd.erase(gpioIdToCheck);
|
||||
GpiodRegular* gpioToCheck,
|
||||
GpioMap& mapToAdd) {
|
||||
/* Cross check with private map */
|
||||
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||
if (gpioMapIter != gpioMap.end()) {
|
||||
if (gpioMapIter->second->gpioType != gpio::GpioTypes::GPIOD_REGULAR) {
|
||||
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
||||
"GPIO type"
|
||||
<< gpioIdToCheck << ". Removing duplicate." << std::endl;
|
||||
mapToAdd.erase(gpioIdToCheck);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
auto ownRegularGpio = dynamic_cast<GpiodRegular*>(gpioMapIter->second);
|
||||
if (ownRegularGpio == nullptr) {
|
||||
return GPIO_TYPE_FAILURE;
|
||||
}
|
||||
|
||||
/* Remove element from map to add because a entry for this GPIO
|
||||
already exists */
|
||||
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition"
|
||||
<< " detected. Duplicate will be removed from map to add." << std::endl;
|
||||
mapToAdd.erase(gpioIdToCheck);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LinuxLibgpioIF::checkForConflictsCallbackGpio(gpioId_t gpioIdToCheck,
|
||||
GpioCallback *callbackGpio, GpioMap& mapToAdd) {
|
||||
/* Cross check with private map */
|
||||
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||
if(gpioMapIter != gpioMap.end()) {
|
||||
if(gpioMapIter->second->gpioType != gpio::GpioTypes::CALLBACK) {
|
||||
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
||||
"GPIO type" << gpioIdToCheck << ". Removing duplicate." << std::endl;
|
||||
mapToAdd.erase(gpioIdToCheck);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
/* Remove element from map to add because a entry for this GPIO
|
||||
already exists */
|
||||
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition"
|
||||
<< " detected. Duplicate will be removed from map to add." << std::endl;
|
||||
mapToAdd.erase(gpioIdToCheck);
|
||||
GpioCallback* callbackGpio,
|
||||
GpioMap& mapToAdd) {
|
||||
/* Cross check with private map */
|
||||
gpioMapIter = gpioMap.find(gpioIdToCheck);
|
||||
if (gpioMapIter != gpioMap.end()) {
|
||||
if (gpioMapIter->second->gpioType != gpio::GpioTypes::CALLBACK) {
|
||||
sif::warning << "LinuxLibgpioIF::checkForConflicts: ID already exists for different "
|
||||
"GPIO type"
|
||||
<< gpioIdToCheck << ". Removing duplicate." << std::endl;
|
||||
mapToAdd.erase(gpioIdToCheck);
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
|
||||
/* Remove element from map to add because a entry for this GPIO
|
||||
already exists */
|
||||
sif::warning << "LinuxLibgpioIF::checkForConflictsRegularGpio: Duplicate GPIO definition"
|
||||
<< " detected. Duplicate will be removed from map to add." << std::endl;
|
||||
mapToAdd.erase(gpioIdToCheck);
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
#ifndef LINUX_GPIO_LINUXLIBGPIOIF_H_
|
||||
#define LINUX_GPIO_LINUXLIBGPIOIF_H_
|
||||
|
||||
#include <linux/gpio/GpioIF.h>
|
||||
#include <fsfwconfig/returnvalues/classIds.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfwconfig/returnvalues/classIds.h>
|
||||
#include <linux/gpio/GpioIF.h>
|
||||
|
||||
class GpioCookie;
|
||||
|
||||
@ -15,63 +15,61 @@ class GpioCookie;
|
||||
* 2019.1.
|
||||
*/
|
||||
class LinuxLibgpioIF : public GpioIF, public SystemObject {
|
||||
public:
|
||||
public:
|
||||
static const uint8_t gpioRetvalId = CLASS_ID::LINUX_LIBGPIO_IF;
|
||||
|
||||
static const uint8_t gpioRetvalId = CLASS_ID::LINUX_LIBGPIO_IF;
|
||||
static constexpr ReturnValue_t UNKNOWN_GPIO_ID =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 1);
|
||||
static constexpr ReturnValue_t DRIVE_GPIO_FAILURE =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 2);
|
||||
static constexpr ReturnValue_t GPIO_TYPE_FAILURE =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 3);
|
||||
static constexpr ReturnValue_t GPIO_INVALID_INSTANCE =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4);
|
||||
|
||||
static constexpr ReturnValue_t UNKNOWN_GPIO_ID =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 1);
|
||||
static constexpr ReturnValue_t DRIVE_GPIO_FAILURE =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 2);
|
||||
static constexpr ReturnValue_t GPIO_TYPE_FAILURE =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 3);
|
||||
static constexpr ReturnValue_t GPIO_INVALID_INSTANCE =
|
||||
HasReturnvaluesIF::makeReturnCode(gpioRetvalId, 4);
|
||||
LinuxLibgpioIF(object_id_t objectId);
|
||||
virtual ~LinuxLibgpioIF();
|
||||
|
||||
LinuxLibgpioIF(object_id_t objectId);
|
||||
virtual ~LinuxLibgpioIF();
|
||||
ReturnValue_t addGpios(GpioCookie* gpioCookie) override;
|
||||
ReturnValue_t pullHigh(gpioId_t gpioId) override;
|
||||
ReturnValue_t pullLow(gpioId_t gpioId) override;
|
||||
ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override;
|
||||
|
||||
ReturnValue_t addGpios(GpioCookie* gpioCookie) override;
|
||||
ReturnValue_t pullHigh(gpioId_t gpioId) override;
|
||||
ReturnValue_t pullLow(gpioId_t gpioId) override;
|
||||
ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) override;
|
||||
private:
|
||||
/* Holds the information and configuration of all used GPIOs */
|
||||
GpioMap gpioMap;
|
||||
GpioMapIter gpioMapIter;
|
||||
|
||||
private:
|
||||
/* Holds the information and configuration of all used GPIOs */
|
||||
GpioMap gpioMap;
|
||||
GpioMapIter gpioMapIter;
|
||||
/**
|
||||
* @brief This functions drives line of a GPIO specified by the GPIO ID.
|
||||
*
|
||||
* @param gpioId The GPIO ID of the GPIO to drive.
|
||||
* @param logiclevel The logic level to set. O or 1.
|
||||
*/
|
||||
ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio, unsigned int logiclevel);
|
||||
|
||||
/**
|
||||
* @brief This functions drives line of a GPIO specified by the GPIO ID.
|
||||
*
|
||||
* @param gpioId The GPIO ID of the GPIO to drive.
|
||||
* @param logiclevel The logic level to set. O or 1.
|
||||
*/
|
||||
ReturnValue_t driveGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio, unsigned int logiclevel);
|
||||
ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio);
|
||||
|
||||
ReturnValue_t configureRegularGpio(gpioId_t gpioId, GpiodRegularBase& regularGpio);
|
||||
/**
|
||||
* @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 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);
|
||||
|
||||
ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio,
|
||||
GpioMap& mapToAdd);
|
||||
ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio,
|
||||
GpioMap& mapToAdd);
|
||||
|
||||
/**
|
||||
* @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd.
|
||||
*/
|
||||
ReturnValue_t configureGpios(GpioMap& mapToAdd);
|
||||
ReturnValue_t checkForConflictsRegularGpio(gpioId_t gpiodId, GpiodRegular* regularGpio,
|
||||
GpioMap& mapToAdd);
|
||||
ReturnValue_t checkForConflictsCallbackGpio(gpioId_t gpiodId, GpioCallback* regularGpio,
|
||||
GpioMap& mapToAdd);
|
||||
|
||||
/**
|
||||
* @brief Performs the initial configuration of all GPIOs specified in the GpioMap mapToAdd.
|
||||
*/
|
||||
ReturnValue_t configureGpios(GpioMap& mapToAdd);
|
||||
};
|
||||
|
||||
#endif /* LINUX_GPIO_LINUXLIBGPIOIF_H_ */
|
||||
|
@ -8,29 +8,16 @@ using gpioId_t = uint16_t;
|
||||
|
||||
namespace gpio {
|
||||
|
||||
enum Levels {
|
||||
LOW = 0,
|
||||
HIGH = 1
|
||||
};
|
||||
enum Levels { LOW = 0, HIGH = 1 };
|
||||
|
||||
enum Direction {
|
||||
IN = 0,
|
||||
OUT = 1
|
||||
};
|
||||
enum Direction { IN = 0, OUT = 1 };
|
||||
|
||||
enum GpioOperation {
|
||||
READ,
|
||||
WRITE
|
||||
};
|
||||
enum GpioOperation { READ, WRITE };
|
||||
|
||||
enum GpioTypes {
|
||||
NONE,
|
||||
GPIOD_REGULAR,
|
||||
CALLBACK
|
||||
};
|
||||
enum GpioTypes { NONE, GPIOD_REGULAR, CALLBACK };
|
||||
|
||||
static constexpr gpioId_t NO_GPIO = -1;
|
||||
}
|
||||
} // namespace gpio
|
||||
|
||||
/**
|
||||
* @brief Struct containing information about the GPIO to use. This is
|
||||
@ -47,51 +34,49 @@ static constexpr gpioId_t NO_GPIO = -1;
|
||||
* pointer.
|
||||
*/
|
||||
class GpioBase {
|
||||
public:
|
||||
public:
|
||||
GpioBase() = default;
|
||||
|
||||
GpioBase() = default;
|
||||
GpioBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction, int initValue)
|
||||
: gpioType(gpioType), consumer(consumer), direction(direction), initValue(initValue) {}
|
||||
|
||||
GpioBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
|
||||
int initValue):
|
||||
gpioType(gpioType), consumer(consumer),direction(direction), initValue(initValue) {}
|
||||
virtual ~GpioBase(){};
|
||||
|
||||
virtual~ GpioBase() {};
|
||||
|
||||
/* Can be used to cast GpioBase to a concrete child implementation */
|
||||
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
|
||||
std::string consumer;
|
||||
gpio::Direction direction = gpio::Direction::IN;
|
||||
int initValue = 0;
|
||||
/* Can be used to cast GpioBase to a concrete child implementation */
|
||||
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
|
||||
std::string consumer;
|
||||
gpio::Direction direction = gpio::Direction::IN;
|
||||
int initValue = 0;
|
||||
};
|
||||
|
||||
class GpiodRegular: public GpioBase {
|
||||
public:
|
||||
GpiodRegular(): GpioBase(gpio::GpioTypes::GPIOD_REGULAR, std::string(),
|
||||
gpio::Direction::IN, 0) {};
|
||||
class GpiodRegular : public GpioBase {
|
||||
public:
|
||||
GpiodRegular()
|
||||
: GpioBase(gpio::GpioTypes::GPIOD_REGULAR, std::string(), gpio::Direction::IN, 0){};
|
||||
|
||||
GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_,
|
||||
gpio::Direction direction_, int initValue_):
|
||||
GpioBase(gpio::GpioTypes::GPIOD_REGULAR, consumer_, direction_, initValue_),
|
||||
chipname(chipname_), lineNum(lineNum_) {}
|
||||
std::string chipname;
|
||||
int lineNum = 0;
|
||||
struct gpiod_line* lineHandle = nullptr;
|
||||
GpiodRegular(std::string chipname_, int lineNum_, std::string consumer_,
|
||||
gpio::Direction direction_, int initValue_)
|
||||
: GpioBase(gpio::GpioTypes::GPIOD_REGULAR, consumer_, direction_, initValue_),
|
||||
chipname(chipname_),
|
||||
lineNum(lineNum_) {}
|
||||
std::string chipname;
|
||||
int lineNum = 0;
|
||||
struct gpiod_line* lineHandle = nullptr;
|
||||
};
|
||||
|
||||
class GpioCallback: public GpioBase {
|
||||
public:
|
||||
GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_,
|
||||
void (* callback) (gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args),
|
||||
void* callbackArgs):
|
||||
GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_),
|
||||
callback(callback), callbackArgs(callbackArgs) {}
|
||||
class GpioCallback : public GpioBase {
|
||||
public:
|
||||
GpioCallback(std::string consumer, gpio::Direction direction_, int initValue_,
|
||||
void (*callback)(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args),
|
||||
void* callbackArgs)
|
||||
: GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_),
|
||||
callback(callback),
|
||||
callbackArgs(callbackArgs) {}
|
||||
|
||||
void (* callback) (gpioId_t gpioId, gpio::GpioOperation gpioOp,
|
||||
int value, void* args) = nullptr;
|
||||
void* callbackArgs = nullptr;
|
||||
void (*callback)(gpioId_t gpioId, gpio::GpioOperation gpioOp, int value, void* args) = nullptr;
|
||||
void* callbackArgs = nullptr;
|
||||
};
|
||||
|
||||
|
||||
using GpioMap = std::unordered_map<gpioId_t, GpioBase*>;
|
||||
using GpioMapIter = GpioMap::iterator;
|
||||
|
||||
|
@ -1,136 +1,128 @@
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <linux/obc/Ptme.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
CCSDSIPCoreBridge::CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination,
|
||||
object_id_t tmStoreId, object_id_t tcStoreId, LinuxLibgpioIF* gpioComIF,
|
||||
std::string uioPtme, gpioId_t papbBusyId, gpioId_t papbEmptyId) :
|
||||
TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId), gpioComIF(gpioComIF), uioPtme(
|
||||
uioPtme), papbBusyId(papbBusyId), papbEmptyId(papbEmptyId) {
|
||||
}
|
||||
object_id_t tmStoreId, object_id_t tcStoreId,
|
||||
LinuxLibgpioIF* gpioComIF, std::string uioPtme,
|
||||
gpioId_t papbBusyId, gpioId_t papbEmptyId)
|
||||
: TmTcBridge(objectId, tcDestination, tmStoreId, tcStoreId),
|
||||
gpioComIF(gpioComIF),
|
||||
uioPtme(uioPtme),
|
||||
papbBusyId(papbBusyId),
|
||||
papbEmptyId(papbEmptyId) {}
|
||||
|
||||
CCSDSIPCoreBridge::~CCSDSIPCoreBridge() {
|
||||
}
|
||||
CCSDSIPCoreBridge::~CCSDSIPCoreBridge() {}
|
||||
|
||||
ReturnValue_t CCSDSIPCoreBridge::initialize() {
|
||||
ReturnValue_t result = TmTcBridge::initialize();
|
||||
ReturnValue_t result = TmTcBridge::initialize();
|
||||
|
||||
fd = open("/dev/uio0", O_RDWR);
|
||||
if (fd < 1) {
|
||||
sif::debug << "CCSDSIPCoreBridge::initialize: Invalid UIO device file" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
fd = open("/dev/uio0", O_RDWR);
|
||||
if (fd < 1) {
|
||||
sif::debug << "CCSDSIPCoreBridge::initialize: Invalid UIO device file" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map uio device in virtual address space
|
||||
* PROT_WRITE: Map uio device in writable only mode
|
||||
*/
|
||||
ptmeBaseAddress = static_cast<uint32_t*>(mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0));
|
||||
/**
|
||||
* Map uio device in virtual address space
|
||||
* PROT_WRITE: Map uio device in writable only mode
|
||||
*/
|
||||
ptmeBaseAddress =
|
||||
static_cast<uint32_t*>(mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
|
||||
|
||||
if (ptmeBaseAddress == MAP_FAILED) {
|
||||
sif::error << "CCSDSIPCoreBridge::initialize: Failed to map uio address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (ptmeBaseAddress == MAP_FAILED) {
|
||||
sif::error << "CCSDSIPCoreBridge::initialize: Failed to map uio address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSIPCoreBridge::handleTm() {
|
||||
|
||||
#if OBSW_TEST_CCSDS_PTME == 1
|
||||
return sendTestFrame();
|
||||
return sendTestFrame();
|
||||
#else
|
||||
return TmTcBridge::handleTm();
|
||||
return TmTcBridge::handleTm();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSIPCoreBridge::sendTm(const uint8_t * data, size_t dataLen) {
|
||||
ReturnValue_t CCSDSIPCoreBridge::sendTm(const uint8_t* data, size_t dataLen) {
|
||||
if (pollPapbBusySignal() == RETURN_OK) {
|
||||
startPacketTransfer();
|
||||
}
|
||||
|
||||
if(pollPapbBusySignal() == RETURN_OK) {
|
||||
startPacketTransfer();
|
||||
for (size_t idx = 0; idx < dataLen; idx++) {
|
||||
if (pollPapbBusySignal() == RETURN_OK) {
|
||||
*(ptmeBaseAddress + PTME_DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
|
||||
} else {
|
||||
sif::debug << "CCSDSIPCoreBridge::sendTm: Only written " << idx - 1 << " of " << dataLen
|
||||
<< " data" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t idx = 0; idx < dataLen; idx++) {
|
||||
if(pollPapbBusySignal() == RETURN_OK) {
|
||||
*(ptmeBaseAddress + PTME_DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
|
||||
}
|
||||
else {
|
||||
sif::debug << "CCSDSIPCoreBridge::sendTm: Only written " << idx - 1 << " of " << dataLen
|
||||
<< " data" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if(pollPapbBusySignal() == RETURN_OK) {
|
||||
endPacketTransfer();
|
||||
}
|
||||
return RETURN_OK;
|
||||
if (pollPapbBusySignal() == RETURN_OK) {
|
||||
endPacketTransfer();
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void CCSDSIPCoreBridge::startPacketTransfer() {
|
||||
*ptmeBaseAddress = PTME_CONFIG_START;
|
||||
}
|
||||
void CCSDSIPCoreBridge::startPacketTransfer() { *ptmeBaseAddress = PTME_CONFIG_START; }
|
||||
|
||||
void CCSDSIPCoreBridge::endPacketTransfer() {
|
||||
*ptmeBaseAddress = PTME_CONFIG_END;
|
||||
}
|
||||
void CCSDSIPCoreBridge::endPacketTransfer() { *ptmeBaseAddress = PTME_CONFIG_END; }
|
||||
|
||||
ReturnValue_t CCSDSIPCoreBridge::pollPapbBusySignal() {
|
||||
int papbBusyState = 0;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
int papbBusyState = 0;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
/** Check if PAPB interface is ready to receive data */
|
||||
result = gpioComIF->readGpio(papbBusyId, &papbBusyState);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: Failed to read papb busy signal"
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (!papbBusyState) {
|
||||
sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: PAPB busy" << std::endl;
|
||||
return PAPB_BUSY;
|
||||
}
|
||||
/** Check if PAPB interface is ready to receive data */
|
||||
result = gpioComIF->readGpio(papbBusyId, &papbBusyState);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: Failed to read papb busy signal"
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (!papbBusyState) {
|
||||
sif::debug << "CCSDSIPCoreBridge::pollPapbBusySignal: PAPB busy" << std::endl;
|
||||
return PAPB_BUSY;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void CCSDSIPCoreBridge::isPtmeBufferEmpty() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
int papbEmptyState = 1;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
int papbEmptyState = 1;
|
||||
|
||||
result = gpioComIF->readGpio(papbEmptyId, &papbEmptyState);
|
||||
result = gpioComIF->readGpio(papbEmptyId, &papbEmptyState);
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Failed to read papb empty signal"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (papbEmptyState == 1) {
|
||||
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is empty" << std::endl;
|
||||
}
|
||||
else {
|
||||
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is not empty" << std::endl;
|
||||
}
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Failed to read papb empty signal"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (papbEmptyState == 1) {
|
||||
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is empty" << std::endl;
|
||||
} else {
|
||||
sif::debug << "CCSDSIPCoreBridge::isPtmeBufferEmpty: Buffer is not empty" << std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ReturnValue_t CCSDSIPCoreBridge::sendTestFrame() {
|
||||
/** Size of one complete transfer frame data field amounts to 1105 bytes */
|
||||
uint8_t testPacket[1105];
|
||||
/** Size of one complete transfer frame data field amounts to 1105 bytes */
|
||||
uint8_t testPacket[1105];
|
||||
|
||||
/** Fill one test packet */
|
||||
for(int idx = 0; idx < 1105; idx++) {
|
||||
testPacket[idx] = static_cast<uint8_t>(idx & 0xFF);
|
||||
}
|
||||
/** Fill one test packet */
|
||||
for (int idx = 0; idx < 1105; idx++) {
|
||||
testPacket[idx] = static_cast<uint8_t>(idx & 0xFF);
|
||||
}
|
||||
|
||||
ReturnValue_t result = sendTm(testPacket, 1105);
|
||||
if(result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
ReturnValue_t result = sendTm(testPacket, 1105);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
@ -1,131 +1,129 @@
|
||||
#ifndef MISSION_OBC_CCSDSIPCOREBRIDGE_H_
|
||||
#define MISSION_OBC_CCSDSIPCOREBRIDGE_H_
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include <fsfw/tmtcservices/TmTcBridge.h>
|
||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
/**
|
||||
* @brief This class handles the interfacing to the telemetry (PTME) and telecommand (PDEC) IP
|
||||
* cores responsible for the CCSDS encoding and decoding. The IP cores are implemented
|
||||
* on the programmable logic and are accessible through the linux UIO driver.
|
||||
*/
|
||||
class CCSDSIPCoreBridge: public TmTcBridge {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId
|
||||
* @param tcDestination
|
||||
* @param tmStoreId
|
||||
* @param tcStoreId
|
||||
* @param uioPtme Name of the uio device file which provides access to the PTME IP Core.
|
||||
* @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the
|
||||
* PTME IP Core. A low logic level indicates the PTME is not ready to
|
||||
* receive more data.
|
||||
* @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the
|
||||
* PTME IP Core. The signal is high when there are no packets in the
|
||||
* external buffer memory (BRAM).
|
||||
*/
|
||||
CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
||||
object_id_t tcStoreId, LinuxLibgpioIF* gpioComIF, std::string uioPtme,
|
||||
gpioId_t papbBusyId, gpioId_t papbEmptyId);
|
||||
virtual ~CCSDSIPCoreBridge();
|
||||
class CCSDSIPCoreBridge : public TmTcBridge {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId
|
||||
* @param tcDestination
|
||||
* @param tmStoreId
|
||||
* @param tcStoreId
|
||||
* @param uioPtme Name of the uio device file which provides access to the PTME IP Core.
|
||||
* @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the
|
||||
* PTME IP Core. A low logic level indicates the PTME is not ready to
|
||||
* receive more data.
|
||||
* @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the
|
||||
* PTME IP Core. The signal is high when there are no packets in the
|
||||
* external buffer memory (BRAM).
|
||||
*/
|
||||
CCSDSIPCoreBridge(object_id_t objectId, object_id_t tcDestination, object_id_t tmStoreId,
|
||||
object_id_t tcStoreId, LinuxLibgpioIF* gpioComIF, std::string uioPtme,
|
||||
gpioId_t papbBusyId, gpioId_t papbEmptyId);
|
||||
virtual ~CCSDSIPCoreBridge();
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
/**
|
||||
* Overwriting this function to provide the capability of testing the PTME IP Core
|
||||
* implementation.
|
||||
*/
|
||||
virtual ReturnValue_t handleTm() override;
|
||||
|
||||
/**
|
||||
* Overwriting this function to provide the capability of testing the PTME IP Core
|
||||
* implementation.
|
||||
*/
|
||||
virtual ReturnValue_t handleTm() override;
|
||||
virtual ReturnValue_t sendTm(const uint8_t* data, size_t dataLen) override;
|
||||
|
||||
virtual ReturnValue_t sendTm(const uint8_t * data, size_t dataLen) override;
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE;
|
||||
|
||||
private:
|
||||
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE;
|
||||
/** Size of mapped address space. 4k (minimal size of pl device) */
|
||||
// static const int MAP_SIZE = 0xFA0;
|
||||
static const int MAP_SIZE = 0x1000;
|
||||
|
||||
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
|
||||
/**
|
||||
* Configuration bits:
|
||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||
* bit[2]: Set this bit to 1 to abort a transfered packet
|
||||
* bit[3]: Signals to PTME the start of a new telemetry packet
|
||||
*/
|
||||
static const uint32_t PTME_CONFIG_START = 0x8;
|
||||
|
||||
/**
|
||||
* Writing this word to the ptme base address signals to the PTME that a complete tm packet has
|
||||
* been transferred.
|
||||
*/
|
||||
static const uint32_t PTME_CONFIG_END = 0x0;
|
||||
|
||||
/** Size of mapped address space. 4k (minimal size of pl device) */
|
||||
// static const int MAP_SIZE = 0xFA0;
|
||||
static const int MAP_SIZE = 0x1000;
|
||||
/**
|
||||
* Writing to this offset within the PTME memory space will insert data for encoding to the
|
||||
* PTME IP core.
|
||||
* The address offset is 0x400 (= 4 * 256)
|
||||
*/
|
||||
static const int PTME_DATA_REG_OFFSET = 256;
|
||||
|
||||
/**
|
||||
* Configuration bits:
|
||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||
* bit[2]: Set this bit to 1 to abort a transfered packet
|
||||
* bit[3]: Signals to PTME the start of a new telemetry packet
|
||||
*/
|
||||
static const uint32_t PTME_CONFIG_START = 0x8;
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
|
||||
/**
|
||||
* Writing this word to the ptme base address signals to the PTME that a complete tm packet has
|
||||
* been transferred.
|
||||
*/
|
||||
static const uint32_t PTME_CONFIG_END = 0x0;
|
||||
/** The uio device file related to the PTME IP Core */
|
||||
std::string uioPtme;
|
||||
|
||||
/**
|
||||
* Writing to this offset within the PTME memory space will insert data for encoding to the
|
||||
* PTME IP core.
|
||||
* The address offset is 0x400 (= 4 * 256)
|
||||
*/
|
||||
static const int PTME_DATA_REG_OFFSET = 256;
|
||||
/** Pulled to low when PTME not ready to receive data */
|
||||
gpioId_t papbBusyId = gpio::NO_GPIO;
|
||||
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
/** High when externally buffer memory of PTME is empty */
|
||||
gpioId_t papbEmptyId = gpio::NO_GPIO;
|
||||
|
||||
/** The uio device file related to the PTME IP Core */
|
||||
std::string uioPtme;
|
||||
/** The file descriptor of the UIO driver */
|
||||
int fd;
|
||||
|
||||
/** Pulled to low when PTME not ready to receive data */
|
||||
gpioId_t papbBusyId = gpio::NO_GPIO;
|
||||
uint32_t* ptmeBaseAddress = nullptr;
|
||||
|
||||
/** High when externally buffer memory of PTME is empty */
|
||||
gpioId_t papbEmptyId = gpio::NO_GPIO;
|
||||
/**
|
||||
* @brief This function sends the config byte to the PTME IP Core to initiate a packet
|
||||
* transfer.
|
||||
*/
|
||||
void startPacketTransfer();
|
||||
|
||||
/** The file descriptor of the UIO driver */
|
||||
int fd;
|
||||
/**
|
||||
* @brief This function sends the config byte to the PTME IP Core to signal the end of a
|
||||
* packet transfer.
|
||||
*/
|
||||
void endPacketTransfer();
|
||||
|
||||
uint32_t* ptmeBaseAddress = nullptr;
|
||||
/**
|
||||
* @brief This function reads the papb busy signal indicating whether the PAPB interface is
|
||||
* ready to receive more data or not. PAPB is ready when PAPB_Busy_N == '1'.
|
||||
*
|
||||
* @return RETURN_OK when ready to receive data else PAPB_BUSY.
|
||||
*/
|
||||
ReturnValue_t pollPapbBusySignal();
|
||||
|
||||
/**
|
||||
* @brief This function sends the config byte to the PTME IP Core to initiate a packet
|
||||
* transfer.
|
||||
*/
|
||||
void startPacketTransfer();
|
||||
/**
|
||||
* @brief This function can be used for debugging to check wheter there are packets in
|
||||
* the packet buffer of the PTME or not.
|
||||
*/
|
||||
void isPtmeBufferEmpty();
|
||||
|
||||
/**
|
||||
* @brief This function sends the config byte to the PTME IP Core to signal the end of a
|
||||
* packet transfer.
|
||||
*/
|
||||
void endPacketTransfer();
|
||||
|
||||
/**
|
||||
* @brief This function reads the papb busy signal indicating whether the PAPB interface is
|
||||
* ready to receive more data or not. PAPB is ready when PAPB_Busy_N == '1'.
|
||||
*
|
||||
* @return RETURN_OK when ready to receive data else PAPB_BUSY.
|
||||
*/
|
||||
ReturnValue_t pollPapbBusySignal();
|
||||
|
||||
/**
|
||||
* @brief This function can be used for debugging to check wheter there are packets in
|
||||
* the packet buffer of the PTME or not.
|
||||
*/
|
||||
void isPtmeBufferEmpty();
|
||||
|
||||
/**
|
||||
* @brief This function sends a complete telemetry transfer frame data field (1105 bytes)
|
||||
* to the input of the PTME IP Core. Can be used to test the implementation.
|
||||
*/
|
||||
ReturnValue_t sendTestFrame();
|
||||
/**
|
||||
* @brief This function sends a complete telemetry transfer frame data field (1105 bytes)
|
||||
* to the input of the PTME IP Core. Can be used to test the implementation.
|
||||
*/
|
||||
ReturnValue_t sendTestFrame();
|
||||
};
|
||||
|
||||
#endif /* MISSION_OBC_CCSDSIPCOREBRIDGE_H_ */
|
||||
|
@ -1,8 +1,5 @@
|
||||
#include <linux/boardtest/I2cTestClass.h>
|
||||
|
||||
I2cTestClass::I2cTestClass(object_id_t objectId): TestTask(objectId) {
|
||||
}
|
||||
I2cTestClass::I2cTestClass(object_id_t objectId) : TestTask(objectId) {}
|
||||
|
||||
ReturnValue_t I2cTestClass::performPeriodicAction() {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
ReturnValue_t I2cTestClass::performPeriodicAction() { return HasReturnvaluesIF::RETURN_OK; }
|
||||
|
@ -3,15 +3,13 @@
|
||||
|
||||
#include <test/testtasks/TestTask.h>
|
||||
|
||||
class I2cTestClass: public TestTask {
|
||||
public:
|
||||
I2cTestClass(object_id_t objectId);
|
||||
class I2cTestClass : public TestTask {
|
||||
public:
|
||||
I2cTestClass(object_id_t objectId);
|
||||
|
||||
ReturnValue_t performPeriodicAction() override;
|
||||
private:
|
||||
ReturnValue_t performPeriodicAction() override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* LINUX_BOARDTEST_I2CTESTCLASS_H_ */
|
||||
|
@ -1,135 +1,127 @@
|
||||
#include "LibgpiodTest.h"
|
||||
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
|
||||
#include "devices/gpioIds.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
|
||||
LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId,
|
||||
GpioCookie* gpioCookie):
|
||||
TestTask(objectId) {
|
||||
|
||||
gpioInterface = ObjectManager::instance()->get<GpioIF>(gpioIfobjectId);
|
||||
if (gpioInterface == nullptr) {
|
||||
sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl;
|
||||
}
|
||||
gpioInterface->addGpios(gpioCookie);
|
||||
testCase = TestCases::BLINK;
|
||||
LibgpiodTest::LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie)
|
||||
: TestTask(objectId) {
|
||||
gpioInterface = ObjectManager::instance()->get<GpioIF>(gpioIfobjectId);
|
||||
if (gpioInterface == nullptr) {
|
||||
sif::error << "LibgpiodTest::LibgpiodTest: Invalid Gpio interface." << std::endl;
|
||||
}
|
||||
gpioInterface->addGpios(gpioCookie);
|
||||
testCase = TestCases::BLINK;
|
||||
}
|
||||
|
||||
LibgpiodTest::~LibgpiodTest() {
|
||||
}
|
||||
LibgpiodTest::~LibgpiodTest() {}
|
||||
|
||||
ReturnValue_t LibgpiodTest::performPeriodicAction() {
|
||||
int gpioState;
|
||||
ReturnValue_t result;
|
||||
int gpioState;
|
||||
ReturnValue_t result;
|
||||
|
||||
switch(testCase) {
|
||||
case(TestCases::READ): {
|
||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio "
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
else {
|
||||
sif::debug << "LibgpiodTest::performPeriodicAction: MIO 0 state = " << gpioState
|
||||
<< std::endl;
|
||||
}
|
||||
break;
|
||||
switch (testCase) {
|
||||
case (TestCases::READ): {
|
||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio " << std::endl;
|
||||
return RETURN_FAILED;
|
||||
} else {
|
||||
sif::debug << "LibgpiodTest::performPeriodicAction: MIO 0 state = " << gpioState
|
||||
<< std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(TestCases::LOOPBACK): {
|
||||
break;
|
||||
case (TestCases::LOOPBACK): {
|
||||
break;
|
||||
}
|
||||
case(TestCases::BLINK): {
|
||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
|
||||
case (TestCases::BLINK): {
|
||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_0, &gpioState);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio " << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (gpioState == 1) {
|
||||
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Failed to read gpio "
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO low!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
if (gpioState == 1) {
|
||||
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO low!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
else if (gpioState == 0) {
|
||||
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO high!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Invalid GPIO state" << std::endl;
|
||||
} else if (gpioState == 0) {
|
||||
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Could not pull GPIO high!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
} else {
|
||||
sif::warning << "LibgpiodTest::performPeriodicAction: Invalid GPIO state" << std::endl;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sif::debug << "LibgpiodTest::performPeriodicAction: Invalid test case" << std::endl;
|
||||
break;
|
||||
}
|
||||
sif::debug << "LibgpiodTest::performPeriodicAction: Invalid test case" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t LibgpiodTest::performOneShotAction() {
|
||||
int gpioState;
|
||||
ReturnValue_t result;
|
||||
int gpioState;
|
||||
ReturnValue_t result;
|
||||
|
||||
switch(testCase) {
|
||||
case(TestCases::READ): {
|
||||
break;
|
||||
switch (testCase) {
|
||||
case (TestCases::READ): {
|
||||
break;
|
||||
}
|
||||
case(TestCases::BLINK): {
|
||||
break;
|
||||
case (TestCases::BLINK): {
|
||||
break;
|
||||
}
|
||||
case(TestCases::LOOPBACK): {
|
||||
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
|
||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||
"GPIO pulled high successfully for loopback test" << std::endl;
|
||||
}
|
||||
else {
|
||||
sif::warning << "LibgpiodTest::performOneShotAction: Could not pull GPIO high!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState);
|
||||
if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 1) {
|
||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||
"GPIO state read successfully and is high" << std::endl;
|
||||
}
|
||||
else {
|
||||
sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not high!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
case (TestCases::LOOPBACK): {
|
||||
result = gpioInterface->pullHigh(gpioIds::TEST_ID_0);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||
"GPIO pulled high successfully for loopback test"
|
||||
<< std::endl;
|
||||
} else {
|
||||
sif::warning << "LibgpiodTest::performOneShotAction: Could not pull GPIO high!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK and gpioState == 1) {
|
||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||
"GPIO state read successfully and is high"
|
||||
<< std::endl;
|
||||
} else {
|
||||
sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not high!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
|
||||
if(result == HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||
"GPIO pulled low successfully for loopback test" << std::endl;
|
||||
}
|
||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState);
|
||||
if(result == HasReturnvaluesIF::RETURN_OK and gpioState == 0) {
|
||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||
"GPIO state read successfully and is low" << std::endl;
|
||||
}
|
||||
else {
|
||||
sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not low!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
break;
|
||||
result = gpioInterface->pullLow(gpioIds::TEST_ID_0);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||
"GPIO pulled low successfully for loopback test"
|
||||
<< std::endl;
|
||||
}
|
||||
result = gpioInterface->readGpio(gpioIds::TEST_ID_1, &gpioState);
|
||||
if (result == HasReturnvaluesIF::RETURN_OK and gpioState == 0) {
|
||||
sif::info << "LibgpiodTest::performOneShotAction: "
|
||||
"GPIO state read successfully and is low"
|
||||
<< std::endl;
|
||||
} else {
|
||||
sif::warning << "LibgpiodTest::performOneShotAction: GPIO read and is not low!"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -1,34 +1,31 @@
|
||||
#ifndef TEST_TESTTASKS_LIBGPIODTEST_H_
|
||||
#define TEST_TESTTASKS_LIBGPIODTEST_H_
|
||||
|
||||
#include "TestTask.h"
|
||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||
|
||||
#include "TestTask.h"
|
||||
|
||||
/**
|
||||
* @brief Test for the GPIO read implementation of the LinuxLibgpioIF.
|
||||
* @author J. Meier
|
||||
*/
|
||||
class LibgpiodTest: public TestTask {
|
||||
public:
|
||||
enum TestCases {
|
||||
READ = 0,
|
||||
LOOPBACK = 1,
|
||||
BLINK
|
||||
};
|
||||
class LibgpiodTest : public TestTask {
|
||||
public:
|
||||
enum TestCases { READ = 0, LOOPBACK = 1, BLINK };
|
||||
|
||||
TestCases testCase;
|
||||
TestCases testCase;
|
||||
|
||||
LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie);
|
||||
virtual ~LibgpiodTest();
|
||||
LibgpiodTest(object_id_t objectId, object_id_t gpioIfobjectId, GpioCookie* gpioCookie);
|
||||
virtual ~LibgpiodTest();
|
||||
|
||||
protected:
|
||||
ReturnValue_t performOneShotAction() override;
|
||||
ReturnValue_t performPeriodicAction() override;
|
||||
protected:
|
||||
ReturnValue_t performOneShotAction() override;
|
||||
ReturnValue_t performPeriodicAction() override;
|
||||
|
||||
private:
|
||||
GpioIF* gpioInterface;
|
||||
private:
|
||||
GpioIF* gpioInterface;
|
||||
};
|
||||
|
||||
#endif /* TEST_TESTTASKS_LIBGPIODTEST_H_ */
|
||||
|
@ -1,503 +1,483 @@
|
||||
#include "SpiTestClass.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||
#include <fsfw_hal/linux/UnixFileGuard.h>
|
||||
#include <fsfw_hal/linux/utility.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <bitset>
|
||||
|
||||
#include "devices/gpioIds.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterface.h>
|
||||
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||
#include <fsfw/tasks/TaskFactory.h>
|
||||
#include <fsfw/timemanager/Stopwatch.h>
|
||||
|
||||
#include <fsfw_hal/linux/utility.h>
|
||||
#include <fsfw_hal/linux/UnixFileGuard.h>
|
||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <bitset>
|
||||
|
||||
SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF* gpioIF): TestTask(objectId),
|
||||
gpioIF(gpioIF) {
|
||||
if(gpioIF == nullptr) {
|
||||
sif::error << "SpiTestClass::SpiTestClass: Invalid GPIO ComIF!" << std::endl;
|
||||
}
|
||||
testMode = TestModes::MGM_LIS3MDL;
|
||||
spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer.data());
|
||||
spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer.data());
|
||||
SpiTestClass::SpiTestClass(object_id_t objectId, GpioIF *gpioIF)
|
||||
: TestTask(objectId), gpioIF(gpioIF) {
|
||||
if (gpioIF == nullptr) {
|
||||
sif::error << "SpiTestClass::SpiTestClass: Invalid GPIO ComIF!" << std::endl;
|
||||
}
|
||||
testMode = TestModes::MGM_LIS3MDL;
|
||||
spiTransferStruct.rx_buf = reinterpret_cast<__u64>(recvBuffer.data());
|
||||
spiTransferStruct.tx_buf = reinterpret_cast<__u64>(sendBuffer.data());
|
||||
}
|
||||
|
||||
ReturnValue_t SpiTestClass::performOneShotAction() {
|
||||
switch(testMode) {
|
||||
case(TestModes::NONE): {
|
||||
break;
|
||||
switch (testMode) {
|
||||
case (TestModes::NONE): {
|
||||
break;
|
||||
}
|
||||
case(TestModes::MGM_LIS3MDL): {
|
||||
performLis3MdlTest(mgm0Lis3mdlChipSelect);
|
||||
break;
|
||||
case (TestModes::MGM_LIS3MDL): {
|
||||
performLis3MdlTest(mgm0Lis3mdlChipSelect);
|
||||
break;
|
||||
}
|
||||
case(TestModes::MGM_RM3100): {
|
||||
performRm3100Test(mgm1Rm3100ChipSelect);
|
||||
break;
|
||||
case (TestModes::MGM_RM3100): {
|
||||
performRm3100Test(mgm1Rm3100ChipSelect);
|
||||
break;
|
||||
}
|
||||
case(TestModes::GYRO_L3GD20H): {
|
||||
performL3gTest(gyro1L3gd20ChipSelect);
|
||||
break;
|
||||
case (TestModes::GYRO_L3GD20H): {
|
||||
performL3gTest(gyro1L3gd20ChipSelect);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t SpiTestClass::performPeriodicAction() {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
ReturnValue_t SpiTestClass::performPeriodicAction() { return HasReturnvaluesIF::RETURN_OK; }
|
||||
|
||||
void SpiTestClass::performRm3100Test(uint8_t mgmId) {
|
||||
/* Configure all SPI chip selects and pull them high */
|
||||
acsInit();
|
||||
/* Configure all SPI chip selects and pull them high */
|
||||
acsInit();
|
||||
|
||||
/* Adapt accordingly */
|
||||
if(mgmId != mgm1Rm3100ChipSelect and mgmId != mgm3Rm3100ChipSelect) {
|
||||
sif::warning << "SpiTestClass::performRm3100Test: Invalid MGM ID!" << std::endl;
|
||||
}
|
||||
gpioId_t currentGpioId = 0;
|
||||
uint8_t chipSelectPin = mgmId;
|
||||
if(chipSelectPin == mgm1Rm3100ChipSelect) {
|
||||
currentGpioId = gpioIds::MGM_1_RM3100_CS;
|
||||
}
|
||||
else {
|
||||
currentGpioId = gpioIds::MGM_3_RM3100_CS;
|
||||
}
|
||||
uint32_t rm3100speed = 976'000;
|
||||
uint8_t rm3100revidReg = 0x36;
|
||||
spi::SpiModes rm3100mode = spi::SpiModes::MODE_3;
|
||||
/* Adapt accordingly */
|
||||
if (mgmId != mgm1Rm3100ChipSelect and mgmId != mgm3Rm3100ChipSelect) {
|
||||
sif::warning << "SpiTestClass::performRm3100Test: Invalid MGM ID!" << std::endl;
|
||||
}
|
||||
gpioId_t currentGpioId = 0;
|
||||
uint8_t chipSelectPin = mgmId;
|
||||
if (chipSelectPin == mgm1Rm3100ChipSelect) {
|
||||
currentGpioId = gpioIds::MGM_1_RM3100_CS;
|
||||
} else {
|
||||
currentGpioId = gpioIds::MGM_3_RM3100_CS;
|
||||
}
|
||||
uint32_t rm3100speed = 976'000;
|
||||
uint8_t rm3100revidReg = 0x36;
|
||||
spi::SpiModes rm3100mode = spi::SpiModes::MODE_3;
|
||||
|
||||
#ifdef RASPBERRY_PI
|
||||
std::string deviceName = "/dev/spidev0.0";
|
||||
std::string deviceName = "/dev/spidev0.0";
|
||||
#else
|
||||
std::string deviceName = "/dev/spidev2.0";
|
||||
std::string deviceName = "/dev/spidev2.0";
|
||||
#endif
|
||||
int fileDescriptor = 0;
|
||||
int fileDescriptor = 0;
|
||||
|
||||
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||
if (fileHelper.getOpenResult()) {
|
||||
sif::error << "SpiTestClass::performRm3100Test: File descriptor could not be opened!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
setSpiSpeedAndMode(fileDescriptor, rm3100mode, rm3100speed);
|
||||
|
||||
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR,
|
||||
"SpiComIF::initializeInterface");
|
||||
if(fileHelper.getOpenResult()) {
|
||||
sif::error << "SpiTestClass::performRm3100Test: File descriptor could not be opened!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
setSpiSpeedAndMode(fileDescriptor, rm3100mode, rm3100speed);
|
||||
uint8_t revId = readRegister(fileDescriptor, currentGpioId, rm3100revidReg);
|
||||
sif::info << "SpiTestClass::performRm3100Test: Revision ID 0b" << std::bitset<8>(revId)
|
||||
<< std::endl;
|
||||
|
||||
uint8_t revId = readRegister(fileDescriptor, currentGpioId, rm3100revidReg);
|
||||
sif::info << "SpiTestClass::performRm3100Test: Revision ID 0b" << std::bitset<8>(revId) <<
|
||||
std::endl;
|
||||
/* Write configuration to CMM register */
|
||||
writeRegister(fileDescriptor, currentGpioId, 0x01, 0x75);
|
||||
uint8_t cmmRegister = readRm3100Register(fileDescriptor, currentGpioId, 0x01);
|
||||
sif::info << "SpiTestClass::performRm3100Test: CMM register value: " << std::hex << "0x"
|
||||
<< static_cast<int>(cmmRegister) << std::dec << std::endl;
|
||||
|
||||
/* Write configuration to CMM register */
|
||||
writeRegister(fileDescriptor, currentGpioId, 0x01, 0x75);
|
||||
uint8_t cmmRegister = readRm3100Register(fileDescriptor , currentGpioId, 0x01);
|
||||
sif::info << "SpiTestClass::performRm3100Test: CMM register value: " <<
|
||||
std::hex << "0x" << static_cast<int>(cmmRegister) << std::dec << std::endl;
|
||||
/* Read the cycle count registers */
|
||||
uint8_t cycleCountsRaw[6];
|
||||
readMultipleRegisters(fileDescriptor, currentGpioId, 0x04, cycleCountsRaw, 6);
|
||||
|
||||
/* Read the cycle count registers */
|
||||
uint8_t cycleCountsRaw[6];
|
||||
readMultipleRegisters(fileDescriptor, currentGpioId, 0x04, cycleCountsRaw, 6);
|
||||
uint16_t cycleCountX = cycleCountsRaw[0] << 8 | cycleCountsRaw[1];
|
||||
uint16_t cycleCountY = cycleCountsRaw[2] << 8 | cycleCountsRaw[3];
|
||||
uint16_t cycleCountZ = cycleCountsRaw[4] << 8 | cycleCountsRaw[5];
|
||||
|
||||
uint16_t cycleCountX = cycleCountsRaw[0] << 8 | cycleCountsRaw[1];
|
||||
uint16_t cycleCountY = cycleCountsRaw[2] << 8 | cycleCountsRaw[3];
|
||||
uint16_t cycleCountZ = cycleCountsRaw[4] << 8 | cycleCountsRaw[5];
|
||||
sif::info << "Cycle count X: " << cycleCountX << std::endl;
|
||||
sif::info << "Cycle count Y: " << cycleCountY << std::endl;
|
||||
sif::info << "Cycle count z: " << cycleCountZ << std::endl;
|
||||
|
||||
sif::info << "Cycle count X: " << cycleCountX << std::endl;
|
||||
sif::info << "Cycle count Y: " << cycleCountY << std::endl;
|
||||
sif::info << "Cycle count z: " << cycleCountZ << std::endl;
|
||||
|
||||
writeRegister(fileDescriptor, currentGpioId, 0x0B, 0x96);
|
||||
uint8_t tmrcReg = readRm3100Register(fileDescriptor, currentGpioId, 0x0B);
|
||||
sif::info << "SpiTestClass::performRm3100Test: TMRC register value: " <<
|
||||
std::hex << "0x" << static_cast<int>(tmrcReg) << std::dec << std::endl;
|
||||
writeRegister(fileDescriptor, currentGpioId, 0x0B, 0x96);
|
||||
uint8_t tmrcReg = readRm3100Register(fileDescriptor, currentGpioId, 0x0B);
|
||||
sif::info << "SpiTestClass::performRm3100Test: TMRC register value: " << std::hex << "0x"
|
||||
<< static_cast<int>(tmrcReg) << std::dec << std::endl;
|
||||
|
||||
TaskFactory::delayTask(10);
|
||||
uint8_t statusReg = readRm3100Register(fileDescriptor, currentGpioId, 0x34);
|
||||
sif::info << "SpiTestClass::performRm3100Test: Status Register 0b" << std::bitset<8>(statusReg)
|
||||
<< std::endl;
|
||||
/* This means that data is not ready */
|
||||
if ((statusReg & 0b1000'0000) == 0) {
|
||||
sif::warning << "SpiTestClass::performRm3100Test: Data not ready!" << std::endl;
|
||||
TaskFactory::delayTask(10);
|
||||
uint8_t statusReg = readRm3100Register(fileDescriptor, currentGpioId, 0x34);
|
||||
sif::info << "SpiTestClass::performRm3100Test: Status Register 0b" <<
|
||||
std::bitset<8>(statusReg) << std::endl;
|
||||
/* This means that data is not ready */
|
||||
if((statusReg & 0b1000'0000) == 0) {
|
||||
sif::warning << "SpiTestClass::performRm3100Test: Data not ready!" << std::endl;
|
||||
TaskFactory::delayTask(10);
|
||||
uint8_t statusReg = readRm3100Register(fileDescriptor, currentGpioId, 0x34);
|
||||
if((statusReg & 0b1000'0000) == 0) {
|
||||
return;
|
||||
}
|
||||
if ((statusReg & 0b1000'0000) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rm3100DefaultCycleCout = 0xC8;
|
||||
/* Gain scales lineary with cycle count and is 38 for cycle count 100 */
|
||||
float rm3100Gain = rm3100DefaultCycleCout / 100.0 * 38.0;
|
||||
float scaleFactor = 1 / rm3100Gain;
|
||||
uint8_t rawValues[9];
|
||||
readMultipleRegisters(fileDescriptor, currentGpioId, 0x24, rawValues, 9);
|
||||
uint32_t rm3100DefaultCycleCout = 0xC8;
|
||||
/* Gain scales lineary with cycle count and is 38 for cycle count 100 */
|
||||
float rm3100Gain = rm3100DefaultCycleCout / 100.0 * 38.0;
|
||||
float scaleFactor = 1 / rm3100Gain;
|
||||
uint8_t rawValues[9];
|
||||
readMultipleRegisters(fileDescriptor, currentGpioId, 0x24, rawValues, 9);
|
||||
|
||||
/* The sensor generates 24 bit signed values */
|
||||
int32_t rawX = ((rawValues[0] << 24) | (rawValues[1] << 16) | (rawValues[2] << 8)) >> 8;
|
||||
int32_t rawY = ((rawValues[3] << 24) | (rawValues[4] << 16) | (rawValues[5] << 8)) >> 8;
|
||||
int32_t rawZ = ((rawValues[6] << 24) | (rawValues[7] << 16) | (rawValues[8] << 8)) >> 8;
|
||||
/* The sensor generates 24 bit signed values */
|
||||
int32_t rawX = ((rawValues[0] << 24) | (rawValues[1] << 16) | (rawValues[2] << 8)) >> 8;
|
||||
int32_t rawY = ((rawValues[3] << 24) | (rawValues[4] << 16) | (rawValues[5] << 8)) >> 8;
|
||||
int32_t rawZ = ((rawValues[6] << 24) | (rawValues[7] << 16) | (rawValues[8] << 8)) >> 8;
|
||||
|
||||
float fieldStrengthX = rawX * scaleFactor;
|
||||
float fieldStrengthY = rawY * scaleFactor;
|
||||
float fieldStrengthZ = rawZ * scaleFactor;
|
||||
float fieldStrengthX = rawX * scaleFactor;
|
||||
float fieldStrengthY = rawY * scaleFactor;
|
||||
float fieldStrengthZ = rawZ * scaleFactor;
|
||||
|
||||
sif::info << "RM3100 measured field strengths in microtesla:" << std::endl;
|
||||
sif::info << "Field Strength X: " << fieldStrengthX << " uT" << std::endl;
|
||||
sif::info << "Field Strength Y: " << fieldStrengthY << " uT" << std::endl;
|
||||
sif::info << "Field Strength Z: " << fieldStrengthZ << " uT" << std::endl;
|
||||
sif::info << "RM3100 measured field strengths in microtesla:" << std::endl;
|
||||
sif::info << "Field Strength X: " << fieldStrengthX << " uT" << std::endl;
|
||||
sif::info << "Field Strength Y: " << fieldStrengthY << " uT" << std::endl;
|
||||
sif::info << "Field Strength Z: " << fieldStrengthZ << " uT" << std::endl;
|
||||
}
|
||||
|
||||
void SpiTestClass::performLis3MdlTest(uint8_t lis3Id) {
|
||||
/* Configure all SPI chip selects and pull them high */
|
||||
acsInit();
|
||||
/* Configure all SPI chip selects and pull them high */
|
||||
acsInit();
|
||||
|
||||
/* Adapt accordingly */
|
||||
if(lis3Id != mgm0Lis3mdlChipSelect and lis3Id != mgm2Lis3mdlChipSelect) {
|
||||
sif::warning << "SpiTestClass::performLis3MdlTest: Invalid MGM ID!" << std::endl;
|
||||
}
|
||||
gpioId_t currentGpioId = 0;
|
||||
uint8_t chipSelectPin = lis3Id;
|
||||
uint8_t whoAmIReg = 0b0000'1111;
|
||||
uint8_t whoAmIRegExpectedVal = 0b0011'1101;
|
||||
if(chipSelectPin == mgm0Lis3mdlChipSelect) {
|
||||
currentGpioId = gpioIds::MGM_0_LIS3_CS;
|
||||
}
|
||||
else {
|
||||
currentGpioId = gpioIds::MGM_2_LIS3_CS;
|
||||
}
|
||||
uint32_t spiSpeed = 10'000'000;
|
||||
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||
/* Adapt accordingly */
|
||||
if (lis3Id != mgm0Lis3mdlChipSelect and lis3Id != mgm2Lis3mdlChipSelect) {
|
||||
sif::warning << "SpiTestClass::performLis3MdlTest: Invalid MGM ID!" << std::endl;
|
||||
}
|
||||
gpioId_t currentGpioId = 0;
|
||||
uint8_t chipSelectPin = lis3Id;
|
||||
uint8_t whoAmIReg = 0b0000'1111;
|
||||
uint8_t whoAmIRegExpectedVal = 0b0011'1101;
|
||||
if (chipSelectPin == mgm0Lis3mdlChipSelect) {
|
||||
currentGpioId = gpioIds::MGM_0_LIS3_CS;
|
||||
} else {
|
||||
currentGpioId = gpioIds::MGM_2_LIS3_CS;
|
||||
}
|
||||
uint32_t spiSpeed = 10'000'000;
|
||||
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||
#ifdef RASPBERRY_PI
|
||||
std::string deviceName = "/dev/spidev0.0";
|
||||
std::string deviceName = "/dev/spidev0.0";
|
||||
#else
|
||||
std::string deviceName = "/dev/spidev2.0";
|
||||
std::string deviceName = "/dev/spidev2.0";
|
||||
#endif
|
||||
int fileDescriptor = 0;
|
||||
int fileDescriptor = 0;
|
||||
|
||||
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR,
|
||||
"SpiComIF::initializeInterface");
|
||||
if(fileHelper.getOpenResult()) {
|
||||
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||
spiTransferStruct.delay_usecs = 0;
|
||||
|
||||
uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false);
|
||||
sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b" <<
|
||||
std::bitset<8>(whoAmIRegVal) << std::endl;
|
||||
if(whoAmIRegVal != whoAmIRegExpectedVal) {
|
||||
sif::warning << "SpiTestClass::performLis3MdlTest: WHO AM I register invalid!"
|
||||
<< std::endl;
|
||||
}
|
||||
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||
if (fileHelper.getOpenResult()) {
|
||||
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||
spiTransferStruct.delay_usecs = 0;
|
||||
|
||||
uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false);
|
||||
sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b"
|
||||
<< std::bitset<8>(whoAmIRegVal) << std::endl;
|
||||
if (whoAmIRegVal != whoAmIRegExpectedVal) {
|
||||
sif::warning << "SpiTestClass::performLis3MdlTest: WHO AM I register invalid!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SpiTestClass::performL3gTest(uint8_t l3gId) {
|
||||
/* Configure all SPI chip selects and pull them high */
|
||||
acsInit();
|
||||
/* Configure all SPI chip selects and pull them high */
|
||||
acsInit();
|
||||
|
||||
gpioId_t currentGpioId = 0;
|
||||
uint8_t chipSelectPin = l3gId;
|
||||
uint8_t whoAmIReg = 0b0000'1111;
|
||||
uint8_t whoAmIRegExpectedVal = 0b1101'0111;
|
||||
gpioId_t currentGpioId = 0;
|
||||
uint8_t chipSelectPin = l3gId;
|
||||
uint8_t whoAmIReg = 0b0000'1111;
|
||||
uint8_t whoAmIRegExpectedVal = 0b1101'0111;
|
||||
|
||||
if(chipSelectPin == gyro1L3gd20ChipSelect) {
|
||||
currentGpioId = gpioIds::GYRO_1_L3G_CS;
|
||||
}
|
||||
else {
|
||||
currentGpioId = gpioIds::GYRO_3_L3G_CS;
|
||||
}
|
||||
uint32_t spiSpeed = 3'900'000;
|
||||
spi::SpiModes spiMode = spi::SpiModes::MODE_3;
|
||||
if (chipSelectPin == gyro1L3gd20ChipSelect) {
|
||||
currentGpioId = gpioIds::GYRO_1_L3G_CS;
|
||||
} else {
|
||||
currentGpioId = gpioIds::GYRO_3_L3G_CS;
|
||||
}
|
||||
uint32_t spiSpeed = 3'900'000;
|
||||
spi::SpiModes spiMode = spi::SpiModes::MODE_3;
|
||||
#ifdef RASPBERRY_PI
|
||||
std::string deviceName = "/dev/spidev0.0";
|
||||
std::string deviceName = "/dev/spidev0.0";
|
||||
#else
|
||||
std::string deviceName = "/dev/spidev2.0";
|
||||
std::string deviceName = "/dev/spidev2.0";
|
||||
#endif
|
||||
int fileDescriptor = 0;
|
||||
int fileDescriptor = 0;
|
||||
|
||||
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR,
|
||||
"SpiComIF::initializeInterface");
|
||||
if(fileHelper.getOpenResult()) {
|
||||
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||
uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false);
|
||||
sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b" <<
|
||||
std::bitset<8>(whoAmIRegVal) << std::endl;
|
||||
if(whoAmIRegVal != whoAmIRegExpectedVal) {
|
||||
sif::warning << "SpiTestClass::performL3gTest: Read WHO AM I register invalid!" <<
|
||||
std::endl;
|
||||
UnixFileGuard fileHelper(deviceName, &fileDescriptor, O_RDWR, "SpiComIF::initializeInterface");
|
||||
if (fileHelper.getOpenResult()) {
|
||||
sif::error << "SpiTestClass::performLis3Mdl3100Test: File descriptor could not be opened!"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
setSpiSpeedAndMode(fileDescriptor, spiMode, spiSpeed);
|
||||
uint8_t whoAmIRegVal = readStmRegister(fileDescriptor, currentGpioId, whoAmIReg, false);
|
||||
sif::info << "SpiTestClass::performLis3MdlTest: WHO AM I register 0b"
|
||||
<< std::bitset<8>(whoAmIRegVal) << std::endl;
|
||||
if (whoAmIRegVal != whoAmIRegExpectedVal) {
|
||||
sif::warning << "SpiTestClass::performL3gTest: Read WHO AM I register invalid!" << std::endl;
|
||||
}
|
||||
|
||||
uint8_t ctrlReg1Addr = 0b0010'0000;
|
||||
{
|
||||
uint8_t commandRegs[5];
|
||||
commandRegs[0] = 0b0000'1111;
|
||||
commandRegs[1] = 0x0;
|
||||
commandRegs[2] = 0x0;
|
||||
/* Configure big endian data format */
|
||||
commandRegs[3] = 0b0100'0000;
|
||||
commandRegs[4] = 0x0;
|
||||
writeMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, commandRegs,
|
||||
sizeof(commandRegs));
|
||||
uint8_t readRegs[5];
|
||||
readMultipleRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readRegs, sizeof(readRegs));
|
||||
for (uint8_t idx = 0; idx < sizeof(readRegs); idx++) {
|
||||
if (readRegs[idx] != commandRegs[0]) {
|
||||
sif::warning << "SpiTestClass::performL3gTest: Read control register "
|
||||
<< static_cast<int>(idx + 1) << " not equal to configured value" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ctrlReg1Addr = 0b0010'0000;
|
||||
{
|
||||
uint8_t commandRegs[5];
|
||||
commandRegs[0] = 0b0000'1111;
|
||||
commandRegs[1] = 0x0;
|
||||
commandRegs[2] = 0x0;
|
||||
/* Configure big endian data format */
|
||||
commandRegs[3] = 0b0100'0000;
|
||||
commandRegs[4] = 0x0;
|
||||
writeMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, commandRegs,
|
||||
sizeof(commandRegs));
|
||||
uint8_t readRegs[5];
|
||||
readMultipleRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readRegs,
|
||||
sizeof(readRegs));
|
||||
for(uint8_t idx = 0; idx < sizeof(readRegs); idx++) {
|
||||
if(readRegs[idx] != commandRegs[0]) {
|
||||
sif::warning << "SpiTestClass::performL3gTest: Read control register " <<
|
||||
static_cast<int>(idx + 1) << " not equal to configured value" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint8_t readOutBuffer[14];
|
||||
readMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readOutBuffer,
|
||||
sizeof(readOutBuffer));
|
||||
|
||||
uint8_t readOutBuffer[14];
|
||||
readMultipleStmRegisters(fileDescriptor, currentGpioId, ctrlReg1Addr, readOutBuffer,
|
||||
sizeof(readOutBuffer));
|
||||
uint8_t statusReg = readOutBuffer[7];
|
||||
sif::info << "SpiTestClass::performL3gTest: Status Register 0b" << std::bitset<8>(statusReg)
|
||||
<< std::endl;
|
||||
|
||||
uint8_t statusReg = readOutBuffer[7];
|
||||
sif::info << "SpiTestClass::performL3gTest: Status Register 0b" <<
|
||||
std::bitset<8>(statusReg) << std::endl;
|
||||
uint16_t l3gRange = 245;
|
||||
float scaleFactor = static_cast<float>(l3gRange) / INT16_MAX;
|
||||
/* The sensor spits out little endian */
|
||||
int16_t angVelocRawX = (readOutBuffer[8] << 8) | readOutBuffer[9];
|
||||
int16_t angVelocRawY = (readOutBuffer[10] << 8) | readOutBuffer[11];
|
||||
int16_t angVelocRawZ = (readOutBuffer[12] << 8) | readOutBuffer[13];
|
||||
|
||||
uint16_t l3gRange = 245;
|
||||
float scaleFactor = static_cast<float>(l3gRange) / INT16_MAX;
|
||||
/* The sensor spits out little endian */
|
||||
int16_t angVelocRawX = (readOutBuffer[8] << 8) | readOutBuffer[9];
|
||||
int16_t angVelocRawY = (readOutBuffer[10] << 8) | readOutBuffer[11];
|
||||
int16_t angVelocRawZ = (readOutBuffer[12] << 8) | readOutBuffer[13];
|
||||
|
||||
float angVelocX = scaleFactor * angVelocRawX;
|
||||
float angVelocY = scaleFactor * angVelocRawY;
|
||||
float angVelocZ = scaleFactor * angVelocRawZ;
|
||||
|
||||
sif::info << "Angular velocities for the L3GD20H in degrees per second:" << std::endl;
|
||||
sif::info << "X: " << angVelocX << std::endl;
|
||||
sif::info << "Y: " << angVelocY << std::endl;
|
||||
sif::info << "Z: " << angVelocZ << std::endl;
|
||||
float angVelocX = scaleFactor * angVelocRawX;
|
||||
float angVelocY = scaleFactor * angVelocRawY;
|
||||
float angVelocZ = scaleFactor * angVelocRawZ;
|
||||
|
||||
sif::info << "Angular velocities for the L3GD20H in degrees per second:" << std::endl;
|
||||
sif::info << "X: " << angVelocX << std::endl;
|
||||
sif::info << "Y: " << angVelocY << std::endl;
|
||||
sif::info << "Z: " << angVelocZ << std::endl;
|
||||
}
|
||||
|
||||
void SpiTestClass::acsInit() {
|
||||
GpioCookie* gpioCookie = new GpioCookie();
|
||||
GpioCookie *gpioCookie = new GpioCookie();
|
||||
|
||||
#ifdef RASPBERRY_PI
|
||||
GpiodRegularByChip* gpio = nullptr;
|
||||
std::string rpiGpioName = "gpiochip0";
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, mgm0Lis3mdlChipSelect, "MGM_0_LIS3",
|
||||
gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
|
||||
GpiodRegularByChip *gpio = nullptr;
|
||||
std::string rpiGpioName = "gpiochip0";
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, mgm0Lis3mdlChipSelect, "MGM_0_LIS3", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
|
||||
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100",
|
||||
gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, mgm1Rm3100ChipSelect, "MGM_1_RM3100", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
|
||||
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS",
|
||||
gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, gyro0AdisChipSelect, "GYRO_0_ADIS", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
|
||||
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G",
|
||||
gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, gyro1L3gd20ChipSelect, "GYRO_1_L3G", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
|
||||
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, gyro3L3gd20ChipSelect, "GYRO_2_L3G",
|
||||
gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio);
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, gyro3L3gd20ChipSelect, "GYRO_2_L3G", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio);
|
||||
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3",
|
||||
gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, mgm2Lis3mdlChipSelect, "MGM_2_LIS3", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
|
||||
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100",
|
||||
gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
|
||||
gpio = new GpiodRegularByChip(rpiGpioName, mgm3Rm3100ChipSelect, "MGM_3_RM3100", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
|
||||
#elif defined(XIPHOS_Q7S)
|
||||
GpiodRegularByLineName* gpio = nullptr;
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, "MGM_0_LIS3", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_1_RM3100", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, "MGM_2_LIS3", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_3_RM3100", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
|
||||
GpiodRegularByLineName *gpio = nullptr;
|
||||
gpio =
|
||||
new GpiodRegularByLineName(q7s::gpioNames::MGM_0_CS, "MGM_0_LIS3", gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_0_LIS3_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_1_RM3100", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_1_RM3100_CS, gpio);
|
||||
gpio =
|
||||
new GpiodRegularByLineName(q7s::gpioNames::MGM_2_CS, "MGM_2_LIS3", gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_2_LIS3_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::MGM_1_CS, "MGM_3_RM3100", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::MGM_3_RM3100_CS, gpio);
|
||||
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, "GYRO_0_ADIS",
|
||||
gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, "GYRO_1_L3G", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, "GYRO_2_ADIS",
|
||||
gpio::DIR_OUT, gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, "GYRO_3_L3G", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ADIS_CS, "GYRO_0_ADIS", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_0_ADIS_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_1_L3G_CS, "GYRO_1_L3G", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_1_L3G_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_2_ADIS_CS, "GYRO_2_ADIS", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_2_ADIS_CS, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_3_L3G_CS, "GYRO_3_L3G", gpio::DIR_OUT,
|
||||
gpio::HIGH);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_3_L3G_CS, gpio);
|
||||
|
||||
// Enable pins must be pulled low for regular operations
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_0_ENABLE", gpio::DIR_OUT,
|
||||
gpio::LOW);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_0_ENABLE, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_2_ENABLE", gpio::DIR_OUT,
|
||||
gpio::LOW);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_2_ENABLE, gpio);
|
||||
// Enable pins must be pulled low for regular operations
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_0_ENABLE", gpio::DIR_OUT,
|
||||
gpio::LOW);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_0_ENABLE, gpio);
|
||||
gpio = new GpiodRegularByLineName(q7s::gpioNames::GYRO_0_ENABLE, "GYRO_2_ENABLE", gpio::DIR_OUT,
|
||||
gpio::LOW);
|
||||
gpioCookie->addGpio(gpioIds::GYRO_2_ENABLE, gpio);
|
||||
#endif
|
||||
if (gpioIF != nullptr) {
|
||||
gpioIF->addGpios(gpioCookie);
|
||||
}
|
||||
if (gpioIF != nullptr) {
|
||||
gpioIF->addGpios(gpioCookie);
|
||||
}
|
||||
}
|
||||
|
||||
void SpiTestClass::setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed) {
|
||||
int mode_test = SPI_MODE_3;
|
||||
int retval = ioctl(spiFd, SPI_IOC_WR_MODE, &mode_test);//reinterpret_cast<uint8_t*>(&mode));
|
||||
if(retval != 0) {
|
||||
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!");
|
||||
}
|
||||
int mode_test = SPI_MODE_3;
|
||||
int retval = ioctl(spiFd, SPI_IOC_WR_MODE, &mode_test); // reinterpret_cast<uint8_t*>(&mode));
|
||||
if (retval != 0) {
|
||||
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI mode failed!");
|
||||
}
|
||||
|
||||
retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
||||
if(retval != 0) {
|
||||
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!");
|
||||
}
|
||||
retval = ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
|
||||
if (retval != 0) {
|
||||
utility::handleIoctlError("SpiTestClass::performRm3100Test: Setting SPI speed failed!");
|
||||
}
|
||||
}
|
||||
|
||||
void SpiTestClass::writeRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value) {
|
||||
spiTransferStruct.len = 2;
|
||||
sendBuffer[0] = reg;
|
||||
sendBuffer[1] = value;
|
||||
spiTransferStruct.len = 2;
|
||||
sendBuffer[0] = reg;
|
||||
sendBuffer[1] = value;
|
||||
|
||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullLow(chipSelect);
|
||||
}
|
||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||
if(retval < 0) {
|
||||
utility::handleIoctlError("SpiTestClass::writeRegister: Write failed");
|
||||
}
|
||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullHigh(chipSelect);
|
||||
}
|
||||
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullLow(chipSelect);
|
||||
}
|
||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||
if (retval < 0) {
|
||||
utility::handleIoctlError("SpiTestClass::writeRegister: Write failed");
|
||||
}
|
||||
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullHigh(chipSelect);
|
||||
}
|
||||
}
|
||||
|
||||
void SpiTestClass::writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value,
|
||||
bool autoIncrement) {
|
||||
if(autoIncrement) {
|
||||
reg |= STM_AUTO_INCR_MASK;
|
||||
}
|
||||
writeRegister(fd, chipSelect, reg, value);
|
||||
bool autoIncrement) {
|
||||
if (autoIncrement) {
|
||||
reg |= STM_AUTO_INCR_MASK;
|
||||
}
|
||||
writeRegister(fd, chipSelect, reg, value);
|
||||
}
|
||||
|
||||
void SpiTestClass::writeMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg,
|
||||
uint8_t *values, size_t len) {
|
||||
if(values == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
reg |= STM_AUTO_INCR_MASK;
|
||||
/* Clear read mask */
|
||||
reg &= ~STM_READ_MASK;
|
||||
writeMultipleRegisters(fd, chipSelect, reg, values, len);
|
||||
uint8_t *values, size_t len) {
|
||||
if (values == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
reg |= STM_AUTO_INCR_MASK;
|
||||
/* Clear read mask */
|
||||
reg &= ~STM_READ_MASK;
|
||||
writeMultipleRegisters(fd, chipSelect, reg, values, len);
|
||||
}
|
||||
|
||||
void SpiTestClass::writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg,
|
||||
uint8_t *values, size_t len) {
|
||||
if(values == nullptr) {
|
||||
return;
|
||||
}
|
||||
void SpiTestClass::writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *values,
|
||||
size_t len) {
|
||||
if (values == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendBuffer[0] = reg;
|
||||
std::memcpy(sendBuffer.data() + 1, values, len);
|
||||
spiTransferStruct.len = len + 1;
|
||||
sendBuffer[0] = reg;
|
||||
std::memcpy(sendBuffer.data() + 1, values, len);
|
||||
spiTransferStruct.len = len + 1;
|
||||
|
||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullLow(chipSelect);
|
||||
}
|
||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||
if(retval < 0) {
|
||||
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
||||
}
|
||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullHigh(chipSelect);
|
||||
}
|
||||
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullLow(chipSelect);
|
||||
}
|
||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||
if (retval < 0) {
|
||||
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
||||
}
|
||||
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullHigh(chipSelect);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t SpiTestClass::readRm3100Register(int fd, gpioId_t chipSelect, uint8_t reg) {
|
||||
return readStmRegister(fd, chipSelect, reg, false);
|
||||
return readStmRegister(fd, chipSelect, reg, false);
|
||||
}
|
||||
|
||||
|
||||
void SpiTestClass::readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply,
|
||||
size_t len) {
|
||||
reg |= STM_AUTO_INCR_MASK;
|
||||
readMultipleRegisters(fd, chipSelect, reg, reply, len);
|
||||
void SpiTestClass::readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg,
|
||||
uint8_t *reply, size_t len) {
|
||||
reg |= STM_AUTO_INCR_MASK;
|
||||
readMultipleRegisters(fd, chipSelect, reg, reply, len);
|
||||
}
|
||||
|
||||
void SpiTestClass::readMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply,
|
||||
size_t len) {
|
||||
if(reply == nullptr) {
|
||||
return;
|
||||
}
|
||||
size_t len) {
|
||||
if (reply == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
spiTransferStruct.len = len + 1;
|
||||
sendBuffer[0] = reg | STM_READ_MASK;
|
||||
spiTransferStruct.len = len + 1;
|
||||
sendBuffer[0] = reg | STM_READ_MASK;
|
||||
|
||||
for(uint8_t idx = 0; idx < len ; idx ++) {
|
||||
sendBuffer[idx + 1] = 0;
|
||||
}
|
||||
for (uint8_t idx = 0; idx < len; idx++) {
|
||||
sendBuffer[idx + 1] = 0;
|
||||
}
|
||||
|
||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullLow(chipSelect);
|
||||
}
|
||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||
if(retval < 0) {
|
||||
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
||||
}
|
||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullHigh(chipSelect);
|
||||
}
|
||||
std::memcpy(reply, recvBuffer.data() + 1, len);
|
||||
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullLow(chipSelect);
|
||||
}
|
||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||
if (retval < 0) {
|
||||
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
||||
}
|
||||
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullHigh(chipSelect);
|
||||
}
|
||||
std::memcpy(reply, recvBuffer.data() + 1, len);
|
||||
}
|
||||
|
||||
uint8_t SpiTestClass::readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg,
|
||||
bool autoIncrement) {
|
||||
reg |= STM_READ_MASK;
|
||||
if(autoIncrement) {
|
||||
reg |= STM_AUTO_INCR_MASK;
|
||||
}
|
||||
return readRegister(fd, chipSelect, reg);
|
||||
bool autoIncrement) {
|
||||
reg |= STM_READ_MASK;
|
||||
if (autoIncrement) {
|
||||
reg |= STM_AUTO_INCR_MASK;
|
||||
}
|
||||
return readRegister(fd, chipSelect, reg);
|
||||
}
|
||||
|
||||
|
||||
uint8_t SpiTestClass::readRegister(int fd, gpioId_t chipSelect, uint8_t reg) {
|
||||
spiTransferStruct.len = 2;
|
||||
sendBuffer[0] = reg;
|
||||
sendBuffer[1] = 0;
|
||||
spiTransferStruct.len = 2;
|
||||
sendBuffer[0] = reg;
|
||||
sendBuffer[1] = 0;
|
||||
|
||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullLow(chipSelect);
|
||||
}
|
||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||
if(retval < 0) {
|
||||
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
||||
}
|
||||
if(gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullHigh(chipSelect);
|
||||
}
|
||||
return recvBuffer[1];
|
||||
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullLow(chipSelect);
|
||||
}
|
||||
int retval = ioctl(fd, SPI_IOC_MESSAGE(1), &spiTransferStruct);
|
||||
if (retval < 0) {
|
||||
utility::handleIoctlError("SpiTestClass::readRegister: Read failed");
|
||||
}
|
||||
if (gpioIF != nullptr and chipSelect != gpio::NO_GPIO) {
|
||||
gpioIF->pullHigh(chipSelect);
|
||||
}
|
||||
return recvBuffer[1];
|
||||
}
|
||||
|
@ -13,83 +13,78 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
class SpiTestClass: public TestTask {
|
||||
public:
|
||||
enum TestModes {
|
||||
NONE,
|
||||
MGM_LIS3MDL,
|
||||
MGM_RM3100,
|
||||
GYRO_L3GD20H,
|
||||
};
|
||||
class SpiTestClass : public TestTask {
|
||||
public:
|
||||
enum TestModes {
|
||||
NONE,
|
||||
MGM_LIS3MDL,
|
||||
MGM_RM3100,
|
||||
GYRO_L3GD20H,
|
||||
};
|
||||
|
||||
TestModes testMode;
|
||||
TestModes testMode;
|
||||
|
||||
SpiTestClass(object_id_t objectId, GpioIF* gpioIF);
|
||||
SpiTestClass(object_id_t objectId, GpioIF* gpioIF);
|
||||
|
||||
ReturnValue_t performOneShotAction() override;
|
||||
ReturnValue_t performPeriodicAction() override;
|
||||
private:
|
||||
ReturnValue_t performOneShotAction() override;
|
||||
ReturnValue_t performPeriodicAction() override;
|
||||
|
||||
GpioIF* gpioIF;
|
||||
private:
|
||||
GpioIF* gpioIF;
|
||||
|
||||
std::array<uint8_t, 128> recvBuffer;
|
||||
std::array<uint8_t, 128> sendBuffer;
|
||||
struct spi_ioc_transfer spiTransferStruct = {};
|
||||
std::array<uint8_t, 128> recvBuffer;
|
||||
std::array<uint8_t, 128> sendBuffer;
|
||||
struct spi_ioc_transfer spiTransferStruct = {};
|
||||
|
||||
void performRm3100Test(uint8_t mgmId);
|
||||
void performLis3MdlTest(uint8_t lis3Id);
|
||||
void performL3gTest(uint8_t l3gId);
|
||||
void performRm3100Test(uint8_t mgmId);
|
||||
void performLis3MdlTest(uint8_t lis3Id);
|
||||
void performL3gTest(uint8_t l3gId);
|
||||
|
||||
/* ACS board specific code which pulls all GPIOs high */
|
||||
void acsInit();
|
||||
/* ACS board specific code which pulls all GPIOs high */
|
||||
void acsInit();
|
||||
|
||||
/* ACS board specific variables */
|
||||
/* ACS board specific variables */
|
||||
#ifdef RASPBERRY_PI
|
||||
uint8_t mgm0Lis3mdlChipSelect = gpio::MGM_0_BCM_PIN;
|
||||
uint8_t mgm1Rm3100ChipSelect = gpio::MGM_1_BCM_PIN;
|
||||
uint8_t mgm2Lis3mdlChipSelect = gpio::MGM_2_BCM_PIN;
|
||||
uint8_t mgm3Rm3100ChipSelect = gpio::MGM_3_BCM_PIN;
|
||||
uint8_t mgm0Lis3mdlChipSelect = gpio::MGM_0_BCM_PIN;
|
||||
uint8_t mgm1Rm3100ChipSelect = gpio::MGM_1_BCM_PIN;
|
||||
uint8_t mgm2Lis3mdlChipSelect = gpio::MGM_2_BCM_PIN;
|
||||
uint8_t mgm3Rm3100ChipSelect = gpio::MGM_3_BCM_PIN;
|
||||
|
||||
uint8_t gyro0AdisChipSelect = gpio::GYRO_0_BCM_PIN;
|
||||
uint8_t gyro1L3gd20ChipSelect = gpio::GYRO_1_BCM_PIN;
|
||||
uint8_t gyro2AdisChipSelect = gpio::GYRO_2_BCM_PIN;
|
||||
uint8_t gyro3L3gd20ChipSelect = gpio::GYRO_3_BCM_PIN;
|
||||
uint8_t gyro0AdisChipSelect = gpio::GYRO_0_BCM_PIN;
|
||||
uint8_t gyro1L3gd20ChipSelect = gpio::GYRO_1_BCM_PIN;
|
||||
uint8_t gyro2AdisChipSelect = gpio::GYRO_2_BCM_PIN;
|
||||
uint8_t gyro3L3gd20ChipSelect = gpio::GYRO_3_BCM_PIN;
|
||||
#else
|
||||
uint8_t mgm0Lis3mdlChipSelect = 0;
|
||||
uint8_t mgm1Rm3100ChipSelect = 0;
|
||||
uint8_t gyro0AdisResetLine = 0;
|
||||
uint8_t gyro0AdisChipSelect = 0;
|
||||
uint8_t gyro1L3gd20ChipSelect = 0;
|
||||
uint8_t gyro2L3gd20ChipSelect = 0;
|
||||
uint8_t mgm2Lis3mdlChipSelect = 0;
|
||||
uint8_t mgm3Rm3100ChipSelect = 0;
|
||||
uint8_t mgm0Lis3mdlChipSelect = 0;
|
||||
uint8_t mgm1Rm3100ChipSelect = 0;
|
||||
uint8_t gyro0AdisResetLine = 0;
|
||||
uint8_t gyro0AdisChipSelect = 0;
|
||||
uint8_t gyro1L3gd20ChipSelect = 0;
|
||||
uint8_t gyro2L3gd20ChipSelect = 0;
|
||||
uint8_t mgm2Lis3mdlChipSelect = 0;
|
||||
uint8_t mgm3Rm3100ChipSelect = 0;
|
||||
#endif
|
||||
|
||||
static constexpr uint8_t STM_READ_MASK = 0b1000'0000;
|
||||
static constexpr uint8_t RM3100_READ_MASK = STM_READ_MASK;
|
||||
static constexpr uint8_t STM_AUTO_INCR_MASK = 0b0100'0000;
|
||||
static constexpr uint8_t STM_READ_MASK = 0b1000'0000;
|
||||
static constexpr uint8_t RM3100_READ_MASK = STM_READ_MASK;
|
||||
static constexpr uint8_t STM_AUTO_INCR_MASK = 0b0100'0000;
|
||||
|
||||
void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed);
|
||||
void setSpiSpeedAndMode(int spiFd, spi::SpiModes mode, uint32_t speed);
|
||||
|
||||
void writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value,
|
||||
bool autoIncrement);
|
||||
void writeMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* values,
|
||||
size_t len);
|
||||
void writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *values,
|
||||
size_t len);
|
||||
void writeRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value);
|
||||
|
||||
uint8_t readRm3100Register(int fd, gpioId_t chipSelect, uint8_t reg);
|
||||
uint8_t readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, bool autoIncrement);
|
||||
uint8_t readRegister(int fd, gpioId_t chipSelect, uint8_t reg);
|
||||
void readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t *reply,
|
||||
size_t len);
|
||||
void readMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg,
|
||||
uint8_t* reply, size_t len);
|
||||
void writeStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value,
|
||||
bool autoIncrement);
|
||||
void writeMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* values,
|
||||
size_t len);
|
||||
void writeMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* values,
|
||||
size_t len);
|
||||
void writeRegister(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t value);
|
||||
|
||||
uint8_t readRm3100Register(int fd, gpioId_t chipSelect, uint8_t reg);
|
||||
uint8_t readStmRegister(int fd, gpioId_t chipSelect, uint8_t reg, bool autoIncrement);
|
||||
uint8_t readRegister(int fd, gpioId_t chipSelect, uint8_t reg);
|
||||
void readMultipleStmRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* reply,
|
||||
size_t len);
|
||||
void readMultipleRegisters(int fd, gpioId_t chipSelect, uint8_t reg, uint8_t* reply, size_t len);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* LINUX_BOARDTEST_SPITESTCLASS_H_ */
|
||||
|
@ -5,110 +5,107 @@
|
||||
#include "q7sConfig.h"
|
||||
#endif
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include <errno.h> // Error integer and strerror() function
|
||||
#include <fcntl.h> // Contains file controls like O_RDWR
|
||||
#include <unistd.h> // write(), read(), close()
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "lwgps/lwgps.h"
|
||||
|
||||
#include <fcntl.h> // Contains file controls like O_RDWR
|
||||
#include <errno.h> // Error integer and strerror() function
|
||||
#include <unistd.h> // write(), read(), close()
|
||||
#define GPS_REPLY_WIRETAPPING 0
|
||||
|
||||
#define GPS_REPLY_WIRETAPPING 0
|
||||
|
||||
UartTestClass::UartTestClass(object_id_t objectId): TestTask(objectId) {
|
||||
}
|
||||
UartTestClass::UartTestClass(object_id_t objectId) : TestTask(objectId) {}
|
||||
|
||||
ReturnValue_t UartTestClass::initialize() {
|
||||
#if RPI_TEST_GPS_DEVICE == 1
|
||||
int result = lwgps_init(&gpsData);
|
||||
if(result == 0) {
|
||||
sif::warning << "lwgps_init error: " << result << std::endl;
|
||||
}
|
||||
int result = lwgps_init(&gpsData);
|
||||
if (result == 0) {
|
||||
sif::warning << "lwgps_init error: " << result << std::endl;
|
||||
}
|
||||
|
||||
/* Get file descriptor */
|
||||
serialPort = open("/dev/serial0", O_RDWR);
|
||||
if(serialPort < 0) {
|
||||
sif::warning << "open call failed with error [" << errno << ", " << strerror(errno)
|
||||
<< std::endl;
|
||||
}
|
||||
/* Setting up UART parameters */
|
||||
tty.c_cflag &= ~PARENB; // Clear parity bit
|
||||
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication
|
||||
tty.c_cflag &= ~CSIZE; // Clear all the size bits
|
||||
tty.c_cflag |= CS8; // 8 bits per byte
|
||||
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
|
||||
tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
|
||||
// Use canonical mode for GPS device
|
||||
tty.c_lflag |= ICANON;
|
||||
tty.c_lflag &= ~ECHO; // Disable echo
|
||||
tty.c_lflag &= ~ECHOE; // Disable erasure
|
||||
tty.c_lflag &= ~ECHONL; // Disable new-line echo
|
||||
tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
|
||||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
|
||||
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes
|
||||
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
|
||||
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
|
||||
/* Get file descriptor */
|
||||
serialPort = open("/dev/serial0", O_RDWR);
|
||||
if (serialPort < 0) {
|
||||
sif::warning << "open call failed with error [" << errno << ", " << strerror(errno)
|
||||
<< std::endl;
|
||||
}
|
||||
/* Setting up UART parameters */
|
||||
tty.c_cflag &= ~PARENB; // Clear parity bit
|
||||
tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication
|
||||
tty.c_cflag &= ~CSIZE; // Clear all the size bits
|
||||
tty.c_cflag |= CS8; // 8 bits per byte
|
||||
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
|
||||
tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
|
||||
// Use canonical mode for GPS device
|
||||
tty.c_lflag |= ICANON;
|
||||
tty.c_lflag &= ~ECHO; // Disable echo
|
||||
tty.c_lflag &= ~ECHOE; // Disable erasure
|
||||
tty.c_lflag &= ~ECHONL; // Disable new-line echo
|
||||
tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
|
||||
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
|
||||
tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR |
|
||||
ICRNL); // Disable any special handling of received bytes
|
||||
tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
|
||||
tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
|
||||
|
||||
// Non-blocking mode
|
||||
tty.c_cc[VTIME] = 0;
|
||||
tty.c_cc[VMIN] = 0;
|
||||
// Non-blocking mode
|
||||
tty.c_cc[VTIME] = 0;
|
||||
tty.c_cc[VMIN] = 0;
|
||||
|
||||
cfsetispeed(&tty, B9600);
|
||||
cfsetospeed(&tty, B9600);
|
||||
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
|
||||
sif::warning << "tcsetattr call failed with error [" << errno << ", " <<
|
||||
strerror(errno) << std::endl;;
|
||||
}
|
||||
// Flush received and unread data. Those are old NMEA strings which are not relevant anymore
|
||||
tcflush(serialPort, TCIFLUSH);
|
||||
cfsetispeed(&tty, B9600);
|
||||
cfsetospeed(&tty, B9600);
|
||||
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
|
||||
sif::warning << "tcsetattr call failed with error [" << errno << ", " << strerror(errno)
|
||||
<< std::endl;
|
||||
;
|
||||
}
|
||||
// Flush received and unread data. Those are old NMEA strings which are not relevant anymore
|
||||
tcflush(serialPort, TCIFLUSH);
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t UartTestClass::performOneShotAction() {
|
||||
#if RPI_TEST_GPS_DEVICE == 1
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t UartTestClass::performPeriodicAction() {
|
||||
#if RPI_TEST_GPS_DEVICE == 1
|
||||
int bytesRead = 0;
|
||||
do {
|
||||
bytesRead = read(serialPort,
|
||||
reinterpret_cast<void*>(recBuf.data()),
|
||||
static_cast<unsigned int>(recBuf.size()));
|
||||
if(bytesRead < 0) {
|
||||
sif::warning << "UartTestClass::performPeriodicAction: read call failed with error [" <<
|
||||
errno << ", " << strerror(errno) << "]" << std::endl;
|
||||
break;
|
||||
}
|
||||
else if(bytesRead >= static_cast<int>(recBuf.size())) {
|
||||
sif::debug << "UartTestClass::performPeriodicAction: "
|
||||
"recv buffer might not be large enough" << std::endl;
|
||||
}
|
||||
else if(bytesRead > 0) {
|
||||
// pass data to lwgps for processing
|
||||
int bytesRead = 0;
|
||||
do {
|
||||
bytesRead = read(serialPort, reinterpret_cast<void*>(recBuf.data()),
|
||||
static_cast<unsigned int>(recBuf.size()));
|
||||
if (bytesRead < 0) {
|
||||
sif::warning << "UartTestClass::performPeriodicAction: read call failed with error [" << errno
|
||||
<< ", " << strerror(errno) << "]" << std::endl;
|
||||
break;
|
||||
} else if (bytesRead >= static_cast<int>(recBuf.size())) {
|
||||
sif::debug << "UartTestClass::performPeriodicAction: "
|
||||
"recv buffer might not be large enough"
|
||||
<< std::endl;
|
||||
} else if (bytesRead > 0) {
|
||||
// pass data to lwgps for processing
|
||||
#if GPS_REPLY_WIRETAPPING == 1
|
||||
sif::info << recBuf.data() << std::endl;
|
||||
sif::info << recBuf.data() << std::endl;
|
||||
#endif
|
||||
int result = lwgps_process(&gpsData, recBuf.data(), bytesRead);
|
||||
if(result == 0) {
|
||||
sif::warning << "UartTestClass::performPeriodicAction: lwgps_process error"
|
||||
<< std::endl;
|
||||
}
|
||||
recvCnt++;
|
||||
if(recvCnt == 6) {
|
||||
recvCnt = 0;
|
||||
sif::info << "GPS Data" << std::endl;
|
||||
// Print messages
|
||||
printf("Valid status: %d\n", gpsData.is_valid);
|
||||
printf("Latitude: %f degrees\n", gpsData.latitude);
|
||||
printf("Longitude: %f degrees\n", gpsData.longitude);
|
||||
printf("Altitude: %f meters\n", gpsData.altitude);
|
||||
}
|
||||
}
|
||||
} while(bytesRead > 0);
|
||||
int result = lwgps_process(&gpsData, recBuf.data(), bytesRead);
|
||||
if (result == 0) {
|
||||
sif::warning << "UartTestClass::performPeriodicAction: lwgps_process error" << std::endl;
|
||||
}
|
||||
recvCnt++;
|
||||
if (recvCnt == 6) {
|
||||
recvCnt = 0;
|
||||
sif::info << "GPS Data" << std::endl;
|
||||
// Print messages
|
||||
printf("Valid status: %d\n", gpsData.is_valid);
|
||||
printf("Latitude: %f degrees\n", gpsData.latitude);
|
||||
printf("Longitude: %f degrees\n", gpsData.longitude);
|
||||
printf("Altitude: %f meters\n", gpsData.altitude);
|
||||
}
|
||||
}
|
||||
} while (bytesRead > 0);
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
#ifndef LINUX_BOARDTEST_UARTTESTCLASS_H_
|
||||
#define LINUX_BOARDTEST_UARTTESTCLASS_H_
|
||||
|
||||
#include "test/testtasks/TestTask.h"
|
||||
#include "lwgps/lwgps.h"
|
||||
#include <termios.h> // Contains POSIX terminal control definitions
|
||||
|
||||
#include <array>
|
||||
#include <termios.h> // Contains POSIX terminal control definitions
|
||||
|
||||
class UartTestClass: public TestTask {
|
||||
public:
|
||||
UartTestClass(object_id_t objectId);
|
||||
#include "lwgps/lwgps.h"
|
||||
#include "test/testtasks/TestTask.h"
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t performOneShotAction() override;
|
||||
ReturnValue_t performPeriodicAction() override;
|
||||
private:
|
||||
class UartTestClass : public TestTask {
|
||||
public:
|
||||
UartTestClass(object_id_t objectId);
|
||||
|
||||
lwgps_t gpsData = {};
|
||||
struct termios tty = {};
|
||||
int serialPort = 0;
|
||||
std::array<uint8_t, 512> recBuf;
|
||||
uint8_t recvCnt = 0;
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t performOneShotAction() override;
|
||||
ReturnValue_t performPeriodicAction() override;
|
||||
|
||||
private:
|
||||
lwgps_t gpsData = {};
|
||||
struct termios tty = {};
|
||||
int serialPort = 0;
|
||||
std::array<uint8_t, 512> recBuf;
|
||||
uint8_t recvCnt = 0;
|
||||
};
|
||||
|
||||
#endif /* LINUX_BOARDTEST_UARTTESTCLASS_H_ */
|
||||
|
@ -1,259 +1,246 @@
|
||||
#include "CspComIF.h"
|
||||
#include "CspCookie.h"
|
||||
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
#include <csp/drivers/can_socketcan.h>
|
||||
#include <fsfw/serialize/SerializeAdapter.h>
|
||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||
|
||||
CspComIF::CspComIF(object_id_t objectId) :
|
||||
SystemObject(objectId) {
|
||||
}
|
||||
#include "CspCookie.h"
|
||||
|
||||
CspComIF::~CspComIF() {
|
||||
}
|
||||
CspComIF::CspComIF(object_id_t objectId) : SystemObject(objectId) {}
|
||||
|
||||
ReturnValue_t CspComIF::initializeInterface(CookieIF *cookie) {
|
||||
if(cookie == nullptr) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
CspComIF::~CspComIF() {}
|
||||
|
||||
CspCookie* cspCookie = dynamic_cast<CspCookie*>(cookie);
|
||||
if(cspCookie == nullptr) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
ReturnValue_t CspComIF::initializeInterface(CookieIF* cookie) {
|
||||
if (cookie == nullptr) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
|
||||
/* Perform CAN and CSP initialization only once */
|
||||
if(cspDeviceMap.empty()){
|
||||
sif::info << "Performing " << canInterface << " initialization.." << std::endl;
|
||||
CspCookie* cspCookie = dynamic_cast<CspCookie*>(cookie);
|
||||
if (cspCookie == nullptr) {
|
||||
return NULLPOINTER;
|
||||
}
|
||||
|
||||
/* Define the memory to allocate for the CSP stack */
|
||||
int buf_count = 10;
|
||||
int buf_size = 300;
|
||||
/* Init CSP and CSP buffer system */
|
||||
if (csp_init(cspOwnAddress) != CSP_ERR_NONE
|
||||
|| csp_buffer_init(buf_count, buf_size) != CSP_ERR_NONE) {
|
||||
sif::error << "Failed to init CSP\r\n" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
/* Perform CAN and CSP initialization only once */
|
||||
if (cspDeviceMap.empty()) {
|
||||
sif::info << "Performing " << canInterface << " initialization.." << std::endl;
|
||||
|
||||
int promisc = 0; // Set filter mode on
|
||||
csp_iface_t *csp_if_ptr = &csp_if;
|
||||
csp_if_ptr = csp_can_socketcan_init(canInterface, bitrate, promisc);
|
||||
|
||||
/* Set default route and start router */
|
||||
uint8_t address = CSP_DEFAULT_ROUTE;
|
||||
uint8_t netmask = 0;
|
||||
uint8_t mac = CSP_NODE_MAC;
|
||||
int result = csp_rtable_set(address, netmask, csp_if_ptr, mac);
|
||||
if(result != CSP_ERR_NONE){
|
||||
sif::error << "Failed to add can interface to router table"
|
||||
<< std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
/* Start the route task */
|
||||
unsigned int task_stack_size = 500;
|
||||
unsigned int priority = 0;
|
||||
result = csp_route_start_task(task_stack_size, priority);
|
||||
if(result != CSP_ERR_NONE){
|
||||
sif::error << "Failed to start csp route task" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
sif::info << canInterface << " initialized successfully" << std::endl;
|
||||
}
|
||||
|
||||
uint8_t cspAddress = cspCookie->getCspAddress();
|
||||
uint16_t maxReplyLength = cspCookie->getMaxReplyLength();
|
||||
if(cspDeviceMap.find(cspAddress) == cspDeviceMap.end()){
|
||||
/* Insert device information in CSP map */
|
||||
cspDeviceMap.emplace(cspAddress, vectorBuffer(maxReplyLength));
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::sendMessage(CookieIF *cookie,
|
||||
const uint8_t * sendData, size_t sendLen) {
|
||||
int result;
|
||||
if(cookie == NULL){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
CspCookie* cspCookie = dynamic_cast<CspCookie*> (cookie);
|
||||
if(cspCookie == NULL){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
/* Extract csp port and bytes to query from command buffer */
|
||||
uint8_t cspPort;
|
||||
uint16_t querySize = 0;
|
||||
result = getPortAndQuerySize(&sendData, &sendLen, &cspPort, &querySize);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
uint8_t cspAddress = cspCookie->getCspAddress();
|
||||
switch(cspPort) {
|
||||
case(Ports::CSP_PING): {
|
||||
initiatePingRequest(cspAddress, querySize);
|
||||
break;
|
||||
}
|
||||
case(Ports::CSP_REBOOT): {
|
||||
csp_reboot(cspAddress);
|
||||
break;
|
||||
}
|
||||
case(Ports::P60_PORT_GNDWDT_RESET):
|
||||
case(Ports::P60_PORT_RPARAM): {
|
||||
/* No CSP fixed port was selected. Send data to the specified port and
|
||||
* wait for querySize number of bytes */
|
||||
result = cspTransfer(cspAddress, cspPort, sendData, sendLen,
|
||||
querySize);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
replySize = querySize;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sif::error << "CspComIF: Invalid port specified" << std::endl;
|
||||
break;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::getSendSuccess(CookieIF *cookie) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::requestReceiveMessage(CookieIF *cookie,
|
||||
size_t requestLen) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::readReceivedMessage(CookieIF *cookie,
|
||||
uint8_t** buffer, size_t* size) {
|
||||
if(cookie == NULL){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
CspCookie* cspCookie = dynamic_cast<CspCookie*> (cookie);
|
||||
if(cspCookie == NULL){
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
uint8_t cspAddress = cspCookie->getCspAddress();
|
||||
|
||||
*buffer = cspDeviceMap[cspAddress].data();
|
||||
*size = replySize;
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::cspTransfer(uint8_t cspAddress, uint8_t cspPort,
|
||||
const uint8_t* cmdBuffer, int cmdLen, uint16_t querySize) {
|
||||
|
||||
uint32_t timeout_ms = 1000;
|
||||
uint16_t bytesRead = 0;
|
||||
int32_t expectedSize = (int32_t)querySize;
|
||||
vectorBufferIter iter = cspDeviceMap.find(cspAddress);
|
||||
if(iter == cspDeviceMap.end()){
|
||||
sif::error << "CSP device with address " << cspAddress << " no found in"
|
||||
<< " device map" << std::endl;
|
||||
}
|
||||
uint8_t* replyBuffer = iter->second.data();
|
||||
|
||||
csp_conn_t * conn = csp_connect(CSP_PRIO_HIGH, cspAddress, cspPort, 0,
|
||||
CSP_O_NONE);
|
||||
|
||||
csp_packet_t* commandPacket = (csp_packet_t*)csp_buffer_get(cmdLen);
|
||||
if (commandPacket == NULL) {
|
||||
sif::error << "CspComIF::cspTransfer: Failed to get memory for a csp packet from the csp "
|
||||
<< "stack" << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
/* Define the memory to allocate for the CSP stack */
|
||||
int buf_count = 10;
|
||||
int buf_size = 300;
|
||||
/* Init CSP and CSP buffer system */
|
||||
if (csp_init(cspOwnAddress) != CSP_ERR_NONE ||
|
||||
csp_buffer_init(buf_count, buf_size) != CSP_ERR_NONE) {
|
||||
sif::error << "Failed to init CSP\r\n" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
memcpy(commandPacket->data, cmdBuffer, cmdLen);
|
||||
commandPacket->length = cmdLen;
|
||||
int promisc = 0; // Set filter mode on
|
||||
csp_iface_t* csp_if_ptr = &csp_if;
|
||||
csp_if_ptr = csp_can_socketcan_init(canInterface, bitrate, promisc);
|
||||
|
||||
if (!csp_send(conn, commandPacket, timeout_ms)) {
|
||||
csp_buffer_free(commandPacket);
|
||||
sif::error << "CspComIF::cspTransfer: Failed to send csp packet" << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
/* Set default route and start router */
|
||||
uint8_t address = CSP_DEFAULT_ROUTE;
|
||||
uint8_t netmask = 0;
|
||||
uint8_t mac = CSP_NODE_MAC;
|
||||
int result = csp_rtable_set(address, netmask, csp_if_ptr, mac);
|
||||
if (result != CSP_ERR_NONE) {
|
||||
sif::error << "Failed to add can interface to router table" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
/* Return when no reply is expected */
|
||||
if (expectedSize == 0) {
|
||||
return RETURN_OK;
|
||||
/* Start the route task */
|
||||
unsigned int task_stack_size = 500;
|
||||
unsigned int priority = 0;
|
||||
result = csp_route_start_task(task_stack_size, priority);
|
||||
if (result != CSP_ERR_NONE) {
|
||||
sif::error << "Failed to start csp route task" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
sif::info << canInterface << " initialized successfully" << std::endl;
|
||||
}
|
||||
|
||||
csp_packet_t * reply;
|
||||
uint8_t cspAddress = cspCookie->getCspAddress();
|
||||
uint16_t maxReplyLength = cspCookie->getMaxReplyLength();
|
||||
if (cspDeviceMap.find(cspAddress) == cspDeviceMap.end()) {
|
||||
/* Insert device information in CSP map */
|
||||
cspDeviceMap.emplace(cspAddress, vectorBuffer(maxReplyLength));
|
||||
}
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) {
|
||||
int result;
|
||||
if (cookie == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
CspCookie* cspCookie = dynamic_cast<CspCookie*>(cookie);
|
||||
if (cspCookie == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
/* Extract csp port and bytes to query from command buffer */
|
||||
uint8_t cspPort;
|
||||
uint16_t querySize = 0;
|
||||
result = getPortAndQuerySize(&sendData, &sendLen, &cspPort, &querySize);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
uint8_t cspAddress = cspCookie->getCspAddress();
|
||||
switch (cspPort) {
|
||||
case (Ports::CSP_PING): {
|
||||
initiatePingRequest(cspAddress, querySize);
|
||||
break;
|
||||
}
|
||||
case (Ports::CSP_REBOOT): {
|
||||
csp_reboot(cspAddress);
|
||||
break;
|
||||
}
|
||||
case (Ports::P60_PORT_GNDWDT_RESET):
|
||||
case (Ports::P60_PORT_RPARAM): {
|
||||
/* No CSP fixed port was selected. Send data to the specified port and
|
||||
* wait for querySize number of bytes */
|
||||
result = cspTransfer(cspAddress, cspPort, sendData, sendLen, querySize);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
replySize = querySize;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sif::error << "CspComIF: Invalid port specified" << std::endl;
|
||||
break;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::getSendSuccess(CookieIF* cookie) { return HasReturnvaluesIF::RETURN_OK; }
|
||||
|
||||
ReturnValue_t CspComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) {
|
||||
if (cookie == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
CspCookie* cspCookie = dynamic_cast<CspCookie*>(cookie);
|
||||
if (cspCookie == NULL) {
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
uint8_t cspAddress = cspCookie->getCspAddress();
|
||||
|
||||
*buffer = cspDeviceMap[cspAddress].data();
|
||||
*size = replySize;
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::cspTransfer(uint8_t cspAddress, uint8_t cspPort, const uint8_t* cmdBuffer,
|
||||
int cmdLen, uint16_t querySize) {
|
||||
uint32_t timeout_ms = 1000;
|
||||
uint16_t bytesRead = 0;
|
||||
int32_t expectedSize = (int32_t)querySize;
|
||||
vectorBufferIter iter = cspDeviceMap.find(cspAddress);
|
||||
if (iter == cspDeviceMap.end()) {
|
||||
sif::error << "CSP device with address " << cspAddress << " no found in"
|
||||
<< " device map" << std::endl;
|
||||
}
|
||||
uint8_t* replyBuffer = iter->second.data();
|
||||
|
||||
csp_conn_t* conn = csp_connect(CSP_PRIO_HIGH, cspAddress, cspPort, 0, CSP_O_NONE);
|
||||
|
||||
csp_packet_t* commandPacket = (csp_packet_t*)csp_buffer_get(cmdLen);
|
||||
if (commandPacket == NULL) {
|
||||
sif::error << "CspComIF::cspTransfer: Failed to get memory for a csp packet from the csp "
|
||||
<< "stack" << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
memcpy(commandPacket->data, cmdBuffer, cmdLen);
|
||||
commandPacket->length = cmdLen;
|
||||
|
||||
if (!csp_send(conn, commandPacket, timeout_ms)) {
|
||||
csp_buffer_free(commandPacket);
|
||||
sif::error << "CspComIF::cspTransfer: Failed to send csp packet" << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
/* Return when no reply is expected */
|
||||
if (expectedSize == 0) {
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
csp_packet_t* reply;
|
||||
reply = csp_read(conn, timeout_ms);
|
||||
if (reply == NULL) {
|
||||
sif::error << "CspComIF::cspTransfer: Failed to read csp packet" << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
memcpy(replyBuffer, reply->data, reply->length);
|
||||
expectedSize = expectedSize - reply->length;
|
||||
bytesRead += reply->length;
|
||||
csp_buffer_free(reply);
|
||||
while (expectedSize > 0) {
|
||||
reply = csp_read(conn, timeout_ms);
|
||||
if (reply == NULL) {
|
||||
sif::error << "CspComIF::cspTransfer: Failed to read csp packet" << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
sif::error << "CspComIF::cspTransfer: Failed to read csp packet" << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
memcpy(replyBuffer, reply->data, reply->length);
|
||||
if ((reply->length + bytesRead) > iter->second.size()) {
|
||||
sif::error << "CspComIF::cspTransfer: Reply buffer to short" << std::endl;
|
||||
csp_buffer_free(reply);
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
memcpy(replyBuffer + bytesRead, reply->data, reply->length);
|
||||
expectedSize = expectedSize - reply->length;
|
||||
bytesRead += reply->length;
|
||||
csp_buffer_free(reply);
|
||||
while (expectedSize > 0) {
|
||||
reply = csp_read(conn, timeout_ms);
|
||||
if (reply == NULL) {
|
||||
sif::error << "CspComIF::cspTransfer: Failed to read csp packet" << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if ((reply->length + bytesRead) > iter->second.size()) {
|
||||
sif::error << "CspComIF::cspTransfer: Reply buffer to short" << std::endl;
|
||||
csp_buffer_free(reply);
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
memcpy(replyBuffer + bytesRead, reply->data, reply->length);
|
||||
expectedSize = expectedSize - reply->length;
|
||||
bytesRead += reply->length;
|
||||
csp_buffer_free(reply);
|
||||
}
|
||||
}
|
||||
|
||||
if(expectedSize != 0){
|
||||
sif::error << "CspComIF::cspTransfer: Received more bytes than requested" << std::endl;
|
||||
sif::debug << "CspComIF::cspTransfer: Received bytes: " << bytesRead << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (expectedSize != 0) {
|
||||
sif::error << "CspComIF::cspTransfer: Received more bytes than requested" << std::endl;
|
||||
sif::debug << "CspComIF::cspTransfer: Received bytes: " << bytesRead << std::endl;
|
||||
csp_close(conn);
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
csp_close(conn);
|
||||
csp_close(conn);
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t CspComIF::getPortAndQuerySize(const uint8_t** sendData,
|
||||
size_t* sendLen, uint8_t* cspPort, uint16_t* querySize) {
|
||||
ReturnValue_t result = SerializeAdapter::deSerialize(cspPort, sendData,
|
||||
sendLen, SerializeIF::Endianness::BIG);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
sif::error << "CspComIF: Failed to deserialize CSP port from command "
|
||||
<< "buffer" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
SerializeAdapter::deSerialize(querySize, sendData, sendLen,
|
||||
SerializeIF::Endianness::BIG);
|
||||
if(result != HasReturnvaluesIF::RETURN_OK){
|
||||
sif::error << "CspComIF: Failed to deserialize querySize from command "
|
||||
<< "buffer" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t CspComIF::getPortAndQuerySize(const uint8_t** sendData, size_t* sendLen,
|
||||
uint8_t* cspPort, uint16_t* querySize) {
|
||||
ReturnValue_t result =
|
||||
SerializeAdapter::deSerialize(cspPort, sendData, sendLen, SerializeIF::Endianness::BIG);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "CspComIF: Failed to deserialize CSP port from command "
|
||||
<< "buffer" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
SerializeAdapter::deSerialize(querySize, sendData, sendLen, SerializeIF::Endianness::BIG);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "CspComIF: Failed to deserialize querySize from command "
|
||||
<< "buffer" << std::endl;
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void CspComIF::initiatePingRequest(uint8_t cspAddress, uint16_t querySize){
|
||||
uint32_t timeout_ms = 500;
|
||||
uint32_t replyTime = csp_ping(cspAddress, timeout_ms, querySize,
|
||||
CSP_O_NONE);
|
||||
sif::info << "Ping address: " << cspAddress << ", reply after "
|
||||
<< replyTime << " ms" << std::endl;
|
||||
/* Store reply time in reply buffer * */
|
||||
uint8_t* replyBuffer = cspDeviceMap[cspAddress].data();
|
||||
memcpy(replyBuffer, &replyTime, sizeof(replyTime));
|
||||
replySize = sizeof(replyTime);
|
||||
void CspComIF::initiatePingRequest(uint8_t cspAddress, uint16_t querySize) {
|
||||
uint32_t timeout_ms = 500;
|
||||
uint32_t replyTime = csp_ping(cspAddress, timeout_ms, querySize, CSP_O_NONE);
|
||||
sif::info << "Ping address: " << cspAddress << ", reply after " << replyTime << " ms"
|
||||
<< std::endl;
|
||||
/* Store reply time in reply buffer * */
|
||||
uint8_t* replyBuffer = cspDeviceMap[cspAddress].data();
|
||||
memcpy(replyBuffer, &replyTime, sizeof(replyTime));
|
||||
replySize = sizeof(replyTime);
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
#ifndef LINUX_CSP_CSPCOMIF_H_
|
||||
#define LINUX_CSP_CSPCOMIF_H_
|
||||
|
||||
#include <csp/csp.h>
|
||||
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <csp/csp.h>
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief This class serves as the communication interface to devices
|
||||
@ -15,75 +15,65 @@
|
||||
* in this implementation.
|
||||
* @author J. Meier
|
||||
*/
|
||||
class CspComIF: public DeviceCommunicationIF, public SystemObject {
|
||||
public:
|
||||
CspComIF(object_id_t objectId);
|
||||
virtual ~CspComIF();
|
||||
class CspComIF : public DeviceCommunicationIF, public SystemObject {
|
||||
public:
|
||||
CspComIF(object_id_t objectId);
|
||||
virtual ~CspComIF();
|
||||
|
||||
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 **readData, size_t *readLen) override;
|
||||
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 **readData, size_t *readLen) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
/**
|
||||
* @brief This function initiates the CSP transfer.
|
||||
*
|
||||
* @param cspAddress The CSP address of the target device.
|
||||
* @param cspPort The port of the target device.
|
||||
* @param timeout The timeout to wait for csp_send and csp_read
|
||||
* functions. Specifies how long the functions wait
|
||||
* for a successful operation.
|
||||
* @param cmdBuffer The data to send.
|
||||
* @param cmdLen The number of bytes to send.
|
||||
* @param querySize The size of the requested message.
|
||||
*/
|
||||
ReturnValue_t cspTransfer(uint8_t cspAddress, uint8_t cspPort, const uint8_t *cmdBuffer,
|
||||
int cmdLen, uint16_t querySize);
|
||||
|
||||
/**
|
||||
* @brief This function initiates the CSP transfer.
|
||||
*
|
||||
* @param cspAddress The CSP address of the target device.
|
||||
* @param cspPort The port of the target device.
|
||||
* @param timeout The timeout to wait for csp_send and csp_read
|
||||
* functions. Specifies how long the functions wait
|
||||
* for a successful operation.
|
||||
* @param cmdBuffer The data to send.
|
||||
* @param cmdLen The number of bytes to send.
|
||||
* @param querySize The size of the requested message.
|
||||
*/
|
||||
ReturnValue_t cspTransfer(uint8_t cspAddress, uint8_t cspPort,
|
||||
const uint8_t* cmdBuffer, int cmdLen, uint16_t querySize);
|
||||
enum Ports { CSP_PING = 1, CSP_REBOOT = 4, P60_PORT_RPARAM = 7, P60_PORT_GNDWDT_RESET = 9 };
|
||||
|
||||
enum Ports {
|
||||
CSP_PING = 1,
|
||||
CSP_REBOOT = 4,
|
||||
P60_PORT_RPARAM = 7,
|
||||
P60_PORT_GNDWDT_RESET = 9
|
||||
};
|
||||
typedef uint8_t node_t;
|
||||
using vectorBuffer = std::vector<uint8_t>;
|
||||
using VectorBufferMap = std::unordered_map<node_t, vectorBuffer>;
|
||||
using vectorBufferIter = VectorBufferMap::iterator;
|
||||
|
||||
/* In this map assigns reply buffers to a CSP device */
|
||||
VectorBufferMap cspDeviceMap;
|
||||
|
||||
typedef uint8_t node_t;
|
||||
using vectorBuffer = std::vector<uint8_t>;
|
||||
using VectorBufferMap = std::unordered_map<node_t, vectorBuffer>;
|
||||
using vectorBufferIter = VectorBufferMap::iterator;
|
||||
uint16_t replySize = 0;
|
||||
|
||||
/* In this map assigns reply buffers to a CSP device */
|
||||
VectorBufferMap cspDeviceMap;
|
||||
/* This is the CSP address of the OBC. */
|
||||
node_t cspOwnAddress = 1;
|
||||
|
||||
uint16_t replySize = 0;
|
||||
/* Interface struct for csp protocol stack */
|
||||
csp_iface_t csp_if;
|
||||
|
||||
/* This is the CSP address of the OBC. */
|
||||
node_t cspOwnAddress = 1;
|
||||
char canInterface[5] = "can0";
|
||||
int bitrate = 1000;
|
||||
|
||||
/* Interface struct for csp protocol stack */
|
||||
csp_iface_t csp_if;
|
||||
/**
|
||||
* @brief Function to extract the csp port and the query size from the
|
||||
* command buffer.
|
||||
*/
|
||||
ReturnValue_t getPortAndQuerySize(const uint8_t **sendData, size_t *sendLen, uint8_t *cspPort,
|
||||
uint16_t *querySize);
|
||||
|
||||
char canInterface[5] = "can0";
|
||||
int bitrate = 1000;
|
||||
|
||||
/**
|
||||
* @brief Function to extract the csp port and the query size from the
|
||||
* command buffer.
|
||||
*/
|
||||
ReturnValue_t getPortAndQuerySize(const uint8_t** sendData, size_t* sendLen,
|
||||
uint8_t* cspPort, uint16_t* querySize);
|
||||
|
||||
/**
|
||||
* @brief This function initiates the ping request.
|
||||
*/
|
||||
void initiatePingRequest(uint8_t cspAddress, uint16_t querySize);
|
||||
/**
|
||||
* @brief This function initiates the ping request.
|
||||
*/
|
||||
void initiatePingRequest(uint8_t cspAddress, uint16_t querySize);
|
||||
};
|
||||
|
||||
#endif /* LINUX_CSP_CSPCOMIF_H_ */
|
||||
|
@ -1,16 +1,10 @@
|
||||
#include "CspCookie.h"
|
||||
|
||||
CspCookie::CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_) :
|
||||
maxReplyLength(maxReplyLength_), cspAddress(cspAddress_) {
|
||||
}
|
||||
CspCookie::CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_)
|
||||
: maxReplyLength(maxReplyLength_), cspAddress(cspAddress_) {}
|
||||
|
||||
CspCookie::~CspCookie() {
|
||||
}
|
||||
CspCookie::~CspCookie() {}
|
||||
|
||||
uint16_t CspCookie::getMaxReplyLength(){
|
||||
return maxReplyLength;
|
||||
}
|
||||
uint16_t CspCookie::getMaxReplyLength() { return maxReplyLength; }
|
||||
|
||||
uint8_t CspCookie::getCspAddress(){
|
||||
return cspAddress;
|
||||
}
|
||||
uint8_t CspCookie::getCspAddress() { return cspAddress; }
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define LINUX_CSP_CSPCOOKIE_H_
|
||||
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
@ -9,19 +10,17 @@
|
||||
* Protocol).
|
||||
* @author J. Meier
|
||||
*/
|
||||
class CspCookie: public CookieIF {
|
||||
public:
|
||||
class CspCookie : public CookieIF {
|
||||
public:
|
||||
CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_);
|
||||
virtual ~CspCookie();
|
||||
|
||||
CspCookie(uint16_t maxReplyLength_, uint8_t cspAddress_);
|
||||
virtual ~CspCookie();
|
||||
uint16_t getMaxReplyLength();
|
||||
uint8_t getCspAddress();
|
||||
|
||||
uint16_t getMaxReplyLength();
|
||||
uint8_t getCspAddress();
|
||||
|
||||
private:
|
||||
|
||||
uint16_t maxReplyLength;
|
||||
uint8_t cspAddress;
|
||||
private:
|
||||
uint16_t maxReplyLength;
|
||||
uint8_t cspAddress;
|
||||
};
|
||||
|
||||
#endif /* LINUX_CSP_CSPCOOKIE_H_ */
|
||||
|
@ -1,202 +1,209 @@
|
||||
#include "SolarArrayDeploymentHandler.h"
|
||||
|
||||
#include <devices/powerSwitcherList.h>
|
||||
#include <devices/gpioIds.h>
|
||||
|
||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||
#include <devices/powerSwitcherList.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/objectmanager/ObjectManager.h>
|
||||
|
||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||
|
||||
SolarArrayDeploymentHandler::SolarArrayDeploymentHandler(object_id_t setObjectId_,
|
||||
object_id_t gpioDriverId_, CookieIF * gpioCookie_, object_id_t mainLineSwitcherObjectId_,
|
||||
uint8_t mainLineSwitch_, gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs) :
|
||||
SystemObject(setObjectId_), gpioDriverId(gpioDriverId_), gpioCookie(gpioCookie_),
|
||||
mainLineSwitcherObjectId(mainLineSwitcherObjectId_), mainLineSwitch(mainLineSwitch_),
|
||||
deplSA1(deplSA1), deplSA2(deplSA2), burnTimeMs(burnTimeMs), actionHelper(this, nullptr) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(cmdQueueSize,
|
||||
MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
object_id_t gpioDriverId_,
|
||||
CookieIF* gpioCookie_,
|
||||
object_id_t mainLineSwitcherObjectId_,
|
||||
uint8_t mainLineSwitch_, gpioId_t deplSA1,
|
||||
gpioId_t deplSA2, uint32_t burnTimeMs)
|
||||
: SystemObject(setObjectId_),
|
||||
gpioDriverId(gpioDriverId_),
|
||||
gpioCookie(gpioCookie_),
|
||||
mainLineSwitcherObjectId(mainLineSwitcherObjectId_),
|
||||
mainLineSwitch(mainLineSwitch_),
|
||||
deplSA1(deplSA1),
|
||||
deplSA2(deplSA2),
|
||||
burnTimeMs(burnTimeMs),
|
||||
actionHelper(this, nullptr) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(
|
||||
cmdQueueSize, MessageQueueMessage::MAX_MESSAGE_SIZE);
|
||||
}
|
||||
|
||||
SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() {
|
||||
}
|
||||
SolarArrayDeploymentHandler::~SolarArrayDeploymentHandler() {}
|
||||
|
||||
ReturnValue_t SolarArrayDeploymentHandler::performOperation(uint8_t operationCode) {
|
||||
|
||||
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
|
||||
handleStateMachine();
|
||||
return RETURN_OK;
|
||||
}
|
||||
if (operationCode == DeviceHandlerIF::PERFORM_OPERATION) {
|
||||
handleStateMachine();
|
||||
return RETURN_OK;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t SolarArrayDeploymentHandler::initialize() {
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
ReturnValue_t result = SystemObject::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
gpioInterface = ObjectManager::instance()->get<GpioIF>(gpioDriverId);
|
||||
if (gpioInterface == nullptr) {
|
||||
sif::error << "SolarArrayDeploymentHandler::initialize: Invalid Gpio interface."
|
||||
<< std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
gpioInterface = ObjectManager::instance()->get<GpioIF>(gpioDriverId);
|
||||
if (gpioInterface == nullptr) {
|
||||
sif::error << "SolarArrayDeploymentHandler::initialize: Invalid Gpio interface." << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
result = gpioInterface->addGpios(dynamic_cast<GpioCookie*>(gpioCookie));
|
||||
if (result != RETURN_OK) {
|
||||
sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface"
|
||||
<< std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
result = gpioInterface->addGpios(dynamic_cast<GpioCookie*>(gpioCookie));
|
||||
if (result != RETURN_OK) {
|
||||
sif::error << "SolarArrayDeploymentHandler::initialize: Failed to initialize Gpio interface"
|
||||
<< std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
if (mainLineSwitcherObjectId != objects::NO_OBJECT) {
|
||||
mainLineSwitcher = ObjectManager::instance()->get<PowerSwitchIF>(mainLineSwitcherObjectId);
|
||||
if (mainLineSwitcher == nullptr) {
|
||||
sif::error
|
||||
<< "SolarArrayDeploymentHandler::initialize: Main line switcher failed to fetch object"
|
||||
<< "from object ID." << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
if (mainLineSwitcherObjectId != objects::NO_OBJECT) {
|
||||
mainLineSwitcher = ObjectManager::instance()->get<PowerSwitchIF>(mainLineSwitcherObjectId);
|
||||
if (mainLineSwitcher == nullptr) {
|
||||
sif::error
|
||||
<< "SolarArrayDeploymentHandler::initialize: Main line switcher failed to fetch object"
|
||||
<< "from object ID." << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
result = actionHelper.initialize(commandQueue);
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
result = actionHelper.initialize(commandQueue);
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void SolarArrayDeploymentHandler::handleStateMachine() {
|
||||
switch (stateMachine) {
|
||||
switch (stateMachine) {
|
||||
case WAIT_ON_DELOYMENT_COMMAND:
|
||||
readCommandQueue();
|
||||
break;
|
||||
readCommandQueue();
|
||||
break;
|
||||
case SWITCH_8V_ON:
|
||||
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON);
|
||||
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
|
||||
stateMachine = WAIT_ON_8V_SWITCH;
|
||||
break;
|
||||
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_ON);
|
||||
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
|
||||
stateMachine = WAIT_ON_8V_SWITCH;
|
||||
break;
|
||||
case WAIT_ON_8V_SWITCH:
|
||||
performWaitOn8VActions();
|
||||
break;
|
||||
performWaitOn8VActions();
|
||||
break;
|
||||
case SWITCH_DEPL_GPIOS:
|
||||
switchDeploymentTransistors();
|
||||
break;
|
||||
switchDeploymentTransistors();
|
||||
break;
|
||||
case WAIT_ON_DEPLOYMENT_FINISH:
|
||||
handleDeploymentFinish();
|
||||
break;
|
||||
handleDeploymentFinish();
|
||||
break;
|
||||
case WAIT_FOR_MAIN_SWITCH_OFF:
|
||||
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) {
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
} else if (mainSwitchCountdown.hasTimedOut()) {
|
||||
triggerEvent(MAIN_SWITCH_OFF_TIMEOUT);
|
||||
sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main"
|
||||
<< " switch off" << std::endl;
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
}
|
||||
break;
|
||||
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_OFF) {
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
} else if (mainSwitchCountdown.hasTimedOut()) {
|
||||
triggerEvent(MAIN_SWITCH_OFF_TIMEOUT);
|
||||
sif::error << "SolarArrayDeploymentHandler::handleStateMachine: Failed to switch main"
|
||||
<< " switch off" << std::endl;
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << std::endl;
|
||||
break;
|
||||
}
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Invalid state" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SolarArrayDeploymentHandler::performWaitOn8VActions() {
|
||||
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) {
|
||||
stateMachine = SWITCH_DEPL_GPIOS;
|
||||
} else {
|
||||
if (mainSwitchCountdown.hasTimedOut()) {
|
||||
triggerEvent(MAIN_SWITCH_ON_TIMEOUT);
|
||||
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
|
||||
MAIN_SWITCH_TIMEOUT_FAILURE);
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
}
|
||||
if (mainLineSwitcher->getSwitchState(mainLineSwitch) == PowerSwitchIF::SWITCH_ON) {
|
||||
stateMachine = SWITCH_DEPL_GPIOS;
|
||||
} else {
|
||||
if (mainSwitchCountdown.hasTimedOut()) {
|
||||
triggerEvent(MAIN_SWITCH_ON_TIMEOUT);
|
||||
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
|
||||
MAIN_SWITCH_TIMEOUT_FAILURE);
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SolarArrayDeploymentHandler::switchDeploymentTransistors() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = gpioInterface->pullHigh(deplSA1);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||
" array deployment switch 1 high " << std::endl;
|
||||
/* If gpio switch high failed, state machine is reset to wait for a command reinitiating
|
||||
* the deployment sequence. */
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED);
|
||||
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
|
||||
SWITCHING_DEPL_SA2_FAILED);
|
||||
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||
}
|
||||
result = gpioInterface->pullHigh(deplSA2);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||
" array deployment switch 2 high " << std::endl;
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED);
|
||||
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS,
|
||||
SWITCHING_DEPL_SA2_FAILED);
|
||||
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||
}
|
||||
deploymentCountdown.setTimeout(burnTimeMs);
|
||||
stateMachine = WAIT_ON_DEPLOYMENT_FINISH;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = gpioInterface->pullHigh(deplSA1);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||
" array deployment switch 1 high "
|
||||
<< std::endl;
|
||||
/* If gpio switch high failed, state machine is reset to wait for a command reinitiating
|
||||
* the deployment sequence. */
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
triggerEvent(DEPL_SA1_GPIO_SWTICH_ON_FAILED);
|
||||
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED);
|
||||
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||
}
|
||||
result = gpioInterface->pullHigh(deplSA2);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||
" array deployment switch 2 high "
|
||||
<< std::endl;
|
||||
stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
triggerEvent(DEPL_SA2_GPIO_SWTICH_ON_FAILED);
|
||||
actionHelper.finish(false, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, SWITCHING_DEPL_SA2_FAILED);
|
||||
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||
}
|
||||
deploymentCountdown.setTimeout(burnTimeMs);
|
||||
stateMachine = WAIT_ON_DEPLOYMENT_FINISH;
|
||||
}
|
||||
|
||||
void SolarArrayDeploymentHandler::handleDeploymentFinish() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
if (deploymentCountdown.hasTimedOut()) {
|
||||
actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, RETURN_OK);
|
||||
result = gpioInterface->pullLow(deplSA1);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||
" array deployment switch 1 low " << std::endl;
|
||||
}
|
||||
result = gpioInterface->pullLow(deplSA2);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||
" array deployment switch 2 low " << std::endl;
|
||||
}
|
||||
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
|
||||
stateMachine = WAIT_FOR_MAIN_SWITCH_OFF;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
if (deploymentCountdown.hasTimedOut()) {
|
||||
actionHelper.finish(true, rememberCommanderId, DEPLOY_SOLAR_ARRAYS, RETURN_OK);
|
||||
result = gpioInterface->pullLow(deplSA1);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||
" array deployment switch 1 low "
|
||||
<< std::endl;
|
||||
}
|
||||
result = gpioInterface->pullLow(deplSA2);
|
||||
if (result != RETURN_OK) {
|
||||
sif::debug << "SolarArrayDeploymentHandler::handleStateMachine: Failed to pull solar"
|
||||
" array deployment switch 2 low "
|
||||
<< std::endl;
|
||||
}
|
||||
mainLineSwitcher->sendSwitchCommand(mainLineSwitch, PowerSwitchIF::SWITCH_OFF);
|
||||
mainSwitchCountdown.setTimeout(mainLineSwitcher->getSwitchDelayMs());
|
||||
stateMachine = WAIT_FOR_MAIN_SWITCH_OFF;
|
||||
}
|
||||
}
|
||||
|
||||
void SolarArrayDeploymentHandler::readCommandQueue() {
|
||||
CommandMessage command;
|
||||
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
||||
if (result != RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
CommandMessage command;
|
||||
ReturnValue_t result = commandQueue->receiveMessage(&command);
|
||||
if (result != RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
result = actionHelper.handleActionMessage(&command);
|
||||
if (result == RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
result = actionHelper.handleActionMessage(&command);
|
||||
if (result == RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t SolarArrayDeploymentHandler::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result;
|
||||
if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) {
|
||||
sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in"
|
||||
<< "waiting-on-command-state" << std::endl;
|
||||
return DEPLOYMENT_ALREADY_EXECUTING;
|
||||
}
|
||||
if (actionId != DEPLOY_SOLAR_ARRAYS) {
|
||||
sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command"
|
||||
<< std::endl;
|
||||
result = COMMAND_NOT_SUPPORTED;
|
||||
} else {
|
||||
stateMachine = SWITCH_8V_ON;
|
||||
rememberCommanderId = commandedBy;
|
||||
result = RETURN_OK;
|
||||
}
|
||||
return result;
|
||||
MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result;
|
||||
if (stateMachine != WAIT_ON_DELOYMENT_COMMAND) {
|
||||
sif::error << "SolarArrayDeploymentHandler::executeAction: Received command while not in"
|
||||
<< "waiting-on-command-state" << std::endl;
|
||||
return DEPLOYMENT_ALREADY_EXECUTING;
|
||||
}
|
||||
if (actionId != DEPLOY_SOLAR_ARRAYS) {
|
||||
sif::error << "SolarArrayDeploymentHandler::executeAction: Received invalid command"
|
||||
<< std::endl;
|
||||
result = COMMAND_NOT_SUPPORTED;
|
||||
} else {
|
||||
stateMachine = SWITCH_8V_ON;
|
||||
rememberCommanderId = commandedBy;
|
||||
result = RETURN_OK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MessageQueueId_t SolarArrayDeploymentHandler::getCommandQueue() const {
|
||||
return commandQueue->getId();
|
||||
return commandQueue->getId();
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
#ifndef MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
|
||||
#define MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_
|
||||
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/action/HasActionsIF.h>
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <fsfw/objectmanager/SystemObject.h>
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||
#include <fsfw/timemanager/Countdown.h>
|
||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
/**
|
||||
@ -17,142 +18,139 @@
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class SolarArrayDeploymentHandler: public ExecutableObjectIF,
|
||||
public SystemObject,
|
||||
public HasReturnvaluesIF,
|
||||
public HasActionsIF {
|
||||
public:
|
||||
class SolarArrayDeploymentHandler : public ExecutableObjectIF,
|
||||
public SystemObject,
|
||||
public HasReturnvaluesIF,
|
||||
public HasActionsIF {
|
||||
public:
|
||||
static const DeviceCommandId_t DEPLOY_SOLAR_ARRAYS = 0x5;
|
||||
|
||||
static const DeviceCommandId_t DEPLOY_SOLAR_ARRAYS = 0x5;
|
||||
/**
|
||||
* @brief constructor
|
||||
*
|
||||
* @param setObjectId The object id of the SolarArrayDeploymentHandler.
|
||||
* @param gpioDriverId The id of the gpio com if.
|
||||
* @param gpioCookie GpioCookie holding information about the gpios used to switch the
|
||||
* transistors.
|
||||
* @param mainLineSwitcherObjectId The object id of the object responsible for switching
|
||||
* the 8V power source. This is normally the PCDU.
|
||||
* @param mainLineSwitch The id of the main line switch. This is defined in
|
||||
* powerSwitcherList.h.
|
||||
* @param deplSA1 gpioId of the GPIO controlling the deployment 1 transistor.
|
||||
* @param deplSA2 gpioId of the GPIO controlling the deployment 2 transistor.
|
||||
* @param burnTimeMs Time duration the power will be applied to the burn wires.
|
||||
*/
|
||||
SolarArrayDeploymentHandler(object_id_t setObjectId, object_id_t gpioDriverId,
|
||||
CookieIF* gpioCookie, object_id_t mainLineSwitcherObjectId,
|
||||
uint8_t mainLineSwitch, gpioId_t deplSA1, gpioId_t deplSA2,
|
||||
uint32_t burnTimeMs);
|
||||
|
||||
/**
|
||||
* @brief constructor
|
||||
*
|
||||
* @param setObjectId The object id of the SolarArrayDeploymentHandler.
|
||||
* @param gpioDriverId The id of the gpio com if.
|
||||
* @param gpioCookie GpioCookie holding information about the gpios used to switch the
|
||||
* transistors.
|
||||
* @param mainLineSwitcherObjectId The object id of the object responsible for switching
|
||||
* the 8V power source. This is normally the PCDU.
|
||||
* @param mainLineSwitch The id of the main line switch. This is defined in
|
||||
* powerSwitcherList.h.
|
||||
* @param deplSA1 gpioId of the GPIO controlling the deployment 1 transistor.
|
||||
* @param deplSA2 gpioId of the GPIO controlling the deployment 2 transistor.
|
||||
* @param burnTimeMs Time duration the power will be applied to the burn wires.
|
||||
*/
|
||||
SolarArrayDeploymentHandler(object_id_t setObjectId, object_id_t gpioDriverId,
|
||||
CookieIF * gpioCookie, object_id_t mainLineSwitcherObjectId, uint8_t mainLineSwitch,
|
||||
gpioId_t deplSA1, gpioId_t deplSA2, uint32_t burnTimeMs);
|
||||
virtual ~SolarArrayDeploymentHandler();
|
||||
|
||||
virtual ~SolarArrayDeploymentHandler();
|
||||
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||
|
||||
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
||||
virtual MessageQueueId_t getCommandQueue() const override;
|
||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
virtual ReturnValue_t initialize() override;
|
||||
|
||||
virtual MessageQueueId_t getCommandQueue() const override;
|
||||
virtual ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
virtual ReturnValue_t initialize() override;
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::SA_DEPL_HANDLER;
|
||||
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA0);
|
||||
static const ReturnValue_t DEPLOYMENT_ALREADY_EXECUTING = MAKE_RETURN_CODE(0xA1);
|
||||
static const ReturnValue_t MAIN_SWITCH_TIMEOUT_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||
static const ReturnValue_t SWITCHING_DEPL_SA1_FAILED = MAKE_RETURN_CODE(0xA3);
|
||||
static const ReturnValue_t SWITCHING_DEPL_SA2_FAILED = MAKE_RETURN_CODE(0xA4);
|
||||
|
||||
private:
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SA_DEPL_HANDLER;
|
||||
static const Event MAIN_SWITCH_ON_TIMEOUT = MAKE_EVENT(0, severity::LOW);
|
||||
static const Event MAIN_SWITCH_OFF_TIMEOUT = MAKE_EVENT(1, severity::LOW);
|
||||
static const Event DEPLOYMENT_FAILED = MAKE_EVENT(2, severity::HIGH);
|
||||
static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH);
|
||||
static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH);
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::SA_DEPL_HANDLER;
|
||||
static const ReturnValue_t COMMAND_NOT_SUPPORTED = MAKE_RETURN_CODE(0xA0);
|
||||
static const ReturnValue_t DEPLOYMENT_ALREADY_EXECUTING = MAKE_RETURN_CODE(0xA1);
|
||||
static const ReturnValue_t MAIN_SWITCH_TIMEOUT_FAILURE = MAKE_RETURN_CODE(0xA2);
|
||||
static const ReturnValue_t SWITCHING_DEPL_SA1_FAILED = MAKE_RETURN_CODE(0xA3);
|
||||
static const ReturnValue_t SWITCHING_DEPL_SA2_FAILED = MAKE_RETURN_CODE(0xA4);
|
||||
enum StateMachine {
|
||||
WAIT_ON_DELOYMENT_COMMAND,
|
||||
SWITCH_8V_ON,
|
||||
WAIT_ON_8V_SWITCH,
|
||||
SWITCH_DEPL_GPIOS,
|
||||
WAIT_ON_DEPLOYMENT_FINISH,
|
||||
WAIT_FOR_MAIN_SWITCH_OFF
|
||||
};
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::SA_DEPL_HANDLER;
|
||||
static const Event MAIN_SWITCH_ON_TIMEOUT = MAKE_EVENT(0, severity::LOW);
|
||||
static const Event MAIN_SWITCH_OFF_TIMEOUT = MAKE_EVENT(1, severity::LOW);
|
||||
static const Event DEPLOYMENT_FAILED = MAKE_EVENT(2, severity::HIGH);
|
||||
static const Event DEPL_SA1_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(3, severity::HIGH);
|
||||
static const Event DEPL_SA2_GPIO_SWTICH_ON_FAILED = MAKE_EVENT(4, severity::HIGH);
|
||||
StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
|
||||
/**
|
||||
* This countdown is used to check if the PCDU sets the 8V line on in the intended time.
|
||||
*/
|
||||
Countdown mainSwitchCountdown;
|
||||
|
||||
enum StateMachine {
|
||||
WAIT_ON_DELOYMENT_COMMAND,
|
||||
SWITCH_8V_ON,
|
||||
WAIT_ON_8V_SWITCH,
|
||||
SWITCH_DEPL_GPIOS,
|
||||
WAIT_ON_DEPLOYMENT_FINISH,
|
||||
WAIT_FOR_MAIN_SWITCH_OFF
|
||||
};
|
||||
/**
|
||||
* This countdown is used to wait for the burn wire being successful cut.
|
||||
*/
|
||||
Countdown deploymentCountdown;
|
||||
|
||||
StateMachine stateMachine = WAIT_ON_DELOYMENT_COMMAND;
|
||||
/**
|
||||
* The message queue id of the component commanding an action will be stored in this variable.
|
||||
* This is necessary to send later the action finish replies.
|
||||
*/
|
||||
MessageQueueId_t rememberCommanderId = 0;
|
||||
|
||||
/**
|
||||
* This countdown is used to check if the PCDU sets the 8V line on in the intended time.
|
||||
*/
|
||||
Countdown mainSwitchCountdown;
|
||||
/** Size of command queue */
|
||||
size_t cmdQueueSize = 20;
|
||||
|
||||
/**
|
||||
* This countdown is used to wait for the burn wire being successful cut.
|
||||
*/
|
||||
Countdown deploymentCountdown;
|
||||
/** The object ID of the GPIO driver which switches the deployment transistors */
|
||||
object_id_t gpioDriverId;
|
||||
|
||||
CookieIF* gpioCookie;
|
||||
|
||||
/**
|
||||
* The message queue id of the component commanding an action will be stored in this variable.
|
||||
* This is necessary to send later the action finish replies.
|
||||
*/
|
||||
MessageQueueId_t rememberCommanderId = 0;
|
||||
/** Object id of the object responsible to switch the 8V power input. Typically the PCDU. */
|
||||
object_id_t mainLineSwitcherObjectId;
|
||||
|
||||
/** Size of command queue */
|
||||
size_t cmdQueueSize = 20;
|
||||
/** Switch number of the 8V power switch */
|
||||
uint8_t mainLineSwitch;
|
||||
|
||||
/** The object ID of the GPIO driver which switches the deployment transistors */
|
||||
object_id_t gpioDriverId;
|
||||
gpioId_t deplSA1;
|
||||
gpioId_t deplSA2;
|
||||
|
||||
CookieIF * gpioCookie;
|
||||
GpioIF* gpioInterface = nullptr;
|
||||
|
||||
/** Object id of the object responsible to switch the 8V power input. Typically the PCDU. */
|
||||
object_id_t mainLineSwitcherObjectId;
|
||||
/** Time duration switches are active to cut the burn wire */
|
||||
uint32_t burnTimeMs;
|
||||
|
||||
/** Switch number of the 8V power switch */
|
||||
uint8_t mainLineSwitch;
|
||||
/** Queue to receive messages from other objects. */
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
|
||||
gpioId_t deplSA1;
|
||||
gpioId_t deplSA2;
|
||||
/**
|
||||
* After initialization this pointer will hold the reference to the main line switcher object.
|
||||
*/
|
||||
PowerSwitchIF* mainLineSwitcher = nullptr;
|
||||
|
||||
GpioIF* gpioInterface = nullptr;
|
||||
ActionHelper actionHelper;
|
||||
|
||||
/** Time duration switches are active to cut the burn wire */
|
||||
uint32_t burnTimeMs;
|
||||
void readCommandQueue();
|
||||
|
||||
/** Queue to receive messages from other objects. */
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
/**
|
||||
* @brief This function performs actions dependent on the current state.
|
||||
*/
|
||||
void handleStateMachine();
|
||||
|
||||
/**
|
||||
* After initialization this pointer will hold the reference to the main line switcher object.
|
||||
*/
|
||||
PowerSwitchIF *mainLineSwitcher = nullptr;
|
||||
/**
|
||||
* @brief This function polls the 8V switch state and changes the state machine when the
|
||||
* switch has been enabled.
|
||||
*/
|
||||
void performWaitOn8VActions();
|
||||
|
||||
ActionHelper actionHelper;
|
||||
/**
|
||||
* @brief This functions handles the switching of the solar array deployment transistors.
|
||||
*/
|
||||
void switchDeploymentTransistors();
|
||||
|
||||
void readCommandQueue();
|
||||
|
||||
/**
|
||||
* @brief This function performs actions dependent on the current state.
|
||||
*/
|
||||
void handleStateMachine();
|
||||
|
||||
/**
|
||||
* @brief This function polls the 8V switch state and changes the state machine when the
|
||||
* switch has been enabled.
|
||||
*/
|
||||
void performWaitOn8VActions();
|
||||
|
||||
/**
|
||||
* @brief This functions handles the switching of the solar array deployment transistors.
|
||||
*/
|
||||
void switchDeploymentTransistors();
|
||||
|
||||
/**
|
||||
* @brief This function performs actions to finish the deployment. Essentially switches
|
||||
* are turned of after the burn time has expired.
|
||||
*/
|
||||
void handleDeploymentFinish();
|
||||
/**
|
||||
* @brief This function performs actions to finish the deployment. Essentially switches
|
||||
* are turned of after the burn time has expired.
|
||||
*/
|
||||
void handleDeploymentFinish();
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_SOLARARRAYDEPLOYMENT_H_ */
|
||||
|
@ -1,230 +1,214 @@
|
||||
#include "SusHandler.h"
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
#include <fsfw/datapool/PoolReadGuard.h>
|
||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||
|
||||
SusHandler::SusHandler(object_id_t objectId, object_id_t comIF, CookieIF * comCookie,
|
||||
LinuxLibgpioIF* gpioComIF, gpioId_t chipSelectId) :
|
||||
DeviceHandlerBase(objectId, comIF, comCookie), gpioComIF(gpioComIF), chipSelectId(
|
||||
chipSelectId), dataset(this) {
|
||||
if (comCookie == NULL) {
|
||||
sif::error << "SusHandler: Invalid com cookie" << std::endl;
|
||||
}
|
||||
if (gpioComIF == NULL) {
|
||||
sif::error << "SusHandler: Invalid GpioComIF" << std::endl;
|
||||
}
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
SusHandler::SusHandler(object_id_t objectId, object_id_t comIF, CookieIF *comCookie,
|
||||
LinuxLibgpioIF *gpioComIF, gpioId_t chipSelectId)
|
||||
: DeviceHandlerBase(objectId, comIF, comCookie),
|
||||
gpioComIF(gpioComIF),
|
||||
chipSelectId(chipSelectId),
|
||||
dataset(this) {
|
||||
if (comCookie == NULL) {
|
||||
sif::error << "SusHandler: Invalid com cookie" << std::endl;
|
||||
}
|
||||
if (gpioComIF == NULL) {
|
||||
sif::error << "SusHandler: Invalid GpioComIF" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
SusHandler::~SusHandler() {
|
||||
}
|
||||
SusHandler::~SusHandler() {}
|
||||
|
||||
ReturnValue_t SusHandler::performOperation(uint8_t counter) {
|
||||
|
||||
if (counter != FIRST_WRITE) {
|
||||
DeviceHandlerBase::performOperation(counter);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
if (mode != MODE_NORMAL) {
|
||||
DeviceHandlerBase::performOperation(DeviceHandlerIF::SEND_WRITE);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
/* If device is in normale mode the communication sequence is initiated here */
|
||||
if (communicationStep == CommunicationStep::IDLE) {
|
||||
communicationStep = CommunicationStep::WRITE_SETUP;
|
||||
}
|
||||
|
||||
DeviceHandlerBase::performOperation(DeviceHandlerIF::SEND_WRITE);
|
||||
|
||||
if (counter != FIRST_WRITE) {
|
||||
DeviceHandlerBase::performOperation(counter);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
if (mode != MODE_NORMAL) {
|
||||
DeviceHandlerBase::performOperation(DeviceHandlerIF::SEND_WRITE);
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
/* If device is in normale mode the communication sequence is initiated here */
|
||||
if (communicationStep == CommunicationStep::IDLE) {
|
||||
communicationStep = CommunicationStep::WRITE_SETUP;
|
||||
}
|
||||
|
||||
DeviceHandlerBase::performOperation(DeviceHandlerIF::SEND_WRITE);
|
||||
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t SusHandler::initialize() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = DeviceHandlerBase::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
auto spiComIF = dynamic_cast<SpiComIF*>(communicationInterface);
|
||||
if (spiComIF == nullptr) {
|
||||
sif::debug << "SusHandler::initialize: Invalid communication interface" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
spiMutex = spiComIF->getMutex();
|
||||
if (spiMutex == nullptr) {
|
||||
sif::debug << "SusHandler::initialize: Failed to get spi mutex" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = DeviceHandlerBase::initialize();
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
auto spiComIF = dynamic_cast<SpiComIF *>(communicationInterface);
|
||||
if (spiComIF == nullptr) {
|
||||
sif::debug << "SusHandler::initialize: Invalid communication interface" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
spiMutex = spiComIF->getMutex();
|
||||
if (spiMutex == nullptr) {
|
||||
sif::debug << "SusHandler::initialize: Failed to get spi mutex" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void SusHandler::doStartUp(){
|
||||
void SusHandler::doStartUp() {
|
||||
#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1
|
||||
setMode(MODE_NORMAL);
|
||||
setMode(MODE_NORMAL);
|
||||
#else
|
||||
setMode(_MODE_TO_ON);
|
||||
setMode(_MODE_TO_ON);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SusHandler::doShutDown(){
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
void SusHandler::doShutDown() { setMode(_MODE_POWER_DOWN); }
|
||||
|
||||
ReturnValue_t SusHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||
if (communicationStep == CommunicationStep::IDLE) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
if (communicationStep == CommunicationStep::WRITE_SETUP) {
|
||||
*id = SUS::WRITE_SETUP;
|
||||
communicationStep = CommunicationStep::START_CONVERSIONS;
|
||||
} else if (communicationStep == CommunicationStep::START_CONVERSIONS) {
|
||||
*id = SUS::START_CONVERSIONS;
|
||||
communicationStep = CommunicationStep::READ_CONVERSIONS;
|
||||
} else if (communicationStep == CommunicationStep::READ_CONVERSIONS) {
|
||||
*id = SUS::READ_CONVERSIONS;
|
||||
communicationStep = CommunicationStep::IDLE;
|
||||
}
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
|
||||
ReturnValue_t SusHandler::buildNormalDeviceCommand(
|
||||
DeviceCommandId_t * id) {
|
||||
|
||||
if (communicationStep == CommunicationStep::IDLE) {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
if (communicationStep == CommunicationStep::WRITE_SETUP) {
|
||||
*id = SUS::WRITE_SETUP;
|
||||
communicationStep = CommunicationStep::START_CONVERSIONS;
|
||||
}
|
||||
else if (communicationStep == CommunicationStep::START_CONVERSIONS) {
|
||||
*id = SUS::START_CONVERSIONS;
|
||||
communicationStep = CommunicationStep::READ_CONVERSIONS;
|
||||
}
|
||||
else if (communicationStep == CommunicationStep::READ_CONVERSIONS) {
|
||||
*id = SUS::READ_CONVERSIONS;
|
||||
communicationStep = CommunicationStep::IDLE;
|
||||
}
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
ReturnValue_t SusHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t SusHandler::buildTransitionDeviceCommand(
|
||||
DeviceCommandId_t * id){
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
ReturnValue_t SusHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
switch (deviceCommand) {
|
||||
case (SUS::WRITE_SETUP): {
|
||||
/**
|
||||
* The sun sensor ADC is shutdown when CS is pulled high, so each time requesting a
|
||||
* measurement the setup has to be rewritten. There must also be a little delay between
|
||||
* the transmission of the setup byte and the first conversion. Thus the conversion
|
||||
* will be performed in an extra step.
|
||||
* Because the chip select is driven manually by the SusHandler the SPI bus must be
|
||||
* protected with a mutex here.
|
||||
*/
|
||||
ReturnValue_t result = spiMutex->lockMutex(timeoutType, timeoutMs);
|
||||
if (result == MutexIF::MUTEX_TIMEOUT) {
|
||||
sif::error << "SusHandler::buildCommandFromCommand: Mutex timeout" << std::endl;
|
||||
return ERROR_LOCK_MUTEX;
|
||||
} else if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "SusHandler::buildCommandFromCommand: Failed to lock spi mutex" << std::endl;
|
||||
return ERROR_LOCK_MUTEX;
|
||||
}
|
||||
|
||||
ReturnValue_t SusHandler::buildCommandFromCommand(
|
||||
DeviceCommandId_t deviceCommand, const uint8_t * commandData,
|
||||
size_t commandDataLen) {
|
||||
switch(deviceCommand) {
|
||||
case(SUS::WRITE_SETUP): {
|
||||
/**
|
||||
* The sun sensor ADC is shutdown when CS is pulled high, so each time requesting a
|
||||
* measurement the setup has to be rewritten. There must also be a little delay between
|
||||
* the transmission of the setup byte and the first conversion. Thus the conversion
|
||||
* will be performed in an extra step.
|
||||
* Because the chip select is driven manually by the SusHandler the SPI bus must be
|
||||
* protected with a mutex here.
|
||||
*/
|
||||
ReturnValue_t result = spiMutex->lockMutex(timeoutType, timeoutMs);
|
||||
if(result == MutexIF::MUTEX_TIMEOUT) {
|
||||
sif::error << "SusHandler::buildCommandFromCommand: Mutex timeout" << std::endl;
|
||||
return ERROR_LOCK_MUTEX;
|
||||
}
|
||||
else if(result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::error << "SusHandler::buildCommandFromCommand: Failed to lock spi mutex"
|
||||
<< std::endl;
|
||||
return ERROR_LOCK_MUTEX;
|
||||
}
|
||||
|
||||
gpioComIF->pullLow(chipSelectId);
|
||||
cmdBuffer[0] = SUS::SETUP;
|
||||
rawPacket = cmdBuffer;
|
||||
rawPacketLen = 1;
|
||||
return RETURN_OK;
|
||||
}
|
||||
case(SUS::START_CONVERSIONS): {
|
||||
std::memset(cmdBuffer, 0, sizeof(cmdBuffer));
|
||||
cmdBuffer[0] = SUS::CONVERSION;
|
||||
rawPacket = cmdBuffer;
|
||||
rawPacketLen = 2;
|
||||
return RETURN_OK;
|
||||
}
|
||||
case(SUS::READ_CONVERSIONS): {
|
||||
std::memset(cmdBuffer, 0, sizeof(cmdBuffer));
|
||||
rawPacket = cmdBuffer;
|
||||
rawPacketLen = SUS::SIZE_READ_CONVERSIONS;
|
||||
return RETURN_OK;
|
||||
}
|
||||
default:
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
gpioComIF->pullLow(chipSelectId);
|
||||
cmdBuffer[0] = SUS::SETUP;
|
||||
rawPacket = cmdBuffer;
|
||||
rawPacketLen = 1;
|
||||
return RETURN_OK;
|
||||
}
|
||||
case (SUS::START_CONVERSIONS): {
|
||||
std::memset(cmdBuffer, 0, sizeof(cmdBuffer));
|
||||
cmdBuffer[0] = SUS::CONVERSION;
|
||||
rawPacket = cmdBuffer;
|
||||
rawPacketLen = 2;
|
||||
return RETURN_OK;
|
||||
}
|
||||
case (SUS::READ_CONVERSIONS): {
|
||||
std::memset(cmdBuffer, 0, sizeof(cmdBuffer));
|
||||
rawPacket = cmdBuffer;
|
||||
rawPacketLen = SUS::SIZE_READ_CONVERSIONS;
|
||||
return RETURN_OK;
|
||||
}
|
||||
default:
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
void SusHandler::fillCommandAndReplyMap() {
|
||||
this->insertInCommandMap(SUS::WRITE_SETUP);
|
||||
this->insertInCommandMap(SUS::START_CONVERSIONS);
|
||||
this->insertInCommandAndReplyMap(SUS::READ_CONVERSIONS, 1, &dataset, SUS::SIZE_READ_CONVERSIONS);
|
||||
this->insertInCommandMap(SUS::WRITE_SETUP);
|
||||
this->insertInCommandMap(SUS::START_CONVERSIONS);
|
||||
this->insertInCommandAndReplyMap(SUS::READ_CONVERSIONS, 1, &dataset, SUS::SIZE_READ_CONVERSIONS);
|
||||
}
|
||||
|
||||
ReturnValue_t SusHandler::scanForReply(const uint8_t *start,
|
||||
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
*foundId = this->getPendingCommand();
|
||||
*foundLen = remainingSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t SusHandler::scanForReply(const uint8_t *start, size_t remainingSize,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
*foundId = this->getPendingCommand();
|
||||
*foundLen = remainingSize;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) {
|
||||
switch (id) {
|
||||
case SUS::READ_CONVERSIONS: {
|
||||
PoolReadGuard readSet(&dataset);
|
||||
dataset.temperatureCelcius = (*(packet) << 8 | *(packet + 1)) * 0.125;
|
||||
dataset.ain0 = (*(packet + 2) << 8 | *(packet + 3));
|
||||
dataset.ain1 = (*(packet + 4) << 8 | *(packet + 5));
|
||||
dataset.ain2 = (*(packet + 6) << 8 | *(packet + 7));
|
||||
dataset.ain3 = (*(packet + 8) << 8 | *(packet + 9));
|
||||
dataset.ain4 = (*(packet + 10) << 8 | *(packet + 11));
|
||||
dataset.ain5 = (*(packet + 12) << 8 | *(packet + 13));
|
||||
ReturnValue_t SusHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) {
|
||||
switch (id) {
|
||||
case SUS::READ_CONVERSIONS: {
|
||||
PoolReadGuard readSet(&dataset);
|
||||
dataset.temperatureCelcius = (*(packet) << 8 | *(packet + 1)) * 0.125;
|
||||
dataset.ain0 = (*(packet + 2) << 8 | *(packet + 3));
|
||||
dataset.ain1 = (*(packet + 4) << 8 | *(packet + 5));
|
||||
dataset.ain2 = (*(packet + 6) << 8 | *(packet + 7));
|
||||
dataset.ain3 = (*(packet + 8) << 8 | *(packet + 9));
|
||||
dataset.ain4 = (*(packet + 10) << 8 | *(packet + 11));
|
||||
dataset.ain5 = (*(packet + 12) << 8 | *(packet + 13));
|
||||
#if OBSW_VERBOSE_LEVEL >= 1 && OBSW_DEBUG_SUS
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", Temperature: "
|
||||
<< dataset.temperatureCelcius << " °C" << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN0: "
|
||||
<< std::dec << dataset.ain0 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN1: "
|
||||
<< std::dec << dataset.ain1 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN2: "
|
||||
<< std::dec << dataset.ain2 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN3: "
|
||||
<< std::dec << dataset.ain3 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN4: "
|
||||
<< std::dec << dataset.ain4 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN5: "
|
||||
<< std::dec << dataset.ain5 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId()
|
||||
<< ", Temperature: " << dataset.temperatureCelcius << " °C" << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN0: " << std::dec
|
||||
<< dataset.ain0 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN1: " << std::dec
|
||||
<< dataset.ain1 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN2: " << std::dec
|
||||
<< dataset.ain2 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN3: " << std::dec
|
||||
<< dataset.ain3 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN4: " << std::dec
|
||||
<< dataset.ain4 << std::endl;
|
||||
sif::info << "SUS object id 0x" << std::hex << this->getObjectId() << ", AIN5: " << std::dec
|
||||
<< dataset.ain5 << std::endl;
|
||||
#endif
|
||||
/** SUS can now be shutdown and thus the SPI bus released again */
|
||||
gpioComIF->pullHigh(chipSelectId);
|
||||
ReturnValue_t result = spiMutex->unlockMutex();
|
||||
if (result != RETURN_OK) {
|
||||
sif::error << "SusHandler::interpretDeviceReply: Failed to unlock spi mutex"
|
||||
<< std::endl;
|
||||
return ERROR_UNLOCK_MUTEX;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "SusHandler::interpretDeviceReply: Unknown reply id" << std::endl;
|
||||
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
|
||||
}
|
||||
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
/** SUS can now be shutdown and thus the SPI bus released again */
|
||||
gpioComIF->pullHigh(chipSelectId);
|
||||
ReturnValue_t result = spiMutex->unlockMutex();
|
||||
if (result != RETURN_OK) {
|
||||
sif::error << "SusHandler::interpretDeviceReply: Failed to unlock spi mutex" << std::endl;
|
||||
return ERROR_UNLOCK_MUTEX;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "SusHandler::interpretDeviceReply: Unknown reply id" << std::endl;
|
||||
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
|
||||
}
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void SusHandler::setNormalDatapoolEntriesInvalid(){
|
||||
void SusHandler::setNormalDatapoolEntriesInvalid() {}
|
||||
|
||||
uint32_t SusHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 1000; }
|
||||
|
||||
ReturnValue_t SusHandler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(SUS::TEMPERATURE_C, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(SUS::AIN0, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(SUS::AIN1, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(SUS::AIN2, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(SUS::AIN3, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(SUS::AIN4, new PoolEntry<uint16_t>({0}));
|
||||
localDataPoolMap.emplace(SUS::AIN5, new PoolEntry<uint16_t>({0}));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
uint32_t SusHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){
|
||||
return 1000;
|
||||
}
|
||||
|
||||
ReturnValue_t SusHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
localDataPoolMap.emplace(SUS::TEMPERATURE_C, new PoolEntry<float>( { 0.0 }));
|
||||
localDataPoolMap.emplace(SUS::AIN0, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(SUS::AIN1, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(SUS::AIN2, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(SUS::AIN3, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(SUS::AIN4, new PoolEntry<uint16_t>( { 0 }));
|
||||
localDataPoolMap.emplace(SUS::AIN5, new PoolEntry<uint16_t>( { 0 }));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
#ifndef MISSION_DEVICES_SUSHANDLER_H_
|
||||
#define MISSION_DEVICES_SUSHANDLER_H_
|
||||
|
||||
#include "devicedefinitions/SusDefinitions.h"
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||
|
||||
#include "devicedefinitions/SusDefinitions.h"
|
||||
|
||||
/**
|
||||
* @brief This is the device handler class for the SUS sensor. The sensor is
|
||||
* based on the MAX1227 ADC. Details about the SUS electronic can be found at
|
||||
@ -18,63 +19,55 @@
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class SusHandler: public DeviceHandlerBase {
|
||||
public:
|
||||
class SusHandler : public DeviceHandlerBase {
|
||||
public:
|
||||
static const uint8_t FIRST_WRITE = 7;
|
||||
|
||||
static const uint8_t FIRST_WRITE = 7;
|
||||
SusHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie,
|
||||
LinuxLibgpioIF* gpioComIF, gpioId_t chipSelectId);
|
||||
virtual ~SusHandler();
|
||||
|
||||
SusHandler(object_id_t objectId, object_id_t comIF,
|
||||
CookieIF * comCookie, LinuxLibgpioIF* gpioComIF, gpioId_t chipSelectId);
|
||||
virtual ~SusHandler();
|
||||
virtual ReturnValue_t performOperation(uint8_t counter) override;
|
||||
|
||||
virtual ReturnValue_t performOperation(uint8_t counter) override;
|
||||
virtual ReturnValue_t initialize() override;
|
||||
|
||||
virtual ReturnValue_t initialize() override;
|
||||
protected:
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
|
||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
|
||||
void fillCommandAndReplyMap() override;
|
||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
|
||||
size_t commandDataLen) override;
|
||||
ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId,
|
||||
size_t* foundLen) override;
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
|
||||
void setNormalDatapoolEntriesInvalid() override;
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
|
||||
protected:
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t * id) override;
|
||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t * id) override;
|
||||
void fillCommandAndReplyMap() override;
|
||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t * commandData,size_t commandDataLen) override;
|
||||
ReturnValue_t scanForReply(const uint8_t *start, size_t remainingSize,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) override;
|
||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) override;
|
||||
void setNormalDatapoolEntriesInvalid() override;
|
||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) override;
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::SUS_HANDLER;
|
||||
|
||||
private:
|
||||
static const ReturnValue_t ERROR_UNLOCK_MUTEX = MAKE_RETURN_CODE(0xA0);
|
||||
static const ReturnValue_t ERROR_LOCK_MUTEX = MAKE_RETURN_CODE(0xA1);
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::SUS_HANDLER;
|
||||
enum class CommunicationStep { IDLE, WRITE_SETUP, START_CONVERSIONS, READ_CONVERSIONS };
|
||||
|
||||
static const ReturnValue_t ERROR_UNLOCK_MUTEX = MAKE_RETURN_CODE(0xA0);
|
||||
static const ReturnValue_t ERROR_LOCK_MUTEX = MAKE_RETURN_CODE(0xA1);
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
|
||||
enum class CommunicationStep {
|
||||
IDLE,
|
||||
WRITE_SETUP,
|
||||
START_CONVERSIONS,
|
||||
READ_CONVERSIONS
|
||||
};
|
||||
gpioId_t chipSelectId = gpio::NO_GPIO;
|
||||
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
SUS::SusDataset dataset;
|
||||
|
||||
gpioId_t chipSelectId = gpio::NO_GPIO;
|
||||
uint8_t cmdBuffer[SUS::MAX_CMD_SIZE];
|
||||
CommunicationStep communicationStep = CommunicationStep::IDLE;
|
||||
|
||||
SUS::SusDataset dataset;
|
||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||
uint32_t timeoutMs = 20;
|
||||
|
||||
uint8_t cmdBuffer[SUS::MAX_CMD_SIZE];
|
||||
CommunicationStep communicationStep = CommunicationStep::IDLE;
|
||||
|
||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||
uint32_t timeoutMs = 20;
|
||||
|
||||
MutexIF* spiMutex = nullptr;
|
||||
MutexIF* spiMutex = nullptr;
|
||||
};
|
||||
|
||||
#endif /* MISSION_DEVICES_SUSHANDLER_H_ */
|
||||
|
@ -3,93 +3,87 @@
|
||||
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <cstdint>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace SUS {
|
||||
|
||||
/**
|
||||
* Some MAX1227 could not be reached with frequencies around 4 MHz. Maybe this is caused by
|
||||
* the decoder and buffer circuits. Thus frequency is here defined to 1 MHz.
|
||||
*/
|
||||
static const uint32_t MAX1227_SPI_FREQ = 1000000;
|
||||
/**
|
||||
* Some MAX1227 could not be reached with frequencies around 4 MHz. Maybe this is caused by
|
||||
* the decoder and buffer circuits. Thus frequency is here defined to 1 MHz.
|
||||
*/
|
||||
static const uint32_t MAX1227_SPI_FREQ = 1000000;
|
||||
|
||||
static const DeviceCommandId_t NONE = 0x0; // Set when no command is pending
|
||||
static const DeviceCommandId_t NONE = 0x0; // Set when no command is pending
|
||||
|
||||
static const DeviceCommandId_t WRITE_SETUP = 0x1;
|
||||
/**
|
||||
* This command initiates the ADC conversion for all channels including the internal
|
||||
* temperature sensor.
|
||||
*/
|
||||
static const DeviceCommandId_t START_CONVERSIONS = 0x2;
|
||||
/**
|
||||
* This command reads the internal fifo which holds the temperature and the channel
|
||||
* conversions.
|
||||
*/
|
||||
static const DeviceCommandId_t READ_CONVERSIONS = 0x3;
|
||||
static const DeviceCommandId_t WRITE_SETUP = 0x1;
|
||||
/**
|
||||
* This command initiates the ADC conversion for all channels including the internal
|
||||
* temperature sensor.
|
||||
*/
|
||||
static const DeviceCommandId_t START_CONVERSIONS = 0x2;
|
||||
/**
|
||||
* This command reads the internal fifo which holds the temperature and the channel
|
||||
* conversions.
|
||||
*/
|
||||
static const DeviceCommandId_t READ_CONVERSIONS = 0x3;
|
||||
|
||||
/**
|
||||
* @brief This is the configuration byte which will be written to the setup register after
|
||||
* power on.
|
||||
*
|
||||
* @note Bit1 (DIFFSEL1) - Bit0 (DIFFSEL0): 0b00, No byte is following the setup byte
|
||||
* Bit3 (REFSEL1) - Bit2 (REFSEL0): 0b10, Internal reference, no wake-up delay
|
||||
* Bit5 (CLKSEL1) - Bit4 (CLKSEL0): 0b10, Internally clocked
|
||||
* Bit7 - Bit6: 0b01, Tells MAX1227 that this byte should be
|
||||
* written to the setup register
|
||||
*
|
||||
*/
|
||||
static const uint8_t SETUP = 0b01101000;
|
||||
/**
|
||||
* @brief This is the configuration byte which will be written to the setup register after
|
||||
* power on.
|
||||
*
|
||||
* @note Bit1 (DIFFSEL1) - Bit0 (DIFFSEL0): 0b00, No byte is following the setup byte
|
||||
* Bit3 (REFSEL1) - Bit2 (REFSEL0): 0b10, Internal reference, no wake-up delay
|
||||
* Bit5 (CLKSEL1) - Bit4 (CLKSEL0): 0b10, Internally clocked
|
||||
* Bit7 - Bit6: 0b01, Tells MAX1227 that this byte should be
|
||||
* written to the setup register
|
||||
*
|
||||
*/
|
||||
static const uint8_t SETUP = 0b01101000;
|
||||
|
||||
/**
|
||||
* @brief This values will always be written to the ADC conversion register to specify the
|
||||
* conversions to perform.
|
||||
* @details Bit0: 1 - Enables temperature conversion
|
||||
* Bit2 (SCAN1) and Bit1 (SCAN0): 0b00, Scans channels 0 through N
|
||||
* Bit6 - Bit3 defines N: 0b0101 (N = 5)
|
||||
* Bit7: Always 1. Tells the ADC that this is the conversion register.
|
||||
*/
|
||||
static const uint8_t CONVERSION = 0b10101001;
|
||||
/**
|
||||
* @brief This values will always be written to the ADC conversion register to specify the
|
||||
* conversions to perform.
|
||||
* @details Bit0: 1 - Enables temperature conversion
|
||||
* Bit2 (SCAN1) and Bit1 (SCAN0): 0b00, Scans channels 0 through N
|
||||
* Bit6 - Bit3 defines N: 0b0101 (N = 5)
|
||||
* Bit7: Always 1. Tells the ADC that this is the conversion register.
|
||||
*/
|
||||
static const uint8_t CONVERSION = 0b10101001;
|
||||
|
||||
static const uint8_t SUS_DATA_SET_ID = READ_CONVERSIONS;
|
||||
static const uint8_t SUS_DATA_SET_ID = READ_CONVERSIONS;
|
||||
|
||||
/** Size of data replies. Temperature and 6 channel convesions (AIN0 - AIN5) */
|
||||
static const uint8_t SIZE_READ_CONVERSIONS = 14;
|
||||
/** Size of data replies. Temperature and 6 channel convesions (AIN0 - AIN5) */
|
||||
static const uint8_t SIZE_READ_CONVERSIONS = 14;
|
||||
|
||||
static const uint8_t MAX_CMD_SIZE = SIZE_READ_CONVERSIONS;
|
||||
static const uint8_t MAX_CMD_SIZE = SIZE_READ_CONVERSIONS;
|
||||
|
||||
static const uint8_t POOL_ENTRIES = 7;
|
||||
static const uint8_t POOL_ENTRIES = 7;
|
||||
|
||||
enum Max1227PoolIds: lp_id_t {
|
||||
TEMPERATURE_C,
|
||||
AIN0,
|
||||
AIN1,
|
||||
AIN2,
|
||||
AIN3,
|
||||
AIN4,
|
||||
AIN5,
|
||||
};
|
||||
|
||||
class SusDataset: public StaticLocalDataSet<POOL_ENTRIES> {
|
||||
public:
|
||||
|
||||
SusDataset(HasLocalDataPoolIF* owner) :
|
||||
StaticLocalDataSet(owner, SUS_DATA_SET_ID) {
|
||||
}
|
||||
|
||||
SusDataset(object_id_t objectId) :
|
||||
StaticLocalDataSet(sid_t(objectId, SUS_DATA_SET_ID)) {
|
||||
}
|
||||
|
||||
lp_var_t<float> temperatureCelcius = lp_var_t<float>(sid.objectId, TEMPERATURE_C, this);
|
||||
lp_var_t<uint16_t> ain0 = lp_var_t<uint16_t>(sid.objectId, AIN0, this);
|
||||
lp_var_t<uint16_t> ain1 = lp_var_t<uint16_t>(sid.objectId, AIN1, this);
|
||||
lp_var_t<uint16_t> ain2 = lp_var_t<uint16_t>(sid.objectId, AIN2, this);
|
||||
lp_var_t<uint16_t> ain3 = lp_var_t<uint16_t>(sid.objectId, AIN3, this);
|
||||
lp_var_t<uint16_t> ain4 = lp_var_t<uint16_t>(sid.objectId, AIN4, this);
|
||||
lp_var_t<uint16_t> ain5 = lp_var_t<uint16_t>(sid.objectId, AIN5, this);
|
||||
enum Max1227PoolIds : lp_id_t {
|
||||
TEMPERATURE_C,
|
||||
AIN0,
|
||||
AIN1,
|
||||
AIN2,
|
||||
AIN3,
|
||||
AIN4,
|
||||
AIN5,
|
||||
};
|
||||
}
|
||||
|
||||
class SusDataset : public StaticLocalDataSet<POOL_ENTRIES> {
|
||||
public:
|
||||
SusDataset(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SUS_DATA_SET_ID) {}
|
||||
|
||||
SusDataset(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, SUS_DATA_SET_ID)) {}
|
||||
|
||||
lp_var_t<float> temperatureCelcius = lp_var_t<float>(sid.objectId, TEMPERATURE_C, this);
|
||||
lp_var_t<uint16_t> ain0 = lp_var_t<uint16_t>(sid.objectId, AIN0, this);
|
||||
lp_var_t<uint16_t> ain1 = lp_var_t<uint16_t>(sid.objectId, AIN1, this);
|
||||
lp_var_t<uint16_t> ain2 = lp_var_t<uint16_t>(sid.objectId, AIN2, this);
|
||||
lp_var_t<uint16_t> ain3 = lp_var_t<uint16_t>(sid.objectId, AIN3, this);
|
||||
lp_var_t<uint16_t> ain4 = lp_var_t<uint16_t>(sid.objectId, AIN4, this);
|
||||
lp_var_t<uint16_t> ain5 = lp_var_t<uint16_t>(sid.objectId, AIN5, this);
|
||||
};
|
||||
} // namespace SUS
|
||||
|
||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_SUS_H_ */
|
||||
|
@ -5,7 +5,3 @@
|
||||
*/
|
||||
|
||||
#include "addresses.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -2,84 +2,85 @@
|
||||
#define FSFWCONFIG_DEVICES_ADDRESSES_H_
|
||||
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include "objects/systemObjectList.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "objects/systemObjectList.h"
|
||||
|
||||
namespace addresses {
|
||||
/* Logical addresses have uint32_t datatype */
|
||||
enum logicalAddresses: address_t {
|
||||
PCDU,
|
||||
/* Logical addresses have uint32_t datatype */
|
||||
enum logicalAddresses : address_t {
|
||||
PCDU,
|
||||
|
||||
MGM_0_LIS3 = objects::MGM_0_LIS3_HANDLER,
|
||||
MGM_1_RM3100 = objects::MGM_1_RM3100_HANDLER,
|
||||
MGM_2_LIS3 = objects::MGM_2_LIS3_HANDLER,
|
||||
MGM_3_RM3100 = objects::MGM_3_RM3100_HANDLER,
|
||||
MGM_0_LIS3 = objects::MGM_0_LIS3_HANDLER,
|
||||
MGM_1_RM3100 = objects::MGM_1_RM3100_HANDLER,
|
||||
MGM_2_LIS3 = objects::MGM_2_LIS3_HANDLER,
|
||||
MGM_3_RM3100 = objects::MGM_3_RM3100_HANDLER,
|
||||
|
||||
GYRO_0_ADIS = objects::GYRO_0_ADIS_HANDLER,
|
||||
GYRO_1_L3G = objects::GYRO_1_L3G_HANDLER,
|
||||
GYRO_2_ADIS = objects::GYRO_2_ADIS_HANDLER,
|
||||
GYRO_3_L3G = objects::GYRO_3_L3G_HANDLER,
|
||||
GYRO_0_ADIS = objects::GYRO_0_ADIS_HANDLER,
|
||||
GYRO_1_L3G = objects::GYRO_1_L3G_HANDLER,
|
||||
GYRO_2_ADIS = objects::GYRO_2_ADIS_HANDLER,
|
||||
GYRO_3_L3G = objects::GYRO_3_L3G_HANDLER,
|
||||
|
||||
RAD_SENSOR = objects::RAD_SENSOR,
|
||||
RAD_SENSOR = objects::RAD_SENSOR,
|
||||
|
||||
SUS_1 = objects::SUS_1,
|
||||
SUS_2 = objects::SUS_2,
|
||||
SUS_3 = objects::SUS_3,
|
||||
SUS_4 = objects::SUS_4,
|
||||
SUS_5 = objects::SUS_5,
|
||||
SUS_6 = objects::SUS_6,
|
||||
SUS_7 = objects::SUS_7,
|
||||
SUS_8 = objects::SUS_8,
|
||||
SUS_9 = objects::SUS_9,
|
||||
SUS_10 = objects::SUS_10,
|
||||
SUS_11 = objects::SUS_11,
|
||||
SUS_12 = objects::SUS_12,
|
||||
SUS_13 = objects::SUS_13,
|
||||
SUS_1 = objects::SUS_1,
|
||||
SUS_2 = objects::SUS_2,
|
||||
SUS_3 = objects::SUS_3,
|
||||
SUS_4 = objects::SUS_4,
|
||||
SUS_5 = objects::SUS_5,
|
||||
SUS_6 = objects::SUS_6,
|
||||
SUS_7 = objects::SUS_7,
|
||||
SUS_8 = objects::SUS_8,
|
||||
SUS_9 = objects::SUS_9,
|
||||
SUS_10 = objects::SUS_10,
|
||||
SUS_11 = objects::SUS_11,
|
||||
SUS_12 = objects::SUS_12,
|
||||
SUS_13 = objects::SUS_13,
|
||||
|
||||
/* Dummy and Test Addresses */
|
||||
DUMMY_ECHO = 129,
|
||||
DUMMY_GPS0 = 130,
|
||||
DUMMY_GPS1 = 131,
|
||||
};
|
||||
/* Dummy and Test Addresses */
|
||||
DUMMY_ECHO = 129,
|
||||
DUMMY_GPS0 = 130,
|
||||
DUMMY_GPS1 = 131,
|
||||
};
|
||||
|
||||
enum i2cAddresses: address_t {
|
||||
IMTQ = 16,
|
||||
TMP1075_TCS_1 = 72,
|
||||
TMP1075_TCS_2 = 73,
|
||||
};
|
||||
enum i2cAddresses : address_t {
|
||||
IMTQ = 16,
|
||||
TMP1075_TCS_1 = 72,
|
||||
TMP1075_TCS_2 = 73,
|
||||
};
|
||||
|
||||
enum spiAddresses: address_t {
|
||||
RTD_IC_3,
|
||||
RTD_IC_4,
|
||||
RTD_IC_5,
|
||||
RTD_IC_6,
|
||||
RTD_IC_7,
|
||||
RTD_IC_8,
|
||||
RTD_IC_9,
|
||||
RTD_IC_10,
|
||||
RTD_IC_11,
|
||||
RTD_IC_12,
|
||||
RTD_IC_13,
|
||||
RTD_IC_14,
|
||||
RTD_IC_15,
|
||||
RTD_IC_16,
|
||||
RTD_IC_17,
|
||||
RTD_IC_18,
|
||||
RW1,
|
||||
RW2,
|
||||
RW3,
|
||||
RW4
|
||||
};
|
||||
|
||||
/* Addresses of devices supporting the CSP protocol */
|
||||
enum cspAddresses: uint8_t {
|
||||
P60DOCK = 4,
|
||||
ACU = 2,
|
||||
PDU1 = 3,
|
||||
/* PDU2 occupies X4 slot of P60Dock */
|
||||
PDU2 = 6
|
||||
};
|
||||
}
|
||||
enum spiAddresses : address_t {
|
||||
RTD_IC_3,
|
||||
RTD_IC_4,
|
||||
RTD_IC_5,
|
||||
RTD_IC_6,
|
||||
RTD_IC_7,
|
||||
RTD_IC_8,
|
||||
RTD_IC_9,
|
||||
RTD_IC_10,
|
||||
RTD_IC_11,
|
||||
RTD_IC_12,
|
||||
RTD_IC_13,
|
||||
RTD_IC_14,
|
||||
RTD_IC_15,
|
||||
RTD_IC_16,
|
||||
RTD_IC_17,
|
||||
RTD_IC_18,
|
||||
RW1,
|
||||
RW2,
|
||||
RW3,
|
||||
RW4
|
||||
};
|
||||
|
||||
/* Addresses of devices supporting the CSP protocol */
|
||||
enum cspAddresses : uint8_t {
|
||||
P60DOCK = 4,
|
||||
ACU = 2,
|
||||
PDU1 = 3,
|
||||
/* PDU2 occupies X4 slot of P60Dock */
|
||||
PDU2 = 6
|
||||
};
|
||||
} // namespace addresses
|
||||
|
||||
#endif /* FSFWCONFIG_DEVICES_ADDRESSES_H_ */
|
||||
|
@ -5,116 +5,112 @@
|
||||
|
||||
namespace gpioIds {
|
||||
enum gpioId_t {
|
||||
HEATER_0,
|
||||
HEATER_1,
|
||||
HEATER_2,
|
||||
HEATER_3,
|
||||
HEATER_4,
|
||||
HEATER_5,
|
||||
HEATER_6,
|
||||
HEATER_7,
|
||||
DEPLSA1,
|
||||
DEPLSA2,
|
||||
HEATER_0,
|
||||
HEATER_1,
|
||||
HEATER_2,
|
||||
HEATER_3,
|
||||
HEATER_4,
|
||||
HEATER_5,
|
||||
HEATER_6,
|
||||
HEATER_7,
|
||||
DEPLSA1,
|
||||
DEPLSA2,
|
||||
|
||||
MGM_0_LIS3_CS,
|
||||
MGM_1_RM3100_CS,
|
||||
GYRO_0_ADIS_CS,
|
||||
GYRO_1_L3G_CS,
|
||||
GYRO_2_ADIS_CS,
|
||||
GYRO_3_L3G_CS,
|
||||
MGM_2_LIS3_CS,
|
||||
MGM_3_RM3100_CS,
|
||||
MGM_0_LIS3_CS,
|
||||
MGM_1_RM3100_CS,
|
||||
GYRO_0_ADIS_CS,
|
||||
GYRO_1_L3G_CS,
|
||||
GYRO_2_ADIS_CS,
|
||||
GYRO_3_L3G_CS,
|
||||
MGM_2_LIS3_CS,
|
||||
MGM_3_RM3100_CS,
|
||||
|
||||
GNSS_0_NRESET,
|
||||
GNSS_1_NRESET,
|
||||
GNSS_0_ENABLE,
|
||||
GNSS_1_ENABLE,
|
||||
GNSS_0_NRESET,
|
||||
GNSS_1_NRESET,
|
||||
GNSS_0_ENABLE,
|
||||
GNSS_1_ENABLE,
|
||||
|
||||
GYRO_0_ENABLE,
|
||||
GYRO_2_ENABLE,
|
||||
GYRO_0_ENABLE,
|
||||
GYRO_2_ENABLE,
|
||||
|
||||
TEST_ID_0,
|
||||
TEST_ID_1,
|
||||
TEST_ID_0,
|
||||
TEST_ID_1,
|
||||
|
||||
RTD_IC_3,
|
||||
RTD_IC_4,
|
||||
RTD_IC_5,
|
||||
RTD_IC_6,
|
||||
RTD_IC_7,
|
||||
RTD_IC_8,
|
||||
RTD_IC_9,
|
||||
RTD_IC_10,
|
||||
RTD_IC_11,
|
||||
RTD_IC_12,
|
||||
RTD_IC_13,
|
||||
RTD_IC_14,
|
||||
RTD_IC_15,
|
||||
RTD_IC_16,
|
||||
RTD_IC_17,
|
||||
RTD_IC_18,
|
||||
RTD_IC_3,
|
||||
RTD_IC_4,
|
||||
RTD_IC_5,
|
||||
RTD_IC_6,
|
||||
RTD_IC_7,
|
||||
RTD_IC_8,
|
||||
RTD_IC_9,
|
||||
RTD_IC_10,
|
||||
RTD_IC_11,
|
||||
RTD_IC_12,
|
||||
RTD_IC_13,
|
||||
RTD_IC_14,
|
||||
RTD_IC_15,
|
||||
RTD_IC_16,
|
||||
RTD_IC_17,
|
||||
RTD_IC_18,
|
||||
|
||||
CS_SUS_1,
|
||||
CS_SUS_2,
|
||||
CS_SUS_3,
|
||||
CS_SUS_4,
|
||||
CS_SUS_5,
|
||||
CS_SUS_6,
|
||||
CS_SUS_7,
|
||||
CS_SUS_8,
|
||||
CS_SUS_9,
|
||||
CS_SUS_10,
|
||||
CS_SUS_11,
|
||||
CS_SUS_12,
|
||||
CS_SUS_13,
|
||||
CS_SUS_1,
|
||||
CS_SUS_2,
|
||||
CS_SUS_3,
|
||||
CS_SUS_4,
|
||||
CS_SUS_5,
|
||||
CS_SUS_6,
|
||||
CS_SUS_7,
|
||||
CS_SUS_8,
|
||||
CS_SUS_9,
|
||||
CS_SUS_10,
|
||||
CS_SUS_11,
|
||||
CS_SUS_12,
|
||||
CS_SUS_13,
|
||||
|
||||
SPI_MUX_BIT_1,
|
||||
SPI_MUX_BIT_2,
|
||||
SPI_MUX_BIT_3,
|
||||
SPI_MUX_BIT_4,
|
||||
SPI_MUX_BIT_5,
|
||||
SPI_MUX_BIT_6,
|
||||
SPI_MUX_BIT_1,
|
||||
SPI_MUX_BIT_2,
|
||||
SPI_MUX_BIT_3,
|
||||
SPI_MUX_BIT_4,
|
||||
SPI_MUX_BIT_5,
|
||||
SPI_MUX_BIT_6,
|
||||
|
||||
CS_RAD_SENSOR,
|
||||
CS_RAD_SENSOR,
|
||||
|
||||
PAPB_BUSY_N,
|
||||
PAPB_EMPTY,
|
||||
PAPB_BUSY_N,
|
||||
PAPB_EMPTY,
|
||||
|
||||
EN_RW1,
|
||||
EN_RW2,
|
||||
EN_RW3,
|
||||
EN_RW4,
|
||||
EN_RW1,
|
||||
EN_RW2,
|
||||
EN_RW3,
|
||||
EN_RW4,
|
||||
|
||||
CS_RW1,
|
||||
CS_RW2,
|
||||
CS_RW3,
|
||||
CS_RW4,
|
||||
CS_RW1,
|
||||
CS_RW2,
|
||||
CS_RW3,
|
||||
CS_RW4,
|
||||
|
||||
EN_RW_CS,
|
||||
EN_RW_CS,
|
||||
|
||||
SPI_MUX,
|
||||
SPI_MUX,
|
||||
|
||||
VC0_PAPB_EMPTY,
|
||||
VC0_PAPB_BUSY,
|
||||
VC1_PAPB_EMPTY,
|
||||
VC1_PAPB_BUSY,
|
||||
VC2_PAPB_EMPTY,
|
||||
VC2_PAPB_BUSY,
|
||||
VC3_PAPB_EMPTY,
|
||||
VC3_PAPB_BUSY,
|
||||
VC0_PAPB_EMPTY,
|
||||
VC0_PAPB_BUSY,
|
||||
VC1_PAPB_EMPTY,
|
||||
VC1_PAPB_BUSY,
|
||||
VC2_PAPB_EMPTY,
|
||||
VC2_PAPB_BUSY,
|
||||
VC3_PAPB_EMPTY,
|
||||
VC3_PAPB_BUSY,
|
||||
|
||||
PDEC_RESET,
|
||||
PDEC_RESET,
|
||||
|
||||
RS485_EN_TX_DATA,
|
||||
RS485_EN_TX_CLOCK,
|
||||
RS485_EN_RX_DATA,
|
||||
RS485_EN_RX_CLOCK,
|
||||
|
||||
RS485_EN_TX_DATA,
|
||||
RS485_EN_TX_CLOCK,
|
||||
RS485_EN_RX_DATA,
|
||||
RS485_EN_RX_CLOCK,
|
||||
|
||||
BIT_RATE_SEL
|
||||
BIT_RATE_SEL
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* FSFWCONFIG_DEVICES_GPIOIDS_H_ */
|
||||
|
@ -4,55 +4,54 @@
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
namespace pcduSwitches {
|
||||
/* Switches are uint8_t datatype and go from 0 to 255 */
|
||||
enum SwitcherList: uint8_t {
|
||||
Q7S,
|
||||
PAYLOAD_PCDU_CH1,
|
||||
RW,
|
||||
TCS_BOARD_8V_HEATER_IN,
|
||||
SUS_REDUNDANT,
|
||||
DEPLOYMENT_MECHANISM,
|
||||
PAYLOAD_PCDU_CH6,
|
||||
ACS_BOARD_SIDE_B,
|
||||
PAYLOAD_CAMERA,
|
||||
TCS_BOARD_3V3,
|
||||
SYRLINKS,
|
||||
STAR_TRACKER,
|
||||
MGT,
|
||||
SUS_NOMINAL,
|
||||
SOLAR_CELL_EXP,
|
||||
PLOC,
|
||||
ACS_BOARD_SIDE_A,
|
||||
NUMBER_OF_SWITCHES
|
||||
};
|
||||
/* Switches are uint8_t datatype and go from 0 to 255 */
|
||||
enum SwitcherList : uint8_t {
|
||||
Q7S,
|
||||
PAYLOAD_PCDU_CH1,
|
||||
RW,
|
||||
TCS_BOARD_8V_HEATER_IN,
|
||||
SUS_REDUNDANT,
|
||||
DEPLOYMENT_MECHANISM,
|
||||
PAYLOAD_PCDU_CH6,
|
||||
ACS_BOARD_SIDE_B,
|
||||
PAYLOAD_CAMERA,
|
||||
TCS_BOARD_3V3,
|
||||
SYRLINKS,
|
||||
STAR_TRACKER,
|
||||
MGT,
|
||||
SUS_NOMINAL,
|
||||
SOLAR_CELL_EXP,
|
||||
PLOC,
|
||||
ACS_BOARD_SIDE_A,
|
||||
NUMBER_OF_SWITCHES
|
||||
};
|
||||
|
||||
static const uint8_t ON = 1;
|
||||
static const uint8_t OFF = 0;
|
||||
static const uint8_t ON = 1;
|
||||
static const uint8_t OFF = 0;
|
||||
|
||||
/* Output states after reboot of the PDUs */
|
||||
static const uint8_t INIT_STATE_Q7S = ON;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
|
||||
static const uint8_t INIT_STATE_RW = OFF;
|
||||
/* Output states after reboot of the PDUs */
|
||||
static const uint8_t INIT_STATE_Q7S = ON;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH1 = OFF;
|
||||
static const uint8_t INIT_STATE_RW = OFF;
|
||||
#if BOARD_TE0720 == 1
|
||||
/* Because the TE0720 is not connected to the PCDU, this switch is always on */
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
|
||||
/* Because the TE0720 is not connected to the PCDU, this switch is always on */
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = ON;
|
||||
#else
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_8V_HEATER_IN = OFF;
|
||||
#endif
|
||||
static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF;
|
||||
static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF;
|
||||
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF;
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF;
|
||||
static const uint8_t INIT_STATE_SYRLINKS = OFF;
|
||||
static const uint8_t INIT_STATE_STAR_TRACKER = OFF;
|
||||
static const uint8_t INIT_STATE_MGT = OFF;
|
||||
static const uint8_t INIT_STATE_SUS_NOMINAL = OFF;
|
||||
static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF;
|
||||
static const uint8_t INIT_STATE_PLOC = OFF;
|
||||
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF;
|
||||
}
|
||||
|
||||
static const uint8_t INIT_STATE_SUS_REDUNDANT = OFF;
|
||||
static const uint8_t INIT_STATE_DEPLOYMENT_MECHANISM = OFF;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_PCDU_CH6 = OFF;
|
||||
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_B = OFF;
|
||||
static const uint8_t INIT_STATE_PAYLOAD_CAMERA = OFF;
|
||||
static const uint8_t INIT_STATE_TCS_BOARD_3V3 = OFF;
|
||||
static const uint8_t INIT_STATE_SYRLINKS = OFF;
|
||||
static const uint8_t INIT_STATE_STAR_TRACKER = OFF;
|
||||
static const uint8_t INIT_STATE_MGT = OFF;
|
||||
static const uint8_t INIT_STATE_SUS_NOMINAL = OFF;
|
||||
static const uint8_t INIT_STATE_SOLAR_CELL_EXP = OFF;
|
||||
static const uint8_t INIT_STATE_PLOC = OFF;
|
||||
static const uint8_t INIT_STATE_ACS_BOARD_SIDE_A = OFF;
|
||||
} // namespace pcduSwitches
|
||||
|
||||
#endif /* FSFWCONFIG_DEVICES_POWERSWITCHERLIST_H_ */
|
||||
|
@ -1,19 +1,19 @@
|
||||
#ifndef FSFWCONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
#define FSFWCONFIG_EVENTS_SUBSYSTEMIDRANGES_H_
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "common/config/commonSubsystemIds.h"
|
||||
#include "fsfw/events/fwSubsystemIdRanges.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* These IDs are part of the ID for an event thrown by a subsystem.
|
||||
* Numbers 0-80 are reserved for FSFW Subsystem IDs (framework/events/)
|
||||
*/
|
||||
namespace SUBSYSTEM_ID {
|
||||
enum: uint8_t {
|
||||
SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END,
|
||||
CORE = 116,
|
||||
enum : uint8_t {
|
||||
SUBSYSTEM_ID_START = COMMON_SUBSYSTEM_ID_END,
|
||||
CORE = 116,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -146,290 +146,290 @@ const char *STR_HELPER_FILE_NOT_EXISTS_STRING = "STR_HELPER_FILE_NOT_EXISTS";
|
||||
const char *STR_HELPER_SENDING_PACKET_FAILED_STRING = "STR_HELPER_SENDING_PACKET_FAILED";
|
||||
const char *STR_HELPER_REQUESTING_MSG_FAILED_STRING = "STR_HELPER_REQUESTING_MSG_FAILED";
|
||||
|
||||
const char * translateEvents(Event event) {
|
||||
switch( (event & 0xffff) ) {
|
||||
case(2200):
|
||||
return STORE_SEND_WRITE_FAILED_STRING;
|
||||
case(2201):
|
||||
return STORE_WRITE_FAILED_STRING;
|
||||
case(2202):
|
||||
return STORE_SEND_READ_FAILED_STRING;
|
||||
case(2203):
|
||||
return STORE_READ_FAILED_STRING;
|
||||
case(2204):
|
||||
return UNEXPECTED_MSG_STRING;
|
||||
case(2205):
|
||||
return STORING_FAILED_STRING;
|
||||
case(2206):
|
||||
return TM_DUMP_FAILED_STRING;
|
||||
case(2207):
|
||||
return STORE_INIT_FAILED_STRING;
|
||||
case(2208):
|
||||
return STORE_INIT_EMPTY_STRING;
|
||||
case(2209):
|
||||
return STORE_CONTENT_CORRUPTED_STRING;
|
||||
case(2210):
|
||||
return STORE_INITIALIZE_STRING;
|
||||
case(2211):
|
||||
return INIT_DONE_STRING;
|
||||
case(2212):
|
||||
return DUMP_FINISHED_STRING;
|
||||
case(2213):
|
||||
return DELETION_FINISHED_STRING;
|
||||
case(2214):
|
||||
return DELETION_FAILED_STRING;
|
||||
case(2215):
|
||||
return AUTO_CATALOGS_SENDING_FAILED_STRING;
|
||||
case(2600):
|
||||
return GET_DATA_FAILED_STRING;
|
||||
case(2601):
|
||||
return STORE_DATA_FAILED_STRING;
|
||||
case(2800):
|
||||
return DEVICE_BUILDING_COMMAND_FAILED_STRING;
|
||||
case(2801):
|
||||
return DEVICE_SENDING_COMMAND_FAILED_STRING;
|
||||
case(2802):
|
||||
return DEVICE_REQUESTING_REPLY_FAILED_STRING;
|
||||
case(2803):
|
||||
return DEVICE_READING_REPLY_FAILED_STRING;
|
||||
case(2804):
|
||||
return DEVICE_INTERPRETING_REPLY_FAILED_STRING;
|
||||
case(2805):
|
||||
return DEVICE_MISSED_REPLY_STRING;
|
||||
case(2806):
|
||||
return DEVICE_UNKNOWN_REPLY_STRING;
|
||||
case(2807):
|
||||
return DEVICE_UNREQUESTED_REPLY_STRING;
|
||||
case(2808):
|
||||
return INVALID_DEVICE_COMMAND_STRING;
|
||||
case(2809):
|
||||
return MONITORING_LIMIT_EXCEEDED_STRING;
|
||||
case(2810):
|
||||
return MONITORING_AMBIGUOUS_STRING;
|
||||
case(4201):
|
||||
return FUSE_CURRENT_HIGH_STRING;
|
||||
case(4202):
|
||||
return FUSE_WENT_OFF_STRING;
|
||||
case(4204):
|
||||
return POWER_ABOVE_HIGH_LIMIT_STRING;
|
||||
case(4205):
|
||||
return POWER_BELOW_LOW_LIMIT_STRING;
|
||||
case(4300):
|
||||
return SWITCH_WENT_OFF_STRING;
|
||||
case(5000):
|
||||
return HEATER_ON_STRING;
|
||||
case(5001):
|
||||
return HEATER_OFF_STRING;
|
||||
case(5002):
|
||||
return HEATER_TIMEOUT_STRING;
|
||||
case(5003):
|
||||
return HEATER_STAYED_ON_STRING;
|
||||
case(5004):
|
||||
return HEATER_STAYED_OFF_STRING;
|
||||
case(5200):
|
||||
return TEMP_SENSOR_HIGH_STRING;
|
||||
case(5201):
|
||||
return TEMP_SENSOR_LOW_STRING;
|
||||
case(5202):
|
||||
return TEMP_SENSOR_GRADIENT_STRING;
|
||||
case(5901):
|
||||
return COMPONENT_TEMP_LOW_STRING;
|
||||
case(5902):
|
||||
return COMPONENT_TEMP_HIGH_STRING;
|
||||
case(5903):
|
||||
return COMPONENT_TEMP_OOL_LOW_STRING;
|
||||
case(5904):
|
||||
return COMPONENT_TEMP_OOL_HIGH_STRING;
|
||||
case(5905):
|
||||
return TEMP_NOT_IN_OP_RANGE_STRING;
|
||||
case(7101):
|
||||
return FDIR_CHANGED_STATE_STRING;
|
||||
case(7102):
|
||||
return FDIR_STARTS_RECOVERY_STRING;
|
||||
case(7103):
|
||||
return FDIR_TURNS_OFF_DEVICE_STRING;
|
||||
case(7201):
|
||||
return MONITOR_CHANGED_STATE_STRING;
|
||||
case(7202):
|
||||
return VALUE_BELOW_LOW_LIMIT_STRING;
|
||||
case(7203):
|
||||
return VALUE_ABOVE_HIGH_LIMIT_STRING;
|
||||
case(7204):
|
||||
return VALUE_OUT_OF_RANGE_STRING;
|
||||
case(7301):
|
||||
return SWITCHING_TM_FAILED_STRING;
|
||||
case(7400):
|
||||
return CHANGING_MODE_STRING;
|
||||
case(7401):
|
||||
return MODE_INFO_STRING;
|
||||
case(7402):
|
||||
return FALLBACK_FAILED_STRING;
|
||||
case(7403):
|
||||
return MODE_TRANSITION_FAILED_STRING;
|
||||
case(7404):
|
||||
return CANT_KEEP_MODE_STRING;
|
||||
case(7405):
|
||||
return OBJECT_IN_INVALID_MODE_STRING;
|
||||
case(7406):
|
||||
return FORCING_MODE_STRING;
|
||||
case(7407):
|
||||
return MODE_CMD_REJECTED_STRING;
|
||||
case(7506):
|
||||
return HEALTH_INFO_STRING;
|
||||
case(7507):
|
||||
return CHILD_CHANGED_HEALTH_STRING;
|
||||
case(7508):
|
||||
return CHILD_PROBLEMS_STRING;
|
||||
case(7509):
|
||||
return OVERWRITING_HEALTH_STRING;
|
||||
case(7510):
|
||||
return TRYING_RECOVERY_STRING;
|
||||
case(7511):
|
||||
return RECOVERY_STEP_STRING;
|
||||
case(7512):
|
||||
return RECOVERY_DONE_STRING;
|
||||
case(7900):
|
||||
return RF_AVAILABLE_STRING;
|
||||
case(7901):
|
||||
return RF_LOST_STRING;
|
||||
case(7902):
|
||||
return BIT_LOCK_STRING;
|
||||
case(7903):
|
||||
return BIT_LOCK_LOST_STRING;
|
||||
case(7905):
|
||||
return FRAME_PROCESSING_FAILED_STRING;
|
||||
case(8900):
|
||||
return CLOCK_SET_STRING;
|
||||
case(8901):
|
||||
return CLOCK_SET_FAILURE_STRING;
|
||||
case(9700):
|
||||
return TEST_STRING;
|
||||
case(10600):
|
||||
return CHANGE_OF_SETUP_PARAMETER_STRING;
|
||||
case(10900):
|
||||
return GPIO_PULL_HIGH_FAILED_STRING;
|
||||
case(10901):
|
||||
return GPIO_PULL_LOW_FAILED_STRING;
|
||||
case(10902):
|
||||
return SWITCH_ALREADY_ON_STRING;
|
||||
case(10903):
|
||||
return SWITCH_ALREADY_OFF_STRING;
|
||||
case(10904):
|
||||
return MAIN_SWITCH_TIMEOUT_STRING;
|
||||
case(11000):
|
||||
return MAIN_SWITCH_ON_TIMEOUT_STRING;
|
||||
case(11001):
|
||||
return MAIN_SWITCH_OFF_TIMEOUT_STRING;
|
||||
case(11002):
|
||||
return DEPLOYMENT_FAILED_STRING;
|
||||
case(11003):
|
||||
return DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING;
|
||||
case(11004):
|
||||
return DEPL_SA2_GPIO_SWTICH_ON_FAILED_STRING;
|
||||
case(11101):
|
||||
return MEMORY_READ_RPT_CRC_FAILURE_STRING;
|
||||
case(11102):
|
||||
return ACK_FAILURE_STRING;
|
||||
case(11103):
|
||||
return EXE_FAILURE_STRING;
|
||||
case(11104):
|
||||
return CRC_FAILURE_EVENT_STRING;
|
||||
case(11201):
|
||||
return SELF_TEST_I2C_FAILURE_STRING;
|
||||
case(11202):
|
||||
return SELF_TEST_SPI_FAILURE_STRING;
|
||||
case(11203):
|
||||
return SELF_TEST_ADC_FAILURE_STRING;
|
||||
case(11204):
|
||||
return SELF_TEST_PWM_FAILURE_STRING;
|
||||
case(11205):
|
||||
return SELF_TEST_TC_FAILURE_STRING;
|
||||
case(11206):
|
||||
return SELF_TEST_MTM_RANGE_FAILURE_STRING;
|
||||
case(11207):
|
||||
return SELF_TEST_COIL_CURRENT_FAILURE_STRING;
|
||||
case(11208):
|
||||
return INVALID_ERROR_BYTE_STRING;
|
||||
case(11301):
|
||||
return ERROR_STATE_STRING;
|
||||
case(11501):
|
||||
return SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING;
|
||||
case(11502):
|
||||
return SUPV_ACK_FAILURE_STRING;
|
||||
case(11503):
|
||||
return SUPV_EXE_FAILURE_STRING;
|
||||
case(11504):
|
||||
return SUPV_CRC_FAILURE_EVENT_STRING;
|
||||
case(11600):
|
||||
return SANITIZATION_FAILED_STRING;
|
||||
case(11700):
|
||||
return UPDATE_FILE_NOT_EXISTS_STRING;
|
||||
case(11701):
|
||||
return ACTION_COMMANDING_FAILED_STRING;
|
||||
case(11702):
|
||||
return UPDATE_AVAILABLE_FAILED_STRING;
|
||||
case(11703):
|
||||
return UPDATE_TRANSFER_FAILED_STRING;
|
||||
case(11704):
|
||||
return UPDATE_VERIFY_FAILED_STRING;
|
||||
case(11705):
|
||||
return UPDATE_FINISHED_STRING;
|
||||
case(11800):
|
||||
return SEND_MRAM_DUMP_FAILED_STRING;
|
||||
case(11801):
|
||||
return MRAM_DUMP_FAILED_STRING;
|
||||
case(11802):
|
||||
return MRAM_DUMP_FINISHED_STRING;
|
||||
case(11901):
|
||||
return INVALID_TC_FRAME_STRING;
|
||||
case(11902):
|
||||
return INVALID_FAR_STRING;
|
||||
case(11903):
|
||||
return CARRIER_LOCK_STRING;
|
||||
case(11904):
|
||||
return BIT_LOCK_PDEC_STRING;
|
||||
case(12000):
|
||||
return IMAGE_UPLOAD_FAILED_STRING;
|
||||
case(12001):
|
||||
return IMAGE_DOWNLOAD_FAILED_STRING;
|
||||
case(12002):
|
||||
return IMAGE_UPLOAD_SUCCESSFUL_STRING;
|
||||
case(12003):
|
||||
return IMAGE_DOWNLOAD_SUCCESSFUL_STRING;
|
||||
case(12004):
|
||||
return FLASH_WRITE_SUCCESSFUL_STRING;
|
||||
case(12005):
|
||||
return FLASH_READ_SUCCESSFUL_STRING;
|
||||
case(12006):
|
||||
return FLASH_WRITE_FAILED_STRING;
|
||||
case(12007):
|
||||
return FLASH_READ_FAILED_STRING;
|
||||
case(12008):
|
||||
return FPGA_DOWNLOAD_SUCCESSFUL_STRING;
|
||||
case(12009):
|
||||
return FPGA_DOWNLOAD_FAILED_STRING;
|
||||
case(12010):
|
||||
return FPGA_UPLOAD_SUCCESSFUL_STRING;
|
||||
case(12011):
|
||||
return FPGA_UPLOAD_FAILED_STRING;
|
||||
case(12012):
|
||||
return STR_HELPER_READING_REPLY_FAILED_STRING;
|
||||
case(12013):
|
||||
return STR_HELPER_COM_ERROR_STRING;
|
||||
case(12014):
|
||||
return STR_HELPER_NO_REPLY_STRING;
|
||||
case(12015):
|
||||
return STR_HELPER_DEC_ERROR_STRING;
|
||||
case(12016):
|
||||
return POSITION_MISMATCH_STRING;
|
||||
case(12017):
|
||||
return STR_HELPER_FILE_NOT_EXISTS_STRING;
|
||||
case(12018):
|
||||
return STR_HELPER_SENDING_PACKET_FAILED_STRING;
|
||||
case(12019):
|
||||
return STR_HELPER_REQUESTING_MSG_FAILED_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
return 0;
|
||||
const char *translateEvents(Event event) {
|
||||
switch ((event & 0xffff)) {
|
||||
case (2200):
|
||||
return STORE_SEND_WRITE_FAILED_STRING;
|
||||
case (2201):
|
||||
return STORE_WRITE_FAILED_STRING;
|
||||
case (2202):
|
||||
return STORE_SEND_READ_FAILED_STRING;
|
||||
case (2203):
|
||||
return STORE_READ_FAILED_STRING;
|
||||
case (2204):
|
||||
return UNEXPECTED_MSG_STRING;
|
||||
case (2205):
|
||||
return STORING_FAILED_STRING;
|
||||
case (2206):
|
||||
return TM_DUMP_FAILED_STRING;
|
||||
case (2207):
|
||||
return STORE_INIT_FAILED_STRING;
|
||||
case (2208):
|
||||
return STORE_INIT_EMPTY_STRING;
|
||||
case (2209):
|
||||
return STORE_CONTENT_CORRUPTED_STRING;
|
||||
case (2210):
|
||||
return STORE_INITIALIZE_STRING;
|
||||
case (2211):
|
||||
return INIT_DONE_STRING;
|
||||
case (2212):
|
||||
return DUMP_FINISHED_STRING;
|
||||
case (2213):
|
||||
return DELETION_FINISHED_STRING;
|
||||
case (2214):
|
||||
return DELETION_FAILED_STRING;
|
||||
case (2215):
|
||||
return AUTO_CATALOGS_SENDING_FAILED_STRING;
|
||||
case (2600):
|
||||
return GET_DATA_FAILED_STRING;
|
||||
case (2601):
|
||||
return STORE_DATA_FAILED_STRING;
|
||||
case (2800):
|
||||
return DEVICE_BUILDING_COMMAND_FAILED_STRING;
|
||||
case (2801):
|
||||
return DEVICE_SENDING_COMMAND_FAILED_STRING;
|
||||
case (2802):
|
||||
return DEVICE_REQUESTING_REPLY_FAILED_STRING;
|
||||
case (2803):
|
||||
return DEVICE_READING_REPLY_FAILED_STRING;
|
||||
case (2804):
|
||||
return DEVICE_INTERPRETING_REPLY_FAILED_STRING;
|
||||
case (2805):
|
||||
return DEVICE_MISSED_REPLY_STRING;
|
||||
case (2806):
|
||||
return DEVICE_UNKNOWN_REPLY_STRING;
|
||||
case (2807):
|
||||
return DEVICE_UNREQUESTED_REPLY_STRING;
|
||||
case (2808):
|
||||
return INVALID_DEVICE_COMMAND_STRING;
|
||||
case (2809):
|
||||
return MONITORING_LIMIT_EXCEEDED_STRING;
|
||||
case (2810):
|
||||
return MONITORING_AMBIGUOUS_STRING;
|
||||
case (4201):
|
||||
return FUSE_CURRENT_HIGH_STRING;
|
||||
case (4202):
|
||||
return FUSE_WENT_OFF_STRING;
|
||||
case (4204):
|
||||
return POWER_ABOVE_HIGH_LIMIT_STRING;
|
||||
case (4205):
|
||||
return POWER_BELOW_LOW_LIMIT_STRING;
|
||||
case (4300):
|
||||
return SWITCH_WENT_OFF_STRING;
|
||||
case (5000):
|
||||
return HEATER_ON_STRING;
|
||||
case (5001):
|
||||
return HEATER_OFF_STRING;
|
||||
case (5002):
|
||||
return HEATER_TIMEOUT_STRING;
|
||||
case (5003):
|
||||
return HEATER_STAYED_ON_STRING;
|
||||
case (5004):
|
||||
return HEATER_STAYED_OFF_STRING;
|
||||
case (5200):
|
||||
return TEMP_SENSOR_HIGH_STRING;
|
||||
case (5201):
|
||||
return TEMP_SENSOR_LOW_STRING;
|
||||
case (5202):
|
||||
return TEMP_SENSOR_GRADIENT_STRING;
|
||||
case (5901):
|
||||
return COMPONENT_TEMP_LOW_STRING;
|
||||
case (5902):
|
||||
return COMPONENT_TEMP_HIGH_STRING;
|
||||
case (5903):
|
||||
return COMPONENT_TEMP_OOL_LOW_STRING;
|
||||
case (5904):
|
||||
return COMPONENT_TEMP_OOL_HIGH_STRING;
|
||||
case (5905):
|
||||
return TEMP_NOT_IN_OP_RANGE_STRING;
|
||||
case (7101):
|
||||
return FDIR_CHANGED_STATE_STRING;
|
||||
case (7102):
|
||||
return FDIR_STARTS_RECOVERY_STRING;
|
||||
case (7103):
|
||||
return FDIR_TURNS_OFF_DEVICE_STRING;
|
||||
case (7201):
|
||||
return MONITOR_CHANGED_STATE_STRING;
|
||||
case (7202):
|
||||
return VALUE_BELOW_LOW_LIMIT_STRING;
|
||||
case (7203):
|
||||
return VALUE_ABOVE_HIGH_LIMIT_STRING;
|
||||
case (7204):
|
||||
return VALUE_OUT_OF_RANGE_STRING;
|
||||
case (7301):
|
||||
return SWITCHING_TM_FAILED_STRING;
|
||||
case (7400):
|
||||
return CHANGING_MODE_STRING;
|
||||
case (7401):
|
||||
return MODE_INFO_STRING;
|
||||
case (7402):
|
||||
return FALLBACK_FAILED_STRING;
|
||||
case (7403):
|
||||
return MODE_TRANSITION_FAILED_STRING;
|
||||
case (7404):
|
||||
return CANT_KEEP_MODE_STRING;
|
||||
case (7405):
|
||||
return OBJECT_IN_INVALID_MODE_STRING;
|
||||
case (7406):
|
||||
return FORCING_MODE_STRING;
|
||||
case (7407):
|
||||
return MODE_CMD_REJECTED_STRING;
|
||||
case (7506):
|
||||
return HEALTH_INFO_STRING;
|
||||
case (7507):
|
||||
return CHILD_CHANGED_HEALTH_STRING;
|
||||
case (7508):
|
||||
return CHILD_PROBLEMS_STRING;
|
||||
case (7509):
|
||||
return OVERWRITING_HEALTH_STRING;
|
||||
case (7510):
|
||||
return TRYING_RECOVERY_STRING;
|
||||
case (7511):
|
||||
return RECOVERY_STEP_STRING;
|
||||
case (7512):
|
||||
return RECOVERY_DONE_STRING;
|
||||
case (7900):
|
||||
return RF_AVAILABLE_STRING;
|
||||
case (7901):
|
||||
return RF_LOST_STRING;
|
||||
case (7902):
|
||||
return BIT_LOCK_STRING;
|
||||
case (7903):
|
||||
return BIT_LOCK_LOST_STRING;
|
||||
case (7905):
|
||||
return FRAME_PROCESSING_FAILED_STRING;
|
||||
case (8900):
|
||||
return CLOCK_SET_STRING;
|
||||
case (8901):
|
||||
return CLOCK_SET_FAILURE_STRING;
|
||||
case (9700):
|
||||
return TEST_STRING;
|
||||
case (10600):
|
||||
return CHANGE_OF_SETUP_PARAMETER_STRING;
|
||||
case (10900):
|
||||
return GPIO_PULL_HIGH_FAILED_STRING;
|
||||
case (10901):
|
||||
return GPIO_PULL_LOW_FAILED_STRING;
|
||||
case (10902):
|
||||
return SWITCH_ALREADY_ON_STRING;
|
||||
case (10903):
|
||||
return SWITCH_ALREADY_OFF_STRING;
|
||||
case (10904):
|
||||
return MAIN_SWITCH_TIMEOUT_STRING;
|
||||
case (11000):
|
||||
return MAIN_SWITCH_ON_TIMEOUT_STRING;
|
||||
case (11001):
|
||||
return MAIN_SWITCH_OFF_TIMEOUT_STRING;
|
||||
case (11002):
|
||||
return DEPLOYMENT_FAILED_STRING;
|
||||
case (11003):
|
||||
return DEPL_SA1_GPIO_SWTICH_ON_FAILED_STRING;
|
||||
case (11004):
|
||||
return DEPL_SA2_GPIO_SWTICH_ON_FAILED_STRING;
|
||||
case (11101):
|
||||
return MEMORY_READ_RPT_CRC_FAILURE_STRING;
|
||||
case (11102):
|
||||
return ACK_FAILURE_STRING;
|
||||
case (11103):
|
||||
return EXE_FAILURE_STRING;
|
||||
case (11104):
|
||||
return CRC_FAILURE_EVENT_STRING;
|
||||
case (11201):
|
||||
return SELF_TEST_I2C_FAILURE_STRING;
|
||||
case (11202):
|
||||
return SELF_TEST_SPI_FAILURE_STRING;
|
||||
case (11203):
|
||||
return SELF_TEST_ADC_FAILURE_STRING;
|
||||
case (11204):
|
||||
return SELF_TEST_PWM_FAILURE_STRING;
|
||||
case (11205):
|
||||
return SELF_TEST_TC_FAILURE_STRING;
|
||||
case (11206):
|
||||
return SELF_TEST_MTM_RANGE_FAILURE_STRING;
|
||||
case (11207):
|
||||
return SELF_TEST_COIL_CURRENT_FAILURE_STRING;
|
||||
case (11208):
|
||||
return INVALID_ERROR_BYTE_STRING;
|
||||
case (11301):
|
||||
return ERROR_STATE_STRING;
|
||||
case (11501):
|
||||
return SUPV_MEMORY_READ_RPT_CRC_FAILURE_STRING;
|
||||
case (11502):
|
||||
return SUPV_ACK_FAILURE_STRING;
|
||||
case (11503):
|
||||
return SUPV_EXE_FAILURE_STRING;
|
||||
case (11504):
|
||||
return SUPV_CRC_FAILURE_EVENT_STRING;
|
||||
case (11600):
|
||||
return SANITIZATION_FAILED_STRING;
|
||||
case (11700):
|
||||
return UPDATE_FILE_NOT_EXISTS_STRING;
|
||||
case (11701):
|
||||
return ACTION_COMMANDING_FAILED_STRING;
|
||||
case (11702):
|
||||
return UPDATE_AVAILABLE_FAILED_STRING;
|
||||
case (11703):
|
||||
return UPDATE_TRANSFER_FAILED_STRING;
|
||||
case (11704):
|
||||
return UPDATE_VERIFY_FAILED_STRING;
|
||||
case (11705):
|
||||
return UPDATE_FINISHED_STRING;
|
||||
case (11800):
|
||||
return SEND_MRAM_DUMP_FAILED_STRING;
|
||||
case (11801):
|
||||
return MRAM_DUMP_FAILED_STRING;
|
||||
case (11802):
|
||||
return MRAM_DUMP_FINISHED_STRING;
|
||||
case (11901):
|
||||
return INVALID_TC_FRAME_STRING;
|
||||
case (11902):
|
||||
return INVALID_FAR_STRING;
|
||||
case (11903):
|
||||
return CARRIER_LOCK_STRING;
|
||||
case (11904):
|
||||
return BIT_LOCK_PDEC_STRING;
|
||||
case (12000):
|
||||
return IMAGE_UPLOAD_FAILED_STRING;
|
||||
case (12001):
|
||||
return IMAGE_DOWNLOAD_FAILED_STRING;
|
||||
case (12002):
|
||||
return IMAGE_UPLOAD_SUCCESSFUL_STRING;
|
||||
case (12003):
|
||||
return IMAGE_DOWNLOAD_SUCCESSFUL_STRING;
|
||||
case (12004):
|
||||
return FLASH_WRITE_SUCCESSFUL_STRING;
|
||||
case (12005):
|
||||
return FLASH_READ_SUCCESSFUL_STRING;
|
||||
case (12006):
|
||||
return FLASH_WRITE_FAILED_STRING;
|
||||
case (12007):
|
||||
return FLASH_READ_FAILED_STRING;
|
||||
case (12008):
|
||||
return FPGA_DOWNLOAD_SUCCESSFUL_STRING;
|
||||
case (12009):
|
||||
return FPGA_DOWNLOAD_FAILED_STRING;
|
||||
case (12010):
|
||||
return FPGA_UPLOAD_SUCCESSFUL_STRING;
|
||||
case (12011):
|
||||
return FPGA_UPLOAD_FAILED_STRING;
|
||||
case (12012):
|
||||
return STR_HELPER_READING_REPLY_FAILED_STRING;
|
||||
case (12013):
|
||||
return STR_HELPER_COM_ERROR_STRING;
|
||||
case (12014):
|
||||
return STR_HELPER_NO_REPLY_STRING;
|
||||
case (12015):
|
||||
return STR_HELPER_DEC_ERROR_STRING;
|
||||
case (12016):
|
||||
return POSITION_MISMATCH_STRING;
|
||||
case (12017):
|
||||
return STR_HELPER_FILE_NOT_EXISTS_STRING;
|
||||
case (12018):
|
||||
return STR_HELPER_SENDING_PACKET_FAILED_STRING;
|
||||
case (12019):
|
||||
return STR_HELPER_REQUESTING_MSG_FAILED_STRING;
|
||||
default:
|
||||
return "UNKNOWN_EVENT";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,6 +3,6 @@
|
||||
|
||||
#include "fsfw/events/Event.h"
|
||||
|
||||
const char * translateEvents(Event event);
|
||||
const char* translateEvents(Event event);
|
||||
|
||||
#endif /* FSFWCONFIG_EVENTS_TRANSLATEEVENTS_H_ */
|
||||
|
@ -1,12 +1,10 @@
|
||||
#include "MissionMessageTypes.h"
|
||||
|
||||
#include <fsfw/ipc/CommandMessage.h>
|
||||
|
||||
|
||||
void messagetypes::clearMissionMessage(CommandMessage* message) {
|
||||
switch(message->getMessageType()) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (message->getMessageType()) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -11,12 +11,12 @@ class CommandMessage;
|
||||
* <fsfw/ipc/FwMessageTypes.h>
|
||||
* @param message Generic Command Message
|
||||
*/
|
||||
namespace messagetypes{
|
||||
namespace messagetypes {
|
||||
enum MESSAGE_TYPE {
|
||||
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
|
||||
MISSION_MESSAGE_TYPE_START = FW_MESSAGES_COUNT,
|
||||
};
|
||||
|
||||
void clearMissionMessage(CommandMessage* message);
|
||||
}
|
||||
} // namespace messagetypes
|
||||
|
||||
#endif /* FSFWCONFIG_IPC_MISSIONMESSAGETYPES_H_ */
|
||||
|
@ -1,10 +1,12 @@
|
||||
#ifndef HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||
#define HOSTED_CONFIG_OBJECTS_SYSTEMOBJECTLIST_H_
|
||||
|
||||
#include "commonObjects.h"
|
||||
#include <fsfw/objectmanager/frameworkObjects.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "commonObjects.h"
|
||||
|
||||
// The objects will be instantiated in the ID order
|
||||
// For naming scheme see flight manual
|
||||
/*
|
||||
@ -31,38 +33,38 @@ Fourth byte is a unique counter.
|
||||
|
||||
*/
|
||||
namespace objects {
|
||||
enum sourceObjects: uint32_t {
|
||||
/* 0x53 reserved for FSFW */
|
||||
FW_ADDRESS_START = PUS_SERVICE_1_VERIFICATION,
|
||||
FW_ADDRESS_END = TIME_STAMPER,
|
||||
PUS_SERVICE_6 = 0x51000500,
|
||||
enum sourceObjects : uint32_t {
|
||||
/* 0x53 reserved for FSFW */
|
||||
FW_ADDRESS_START = PUS_SERVICE_1_VERIFICATION,
|
||||
FW_ADDRESS_END = TIME_STAMPER,
|
||||
PUS_SERVICE_6 = 0x51000500,
|
||||
|
||||
CCSDS_IP_CORE_BRIDGE = 0x73500000,
|
||||
TM_FUNNEL = 0x73000100,
|
||||
CCSDS_IP_CORE_BRIDGE = 0x73500000,
|
||||
TM_FUNNEL = 0x73000100,
|
||||
|
||||
/* 0x49 ('I') for Communication Interfaces **/
|
||||
ARDUINO_COM_IF = 0x49000000,
|
||||
CSP_COM_IF = 0x49050001,
|
||||
I2C_COM_IF = 0x49040002,
|
||||
UART_COM_IF = 0x49030003,
|
||||
SPI_COM_IF = 0x49020004,
|
||||
GPIO_IF = 0x49010005,
|
||||
/* 0x49 ('I') for Communication Interfaces **/
|
||||
ARDUINO_COM_IF = 0x49000000,
|
||||
CSP_COM_IF = 0x49050001,
|
||||
I2C_COM_IF = 0x49040002,
|
||||
UART_COM_IF = 0x49030003,
|
||||
SPI_COM_IF = 0x49020004,
|
||||
GPIO_IF = 0x49010005,
|
||||
|
||||
/* Custom device handler */
|
||||
PCDU_HANDLER = 0x442000A1,
|
||||
SOLAR_ARRAY_DEPL_HANDLER = 0x444100A2,
|
||||
SYRLINKS_HK_HANDLER = 0x445300A3,
|
||||
HEATER_HANDLER = 0x444100A4,
|
||||
RAD_SENSOR = 0x443200A5,
|
||||
/* Custom device handler */
|
||||
PCDU_HANDLER = 0x442000A1,
|
||||
SOLAR_ARRAY_DEPL_HANDLER = 0x444100A2,
|
||||
SYRLINKS_HK_HANDLER = 0x445300A3,
|
||||
HEATER_HANDLER = 0x444100A4,
|
||||
RAD_SENSOR = 0x443200A5,
|
||||
|
||||
/* 0x54 ('T') for test handlers */
|
||||
TEST_TASK = 0x54694269,
|
||||
LIBGPIOD_TEST = 0x54123456,
|
||||
SPI_TEST = 0x54000010,
|
||||
UART_TEST = 0x54000020,
|
||||
DUMMY_INTERFACE = 0x5400CAFE,
|
||||
DUMMY_HANDLER = 0x5400AFFE,
|
||||
P60DOCK_TEST_TASK = 0x00005060,
|
||||
/* 0x54 ('T') for test handlers */
|
||||
TEST_TASK = 0x54694269,
|
||||
LIBGPIOD_TEST = 0x54123456,
|
||||
SPI_TEST = 0x54000010,
|
||||
UART_TEST = 0x54000020,
|
||||
DUMMY_INTERFACE = 0x5400CAFE,
|
||||
DUMMY_HANDLER = 0x5400AFFE,
|
||||
P60DOCK_TEST_TASK = 0x00005060,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -120,236 +120,236 @@ const char *TM_FUNNEL_STRING = "TM_FUNNEL";
|
||||
const char *CCSDS_IP_CORE_BRIDGE_STRING = "CCSDS_IP_CORE_BRIDGE";
|
||||
const char *NO_OBJECT_STRING = "NO_OBJECT";
|
||||
|
||||
const char* translateObject(object_id_t object) {
|
||||
switch( (object & 0xFFFFFFFF) ) {
|
||||
case 0x00005060:
|
||||
return P60DOCK_TEST_TASK_STRING;
|
||||
case 0x43000003:
|
||||
return CORE_CONTROLLER_STRING;
|
||||
case 0x43100002:
|
||||
return ACS_CONTROLLER_STRING;
|
||||
case 0x43400001:
|
||||
return THERMAL_CONTROLLER_STRING;
|
||||
case 0x44120006:
|
||||
return MGM_0_LIS3_HANDLER_STRING;
|
||||
case 0x44120010:
|
||||
return GYRO_0_ADIS_HANDLER_STRING;
|
||||
case 0x44120032:
|
||||
return SUS_1_STRING;
|
||||
case 0x44120033:
|
||||
return SUS_2_STRING;
|
||||
case 0x44120034:
|
||||
return SUS_3_STRING;
|
||||
case 0x44120035:
|
||||
return SUS_4_STRING;
|
||||
case 0x44120036:
|
||||
return SUS_5_STRING;
|
||||
case 0x44120037:
|
||||
return SUS_6_STRING;
|
||||
case 0x44120038:
|
||||
return SUS_7_STRING;
|
||||
case 0x44120039:
|
||||
return SUS_8_STRING;
|
||||
case 0x44120040:
|
||||
return SUS_9_STRING;
|
||||
case 0x44120041:
|
||||
return SUS_10_STRING;
|
||||
case 0x44120042:
|
||||
return SUS_11_STRING;
|
||||
case 0x44120043:
|
||||
return SUS_12_STRING;
|
||||
case 0x44120044:
|
||||
return SUS_13_STRING;
|
||||
case 0x44120047:
|
||||
return RW1_STRING;
|
||||
case 0x44120107:
|
||||
return MGM_1_RM3100_HANDLER_STRING;
|
||||
case 0x44120111:
|
||||
return GYRO_1_L3G_HANDLER_STRING;
|
||||
case 0x44120148:
|
||||
return RW2_STRING;
|
||||
case 0x44120208:
|
||||
return MGM_2_LIS3_HANDLER_STRING;
|
||||
case 0x44120212:
|
||||
return GYRO_2_ADIS_HANDLER_STRING;
|
||||
case 0x44120249:
|
||||
return RW3_STRING;
|
||||
case 0x44120309:
|
||||
return MGM_3_RM3100_HANDLER_STRING;
|
||||
case 0x44120313:
|
||||
return GYRO_3_L3G_HANDLER_STRING;
|
||||
case 0x44120350:
|
||||
return RW4_STRING;
|
||||
case 0x44130001:
|
||||
return STAR_TRACKER_STRING;
|
||||
case 0x44130045:
|
||||
return GPS0_HANDLER_STRING;
|
||||
case 0x44130146:
|
||||
return GPS1_HANDLER_STRING;
|
||||
case 0x44140014:
|
||||
return IMTQ_HANDLER_STRING;
|
||||
case 0x442000A1:
|
||||
return PCDU_HANDLER_STRING;
|
||||
case 0x44250000:
|
||||
return P60DOCK_HANDLER_STRING;
|
||||
case 0x44250001:
|
||||
return PDU1_HANDLER_STRING;
|
||||
case 0x44250002:
|
||||
return PDU2_HANDLER_STRING;
|
||||
case 0x44250003:
|
||||
return ACU_HANDLER_STRING;
|
||||
case 0x443200A5:
|
||||
return RAD_SENSOR_STRING;
|
||||
case 0x44330000:
|
||||
return PLOC_UPDATER_STRING;
|
||||
case 0x44330001:
|
||||
return PLOC_MEMORY_DUMPER_STRING;
|
||||
case 0x44330002:
|
||||
return STR_HELPER_STRING;
|
||||
case 0x44330015:
|
||||
return PLOC_MPSOC_HANDLER_STRING;
|
||||
case 0x44330016:
|
||||
return PLOC_SUPERVISOR_HANDLER_STRING;
|
||||
case 0x444100A2:
|
||||
return SOLAR_ARRAY_DEPL_HANDLER_STRING;
|
||||
case 0x444100A4:
|
||||
return HEATER_HANDLER_STRING;
|
||||
case 0x44420004:
|
||||
return TMP1075_HANDLER_1_STRING;
|
||||
case 0x44420005:
|
||||
return TMP1075_HANDLER_2_STRING;
|
||||
case 0x44420016:
|
||||
return RTD_IC_3_STRING;
|
||||
case 0x44420017:
|
||||
return RTD_IC_4_STRING;
|
||||
case 0x44420018:
|
||||
return RTD_IC_5_STRING;
|
||||
case 0x44420019:
|
||||
return RTD_IC_6_STRING;
|
||||
case 0x44420020:
|
||||
return RTD_IC_7_STRING;
|
||||
case 0x44420021:
|
||||
return RTD_IC_8_STRING;
|
||||
case 0x44420022:
|
||||
return RTD_IC_9_STRING;
|
||||
case 0x44420023:
|
||||
return RTD_IC_10_STRING;
|
||||
case 0x44420024:
|
||||
return RTD_IC_11_STRING;
|
||||
case 0x44420025:
|
||||
return RTD_IC_12_STRING;
|
||||
case 0x44420026:
|
||||
return RTD_IC_13_STRING;
|
||||
case 0x44420027:
|
||||
return RTD_IC_14_STRING;
|
||||
case 0x44420028:
|
||||
return RTD_IC_15_STRING;
|
||||
case 0x44420029:
|
||||
return RTD_IC_16_STRING;
|
||||
case 0x44420030:
|
||||
return RTD_IC_17_STRING;
|
||||
case 0x44420031:
|
||||
return RTD_IC_18_STRING;
|
||||
case 0x445300A3:
|
||||
return SYRLINKS_HK_HANDLER_STRING;
|
||||
case 0x49000000:
|
||||
return ARDUINO_COM_IF_STRING;
|
||||
case 0x49010005:
|
||||
return GPIO_IF_STRING;
|
||||
case 0x49020004:
|
||||
return SPI_COM_IF_STRING;
|
||||
case 0x49030003:
|
||||
return UART_COM_IF_STRING;
|
||||
case 0x49040002:
|
||||
return I2C_COM_IF_STRING;
|
||||
case 0x49050001:
|
||||
return CSP_COM_IF_STRING;
|
||||
case 0x50000100:
|
||||
return CCSDS_PACKET_DISTRIBUTOR_STRING;
|
||||
case 0x50000200:
|
||||
return PUS_PACKET_DISTRIBUTOR_STRING;
|
||||
case 0x50000300:
|
||||
return TMTC_BRIDGE_STRING;
|
||||
case 0x50000400:
|
||||
return TMTC_POLLING_TASK_STRING;
|
||||
case 0x50000500:
|
||||
return FILE_SYSTEM_HANDLER_STRING;
|
||||
case 0x50000600:
|
||||
return PTME_STRING;
|
||||
case 0x50000700:
|
||||
return PAPB_VC0_STRING;
|
||||
case 0x50000701:
|
||||
return PAPB_VC1_STRING;
|
||||
case 0x50000702:
|
||||
return PAPB_VC2_STRING;
|
||||
case 0x50000703:
|
||||
return PAPB_VC3_STRING;
|
||||
case 0x50000704:
|
||||
return PDEC_HANDLER_STRING;
|
||||
case 0x50000800:
|
||||
return CCSDS_HANDLER_STRING;
|
||||
case 0x51000500:
|
||||
return PUS_SERVICE_6_STRING;
|
||||
case 0x53000000:
|
||||
return FSFW_OBJECTS_START_STRING;
|
||||
case 0x53000001:
|
||||
return PUS_SERVICE_1_VERIFICATION_STRING;
|
||||
case 0x53000002:
|
||||
return PUS_SERVICE_2_DEVICE_ACCESS_STRING;
|
||||
case 0x53000003:
|
||||
return PUS_SERVICE_3_HOUSEKEEPING_STRING;
|
||||
case 0x53000005:
|
||||
return PUS_SERVICE_5_EVENT_REPORTING_STRING;
|
||||
case 0x53000008:
|
||||
return PUS_SERVICE_8_FUNCTION_MGMT_STRING;
|
||||
case 0x53000009:
|
||||
return PUS_SERVICE_9_TIME_MGMT_STRING;
|
||||
case 0x53000017:
|
||||
return PUS_SERVICE_17_TEST_STRING;
|
||||
case 0x53000020:
|
||||
return PUS_SERVICE_20_PARAMETERS_STRING;
|
||||
case 0x53000200:
|
||||
return PUS_SERVICE_200_MODE_MGMT_STRING;
|
||||
case 0x53000201:
|
||||
return PUS_SERVICE_201_HEALTH_STRING;
|
||||
case 0x53010000:
|
||||
return HEALTH_TABLE_STRING;
|
||||
case 0x53010100:
|
||||
return MODE_STORE_STRING;
|
||||
case 0x53030000:
|
||||
return EVENT_MANAGER_STRING;
|
||||
case 0x53040000:
|
||||
return INTERNAL_ERROR_REPORTER_STRING;
|
||||
case 0x534f0100:
|
||||
return TC_STORE_STRING;
|
||||
case 0x534f0200:
|
||||
return TM_STORE_STRING;
|
||||
case 0x534f0300:
|
||||
return IPC_STORE_STRING;
|
||||
case 0x53500010:
|
||||
return TIME_STAMPER_STRING;
|
||||
case 0x53ffffff:
|
||||
return FSFW_OBJECTS_END_STRING;
|
||||
case 0x54000010:
|
||||
return SPI_TEST_STRING;
|
||||
case 0x54000020:
|
||||
return UART_TEST_STRING;
|
||||
case 0x5400AFFE:
|
||||
return DUMMY_HANDLER_STRING;
|
||||
case 0x5400CAFE:
|
||||
return DUMMY_INTERFACE_STRING;
|
||||
case 0x54123456:
|
||||
return LIBGPIOD_TEST_STRING;
|
||||
case 0x54694269:
|
||||
return TEST_TASK_STRING;
|
||||
case 0x73000100:
|
||||
return TM_FUNNEL_STRING;
|
||||
case 0x73500000:
|
||||
return CCSDS_IP_CORE_BRIDGE_STRING;
|
||||
case 0xFFFFFFFF:
|
||||
return NO_OBJECT_STRING;
|
||||
default:
|
||||
return "UNKNOWN_OBJECT";
|
||||
}
|
||||
return 0;
|
||||
const char *translateObject(object_id_t object) {
|
||||
switch ((object & 0xFFFFFFFF)) {
|
||||
case 0x00005060:
|
||||
return P60DOCK_TEST_TASK_STRING;
|
||||
case 0x43000003:
|
||||
return CORE_CONTROLLER_STRING;
|
||||
case 0x43100002:
|
||||
return ACS_CONTROLLER_STRING;
|
||||
case 0x43400001:
|
||||
return THERMAL_CONTROLLER_STRING;
|
||||
case 0x44120006:
|
||||
return MGM_0_LIS3_HANDLER_STRING;
|
||||
case 0x44120010:
|
||||
return GYRO_0_ADIS_HANDLER_STRING;
|
||||
case 0x44120032:
|
||||
return SUS_1_STRING;
|
||||
case 0x44120033:
|
||||
return SUS_2_STRING;
|
||||
case 0x44120034:
|
||||
return SUS_3_STRING;
|
||||
case 0x44120035:
|
||||
return SUS_4_STRING;
|
||||
case 0x44120036:
|
||||
return SUS_5_STRING;
|
||||
case 0x44120037:
|
||||
return SUS_6_STRING;
|
||||
case 0x44120038:
|
||||
return SUS_7_STRING;
|
||||
case 0x44120039:
|
||||
return SUS_8_STRING;
|
||||
case 0x44120040:
|
||||
return SUS_9_STRING;
|
||||
case 0x44120041:
|
||||
return SUS_10_STRING;
|
||||
case 0x44120042:
|
||||
return SUS_11_STRING;
|
||||
case 0x44120043:
|
||||
return SUS_12_STRING;
|
||||
case 0x44120044:
|
||||
return SUS_13_STRING;
|
||||
case 0x44120047:
|
||||
return RW1_STRING;
|
||||
case 0x44120107:
|
||||
return MGM_1_RM3100_HANDLER_STRING;
|
||||
case 0x44120111:
|
||||
return GYRO_1_L3G_HANDLER_STRING;
|
||||
case 0x44120148:
|
||||
return RW2_STRING;
|
||||
case 0x44120208:
|
||||
return MGM_2_LIS3_HANDLER_STRING;
|
||||
case 0x44120212:
|
||||
return GYRO_2_ADIS_HANDLER_STRING;
|
||||
case 0x44120249:
|
||||
return RW3_STRING;
|
||||
case 0x44120309:
|
||||
return MGM_3_RM3100_HANDLER_STRING;
|
||||
case 0x44120313:
|
||||
return GYRO_3_L3G_HANDLER_STRING;
|
||||
case 0x44120350:
|
||||
return RW4_STRING;
|
||||
case 0x44130001:
|
||||
return STAR_TRACKER_STRING;
|
||||
case 0x44130045:
|
||||
return GPS0_HANDLER_STRING;
|
||||
case 0x44130146:
|
||||
return GPS1_HANDLER_STRING;
|
||||
case 0x44140014:
|
||||
return IMTQ_HANDLER_STRING;
|
||||
case 0x442000A1:
|
||||
return PCDU_HANDLER_STRING;
|
||||
case 0x44250000:
|
||||
return P60DOCK_HANDLER_STRING;
|
||||
case 0x44250001:
|
||||
return PDU1_HANDLER_STRING;
|
||||
case 0x44250002:
|
||||
return PDU2_HANDLER_STRING;
|
||||
case 0x44250003:
|
||||
return ACU_HANDLER_STRING;
|
||||
case 0x443200A5:
|
||||
return RAD_SENSOR_STRING;
|
||||
case 0x44330000:
|
||||
return PLOC_UPDATER_STRING;
|
||||
case 0x44330001:
|
||||
return PLOC_MEMORY_DUMPER_STRING;
|
||||
case 0x44330002:
|
||||
return STR_HELPER_STRING;
|
||||
case 0x44330015:
|
||||
return PLOC_MPSOC_HANDLER_STRING;
|
||||
case 0x44330016:
|
||||
return PLOC_SUPERVISOR_HANDLER_STRING;
|
||||
case 0x444100A2:
|
||||
return SOLAR_ARRAY_DEPL_HANDLER_STRING;
|
||||
case 0x444100A4:
|
||||
return HEATER_HANDLER_STRING;
|
||||
case 0x44420004:
|
||||
return TMP1075_HANDLER_1_STRING;
|
||||
case 0x44420005:
|
||||
return TMP1075_HANDLER_2_STRING;
|
||||
case 0x44420016:
|
||||
return RTD_IC_3_STRING;
|
||||
case 0x44420017:
|
||||
return RTD_IC_4_STRING;
|
||||
case 0x44420018:
|
||||
return RTD_IC_5_STRING;
|
||||
case 0x44420019:
|
||||
return RTD_IC_6_STRING;
|
||||
case 0x44420020:
|
||||
return RTD_IC_7_STRING;
|
||||
case 0x44420021:
|
||||
return RTD_IC_8_STRING;
|
||||
case 0x44420022:
|
||||
return RTD_IC_9_STRING;
|
||||
case 0x44420023:
|
||||
return RTD_IC_10_STRING;
|
||||
case 0x44420024:
|
||||
return RTD_IC_11_STRING;
|
||||
case 0x44420025:
|
||||
return RTD_IC_12_STRING;
|
||||
case 0x44420026:
|
||||
return RTD_IC_13_STRING;
|
||||
case 0x44420027:
|
||||
return RTD_IC_14_STRING;
|
||||
case 0x44420028:
|
||||
return RTD_IC_15_STRING;
|
||||
case 0x44420029:
|
||||
return RTD_IC_16_STRING;
|
||||
case 0x44420030:
|
||||
return RTD_IC_17_STRING;
|
||||
case 0x44420031:
|
||||
return RTD_IC_18_STRING;
|
||||
case 0x445300A3:
|
||||
return SYRLINKS_HK_HANDLER_STRING;
|
||||
case 0x49000000:
|
||||
return ARDUINO_COM_IF_STRING;
|
||||
case 0x49010005:
|
||||
return GPIO_IF_STRING;
|
||||
case 0x49020004:
|
||||
return SPI_COM_IF_STRING;
|
||||
case 0x49030003:
|
||||
return UART_COM_IF_STRING;
|
||||
case 0x49040002:
|
||||
return I2C_COM_IF_STRING;
|
||||
case 0x49050001:
|
||||
return CSP_COM_IF_STRING;
|
||||
case 0x50000100:
|
||||
return CCSDS_PACKET_DISTRIBUTOR_STRING;
|
||||
case 0x50000200:
|
||||
return PUS_PACKET_DISTRIBUTOR_STRING;
|
||||
case 0x50000300:
|
||||
return TMTC_BRIDGE_STRING;
|
||||
case 0x50000400:
|
||||
return TMTC_POLLING_TASK_STRING;
|
||||
case 0x50000500:
|
||||
return FILE_SYSTEM_HANDLER_STRING;
|
||||
case 0x50000600:
|
||||
return PTME_STRING;
|
||||
case 0x50000700:
|
||||
return PAPB_VC0_STRING;
|
||||
case 0x50000701:
|
||||
return PAPB_VC1_STRING;
|
||||
case 0x50000702:
|
||||
return PAPB_VC2_STRING;
|
||||
case 0x50000703:
|
||||
return PAPB_VC3_STRING;
|
||||
case 0x50000704:
|
||||
return PDEC_HANDLER_STRING;
|
||||
case 0x50000800:
|
||||
return CCSDS_HANDLER_STRING;
|
||||
case 0x51000500:
|
||||
return PUS_SERVICE_6_STRING;
|
||||
case 0x53000000:
|
||||
return FSFW_OBJECTS_START_STRING;
|
||||
case 0x53000001:
|
||||
return PUS_SERVICE_1_VERIFICATION_STRING;
|
||||
case 0x53000002:
|
||||
return PUS_SERVICE_2_DEVICE_ACCESS_STRING;
|
||||
case 0x53000003:
|
||||
return PUS_SERVICE_3_HOUSEKEEPING_STRING;
|
||||
case 0x53000005:
|
||||
return PUS_SERVICE_5_EVENT_REPORTING_STRING;
|
||||
case 0x53000008:
|
||||
return PUS_SERVICE_8_FUNCTION_MGMT_STRING;
|
||||
case 0x53000009:
|
||||
return PUS_SERVICE_9_TIME_MGMT_STRING;
|
||||
case 0x53000017:
|
||||
return PUS_SERVICE_17_TEST_STRING;
|
||||
case 0x53000020:
|
||||
return PUS_SERVICE_20_PARAMETERS_STRING;
|
||||
case 0x53000200:
|
||||
return PUS_SERVICE_200_MODE_MGMT_STRING;
|
||||
case 0x53000201:
|
||||
return PUS_SERVICE_201_HEALTH_STRING;
|
||||
case 0x53010000:
|
||||
return HEALTH_TABLE_STRING;
|
||||
case 0x53010100:
|
||||
return MODE_STORE_STRING;
|
||||
case 0x53030000:
|
||||
return EVENT_MANAGER_STRING;
|
||||
case 0x53040000:
|
||||
return INTERNAL_ERROR_REPORTER_STRING;
|
||||
case 0x534f0100:
|
||||
return TC_STORE_STRING;
|
||||
case 0x534f0200:
|
||||
return TM_STORE_STRING;
|
||||
case 0x534f0300:
|
||||
return IPC_STORE_STRING;
|
||||
case 0x53500010:
|
||||
return TIME_STAMPER_STRING;
|
||||
case 0x53ffffff:
|
||||
return FSFW_OBJECTS_END_STRING;
|
||||
case 0x54000010:
|
||||
return SPI_TEST_STRING;
|
||||
case 0x54000020:
|
||||
return UART_TEST_STRING;
|
||||
case 0x5400AFFE:
|
||||
return DUMMY_HANDLER_STRING;
|
||||
case 0x5400CAFE:
|
||||
return DUMMY_INTERFACE_STRING;
|
||||
case 0x54123456:
|
||||
return LIBGPIOD_TEST_STRING;
|
||||
case 0x54694269:
|
||||
return TEST_TASK_STRING;
|
||||
case 0x73000100:
|
||||
return TM_FUNNEL_STRING;
|
||||
case 0x73500000:
|
||||
return CCSDS_IP_CORE_BRIDGE_STRING;
|
||||
case 0xFFFFFFFF:
|
||||
return NO_OBJECT_STRING;
|
||||
default:
|
||||
return "UNKNOWN_OBJECT";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@ class FixedTimeslotTaskIF;
|
||||
namespace pst {
|
||||
|
||||
/* 0.4 second period init*/
|
||||
ReturnValue_t pstGpio(FixedTimeslotTaskIF *thisSequence);
|
||||
ReturnValue_t pstGpio(FixedTimeslotTaskIF* thisSequence);
|
||||
|
||||
/**
|
||||
* @brief This function creates the PST for all gomspace devices.
|
||||
@ -40,7 +40,7 @@ ReturnValue_t pstGpio(FixedTimeslotTaskIF *thisSequence);
|
||||
* Scheduled in a separate PST because the gomspace library uses blocking calls when requesting
|
||||
* data from devices.
|
||||
*/
|
||||
ReturnValue_t pstGompaceCan(FixedTimeslotTaskIF *thisSequence);
|
||||
ReturnValue_t pstGompaceCan(FixedTimeslotTaskIF* thisSequence);
|
||||
|
||||
ReturnValue_t pstUart(FixedTimeslotTaskIF* thisSequence);
|
||||
|
||||
@ -62,7 +62,6 @@ ReturnValue_t pstTest(FixedTimeslotTaskIF* thisSequence);
|
||||
ReturnValue_t pollingSequenceTE0720(FixedTimeslotTaskIF* thisSequence);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
} // namespace pst
|
||||
|
||||
#endif /* POLLINGSEQUENCEINIT_H_ */
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef FSFWCONFIG_RETURNVALUES_CLASSIDS_H_
|
||||
#define FSFWCONFIG_RETURNVALUES_CLASSIDS_H_
|
||||
|
||||
#include <fsfw/returnvalues/FwClassIds.h>
|
||||
#include <common/config/commonClassIds.h>
|
||||
#include <fsfw/returnvalues/FwClassIds.h>
|
||||
|
||||
/**
|
||||
* Source IDs starts at 73 for now
|
||||
@ -11,13 +11,12 @@
|
||||
*/
|
||||
namespace CLASS_ID {
|
||||
enum {
|
||||
CLASS_ID_START = COMMON_CLASS_ID_END,
|
||||
SA_DEPL_HANDLER, //SADPL
|
||||
SD_CARD_MANAGER, //SDMA
|
||||
SCRATCH_BUFFER, //SCBU
|
||||
CLASS_ID_END // [EXPORT] : [END]
|
||||
CLASS_ID_START = COMMON_CLASS_ID_END,
|
||||
SA_DEPL_HANDLER, // SADPL
|
||||
SD_CARD_MANAGER, // SDMA
|
||||
SCRATCH_BUFFER, // SCBU
|
||||
CLASS_ID_END // [EXPORT] : [END]
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif /* FSFWCONFIG_RETURNVALUES_CLASSIDS_H_ */
|
||||
|
@ -2,21 +2,21 @@
|
||||
#define CONFIG_TMTC_PUSIDS_HPP_
|
||||
|
||||
namespace pus {
|
||||
enum Ids{
|
||||
PUS_SERVICE_1 = 1,
|
||||
PUS_SERVICE_2 = 2,
|
||||
PUS_SERVICE_3 = 3,
|
||||
PUS_SERVICE_3_PSB = 3,
|
||||
PUS_SERVICE_5 = 5,
|
||||
PUS_SERVICE_6 = 6,
|
||||
PUS_SERVICE_8 = 8,
|
||||
PUS_SERVICE_9 = 9,
|
||||
PUS_SERVICE_17 = 17,
|
||||
PUS_SERVICE_19 = 19,
|
||||
PUS_SERVICE_20 = 20,
|
||||
PUS_SERVICE_23 = 23,
|
||||
PUS_SERVICE_200 = 200,
|
||||
PUS_SERVICE_201 = 201,
|
||||
enum Ids {
|
||||
PUS_SERVICE_1 = 1,
|
||||
PUS_SERVICE_2 = 2,
|
||||
PUS_SERVICE_3 = 3,
|
||||
PUS_SERVICE_3_PSB = 3,
|
||||
PUS_SERVICE_5 = 5,
|
||||
PUS_SERVICE_6 = 6,
|
||||
PUS_SERVICE_8 = 8,
|
||||
PUS_SERVICE_9 = 9,
|
||||
PUS_SERVICE_17 = 17,
|
||||
PUS_SERVICE_19 = 19,
|
||||
PUS_SERVICE_20 = 20,
|
||||
PUS_SERVICE_23 = 23,
|
||||
PUS_SERVICE_200 = 200,
|
||||
PUS_SERVICE_201 = 201,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,104 +1,98 @@
|
||||
#include <linux/obc/PapbVcInterface.h>
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
PapbVcInterface::PapbVcInterface(object_id_t objectId, LinuxLibgpioIF* gpioComIF,
|
||||
gpioId_t papbBusyId, gpioId_t papbEmptyId, uint32_t vcOffset) :
|
||||
SystemObject(objectId), gpioComIF(gpioComIF), papbBusyId(
|
||||
papbBusyId), papbEmptyId(papbEmptyId), vcOffset(vcOffset) {
|
||||
}
|
||||
|
||||
PapbVcInterface::~PapbVcInterface() {
|
||||
}
|
||||
gpioId_t papbBusyId, gpioId_t papbEmptyId, uint32_t vcOffset)
|
||||
: SystemObject(objectId),
|
||||
gpioComIF(gpioComIF),
|
||||
papbBusyId(papbBusyId),
|
||||
papbEmptyId(papbEmptyId),
|
||||
vcOffset(vcOffset) {}
|
||||
|
||||
PapbVcInterface::~PapbVcInterface() {}
|
||||
|
||||
void PapbVcInterface::setRegisterAddress(uint32_t* ptmeBaseAddress) {
|
||||
vcBaseReg = ptmeBaseAddress + vcOffset;
|
||||
vcBaseReg = ptmeBaseAddress + vcOffset;
|
||||
}
|
||||
|
||||
ReturnValue_t PapbVcInterface::write(const uint8_t * data, size_t size) {
|
||||
ReturnValue_t PapbVcInterface::write(const uint8_t* data, size_t size) {
|
||||
if (pollPapbBusySignal() == RETURN_OK) {
|
||||
startPacketTransfer();
|
||||
}
|
||||
|
||||
if(pollPapbBusySignal() == RETURN_OK) {
|
||||
startPacketTransfer();
|
||||
for (size_t idx = 0; idx < size; idx++) {
|
||||
if (pollPapbBusySignal() == RETURN_OK) {
|
||||
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
|
||||
} else {
|
||||
sif::warning << "PapbVcInterface::write: Only written " << idx << " of " << size << " data"
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t idx = 0; idx < size; idx++) {
|
||||
if(pollPapbBusySignal() == RETURN_OK) {
|
||||
*(vcBaseReg + DATA_REG_OFFSET) = static_cast<uint32_t>(*(data + idx));
|
||||
}
|
||||
else {
|
||||
sif::warning << "PapbVcInterface::write: Only written " << idx << " of "
|
||||
<< size << " data" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if(pollPapbBusySignal() == RETURN_OK) {
|
||||
endPacketTransfer();
|
||||
}
|
||||
return RETURN_OK;
|
||||
if (pollPapbBusySignal() == RETURN_OK) {
|
||||
endPacketTransfer();
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PapbVcInterface::startPacketTransfer() {
|
||||
*vcBaseReg = CONFIG_START;
|
||||
}
|
||||
void PapbVcInterface::startPacketTransfer() { *vcBaseReg = CONFIG_START; }
|
||||
|
||||
void PapbVcInterface::endPacketTransfer() {
|
||||
*vcBaseReg = CONFIG_END;
|
||||
}
|
||||
void PapbVcInterface::endPacketTransfer() { *vcBaseReg = CONFIG_END; }
|
||||
|
||||
ReturnValue_t PapbVcInterface::pollPapbBusySignal() {
|
||||
int papbBusyState = 0;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
int papbBusyState = 0;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
/** Check if PAPB interface is ready to receive data */
|
||||
result = gpioComIF->readGpio(papbBusyId, &papbBusyState);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PapbVcInterface::pollPapbBusySignal: Failed to read papb busy signal"
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (!papbBusyState) {
|
||||
sif::warning << "PapbVcInterface::pollPapbBusySignal: PAPB busy" << std::endl;
|
||||
return PAPB_BUSY;
|
||||
}
|
||||
/** Check if PAPB interface is ready to receive data */
|
||||
result = gpioComIF->readGpio(papbBusyId, &papbBusyState);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PapbVcInterface::pollPapbBusySignal: Failed to read papb busy signal"
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (!papbBusyState) {
|
||||
sif::warning << "PapbVcInterface::pollPapbBusySignal: PAPB busy" << std::endl;
|
||||
return PAPB_BUSY;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PapbVcInterface::isVcInterfaceBufferEmpty() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
int papbEmptyState = 1;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
int papbEmptyState = 1;
|
||||
|
||||
result = gpioComIF->readGpio(papbEmptyId, &papbEmptyState);
|
||||
result = gpioComIF->readGpio(papbEmptyId, &papbEmptyState);
|
||||
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PapbVcInterface::isVcInterfaceBufferEmpty: Failed to read papb empty signal"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (papbEmptyState == 1) {
|
||||
sif::debug << "PapbVcInterface::isVcInterfaceBufferEmpty: Buffer is empty" << std::endl;
|
||||
}
|
||||
else {
|
||||
sif::debug << "PapbVcInterface::isVcInterfaceBufferEmpty: Buffer is not empty" << std::endl;
|
||||
}
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PapbVcInterface::isVcInterfaceBufferEmpty: Failed to read papb empty signal"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (papbEmptyState == 1) {
|
||||
sif::debug << "PapbVcInterface::isVcInterfaceBufferEmpty: Buffer is empty" << std::endl;
|
||||
} else {
|
||||
sif::debug << "PapbVcInterface::isVcInterfaceBufferEmpty: Buffer is not empty" << std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ReturnValue_t PapbVcInterface::sendTestFrame() {
|
||||
/** Size of one complete transfer frame data field amounts to 1105 bytes */
|
||||
uint8_t testPacket[1105];
|
||||
/** Size of one complete transfer frame data field amounts to 1105 bytes */
|
||||
uint8_t testPacket[1105];
|
||||
|
||||
/** Fill one test packet */
|
||||
for(int idx = 0; idx < 1105; idx++) {
|
||||
testPacket[idx] = static_cast<uint8_t>(idx & 0xFF);
|
||||
}
|
||||
/** Fill one test packet */
|
||||
for (int idx = 0; idx < 1105; idx++) {
|
||||
testPacket[idx] = static_cast<uint8_t>(idx & 0xFF);
|
||||
}
|
||||
|
||||
ReturnValue_t result = write(testPacket, 1105);
|
||||
if(result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
ReturnValue_t result = write(testPacket, 1105);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
#ifndef LINUX_OBC_PAPBVCINTERFACE_H_
|
||||
#define LINUX_OBC_PAPBVCINTERFACE_H_
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "linux/obc/VcInterfaceIF.h"
|
||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "linux/obc/VcInterfaceIF.h"
|
||||
|
||||
/**
|
||||
* @brief This class handles the transmission of data to a virtual channel of the PTME IP Core
|
||||
@ -14,99 +15,96 @@
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PapbVcInterface: public SystemObject,
|
||||
public VcInterfaceIF,
|
||||
public HasReturnvaluesIF {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId
|
||||
* @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the
|
||||
* VcInterface IP Core. A low logic level indicates the VcInterface is not
|
||||
* ready to receive more data.
|
||||
* @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the
|
||||
* VcInterface IP Core. The signal is high when there are no packets in the
|
||||
* external buffer memory (BRAM).
|
||||
*/
|
||||
PapbVcInterface(object_id_t objectId, LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId,
|
||||
gpioId_t papbEmptyId, uint32_t vcOffset);
|
||||
virtual ~PapbVcInterface();
|
||||
class PapbVcInterface : public SystemObject, public VcInterfaceIF, public HasReturnvaluesIF {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId
|
||||
* @param papbBusyId The ID of the GPIO which is connected to the PAPBBusy_N signal of the
|
||||
* VcInterface IP Core. A low logic level indicates the VcInterface is not
|
||||
* ready to receive more data.
|
||||
* @param papbEmptyId The ID of the GPIO which is connected to the PAPBEmpty signal of the
|
||||
* VcInterface IP Core. The signal is high when there are no packets in the
|
||||
* external buffer memory (BRAM).
|
||||
*/
|
||||
PapbVcInterface(object_id_t objectId, LinuxLibgpioIF* gpioComIF, gpioId_t papbBusyId,
|
||||
gpioId_t papbEmptyId, uint32_t vcOffset);
|
||||
virtual ~PapbVcInterface();
|
||||
|
||||
ReturnValue_t write(const uint8_t* data, size_t size) override;
|
||||
ReturnValue_t write(const uint8_t* data, size_t size) override;
|
||||
|
||||
void setRegisterAddress(uint32_t* ptmeBaseAddress) override;
|
||||
void setRegisterAddress(uint32_t* ptmeBaseAddress) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE;
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::CCSDS_IP_CORE_BRIDGE;
|
||||
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
|
||||
|
||||
static const ReturnValue_t PAPB_BUSY = MAKE_RETURN_CODE(0xA0);
|
||||
/**
|
||||
* Configuration bits:
|
||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||
* bit[2]: Set this bit to 1 to abort a transfered packet
|
||||
* bit[3]: Signals to VcInterface the start of a new telemetry packet
|
||||
*/
|
||||
static const uint32_t CONFIG_START = 0x8;
|
||||
|
||||
/**
|
||||
* Configuration bits:
|
||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||
* bit[2]: Set this bit to 1 to abort a transfered packet
|
||||
* bit[3]: Signals to VcInterface the start of a new telemetry packet
|
||||
*/
|
||||
static const uint32_t CONFIG_START = 0x8;
|
||||
/**
|
||||
* Writing this word to the VcInterface base address signals to the virtual channel interface
|
||||
* that a complete tm packet has been transferred.
|
||||
*/
|
||||
static const uint32_t CONFIG_END = 0x0;
|
||||
|
||||
/**
|
||||
* Writing this word to the VcInterface base address signals to the virtual channel interface
|
||||
* that a complete tm packet has been transferred.
|
||||
*/
|
||||
static const uint32_t CONFIG_END = 0x0;
|
||||
/**
|
||||
* Writing to this offset within the memory space of a virtual channel will insert data for
|
||||
* encoding to the external buffer memory of the PTME IP Core.
|
||||
* The address offset is 0x400 (= 4 * 256)
|
||||
*/
|
||||
static const int DATA_REG_OFFSET = 256;
|
||||
|
||||
/**
|
||||
* Writing to this offset within the memory space of a virtual channel will insert data for
|
||||
* encoding to the external buffer memory of the PTME IP Core.
|
||||
* The address offset is 0x400 (= 4 * 256)
|
||||
*/
|
||||
static const int DATA_REG_OFFSET = 256;
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
/** Pulled to low when virtual channel not ready to receive data */
|
||||
gpioId_t papbBusyId = gpio::NO_GPIO;
|
||||
/** High when external buffer memory of virtual channel is empty */
|
||||
gpioId_t papbEmptyId = gpio::NO_GPIO;
|
||||
|
||||
/** Pulled to low when virtual channel not ready to receive data */
|
||||
gpioId_t papbBusyId = gpio::NO_GPIO;
|
||||
/** High when external buffer memory of virtual channel is empty */
|
||||
gpioId_t papbEmptyId = gpio::NO_GPIO;
|
||||
uint32_t* vcBaseReg = nullptr;
|
||||
|
||||
uint32_t* vcBaseReg = nullptr;
|
||||
uint32_t vcOffset = 0;
|
||||
|
||||
uint32_t vcOffset = 0;
|
||||
/**
|
||||
* @brief This function sends the config byte to the virtual channel of the PTME IP Core
|
||||
* to initiate a packet transfer.
|
||||
*/
|
||||
void startPacketTransfer();
|
||||
|
||||
/**
|
||||
* @brief This function sends the config byte to the virtual channel of the PTME IP Core
|
||||
* to initiate a packet transfer.
|
||||
*/
|
||||
void startPacketTransfer();
|
||||
/**
|
||||
* @brief This function sends the config byte to the virtual channel interface of the PTME
|
||||
* IP Core to signal the end of a packet transfer.
|
||||
*/
|
||||
void endPacketTransfer();
|
||||
|
||||
/**
|
||||
* @brief This function sends the config byte to the virtual channel interface of the PTME
|
||||
* IP Core to signal the end of a packet transfer.
|
||||
*/
|
||||
void endPacketTransfer();
|
||||
/**
|
||||
* @brief This function reads the papb busy signal indicating whether the virtual channel
|
||||
* interface is ready to receive more data or not. PAPB is ready when
|
||||
* PAPB_Busy_N == '1'.
|
||||
*
|
||||
* @return RETURN_OK when ready to receive data else PAPB_BUSY.
|
||||
*/
|
||||
ReturnValue_t pollPapbBusySignal();
|
||||
|
||||
/**
|
||||
* @brief This function reads the papb busy signal indicating whether the virtual channel
|
||||
* interface is ready to receive more data or not. PAPB is ready when
|
||||
* PAPB_Busy_N == '1'.
|
||||
*
|
||||
* @return RETURN_OK when ready to receive data else PAPB_BUSY.
|
||||
*/
|
||||
ReturnValue_t pollPapbBusySignal();
|
||||
/**
|
||||
* @brief This function can be used for debugging to check whether there are packets in
|
||||
* the packet buffer of the virtual channel or not.
|
||||
*/
|
||||
void isVcInterfaceBufferEmpty();
|
||||
|
||||
/**
|
||||
* @brief This function can be used for debugging to check whether there are packets in
|
||||
* the packet buffer of the virtual channel or not.
|
||||
*/
|
||||
void isVcInterfaceBufferEmpty();
|
||||
|
||||
/**
|
||||
* @brief This function sends a complete telemetry transfer frame data field (1105 bytes)
|
||||
* to the papb interface of the PTME IP Core. Can be used to test the implementation.
|
||||
*/
|
||||
ReturnValue_t sendTestFrame();
|
||||
/**
|
||||
* @brief This function sends a complete telemetry transfer frame data field (1105 bytes)
|
||||
* to the papb interface of the PTME IP Core. Can be used to test the implementation.
|
||||
*/
|
||||
ReturnValue_t sendTestFrame();
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_PAPBVCINTERFACE_H_ */
|
||||
|
@ -1,36 +1,33 @@
|
||||
#include "PdecConfig.h"
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
PdecConfig::PdecConfig() {
|
||||
initialize();
|
||||
}
|
||||
PdecConfig::PdecConfig() { initialize(); }
|
||||
|
||||
PdecConfig::~PdecConfig() {
|
||||
|
||||
}
|
||||
PdecConfig::~PdecConfig() {}
|
||||
|
||||
void PdecConfig::initialize() {
|
||||
uint32_t word = 0;
|
||||
word |= (VERSION_ID << 30);
|
||||
word |= (BYPASS_FLAG << 29);
|
||||
word |= (CONTROL_COMMAND_FLAG << 28);
|
||||
word |= (RESERVED_FIELD_A << 26);
|
||||
word |= (SPACECRAFT_ID << 16);
|
||||
word |= (VIRTUAL_CHANNEL << 10);
|
||||
word |= (DUMMY_BITS << 8);
|
||||
word |= POSITIVE_WINDOW;
|
||||
configWords[0] = word;
|
||||
word = 0;
|
||||
word |= (NEGATIVE_WINDOW << 24);
|
||||
word |= (HIGH_AU_MAP_ID << 16);
|
||||
word |= (ENABLE_DERANDOMIZER << 8);
|
||||
configWords[1] = word;
|
||||
uint32_t word = 0;
|
||||
word |= (VERSION_ID << 30);
|
||||
word |= (BYPASS_FLAG << 29);
|
||||
word |= (CONTROL_COMMAND_FLAG << 28);
|
||||
word |= (RESERVED_FIELD_A << 26);
|
||||
word |= (SPACECRAFT_ID << 16);
|
||||
word |= (VIRTUAL_CHANNEL << 10);
|
||||
word |= (DUMMY_BITS << 8);
|
||||
word |= POSITIVE_WINDOW;
|
||||
configWords[0] = word;
|
||||
word = 0;
|
||||
word |= (NEGATIVE_WINDOW << 24);
|
||||
word |= (HIGH_AU_MAP_ID << 16);
|
||||
word |= (ENABLE_DERANDOMIZER << 8);
|
||||
configWords[1] = word;
|
||||
}
|
||||
|
||||
uint32_t PdecConfig::getConfigWord(uint8_t wordNo) {
|
||||
if (wordNo >= CONFIG_WORDS_NUM) {
|
||||
sif::error << "PdecConfig::getConfigWord: Invalid word number" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
return configWords[wordNo];
|
||||
if (wordNo >= CONFIG_WORDS_NUM) {
|
||||
sif::error << "PdecConfig::getConfigWord: Invalid word number" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
return configWords[wordNo];
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef LINUX_OBC_PDECCONFIG_H_
|
||||
#define LINUX_OBC_PDECCONFIG_H_
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include <cstring>
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
* @brief This class generates the configuration words for the configuration memory of the PDEC
|
||||
* IP Cores.
|
||||
@ -14,39 +15,38 @@
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PdecConfig {
|
||||
public:
|
||||
PdecConfig();
|
||||
virtual ~PdecConfig();
|
||||
|
||||
public:
|
||||
PdecConfig();
|
||||
virtual ~PdecConfig();
|
||||
/**
|
||||
* @brief Returns the configuration word by specifying the position.
|
||||
*/
|
||||
uint32_t getConfigWord(uint8_t wordNo);
|
||||
|
||||
/**
|
||||
* @brief Returns the configuration word by specifying the position.
|
||||
*/
|
||||
uint32_t getConfigWord(uint8_t wordNo);
|
||||
private:
|
||||
// TC transfer frame configuration parameters
|
||||
static const uint8_t VERSION_ID = 0;
|
||||
// BD Frames
|
||||
static const uint8_t BYPASS_FLAG = 1;
|
||||
static const uint8_t CONTROL_COMMAND_FLAG = 0;
|
||||
|
||||
private:
|
||||
// TC transfer frame configuration parameters
|
||||
static const uint8_t VERSION_ID = 0;
|
||||
// BD Frames
|
||||
static const uint8_t BYPASS_FLAG = 1;
|
||||
static const uint8_t CONTROL_COMMAND_FLAG = 0;
|
||||
static const uint8_t VIRTUAL_CHANNEL = 0;
|
||||
static const uint8_t RESERVED_FIELD_A = 0;
|
||||
static const uint16_t SPACECRAFT_ID = 0x274;
|
||||
static const uint16_t DUMMY_BITS = 0;
|
||||
// Parameters to control the FARM for AD frames
|
||||
// Set here for future use
|
||||
static const uint8_t POSITIVE_WINDOW = 10;
|
||||
static const uint8_t NEGATIVE_WINDOW = 151;
|
||||
static const uint8_t HIGH_AU_MAP_ID = 0xF;
|
||||
static const uint8_t ENABLE_DERANDOMIZER = 1;
|
||||
|
||||
static const uint8_t VIRTUAL_CHANNEL = 0;
|
||||
static const uint8_t RESERVED_FIELD_A = 0;
|
||||
static const uint16_t SPACECRAFT_ID = 0x274;
|
||||
static const uint16_t DUMMY_BITS = 0;
|
||||
// Parameters to control the FARM for AD frames
|
||||
// Set here for future use
|
||||
static const uint8_t POSITIVE_WINDOW = 10;
|
||||
static const uint8_t NEGATIVE_WINDOW = 151;
|
||||
static const uint8_t HIGH_AU_MAP_ID = 0xF;
|
||||
static const uint8_t ENABLE_DERANDOMIZER = 1;
|
||||
static const uint8_t CONFIG_WORDS_NUM = 2;
|
||||
|
||||
static const uint8_t CONFIG_WORDS_NUM = 2;
|
||||
uint32_t configWords[CONFIG_WORDS_NUM];
|
||||
|
||||
uint32_t configWords[CONFIG_WORDS_NUM];
|
||||
|
||||
void initialize();
|
||||
void initialize();
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_PDECCONFIG_H_ */
|
||||
|
@ -1,578 +1,568 @@
|
||||
#include "PdecHandler.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "PdecHandler.h"
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/tmtcservices/TmTcMessage.h"
|
||||
#include "fsfw/objectmanager/ObjectManager.h"
|
||||
#include "fsfw/ipc/QueueFactory.h"
|
||||
|
||||
|
||||
PdecHandler::PdecHandler(object_id_t objectId, object_id_t tcDestinationId,
|
||||
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory,
|
||||
std::string uioRamMemory, std::string uioRegisters) :
|
||||
SystemObject(objectId), tcDestinationId(tcDestinationId), gpioComIF(gpioComIF), pdecReset(
|
||||
pdecReset), uioConfigMemory(uioConfigMemory), uioRamMemory(uioRamMemory), uioRegisters(
|
||||
uioRegisters), actionHelper(this, nullptr) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||
LinuxLibgpioIF* gpioComIF, gpioId_t pdecReset, std::string uioConfigMemory,
|
||||
std::string uioRamMemory, std::string uioRegisters)
|
||||
: SystemObject(objectId),
|
||||
tcDestinationId(tcDestinationId),
|
||||
gpioComIF(gpioComIF),
|
||||
pdecReset(pdecReset),
|
||||
uioConfigMemory(uioConfigMemory),
|
||||
uioRamMemory(uioRamMemory),
|
||||
uioRegisters(uioRegisters),
|
||||
actionHelper(this, nullptr) {
|
||||
commandQueue = QueueFactory::instance()->createMessageQueue(QUEUE_SIZE);
|
||||
}
|
||||
|
||||
PdecHandler::~PdecHandler() {
|
||||
}
|
||||
PdecHandler::~PdecHandler() {}
|
||||
|
||||
ReturnValue_t PdecHandler::initialize() {
|
||||
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
||||
if (tcStore == nullptr) {
|
||||
sif::error << "PdecHandler::initialize: Invalid TC store" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
tcStore = ObjectManager::instance()->get<StorageManagerIF>(objects::TC_STORE);
|
||||
if (tcStore == nullptr) {
|
||||
sif::error << "PdecHandler::initialize: Invalid TC store" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
tcDestination = ObjectManager::instance()->get<AcceptsTelecommandsIF>(tcDestinationId);
|
||||
|
||||
tcDestination = ObjectManager::instance()->get<AcceptsTelecommandsIF>(
|
||||
tcDestinationId);
|
||||
if (tcDestination == nullptr) {
|
||||
sif::error << "PdecHandler::initialize: Invalid tc destination specified" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
if (tcDestination == nullptr) {
|
||||
sif::error << "PdecHandler::initialize: Invalid tc destination specified" << std::endl;
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = getRegisterAddress();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
result = getRegisterAddress();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
result = getConfigMemoryBaseAddress();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
result = getConfigMemoryBaseAddress();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
result = getRamBaseAddress();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
result = getRamBaseAddress();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
writePdecConfig();
|
||||
|
||||
writePdecConfig();
|
||||
result = releasePdec();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
|
||||
result = releasePdec();
|
||||
if (result != RETURN_OK) {
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
result = actionHelper.initialize(commandQueue);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = actionHelper.initialize(commandQueue);
|
||||
if (result != RETURN_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
MessageQueueId_t PdecHandler::getCommandQueue() const {
|
||||
return commandQueue->getId();
|
||||
}
|
||||
MessageQueueId_t PdecHandler::getCommandQueue() const { return commandQueue->getId(); }
|
||||
|
||||
ReturnValue_t PdecHandler::getRegisterAddress() {
|
||||
int fd = open(uioRegisters.c_str(), O_RDWR);
|
||||
if (fd < 1) {
|
||||
sif::warning << "PdecHandler::getRegisterAddress: Invalid UIO device file" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
int fd = open(uioRegisters.c_str(), O_RDWR);
|
||||
if (fd < 1) {
|
||||
sif::warning << "PdecHandler::getRegisterAddress: Invalid UIO device file" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
registerBaseAddress = static_cast<uint32_t*>(mmap(NULL, REGISTER_MAP_SIZE,
|
||||
PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0));
|
||||
registerBaseAddress = static_cast<uint32_t*>(
|
||||
mmap(NULL, REGISTER_MAP_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0));
|
||||
|
||||
if (registerBaseAddress == MAP_FAILED) {
|
||||
sif::error << "PdecHandler::getRegisterAddress: Failed to map uio address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (registerBaseAddress == MAP_FAILED) {
|
||||
sif::error << "PdecHandler::getRegisterAddress: Failed to map uio address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PdecHandler::getConfigMemoryBaseAddress() {
|
||||
int fd = open(uioConfigMemory.c_str(), O_RDWR);
|
||||
if (fd < 1) {
|
||||
sif::warning << "PdecHandler::getConfigMemoryBaseAddress: Invalid UIO device file" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
int fd = open(uioConfigMemory.c_str(), O_RDWR);
|
||||
if (fd < 1) {
|
||||
sif::warning << "PdecHandler::getConfigMemoryBaseAddress: Invalid UIO device file" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
memoryBaseAddress = static_cast<uint32_t*>(mmap(NULL, CONFIG_MEMORY_MAP_SIZE, PROT_WRITE | PROT_READ,
|
||||
MAP_SHARED, fd, 0));
|
||||
memoryBaseAddress = static_cast<uint32_t*>(
|
||||
mmap(NULL, CONFIG_MEMORY_MAP_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0));
|
||||
|
||||
if (memoryBaseAddress == MAP_FAILED) {
|
||||
sif::error << "PdecHandler::getConfigMemoryBaseAddress: Failed to map uio address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
if (memoryBaseAddress == MAP_FAILED) {
|
||||
sif::error << "PdecHandler::getConfigMemoryBaseAddress: Failed to map uio address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PdecHandler::getRamBaseAddress() {
|
||||
int fd = open(uioRamMemory.c_str(), O_RDWR);
|
||||
int fd = open(uioRamMemory.c_str(), O_RDWR);
|
||||
|
||||
ramBaseAddress = static_cast<uint32_t*>(mmap(NULL, RAM_MAP_SIZE, PROT_WRITE | PROT_READ,
|
||||
MAP_SHARED, fd, 0));
|
||||
ramBaseAddress =
|
||||
static_cast<uint32_t*>(mmap(NULL, RAM_MAP_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0));
|
||||
|
||||
if (ramBaseAddress == MAP_FAILED) {
|
||||
sif::error << "PdecHandler::getRamBaseAddress: Failed to map RAM base address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
if (ramBaseAddress == MAP_FAILED) {
|
||||
sif::error << "PdecHandler::getRamBaseAddress: Failed to map RAM base address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PdecHandler::writePdecConfig() {
|
||||
void PdecHandler::writePdecConfig() {
|
||||
PdecConfig pdecConfig;
|
||||
|
||||
PdecConfig pdecConfig;
|
||||
*(memoryBaseAddress + FRAME_HEADER_OFFSET) = pdecConfig.getConfigWord(0);
|
||||
*(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1);
|
||||
|
||||
*(memoryBaseAddress + FRAME_HEADER_OFFSET)= pdecConfig.getConfigWord(0);
|
||||
*(memoryBaseAddress + FRAME_HEADER_OFFSET + 1) = pdecConfig.getConfigWord(1);
|
||||
// Configure all MAP IDs as invalid
|
||||
for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) {
|
||||
*(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx + 1 / 4) =
|
||||
NO_DESTINATION << 24 | NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION;
|
||||
}
|
||||
|
||||
// Configure all MAP IDs as invalid
|
||||
for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) {
|
||||
*(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + idx + 1 / 4) = NO_DESTINATION << 24
|
||||
| NO_DESTINATION << 16 | NO_DESTINATION << 8 | NO_DESTINATION;
|
||||
// All TCs with MAP ID 7 will be routed to the PM module (can then be read from memory)
|
||||
uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER);
|
||||
*(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + 1) =
|
||||
(NO_DESTINATION << 24) | (NO_DESTINATION << 16) | (NO_DESTINATION << 8) | routeToPm;
|
||||
|
||||
}
|
||||
|
||||
// All TCs with MAP ID 7 will be routed to the PM module (can then be read from memory)
|
||||
uint8_t routeToPm = calcMapAddrEntry(PM_BUFFER);
|
||||
*(memoryBaseAddress + MAP_ADDR_LUT_OFFSET + 1) = (NO_DESTINATION << 24) | (NO_DESTINATION << 16) | (NO_DESTINATION << 8)
|
||||
| routeToPm;
|
||||
|
||||
// Write map id clock frequencies
|
||||
for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) {
|
||||
*(memoryBaseAddress + MAP_CLK_FREQ_OFFSET + idx / 4) = MAP_CLK_FREQ << 24
|
||||
| MAP_CLK_FREQ << 16 | MAP_CLK_FREQ << 8 | MAP_CLK_FREQ;
|
||||
|
||||
}
|
||||
// Write map id clock frequencies
|
||||
for (int idx = 0; idx <= MAX_MAP_ADDR; idx += 4) {
|
||||
*(memoryBaseAddress + MAP_CLK_FREQ_OFFSET + idx / 4) =
|
||||
MAP_CLK_FREQ << 24 | MAP_CLK_FREQ << 16 | MAP_CLK_FREQ << 8 | MAP_CLK_FREQ;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PdecHandler::resetFarStatFlag() {
|
||||
uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET);
|
||||
if (pdecFar != FAR_RESET) {
|
||||
sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value."
|
||||
<< " Read value: 0x" << std::hex << static_cast<unsigned int>(pdecFar) << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET);
|
||||
if (pdecFar != FAR_RESET) {
|
||||
sif::warning << "PdecHandler::resetFarStatFlag: FAR register did not match expected value."
|
||||
<< " Read value: 0x" << std::hex << static_cast<unsigned int>(pdecFar)
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
#if OBSW_DEBUG_PDEC_HANDLER == 1
|
||||
sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar
|
||||
<< std::endl;
|
||||
sif::debug << "PdecHandler::resetFarStatFlag: read FAR with value: 0x" << std::hex << pdecFar
|
||||
<< std::endl;
|
||||
#endif /* OBSW_DEBUG_PDEC_HANDLER == 1 */
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t PdecHandler::releasePdec() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = gpioComIF->pullHigh(pdecReset);
|
||||
if (result != RETURN_OK) {
|
||||
sif::error << "PdecHandler::releasePdec: Failed to release PDEC reset signal" << std::endl;
|
||||
}
|
||||
return result;
|
||||
ReturnValue_t PdecHandler::releasePdec() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
result = gpioComIF->pullHigh(pdecReset);
|
||||
if (result != RETURN_OK) {
|
||||
sif::error << "PdecHandler::releasePdec: Failed to release PDEC reset signal" << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ReturnValue_t PdecHandler::performOperation(uint8_t operationCode) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
readCommandQueue();
|
||||
|
||||
readCommandQueue();
|
||||
|
||||
switch(state) {
|
||||
switch (state) {
|
||||
case State::INIT:
|
||||
resetFarStatFlag();
|
||||
if (result != RETURN_OK) {
|
||||
// Requires reconfiguration and reinitialization of PDEC
|
||||
triggerEvent(INVALID_FAR);
|
||||
state = State::WAIT_FOR_RECOVERY;
|
||||
return result;
|
||||
}
|
||||
state = State::RUNNING;
|
||||
break;
|
||||
resetFarStatFlag();
|
||||
if (result != RETURN_OK) {
|
||||
// Requires reconfiguration and reinitialization of PDEC
|
||||
triggerEvent(INVALID_FAR);
|
||||
state = State::WAIT_FOR_RECOVERY;
|
||||
return result;
|
||||
}
|
||||
state = State::RUNNING;
|
||||
break;
|
||||
case State::RUNNING:
|
||||
if (newTcReceived()) {
|
||||
handleNewTc();
|
||||
}
|
||||
checkLocks();
|
||||
break;
|
||||
if (newTcReceived()) {
|
||||
handleNewTc();
|
||||
}
|
||||
checkLocks();
|
||||
break;
|
||||
case State::WAIT_FOR_RECOVERY:
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
sif::debug << "PdecHandler::performOperation: Invalid state" << std::endl;
|
||||
break;
|
||||
}
|
||||
sif::debug << "PdecHandler::performOperation: Invalid state" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PdecHandler::readCommandQueue(void) {
|
||||
CommandMessage commandMessage;
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
CommandMessage commandMessage;
|
||||
ReturnValue_t result = RETURN_FAILED;
|
||||
|
||||
result = commandQueue->receiveMessage(&commandMessage);
|
||||
result = commandQueue->receiveMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
result = actionHelper.handleActionMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
result = actionHelper.handleActionMessage(&commandMessage);
|
||||
if (result == RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
CommandMessage reply;
|
||||
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND,
|
||||
commandMessage.getCommand());
|
||||
commandQueue->reply(&reply);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
CommandMessage reply;
|
||||
reply.setReplyRejected(CommandMessage::UNKNOWN_COMMAND, commandMessage.getCommand());
|
||||
commandQueue->reply(&reply);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool PdecHandler::newTcReceived() {
|
||||
uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET);
|
||||
uint32_t pdecFar = *(registerBaseAddress + PDEC_FAR_OFFSET);
|
||||
|
||||
if (pdecFar >> STAT_POSITION != NEW_FAR_RECEIVED) {
|
||||
return false;
|
||||
}
|
||||
if (!checkFrameAna(pdecFar)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (pdecFar >> STAT_POSITION != NEW_FAR_RECEIVED) {
|
||||
return false;
|
||||
}
|
||||
if (!checkFrameAna(pdecFar)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PdecHandler::checkLocks() {
|
||||
uint32_t clcw = getClcw();
|
||||
if (!(clcw & NO_RF_MASK) && (lastClcw & NO_RF_MASK)) {
|
||||
// Rf available changed from 0 to 1
|
||||
triggerEvent(CARRIER_LOCK);
|
||||
}
|
||||
if (!(clcw & NO_BITLOCK_MASK) && (lastClcw & NO_BITLOCK_MASK)) {
|
||||
// Bit lock changed from 0 to 1
|
||||
triggerEvent(BIT_LOCK_PDEC);
|
||||
}
|
||||
lastClcw = clcw;
|
||||
uint32_t clcw = getClcw();
|
||||
if (!(clcw & NO_RF_MASK) && (lastClcw & NO_RF_MASK)) {
|
||||
// Rf available changed from 0 to 1
|
||||
triggerEvent(CARRIER_LOCK);
|
||||
}
|
||||
if (!(clcw & NO_BITLOCK_MASK) && (lastClcw & NO_BITLOCK_MASK)) {
|
||||
// Bit lock changed from 0 to 1
|
||||
triggerEvent(BIT_LOCK_PDEC);
|
||||
}
|
||||
lastClcw = clcw;
|
||||
}
|
||||
|
||||
bool PdecHandler::checkFrameAna(uint32_t pdecFar) {
|
||||
bool frameValid = false;
|
||||
FrameAna_t frameAna = static_cast<FrameAna_t>((pdecFar & FRAME_ANA_MASK) >> FRAME_ANA_POSITION);
|
||||
switch(frameAna) {
|
||||
case(FrameAna_t::ABANDONED_CLTU): {
|
||||
triggerEvent(INVALID_TC_FRAME, ABANDONED_CLTU);
|
||||
sif::warning << "PdecHandler::checkFrameAna: Abondoned CLTU" << std::endl;
|
||||
break;
|
||||
bool frameValid = false;
|
||||
FrameAna_t frameAna = static_cast<FrameAna_t>((pdecFar & FRAME_ANA_MASK) >> FRAME_ANA_POSITION);
|
||||
switch (frameAna) {
|
||||
case (FrameAna_t::ABANDONED_CLTU): {
|
||||
triggerEvent(INVALID_TC_FRAME, ABANDONED_CLTU);
|
||||
sif::warning << "PdecHandler::checkFrameAna: Abondoned CLTU" << std::endl;
|
||||
break;
|
||||
}
|
||||
case(FrameAna_t::FRAME_DIRTY): {
|
||||
triggerEvent(INVALID_TC_FRAME, FRAME_DIRTY);
|
||||
sif::warning << "PdecHandler::checkFrameAna: Frame dirty" << std::endl;
|
||||
break;
|
||||
case (FrameAna_t::FRAME_DIRTY): {
|
||||
triggerEvent(INVALID_TC_FRAME, FRAME_DIRTY);
|
||||
sif::warning << "PdecHandler::checkFrameAna: Frame dirty" << std::endl;
|
||||
break;
|
||||
}
|
||||
case(FrameAna_t::FRAME_ILLEGAL): {
|
||||
sif::warning << "PdecHandler::checkFrameAna: Frame illegal for one reason" << std::endl;
|
||||
handleIReason(pdecFar, FRAME_ILLEGAL_ONE_REASON);
|
||||
break;
|
||||
case (FrameAna_t::FRAME_ILLEGAL): {
|
||||
sif::warning << "PdecHandler::checkFrameAna: Frame illegal for one reason" << std::endl;
|
||||
handleIReason(pdecFar, FRAME_ILLEGAL_ONE_REASON);
|
||||
break;
|
||||
}
|
||||
case(FrameAna_t::FRAME_ILLEGAL_MULTI_REASON): {
|
||||
sif::warning << "PdecHandler::checkFrameAna: Frame illegal for multiple reasons"
|
||||
<< std::endl;
|
||||
handleIReason(pdecFar, FRAME_ILLEGAL_MULTIPLE_REASONS);
|
||||
break;
|
||||
case (FrameAna_t::FRAME_ILLEGAL_MULTI_REASON): {
|
||||
sif::warning << "PdecHandler::checkFrameAna: Frame illegal for multiple reasons" << std::endl;
|
||||
handleIReason(pdecFar, FRAME_ILLEGAL_MULTIPLE_REASONS);
|
||||
break;
|
||||
}
|
||||
case(FrameAna_t::AD_DISCARDED_LOCKOUT): {
|
||||
triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT);
|
||||
sif::warning << "PdecHandler::checkFrameAna: AD frame discarded because of lockout"
|
||||
<< std::endl;
|
||||
break;
|
||||
case (FrameAna_t::AD_DISCARDED_LOCKOUT): {
|
||||
triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT);
|
||||
sif::warning << "PdecHandler::checkFrameAna: AD frame discarded because of lockout"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
case(FrameAna_t::AD_DISCARDED_WAIT): {
|
||||
triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT);
|
||||
sif::warning << "PdecHandler::checkFrameAna: AD frame discarded because of wait"
|
||||
<< std::endl;
|
||||
break;
|
||||
case (FrameAna_t::AD_DISCARDED_WAIT): {
|
||||
triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_LOCKOUT);
|
||||
sif::warning << "PdecHandler::checkFrameAna: AD frame discarded because of wait" << std::endl;
|
||||
break;
|
||||
}
|
||||
case(FrameAna_t::AD_DISCARDED_NS_VR): {
|
||||
triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_NS_VS);
|
||||
sif::warning << "PdecHandler::checkFrameAna: AD frame discarded because N(S) or V(R)"
|
||||
<< std::endl;
|
||||
break;
|
||||
case (FrameAna_t::AD_DISCARDED_NS_VR): {
|
||||
triggerEvent(INVALID_TC_FRAME, AD_DISCARDED_NS_VS);
|
||||
sif::warning << "PdecHandler::checkFrameAna: AD frame discarded because N(S) or V(R)"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
case(FrameAna_t::FRAME_ACCEPTED): {
|
||||
case (FrameAna_t::FRAME_ACCEPTED): {
|
||||
#if OBSW_DEBUG_PDEC_HANDLER == 1
|
||||
sif::info << "PdecHandler::checkFrameAna: Accepted TC frame" << std::endl;
|
||||
sif::info << "PdecHandler::checkFrameAna: Accepted TC frame" << std::endl;
|
||||
#endif
|
||||
frameValid = true;
|
||||
break;
|
||||
frameValid = true;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::debug << "PdecHandler::checkFrameAna: Invalid frame analysis report" << std::endl;
|
||||
break;
|
||||
sif::debug << "PdecHandler::checkFrameAna: Invalid frame analysis report" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return frameValid;
|
||||
}
|
||||
return frameValid;
|
||||
}
|
||||
|
||||
void PdecHandler::handleIReason(uint32_t pdecFar, ReturnValue_t parameter1) {
|
||||
IReason_t ireason = static_cast<IReason_t>((pdecFar & IREASON_MASK) >> IREASON_POSITION);
|
||||
switch(ireason) {
|
||||
case(IReason_t::NO_REPORT): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, NO_REPORT);
|
||||
sif::info << "PdecHandler::handleIReason: No illegal report" << std::endl;
|
||||
break;
|
||||
IReason_t ireason = static_cast<IReason_t>((pdecFar & IREASON_MASK) >> IREASON_POSITION);
|
||||
switch (ireason) {
|
||||
case (IReason_t::NO_REPORT): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, NO_REPORT);
|
||||
sif::info << "PdecHandler::handleIReason: No illegal report" << std::endl;
|
||||
break;
|
||||
}
|
||||
case(IReason_t::ERROR_VERSION_NUMBER): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, ERROR_VERSION_NUMBER);
|
||||
sif::info << "PdecHandler::handleIReason: Error in version number and reserved A and B "
|
||||
case (IReason_t::ERROR_VERSION_NUMBER): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, ERROR_VERSION_NUMBER);
|
||||
sif::info << "PdecHandler::handleIReason: Error in version number and reserved A and B "
|
||||
<< "fields" << std::endl;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case(IReason_t::ILLEGAL_COMBINATION): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, ILLEGAL_COMBINATION);
|
||||
sif::info << "PdecHandler::handleIReason: Illegal combination (AC) of bypass and control "
|
||||
case (IReason_t::ILLEGAL_COMBINATION): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, ILLEGAL_COMBINATION);
|
||||
sif::info << "PdecHandler::handleIReason: Illegal combination (AC) of bypass and control "
|
||||
<< "command flags" << std::endl;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case(IReason_t::INVALID_SC_ID): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_SC_ID);
|
||||
sif::info << "PdecHandler::handleIReason: Invalid spacecraft identifier " << std::endl;
|
||||
break;
|
||||
case (IReason_t::INVALID_SC_ID): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_SC_ID);
|
||||
sif::info << "PdecHandler::handleIReason: Invalid spacecraft identifier " << std::endl;
|
||||
break;
|
||||
}
|
||||
case(IReason_t::INVALID_VC_ID_MSB): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_MSB);
|
||||
sif::info << "PdecHandler::handleIReason: VC identifier bit 0 to 4 did not match "
|
||||
case (IReason_t::INVALID_VC_ID_MSB): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_MSB);
|
||||
sif::info << "PdecHandler::handleIReason: VC identifier bit 0 to 4 did not match "
|
||||
<< std::endl;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case(IReason_t::INVALID_VC_ID_LSB): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_LSB);
|
||||
sif::info << "PdecHandler::handleIReason: VC identifier bit 5 did not match " << std::endl;
|
||||
break;
|
||||
case (IReason_t::INVALID_VC_ID_LSB): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_VC_ID_LSB);
|
||||
sif::info << "PdecHandler::handleIReason: VC identifier bit 5 did not match " << std::endl;
|
||||
break;
|
||||
}
|
||||
case(IReason_t::NS_NOT_ZERO): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, NS_NOT_ZERO);
|
||||
sif::info << "PdecHandler::handleIReason: N(S) of BC or BD frame not set to all zeros"
|
||||
case (IReason_t::NS_NOT_ZERO): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, NS_NOT_ZERO);
|
||||
sif::info << "PdecHandler::handleIReason: N(S) of BC or BD frame not set to all zeros"
|
||||
<< std::endl;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case(IReason_t::INCORRECT_BC_CC): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_BC_CC);
|
||||
sif::info << "PdecHandler::handleIReason: Invalid BC control command format" << std::endl;
|
||||
break;
|
||||
case (IReason_t::INCORRECT_BC_CC): {
|
||||
triggerEvent(INVALID_TC_FRAME, parameter1, INVALID_BC_CC);
|
||||
sif::info << "PdecHandler::handleIReason: Invalid BC control command format" << std::endl;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::info << "PdecHandler::handleIReason: Invalid reason id" << std::endl;
|
||||
break;
|
||||
}
|
||||
sif::info << "PdecHandler::handleIReason: Invalid reason id" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PdecHandler::handleNewTc() {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
|
||||
uint32_t tcLength = 0;
|
||||
result = readTc(tcLength);
|
||||
if (result != RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
uint32_t tcLength = 0;
|
||||
result = readTc(tcLength);
|
||||
if (result != RETURN_OK) {
|
||||
return;
|
||||
}
|
||||
#if OBSW_DEBUG_PDEC_HANDLER == 1
|
||||
unsigned int mapId = tcSegment[0] & MAP_ID_MASK;
|
||||
sif::info << "PdecHandler::handleNewTc: Received TC segment with map ID " << mapId
|
||||
<< std::endl;
|
||||
printTC(tcLength);
|
||||
unsigned int mapId = tcSegment[0] & MAP_ID_MASK;
|
||||
sif::info << "PdecHandler::handleNewTc: Received TC segment with map ID " << mapId << std::endl;
|
||||
printTC(tcLength);
|
||||
#endif /* OBSW_DEBUG_PDEC_HANDLER */
|
||||
|
||||
store_address_t storeId;
|
||||
result = tcStore->addData(&storeId, tcSegment + 1, tcLength - 1);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PdecHandler::handleNewTc: Failed to add received space packet to store"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
TmTcMessage message(storeId);
|
||||
|
||||
result = MessageQueueSenderIF::sendMessage(tcDestination->getRequestQueue(), &message);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "PdecHandler::handleNewTc: Failed to send message to TC destination"
|
||||
<< std::endl;
|
||||
tcStore->deleteData(storeId);
|
||||
return;
|
||||
}
|
||||
|
||||
store_address_t storeId;
|
||||
result = tcStore->addData(&storeId, tcSegment + 1, tcLength - 1);
|
||||
if (result != RETURN_OK) {
|
||||
sif::warning << "PdecHandler::handleNewTc: Failed to add received space packet to store"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
TmTcMessage message(storeId);
|
||||
|
||||
result = MessageQueueSenderIF::sendMessage(tcDestination->getRequestQueue(), &message);
|
||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||
sif::warning << "PdecHandler::handleNewTc: Failed to send message to TC destination"
|
||||
<< std::endl;
|
||||
tcStore->deleteData(storeId);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ReturnValue_t PdecHandler::readTc(uint32_t& tcLength) {
|
||||
uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - PHYSICAL_RAM_BASE_ADDRESS) / 4;
|
||||
uint32_t tcOffset = (*(registerBaseAddress + PDEC_BPTR_OFFSET) - PHYSICAL_RAM_BASE_ADDRESS) / 4;
|
||||
|
||||
#if OBSW_DEBUG_PDEC_HANDLER == 1
|
||||
sif::debug << "PdecHandler::readTc: TC offset: 0x" << std::hex << tcOffset << std::endl;
|
||||
sif::debug << "PdecHandler::readTc: TC offset: 0x" << std::hex << tcOffset << std::endl;
|
||||
#endif /* OBSW_DEBUG_PDEC_HANDLER */
|
||||
|
||||
tcLength = *(registerBaseAddress + PDEC_SLEN_OFFSET);
|
||||
tcLength = *(registerBaseAddress + PDEC_SLEN_OFFSET);
|
||||
|
||||
#if OBSW_DEBUG_PDEC_HANDLER == 1
|
||||
sif::debug << "PdecHandler::readTc: TC segment length: " << std::dec << tcLength << std::endl;
|
||||
sif::debug << "PdecHandler::readTc: TC segment length: " << std::dec << tcLength << std::endl;
|
||||
#endif /* OBSW_DEBUG_PDEC_HANDLER */
|
||||
|
||||
if (tcLength > MAX_TC_SEGMENT_SIZE) {
|
||||
sif::warning << "PdecHandler::handleNewTc: Read invalid TC length from PDEC register"
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
if (tcLength > MAX_TC_SEGMENT_SIZE) {
|
||||
sif::warning << "PdecHandler::handleNewTc: Read invalid TC length from PDEC register"
|
||||
<< std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
uint32_t idx = 0;
|
||||
uint32_t tcData = 0;
|
||||
for (idx = 0; idx <= tcLength; idx = idx + 4) {
|
||||
tcData = *(ramBaseAddress + tcOffset + idx / 4);
|
||||
if (idx == 0) {
|
||||
tcSegment[idx] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
|
||||
tcSegment[idx + 1] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
|
||||
tcSegment[idx + 2] = static_cast<uint8_t>(tcData & 0xFF);
|
||||
} else if (tcLength - idx + 1 == 3) {
|
||||
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 24) & 0xFF);
|
||||
tcSegment[idx] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
|
||||
tcSegment[idx + 1] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
|
||||
} else if (tcLength - idx + 1 == 2) {
|
||||
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 24) & 0xFF);
|
||||
tcSegment[idx] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
|
||||
} else if (tcLength - idx + 1 == 1) {
|
||||
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 24) & 0xFF);
|
||||
} else {
|
||||
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 24) & 0xFF);
|
||||
tcSegment[idx] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
|
||||
tcSegment[idx + 1] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
|
||||
tcSegment[idx + 2] = static_cast<uint8_t>(tcData & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t idx = 0;
|
||||
uint32_t tcData = 0;
|
||||
for (idx = 0; idx <= tcLength; idx = idx + 4) {
|
||||
tcData = *(ramBaseAddress + tcOffset + idx / 4);
|
||||
if (idx == 0) {
|
||||
tcSegment[idx] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
|
||||
tcSegment[idx + 1] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
|
||||
tcSegment[idx + 2] = static_cast<uint8_t>(tcData & 0xFF);
|
||||
}
|
||||
else if (tcLength - idx + 1 == 3) {
|
||||
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 24) & 0xFF);
|
||||
tcSegment[idx] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
|
||||
tcSegment[idx + 1] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
|
||||
}
|
||||
else if (tcLength - idx + 1 == 2) {
|
||||
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 24) & 0xFF);
|
||||
tcSegment[idx] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
|
||||
}
|
||||
else if (tcLength - idx + 1 == 1) {
|
||||
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 24) & 0xFF);
|
||||
}
|
||||
else {
|
||||
tcSegment[idx - 1] = static_cast<uint8_t>((tcData >> 24) & 0xFF);
|
||||
tcSegment[idx] = static_cast<uint8_t>((tcData >> 16) & 0xFF);
|
||||
tcSegment[idx + 1] = static_cast<uint8_t>((tcData >> 8) & 0xFF);
|
||||
tcSegment[idx + 2] = static_cast<uint8_t>(tcData & 0xFF);
|
||||
}
|
||||
}
|
||||
// Backend buffer is handled back to PDEC3
|
||||
*(registerBaseAddress + PDEC_BFREE_OFFSET) = 0;
|
||||
|
||||
// Backend buffer is handled back to PDEC3
|
||||
*(registerBaseAddress + PDEC_BFREE_OFFSET) = 0;
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
void PdecHandler::printTC(uint32_t tcLength) {
|
||||
std::stringstream tcSegmentStream;
|
||||
tcSegmentStream << "TC segment data: 0x";
|
||||
for (uint32_t idx = 0; idx < tcLength; idx++) {
|
||||
tcSegmentStream << std::setfill('0') << std::setw(2) << std::hex
|
||||
<< static_cast<unsigned int>(tcSegment[idx]);
|
||||
}
|
||||
sif::info << tcSegmentStream.str() << std::endl;
|
||||
std::stringstream tcSegmentStream;
|
||||
tcSegmentStream << "TC segment data: 0x";
|
||||
for (uint32_t idx = 0; idx < tcLength; idx++) {
|
||||
tcSegmentStream << std::setfill('0') << std::setw(2) << std::hex
|
||||
<< static_cast<unsigned int>(tcSegment[idx]);
|
||||
}
|
||||
sif::info << tcSegmentStream.str() << std::endl;
|
||||
}
|
||||
|
||||
uint8_t PdecHandler::calcMapAddrEntry(uint8_t moduleId) {
|
||||
uint8_t lutEntry = 0;
|
||||
uint8_t parity = getOddParity(moduleId | (1 << VALID_POSITION));
|
||||
lutEntry = (parity << PARITY_POSITION) | (1 << VALID_POSITION) | moduleId;
|
||||
return lutEntry;
|
||||
uint8_t lutEntry = 0;
|
||||
uint8_t parity = getOddParity(moduleId | (1 << VALID_POSITION));
|
||||
lutEntry = (parity << PARITY_POSITION) | (1 << VALID_POSITION) | moduleId;
|
||||
return lutEntry;
|
||||
}
|
||||
|
||||
uint8_t PdecHandler::getOddParity(uint8_t number) {
|
||||
uint8_t parityBit = 0;
|
||||
uint8_t countBits = 0;
|
||||
for (unsigned int idx = 0; idx < sizeof(number) * 8; idx++) {
|
||||
countBits += (number >> idx) & 0x1;
|
||||
}
|
||||
parityBit = ~(countBits & 0x1) & 0x1;
|
||||
return parityBit;
|
||||
uint8_t parityBit = 0;
|
||||
uint8_t countBits = 0;
|
||||
for (unsigned int idx = 0; idx < sizeof(number) * 8; idx++) {
|
||||
countBits += (number >> idx) & 0x1;
|
||||
}
|
||||
parityBit = ~(countBits & 0x1) & 0x1;
|
||||
return parityBit;
|
||||
}
|
||||
|
||||
uint32_t PdecHandler::getClcw() {
|
||||
return *(registerBaseAddress + PDEC_CLCW_OFFSET);
|
||||
}
|
||||
uint32_t PdecHandler::getClcw() { return *(registerBaseAddress + PDEC_CLCW_OFFSET); }
|
||||
|
||||
uint32_t PdecHandler::getPdecMon() {
|
||||
return *(registerBaseAddress + PDEC_MON_OFFSET);
|
||||
}
|
||||
uint32_t PdecHandler::getPdecMon() { return *(registerBaseAddress + PDEC_MON_OFFSET); }
|
||||
|
||||
void PdecHandler::printClcw() {
|
||||
uint32_t clcw = getClcw();
|
||||
uint8_t type = static_cast<uint8_t>((clcw >> 31) & 0x1);
|
||||
uint8_t versionNo = static_cast<uint8_t>((clcw >> 29) & 0x3);
|
||||
uint8_t status = static_cast<uint8_t>((clcw >> 26) & 0x7);
|
||||
uint8_t cop = static_cast<uint8_t>((clcw >> 24) & 0x3);
|
||||
uint8_t vcId = static_cast<uint8_t>((clcw >> 18) & 0x3F);
|
||||
uint8_t noRf = static_cast<uint8_t>((clcw >> 15) & 0x1);
|
||||
uint8_t noBitLock = static_cast<uint8_t>((clcw >> 14) & 0x1);
|
||||
uint8_t lockoutFlag = static_cast<uint8_t>((clcw >> 13) & 0x1);
|
||||
uint8_t waitFlag = static_cast<uint8_t>((clcw >> 12) & 0x1);
|
||||
uint8_t retransmitFlag = static_cast<uint8_t>((clcw >> 11) & 0x1);
|
||||
uint8_t farmBcnt = static_cast<uint8_t>((clcw >> 9) & 0x3);
|
||||
// Expected frame sequence number in te next AD frame
|
||||
uint8_t repValue = static_cast<uint8_t>(clcw & 0xFF);
|
||||
sif::info << std::setw(30) << std::left << "CLCW type: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(type) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW version no: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(versionNo) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW status: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(status) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW COP: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(cop) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW virtual channel ID: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(vcId) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW no RF: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(noRf) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW no bit lock: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(noBitLock) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW lockout flag: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(lockoutFlag) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW wait flag: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(waitFlag) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW retransmit flag: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(retransmitFlag) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW FARM B count: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(farmBcnt) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW rep value: " << std::hex
|
||||
<< "0x" << static_cast<unsigned int>(repValue) << std::endl;
|
||||
uint32_t clcw = getClcw();
|
||||
uint8_t type = static_cast<uint8_t>((clcw >> 31) & 0x1);
|
||||
uint8_t versionNo = static_cast<uint8_t>((clcw >> 29) & 0x3);
|
||||
uint8_t status = static_cast<uint8_t>((clcw >> 26) & 0x7);
|
||||
uint8_t cop = static_cast<uint8_t>((clcw >> 24) & 0x3);
|
||||
uint8_t vcId = static_cast<uint8_t>((clcw >> 18) & 0x3F);
|
||||
uint8_t noRf = static_cast<uint8_t>((clcw >> 15) & 0x1);
|
||||
uint8_t noBitLock = static_cast<uint8_t>((clcw >> 14) & 0x1);
|
||||
uint8_t lockoutFlag = static_cast<uint8_t>((clcw >> 13) & 0x1);
|
||||
uint8_t waitFlag = static_cast<uint8_t>((clcw >> 12) & 0x1);
|
||||
uint8_t retransmitFlag = static_cast<uint8_t>((clcw >> 11) & 0x1);
|
||||
uint8_t farmBcnt = static_cast<uint8_t>((clcw >> 9) & 0x3);
|
||||
// Expected frame sequence number in te next AD frame
|
||||
uint8_t repValue = static_cast<uint8_t>(clcw & 0xFF);
|
||||
sif::info << std::setw(30) << std::left << "CLCW type: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(type) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW version no: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(versionNo) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW status: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(status) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW COP: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(cop) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW virtual channel ID: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(vcId) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW no RF: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(noRf) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW no bit lock: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(noBitLock) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW lockout flag: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(lockoutFlag) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW wait flag: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(waitFlag) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW retransmit flag: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(retransmitFlag) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW FARM B count: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(farmBcnt) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "CLCW rep value: " << std::hex << "0x"
|
||||
<< static_cast<unsigned int>(repValue) << std::endl;
|
||||
}
|
||||
|
||||
void PdecHandler::printPdecMon() {
|
||||
uint32_t pdecMon = getPdecMon();
|
||||
uint32_t tc0ChannelStatus = (pdecMon & TC0_STATUS_MASK) >> TC0_STATUS_POS;
|
||||
uint32_t tc1ChannelStatus = (pdecMon & TC1_STATUS_MASK) >> TC1_STATUS_POS;
|
||||
uint32_t tc2ChannelStatus = (pdecMon & TC2_STATUS_MASK) >> TC2_STATUS_POS;
|
||||
uint32_t tc3ChannelStatus = (pdecMon & TC3_STATUS_MASK) >> TC3_STATUS_POS;
|
||||
uint32_t tc4ChannelStatus = (pdecMon & TC4_STATUS_MASK) >> TC4_STATUS_POS;
|
||||
uint32_t tc5ChannelStatus = (pdecMon & TC5_STATUS_MASK) >> TC5_STATUS_POS;
|
||||
uint32_t lock = (pdecMon & LOCK_MASK) >> LOCK_POS;
|
||||
sif::info << std::setw(30) << std::left << "TC0 status: " << getMonStatusString(tc0ChannelStatus) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC1 status: " << getMonStatusString(tc1ChannelStatus) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC2 status: " << getMonStatusString(tc2ChannelStatus) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC3 status: " << getMonStatusString(tc3ChannelStatus) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC4 status: " << getMonStatusString(tc4ChannelStatus) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC5 status: " << getMonStatusString(tc5ChannelStatus) << std::endl;
|
||||
sif::info << std::setw(30) << std::left << "Start sequence lock: " << lock << std::endl;
|
||||
uint32_t pdecMon = getPdecMon();
|
||||
uint32_t tc0ChannelStatus = (pdecMon & TC0_STATUS_MASK) >> TC0_STATUS_POS;
|
||||
uint32_t tc1ChannelStatus = (pdecMon & TC1_STATUS_MASK) >> TC1_STATUS_POS;
|
||||
uint32_t tc2ChannelStatus = (pdecMon & TC2_STATUS_MASK) >> TC2_STATUS_POS;
|
||||
uint32_t tc3ChannelStatus = (pdecMon & TC3_STATUS_MASK) >> TC3_STATUS_POS;
|
||||
uint32_t tc4ChannelStatus = (pdecMon & TC4_STATUS_MASK) >> TC4_STATUS_POS;
|
||||
uint32_t tc5ChannelStatus = (pdecMon & TC5_STATUS_MASK) >> TC5_STATUS_POS;
|
||||
uint32_t lock = (pdecMon & LOCK_MASK) >> LOCK_POS;
|
||||
sif::info << std::setw(30) << std::left << "TC0 status: " << getMonStatusString(tc0ChannelStatus)
|
||||
<< std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC1 status: " << getMonStatusString(tc1ChannelStatus)
|
||||
<< std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC2 status: " << getMonStatusString(tc2ChannelStatus)
|
||||
<< std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC3 status: " << getMonStatusString(tc3ChannelStatus)
|
||||
<< std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC4 status: " << getMonStatusString(tc4ChannelStatus)
|
||||
<< std::endl;
|
||||
sif::info << std::setw(30) << std::left << "TC5 status: " << getMonStatusString(tc5ChannelStatus)
|
||||
<< std::endl;
|
||||
sif::info << std::setw(30) << std::left << "Start sequence lock: " << lock << std::endl;
|
||||
}
|
||||
|
||||
std::string PdecHandler::getMonStatusString(uint32_t status) {
|
||||
switch(status) {
|
||||
case TC_CHANNEL_INACTIVE:
|
||||
return std::string("inactive");
|
||||
case TC_CHANNEL_ACTIVE:
|
||||
return std::string("active");
|
||||
case TC_CHANNEL_TIMEDOUT:
|
||||
return std::string("timed out");
|
||||
default:
|
||||
sif::warning << "PdecHandler::getMonStatusString: Invalid status" << std::endl;
|
||||
return std::string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId,
|
||||
MessageQueueId_t commandedBy, const uint8_t* data, size_t size) {
|
||||
switch(actionId) {
|
||||
case PRINT_CLCW:
|
||||
printClcw();
|
||||
return EXECUTION_FINISHED;
|
||||
case PRINT_PDEC_MON:
|
||||
printPdecMon();
|
||||
return EXECUTION_FINISHED;
|
||||
switch (status) {
|
||||
case TC_CHANNEL_INACTIVE:
|
||||
return std::string("inactive");
|
||||
case TC_CHANNEL_ACTIVE:
|
||||
return std::string("active");
|
||||
case TC_CHANNEL_TIMEDOUT:
|
||||
return std::string("timed out");
|
||||
default:
|
||||
return COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
sif::warning << "PdecHandler::getMonStatusString: Invalid status" << std::endl;
|
||||
return std::string();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t PdecHandler::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) {
|
||||
switch (actionId) {
|
||||
case PRINT_CLCW:
|
||||
printClcw();
|
||||
return EXECUTION_FINISHED;
|
||||
case PRINT_PDEC_MON:
|
||||
printPdecMon();
|
||||
return EXECUTION_FINISHED;
|
||||
default:
|
||||
return COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
|
@ -3,15 +3,15 @@
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "PdecConfig.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/action/ActionHelper.h"
|
||||
#include "fsfw/action/HasActionsIF.h"
|
||||
#include "fsfw/objectmanager/SystemObject.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw/storagemanager/StorageManagerIF.h"
|
||||
#include "fsfw/tasks/ExecutableObjectIF.h"
|
||||
#include "fsfw/tmtcservices/AcceptsTelecommandsIF.h"
|
||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||
#include "fsfw_hal/linux/gpio/LinuxLibgpioIF.h"
|
||||
|
||||
/**
|
||||
* @brief This class controls the PDEC IP Core implemented in the programmable logic of the
|
||||
@ -35,386 +35,381 @@ class PdecHandler : public SystemObject,
|
||||
public ExecutableObjectIF,
|
||||
public HasReturnvaluesIF,
|
||||
public HasActionsIF {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param objectId Object ID of PDEC handler system object
|
||||
* @param tcDestinationId Object ID of object responsible for processing TCs.
|
||||
* @param gpioComIF Pointer to GPIO interace responsible for driving GPIOs.
|
||||
* @param pdecReset GPIO ID of GPIO connected to the reset signal of the PDEC.
|
||||
* @param uioConfigMemory String of uio device file same mapped to the PDEC memory space
|
||||
* @param uioregsiters String of uio device file same mapped to the PDEC register space
|
||||
*/
|
||||
PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF,
|
||||
gpioId_t pdecReset, std::string uioConfigMemory, std::string uioRamMemory,
|
||||
std::string uioRegisters);
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param objectId Object ID of PDEC handler system object
|
||||
* @param tcDestinationId Object ID of object responsible for processing TCs.
|
||||
* @param gpioComIF Pointer to GPIO interace responsible for driving GPIOs.
|
||||
* @param pdecReset GPIO ID of GPIO connected to the reset signal of the PDEC.
|
||||
* @param uioConfigMemory String of uio device file same mapped to the PDEC memory space
|
||||
* @param uioregsiters String of uio device file same mapped to the PDEC register space
|
||||
*/
|
||||
PdecHandler(object_id_t objectId, object_id_t tcDestinationId, LinuxLibgpioIF* gpioComIF,
|
||||
gpioId_t pdecReset, std::string uioConfigMemory, std::string uioRamMemory,
|
||||
std::string uioRegisters);
|
||||
virtual ~PdecHandler();
|
||||
|
||||
virtual ~PdecHandler();
|
||||
ReturnValue_t performOperation(uint8_t operationCode = 0);
|
||||
|
||||
ReturnValue_t performOperation(uint8_t operationCode = 0);
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
|
||||
MessageQueueId_t getCommandQueue() const;
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
|
||||
|
||||
static const uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::PDEC_HANDLER;
|
||||
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
|
||||
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
|
||||
//! P2: When frame declared illegal this parameter this parameter gives information about the
|
||||
//! reason (IReason field of the PDEC_FAR register)
|
||||
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
|
||||
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] Carrier lock detected
|
||||
static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Bit lock detected (data valid)
|
||||
static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO);
|
||||
|
||||
//! [EXPORT] : [COMMENT] Frame acceptance report signals an invalid frame
|
||||
//! P1: The frame analysis information (FrameAna field of PDEC_FAR register)
|
||||
//! P2: When frame declared illegal this parameter this parameter gives information about the reason (IReason field of the PDEC_FAR register)
|
||||
static const Event INVALID_TC_FRAME = MAKE_EVENT(1, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] Read invalid FAR from PDEC after startup
|
||||
static const Event INVALID_FAR = MAKE_EVENT(2, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT] Carrier lock detected
|
||||
static const Event CARRIER_LOCK = MAKE_EVENT(3, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Bit lock detected (data valid)
|
||||
static const Event BIT_LOCK_PDEC = MAKE_EVENT(4, severity::INFO);
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
|
||||
|
||||
private:
|
||||
static const ReturnValue_t ABANDONED_CLTU = MAKE_RETURN_CODE(0xA0);
|
||||
static const ReturnValue_t FRAME_DIRTY = MAKE_RETURN_CODE(0xA1);
|
||||
static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2);
|
||||
static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2);
|
||||
static const ReturnValue_t AD_DISCARDED_LOCKOUT = MAKE_RETURN_CODE(0xA3);
|
||||
static const ReturnValue_t AD_DISCARDED_WAIT = MAKE_RETURN_CODE(0xA4);
|
||||
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PDEC_HANDLER;
|
||||
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
|
||||
|
||||
static const ReturnValue_t ABANDONED_CLTU = MAKE_RETURN_CODE(0xA0);
|
||||
static const ReturnValue_t FRAME_DIRTY = MAKE_RETURN_CODE(0xA1);
|
||||
static const ReturnValue_t FRAME_ILLEGAL_ONE_REASON = MAKE_RETURN_CODE(0xA2);
|
||||
static const ReturnValue_t FRAME_ILLEGAL_MULTIPLE_REASONS = MAKE_RETURN_CODE(0xA2);
|
||||
static const ReturnValue_t AD_DISCARDED_LOCKOUT = MAKE_RETURN_CODE(0xA3);
|
||||
static const ReturnValue_t AD_DISCARDED_WAIT = MAKE_RETURN_CODE(0xA4);
|
||||
static const ReturnValue_t AD_DISCARDED_NS_VS = MAKE_RETURN_CODE(0xA5);
|
||||
static const ReturnValue_t NO_REPORT = MAKE_RETURN_CODE(0xA6);
|
||||
//! Error in version number and reserved A and B fields
|
||||
static const ReturnValue_t ERROR_VERSION_NUMBER = MAKE_RETURN_CODE(0xA7);
|
||||
//! Illegal combination of bypass and control command flag
|
||||
static const ReturnValue_t ILLEGAL_COMBINATION = MAKE_RETURN_CODE(0xA8);
|
||||
//! Spacecraft identifier did not match
|
||||
static const ReturnValue_t INVALID_SC_ID = MAKE_RETURN_CODE(0xA9);
|
||||
//! VC identifier bits 0 to 4 did not match
|
||||
static const ReturnValue_t INVALID_VC_ID_MSB = MAKE_RETURN_CODE(0xAA);
|
||||
//! VC identifier bit 5 did not match
|
||||
static const ReturnValue_t INVALID_VC_ID_LSB = MAKE_RETURN_CODE(0xAB);
|
||||
//! N(S) of BC or BD frame not set to all zeros
|
||||
static const ReturnValue_t NS_NOT_ZERO = MAKE_RETURN_CODE(0xAC);
|
||||
//! Invalid BC control command
|
||||
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
|
||||
|
||||
//! [EXPORT] : [COMMENT] Received action message with unknown action id
|
||||
static const ReturnValue_t COMMAND_NOT_IMPLEMENTED = MAKE_RETURN_CODE(0xB0);
|
||||
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
|
||||
|
||||
static const ReturnValue_t NO_REPORT = MAKE_RETURN_CODE(0xA6);
|
||||
//! Error in version number and reserved A and B fields
|
||||
static const ReturnValue_t ERROR_VERSION_NUMBER = MAKE_RETURN_CODE(0xA7);
|
||||
//! Illegal combination of bypass and control command flag
|
||||
static const ReturnValue_t ILLEGAL_COMBINATION = MAKE_RETURN_CODE(0xA8);
|
||||
//! Spacecraft identifier did not match
|
||||
static const ReturnValue_t INVALID_SC_ID = MAKE_RETURN_CODE(0xA9);
|
||||
//! VC identifier bits 0 to 4 did not match
|
||||
static const ReturnValue_t INVALID_VC_ID_MSB = MAKE_RETURN_CODE(0xAA);
|
||||
//! VC identifier bit 5 did not match
|
||||
static const ReturnValue_t INVALID_VC_ID_LSB = MAKE_RETURN_CODE(0xAB);
|
||||
//! N(S) of BC or BD frame not set to all zeros
|
||||
static const ReturnValue_t NS_NOT_ZERO = MAKE_RETURN_CODE(0xAC);
|
||||
//! Invalid BC control command
|
||||
static const ReturnValue_t INVALID_BC_CC = MAKE_RETURN_CODE(0xAE);
|
||||
// Action IDs
|
||||
static const ActionId_t PRINT_CLCW = 0;
|
||||
// Print PDEC monitor register
|
||||
static const ActionId_t PRINT_PDEC_MON = 1;
|
||||
|
||||
static const uint32_t QUEUE_SIZE = common::CCSDS_HANDLER_QUEUE_SIZE;
|
||||
static const uint8_t STAT_POSITION = 31;
|
||||
static const uint8_t FRAME_ANA_POSITION = 28;
|
||||
static const uint8_t IREASON_POSITION = 25;
|
||||
|
||||
// Action IDs
|
||||
static const ActionId_t PRINT_CLCW = 0;
|
||||
// Print PDEC monitor register
|
||||
static const ActionId_t PRINT_PDEC_MON = 1;
|
||||
static const uint8_t NEW_FAR_RECEIVED = 0;
|
||||
|
||||
static const uint8_t STAT_POSITION = 31;
|
||||
static const uint8_t FRAME_ANA_POSITION = 28;
|
||||
static const uint8_t IREASON_POSITION = 25;
|
||||
static const uint32_t FRAME_ANA_MASK = 0x70000000;
|
||||
static const uint32_t IREASON_MASK = 0x0E000000;
|
||||
|
||||
static const uint8_t NEW_FAR_RECEIVED = 0;
|
||||
static const uint32_t TC_CHANNEL_INACTIVE = 0x0;
|
||||
static const uint32_t TC_CHANNEL_ACTIVE = 0x1;
|
||||
static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2;
|
||||
|
||||
static const uint32_t FRAME_ANA_MASK = 0x70000000;
|
||||
static const uint32_t IREASON_MASK = 0x0E000000;
|
||||
static const uint32_t TC0_STATUS_MASK = 0x3;
|
||||
static const uint32_t TC1_STATUS_MASK = 0xC;
|
||||
static const uint32_t TC2_STATUS_MASK = 0x300;
|
||||
static const uint32_t TC3_STATUS_MASK = 0xC00;
|
||||
static const uint32_t TC4_STATUS_MASK = 0x30000;
|
||||
static const uint32_t TC5_STATUS_MASK = 0xc00000;
|
||||
// Lock register set to 1 when start sequence has been found (CLTU is beeing processed)
|
||||
static const uint32_t LOCK_MASK = 0xc00000;
|
||||
|
||||
static const uint32_t TC_CHANNEL_INACTIVE = 0x0;
|
||||
static const uint32_t TC_CHANNEL_ACTIVE = 0x1;
|
||||
static const uint32_t TC_CHANNEL_TIMEDOUT = 0x2;
|
||||
static const uint32_t TC0_STATUS_POS = 0;
|
||||
static const uint32_t TC1_STATUS_POS = 2;
|
||||
static const uint32_t TC2_STATUS_POS = 4;
|
||||
static const uint32_t TC3_STATUS_POS = 6;
|
||||
static const uint32_t TC4_STATUS_POS = 8;
|
||||
static const uint32_t TC5_STATUS_POS = 10;
|
||||
// Lock register set to 1 when start sequence has been found (CLTU is beeing processed)
|
||||
static const uint32_t LOCK_POS = 12;
|
||||
|
||||
static const uint32_t TC0_STATUS_MASK = 0x3;
|
||||
static const uint32_t TC1_STATUS_MASK = 0xC;
|
||||
static const uint32_t TC2_STATUS_MASK = 0x300;
|
||||
static const uint32_t TC3_STATUS_MASK = 0xC00;
|
||||
static const uint32_t TC4_STATUS_MASK = 0x30000;
|
||||
static const uint32_t TC5_STATUS_MASK = 0xc00000;
|
||||
// Lock register set to 1 when start sequence has been found (CLTU is beeing processed)
|
||||
static const uint32_t LOCK_MASK = 0xc00000;
|
||||
|
||||
static const uint32_t TC0_STATUS_POS = 0;
|
||||
static const uint32_t TC1_STATUS_POS = 2;
|
||||
static const uint32_t TC2_STATUS_POS = 4;
|
||||
static const uint32_t TC3_STATUS_POS = 6;
|
||||
static const uint32_t TC4_STATUS_POS = 8;
|
||||
static const uint32_t TC5_STATUS_POS = 10;
|
||||
// Lock register set to 1 when start sequence has been found (CLTU is beeing processed)
|
||||
static const uint32_t LOCK_POS = 12;
|
||||
|
||||
/**
|
||||
* UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4
|
||||
* Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10
|
||||
*/
|
||||
static const uint32_t PDEC_FAR_OFFSET = 0xA10;
|
||||
static const uint32_t PDEC_CLCW_OFFSET = 0xA12;
|
||||
static const uint32_t PDEC_BFREE_OFFSET = 0xA24;
|
||||
static const uint32_t PDEC_BPTR_OFFSET = 0xA25;
|
||||
static const uint32_t PDEC_SLEN_OFFSET = 0xA26;
|
||||
static const uint32_t PDEC_MON_OFFSET = 0xA27;
|
||||
/**
|
||||
* UIO is 4 byte aligned. Thus offset is calculated with "true offset" / 4
|
||||
* Example: PDEC_FAR = 0x2840 => Offset in virtual address space is 0xA10
|
||||
*/
|
||||
static const uint32_t PDEC_FAR_OFFSET = 0xA10;
|
||||
static const uint32_t PDEC_CLCW_OFFSET = 0xA12;
|
||||
static const uint32_t PDEC_BFREE_OFFSET = 0xA24;
|
||||
static const uint32_t PDEC_BPTR_OFFSET = 0xA25;
|
||||
static const uint32_t PDEC_SLEN_OFFSET = 0xA26;
|
||||
static const uint32_t PDEC_MON_OFFSET = 0xA27;
|
||||
|
||||
#if BOARD_TE0720 == 1
|
||||
static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
|
||||
static const int RAM_MAP_SIZE = 0x4000;
|
||||
static const int REGISTER_MAP_SIZE = 0x10000;
|
||||
static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
|
||||
static const int RAM_MAP_SIZE = 0x4000;
|
||||
static const int REGISTER_MAP_SIZE = 0x10000;
|
||||
#else
|
||||
static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
|
||||
static const int RAM_MAP_SIZE = 0x4000;
|
||||
static const int REGISTER_MAP_SIZE = 0x4000;
|
||||
static const int CONFIG_MEMORY_MAP_SIZE = 0x400;
|
||||
static const int RAM_MAP_SIZE = 0x4000;
|
||||
static const int REGISTER_MAP_SIZE = 0x4000;
|
||||
#endif /* BOARD_TE0720 == 1 */
|
||||
|
||||
// 0x200 / 4 = 0x80
|
||||
static const uint32_t FRAME_HEADER_OFFSET = 0x80;
|
||||
// 0x200 / 4 = 0x80
|
||||
static const uint32_t FRAME_HEADER_OFFSET = 0x80;
|
||||
|
||||
static const size_t MAX_TC_SEGMENT_SIZE = 1017;
|
||||
static const uint8_t MAP_ID_MASK = 0x3F;
|
||||
static const size_t MAX_TC_SEGMENT_SIZE = 1017;
|
||||
static const uint8_t MAP_ID_MASK = 0x3F;
|
||||
|
||||
#if BOARD_TE0720 == 1
|
||||
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000;
|
||||
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x32000000;
|
||||
#else
|
||||
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x26000000;
|
||||
static const uint32_t PHYSICAL_RAM_BASE_ADDRESS = 0x26000000;
|
||||
#endif
|
||||
|
||||
static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0;
|
||||
static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90;
|
||||
static const uint32_t MAP_ADDR_LUT_OFFSET = 0xA0;
|
||||
static const uint32_t MAP_CLK_FREQ_OFFSET = 0x90;
|
||||
|
||||
static const uint8_t MAX_MAP_ADDR = 63;
|
||||
// Writing this to the map address in the look up table will invalidate a MAP ID.
|
||||
static const uint8_t NO_DESTINATION = 0;
|
||||
static const uint8_t VALID_POSITION = 6;
|
||||
static const uint8_t PARITY_POSITION = 7;
|
||||
static const uint8_t MAX_MAP_ADDR = 63;
|
||||
// Writing this to the map address in the look up table will invalidate a MAP ID.
|
||||
static const uint8_t NO_DESTINATION = 0;
|
||||
static const uint8_t VALID_POSITION = 6;
|
||||
static const uint8_t PARITY_POSITION = 7;
|
||||
|
||||
// Expected value stored in FAR register after reset
|
||||
static const uint32_t FAR_RESET = 0x7FE0;
|
||||
// Expected value stored in FAR register after reset
|
||||
static const uint32_t FAR_RESET = 0x7FE0;
|
||||
|
||||
static const uint32_t TC_SEGMENT_LEN = 1017;
|
||||
static const uint32_t TC_SEGMENT_LEN = 1017;
|
||||
|
||||
static const uint32_t NO_RF_MASK = 0x8000;
|
||||
static const uint32_t NO_BITLOCK_MASK = 0x4000;
|
||||
static const uint32_t NO_RF_MASK = 0x8000;
|
||||
static const uint32_t NO_BITLOCK_MASK = 0x4000;
|
||||
|
||||
/**
|
||||
* TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in
|
||||
* the PDEC memory.
|
||||
*/
|
||||
static const uint8_t PM_BUFFER = 7;
|
||||
/**
|
||||
* TCs with map addresses (also know as Map IDs) assigned to this channel will be stored in
|
||||
* the PDEC memory.
|
||||
*/
|
||||
static const uint8_t PM_BUFFER = 7;
|
||||
|
||||
// MAP clock frequency. Must be a value between 1 and 13 otherwise the TC segment will be
|
||||
// discarded
|
||||
static const uint8_t MAP_CLK_FREQ = 2;
|
||||
// MAP clock frequency. Must be a value between 1 and 13 otherwise the TC segment will be
|
||||
// discarded
|
||||
static const uint8_t MAP_CLK_FREQ = 2;
|
||||
|
||||
enum class FrameAna_t: uint8_t {
|
||||
ABANDONED_CLTU,
|
||||
FRAME_DIRTY,
|
||||
FRAME_ILLEGAL,
|
||||
FRAME_ILLEGAL_MULTI_REASON,
|
||||
AD_DISCARDED_LOCKOUT,
|
||||
AD_DISCARDED_WAIT,
|
||||
AD_DISCARDED_NS_VR,
|
||||
FRAME_ACCEPTED
|
||||
};
|
||||
enum class FrameAna_t : uint8_t {
|
||||
ABANDONED_CLTU,
|
||||
FRAME_DIRTY,
|
||||
FRAME_ILLEGAL,
|
||||
FRAME_ILLEGAL_MULTI_REASON,
|
||||
AD_DISCARDED_LOCKOUT,
|
||||
AD_DISCARDED_WAIT,
|
||||
AD_DISCARDED_NS_VR,
|
||||
FRAME_ACCEPTED
|
||||
};
|
||||
|
||||
enum class IReason_t: uint8_t {
|
||||
NO_REPORT,
|
||||
ERROR_VERSION_NUMBER,
|
||||
ILLEGAL_COMBINATION,
|
||||
INVALID_SC_ID,
|
||||
INVALID_VC_ID_LSB,
|
||||
INVALID_VC_ID_MSB,
|
||||
NS_NOT_ZERO,
|
||||
INCORRECT_BC_CC
|
||||
};
|
||||
enum class IReason_t : uint8_t {
|
||||
NO_REPORT,
|
||||
ERROR_VERSION_NUMBER,
|
||||
ILLEGAL_COMBINATION,
|
||||
INVALID_SC_ID,
|
||||
INVALID_VC_ID_LSB,
|
||||
INVALID_VC_ID_MSB,
|
||||
NS_NOT_ZERO,
|
||||
INCORRECT_BC_CC
|
||||
};
|
||||
|
||||
enum class State: uint8_t {
|
||||
INIT,
|
||||
RUNNING,
|
||||
WAIT_FOR_RECOVERY
|
||||
};
|
||||
enum class State : uint8_t { INIT, RUNNING, WAIT_FOR_RECOVERY };
|
||||
|
||||
/**
|
||||
* @brief Reads and handles messages stored in the commandQueue
|
||||
*/
|
||||
void readCommandQueue(void);
|
||||
/**
|
||||
* @brief Reads and handles messages stored in the commandQueue
|
||||
*/
|
||||
void readCommandQueue(void);
|
||||
|
||||
/**
|
||||
* @brief Opens UIO device assigned to AXI to AHB converter giving access to the PDEC
|
||||
* registers. The register base address will be mapped into the virtual address space.
|
||||
*/
|
||||
ReturnValue_t getRegisterAddress();
|
||||
/**
|
||||
* @brief Opens UIO device assigned to AXI to AHB converter giving access to the PDEC
|
||||
* registers. The register base address will be mapped into the virtual address space.
|
||||
*/
|
||||
ReturnValue_t getRegisterAddress();
|
||||
|
||||
/**
|
||||
* @brief Opens UIO device assigned to the base address of the PDEC memory space and maps the
|
||||
* physical address into the virtual address space.
|
||||
*/
|
||||
ReturnValue_t getConfigMemoryBaseAddress();
|
||||
/**
|
||||
* @brief Opens UIO device assigned to the base address of the PDEC memory space and maps the
|
||||
* physical address into the virtual address space.
|
||||
*/
|
||||
ReturnValue_t getConfigMemoryBaseAddress();
|
||||
|
||||
/**
|
||||
* @brief Opens UIO device assigned to the RAM section of the PDEC IP core memory map.
|
||||
*
|
||||
* @details A received TC segment will be written to this memory area.
|
||||
*/
|
||||
ReturnValue_t getRamBaseAddress();
|
||||
/**
|
||||
* @brief Opens UIO device assigned to the RAM section of the PDEC IP core memory map.
|
||||
*
|
||||
* @details A received TC segment will be written to this memory area.
|
||||
*/
|
||||
ReturnValue_t getRamBaseAddress();
|
||||
|
||||
/**
|
||||
* @brief This functions writes the configuration parameters to the configuration
|
||||
* section of the PDEC.
|
||||
*/
|
||||
void writePdecConfig();
|
||||
/**
|
||||
* @brief This functions writes the configuration parameters to the configuration
|
||||
* section of the PDEC.
|
||||
*/
|
||||
void writePdecConfig();
|
||||
|
||||
/**
|
||||
* @brief Reading the FAR resets the set stat flag which signals a new TC. Without clearing
|
||||
* this flag no new TC will be excepted. After start up the flag is set and needs
|
||||
* to be reset.
|
||||
* Stat flag 0 - new TC received
|
||||
* Stat flag 1 - old TC (ready to receive next TC)
|
||||
*/
|
||||
ReturnValue_t resetFarStatFlag();
|
||||
/**
|
||||
* @brief Reading the FAR resets the set stat flag which signals a new TC. Without clearing
|
||||
* this flag no new TC will be excepted. After start up the flag is set and needs
|
||||
* to be reset.
|
||||
* Stat flag 0 - new TC received
|
||||
* Stat flag 1 - old TC (ready to receive next TC)
|
||||
*/
|
||||
ReturnValue_t resetFarStatFlag();
|
||||
|
||||
/**
|
||||
* @brief Releases the PDEC from reset state. PDEC will start with loading the written
|
||||
* configuration parameters.
|
||||
*/
|
||||
ReturnValue_t releasePdec();
|
||||
/**
|
||||
* @brief Releases the PDEC from reset state. PDEC will start with loading the written
|
||||
* configuration parameters.
|
||||
*/
|
||||
ReturnValue_t releasePdec();
|
||||
|
||||
/**
|
||||
* @brief Reads the FAR register and checks if a new TC has been received.
|
||||
*/
|
||||
bool newTcReceived();
|
||||
/**
|
||||
* @brief Reads the FAR register and checks if a new TC has been received.
|
||||
*/
|
||||
bool newTcReceived();
|
||||
|
||||
/**
|
||||
* @brief Checks if carrier lock or bit lock has been detected and triggers appropriate
|
||||
* event.
|
||||
*/
|
||||
void checkLocks();
|
||||
/**
|
||||
* @brief Checks if carrier lock or bit lock has been detected and triggers appropriate
|
||||
* event.
|
||||
*/
|
||||
void checkLocks();
|
||||
|
||||
/**
|
||||
* @brief Analyzes the FramAna field (frame analysis data) of a FAR report.
|
||||
*
|
||||
* @return True if frame valid, otherwise false.
|
||||
*/
|
||||
bool checkFrameAna(uint32_t pdecFar);
|
||||
/**
|
||||
* @brief Analyzes the FramAna field (frame analysis data) of a FAR report.
|
||||
*
|
||||
* @return True if frame valid, otherwise false.
|
||||
*/
|
||||
bool checkFrameAna(uint32_t pdecFar);
|
||||
|
||||
/**
|
||||
* @brief This function handles the IReason field of the frame analysis report.
|
||||
*
|
||||
* @details In case frame as been declared illegal for multiple reasons, the reason with the
|
||||
* lowest value will be shown.
|
||||
*/
|
||||
void handleIReason(uint32_t pdecFar, ReturnValue_t parameter1);
|
||||
/**
|
||||
* @brief This function handles the IReason field of the frame analysis report.
|
||||
*
|
||||
* @details In case frame as been declared illegal for multiple reasons, the reason with the
|
||||
* lowest value will be shown.
|
||||
*/
|
||||
void handleIReason(uint32_t pdecFar, ReturnValue_t parameter1);
|
||||
|
||||
/**
|
||||
* @brief Handles the reception of new TCs. Reads the pointer to the storage location of the
|
||||
* new TC segment, extracts the PUS packet and forwards the data to the object
|
||||
* responsible for processing the TC.
|
||||
*/
|
||||
void handleNewTc();
|
||||
/**
|
||||
* @brief Handles the reception of new TCs. Reads the pointer to the storage location of the
|
||||
* new TC segment, extracts the PUS packet and forwards the data to the object
|
||||
* responsible for processing the TC.
|
||||
*/
|
||||
void handleNewTc();
|
||||
|
||||
/**
|
||||
* @brief Function reads the last received TC segment from the PDEC memory and copies
|
||||
* the data to the tcSegement array.
|
||||
*
|
||||
* @param tcLength The length of the received TC.
|
||||
*
|
||||
*/
|
||||
ReturnValue_t readTc(uint32_t& tcLength);
|
||||
/**
|
||||
* @brief Function reads the last received TC segment from the PDEC memory and copies
|
||||
* the data to the tcSegement array.
|
||||
*
|
||||
* @param tcLength The length of the received TC.
|
||||
*
|
||||
*/
|
||||
ReturnValue_t readTc(uint32_t& tcLength);
|
||||
|
||||
/**
|
||||
* @brief Prints the tc segment data
|
||||
*/
|
||||
void printTC(uint32_t tcLength);
|
||||
/**
|
||||
* @brief Prints the tc segment data
|
||||
*/
|
||||
void printTC(uint32_t tcLength);
|
||||
|
||||
/**
|
||||
* @brief This function calculates the entry for the configuration of the MAP ID routing.
|
||||
*
|
||||
* @param mapAddr The MAP ID to configure
|
||||
* @param moduleId The destination module where all TCs with the map id mapAddr will be routed
|
||||
* to.
|
||||
*
|
||||
* @details The PDEC has different modules where the TCs can be routed to. A lookup table is
|
||||
* used which links the MAP ID field to the destination module. The entry for this
|
||||
* lookup table is created by this function and must be stored in the configuration
|
||||
* memory region of the PDEC. The entry has a specific format
|
||||
*/
|
||||
uint8_t calcMapAddrEntry(uint8_t moduleId);
|
||||
/**
|
||||
* @brief This function calculates the entry for the configuration of the MAP ID routing.
|
||||
*
|
||||
* @param mapAddr The MAP ID to configure
|
||||
* @param moduleId The destination module where all TCs with the map id mapAddr will be routed
|
||||
* to.
|
||||
*
|
||||
* @details The PDEC has different modules where the TCs can be routed to. A lookup table is
|
||||
* used which links the MAP ID field to the destination module. The entry for this
|
||||
* lookup table is created by this function and must be stored in the configuration
|
||||
* memory region of the PDEC. The entry has a specific format
|
||||
*/
|
||||
uint8_t calcMapAddrEntry(uint8_t moduleId);
|
||||
|
||||
/**
|
||||
* @brief This functions calculates the odd parity of the bits in number.
|
||||
*
|
||||
* @param number The number from which to calculate the odd parity.
|
||||
*/
|
||||
uint8_t getOddParity(uint8_t number);
|
||||
/**
|
||||
* @brief This functions calculates the odd parity of the bits in number.
|
||||
*
|
||||
* @param number The number from which to calculate the odd parity.
|
||||
*/
|
||||
uint8_t getOddParity(uint8_t number);
|
||||
|
||||
/**
|
||||
* brief Returns the 32-bit wide communication link control word (CLCW)
|
||||
*/
|
||||
uint32_t getClcw();
|
||||
/**
|
||||
* brief Returns the 32-bit wide communication link control word (CLCW)
|
||||
*/
|
||||
uint32_t getClcw();
|
||||
|
||||
/**
|
||||
* @brief Returns the PDEC monitor register content
|
||||
*
|
||||
*/
|
||||
uint32_t getPdecMon();
|
||||
/**
|
||||
* @brief Returns the PDEC monitor register content
|
||||
*
|
||||
*/
|
||||
uint32_t getPdecMon();
|
||||
|
||||
/**
|
||||
* @brief Reads and prints the CLCW. Can be useful for debugging.
|
||||
*/
|
||||
void printClcw();
|
||||
/**
|
||||
* @brief Reads and prints the CLCW. Can be useful for debugging.
|
||||
*/
|
||||
void printClcw();
|
||||
|
||||
/**
|
||||
* @brief Prints monitor register information to debug console.
|
||||
*/
|
||||
void printPdecMon();
|
||||
/**
|
||||
* @brief Prints monitor register information to debug console.
|
||||
*/
|
||||
void printPdecMon();
|
||||
|
||||
std::string getMonStatusString(uint32_t status);
|
||||
std::string getMonStatusString(uint32_t status);
|
||||
|
||||
object_id_t tcDestinationId;
|
||||
object_id_t tcDestinationId;
|
||||
|
||||
AcceptsTelecommandsIF* tcDestination = nullptr;
|
||||
AcceptsTelecommandsIF* tcDestination = nullptr;
|
||||
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
LinuxLibgpioIF* gpioComIF = nullptr;
|
||||
|
||||
/**
|
||||
* Reset signal is required to hold PDEC in reset state until the configuration has been
|
||||
* written to the appropriate memory space.
|
||||
* Can also be used to reboot PDEC in case of erros.
|
||||
*/
|
||||
gpioId_t pdecReset = gpio::NO_GPIO;
|
||||
/**
|
||||
* Reset signal is required to hold PDEC in reset state until the configuration has been
|
||||
* written to the appropriate memory space.
|
||||
* Can also be used to reboot PDEC in case of erros.
|
||||
*/
|
||||
gpioId_t pdecReset = gpio::NO_GPIO;
|
||||
|
||||
// UIO device file giving access to the PDEC configuration memory section
|
||||
std::string uioConfigMemory;
|
||||
// UIO device file giving access to the PDEC configuration memory section
|
||||
std::string uioConfigMemory;
|
||||
|
||||
// UIO device file giving access to the PDEC RAM section
|
||||
std::string uioRamMemory;
|
||||
// UIO device file giving access to the PDEC RAM section
|
||||
std::string uioRamMemory;
|
||||
|
||||
// UIO device file giving access to the PDEC register space
|
||||
std::string uioRegisters;
|
||||
// UIO device file giving access to the PDEC register space
|
||||
std::string uioRegisters;
|
||||
|
||||
ActionHelper actionHelper;
|
||||
ActionHelper actionHelper;
|
||||
|
||||
StorageManagerIF* tcStore = nullptr;
|
||||
StorageManagerIF* tcStore = nullptr;
|
||||
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
MessageQueueIF* commandQueue = nullptr;
|
||||
|
||||
State state = State::INIT;
|
||||
State state = State::INIT;
|
||||
|
||||
/**
|
||||
* Pointer pointing to base address of the PDEC memory space.
|
||||
* This address is equivalent with the base address of the section named configuration area in
|
||||
* the PDEC datasheet.
|
||||
*/
|
||||
uint32_t* memoryBaseAddress = nullptr;
|
||||
/**
|
||||
* Pointer pointing to base address of the PDEC memory space.
|
||||
* This address is equivalent with the base address of the section named configuration area in
|
||||
* the PDEC datasheet.
|
||||
*/
|
||||
uint32_t* memoryBaseAddress = nullptr;
|
||||
|
||||
uint32_t* ramBaseAddress = nullptr;
|
||||
uint32_t* ramBaseAddress = nullptr;
|
||||
|
||||
// Pointer pointing to base address of register space
|
||||
uint32_t* registerBaseAddress = nullptr;
|
||||
// Pointer pointing to base address of register space
|
||||
uint32_t* registerBaseAddress = nullptr;
|
||||
|
||||
uint32_t pdecFar = 0;
|
||||
uint32_t pdecFar = 0;
|
||||
|
||||
uint8_t tcSegment[TC_SEGMENT_LEN];
|
||||
uint8_t tcSegment[TC_SEGMENT_LEN];
|
||||
|
||||
// Used to check carrier and bit lock changes (default set to no rf and no bitlock)
|
||||
uint32_t lastClcw = 0xC000;
|
||||
// Used to check carrier and bit lock changes (default set to no rf and no bitlock)
|
||||
uint32_t lastClcw = 0xC000;
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_PDECHANDLER_H_ */
|
||||
|
@ -1,72 +1,69 @@
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <linux/obc/Ptme.h>
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "PtmeConfig.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
Ptme::Ptme(object_id_t objectId): SystemObject(objectId) {
|
||||
}
|
||||
Ptme::Ptme(object_id_t objectId) : SystemObject(objectId) {}
|
||||
|
||||
Ptme::~Ptme() {
|
||||
}
|
||||
Ptme::~Ptme() {}
|
||||
|
||||
ReturnValue_t Ptme::initialize() {
|
||||
int fd = open(PtmeConfig::UIO_DEVICE_FILE, O_RDWR);
|
||||
if (fd < 1) {
|
||||
sif::warning << "Ptme::initialize: Invalid UIO device file" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
int fd = open(PtmeConfig::UIO_DEVICE_FILE, O_RDWR);
|
||||
if (fd < 1) {
|
||||
sif::warning << "Ptme::initialize: Invalid UIO device file" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
/**
|
||||
* Map uio device in virtual address space
|
||||
* PROT_WRITE: Map uio device in writable only mode
|
||||
*/
|
||||
ptmeBaseAddress = static_cast<uint32_t*>(mmap(NULL, MAP_SIZE, PROT_WRITE, MAP_SHARED, fd, 0));
|
||||
|
||||
/**
|
||||
* Map uio device in virtual address space
|
||||
* PROT_WRITE: Map uio device in writable only mode
|
||||
*/
|
||||
ptmeBaseAddress = static_cast<uint32_t*>(mmap(NULL, MAP_SIZE, PROT_WRITE,
|
||||
MAP_SHARED, fd, 0));
|
||||
if (ptmeBaseAddress == MAP_FAILED) {
|
||||
sif::error << "Ptme::initialize: Failed to map uio address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
|
||||
if (ptmeBaseAddress == MAP_FAILED) {
|
||||
sif::error << "Ptme::initialize: Failed to map uio address" << std::endl;
|
||||
return RETURN_FAILED;
|
||||
}
|
||||
VcInterfaceMapIter iter;
|
||||
for (iter = vcInterfaceMap.begin(); iter != vcInterfaceMap.end(); iter++) {
|
||||
iter->second->setRegisterAddress(ptmeBaseAddress);
|
||||
}
|
||||
|
||||
VcInterfaceMapIter iter;
|
||||
for (iter = vcInterfaceMap.begin(); iter != vcInterfaceMap.end(); iter++) {
|
||||
iter->second->setRegisterAddress(ptmeBaseAddress);
|
||||
}
|
||||
|
||||
return RETURN_OK;
|
||||
return RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t * data, size_t size) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
VcInterfaceMapIter vcInterfaceMapIter = vcInterfaceMap.find(vcId);
|
||||
if (vcInterfaceMapIter == vcInterfaceMap.end()) {
|
||||
sif::warning << "Ptme::writeToVc: No virtual channel interface found for the virtual "
|
||||
"channel with id " << static_cast<unsigned int>(vcId) << std::endl;
|
||||
return UNKNOWN_VC_ID;
|
||||
}
|
||||
result = vcInterfaceMapIter->second->write(data, size);
|
||||
return result;
|
||||
ReturnValue_t Ptme::writeToVc(uint8_t vcId, const uint8_t* data, size_t size) {
|
||||
ReturnValue_t result = RETURN_OK;
|
||||
VcInterfaceMapIter vcInterfaceMapIter = vcInterfaceMap.find(vcId);
|
||||
if (vcInterfaceMapIter == vcInterfaceMap.end()) {
|
||||
sif::warning << "Ptme::writeToVc: No virtual channel interface found for the virtual "
|
||||
"channel with id "
|
||||
<< static_cast<unsigned int>(vcId) << std::endl;
|
||||
return UNKNOWN_VC_ID;
|
||||
}
|
||||
result = vcInterfaceMapIter->second->write(data, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Ptme::addVcInterface(VcId_t vcId, VcInterfaceIF* vc) {
|
||||
if (vcId > common::NUMBER_OF_VIRTUAL_CHANNELS) {
|
||||
sif::warning << "Ptme::addVcInterface: Invalid virtual channel ID" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (vcId > common::NUMBER_OF_VIRTUAL_CHANNELS) {
|
||||
sif::warning << "Ptme::addVcInterface: Invalid virtual channel ID" << std::endl;
|
||||
return;
|
||||
}
|
||||
if (vc == nullptr) {
|
||||
sif::warning << "Ptme::addVcInterface: Invalid virtual channel interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (vc == nullptr) {
|
||||
sif::warning << "Ptme::addVcInterface: Invalid virtual channel interface" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto status = vcInterfaceMap.emplace(vcId, vc);
|
||||
if (status.second == false) {
|
||||
sif::warning << "Ptme::addVcInterface: Failed to add virtual channel interface to "
|
||||
"virtual channel map" << std::endl;
|
||||
return;
|
||||
}
|
||||
auto status = vcInterfaceMap.emplace(vcId, vc);
|
||||
if (status.second == false) {
|
||||
sif::warning << "Ptme::addVcInterface: Failed to add virtual channel interface to "
|
||||
"virtual channel map"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
116
linux/obc/Ptme.h
116
linux/obc/Ptme.h
@ -1,91 +1,87 @@
|
||||
#ifndef LINUX_OBC_PTME_H_
|
||||
#define LINUX_OBC_PTME_H_
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "linux/obc/PtmeIF.h"
|
||||
#include "linux/obc/VcInterfaceIF.h"
|
||||
#include <fsfw_hal/common/gpio/gpioDefinitions.h>
|
||||
#include <fsfw_hal/linux/gpio/LinuxLibgpioIF.h>
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "linux/obc/PtmeIF.h"
|
||||
#include "linux/obc/VcInterfaceIF.h"
|
||||
|
||||
/**
|
||||
* @brief This class handles the interfacing to the telemetry (PTME) IP core responsible for the
|
||||
* encoding of telemetry packets according to the CCSDS standards CCSDS 131.0-B-3 (TM Synchro-
|
||||
* nization and channel coding) and CCSDS 132.0-B-2 (TM Space Data Link Protocoll).
|
||||
* The IP cores are implemented on the programmable logic and are accessible through the
|
||||
* linux UIO driver.
|
||||
* encoding of telemetry packets according to the CCSDS standards CCSDS 131.0-B-3 (TM
|
||||
* Synchro- nization and channel coding) and CCSDS 132.0-B-2 (TM Space Data Link Protocoll). The IP
|
||||
* cores are implemented on the programmable logic and are accessible through the linux UIO driver.
|
||||
*/
|
||||
class Ptme : public PtmeIF,
|
||||
public SystemObject,
|
||||
public HasReturnvaluesIF {
|
||||
public:
|
||||
class Ptme : public PtmeIF, public SystemObject, public HasReturnvaluesIF {
|
||||
public:
|
||||
using VcId_t = uint8_t;
|
||||
|
||||
using VcId_t = uint8_t;
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId
|
||||
*/
|
||||
Ptme(object_id_t objectId);
|
||||
virtual ~Ptme();
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param objectId
|
||||
*/
|
||||
Ptme(object_id_t objectId);
|
||||
virtual ~Ptme();
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) override;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) override;
|
||||
/**
|
||||
* @brief This function adds the reference to a virtual channel interface to the vcInterface
|
||||
* map.
|
||||
*/
|
||||
void addVcInterface(VcId_t vcId, VcInterfaceIF* vc);
|
||||
|
||||
/**
|
||||
* @brief This function adds the reference to a virtual channel interface to the vcInterface
|
||||
* map.
|
||||
*/
|
||||
void addVcInterface(VcId_t vcId, VcInterfaceIF* vc);
|
||||
private:
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PTME;
|
||||
|
||||
private:
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::PTME;
|
||||
|
||||
static const ReturnValue_t UNKNOWN_VC_ID = MAKE_RETURN_CODE(0xA0);
|
||||
static const ReturnValue_t UNKNOWN_VC_ID = MAKE_RETURN_CODE(0xA0);
|
||||
|
||||
#if BOARD_TE0720 == 1
|
||||
/** Size of mapped address space */
|
||||
static const int MAP_SIZE = 0x40000;
|
||||
/** Size of mapped address space */
|
||||
static const int MAP_SIZE = 0x40000;
|
||||
#else
|
||||
/** Size of mapped address space */
|
||||
static const int MAP_SIZE = 0x40000;
|
||||
/** Size of mapped address space */
|
||||
static const int MAP_SIZE = 0x40000;
|
||||
#endif /* BOARD_TE0720 == 1 */
|
||||
|
||||
/**
|
||||
* Configuration bits:
|
||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||
* bit[2]: Set this bit to 1 to abort a transfered packet
|
||||
* bit[3]: Signals to PTME the start of a new telemetry packet
|
||||
*/
|
||||
static const uint32_t PTME_CONFIG_START = 0x8;
|
||||
/**
|
||||
* Configuration bits:
|
||||
* bit[1:0]: Size of data (1,2,3 or 4 bytes). 1 Byte <=> b00
|
||||
* bit[2]: Set this bit to 1 to abort a transfered packet
|
||||
* bit[3]: Signals to PTME the start of a new telemetry packet
|
||||
*/
|
||||
static const uint32_t PTME_CONFIG_START = 0x8;
|
||||
|
||||
/**
|
||||
* Writing this word to the ptme base address signals to the PTME that a complete tm packet has
|
||||
* been transferred.
|
||||
*/
|
||||
static const uint32_t PTME_CONFIG_END = 0x0;
|
||||
/**
|
||||
* Writing this word to the ptme base address signals to the PTME that a complete tm packet has
|
||||
* been transferred.
|
||||
*/
|
||||
static const uint32_t PTME_CONFIG_END = 0x0;
|
||||
|
||||
/**
|
||||
* Writing to this offset within the PTME memory space will insert data for encoding to the
|
||||
* PTME IP core.
|
||||
* The address offset is 0x400 (= 4 * 256)
|
||||
*/
|
||||
static const int PTME_DATA_REG_OFFSET = 256;
|
||||
/**
|
||||
* Writing to this offset within the PTME memory space will insert data for encoding to the
|
||||
* PTME IP core.
|
||||
* The address offset is 0x400 (= 4 * 256)
|
||||
*/
|
||||
static const int PTME_DATA_REG_OFFSET = 256;
|
||||
|
||||
/** The file descriptor of the UIO driver */
|
||||
int fd = 0;
|
||||
/** The file descriptor of the UIO driver */
|
||||
int fd = 0;
|
||||
|
||||
uint32_t* ptmeBaseAddress = nullptr;
|
||||
uint32_t* ptmeBaseAddress = nullptr;
|
||||
|
||||
using VcInterfaceMap = std::unordered_map<VcId_t, VcInterfaceIF*>;
|
||||
using VcInterfaceMapIter = VcInterfaceMap::iterator;
|
||||
using VcInterfaceMap = std::unordered_map<VcId_t, VcInterfaceIF*>;
|
||||
using VcInterfaceMapIter = VcInterfaceMap::iterator;
|
||||
|
||||
VcInterfaceMap vcInterfaceMap;
|
||||
VcInterfaceMap vcInterfaceMap;
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_PTME_H_ */
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef LINUX_OBC_PTMECONFIG_H_
|
||||
#define LINUX_OBC_PTMECONFIG_H_
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include <cstring>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
* @brief PTME specific configuration parameters derived from FPGA design and device tree.
|
||||
@ -11,20 +12,20 @@
|
||||
* @author J. Meier
|
||||
*/
|
||||
namespace PtmeConfig {
|
||||
/**
|
||||
* Offset of virtual channels mapped into address space
|
||||
* 0x10000 = (0x4000 * 4)
|
||||
*/
|
||||
static const uint32_t VC0_OFFSETT = 0;
|
||||
static const uint32_t VC1_OFFSETT = 0x4000;
|
||||
static const uint32_t VC2_OFFSETT = 0x8000;
|
||||
static const uint32_t VC3_OFFSETT = 0xC000;
|
||||
/**
|
||||
* Offset of virtual channels mapped into address space
|
||||
* 0x10000 = (0x4000 * 4)
|
||||
*/
|
||||
static const uint32_t VC0_OFFSETT = 0;
|
||||
static const uint32_t VC1_OFFSETT = 0x4000;
|
||||
static const uint32_t VC2_OFFSETT = 0x8000;
|
||||
static const uint32_t VC3_OFFSETT = 0xC000;
|
||||
#if BOARD_TE0720 == 0
|
||||
static const char UIO_DEVICE_FILE[] = "/dev/uio1";
|
||||
static const char UIO_DEVICE_FILE[] = "/dev/uio1";
|
||||
#else
|
||||
static const char UIO_DEVICE_FILE[] = "/dev/uio1";
|
||||
static const char UIO_DEVICE_FILE[] = "/dev/uio1";
|
||||
#endif
|
||||
|
||||
};
|
||||
}; // namespace PtmeConfig
|
||||
|
||||
#endif /* LINUX_OBC_PTMECONFIG_H_ */
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief Interface class for managing the PTME IP Core implemented in the programmable logic.
|
||||
*
|
||||
@ -12,17 +11,17 @@
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PtmeIF {
|
||||
public:
|
||||
virtual ~PtmeIF(){};
|
||||
public:
|
||||
virtual ~PtmeIF(){};
|
||||
|
||||
/**
|
||||
* @brief Implements to function to write to a specific virtual channel.
|
||||
*
|
||||
* @param vcId Virtual channel to write to
|
||||
* @param data Pointer to buffer holding the data to write
|
||||
* @param size Number of bytes to write
|
||||
*/
|
||||
virtual ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) = 0;
|
||||
/**
|
||||
* @brief Implements to function to write to a specific virtual channel.
|
||||
*
|
||||
* @param vcId Virtual channel to write to
|
||||
* @param data Pointer to buffer holding the data to write
|
||||
* @param size Number of bytes to write
|
||||
*/
|
||||
virtual ReturnValue_t writeToVc(uint8_t vcId, const uint8_t* data, size_t size) = 0;
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_PTMEIF_H_ */
|
||||
|
@ -1,27 +1,25 @@
|
||||
#include "PtmeRateSetter.h"
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
PtmeRateSetter::PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif) :
|
||||
bitrateSel(bitrateSel), gpioif(gpioif) {
|
||||
}
|
||||
PtmeRateSetter::PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif)
|
||||
: bitrateSel(bitrateSel), gpioif(gpioif) {}
|
||||
|
||||
PtmeRateSetter::~PtmeRateSetter() {
|
||||
}
|
||||
PtmeRateSetter::~PtmeRateSetter() {}
|
||||
|
||||
ReturnValue_t PtmeRateSetter::setRate(BitRates rate) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
switch(rate) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
switch (rate) {
|
||||
case RATE_2000KHZ:
|
||||
result = gpioif->pullHigh(bitrateSel);
|
||||
break;
|
||||
result = gpioif->pullHigh(bitrateSel);
|
||||
break;
|
||||
case RATE_400KHZ:
|
||||
result = gpioif->pullLow(bitrateSel);
|
||||
break;
|
||||
result = gpioif->pullLow(bitrateSel);
|
||||
break;
|
||||
default:
|
||||
sif::debug << "PtmeRateSetter::setRate: Invalid rate" << std::endl;
|
||||
result = HasReturnvaluesIF::RETURN_FAILED;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
sif::debug << "PtmeRateSetter::setRate: Invalid rate" << std::endl;
|
||||
result = HasReturnvaluesIF::RETURN_FAILED;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2,9 +2,9 @@
|
||||
#define LINUX_OBC_PTMERATESETTER_H_
|
||||
|
||||
#include "TxRateSetterIF.h"
|
||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include "fsfw_hal/common/gpio/GpioIF.h"
|
||||
#include "fsfw_hal/common/gpio/gpioDefinitions.h"
|
||||
|
||||
/**
|
||||
* @brief Class to set the downlink bit rate by using the cadu_rate_switcher implemented in
|
||||
@ -15,26 +15,24 @@
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class PtmeRateSetter: public TxRateSetterIF {
|
||||
public:
|
||||
class PtmeRateSetter : public TxRateSetterIF {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param bitrateSel GPIO ID of the GPIO connected to the bitrate_sel input of the
|
||||
* cadu_rate_switcher.
|
||||
* @param gpioif GPIO interface to drive the bitrateSel GPIO
|
||||
*/
|
||||
PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif);
|
||||
virtual ~PtmeRateSetter();
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param bitrateSel GPIO ID of the GPIO connected to the bitrate_sel input of the
|
||||
* cadu_rate_switcher.
|
||||
* @param gpioif GPIO interface to drive the bitrateSel GPIO
|
||||
*/
|
||||
PtmeRateSetter(gpioId_t bitrateSel, GpioIF* gpioif);
|
||||
virtual ~PtmeRateSetter();
|
||||
virtual ReturnValue_t setRate(BitRates rate);
|
||||
|
||||
virtual ReturnValue_t setRate(BitRates rate);
|
||||
private:
|
||||
gpioId_t bitrateSel = gpio::NO_GPIO;
|
||||
|
||||
private:
|
||||
|
||||
gpioId_t bitrateSel = gpio::NO_GPIO;
|
||||
|
||||
GpioIF* gpioif = nullptr;
|
||||
GpioIF* gpioif = nullptr;
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_PTMERATESETTER_H_ */
|
||||
|
@ -3,10 +3,7 @@
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
enum BitRates : uint32_t {
|
||||
RATE_2000KHZ,
|
||||
RATE_400KHZ
|
||||
};
|
||||
enum BitRates : uint32_t { RATE_2000KHZ, RATE_400KHZ };
|
||||
|
||||
/**
|
||||
* @brief Abstract class for objects implementing the functionality to switch the
|
||||
@ -15,11 +12,11 @@ enum BitRates : uint32_t {
|
||||
* @author J. Meier
|
||||
*/
|
||||
class TxRateSetterIF {
|
||||
public:
|
||||
TxRateSetterIF() {};
|
||||
virtual ~TxRateSetterIF() {};
|
||||
public:
|
||||
TxRateSetterIF(){};
|
||||
virtual ~TxRateSetterIF(){};
|
||||
|
||||
virtual ReturnValue_t setRate(BitRates bitRate) = 0;
|
||||
virtual ReturnValue_t setRate(BitRates bitRate) = 0;
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_TXRATESETTERIF_H_ */
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define LINUX_OBC_VCINTERFACEIF_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
/**
|
||||
@ -11,19 +12,19 @@
|
||||
* @author J. Meier
|
||||
*/
|
||||
class VcInterfaceIF {
|
||||
public:
|
||||
virtual ~VcInterfaceIF(){};
|
||||
public:
|
||||
virtual ~VcInterfaceIF(){};
|
||||
|
||||
/**
|
||||
* @brief Implememts the functionality to write data in the virtual channel of the PTME IP
|
||||
* Core.
|
||||
*
|
||||
* @param data Pointer to buffer holding the data to write
|
||||
* @param size Number of bytes to write
|
||||
*/
|
||||
virtual ReturnValue_t write(const uint8_t* data, size_t size) = 0;
|
||||
/**
|
||||
* @brief Implememts the functionality to write data in the virtual channel of the PTME IP
|
||||
* Core.
|
||||
*
|
||||
* @param data Pointer to buffer holding the data to write
|
||||
* @param size Number of bytes to write
|
||||
*/
|
||||
virtual ReturnValue_t write(const uint8_t* data, size_t size) = 0;
|
||||
|
||||
virtual void setRegisterAddress(uint32_t* ptmeBaseAddress) = 0;
|
||||
virtual void setRegisterAddress(uint32_t* ptmeBaseAddress) = 0;
|
||||
};
|
||||
|
||||
#endif /* LINUX_OBC_VCINTERFACEIF_H_ */
|
||||
|
@ -1,13 +1,14 @@
|
||||
#include "OBSWConfig.h"
|
||||
#include "FSFWConfig.h"
|
||||
#include "utility.h"
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include <cstring>
|
||||
|
||||
#include "FSFWConfig.h"
|
||||
#include "OBSWConfig.h"
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
void utility::handleSystemError(int retcode, std::string function) {
|
||||
#if OBSW_VERBOSE_LEVEL >= 1
|
||||
sif::warning << function << ": System call failed with code " << retcode << ": " <<
|
||||
strerror(retcode) << std::endl;
|
||||
sif::warning << function << ": System call failed with code " << retcode << ": "
|
||||
<< strerror(retcode) << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef LINUX_UTILITY_UTILITY_H_
|
||||
#define LINUX_UTILITY_UTILITY_H_
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
#include <string>
|
||||
|
||||
#include "fsfw/returnvalues/HasReturnvaluesIF.h"
|
||||
|
||||
namespace utility {
|
||||
|
||||
void handleSystemError(int retcode, std::string function);
|
||||
|
Reference in New Issue
Block a user