Compare commits
76 Commits
Author | SHA1 | Date | |
---|---|---|---|
6b671cfa65 | |||
3408624056 | |||
146767b04f | |||
f4951385fd | |||
f259face36 | |||
8482416ac5 | |||
a419589a7f | |||
ebcd0cdfa1 | |||
9960fc8ce7 | |||
353b9bd322 | |||
014ac8b8c2 | |||
cd8bbaf1f9 | |||
d98873c9a6 | |||
d5d43e8d44 | |||
55dd4b28ee | |||
f9ed42f8a5 | |||
e9fc0c453d | |||
ca44b541b1 | |||
2968856d71 | |||
e4530544c2 | |||
103800e40c | |||
aa78d744b4 | |||
54c29e893d | |||
b9d0e4bdd9 | |||
cdcadf3c18 | |||
a8d19b0ff9 | |||
5bdb7414bf | |||
77b8c6eb3e | |||
db669c44f6 | |||
bfb91f1baa | |||
3c33d01089 | |||
bd8389e0c9 | |||
58aef99bbc | |||
9020014245 | |||
e523c2fe25 | |||
3bd434bbc3 | |||
d8ec121131 | |||
3e54bc9c3f | |||
4ca45f348c | |||
34a0288987 | |||
f031c46cb5 | |||
dbf627cc12 | |||
b06db0a0fc | |||
0a68b50ad7 | |||
b11ed219a2 | |||
67082a6559 | |||
36d5f8fd31 | |||
cdba7985ea | |||
38b7593900 | |||
78cc0fc52d | |||
4ed112d019 | |||
7549a24f6f | |||
d53fdf9078 | |||
67988dad64 | |||
56c5838d15 | |||
2950876ce4 | |||
a875bf55b8 | |||
a28ba4ec66 | |||
c65b402361 | |||
f5e47c6114 | |||
600921e3a0 | |||
3c38410643 | |||
2e0a685507 | |||
0ade2ae0ee | |||
b050047d9a | |||
65c231e92d | |||
5e93282662 | |||
0cabe3a9ea | |||
845548ed25 | |||
858c6c301e | |||
9825a8583f | |||
babc4f80a8 | |||
3299260653 | |||
a0e531445a | |||
69bbe4ea39 | |||
a06d90daad |
46
CHANGELOG.md
46
CHANGELOG.md
@ -16,6 +16,52 @@ will consitute of a breaking change warranting a new major release:
|
||||
|
||||
# [unreleased]
|
||||
|
||||
# [v1.44.0] 2023-04-07
|
||||
|
||||
- eive-tmtc: v2.22.0
|
||||
|
||||
## Added
|
||||
|
||||
- Special I2C recovery handling. If the I2C bus is unavailable for whatever reason, the EIVE
|
||||
system component will power-cycle all I2C devices by first going to the OFF/BOOT mode, then
|
||||
power-cycling the 3V3 stack and rebooting the battery, and finally going back to safe mode.
|
||||
If this does not restore the bus, a full reboot will be performed. This special sequence can
|
||||
be commanded as well.
|
||||
|
||||
## Fixed
|
||||
|
||||
- RW Assembly: Correctly transition back to off when more than 1 devices is OFF. Also do this
|
||||
when this was due to two devices being marked faulty.
|
||||
- RW dummy and STR dummy components: Set/Update modes correctly.
|
||||
- RW handlers: Bugfix for TM set retrieval and special request handling in general where the CRC
|
||||
check always failed for special request. Also removed an unnecessary delay for special requests.
|
||||
- RW handlers: Polling is now disabled for RWs which are off.
|
||||
|
||||
## Changed
|
||||
|
||||
- RW shutdown now waits for the speed to be near 0 or for a OFF transition countdown to be expired
|
||||
before going to off.
|
||||
|
||||
# [v1.43.2] 2023-04-05
|
||||
|
||||
## Changed
|
||||
|
||||
- Adapted HK data rates to new table for LEOP SAFE mode.
|
||||
- GPS controller HK is now generated periodically as well.
|
||||
- Better mode combination checks for assembly components. This includes:
|
||||
- IMTQ assembly
|
||||
- Syrlinks assembly
|
||||
- Dual Lane Assembly
|
||||
- RWs are no longer commanded by the ACS Controller during safe mode. Instead the RW speed command
|
||||
is set to 0 as part or the `doShutDown` of the RW handler.
|
||||
|
||||
## Fixed
|
||||
|
||||
- Dual lane assemblies: Fix handling when health states are overwritten. Also add better handling
|
||||
when some devices are permanent faulty and some are only faulty. In that case, only the faulty
|
||||
devices will be restored.
|
||||
- ACS dual lane assembly: Gyro 3 helper mode was assigned to the Gyro 2 mode.
|
||||
|
||||
# [v1.43.1] 2023-04-04
|
||||
|
||||
## Fixed
|
||||
|
@ -10,8 +10,8 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(OBSW_VERSION_MAJOR 1)
|
||||
set(OBSW_VERSION_MINOR 43)
|
||||
set(OBSW_VERSION_REVISION 1)
|
||||
set(OBSW_VERSION_MINOR 44)
|
||||
set(OBSW_VERSION_REVISION 0)
|
||||
|
||||
# set(CMAKE_VERBOSE TRUE)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 284 translations.
|
||||
* @brief Auto-generated event translation file. Contains 285 translations.
|
||||
* @details
|
||||
* Generated on: 2023-04-04 13:59:07
|
||||
* Generated on: 2023-04-07 17:42:57
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -266,7 +266,8 @@ const char *VERSION_INFO_STRING = "VERSION_INFO";
|
||||
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
||||
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||
const char *I2C_UNAVAILABLE_REBOOT_STRING = "I2C_UNAVAILABLE_REBOOT";
|
||||
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
||||
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||
@ -815,7 +816,9 @@ const char *translateEvents(Event event) {
|
||||
case (14008):
|
||||
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
||||
case (14010):
|
||||
return I2C_UNAVAILABLE_REBOOT_STRING;
|
||||
return TRYING_I2C_RECOVERY_STRING;
|
||||
case (14011):
|
||||
return I2C_REBOOT_STRING;
|
||||
case (14100):
|
||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||
case (14101):
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 171 translations.
|
||||
* Generated on: 2023-04-04 13:59:07
|
||||
* Generated on: 2023-04-07 17:42:57
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
|
@ -252,7 +252,7 @@ ReturnValue_t openSpi(const std::string& devname, int flags, GpioIF* gpioIF, gpi
|
||||
fd = open(devname.c_str(), flags);
|
||||
if (fd < 0) {
|
||||
sif::error << "rwSpiCallback::spiCallback: Failed to open device file" << std::endl;
|
||||
return SpiComIF::OPENING_FILE_FAILED;
|
||||
return spi::OPENING_FILE_FAILED;
|
||||
}
|
||||
|
||||
// Pull SPI CS low. For now, no support for active high given
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
#include "fsfw/timemanager/Stopwatch.h"
|
||||
#include "fsfw/version.h"
|
||||
#include "mission/sysDefs.h"
|
||||
#include "watchdog/definitions.h"
|
||||
#if OBSW_ADD_TMTC_UDP_SERVER == 1
|
||||
#include "fsfw/osal/common/UdpTmTcBridge.h"
|
||||
@ -31,8 +32,7 @@
|
||||
xsc::Chip CoreController::CURRENT_CHIP = xsc::Chip::NO_CHIP;
|
||||
xsc::Copy CoreController::CURRENT_COPY = xsc::Copy::NO_COPY;
|
||||
|
||||
CoreController::CoreController(object_id_t objectId, const std::atomic_uint16_t &i2cErrors,
|
||||
bool enableHkSet)
|
||||
CoreController::CoreController(object_id_t objectId, bool enableHkSet)
|
||||
: ExtendedControllerBase(objectId, 5),
|
||||
enableHkSet(enableHkSet),
|
||||
cmdExecutor(4096),
|
||||
@ -40,8 +40,7 @@ CoreController::CoreController(object_id_t objectId, const std::atomic_uint16_t
|
||||
cmdRepliesSizes(128),
|
||||
opDivider5(5),
|
||||
opDivider10(10),
|
||||
hkSet(this),
|
||||
i2cErrors(i2cErrors) {
|
||||
hkSet(this) {
|
||||
cmdExecutor.setRingBuffer(&cmdReplyBuf, &cmdRepliesSizes);
|
||||
try {
|
||||
sdcMan = SdCardManager::instance();
|
||||
@ -110,17 +109,12 @@ void CoreController::performControlOperation() {
|
||||
sdStateMachine();
|
||||
performMountedSdCardOperations();
|
||||
readHkData();
|
||||
if (i2cErrors >= 5) {
|
||||
bool protOpPerformed = false;
|
||||
triggerEvent(I2C_UNAVAILABLE_REBOOT);
|
||||
gracefulShutdownTasks(CURRENT_CHIP, CURRENT_COPY, protOpPerformed);
|
||||
std::system("xsc_boot_copy -r");
|
||||
}
|
||||
|
||||
if (shellCmdIsExecuting) {
|
||||
bool replyReceived = false;
|
||||
// TODO: We could read the data in the ring buffer and send it as an action data reply.
|
||||
if (cmdExecutor.check(replyReceived) == CommandExecutor::EXECUTION_FINISHED) {
|
||||
actionHelper.finish(true, successRecipient, EXECUTE_SHELL_CMD);
|
||||
actionHelper.finish(true, successRecipient, core::EXECUTE_SHELL_CMD);
|
||||
shellCmdIsExecuting = false;
|
||||
cmdReplyBuf.clear();
|
||||
while (not cmdRepliesSizes.empty()) {
|
||||
@ -138,7 +132,7 @@ ReturnValue_t CoreController::initializeLocalDataPool(localpool::DataPool &local
|
||||
localDataPoolMap.emplace(core::TEMPERATURE, &tempPoolEntry);
|
||||
localDataPoolMap.emplace(core::PS_VOLTAGE, &psVoltageEntry);
|
||||
localDataPoolMap.emplace(core::PL_VOLTAGE, &plVoltageEntry);
|
||||
poolManager.subscribeForRegularPeriodicPacket({hkSet.getSid(), enableHkSet, 12.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({hkSet.getSid(), enableHkSet, 60.0});
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -163,7 +157,7 @@ ReturnValue_t CoreController::initialize() {
|
||||
|
||||
sdStateMachine();
|
||||
|
||||
triggerEvent(REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
|
||||
triggerEvent(core::REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
|
||||
EventManagerIF *eventManager =
|
||||
ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||
if (eventManager == nullptr or eventQueue == nullptr) {
|
||||
@ -202,6 +196,7 @@ ReturnValue_t CoreController::initializeAfterTaskCreation() {
|
||||
|
||||
ReturnValue_t CoreController::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t *data, size_t size) {
|
||||
using namespace core;
|
||||
switch (actionId) {
|
||||
case (ANNOUNCE_VERSION): {
|
||||
uint32_t p1 = (common::OBSW_VERSION_MAJOR << 24) | (common::OBSW_VERSION_MINOR << 16) |
|
||||
@ -1324,7 +1319,7 @@ ReturnValue_t CoreController::performSdCardCheck() {
|
||||
someSdCardActive = true;
|
||||
}
|
||||
if (not someSdCardActive and remountAttemptFlag) {
|
||||
triggerEvent(NO_SD_CARD_ACTIVE);
|
||||
triggerEvent(core::NO_SD_CARD_ACTIVE);
|
||||
initSdCardBlocking();
|
||||
remountAttemptFlag = false;
|
||||
}
|
||||
@ -1378,7 +1373,7 @@ void CoreController::performRebootFileHandling(bool recreateFile) {
|
||||
if (rebootFile.bootFlag) {
|
||||
// Trigger event to inform ground that a reboot was triggered
|
||||
uint32_t p1 = rebootFile.lastChip << 16 | rebootFile.lastCopy;
|
||||
triggerEvent(REBOOT_MECHANISM_TRIGGERED, p1, 0);
|
||||
triggerEvent(core::REBOOT_MECHANISM_TRIGGERED, p1, 0);
|
||||
// Clear the boot flag
|
||||
rebootFile.bootFlag = false;
|
||||
}
|
||||
@ -2047,8 +2042,9 @@ void CoreController::announceBootCounts() {
|
||||
rebootFile.img00Cnt + rebootFile.img01Cnt + rebootFile.img10Cnt + rebootFile.img11Cnt;
|
||||
uint32_t individualBootCountsP1 = (rebootFile.img00Cnt << 16) | rebootFile.img01Cnt;
|
||||
uint32_t individualBootCountsP2 = (rebootFile.img10Cnt << 16) | rebootFile.img11Cnt;
|
||||
triggerEvent(INDIVIDUAL_BOOT_COUNTS, individualBootCountsP1, individualBootCountsP2);
|
||||
triggerEvent(REBOOT_COUNTER, (totalBootCount >> 32) & 0xffffffff, totalBootCount & 0xffffffff);
|
||||
triggerEvent(core::INDIVIDUAL_BOOT_COUNTS, individualBootCountsP1, individualBootCountsP2);
|
||||
triggerEvent(core::REBOOT_COUNTER, (totalBootCount >> 32) & 0xffffffff,
|
||||
totalBootCount & 0xffffffff);
|
||||
}
|
||||
|
||||
bool CoreController::isNumber(const std::string &s) {
|
||||
|
@ -78,64 +78,7 @@ class CoreController : public ExtendedControllerBase {
|
||||
static constexpr dur_millis_t INIT_SD_CARD_CHECK_TIMEOUT = 5000;
|
||||
static constexpr dur_millis_t DEFAULT_SD_CARD_CHECK_TIMEOUT = 60000;
|
||||
|
||||
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
||||
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
|
||||
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
|
||||
static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3;
|
||||
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
|
||||
static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6;
|
||||
static constexpr ActionId_t SWITCH_IMG_LOCK = 7;
|
||||
static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8;
|
||||
|
||||
static constexpr ActionId_t OBSW_UPDATE_FROM_SD_0 = 10;
|
||||
static constexpr ActionId_t OBSW_UPDATE_FROM_SD_1 = 11;
|
||||
static constexpr ActionId_t OBSW_UPDATE_FROM_TMP = 12;
|
||||
|
||||
static constexpr ActionId_t SWITCH_TO_SD_0 = 16;
|
||||
static constexpr ActionId_t SWITCH_TO_SD_1 = 17;
|
||||
static constexpr ActionId_t SWITCH_TO_BOTH_SD_CARDS = 18;
|
||||
|
||||
//! Reboot using the xsc_boot_copy command
|
||||
static constexpr ActionId_t XSC_REBOOT_OBC = 32;
|
||||
static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
|
||||
//! Reboot using the reboot command
|
||||
static constexpr ActionId_t REBOOT_OBC = 34;
|
||||
|
||||
static constexpr ActionId_t EXECUTE_SHELL_CMD = 40;
|
||||
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
||||
|
||||
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||
//! [EXPORT] : [COMMENT] Software reboot occurred. Can also be a systemd reboot.
|
||||
//! P1: Current Chip, P2: Current Copy
|
||||
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] The reboot mechanism was triggered.
|
||||
//! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy,
|
||||
//! P2: Each byte is the respective reboot count for the slots
|
||||
static constexpr Event REBOOT_MECHANISM_TRIGGERED =
|
||||
event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM);
|
||||
//! Trying to find a way how to determine that the reboot came from ProASIC3 or PCDU..
|
||||
static constexpr Event REBOOT_HW = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM);
|
||||
//! [EXPORT] : [COMMENT] No SD card was active. Core controller will attempt to re-initialize
|
||||
//! a SD card.
|
||||
static constexpr Event NO_SD_CARD_ACTIVE = event::makeEvent(SUBSYSTEM_ID, 4, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT]
|
||||
//! P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash
|
||||
//! P2: First four letters of Git SHA is the last byte of P1 is set.
|
||||
static constexpr Event VERSION_INFO = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] P1: Current Chip, P2: Current Copy
|
||||
static constexpr Event CURRENT_IMAGE_INFO = event::makeEvent(SUBSYSTEM_ID, 6, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Total reboot counter, which is the sum of the boot count of all
|
||||
//! individual images.
|
||||
static constexpr Event REBOOT_COUNTER = event::makeEvent(SUBSYSTEM_ID, 7, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Get the boot count of the individual images.
|
||||
//! P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1.
|
||||
//! P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.
|
||||
static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
|
||||
static constexpr Event I2C_UNAVAILABLE_REBOOT =
|
||||
event::makeEvent(SUBSYSTEM_ID, 10, severity::MEDIUM);
|
||||
|
||||
CoreController(object_id_t objectId, const std::atomic_uint16_t& i2cErrors, bool enableHkSet);
|
||||
CoreController(object_id_t objectId, bool enableHkSet);
|
||||
virtual ~CoreController();
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
@ -266,7 +209,6 @@ class CoreController : public ExtendedControllerBase {
|
||||
PoolEntry<float> plVoltageEntry = PoolEntry<float>(0.0);
|
||||
|
||||
core::HkSet hkSet;
|
||||
const std::atomic_uint16_t& i2cErrors;
|
||||
|
||||
#if OBSW_SD_CARD_MUST_BE_ON == 1
|
||||
bool remountAttemptFlag = true;
|
||||
|
@ -360,7 +360,8 @@ void ObjectFactory::createAcsBoardGpios(GpioCookie& cookie) {
|
||||
}
|
||||
|
||||
void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF,
|
||||
SerialComIF* uartComIF, PowerSwitchIF& pwrSwitcher) {
|
||||
SerialComIF* uartComIF, PowerSwitchIF& pwrSwitcher,
|
||||
bool enableHkSets) {
|
||||
using namespace gpio;
|
||||
GpioCookie* gpioCookieAcsBoard = new GpioCookie();
|
||||
createAcsBoardGpios(*gpioCookieAcsBoard);
|
||||
@ -514,8 +515,8 @@ void ObjectFactory::createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF*
|
||||
#endif
|
||||
RESET_ARGS_GNSS.gpioComIF = gpioComIF;
|
||||
RESET_ARGS_GNSS.waitPeriodMs = 100;
|
||||
auto gpsCtrl =
|
||||
new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT, debugGps);
|
||||
auto gpsCtrl = new GpsHyperionLinuxController(objects::GPS_CONTROLLER, objects::NO_OBJECT,
|
||||
enableHkSets, debugGps);
|
||||
gpsCtrl->setResetPinTriggerFunction(gps::triggerGpioResetPin, &RESET_ARGS_GNSS);
|
||||
|
||||
ObjectFactory::createAcsBoardAssy(pwrSwitcher, assemblyChildren, gpsCtrl, gpioComIF);
|
||||
|
@ -23,7 +23,6 @@ class HealthTableIF;
|
||||
class AcsBoardAssembly;
|
||||
class GpioIF;
|
||||
|
||||
extern std::atomic_uint16_t I2C_FATAL_ERRORS;
|
||||
extern std::atomic_bool PTME_LOCKED;
|
||||
|
||||
namespace ObjectFactory {
|
||||
@ -62,7 +61,7 @@ void createTmpComponents();
|
||||
ReturnValue_t createRadSensorComponent(LinuxLibgpioIF* gpioComIF, Stack5VHandler& handler);
|
||||
void createAcsBoardGpios(GpioCookie& cookie);
|
||||
void createAcsBoardComponents(SpiComIF& spiComIF, LinuxLibgpioIF* gpioComIF, SerialComIF* uartComIF,
|
||||
PowerSwitchIF& pwrSwitcher);
|
||||
PowerSwitchIF& pwrSwitcher, bool enableHkSets);
|
||||
void createHeaterComponents(GpioIF* gpioIF, PowerSwitchIF* pwrSwitcher, HealthTableIF* healthTable,
|
||||
HeaterHandler*& heaterHandler);
|
||||
void createImtqComponents(PowerSwitchIF* pwrSwitcher, bool enableHkSets);
|
||||
|
@ -237,7 +237,7 @@ void scheduling::initTasks() {
|
||||
|
||||
#if OBSW_ADD_RW == 1
|
||||
PeriodicTaskIF* rwPolling =
|
||||
factory->createPeriodicTask("RW_POLLING_TASK", 80, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2,
|
||||
factory->createPeriodicTask("RW_POLLING_TASK", 75, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2,
|
||||
0.4, missedDeadlineFunc, &RR_SCHEDULING);
|
||||
result = rwPolling->addComponent(objects::RW_POLLING_TASK);
|
||||
if (result != returnvalue::OK) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <fsfw/power/DummyPowerSwitcher.h>
|
||||
#include <fsfw_hal/common/gpio/GpioCookie.h>
|
||||
#include <mission/power/gsDefs.h>
|
||||
#include <mission/system/tree/system.h>
|
||||
#include <mission/system/systemTree.h>
|
||||
#include <mission/utility/DummySdCardManager.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
@ -71,7 +71,7 @@ void ObjectFactory::produce(void* args) {
|
||||
|
||||
dummy::createDummies(dummyCfg, *pwrSwitcher, gpioComIF);
|
||||
|
||||
new CoreController(objects::CORE_CONTROLLER, I2C_FATAL_ERRORS, enableHkSets);
|
||||
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
||||
|
||||
// Regular FM code, does not work for EM if the hardware is not connected
|
||||
// createPcduComponents(gpioComIF, &pwrSwitcher);
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <fsfw/storagemanager/LocalPool.h>
|
||||
#include <fsfw/storagemanager/PoolManager.h>
|
||||
#include <mission/power/gsDefs.h>
|
||||
#include <mission/system/EiveSystem.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
#include "bsp_q7s/core/CoreController.h"
|
||||
@ -13,7 +14,7 @@
|
||||
#include "linux/ObjectFactory.h"
|
||||
#include "linux/callbacks/gpioCallbacks.h"
|
||||
#include "mission/genericFactory.h"
|
||||
#include "mission/system/tree/system.h"
|
||||
#include "mission/system/systemTree.h"
|
||||
#include "mission/tmtc/tmFilters.h"
|
||||
|
||||
void ObjectFactory::produce(void* args) {
|
||||
@ -43,8 +44,10 @@ void ObjectFactory::produce(void* args) {
|
||||
q7s::gpioCallbacks::initSpiCsDecoder(gpioComIF);
|
||||
gpioCallbacks::disableAllDecoder(gpioComIF);
|
||||
|
||||
new CoreController(objects::CORE_CONTROLLER, I2C_FATAL_ERRORS, enableHkSets);
|
||||
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
||||
createPcduComponents(gpioComIF, &pwrSwitcher, enableHkSets);
|
||||
satsystem::EIVE_SYSTEM.setI2cRecoveryParams(pwrSwitcher);
|
||||
|
||||
auto* stackHandler = new Stack5VHandler(*pwrSwitcher);
|
||||
|
||||
#if OBSW_ADD_RAD_SENSORS == 1
|
||||
@ -55,7 +58,7 @@ void ObjectFactory::produce(void* args) {
|
||||
#endif
|
||||
|
||||
#if OBSW_ADD_ACS_BOARD == 1
|
||||
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher);
|
||||
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher, true);
|
||||
#endif
|
||||
HeaterHandler* heaterHandler;
|
||||
createHeaterComponents(gpioComIF, pwrSwitcher, healthTable, heaterHandler);
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "fsfw/version.h"
|
||||
#include "mission/acs/defs.h"
|
||||
#include "mission/com/defs.h"
|
||||
#include "mission/system/tree/system.h"
|
||||
#include "mission/system/systemTree.h"
|
||||
#include "q7sConfig.h"
|
||||
#include "watchdog/definitions.h"
|
||||
|
||||
|
@ -37,19 +37,19 @@ uint32_t BpxDummy::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return
|
||||
|
||||
ReturnValue_t BpxDummy::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_1, &battTemp1);
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_2, &battTemp2);
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_3, &battTemp3);
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_4, &battTemp4);
|
||||
localDataPoolMap.emplace(BpxBattery::CHARGE_CURRENT, &chargeCurrent);
|
||||
localDataPoolMap.emplace(BpxBattery::DISCHARGE_CURRENT, &dischargeCurrent);
|
||||
localDataPoolMap.emplace(BpxBattery::HEATER_CURRENT, &heaterCurrent);
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_VOLTAGE, &battVolt);
|
||||
localDataPoolMap.emplace(BpxBattery::REBOOT_COUNTER, &rebootCounter);
|
||||
localDataPoolMap.emplace(BpxBattery::BOOTCAUSE, &bootCause);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_TEMP_1, &battTemp1);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_TEMP_2, &battTemp2);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_TEMP_3, &battTemp3);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_TEMP_4, &battTemp4);
|
||||
localDataPoolMap.emplace(bpxBat::CHARGE_CURRENT, &chargeCurrent);
|
||||
localDataPoolMap.emplace(bpxBat::DISCHARGE_CURRENT, &dischargeCurrent);
|
||||
localDataPoolMap.emplace(bpxBat::HEATER_CURRENT, &heaterCurrent);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_VOLTAGE, &battVolt);
|
||||
localDataPoolMap.emplace(bpxBat::REBOOT_COUNTER, &rebootCounter);
|
||||
localDataPoolMap.emplace(bpxBat::BOOTCAUSE, &bootCause);
|
||||
|
||||
localDataPoolMap.emplace(BpxBattery::BATTERY_HEATER_MODE, &battheatMode);
|
||||
localDataPoolMap.emplace(BpxBattery::BATTHEAT_LOW_LIMIT, &battheatLow);
|
||||
localDataPoolMap.emplace(BpxBattery::BATTHEAT_HIGH_LIMIT, &battheatHigh);
|
||||
localDataPoolMap.emplace(bpxBat::BATTERY_HEATER_MODE, &battheatMode);
|
||||
localDataPoolMap.emplace(bpxBat::BATTHEAT_LOW_LIMIT, &battheatLow);
|
||||
localDataPoolMap.emplace(bpxBat::BATTHEAT_HIGH_LIMIT, &battheatHigh);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -7,9 +7,9 @@ RwDummy::RwDummy(object_id_t objectId, object_id_t comif, CookieIF *comCookie)
|
||||
|
||||
RwDummy::~RwDummy() {}
|
||||
|
||||
void RwDummy::doStartUp() {}
|
||||
void RwDummy::doStartUp() { setMode(MODE_ON); }
|
||||
|
||||
void RwDummy::doShutDown() {}
|
||||
void RwDummy::doShutDown() { setMode(MODE_OFF); }
|
||||
|
||||
ReturnValue_t RwDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) { return NOTHING_TO_SEND; }
|
||||
|
||||
|
@ -7,9 +7,9 @@ StarTrackerDummy::StarTrackerDummy(object_id_t objectId, object_id_t comif, Cook
|
||||
|
||||
StarTrackerDummy::~StarTrackerDummy() {}
|
||||
|
||||
void StarTrackerDummy::doStartUp() {}
|
||||
void StarTrackerDummy::doStartUp() { setMode(MODE_ON); }
|
||||
|
||||
void StarTrackerDummy::doShutDown() {}
|
||||
void StarTrackerDummy::doShutDown() { setMode(_MODE_POWER_DOWN); }
|
||||
|
||||
ReturnValue_t StarTrackerDummy::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||
return NOTHING_TO_SEND;
|
||||
|
2
fsfw
2
fsfw
Submodule fsfw updated: 6650c293da...285d327b97
@ -101,8 +101,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11401;0x2c89;GPIO_PULL_LOW_FAILED;LOW;No description;mission/tcs/HeaterHandler.h
|
||||
11402;0x2c8a;HEATER_WENT_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
||||
11403;0x2c8b;HEATER_WENT_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
||||
11404;0x2c8c;SWITCH_ALREADY_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
||||
11405;0x2c8d;SWITCH_ALREADY_OFF;LOW;No description;mission/tcs/HeaterHandler.h
|
||||
11404;0x2c8c;SWITCH_ALREADY_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
||||
11405;0x2c8d;SWITCH_ALREADY_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
||||
11406;0x2c8e;MAIN_SWITCH_TIMEOUT;MEDIUM;No description;mission/tcs/HeaterHandler.h
|
||||
11407;0x2c8f;FAULTY_HEATER_WAS_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
||||
11500;0x2cec;BURN_PHASE_START;INFO;P1: Burn duration in milliseconds, P2: Dry run flag;mission/SolarArrayDeploymentHandler.h
|
||||
@ -251,16 +251,17 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h
|
||||
14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h
|
||||
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h
|
||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h
|
||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h
|
||||
14010;0x36ba;I2C_UNAVAILABLE_REBOOT;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;mission/sysDefs.h
|
||||
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;mission/sysDefs.h
|
||||
14003;0x36b3;REBOOT_HW;MEDIUM;No description;mission/sysDefs.h
|
||||
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;mission/sysDefs.h
|
||||
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;mission/sysDefs.h
|
||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
|
||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
|
||||
14010;0x36ba;TRYING_I2C_RECOVERY;MEDIUM;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
|
||||
14011;0x36bb;I2C_REBOOT;MEDIUM;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
|
||||
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||
|
|
@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||
0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||
0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||
0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
|
||||
0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
|
||||
0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
|
||||
0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
|
||||
0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
@ -402,9 +402,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||
0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||
0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
||||
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
||||
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
||||
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4503;HSPI_Timeout;No description;3;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4504;HSPI_Busy;No description;4;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4505;HSPI_GenericError;No description;5;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||
0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||
0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||
|
|
@ -101,8 +101,8 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
11401;0x2c89;GPIO_PULL_LOW_FAILED;LOW;No description;mission/tcs/HeaterHandler.h
|
||||
11402;0x2c8a;HEATER_WENT_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
||||
11403;0x2c8b;HEATER_WENT_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
||||
11404;0x2c8c;SWITCH_ALREADY_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
||||
11405;0x2c8d;SWITCH_ALREADY_OFF;LOW;No description;mission/tcs/HeaterHandler.h
|
||||
11404;0x2c8c;SWITCH_ALREADY_ON;INFO;No description;mission/tcs/HeaterHandler.h
|
||||
11405;0x2c8d;SWITCH_ALREADY_OFF;INFO;No description;mission/tcs/HeaterHandler.h
|
||||
11406;0x2c8e;MAIN_SWITCH_TIMEOUT;MEDIUM;No description;mission/tcs/HeaterHandler.h
|
||||
11407;0x2c8f;FAULTY_HEATER_WAS_ON;LOW;No description;mission/tcs/HeaterHandler.h
|
||||
11500;0x2cec;BURN_PHASE_START;INFO;P1: Burn duration in milliseconds, P2: Dry run flag;mission/SolarArrayDeploymentHandler.h
|
||||
@ -251,16 +251,17 @@ Event ID (dec); Event ID (hex); Name; Severity; Description; File Path
|
||||
13903;0x364f;INSERT_CONFIGFILEVALUE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13904;0x3650;WRITE_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
13905;0x3651;READ_CONFIGFILE_FAILED;MEDIUM;No description;mission/utility/GlobalConfigHandler.h
|
||||
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;bsp_q7s/core/CoreController.h
|
||||
14003;0x36b3;REBOOT_HW;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;bsp_q7s/core/CoreController.h
|
||||
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;bsp_q7s/core/CoreController.h
|
||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;bsp_q7s/core/CoreController.h
|
||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;bsp_q7s/core/CoreController.h
|
||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;bsp_q7s/core/CoreController.h
|
||||
14010;0x36ba;I2C_UNAVAILABLE_REBOOT;MEDIUM;No description;bsp_q7s/core/CoreController.h
|
||||
14000;0x36b0;ALLOC_FAILURE;MEDIUM;No description;mission/sysDefs.h
|
||||
14001;0x36b1;REBOOT_SW;LOW; Software reboot occurred. Can also be a systemd reboot. P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||
14002;0x36b2;REBOOT_MECHANISM_TRIGGERED;MEDIUM;The reboot mechanism was triggered. P1: First 16 bits: Last Chip, Last 16 bits: Last Copy, P2: Each byte is the respective reboot count for the slots;mission/sysDefs.h
|
||||
14003;0x36b3;REBOOT_HW;MEDIUM;No description;mission/sysDefs.h
|
||||
14004;0x36b4;NO_SD_CARD_ACTIVE;HIGH;No SD card was active. Core controller will attempt to re-initialize a SD card.;mission/sysDefs.h
|
||||
14005;0x36b5;VERSION_INFO;INFO;P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash P2: First four letters of Git SHA is the last byte of P1 is set.;mission/sysDefs.h
|
||||
14006;0x36b6;CURRENT_IMAGE_INFO;INFO;P1: Current Chip, P2: Current Copy;mission/sysDefs.h
|
||||
14007;0x36b7;REBOOT_COUNTER;INFO;Total reboot counter, which is the sum of the boot count of all individual images.;mission/sysDefs.h
|
||||
14008;0x36b8;INDIVIDUAL_BOOT_COUNTS;INFO;Get the boot count of the individual images. P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1. P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.;mission/sysDefs.h
|
||||
14010;0x36ba;TRYING_I2C_RECOVERY;MEDIUM;I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C devices.;mission/sysDefs.h
|
||||
14011;0x36bb;I2C_REBOOT;MEDIUM;I2C is unavailable. Recovery did not work, performing full reboot.;mission/sysDefs.h
|
||||
14100;0x3714;NO_VALID_SENSOR_TEMPERATURE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||
14101;0x3715;NO_HEALTHY_HEATER_AVAILABLE;MEDIUM;No description;mission/controller/tcsDefs.h
|
||||
14102;0x3716;SYRLINKS_OVERHEATING;HIGH;No description;mission/controller/tcsDefs.h
|
||||
|
|
@ -371,8 +371,8 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x3e03;HKM_PeriodicHelperInvalid;No description;3;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||
0x3e04;HKM_PoolobjectNotFound;No description;4;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||
0x3e05;HKM_DatasetNotFound;No description;5;HOUSEKEEPING_MANAGER;fsfw/src/fsfw/datapoollocal/LocalDataPoolManager.h
|
||||
0x3f01;DLEE_NoPacketFound;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
|
||||
0x3f02;DLEE_PossiblePacketLoss;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleParser.h
|
||||
0x3f01;DLEE_StreamTooShort;No description;1;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
|
||||
0x3f02;DLEE_DecodingError;No description;2;DLE_ENCODER;fsfw/src/fsfw/globalfunctions/DleEncoder.h
|
||||
0x4201;PUS11_InvalidTypeTimeWindow;No description;1;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4202;PUS11_InvalidTimeWindow;No description;2;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
0x4203;PUS11_TimeshiftingNotPossible;No description;3;PUS_SERVICE_11;fsfw/src/fsfw/pus/Service11TelecommandScheduling.h
|
||||
@ -402,9 +402,12 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x4403;UXOS_CommandError;Command execution failed;3;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||
0x4404;UXOS_NoCommandLoadedOrPending;;4;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||
0x4406;UXOS_PcloseCallError;No description;6;LINUX_OSAL;fsfw/src/fsfw_hal/linux/CommandExecutor.h
|
||||
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
||||
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
||||
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/linux/spi/SpiComIF.h
|
||||
0x4500;HSPI_OpeningFileFailed;No description;0;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4501;HSPI_FullDuplexTransferFailed;No description;1;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4502;HSPI_HalfDuplexTransferFailed;No description;2;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4503;HSPI_Timeout;No description;3;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4504;HSPI_Busy;No description;4;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4505;HSPI_GenericError;No description;5;HAL_SPI;fsfw/src/fsfw_hal/common/spi/spiCommon.h
|
||||
0x4601;HURT_UartReadFailure;No description;1;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||
0x4602;HURT_UartReadSizeMissmatch;No description;2;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||
0x4603;HURT_UartRxBufferTooSmall;No description;3;HAL_UART;fsfw/src/fsfw_hal/linux/serial/SerialComIF.h
|
||||
@ -493,8 +496,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x58a3;SUSS_ExecutionFailed;Command execution failed;163;SUS_HANDLER;mission/acs/RwHandler.h
|
||||
0x58a4;SUSS_CrcError;Reaction wheel reply has invalid crc;164;SUS_HANDLER;mission/acs/RwHandler.h
|
||||
0x58a5;SUSS_ValueNotRead;No description;165;SUS_HANDLER;mission/acs/RwHandler.h
|
||||
0x5900;IPCI_NoReplyAvailable;No description;0;CCSDS_IP_CORE_BRIDGE;linux/acs/ImtqPollingTask.h
|
||||
0x5901;IPCI_NoPacketFound;No description;1;CCSDS_IP_CORE_BRIDGE;linux/com/SyrlinksComHandler.h
|
||||
0x59a0;IPCI_PapbBusy;No description;160;CCSDS_IP_CORE_BRIDGE;linux/ipcore/PapbVcInterface.h
|
||||
0x5aa0;PTME_UnknownVcId;No description;160;PTME;linux/ipcore/Ptme.h
|
||||
0x5c01;STRHLP_SdNotMounted;SD card specified in path string not mounted;1;STR_HELPER;linux/acs/StrComHandler.h
|
||||
@ -542,7 +543,6 @@ Full ID (hex); Name; Description; Unique ID; Subsytem Name; File Path
|
||||
0x63a0;NVMB_KeyNotExists;Specified key does not exist in json file;160;NVM_PARAM_BASE;mission/memory/NvmParameterBase.h
|
||||
0x64a0;FSHLP_SdNotMounted;SD card specified with path string not mounted;160;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
||||
0x64a1;FSHLP_FileNotExists;Specified file does not exist on filesystem;161;FILE_SYSTEM_HELPER;bsp_q7s/fs/FilesystemHelper.h
|
||||
0x6502;PLMPHLP_InvalidCrc;No description;2;PLOC_MPSOC_HELPER;linux/payload/ScexHelper.h
|
||||
0x65a0;PLMPHLP_FileClosedAccidentally;File accidentally close;160;PLOC_MPSOC_HELPER;linux/payload/PlocMpsocHelper.h
|
||||
0x66a0;SADPL_CommandNotSupported;No description;160;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||
0x66a1;SADPL_DeploymentAlreadyExecuting;No description;161;SA_DEPL_HANDLER;mission/SolarArrayDeploymentHandler.h
|
||||
|
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 284 translations.
|
||||
* @brief Auto-generated event translation file. Contains 285 translations.
|
||||
* @details
|
||||
* Generated on: 2023-04-04 13:59:07
|
||||
* Generated on: 2023-04-07 17:42:57
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -266,7 +266,8 @@ const char *VERSION_INFO_STRING = "VERSION_INFO";
|
||||
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
||||
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||
const char *I2C_UNAVAILABLE_REBOOT_STRING = "I2C_UNAVAILABLE_REBOOT";
|
||||
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
||||
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||
@ -815,7 +816,9 @@ const char *translateEvents(Event event) {
|
||||
case (14008):
|
||||
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
||||
case (14010):
|
||||
return I2C_UNAVAILABLE_REBOOT_STRING;
|
||||
return TRYING_I2C_RECOVERY_STRING;
|
||||
case (14011):
|
||||
return I2C_REBOOT_STRING;
|
||||
case (14100):
|
||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||
case (14101):
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 175 translations.
|
||||
* Generated on: 2023-04-04 13:59:07
|
||||
* Generated on: 2023-04-07 17:42:57
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
|
@ -373,7 +373,7 @@ ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen
|
||||
std::string device = spiComIF.getSpiDev();
|
||||
UnixFileGuard fileHelper(device, fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return SpiComIF::OPENING_FILE_FAILED;
|
||||
return spi::OPENING_FILE_FAILED;
|
||||
}
|
||||
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||
uint32_t spiSpeed = 0;
|
||||
@ -416,7 +416,7 @@ ReturnValue_t AcsBoardPolling::readAdisCfg(SpiCookie& cookie, size_t transferLen
|
||||
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie.getTransferStructHandle());
|
||||
if (retval < 0) {
|
||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||
result = SpiComIF::FULL_DUPLEX_TRANSFER_FAILED;
|
||||
result = spi::FULL_DUPLEX_TRANSFER_FAILED;
|
||||
}
|
||||
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||
comIf->performSpiWiretapping(cookie);
|
||||
|
@ -18,8 +18,11 @@
|
||||
#include <ctime>
|
||||
|
||||
GpsHyperionLinuxController::GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId,
|
||||
bool debugHyperionGps)
|
||||
: ExtendedControllerBase(objectId), gpsSet(this), debugHyperionGps(debugHyperionGps) {}
|
||||
bool enableHkSets, bool debugHyperionGps)
|
||||
: ExtendedControllerBase(objectId),
|
||||
gpsSet(this),
|
||||
enableHkSets(enableHkSets),
|
||||
debugHyperionGps(debugHyperionGps) {}
|
||||
|
||||
GpsHyperionLinuxController::~GpsHyperionLinuxController() {
|
||||
gps_stream(&gps, WATCH_DISABLE, nullptr);
|
||||
@ -86,7 +89,7 @@ ReturnValue_t GpsHyperionLinuxController::initializeLocalDataPool(
|
||||
localDataPoolMap.emplace(GpsHyperion::SATS_IN_USE, new PoolEntry<uint8_t>());
|
||||
localDataPoolMap.emplace(GpsHyperion::SATS_IN_VIEW, new PoolEntry<uint8_t>());
|
||||
localDataPoolMap.emplace(GpsHyperion::FIX_MODE, new PoolEntry<uint8_t>());
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), false, 30.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsSet.getSid(), enableHkSets, 30.0});
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
|
||||
|
||||
enum ReadModes { SHM = 0, SOCKET = 1 };
|
||||
|
||||
GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId,
|
||||
GpsHyperionLinuxController(object_id_t objectId, object_id_t parentId, bool enableHkSets,
|
||||
bool debugHyperionGps = false);
|
||||
virtual ~GpsHyperionLinuxController();
|
||||
|
||||
@ -58,6 +58,7 @@ class GpsHyperionLinuxController : public ExtendedControllerBase {
|
||||
private:
|
||||
GpsPrimaryDataset gpsSet;
|
||||
gps_data_t gps = {};
|
||||
bool enableHkSets = false;
|
||||
const char* currentClientBuf = nullptr;
|
||||
ReadModes readMode = ReadModes::SOCKET;
|
||||
Countdown maxTimeToReachFix = Countdown(MAX_SECONDS_TO_REACH_FIX * 1000);
|
||||
|
@ -22,6 +22,7 @@ class ImtqPollingTask : public SystemObject,
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
private:
|
||||
//! [EXPORT] : [SKIP]
|
||||
static constexpr ReturnValue_t NO_REPLY_AVAILABLE = returnvalue::makeCode(2, 0);
|
||||
|
||||
enum class InternalState { IDLE, IS_BUSY } state = InternalState::IDLE;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "devConf.h"
|
||||
#include "mission/acs/defs.h"
|
||||
#include "mission/acs/rwHelpers.h"
|
||||
|
||||
RwPollingTask::RwPollingTask(object_id_t objectId, const char* spiDev, GpioIF& gpioIF)
|
||||
@ -35,6 +36,7 @@ ReturnValue_t RwPollingTask::performOperation(uint8_t operationCode) {
|
||||
semaphore->acquire();
|
||||
// This loop takes 50 ms on a debug build.
|
||||
// Stopwatch watch;
|
||||
// Give all device handlers some time to submit requests.
|
||||
TaskFactory::delayTask(5);
|
||||
int fd = 0;
|
||||
for (auto& skip : skipCommandingForRw) {
|
||||
@ -45,13 +47,24 @@ ReturnValue_t RwPollingTask::performOperation(uint8_t operationCode) {
|
||||
if (result != returnvalue::OK) {
|
||||
continue;
|
||||
}
|
||||
acs::SimpleSensorMode currentMode;
|
||||
rws::SpecialRwRequest specialRequest;
|
||||
|
||||
for (unsigned idx = 0; idx < rwCookies.size(); idx++) {
|
||||
if (rwCookies[idx]->specialRequest == rws::SpecialRwRequest::RESET_MCU) {
|
||||
{
|
||||
MutexGuard mg(ipcLock);
|
||||
currentMode = rwRequests[idx].mode;
|
||||
specialRequest = rwRequests[idx].specialRequest;
|
||||
skipSetSpeedReply[idx] = rwRequests[idx].setSpeed;
|
||||
}
|
||||
if (currentMode == acs::SimpleSensorMode::OFF) {
|
||||
skipCommandingForRw[idx] = true;
|
||||
} else if (specialRequest == rws::SpecialRwRequest::RESET_MCU) {
|
||||
prepareSimpleCommand(rws::RESET_MCU);
|
||||
// No point in commanding that specific RW for the cycle.
|
||||
skipCommandingForRw[idx] = true;
|
||||
writeOneRwCmd(idx, fd);
|
||||
} else if (rwCookies[idx]->setSpeed) {
|
||||
} else if (skipSetSpeedReply[idx]) {
|
||||
prepareSetSpeedCmd(idx);
|
||||
if (writeOneRwCmd(idx, fd) != returnvalue::OK) {
|
||||
continue;
|
||||
@ -121,31 +134,14 @@ ReturnValue_t RwPollingTask::initializeInterface(CookieIF* cookie) {
|
||||
|
||||
ReturnValue_t RwPollingTask::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
||||
size_t sendLen) {
|
||||
if (sendData == nullptr or sendLen < 8) {
|
||||
if (sendData == nullptr or sendLen != sizeof(rws::RwRequest)) {
|
||||
return DeviceHandlerIF::INVALID_DATA;
|
||||
}
|
||||
int32_t speed = 0;
|
||||
uint16_t rampTime = 0;
|
||||
const uint8_t* currentBuf = sendData;
|
||||
bool setSpeed = currentBuf[0];
|
||||
currentBuf += 1;
|
||||
sendLen -= 1;
|
||||
SerializeAdapter::deSerialize(&speed, ¤tBuf, &sendLen, SerializeIF::Endianness::MACHINE);
|
||||
SerializeAdapter::deSerialize(&rampTime, ¤tBuf, &sendLen, SerializeIF::Endianness::MACHINE);
|
||||
rws::SpecialRwRequest specialRequest = rws::SpecialRwRequest::REQUEST_NONE;
|
||||
if (sendLen == 8 and sendData[7] < static_cast<uint8_t>(rws::SpecialRwRequest::NUM_REQUESTS)) {
|
||||
specialRequest = static_cast<rws::SpecialRwRequest>(sendData[7]);
|
||||
}
|
||||
RwCookie* rwCookie = dynamic_cast<RwCookie*>(cookie);
|
||||
if (rwCookie == nullptr) {
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
const rws::RwRequest* rwRequest = reinterpret_cast<const rws::RwRequest*>(sendData);
|
||||
uint8_t rwIdx = rwRequest->rwIdx;
|
||||
{
|
||||
MutexGuard mg(ipcLock);
|
||||
rwCookie->setSpeed = setSpeed;
|
||||
rwCookie->currentRwSpeed = speed;
|
||||
rwCookie->currentRampTime = rampTime;
|
||||
rwCookie->specialRequest = specialRequest;
|
||||
std::memcpy(&rwRequests[rwIdx], rwRequest, sizeof(rws::RwRequest));
|
||||
if (state == InternalState::IDLE) {
|
||||
state = InternalState::IS_BUSY;
|
||||
semaphore->release();
|
||||
@ -202,7 +198,7 @@ ReturnValue_t RwPollingTask::openSpi(int flags, int& fd) {
|
||||
fd = open(spiDev, flags);
|
||||
if (fd < 0) {
|
||||
sif::error << "RwPollingTask::openSpi: Failed to open device file" << std::endl;
|
||||
return SpiComIF::OPENING_FILE_FAILED;
|
||||
return spi::OPENING_FILE_FAILED;
|
||||
}
|
||||
|
||||
return returnvalue::OK;
|
||||
@ -332,7 +328,7 @@ ReturnValue_t RwPollingTask::writeOneRwCmd(uint8_t rwIdx, int fd) {
|
||||
ReturnValue_t RwPollingTask::readAllRws(DeviceCommandId_t id) {
|
||||
// SPI dev will be opened in readNextReply on demand.
|
||||
for (unsigned idx = 0; idx < rwCookies.size(); idx++) {
|
||||
if (((id == rws::SET_SPEED) and !rwCookies[idx]->setSpeed) or skipCommandingForRw[idx]) {
|
||||
if (((id == rws::SET_SPEED) and !skipSetSpeedReply[idx]) or skipCommandingForRw[idx]) {
|
||||
continue;
|
||||
}
|
||||
uint8_t* replyBuf;
|
||||
@ -395,7 +391,7 @@ void RwPollingTask::fillSpecialRequestArray() {
|
||||
specialRequestIds[idx] = DeviceHandlerIF::NO_COMMAND_ID;
|
||||
continue;
|
||||
}
|
||||
switch (rwCookies[idx]->specialRequest) {
|
||||
switch (rwRequests[idx].specialRequest) {
|
||||
case (rws::SpecialRwRequest::GET_TM): {
|
||||
specialRequestIds[idx] = rws::GET_TM;
|
||||
break;
|
||||
@ -426,14 +422,14 @@ void RwPollingTask::handleSpecialRequests() {
|
||||
writeOneRwCmd(idx, fd);
|
||||
}
|
||||
closeSpi(fd);
|
||||
usleep(rws::SPI_REPLY_DELAY);
|
||||
for (unsigned idx = 0; idx < rwCookies.size(); idx++) {
|
||||
if (specialRequestIds[idx] == DeviceHandlerIF::NO_COMMAND_ID) {
|
||||
continue;
|
||||
}
|
||||
uint8_t* replyBuf;
|
||||
size_t maxReadLen = idAndIdxToReadBuffer(specialRequestIds[idx], idx, &replyBuf);
|
||||
result = readNextReply(*rwCookies[idx], replyBuf, maxReadLen);
|
||||
// Skip first byte for actual read buffer: Valid byte
|
||||
result = readNextReply(*rwCookies[idx], replyBuf + 1, maxReadLen);
|
||||
if (result == returnvalue::OK) {
|
||||
// The first byte is always a flag which shows whether the value was read
|
||||
// properly at least once.
|
||||
@ -455,17 +451,12 @@ void RwPollingTask::setAllReadFlagsFalse() {
|
||||
}
|
||||
}
|
||||
|
||||
// This closes the SPI
|
||||
void RwPollingTask::closeSpi(int fd) {
|
||||
// This will perform the function to close the SPI
|
||||
close(fd);
|
||||
// The SPI is now closed.
|
||||
}
|
||||
void RwPollingTask::closeSpi(int fd) { close(fd); }
|
||||
|
||||
ReturnValue_t RwPollingTask::sendOneMessage(int fd, RwCookie& rwCookie) {
|
||||
gpioId_t gpioId = rwCookie.getChipSelectPin();
|
||||
if (spiLock == nullptr) {
|
||||
sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl;
|
||||
sif::warning << "RwPollingTask: Mutex or GPIO interface invalid" << std::endl;
|
||||
return returnvalue::FAILED;
|
||||
}
|
||||
// Add datalinklayer like specified in the datasheet.
|
||||
@ -473,7 +464,7 @@ ReturnValue_t RwPollingTask::sendOneMessage(int fd, RwCookie& rwCookie) {
|
||||
rws::encodeHdlc(writeBuffer.data(), writeLen, encodedBuffer.data(), lenToSend);
|
||||
pullCsLow(gpioId, gpioIF);
|
||||
if (write(fd, encodedBuffer.data(), lenToSend) != static_cast<ssize_t>(lenToSend)) {
|
||||
sif::error << "rwSpiCallback::spiCallback: Write failed!" << std::endl;
|
||||
sif::error << "RwPollingTask: Write failed!" << std::endl;
|
||||
pullCsHigh(gpioId, gpioIF);
|
||||
return rws::SPI_WRITE_FAILURE;
|
||||
}
|
||||
@ -484,7 +475,7 @@ ReturnValue_t RwPollingTask::sendOneMessage(int fd, RwCookie& rwCookie) {
|
||||
ReturnValue_t RwPollingTask::pullCsLow(gpioId_t gpioId, GpioIF& gpioIF) {
|
||||
ReturnValue_t result = spiLock->lockMutex(TIMEOUT_TYPE, TIMEOUT_MS);
|
||||
if (result != returnvalue::OK) {
|
||||
sif::debug << "RwPollingTask::pullCsLow: Failed to lock mutex" << std::endl;
|
||||
sif::warning << "RwPollingTask::pullCsLow: Failed to lock mutex" << std::endl;
|
||||
return result;
|
||||
}
|
||||
// Pull SPI CS low. For now, no support for active high given
|
||||
@ -525,8 +516,8 @@ ReturnValue_t RwPollingTask::prepareSetSpeedCmd(uint8_t rwIdx) {
|
||||
uint16_t rampTimeToSet = 10;
|
||||
{
|
||||
MutexGuard mg(ipcLock);
|
||||
speedToSet = rwCookies[rwIdx]->currentRwSpeed;
|
||||
rampTimeToSet = rwCookies[rwIdx]->currentRampTime;
|
||||
speedToSet = rwRequests[rwIdx].currentRwSpeed;
|
||||
rampTimeToSet = rwRequests[rwIdx].currentRampTime;
|
||||
}
|
||||
size_t serLen = 1;
|
||||
SerializeAdapter::serialize(&speedToSet, &serPtr, &serLen, writeBuffer.size(),
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||
#include <mission/acs/defs.h>
|
||||
|
||||
#include "mission/acs/rwHelpers.h"
|
||||
|
||||
@ -26,10 +27,6 @@ class RwCookie : public SpiCookie {
|
||||
std::array<uint8_t, REPLY_BUF_LEN> replyBuf{};
|
||||
std::array<uint8_t, REPLY_BUF_LEN> exchangeBuf{};
|
||||
MutexIF* bufLock;
|
||||
bool setSpeed = true;
|
||||
int32_t currentRwSpeed = 0;
|
||||
uint16_t currentRampTime = 0;
|
||||
rws::SpecialRwRequest specialRequest = rws::SpecialRwRequest::REQUEST_NONE;
|
||||
uint8_t rwIdx;
|
||||
};
|
||||
|
||||
@ -50,8 +47,10 @@ class RwPollingTask : public SystemObject, public ExecutableObjectIF, public Dev
|
||||
const char* spiDev;
|
||||
GpioIF& gpioIF;
|
||||
std::array<bool, 4> skipCommandingForRw;
|
||||
std::array<bool, 4> skipSetSpeedReply;
|
||||
std::array<DeviceCommandId_t, 4> specialRequestIds;
|
||||
std::array<RwCookie*, 4> rwCookies;
|
||||
std::array<rws::RwRequest, 4> rwRequests{};
|
||||
std::array<uint8_t, rws::MAX_CMD_SIZE> writeBuffer;
|
||||
std::array<uint8_t, rws::MAX_CMD_SIZE * 2> encodedBuffer;
|
||||
|
||||
|
@ -37,7 +37,7 @@ void I2cTestClass::battInit() {
|
||||
if (ioctl(bpxInfo.fd, I2C_SLAVE, bpxInfo.addr) < 0) {
|
||||
sif::error << "Failed to acquire bus access and/or talk to slave" << std::endl;
|
||||
}
|
||||
cmdBuf[0] = BpxBattery::PORT_PING;
|
||||
cmdBuf[0] = bpxBat::PORT_PING;
|
||||
cmdBuf[1] = 0x42;
|
||||
sendLen = 2;
|
||||
ReturnValue_t result = i2cWrite(bpxInfo.fd, cmdBuf.data(), sendLen);
|
||||
@ -66,7 +66,7 @@ void I2cTestClass::battPeriodic() {
|
||||
if (ioctl(bpxInfo.fd, I2C_SLAVE, bpxInfo.addr) < 0) {
|
||||
sif::error << "Failed to acquire bus access and/or talk to slave" << std::endl;
|
||||
}
|
||||
cmdBuf[0] = BpxBattery::PORT_GET_HK;
|
||||
cmdBuf[0] = bpxBat::PORT_GET_HK;
|
||||
sendLen = 1;
|
||||
ReturnValue_t result = i2cWrite(bpxInfo.fd, cmdBuf.data(), sendLen);
|
||||
if (result != returnvalue::OK) {
|
||||
|
@ -20,6 +20,7 @@ class SyrlinksComHandler : public DeviceCommunicationIF,
|
||||
|
||||
//! [EXPORT] : [SKIP]
|
||||
static constexpr ReturnValue_t NO_SERIAL_DATA_READ = returnvalue::makeCode(2, 0);
|
||||
//! [EXPORT] : [SKIP]
|
||||
static constexpr ReturnValue_t NO_PACKET_FOUND = returnvalue::makeCode(2, 1);
|
||||
|
||||
enum class State { SLEEPING, ACTIVE } state = State::SLEEPING;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @brief Auto-generated event translation file. Contains 284 translations.
|
||||
* @brief Auto-generated event translation file. Contains 285 translations.
|
||||
* @details
|
||||
* Generated on: 2023-04-04 13:59:07
|
||||
* Generated on: 2023-04-07 17:42:57
|
||||
*/
|
||||
#include "translateEvents.h"
|
||||
|
||||
@ -266,7 +266,8 @@ const char *VERSION_INFO_STRING = "VERSION_INFO";
|
||||
const char *CURRENT_IMAGE_INFO_STRING = "CURRENT_IMAGE_INFO";
|
||||
const char *REBOOT_COUNTER_STRING = "REBOOT_COUNTER";
|
||||
const char *INDIVIDUAL_BOOT_COUNTS_STRING = "INDIVIDUAL_BOOT_COUNTS";
|
||||
const char *I2C_UNAVAILABLE_REBOOT_STRING = "I2C_UNAVAILABLE_REBOOT";
|
||||
const char *TRYING_I2C_RECOVERY_STRING = "TRYING_I2C_RECOVERY";
|
||||
const char *I2C_REBOOT_STRING = "I2C_REBOOT";
|
||||
const char *NO_VALID_SENSOR_TEMPERATURE_STRING = "NO_VALID_SENSOR_TEMPERATURE";
|
||||
const char *NO_HEALTHY_HEATER_AVAILABLE_STRING = "NO_HEALTHY_HEATER_AVAILABLE";
|
||||
const char *SYRLINKS_OVERHEATING_STRING = "SYRLINKS_OVERHEATING";
|
||||
@ -815,7 +816,9 @@ const char *translateEvents(Event event) {
|
||||
case (14008):
|
||||
return INDIVIDUAL_BOOT_COUNTS_STRING;
|
||||
case (14010):
|
||||
return I2C_UNAVAILABLE_REBOOT_STRING;
|
||||
return TRYING_I2C_RECOVERY_STRING;
|
||||
case (14011):
|
||||
return I2C_REBOOT_STRING;
|
||||
case (14100):
|
||||
return NO_VALID_SENSOR_TEMPERATURE_STRING;
|
||||
case (14101):
|
||||
|
@ -2,7 +2,7 @@
|
||||
* @brief Auto-generated object translation file.
|
||||
* @details
|
||||
* Contains 175 translations.
|
||||
* Generated on: 2023-04-04 13:59:07
|
||||
* Generated on: 2023-04-07 17:42:57
|
||||
*/
|
||||
#include "translateObjects.h"
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
class ScexHelper : public SerializeIF {
|
||||
public:
|
||||
//! [EXPORT] : [SKIP]
|
||||
static const ReturnValue_t INVALID_CRC = returnvalue::makeCode(0, 2);
|
||||
|
||||
ScexHelper();
|
||||
|
@ -795,9 +795,9 @@ ReturnValue_t ImtqHandler::initializeLocalDataPool(localpool::DataPool& localDat
|
||||
localDataPoolMap.emplace(imtq::FINA_NEG_Z_COIL_Z_TEMPERATURE, new PoolEntry<int16_t>({0}));
|
||||
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 12.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetNoTorque.getSid(), enableHkSets, 30.0));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 12.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(hkDatasetWithTorque.getSid(), enableHkSets, 30.0));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(rawMtmNoTorque.getSid(), false, 10.0));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <fsfw/globalfunctions/CRC.h>
|
||||
#include <fsfw/globalfunctions/arrayprinter.h>
|
||||
#include <fsfw_hal/common/gpio/GpioIF.h>
|
||||
#include <mission/acs/defs.h>
|
||||
|
||||
#include "OBSWConfig.h"
|
||||
|
||||
@ -23,40 +24,52 @@ RwHandler::RwHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCooki
|
||||
if (gpioComIF == nullptr) {
|
||||
sif::error << "RwHandler: Invalid gpio communication interface" << std::endl;
|
||||
}
|
||||
currentRequest.rwIdx = rwIdx;
|
||||
}
|
||||
|
||||
RwHandler::~RwHandler() {}
|
||||
|
||||
void RwHandler::doStartUp() {
|
||||
internalState = InternalState::DEFAULT;
|
||||
|
||||
if (gpioComIF->pullHigh(enableGpio) != returnvalue::OK) {
|
||||
sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to high";
|
||||
sif::error << "RW Handler " << rwIdx << ": Failed to pull ENABLE pin high for startup";
|
||||
}
|
||||
currentRequest.mode = acs::SimpleSensorMode::NORMAL;
|
||||
updatePeriodicReply(true, rws::REPLY_ID);
|
||||
statusSet.setReportingEnabled(true);
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
|
||||
void RwHandler::doShutDown() {
|
||||
if (gpioComIF->pullLow(enableGpio) != returnvalue::OK) {
|
||||
sif::debug << "RwHandler::doStartUp: Failed to pull enable gpio to low";
|
||||
if (internalState != InternalState::SHUTDOWN) {
|
||||
internalState = InternalState::SHUTDOWN;
|
||||
shutdownState = ShutdownState::SET_SPEED_ZERO;
|
||||
offTransitionCountdown.resetTimer();
|
||||
}
|
||||
internalState = InternalState::DEFAULT;
|
||||
updatePeriodicReply(false, rws::REPLY_ID);
|
||||
{
|
||||
PoolReadGuard pg(&statusSet);
|
||||
statusSet.currSpeed = 0.0;
|
||||
statusSet.referenceSpeed = 0.0;
|
||||
statusSet.state = 0;
|
||||
statusSet.setValidity(false, true);
|
||||
statusSet.setReportingEnabled(false);
|
||||
if ((internalState == InternalState::SHUTDOWN) and
|
||||
(shutdownState == ShutdownState::DONE or offTransitionCountdown.hasTimedOut())) {
|
||||
if (gpioComIF->pullLow(enableGpio) != returnvalue::OK) {
|
||||
sif::error << "RW Handler " << rwIdx << ": Failed to pull ENABLE pin low for shutdown";
|
||||
}
|
||||
updatePeriodicReply(false, rws::REPLY_ID);
|
||||
{
|
||||
PoolReadGuard pg(&statusSet);
|
||||
statusSet.currSpeed = 0.0;
|
||||
statusSet.referenceSpeed = 0.0;
|
||||
statusSet.state = 0;
|
||||
statusSet.setValidity(false, true);
|
||||
statusSet.setReportingEnabled(false);
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&tmDataset);
|
||||
tmDataset.setValidity(false, true);
|
||||
}
|
||||
internalState = InternalState::DEFAULT;
|
||||
shutdownState = ShutdownState::NONE;
|
||||
// The power switch is handled by the assembly, so we can go off here directly.
|
||||
setMode(MODE_OFF);
|
||||
}
|
||||
{
|
||||
PoolReadGuard pg(&tmDataset);
|
||||
tmDataset.setValidity(false, true);
|
||||
}
|
||||
// The power switch is handled by the assembly, so we can go off here directly.
|
||||
setMode(MODE_OFF);
|
||||
}
|
||||
|
||||
ReturnValue_t RwHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
@ -73,6 +86,20 @@ ReturnValue_t RwHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
}
|
||||
|
||||
ReturnValue_t RwHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (internalState == InternalState::SHUTDOWN) {
|
||||
if (shutdownState == ShutdownState::SET_SPEED_ZERO) {
|
||||
{
|
||||
PoolReadGuard pg(&rwSpeedActuationSet);
|
||||
rwSpeedActuationSet.setRwSpeed(0, 10);
|
||||
}
|
||||
*id = rws::REQUEST_ID;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
} else if (shutdownState == ShutdownState::STOP_POLLING) {
|
||||
currentRequest.mode = acs::SimpleSensorMode::OFF;
|
||||
*id = rws::REQUEST_ID;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
}
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
|
||||
@ -115,32 +142,36 @@ ReturnValue_t RwHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand
|
||||
return result;
|
||||
}
|
||||
// set speed flag.
|
||||
commandBuffer[0] = true;
|
||||
rawPacketLen = 1;
|
||||
uint8_t* currentCmdBuf = commandBuffer + 1;
|
||||
rwSpeedActuationSet.serialize(¤tCmdBuf, &rawPacketLen, sizeof(commandBuffer),
|
||||
SerializeIF::Endianness::MACHINE);
|
||||
commandBuffer[rawPacketLen++] = static_cast<uint8_t>(rws::SpecialRwRequest::REQUEST_NONE);
|
||||
rawPacket = commandBuffer;
|
||||
currentRequest.setSpeed = true;
|
||||
rwSpeedActuationSet.getRwSpeed(currentRequest.currentRwSpeed, currentRequest.currentRampTime);
|
||||
currentRequest.specialRequest = rws::SpecialRwRequest::REQUEST_NONE;
|
||||
rawPacket = reinterpret_cast<uint8_t*>(¤tRequest);
|
||||
rawPacketLen = sizeof(rws::RwRequest);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (rws::RESET_MCU): {
|
||||
commandBuffer[0] = false;
|
||||
commandBuffer[7] = static_cast<uint8_t>(rws::SpecialRwRequest::RESET_MCU);
|
||||
currentRequest.setSpeed = false;
|
||||
currentRequest.specialRequest = rws::SpecialRwRequest::RESET_MCU;
|
||||
internalState = InternalState::RESET_MCU;
|
||||
rawPacket = reinterpret_cast<uint8_t*>(¤tRequest);
|
||||
rawPacketLen = sizeof(rws::RwRequest);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
case (rws::INIT_RW_CONTROLLER): {
|
||||
commandBuffer[0] = false;
|
||||
commandBuffer[7] = static_cast<uint8_t>(rws::SpecialRwRequest::INIT_RW_CONTROLLER);
|
||||
currentRequest.setSpeed = false;
|
||||
currentRequest.specialRequest = rws::SpecialRwRequest::INIT_RW_CONTROLLER;
|
||||
internalState = InternalState::INIT_RW_CONTROLLER;
|
||||
rawPacket = reinterpret_cast<uint8_t*>(¤tRequest);
|
||||
rawPacketLen = sizeof(rws::RwRequest);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
case (rws::GET_TM): {
|
||||
commandBuffer[0] = false;
|
||||
commandBuffer[7] = static_cast<uint8_t>(rws::SpecialRwRequest::GET_TM);
|
||||
currentRequest.setSpeed = false;
|
||||
currentRequest.specialRequest = rws::SpecialRwRequest::GET_TM;
|
||||
internalState = InternalState::GET_TM;
|
||||
rawPacket = reinterpret_cast<uint8_t*>(¤tRequest);
|
||||
rawPacketLen = sizeof(rws::RwRequest);
|
||||
return returnvalue::OK;
|
||||
}
|
||||
default:
|
||||
@ -168,6 +199,9 @@ ReturnValue_t RwHandler::scanForReply(const uint8_t* start, size_t remainingSize
|
||||
*foundLen = remainingSize;
|
||||
*foundId = rws::REPLY_ID;
|
||||
}
|
||||
if (internalState == InternalState::SHUTDOWN and shutdownState == ShutdownState::STOP_POLLING) {
|
||||
shutdownState = ShutdownState::DONE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
@ -377,6 +411,12 @@ void RwHandler::handleGetRwStatusReply(const uint8_t* packet) {
|
||||
|
||||
statusSet.setValidity(true, true);
|
||||
|
||||
if (internalState == InternalState::SHUTDOWN and std::abs(tmDataset.rwCurrSpeed.value) <= 2 and
|
||||
shutdownState == ShutdownState::SET_SPEED_ZERO) {
|
||||
// Finish transition to off.
|
||||
shutdownState = ShutdownState::STOP_POLLING;
|
||||
}
|
||||
|
||||
if (statusSet.state == rws::STATE_ERROR) {
|
||||
// Trigger FDIR reaction, first recovery, then faulty if it doesnt fix the issue.
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT, statusSet.state.value, 0);
|
||||
|
@ -75,6 +75,8 @@ class RwHandler : public DeviceHandlerBase {
|
||||
GpioIF* gpioComIF = nullptr;
|
||||
gpioId_t enableGpio = gpio::NO_GPIO;
|
||||
bool debugMode = false;
|
||||
Countdown offTransitionCountdown = Countdown(5000);
|
||||
rws::RwRequest currentRequest;
|
||||
|
||||
rws::StatusSet statusSet;
|
||||
rws::LastResetSatus lastResetStatusSet;
|
||||
@ -87,27 +89,16 @@ class RwHandler : public DeviceHandlerBase {
|
||||
PoolEntry<int32_t> rwSpeed = PoolEntry<int32_t>({0});
|
||||
PoolEntry<uint16_t> rampTime = PoolEntry<uint16_t>({10});
|
||||
|
||||
enum class InternalState {
|
||||
DEFAULT,
|
||||
GET_TM,
|
||||
INIT_RW_CONTROLLER,
|
||||
RESET_MCU,
|
||||
// GET_RESET_STATUS,
|
||||
// CLEAR_RESET_STATUS,
|
||||
// READ_TEMPERATURE,
|
||||
// SET_SPEED,
|
||||
// GET_RW_SATUS
|
||||
};
|
||||
enum class InternalState { DEFAULT, GET_TM, INIT_RW_CONTROLLER, RESET_MCU, SHUTDOWN };
|
||||
enum class ShutdownState {
|
||||
NONE,
|
||||
SET_SPEED_ZERO,
|
||||
STOP_POLLING,
|
||||
DONE,
|
||||
} shutdownState = ShutdownState::NONE;
|
||||
|
||||
InternalState internalState = InternalState::DEFAULT;
|
||||
|
||||
/**
|
||||
* @brief This function can be used to build commands which do not contain any data apart
|
||||
* from the command id and the CRC.
|
||||
* @param commandId The command id of the command to build.
|
||||
*/
|
||||
// void prepareSimpleCommand(DeviceCommandId_t id);
|
||||
|
||||
/**
|
||||
* @brief This function checks if the receiced speed and ramp time to set are in a valid
|
||||
* range.
|
||||
@ -115,13 +106,6 @@ class RwHandler : public DeviceHandlerBase {
|
||||
*/
|
||||
ReturnValue_t checkSpeedAndRampTime();
|
||||
|
||||
/**
|
||||
* @brief This function prepares the set speed command from the dataSet received with
|
||||
* an action message or set in the software.
|
||||
* @return returnvalue::OK if successful, otherwise error code.
|
||||
*/
|
||||
// ReturnValue_t prepareSetSpeedCmd();
|
||||
|
||||
/**
|
||||
* @brief This function writes the last reset status retrieved with the get last reset status
|
||||
* command into the reset status dataset.
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <fsfw/datapoollocal/LocalPoolVariable.h>
|
||||
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <mission/acs/defs.h>
|
||||
|
||||
#include "eive/resultClassIds.h"
|
||||
#include "events/subsystemIdRanges.h"
|
||||
@ -36,6 +37,15 @@ enum class SpecialRwRequest : uint8_t {
|
||||
NUM_REQUESTS
|
||||
};
|
||||
|
||||
struct RwRequest {
|
||||
acs::SimpleSensorMode mode = acs::SimpleSensorMode::OFF;
|
||||
bool setSpeed = true;
|
||||
int32_t currentRwSpeed = 0;
|
||||
uint16_t currentRampTime = 0;
|
||||
rws::SpecialRwRequest specialRequest = rws::SpecialRwRequest::REQUEST_NONE;
|
||||
uint8_t rwIdx = 0;
|
||||
};
|
||||
|
||||
static const uint8_t INTERFACE_ID = CLASS_ID::RW_HANDLER;
|
||||
|
||||
static const ReturnValue_t SPI_WRITE_FAILURE = MAKE_RETURN_CODE(0xB0);
|
||||
|
@ -277,7 +277,7 @@ void StarTrackerHandler::performOperationHook() {
|
||||
}
|
||||
}
|
||||
|
||||
Submode_t StarTrackerHandler::getInitialSubmode() { return SUBMODE_BOOTLOADER; }
|
||||
Submode_t StarTrackerHandler::getInitialSubmode() { return startracker::SUBMODE_BOOTLOADER; }
|
||||
|
||||
ReturnValue_t StarTrackerHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (strHelperHandlingSpecialRequest) {
|
||||
@ -705,7 +705,7 @@ ReturnValue_t StarTrackerHandler::isModeCombinationValid(Mode_t mode, Submode_t
|
||||
return INVALID_SUBMODE;
|
||||
}
|
||||
case MODE_ON:
|
||||
if (submode == SUBMODE_BOOTLOADER || submode == SUBMODE_FIRMWARE) {
|
||||
if (submode == startracker::SUBMODE_BOOTLOADER || submode == startracker::SUBMODE_FIRMWARE) {
|
||||
return returnvalue::OK;
|
||||
} else {
|
||||
return INVALID_SUBMODE;
|
||||
@ -736,6 +736,7 @@ void StarTrackerHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||
}
|
||||
|
||||
void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) {
|
||||
using namespace startracker;
|
||||
uint8_t dhbSubmode = getSubmode();
|
||||
// We hide that the transition to submode firmware actually goes through the submode bootloader.
|
||||
// This is because the startracker always starts in bootloader mode but we want to allow direct
|
||||
@ -762,6 +763,7 @@ void StarTrackerHandler::doOnTransition(Submode_t subModeFrom) {
|
||||
}
|
||||
|
||||
void StarTrackerHandler::doNormalTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||
using namespace startracker;
|
||||
if (subModeFrom == SUBMODE_FIRMWARE) {
|
||||
setMode(MODE_NORMAL);
|
||||
} else if (subModeFrom == SUBMODE_BOOTLOADER) {
|
||||
@ -787,7 +789,7 @@ void StarTrackerHandler::bootFirmware(Mode_t toMode) {
|
||||
if (toMode == MODE_NORMAL) {
|
||||
setMode(toMode, 0);
|
||||
} else {
|
||||
setMode(toMode, SUBMODE_FIRMWARE);
|
||||
setMode(toMode, startracker::SUBMODE_FIRMWARE);
|
||||
}
|
||||
sif::info << "STR: Firmware boot success" << std::endl;
|
||||
internalState = InternalState::IDLE;
|
||||
|
@ -54,9 +54,6 @@ class StarTrackerHandler : public DeviceHandlerBase {
|
||||
|
||||
Submode_t getInitialSubmode() override;
|
||||
|
||||
static const Submode_t SUBMODE_BOOTLOADER = 1;
|
||||
static const Submode_t SUBMODE_FIRMWARE = 2;
|
||||
|
||||
protected:
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
|
@ -11,6 +11,9 @@
|
||||
|
||||
namespace startracker {
|
||||
|
||||
static const Submode_t SUBMODE_BOOTLOADER = 1;
|
||||
static const Submode_t SUBMODE_FIRMWARE = 2;
|
||||
|
||||
/**
|
||||
* @brief Returns the frame type field of a decoded frame.
|
||||
*/
|
||||
|
@ -45,6 +45,10 @@ ReturnValue_t PersistentLogTmStoreTask::performOperation(uint8_t opCode) {
|
||||
// TODO: Might not be necessary
|
||||
sif::debug << "VC busy, delaying" << std::endl;
|
||||
TaskFactory::delayTask(10);
|
||||
} else {
|
||||
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
|
||||
// Polling the PAPB of the PTME core too often leads to scheuduling issues.
|
||||
TaskFactory::delayTask(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ ReturnValue_t PersistentSingleTmStoreTask::performOperation(uint8_t opCode) {
|
||||
TaskFactory::delayTask(10);
|
||||
} else {
|
||||
// TODO: Would be best to remove this, but not delaying here can lead to evil issues.
|
||||
// Polling the PAPB of the PTME core too often leads to scheuduling issues.
|
||||
TaskFactory::delayTask(2);
|
||||
}
|
||||
}
|
||||
|
@ -664,7 +664,7 @@ ReturnValue_t SyrlinksHandler::initializeLocalDataPool(localpool::DataPool& loca
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(rxDataset.getSid(), enableHkSets, 60.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(temperatureSet.getSid(), enableHkSets, 60.0));
|
||||
subdp::RegularHkPeriodicParams(temperatureSet.getSid(), enableHkSets, 120.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -221,9 +221,8 @@ void AcsController::performSafe() {
|
||||
|
||||
updateCtrlValData(errAng);
|
||||
updateActuatorCmdData(cmdDipolMtqs);
|
||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
||||
// acsParameters.magnetorquesParameter.torqueDuration, 0, 0, 0, 0,
|
||||
// acsParameters.rwHandlingParameters.rampTime);
|
||||
// commandActuators(cmdDipolMtqs[0], cmdDipolMtqs[1], cmdDipolMtqs[2],
|
||||
// acsParameters.magnetorquerParameter.torqueDuration);
|
||||
}
|
||||
|
||||
void AcsController::performDetumble() {
|
||||
@ -472,6 +471,18 @@ void AcsController::performPointingCtrl() {
|
||||
// acsParameters.rwHandlingParameters.rampTime);
|
||||
}
|
||||
|
||||
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||
uint16_t dipoleTorqueDuration) {
|
||||
{
|
||||
PoolReadGuard pg(&dipoleSet);
|
||||
MutexGuard mg(torquer::lazyLock(), torquer::LOCK_TYPE, torquer::LOCK_TIMEOUT,
|
||||
torquer::LOCK_CTX);
|
||||
torquer::NEW_ACTUATION_FLAG = true;
|
||||
dipoleSet.setDipoles(xDipole, yDipole, zDipole, dipoleTorqueDuration);
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t AcsController::commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||
uint16_t dipoleTorqueDuration, int32_t rw1Speed,
|
||||
int32_t rw2Speed, int32_t rw3Speed, int32_t rw4Speed,
|
||||
@ -565,7 +576,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_3_RM3100_UT, &mgm3VecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_NT, &imtqMgmVecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_IMTQ_CAL_ACT_STATUS, &imtqCalActStatus);
|
||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 5.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataRaw.getSid(), false, 10.0});
|
||||
// MGM Processed
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_0_VEC, &mgm0VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_1_VEC, &mgm1VecProc);
|
||||
@ -575,7 +586,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT, &mgmVecTot);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MGM_VEC_TOT_DERIVATIVE, &mgmVecTotDer);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MAG_IGRF_MODEL, &magIgrf);
|
||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), enableHkSets, 12.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({mgmDataProcessed.getSid(), enableHkSets, 10.0});
|
||||
// SUS Raw
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, &sus0ValRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_N_LOC_XBYFZM_PT_XB, &sus1ValRaw);
|
||||
@ -589,7 +600,7 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_9_R_LOC_XBYBZB_PT_YF, &sus9ValRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_10_N_LOC_XMYBZF_PT_ZF, &sus10ValRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_11_R_LOC_XBYMZB_PT_ZB, &sus11ValRaw);
|
||||
poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 5.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({susDataRaw.getSid(), false, 10.0});
|
||||
// SUS Processed
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_0_VEC, &sus0VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_1_VEC, &sus1VecProc);
|
||||
@ -606,43 +617,43 @@ ReturnValue_t AcsController::initializeLocalDataPool(localpool::DataPool &localD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT, &susVecTot);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUS_VEC_TOT_DERIVATIVE, &susVecTotDer);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SUN_IJK_MODEL, &sunIjk);
|
||||
poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), enableHkSets, 12.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({susDataProcessed.getSid(), enableHkSets, 10.0});
|
||||
// GYR Raw
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_ADIS, &gyr0VecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_L3, &gyr1VecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_ADIS, &gyr2VecRaw);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_L3, &gyr3VecRaw);
|
||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 5.0});
|
||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataRaw.getSid(), false, 10.0});
|
||||
// GYR Processed
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_0_VEC, &gyr0VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_1_VEC, &gyr1VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_2_VEC, &gyr2VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_3_VEC, &gyr3VecProc);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GYR_VEC_TOT, &gyrVecTot);
|
||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), enableHkSets, 12.0});
|
||||
poolManager.subscribeForDiagPeriodicPacket({gyrDataProcessed.getSid(), enableHkSets, 10.0});
|
||||
// GPS Processed
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GC_LATITUDE, &gcLatitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GD_LONGITUDE, &gdLongitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ALTITUDE, &altitude);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_POSITION, &gpsPosition);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::GPS_VELOCITY, &gpsVelocity);
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 12.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({gpsDataProcessed.getSid(), enableHkSets, 30.0});
|
||||
// MEKF
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::QUAT_MEKF, &quatMekf);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::SAT_ROT_RATE_MEKF, &satRotRateMekf);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MEKF_STATUS, &mekfStatus);
|
||||
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 12.0});
|
||||
poolManager.subscribeForDiagPeriodicPacket({mekfData.getSid(), enableHkSets, 10.0});
|
||||
// Ctrl Values
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_QUAT, &tgtQuat);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_QUAT, &errQuat);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::ERROR_ANG, &errAng);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::TGT_ROT_RATE, &tgtRotRate);
|
||||
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), enableHkSets, 12.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({ctrlValData.getSid(), enableHkSets, 10.0});
|
||||
// Actuator CMD
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_TORQUE, &rwTargetTorque);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::RW_TARGET_SPEED, &rwTargetSpeed);
|
||||
localDataPoolMap.emplace(acsctrl::PoolIds::MTQ_TARGET_DIPOLE, &mtqTargetDipole);
|
||||
poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), enableHkSets, 12.0});
|
||||
poolManager.subscribeForRegularPeriodicPacket({actuatorCmdData.getSid(), enableHkSets, 10.0});
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,8 @@ class AcsController : public ExtendedControllerBase, public ReceivesParameterMes
|
||||
void modeChanged(Mode_t mode, Submode_t submode);
|
||||
void announceMode(bool recursive);
|
||||
|
||||
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||
uint16_t dipoleTorqueDuration);
|
||||
ReturnValue_t commandActuators(int16_t xDipole, int16_t yDipole, int16_t zDipole,
|
||||
uint16_t dipoleTorqueDuration, int32_t rw1Speed, int32_t rw2Speed,
|
||||
int32_t rw3Speed, int32_t rw4Speed, uint16_t rampTime);
|
||||
|
@ -260,13 +260,13 @@ ReturnValue_t ThermalController::initializeLocalDataPool(localpool::DataPool& lo
|
||||
enableHkSets = true;
|
||||
#endif
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(sensorTemperatures.getSid(), enableHkSets, 60.0));
|
||||
subdp::RegularHkPeriodicParams(sensorTemperatures.getSid(), enableHkSets, 120.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(susTemperatures.getSid(), enableHkSets, 60.0));
|
||||
subdp::RegularHkPeriodicParams(susTemperatures.getSid(), enableHkSets, 240.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(deviceTemperatures.getSid(), enableHkSets, 60.0));
|
||||
subdp::RegularHkPeriodicParams(deviceTemperatures.getSid(), enableHkSets, 120.0));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(heaterInfo.getSid(), enableHkSets, 30.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(heaterInfo.getSid(), enableHkSets, 120.0));
|
||||
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -182,14 +182,10 @@ class ThermalController : public ExtendedControllerBase {
|
||||
susMax1227::SusDataset susSet11;
|
||||
|
||||
lp_var_t<float> tempQ7s = lp_var_t<float>(objects::CORE_CONTROLLER, core::PoolIds::TEMPERATURE);
|
||||
lp_var_t<int16_t> battTemp1 =
|
||||
lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_1);
|
||||
lp_var_t<int16_t> battTemp2 =
|
||||
lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_2);
|
||||
lp_var_t<int16_t> battTemp3 =
|
||||
lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_3);
|
||||
lp_var_t<int16_t> battTemp4 =
|
||||
lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, BpxBattery::BATT_TEMP_4);
|
||||
lp_var_t<int16_t> battTemp1 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_1);
|
||||
lp_var_t<int16_t> battTemp2 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_2);
|
||||
lp_var_t<int16_t> battTemp3 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_3);
|
||||
lp_var_t<int16_t> battTemp4 = lp_var_t<int16_t>(objects::BPX_BATT_HANDLER, bpxBat::BATT_TEMP_4);
|
||||
lp_var_t<int32_t> tempRw1 = lp_var_t<int32_t>(objects::RW1, rws::TEMPERATURE_C);
|
||||
lp_var_t<int32_t> tempRw2 = lp_var_t<int32_t>(objects::RW2, rws::TEMPERATURE_C);
|
||||
lp_var_t<int32_t> tempRw3 = lp_var_t<int32_t>(objects::RW3, rws::TEMPERATURE_C);
|
||||
|
@ -726,7 +726,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
|
||||
int fileDescriptor = 0;
|
||||
UnixFileGuard fileHelper(comIf->getSpiDev(), fileDescriptor, O_RDWR, "SpiComIF::sendMessage");
|
||||
if (fileHelper.getOpenResult() != returnvalue::OK) {
|
||||
return SpiComIF::OPENING_FILE_FAILED;
|
||||
return spi::OPENING_FILE_FAILED;
|
||||
}
|
||||
spi::SpiModes spiMode = spi::SpiModes::MODE_0;
|
||||
uint32_t spiSpeed = 0;
|
||||
@ -782,7 +782,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
|
||||
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie->getTransferStructHandle());
|
||||
if (retval < 0) {
|
||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||
result = SpiComIF::FULL_DUPLEX_TRANSFER_FAILED;
|
||||
result = spi::FULL_DUPLEX_TRANSFER_FAILED;
|
||||
}
|
||||
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||
comIf->performSpiWiretapping(cookie);
|
||||
@ -804,7 +804,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
|
||||
retval = ioctl(fileDescriptor, SPI_IOC_MESSAGE(1), cookie->getTransferStructHandle());
|
||||
if (retval < 0) {
|
||||
utility::handleIoctlError("SpiComIF::sendMessage: ioctl error.");
|
||||
result = SpiComIF::FULL_DUPLEX_TRANSFER_FAILED;
|
||||
result = spi::FULL_DUPLEX_TRANSFER_FAILED;
|
||||
}
|
||||
#if FSFW_HAL_SPI_WIRETAPPING == 1
|
||||
comIf->performSpiWiretapping(cookie);
|
||||
|
@ -149,9 +149,9 @@ ReturnValue_t ACUHandler::initializeLocalDataPool(localpool::DataPool &localData
|
||||
localDataPoolMap.emplace(pool::ACU_WDT_GND_LEFT, new PoolEntry<uint32_t>({0}));
|
||||
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 20.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 3000.0));
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -27,54 +27,56 @@ void BpxBatteryHandler::doStartUp() {
|
||||
void BpxBatteryHandler::doShutDown() {
|
||||
// Perform a COM check on reboot
|
||||
state = States::CHECK_COM;
|
||||
setMode(MODE_OFF);
|
||||
}
|
||||
|
||||
ReturnValue_t BpxBatteryHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||
*id = BpxBattery::GET_HK;
|
||||
*id = bpxBat::GET_HK;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
|
||||
ReturnValue_t BpxBatteryHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||
if (state == States::CHECK_COM) {
|
||||
*id = BpxBattery::PING;
|
||||
*id = bpxBat::PING;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void BpxBatteryHandler::fillCommandAndReplyMap() {
|
||||
using namespace BpxBattery;
|
||||
using namespace bpxBat;
|
||||
insertInCommandAndReplyMap(GET_HK, 1, &hkSet, GET_HK_REPLY_LEN);
|
||||
insertInCommandAndReplyMap(BpxBattery::PING, 1, nullptr, PING_REPLY_LEN);
|
||||
insertInCommandAndReplyMap(BpxBattery::REBOOT, 1, nullptr, 0);
|
||||
insertInCommandAndReplyMap(BpxBattery::RESET_COUNTERS, 1, nullptr, EMPTY_REPLY_LEN);
|
||||
insertInCommandAndReplyMap(BpxBattery::CONFIG_CMD, 1, nullptr, EMPTY_REPLY_LEN);
|
||||
insertInCommandAndReplyMap(BpxBattery::CONFIG_GET, 1, &cfgSet, CONFIG_GET_REPLY_LEN);
|
||||
insertInCommandAndReplyMap(bpxBat::PING, 1, nullptr, PING_REPLY_LEN);
|
||||
insertInCommandAndReplyMap(bpxBat::REBOOT, 1, nullptr, 0);
|
||||
insertInCommandAndReplyMap(bpxBat::RESET_COUNTERS, 1, nullptr, EMPTY_REPLY_LEN);
|
||||
insertInCommandAndReplyMap(bpxBat::CONFIG_CMD, 1, nullptr, EMPTY_REPLY_LEN);
|
||||
insertInCommandAndReplyMap(bpxBat::CONFIG_GET, 1, &cfgSet, CONFIG_GET_REPLY_LEN);
|
||||
}
|
||||
|
||||
ReturnValue_t BpxBatteryHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t* commandData,
|
||||
size_t commandDataLen) {
|
||||
switch (deviceCommand) {
|
||||
case (BpxBattery::GET_HK): {
|
||||
cmdBuf[0] = BpxBattery::PORT_GET_HK;
|
||||
case (bpxBat::GET_HK): {
|
||||
cmdBuf[0] = bpxBat::PORT_GET_HK;
|
||||
this->rawPacketLen = 1;
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::PING): {
|
||||
case (bpxBat::PING): {
|
||||
if (commandDataLen == 1 and commandData != nullptr) {
|
||||
sentPingByte = commandData[0];
|
||||
} else {
|
||||
sentPingByte = BpxBattery::DEFAULT_PING_SENT_BYTE;
|
||||
sentPingByte = bpxBat::DEFAULT_PING_SENT_BYTE;
|
||||
}
|
||||
|
||||
cmdBuf[0] = BpxBattery::PORT_PING;
|
||||
cmdBuf[0] = bpxBat::PORT_PING;
|
||||
cmdBuf[1] = sentPingByte;
|
||||
this->rawPacketLen = 2;
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::REBOOT): {
|
||||
cmdBuf[0] = BpxBattery::PORT_REBOOT;
|
||||
case (bpxBat::REBOOT): {
|
||||
sif::info << "BPX BATT: Executing reboot command" << std::endl;
|
||||
cmdBuf[0] = bpxBat::PORT_REBOOT;
|
||||
cmdBuf[1] = 0x80;
|
||||
cmdBuf[2] = 0x07;
|
||||
cmdBuf[3] = 0x80;
|
||||
@ -85,26 +87,26 @@ ReturnValue_t BpxBatteryHandler::buildCommandFromCommand(DeviceCommandId_t devic
|
||||
triggerEvent(DeviceHandlerIF::DEVICE_WANTS_HARD_REBOOT);
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::RESET_COUNTERS): {
|
||||
cmdBuf[0] = BpxBattery::PORT_RESET_COUNTERS;
|
||||
cmdBuf[1] = BpxBattery::RESET_COUNTERS_MAGIC_VALUE;
|
||||
case (bpxBat::RESET_COUNTERS): {
|
||||
cmdBuf[0] = bpxBat::PORT_RESET_COUNTERS;
|
||||
cmdBuf[1] = bpxBat::RESET_COUNTERS_MAGIC_VALUE;
|
||||
this->rawPacketLen = 2;
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::CONFIG_CMD): {
|
||||
cmdBuf[0] = BpxBattery::PORT_CONFIG_CMD;
|
||||
case (bpxBat::CONFIG_CMD): {
|
||||
cmdBuf[0] = bpxBat::PORT_CONFIG_CMD;
|
||||
// Needs to be set to 0x01 according to datasheet
|
||||
cmdBuf[1] = 0x01;
|
||||
this->rawPacketLen = 2;
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::CONFIG_GET): {
|
||||
cmdBuf[0] = BpxBattery::PORT_CONFIG_GET;
|
||||
case (bpxBat::CONFIG_GET): {
|
||||
cmdBuf[0] = bpxBat::PORT_CONFIG_GET;
|
||||
this->rawPacketLen = 1;
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::CONFIG_SET): {
|
||||
cmdBuf[0] = BpxBattery::PORT_CONFIG_SET;
|
||||
case (bpxBat::CONFIG_SET): {
|
||||
cmdBuf[0] = bpxBat::PORT_CONFIG_SET;
|
||||
if (commandDataLen != 3) {
|
||||
return DeviceHandlerIF::INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS;
|
||||
}
|
||||
@ -114,8 +116,8 @@ ReturnValue_t BpxBatteryHandler::buildCommandFromCommand(DeviceCommandId_t devic
|
||||
this->rawPacketLen = 4;
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::MAN_HEAT_ON): {
|
||||
cmdBuf[0] = BpxBattery::PORT_MAN_HEAT_ON;
|
||||
case (bpxBat::MAN_HEAT_ON): {
|
||||
cmdBuf[0] = bpxBat::PORT_MAN_HEAT_ON;
|
||||
if (commandDataLen != 2) {
|
||||
return DeviceHandlerIF::INVALID_NUMBER_OR_LENGTH_OF_PARAMETERS;
|
||||
}
|
||||
@ -125,8 +127,8 @@ ReturnValue_t BpxBatteryHandler::buildCommandFromCommand(DeviceCommandId_t devic
|
||||
this->rawPacketLen = 3;
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::MAN_HEAT_OFF): {
|
||||
cmdBuf[0] = BpxBattery::PORT_MAN_HEAT_OFF;
|
||||
case (bpxBat::MAN_HEAT_OFF): {
|
||||
cmdBuf[0] = bpxBat::PORT_MAN_HEAT_OFF;
|
||||
this->rawPacketLen = 1;
|
||||
break;
|
||||
}
|
||||
@ -142,35 +144,35 @@ ReturnValue_t BpxBatteryHandler::buildCommandFromCommand(DeviceCommandId_t devic
|
||||
|
||||
ReturnValue_t BpxBatteryHandler::scanForReply(const uint8_t* start, size_t remainingSize,
|
||||
DeviceCommandId_t* foundId, size_t* foundLen) {
|
||||
using namespace BpxBattery;
|
||||
using namespace bpxBat;
|
||||
switch (lastCmd) {
|
||||
case (BpxBattery::GET_HK): {
|
||||
case (bpxBat::GET_HK): {
|
||||
if (remainingSize != GET_HK_REPLY_LEN) {
|
||||
return DeviceHandlerIF::LENGTH_MISSMATCH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::PING):
|
||||
case (BpxBattery::MAN_HEAT_ON):
|
||||
case (BpxBattery::MAN_HEAT_OFF): {
|
||||
case (bpxBat::PING):
|
||||
case (bpxBat::MAN_HEAT_ON):
|
||||
case (bpxBat::MAN_HEAT_OFF): {
|
||||
if (remainingSize != PING_REPLY_LEN) {
|
||||
return DeviceHandlerIF::LENGTH_MISSMATCH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::REBOOT): {
|
||||
case (bpxBat::REBOOT): {
|
||||
// Ignore
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::RESET_COUNTERS):
|
||||
case (BpxBattery::CONFIG_CMD):
|
||||
case (BpxBattery::CONFIG_SET): {
|
||||
case (bpxBat::RESET_COUNTERS):
|
||||
case (bpxBat::CONFIG_CMD):
|
||||
case (bpxBat::CONFIG_SET): {
|
||||
if (remainingSize != EMPTY_REPLY_LEN) {
|
||||
return DeviceHandlerIF::LENGTH_MISSMATCH;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::CONFIG_GET): {
|
||||
case (bpxBat::CONFIG_GET): {
|
||||
if (remainingSize != CONFIG_GET_REPLY_LEN) {
|
||||
return DeviceHandlerIF::LENGTH_MISSMATCH;
|
||||
}
|
||||
@ -187,11 +189,11 @@ ReturnValue_t BpxBatteryHandler::scanForReply(const uint8_t* start, size_t remai
|
||||
}
|
||||
|
||||
ReturnValue_t BpxBatteryHandler::interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) {
|
||||
if (id != BpxBattery::REBOOT and packet[1] != 0) {
|
||||
if (id != bpxBat::REBOOT and packet[1] != 0) {
|
||||
return DeviceHandlerIF::DEVICE_REPORTED_ERROR;
|
||||
}
|
||||
switch (id) {
|
||||
case (BpxBattery::GET_HK): {
|
||||
case (bpxBat::GET_HK): {
|
||||
PoolReadGuard rg(&hkSet);
|
||||
ReturnValue_t result = hkSet.parseRawHk(packet + 2, 21);
|
||||
hkSet.setValidity(true, true);
|
||||
@ -213,7 +215,7 @@ ReturnValue_t BpxBatteryHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::PING): {
|
||||
case (bpxBat::PING): {
|
||||
if (packet[2] != sentPingByte) {
|
||||
return DeviceHandlerIF::INVALID_DATA;
|
||||
}
|
||||
@ -222,19 +224,19 @@ ReturnValue_t BpxBatteryHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::RESET_COUNTERS):
|
||||
case (BpxBattery::CONFIG_CMD):
|
||||
case (BpxBattery::CONFIG_SET): {
|
||||
case (bpxBat::RESET_COUNTERS):
|
||||
case (bpxBat::CONFIG_CMD):
|
||||
case (bpxBat::CONFIG_SET): {
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::MAN_HEAT_ON):
|
||||
case (BpxBattery::MAN_HEAT_OFF): {
|
||||
case (bpxBat::MAN_HEAT_ON):
|
||||
case (bpxBat::MAN_HEAT_OFF): {
|
||||
if (packet[2] != 0x01) {
|
||||
return DeviceHandlerIF::DEVICE_DID_NOT_EXECUTE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::CONFIG_GET): {
|
||||
case (bpxBat::CONFIG_GET): {
|
||||
PoolReadGuard rg(&cfgSet);
|
||||
ReturnValue_t result = cfgSet.parseRawHk(packet + 2, 3);
|
||||
if (result != returnvalue::OK) {
|
||||
@ -243,7 +245,7 @@ ReturnValue_t BpxBatteryHandler::interpretDeviceReply(DeviceCommandId_t id, cons
|
||||
cfgSet.setValidity(true, true);
|
||||
break;
|
||||
}
|
||||
case (BpxBattery::REBOOT): {
|
||||
case (bpxBat::REBOOT): {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -257,20 +259,20 @@ uint32_t BpxBatteryHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo)
|
||||
|
||||
ReturnValue_t BpxBatteryHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||
LocalDataPoolManager& poolManager) {
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_1, &battTemp1);
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_2, &battTemp2);
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_3, &battTemp3);
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_TEMP_4, &battTemp4);
|
||||
localDataPoolMap.emplace(BpxBattery::CHARGE_CURRENT, &chargeCurrent);
|
||||
localDataPoolMap.emplace(BpxBattery::DISCHARGE_CURRENT, &dischargeCurrent);
|
||||
localDataPoolMap.emplace(BpxBattery::HEATER_CURRENT, &heaterCurrent);
|
||||
localDataPoolMap.emplace(BpxBattery::BATT_VOLTAGE, &battVolt);
|
||||
localDataPoolMap.emplace(BpxBattery::REBOOT_COUNTER, &rebootCounter);
|
||||
localDataPoolMap.emplace(BpxBattery::BOOTCAUSE, &bootCause);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_TEMP_1, &battTemp1);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_TEMP_2, &battTemp2);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_TEMP_3, &battTemp3);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_TEMP_4, &battTemp4);
|
||||
localDataPoolMap.emplace(bpxBat::CHARGE_CURRENT, &chargeCurrent);
|
||||
localDataPoolMap.emplace(bpxBat::DISCHARGE_CURRENT, &dischargeCurrent);
|
||||
localDataPoolMap.emplace(bpxBat::HEATER_CURRENT, &heaterCurrent);
|
||||
localDataPoolMap.emplace(bpxBat::BATT_VOLTAGE, &battVolt);
|
||||
localDataPoolMap.emplace(bpxBat::REBOOT_COUNTER, &rebootCounter);
|
||||
localDataPoolMap.emplace(bpxBat::BOOTCAUSE, &bootCause);
|
||||
|
||||
localDataPoolMap.emplace(BpxBattery::BATTERY_HEATER_MODE, &battheatMode);
|
||||
localDataPoolMap.emplace(BpxBattery::BATTHEAT_LOW_LIMIT, &battheatLow);
|
||||
localDataPoolMap.emplace(BpxBattery::BATTHEAT_HIGH_LIMIT, &battheatHigh);
|
||||
localDataPoolMap.emplace(bpxBat::BATTERY_HEATER_MODE, &battheatMode);
|
||||
localDataPoolMap.emplace(bpxBat::BATTHEAT_LOW_LIMIT, &battheatLow);
|
||||
localDataPoolMap.emplace(bpxBat::BATTHEAT_HIGH_LIMIT, &battheatHigh);
|
||||
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(hkSet.getSid(), enableHkSets, 20.0));
|
||||
|
@ -25,7 +25,7 @@ class BpxBatteryHandler : public DeviceHandlerBase {
|
||||
bool commandExecuted = false;
|
||||
bool debugMode = false;
|
||||
bool goToNormalModeImmediately = false;
|
||||
uint8_t sentPingByte = BpxBattery::DEFAULT_PING_SENT_BYTE;
|
||||
uint8_t sentPingByte = bpxBat::DEFAULT_PING_SENT_BYTE;
|
||||
#if OBSW_THREAD_TRACING == 1
|
||||
uint32_t opCounter = 0;
|
||||
#endif
|
||||
|
@ -166,9 +166,9 @@ ReturnValue_t P60DockHandler::initializeLocalDataPool(localpool::DataPool &local
|
||||
localDataPoolMap.emplace(pool::P60DOCK_ANT6_DEPL, new PoolEntry<int8_t>({0}));
|
||||
localDataPoolMap.emplace(pool::P60DOCK_AR6_DEPL, new PoolEntry<int8_t>({0}));
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 20.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 3000.0));
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -90,9 +90,9 @@ ReturnValue_t Pdu1Handler::initializeLocalDataPool(localpool::DataPool &localDat
|
||||
LocalDataPoolManager &poolManager) {
|
||||
initializePduPool(localDataPoolMap, poolManager, pcdu::INIT_SWITCHES_PDU1);
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 20.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 3000.0));
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -49,9 +49,9 @@ ReturnValue_t Pdu2Handler::initializeLocalDataPool(localpool::DataPool &localDat
|
||||
LocalDataPoolManager &poolManager) {
|
||||
initializePduPool(localDataPoolMap, poolManager, pcdu::INIT_SWITCHES_PDU2);
|
||||
poolManager.subscribeForDiagPeriodicPacket(
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 10.0));
|
||||
subdp::DiagnosticsHkPeriodicParams(coreHk.getSid(), enableHkSets, 30.0));
|
||||
poolManager.subscribeForRegularPeriodicPacket(
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 30.0));
|
||||
subdp::RegularHkPeriodicParams(auxHk.getSid(), enableHkSets, 6000.0));
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
||||
|
||||
namespace BpxBattery {
|
||||
namespace bpxBat {
|
||||
|
||||
enum LocalPoolIds {
|
||||
CHARGE_CURRENT = 0,
|
||||
@ -114,18 +114,18 @@ class BpxHkDeserializer : public SerialLinkedListAdapter<SerializeIF> {
|
||||
}
|
||||
};
|
||||
|
||||
}; // namespace BpxBattery
|
||||
}; // namespace bpxBat
|
||||
|
||||
/**
|
||||
* @brief BPX HK data holder
|
||||
*/
|
||||
class BpxBatteryHk : public StaticLocalDataSet<BpxBattery::HK_ENTRIES> {
|
||||
class BpxBatteryHk : public StaticLocalDataSet<bpxBat::HK_ENTRIES> {
|
||||
public:
|
||||
/**
|
||||
* Constructor for data users
|
||||
* @param gyroId
|
||||
*/
|
||||
BpxBatteryHk(object_id_t bpxId) : StaticLocalDataSet(sid_t(bpxId, BpxBattery::HK_SET_ID)) {
|
||||
BpxBatteryHk(object_id_t bpxId) : StaticLocalDataSet(sid_t(bpxId, bpxBat::HK_SET_ID)) {
|
||||
setAllVariablesReadOnly();
|
||||
}
|
||||
|
||||
@ -176,28 +176,25 @@ class BpxBatteryHk : public StaticLocalDataSet<BpxBattery::HK_ENTRIES> {
|
||||
}
|
||||
|
||||
//! Charge current in mA
|
||||
lp_var_t<uint16_t> chargeCurrent =
|
||||
lp_var_t<uint16_t>(sid.objectId, BpxBattery::CHARGE_CURRENT, this);
|
||||
lp_var_t<uint16_t> chargeCurrent = lp_var_t<uint16_t>(sid.objectId, bpxBat::CHARGE_CURRENT, this);
|
||||
//! Discharge current in mA
|
||||
lp_var_t<uint16_t> dischargeCurrent =
|
||||
lp_var_t<uint16_t>(sid.objectId, BpxBattery::DISCHARGE_CURRENT, this);
|
||||
lp_var_t<uint16_t>(sid.objectId, bpxBat::DISCHARGE_CURRENT, this);
|
||||
//! Heater current in mA
|
||||
lp_var_t<uint16_t> heaterCurrent =
|
||||
lp_var_t<uint16_t>(sid.objectId, BpxBattery::HEATER_CURRENT, this);
|
||||
lp_var_t<uint16_t> heaterCurrent = lp_var_t<uint16_t>(sid.objectId, bpxBat::HEATER_CURRENT, this);
|
||||
|
||||
//! Battery voltage in mV
|
||||
lp_var_t<uint16_t> battVoltage = lp_var_t<uint16_t>(sid.objectId, BpxBattery::BATT_VOLTAGE, this);
|
||||
lp_var_t<uint16_t> battVoltage = lp_var_t<uint16_t>(sid.objectId, bpxBat::BATT_VOLTAGE, this);
|
||||
//! Battery temperature 1 in degC
|
||||
lp_var_t<int16_t> battTemp1 = lp_var_t<int16_t>(sid.objectId, BpxBattery::BATT_TEMP_1, this);
|
||||
lp_var_t<int16_t> battTemp1 = lp_var_t<int16_t>(sid.objectId, bpxBat::BATT_TEMP_1, this);
|
||||
//! Battery temperature 2 in degC
|
||||
lp_var_t<int16_t> battTemp2 = lp_var_t<int16_t>(sid.objectId, BpxBattery::BATT_TEMP_2, this);
|
||||
lp_var_t<int16_t> battTemp2 = lp_var_t<int16_t>(sid.objectId, bpxBat::BATT_TEMP_2, this);
|
||||
//! Battery temperature 3 in degC
|
||||
lp_var_t<int16_t> battTemp3 = lp_var_t<int16_t>(sid.objectId, BpxBattery::BATT_TEMP_3, this);
|
||||
lp_var_t<int16_t> battTemp3 = lp_var_t<int16_t>(sid.objectId, bpxBat::BATT_TEMP_3, this);
|
||||
//! Battery temperature 4 in degC
|
||||
lp_var_t<int16_t> battTemp4 = lp_var_t<int16_t>(sid.objectId, BpxBattery::BATT_TEMP_4, this);
|
||||
lp_var_t<uint32_t> rebootCounter =
|
||||
lp_var_t<uint32_t>(sid.objectId, BpxBattery::REBOOT_COUNTER, this);
|
||||
lp_var_t<uint8_t> bootcause = lp_var_t<uint8_t>(sid.objectId, BpxBattery::BOOTCAUSE, this);
|
||||
lp_var_t<int16_t> battTemp4 = lp_var_t<int16_t>(sid.objectId, bpxBat::BATT_TEMP_4, this);
|
||||
lp_var_t<uint32_t> rebootCounter = lp_var_t<uint32_t>(sid.objectId, bpxBat::REBOOT_COUNTER, this);
|
||||
lp_var_t<uint8_t> bootcause = lp_var_t<uint8_t>(sid.objectId, bpxBat::BOOTCAUSE, this);
|
||||
|
||||
private:
|
||||
friend class BpxBatteryHandler;
|
||||
@ -205,16 +202,16 @@ class BpxBatteryHk : public StaticLocalDataSet<BpxBattery::HK_ENTRIES> {
|
||||
* Constructor for data creator
|
||||
* @param hkOwner
|
||||
*/
|
||||
BpxBatteryHk(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, BpxBattery::HK_SET_ID) {}
|
||||
BpxBatteryHk(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, bpxBat::HK_SET_ID) {}
|
||||
};
|
||||
|
||||
class BpxBatteryCfg : public StaticLocalDataSet<BpxBattery::CFG_ENTRIES> {
|
||||
class BpxBatteryCfg : public StaticLocalDataSet<bpxBat::CFG_ENTRIES> {
|
||||
public:
|
||||
/**
|
||||
* Constructor for data users
|
||||
* @param gyroId
|
||||
*/
|
||||
BpxBatteryCfg(object_id_t bpxId) : StaticLocalDataSet(sid_t(bpxId, BpxBattery::CFG_SET_ID)) {
|
||||
BpxBatteryCfg(object_id_t bpxId) : StaticLocalDataSet(sid_t(bpxId, bpxBat::CFG_SET_ID)) {
|
||||
setAllVariablesReadOnly();
|
||||
}
|
||||
|
||||
@ -230,13 +227,12 @@ class BpxBatteryCfg : public StaticLocalDataSet<BpxBattery::CFG_ENTRIES> {
|
||||
|
||||
//! Mode for battheater [0=OFF,1=Auto]
|
||||
lp_var_t<uint8_t> battheatermode =
|
||||
lp_var_t<uint8_t>(sid.objectId, BpxBattery::BATTERY_HEATER_MODE, this);
|
||||
lp_var_t<uint8_t>(sid.objectId, bpxBat::BATTERY_HEATER_MODE, this);
|
||||
//! Turn heater on at [degC]
|
||||
lp_var_t<int8_t> battheaterLow =
|
||||
lp_var_t<int8_t>(sid.objectId, BpxBattery::BATTHEAT_LOW_LIMIT, this);
|
||||
lp_var_t<int8_t> battheaterLow = lp_var_t<int8_t>(sid.objectId, bpxBat::BATTHEAT_LOW_LIMIT, this);
|
||||
//! Turn heater off at [degC]
|
||||
lp_var_t<int8_t> battheaterHigh =
|
||||
lp_var_t<int8_t>(sid.objectId, BpxBattery::BATTHEAT_HIGH_LIMIT, this);
|
||||
lp_var_t<int8_t>(sid.objectId, bpxBat::BATTHEAT_HIGH_LIMIT, this);
|
||||
|
||||
private:
|
||||
friend class BpxBatteryHandler;
|
||||
@ -244,8 +240,7 @@ class BpxBatteryCfg : public StaticLocalDataSet<BpxBattery::CFG_ENTRIES> {
|
||||
* Constructor for data creator
|
||||
* @param hkOwner
|
||||
*/
|
||||
BpxBatteryCfg(HasLocalDataPoolIF* hkOwner)
|
||||
: StaticLocalDataSet(hkOwner, BpxBattery::CFG_SET_ID) {}
|
||||
BpxBatteryCfg(HasLocalDataPoolIF* hkOwner) : StaticLocalDataSet(hkOwner, bpxBat::CFG_SET_ID) {}
|
||||
};
|
||||
|
||||
#endif /* MISSION_POWER_BPXBATTDEFS_H_ */
|
||||
|
@ -1,12 +1,79 @@
|
||||
#ifndef MISSION_SYSDEFS_H_
|
||||
#define MISSION_SYSDEFS_H_
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "acs/defs.h"
|
||||
|
||||
extern std::atomic_uint16_t I2C_FATAL_ERRORS;
|
||||
|
||||
namespace satsystem {
|
||||
|
||||
enum Mode : Mode_t { BOOT = 5, SAFE = acs::AcsMode::SAFE, PTG_IDLE = acs::AcsMode::PTG_IDLE };
|
||||
|
||||
}
|
||||
|
||||
namespace core {
|
||||
static constexpr ActionId_t LIST_DIRECTORY_INTO_FILE = 0;
|
||||
static constexpr ActionId_t ANNOUNCE_VERSION = 1;
|
||||
static constexpr ActionId_t ANNOUNCE_CURRENT_IMAGE = 2;
|
||||
static constexpr ActionId_t ANNOUNCE_BOOT_COUNTS = 3;
|
||||
static constexpr ActionId_t SWITCH_REBOOT_FILE_HANDLING = 5;
|
||||
static constexpr ActionId_t RESET_REBOOT_COUNTERS = 6;
|
||||
static constexpr ActionId_t SWITCH_IMG_LOCK = 7;
|
||||
static constexpr ActionId_t SET_MAX_REBOOT_CNT = 8;
|
||||
|
||||
static constexpr ActionId_t OBSW_UPDATE_FROM_SD_0 = 10;
|
||||
static constexpr ActionId_t OBSW_UPDATE_FROM_SD_1 = 11;
|
||||
static constexpr ActionId_t OBSW_UPDATE_FROM_TMP = 12;
|
||||
|
||||
static constexpr ActionId_t SWITCH_TO_SD_0 = 16;
|
||||
static constexpr ActionId_t SWITCH_TO_SD_1 = 17;
|
||||
static constexpr ActionId_t SWITCH_TO_BOTH_SD_CARDS = 18;
|
||||
|
||||
//! Reboot using the xsc_boot_copy command
|
||||
static constexpr ActionId_t XSC_REBOOT_OBC = 32;
|
||||
static constexpr ActionId_t MOUNT_OTHER_COPY = 33;
|
||||
//! Reboot using the reboot command
|
||||
static constexpr ActionId_t REBOOT_OBC = 34;
|
||||
|
||||
static constexpr ActionId_t EXECUTE_SHELL_CMD = 40;
|
||||
|
||||
static constexpr uint8_t SUBSYSTEM_ID = SUBSYSTEM_ID::CORE;
|
||||
|
||||
static constexpr Event ALLOC_FAILURE = event::makeEvent(SUBSYSTEM_ID, 0, severity::MEDIUM);
|
||||
//! [EXPORT] : [COMMENT] Software reboot occurred. Can also be a systemd reboot.
|
||||
//! P1: Current Chip, P2: Current Copy
|
||||
static constexpr Event REBOOT_SW = event::makeEvent(SUBSYSTEM_ID, 1, severity::LOW);
|
||||
//! [EXPORT] : [COMMENT] The reboot mechanism was triggered.
|
||||
//! P1: First 16 bits: Last Chip, Last 16 bits: Last Copy,
|
||||
//! P2: Each byte is the respective reboot count for the slots
|
||||
static constexpr Event REBOOT_MECHANISM_TRIGGERED =
|
||||
event::makeEvent(SUBSYSTEM_ID, 2, severity::MEDIUM);
|
||||
//! Trying to find a way how to determine that the reboot came from ProASIC3 or PCDU..
|
||||
static constexpr Event REBOOT_HW = event::makeEvent(SUBSYSTEM_ID, 3, severity::MEDIUM);
|
||||
//! [EXPORT] : [COMMENT] No SD card was active. Core controller will attempt to re-initialize
|
||||
//! a SD card.
|
||||
static constexpr Event NO_SD_CARD_ACTIVE = event::makeEvent(SUBSYSTEM_ID, 4, severity::HIGH);
|
||||
//! [EXPORT] : [COMMENT]
|
||||
//! P1: Byte 0: Major, Byte 1: Minor, Byte 2: Patch, Byte 3: Has Git Hash
|
||||
//! P2: First four letters of Git SHA is the last byte of P1 is set.
|
||||
static constexpr Event VERSION_INFO = event::makeEvent(SUBSYSTEM_ID, 5, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] P1: Current Chip, P2: Current Copy
|
||||
static constexpr Event CURRENT_IMAGE_INFO = event::makeEvent(SUBSYSTEM_ID, 6, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Total reboot counter, which is the sum of the boot count of all
|
||||
//! individual images.
|
||||
static constexpr Event REBOOT_COUNTER = event::makeEvent(SUBSYSTEM_ID, 7, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] Get the boot count of the individual images.
|
||||
//! P1: First 16 bits boot count of image 0 0, last 16 bits boot count of image 0 1.
|
||||
//! P2: First 16 bits boot count of image 1 0, last 16 bits boot count of image 1 1.
|
||||
static constexpr Event INDIVIDUAL_BOOT_COUNTS = event::makeEvent(SUBSYSTEM_ID, 8, severity::INFO);
|
||||
//! [EXPORT] : [COMMENT] I2C is unavailable. Trying recovery of I2C bus by power cycling all I2C
|
||||
//! devices.
|
||||
static constexpr Event TRYING_I2C_RECOVERY = event::makeEvent(SUBSYSTEM_ID, 10, severity::MEDIUM);
|
||||
//! [EXPORT] : [COMMENT] I2C is unavailable. Recovery did not work, performing full reboot.
|
||||
static constexpr Event I2C_REBOOT = event::makeEvent(SUBSYSTEM_ID, 11, severity::MEDIUM);
|
||||
|
||||
} // namespace core
|
||||
|
||||
#endif /* MISSION_SYSDEFS_H_ */
|
||||
|
@ -5,4 +5,6 @@ add_subdirectory(com)
|
||||
add_subdirectory(fdir)
|
||||
add_subdirectory(power)
|
||||
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE DualLanePowerStateMachine.cpp)
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION} PRIVATE systemTree.cpp DualLanePowerStateMachine.cpp
|
||||
EiveSystem.cpp treeUtil.cpp)
|
||||
|
278
mission/system/EiveSystem.cpp
Normal file
278
mission/system/EiveSystem.cpp
Normal file
@ -0,0 +1,278 @@
|
||||
#include "EiveSystem.h"
|
||||
|
||||
#include <eive/objects.h>
|
||||
#include <fsfw/events/EventManager.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
#include <mission/acs/defs.h>
|
||||
#include <mission/com/defs.h>
|
||||
#include <mission/controller/tcsDefs.h>
|
||||
|
||||
#include "mission/power/bpxBattDefs.h"
|
||||
#include "mission/power/defs.h"
|
||||
#include "mission/sysDefs.h"
|
||||
|
||||
EiveSystem::EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
|
||||
uint32_t maxNumberOfTables, std::atomic_uint16_t& i2cErrors)
|
||||
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables),
|
||||
actionHelper(this, commandQueue),
|
||||
i2cErrors(i2cErrors) {
|
||||
auto mqArgs = MqArgs(SubsystemBase::getObjectId(), static_cast<void*>(this));
|
||||
eventQueue =
|
||||
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
}
|
||||
|
||||
void EiveSystem::announceMode(bool recursive) {
|
||||
const char* modeStr = "UNKNOWN";
|
||||
switch (mode) {
|
||||
case (satsystem::Mode::BOOT): {
|
||||
modeStr = "OFF/BOOT";
|
||||
break;
|
||||
}
|
||||
case (satsystem::Mode::SAFE): {
|
||||
modeStr = "SAFE";
|
||||
break;
|
||||
}
|
||||
case (satsystem::Mode::PTG_IDLE): {
|
||||
modeStr = "POINTING IDLE";
|
||||
break;
|
||||
}
|
||||
case (acs::AcsMode::PTG_INERTIAL): {
|
||||
modeStr = "POINTING INERTIAL";
|
||||
break;
|
||||
}
|
||||
case (acs::AcsMode::PTG_TARGET): {
|
||||
modeStr = "POINTING TARGET";
|
||||
break;
|
||||
}
|
||||
case (acs::AcsMode::PTG_TARGET_GS): {
|
||||
modeStr = "POINTING TARGET GS";
|
||||
break;
|
||||
}
|
||||
}
|
||||
sif::info << "EIVE system is now in " << modeStr << " mode" << std::endl;
|
||||
return Subsystem::announceMode(recursive);
|
||||
}
|
||||
|
||||
void EiveSystem::performChildOperation() {
|
||||
Subsystem::performChildOperation();
|
||||
handleEventMessages();
|
||||
if (not isInTransition and performSafeRecovery) {
|
||||
commandSelfToSafe();
|
||||
performSafeRecovery = false;
|
||||
return;
|
||||
}
|
||||
i2cRecoveryLogic();
|
||||
}
|
||||
|
||||
ReturnValue_t EiveSystem::initialize() {
|
||||
if (powerSwitcher == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
ReturnValue_t result = actionHelper.initialize();
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
auto* bpxDest = ObjectManager::instance()->get<HasActionsIF>(objects::BPX_BATT_HANDLER);
|
||||
if (bpxDest == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
bpxBattQueueId = bpxDest->getCommandQueue();
|
||||
|
||||
auto* coreCtrl = ObjectManager::instance()->get<HasActionsIF>(objects::CORE_CONTROLLER);
|
||||
if (coreCtrl == nullptr) {
|
||||
return ObjectManager::CHILD_INIT_FAILED;
|
||||
}
|
||||
coreCtrlQueueId = coreCtrl->getCommandQueue();
|
||||
|
||||
auto* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||
if (manager == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "AcsSubsystem::initialize: Invalid event manager" << std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
result = manager->registerListener(eventQueue->getId());
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "AcsSubsystem::registerListener: Failed to register as "
|
||||
"listener"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
manager->subscribeToEvent(eventQueue->getId(),
|
||||
event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING));
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING));
|
||||
|
||||
// manager->subscribeToEvent(eventQueue->getId(), event::getEventId(CoreController::))
|
||||
return Subsystem::initialize();
|
||||
}
|
||||
|
||||
void EiveSystem::handleEventMessages() {
|
||||
EventMessage event;
|
||||
for (ReturnValue_t status = eventQueue->receiveMessage(&event); status == returnvalue::OK;
|
||||
status = eventQueue->receiveMessage(&event)) {
|
||||
switch (event.getMessageId()) {
|
||||
case EventMessage::EVENT_MESSAGE:
|
||||
switch (event.getEvent()) {
|
||||
case tcsCtrl::OBC_OVERHEATING:
|
||||
case tcsCtrl::PCDU_SYSTEM_OVERHEATING: {
|
||||
if (isInTransition) {
|
||||
performSafeRecovery = true;
|
||||
return;
|
||||
}
|
||||
|
||||
commandSelfToSafe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sif::debug << "EiveSystem: Did not subscribe to event " << event.getEvent() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MessageQueueId_t EiveSystem::getCommandQueue() const { return Subsystem::getCommandQueue(); }
|
||||
|
||||
ReturnValue_t EiveSystem::executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) {
|
||||
switch (actionId) {
|
||||
case (EXECUTE_I2C_REBOOT): {
|
||||
triggerEvent(core::TRYING_I2C_RECOVERY);
|
||||
performI2cReboot = true;
|
||||
i2cRebootState = I2cRebootState::SYSTEM_MODE_BOOT;
|
||||
this->actionCommandedBy = commandedBy;
|
||||
return returnvalue::OK;
|
||||
}
|
||||
default: {
|
||||
return HasActionsIF::INVALID_ACTION_ID;
|
||||
}
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
void EiveSystem::setI2cRecoveryParams(PowerSwitchIF* pwrSwitcher) {
|
||||
this->powerSwitcher = pwrSwitcher;
|
||||
}
|
||||
|
||||
void EiveSystem::i2cRecoveryLogic() {
|
||||
ReturnValue_t result;
|
||||
if (not performI2cReboot) {
|
||||
// If a recovery worked, need to reset these flags and the error count after some time.
|
||||
if (i2cRecoveryClearCountdown.hasTimedOut()) {
|
||||
i2cErrors = 0;
|
||||
alreadyTriedI2cRecovery = false;
|
||||
i2cRebootHandlingCountdown.resetTimer();
|
||||
}
|
||||
// If an I2C recovery is not ongoing and the I2C error counter is above a threshold, try
|
||||
// recovery or reboot if recovery was already attempted.
|
||||
if (i2cErrors >= 5) {
|
||||
if (not alreadyTriedI2cRecovery) {
|
||||
// Try recovery.
|
||||
executeAction(EXECUTE_I2C_REBOOT, MessageQueueIF::NO_QUEUE, nullptr, 0);
|
||||
} else {
|
||||
// We already tried an I2C recovery but the bus is still broken.
|
||||
// Send full reboot request to core controller.
|
||||
CommandMessage msg;
|
||||
ActionMessage::setCommand(&msg, core::REBOOT_OBC, store_address_t());
|
||||
result = commandQueue->sendMessage(coreCtrlQueueId, &msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (not isInTransition and performI2cReboot) {
|
||||
switch (i2cRebootState) {
|
||||
case (I2cRebootState::NONE): {
|
||||
break;
|
||||
}
|
||||
case (I2cRebootState::SYSTEM_MODE_BOOT): {
|
||||
startTransition(satsystem::Mode::BOOT, 0);
|
||||
i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT;
|
||||
i2cRebootHandlingCountdown.resetTimer();
|
||||
break;
|
||||
}
|
||||
case (I2cRebootState::SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT): {
|
||||
if (mode == satsystem::Mode::BOOT) {
|
||||
result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
|
||||
PowerSwitchIF::SWITCH_OFF);
|
||||
if (result != returnvalue::OK) {
|
||||
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
|
||||
commonI2cRecoverySequenceFinish();
|
||||
return;
|
||||
}
|
||||
CommandMessage msg;
|
||||
store_address_t dummy{};
|
||||
ActionMessage::setCommand(&msg, bpxBat::REBOOT, dummy);
|
||||
result = commandQueue->sendMessage(bpxBattQueueId, &msg);
|
||||
if (result != returnvalue::OK) {
|
||||
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
|
||||
commonI2cRecoverySequenceFinish();
|
||||
return;
|
||||
}
|
||||
i2cRebootState = I2cRebootState::WAIT_CYCLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (I2cRebootState::WAIT_CYCLE): {
|
||||
i2cRebootState = I2cRebootState::SWITCH_3V3_STACK_ON;
|
||||
break;
|
||||
}
|
||||
case (I2cRebootState::SWITCH_3V3_STACK_ON): {
|
||||
result = powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
|
||||
PowerSwitchIF::SWITCH_ON);
|
||||
if (result != returnvalue::OK) {
|
||||
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, result);
|
||||
commonI2cRecoverySequenceFinish();
|
||||
return;
|
||||
}
|
||||
i2cRebootState = I2cRebootState::SYSTEM_MODE_SAFE;
|
||||
break;
|
||||
}
|
||||
case (I2cRebootState::SYSTEM_MODE_SAFE): {
|
||||
if (powerSwitcher->getSwitchState(power::Switches::P60_DOCK_3V3_STACK) ==
|
||||
PowerSwitchIF::SWITCH_ON) {
|
||||
// This should always be accepted
|
||||
commonI2cRecoverySequenceFinish();
|
||||
actionHelper.finish(true, actionCommandedBy, EXECUTE_I2C_REBOOT);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
sif::error << "EiveSystem: Unexpected I2C reboot state" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Timeout handling for the internal procedure.
|
||||
if (i2cRebootState != I2cRebootState::NONE and i2cRebootHandlingCountdown.hasTimedOut()) {
|
||||
actionHelper.finish(false, actionCommandedBy, EXECUTE_I2C_REBOOT, returnvalue::FAILED);
|
||||
// Command stack back on in any case.
|
||||
powerSwitcher->sendSwitchCommand(power::Switches::P60_DOCK_3V3_STACK,
|
||||
PowerSwitchIF::SWITCH_ON);
|
||||
commonI2cRecoverySequenceFinish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); }
|
||||
|
||||
void EiveSystem::commonI2cRecoverySequenceFinish() {
|
||||
alreadyTriedI2cRecovery = true;
|
||||
performI2cReboot = false;
|
||||
i2cRebootState = I2cRebootState::NONE;
|
||||
// Reset this counter and the recovery clear countdown. If I2C devices are still problematic,
|
||||
// we will get a full reboot next time this count goes above 5.
|
||||
i2cErrors = 0;
|
||||
i2cRecoveryClearCountdown.resetTimer();
|
||||
// This should always be accepted
|
||||
commandSelfToSafe();
|
||||
}
|
||||
|
||||
ReturnValue_t EiveSystem::handleCommandMessage(CommandMessage* message) {
|
||||
if (message->getMessageType() == messagetypes::ACTION) {
|
||||
return actionHelper.handleActionMessage(message);
|
||||
}
|
||||
return Subsystem::handleCommandMessage(message);
|
||||
}
|
60
mission/system/EiveSystem.h
Normal file
60
mission/system/EiveSystem.h
Normal file
@ -0,0 +1,60 @@
|
||||
#ifndef MISSION_SYSTEM_EIVESYSTEM_H_
|
||||
#define MISSION_SYSTEM_EIVESYSTEM_H_
|
||||
|
||||
#include <fsfw/action/HasActionsIF.h>
|
||||
#include <fsfw/power/PowerSwitchIF.h>
|
||||
#include <fsfw/subsystem/Subsystem.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
class EiveSystem : public Subsystem, public HasActionsIF {
|
||||
public:
|
||||
static constexpr ActionId_t EXECUTE_I2C_REBOOT = 10;
|
||||
|
||||
EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables,
|
||||
std::atomic_uint16_t& i2cErrors);
|
||||
|
||||
void setI2cRecoveryParams(PowerSwitchIF* pwrSwitcher);
|
||||
|
||||
[[nodiscard]] MessageQueueId_t getCommandQueue() const override;
|
||||
|
||||
private:
|
||||
enum class I2cRebootState {
|
||||
NONE,
|
||||
SYSTEM_MODE_BOOT,
|
||||
SWITCH_3V3_STACK_OFF_AND_BATT_REBOOT,
|
||||
WAIT_CYCLE,
|
||||
SWITCH_3V3_STACK_ON,
|
||||
SYSTEM_MODE_SAFE
|
||||
} i2cRebootState = I2cRebootState::NONE;
|
||||
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
bool performSafeRecovery = false;
|
||||
bool performI2cReboot = false;
|
||||
bool alreadyTriedI2cRecovery = false;
|
||||
|
||||
ActionHelper actionHelper;
|
||||
PowerSwitchIF* powerSwitcher = nullptr;
|
||||
std::atomic_uint16_t& i2cErrors;
|
||||
|
||||
MessageQueueId_t bpxBattQueueId = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t coreCtrlQueueId = MessageQueueIF::NO_QUEUE;
|
||||
MessageQueueId_t actionCommandedBy = MessageQueueIF::NO_QUEUE;
|
||||
Countdown i2cRebootHandlingCountdown = Countdown(10000);
|
||||
// After 1 minute, clear the flag to avoid full reboots on I2C issues.
|
||||
Countdown i2cRecoveryClearCountdown = Countdown(60000);
|
||||
ReturnValue_t initialize() override;
|
||||
void performChildOperation() override;
|
||||
void announceMode(bool recursive) override;
|
||||
|
||||
ReturnValue_t executeAction(ActionId_t actionId, MessageQueueId_t commandedBy,
|
||||
const uint8_t* data, size_t size) override;
|
||||
ReturnValue_t handleCommandMessage(CommandMessage* message) override;
|
||||
|
||||
void i2cRecoveryLogic();
|
||||
void handleEventMessages();
|
||||
void commandSelfToSafe();
|
||||
void commonI2cRecoverySequenceFinish();
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */
|
@ -57,8 +57,8 @@ ReturnValue_t AcsBoardAssembly::commandChildren(Mode_t mode, Submode_t submode)
|
||||
modeTable[ModeTableIdx::GPS].setSubmode(SUBMODE_NONE);
|
||||
if (recoveryState == RecoveryState::RECOVERY_IDLE) {
|
||||
result = checkAndHandleHealthStates(mode, submode);
|
||||
if (result == NEED_TO_CHANGE_HEALTH) {
|
||||
return returnvalue::OK;
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (recoveryState != RecoveryState::RECOVERY_STARTED) {
|
||||
@ -238,7 +238,7 @@ void AcsBoardAssembly::refreshHelperModes() {
|
||||
helper.gyro0SideAMode = childrenMap.at(helper.gyro0AdisIdSideA).mode;
|
||||
helper.gyro1SideAMode = childrenMap.at(helper.gyro1L3gIdSideA).mode;
|
||||
helper.gyro2SideBMode = childrenMap.at(helper.gyro2AdisIdSideB).mode;
|
||||
helper.gyro3SideBMode = childrenMap.at(helper.gyro2AdisIdSideB).mode;
|
||||
helper.gyro3SideBMode = childrenMap.at(helper.gyro3L3gIdSideB).mode;
|
||||
helper.mgm0SideAMode = childrenMap.at(helper.mgm0Lis3IdSideA).mode;
|
||||
helper.mgm1SideAMode = childrenMap.at(helper.mgm1Rm3100IdSideA).mode;
|
||||
helper.mgm2SideBMode = childrenMap.at(helper.mgm2Lis3IdSideB).mode;
|
||||
@ -256,22 +256,57 @@ ReturnValue_t AcsBoardAssembly::initialize() {
|
||||
return AssemblyBase::initialize();
|
||||
}
|
||||
|
||||
ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
|
||||
Submode_t deviceSubmode) {
|
||||
ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t commandedMode,
|
||||
Submode_t commandedSubmode) {
|
||||
using namespace returnvalue;
|
||||
ReturnValue_t status = returnvalue::OK;
|
||||
bool healthNeedsToBeOverwritten = false;
|
||||
auto checkAcsBoardSensorGroup = [&](object_id_t o0, object_id_t o1, object_id_t o2,
|
||||
object_id_t o3) {
|
||||
HealthState h0 = healthHelper.healthTable->getHealth(o0);
|
||||
HealthState h1 = healthHelper.healthTable->getHealth(o1);
|
||||
HealthState h2 = healthHelper.healthTable->getHealth(o2);
|
||||
HealthState h3 = healthHelper.healthTable->getHealth(o3);
|
||||
// All device are faulty or permanent faulty, but this is a safe mode assembly, so we need
|
||||
// to restore the devices.
|
||||
if ((h0 == FAULTY or h0 == PERMANENT_FAULTY) and (h1 == FAULTY or h1 == PERMANENT_FAULTY) and
|
||||
(h2 == FAULTY or h2 == PERMANENT_FAULTY) and (h3 == FAULTY or h3 == PERMANENT_FAULTY)) {
|
||||
overwriteDeviceHealth(o0, h0);
|
||||
overwriteDeviceHealth(o1, h1);
|
||||
overwriteDeviceHealth(o2, h2);
|
||||
overwriteDeviceHealth(o3, h3);
|
||||
uint8_t numPermFaulty = 0;
|
||||
if (h0 == PERMANENT_FAULTY) {
|
||||
numPermFaulty++;
|
||||
}
|
||||
if (h1 == PERMANENT_FAULTY) {
|
||||
numPermFaulty++;
|
||||
}
|
||||
if (h2 == PERMANENT_FAULTY) {
|
||||
numPermFaulty++;
|
||||
}
|
||||
if (h3 == PERMANENT_FAULTY) {
|
||||
numPermFaulty++;
|
||||
}
|
||||
if (numPermFaulty < 4) {
|
||||
// Some are faulty and some are permanent faulty, so only set faulty ones to
|
||||
// EXTERNAL_CONTROL.
|
||||
if (h0 == FAULTY) {
|
||||
overwriteDeviceHealth(o0, h0);
|
||||
}
|
||||
if (h1 == FAULTY) {
|
||||
overwriteDeviceHealth(o1, h1);
|
||||
}
|
||||
if (h2 == FAULTY) {
|
||||
overwriteDeviceHealth(o2, h2);
|
||||
}
|
||||
if (h3 == FAULTY) {
|
||||
overwriteDeviceHealth(o3, h3);
|
||||
}
|
||||
} else {
|
||||
// All permanent faulty, so set all to EXTERNAL_CONTROL
|
||||
overwriteDeviceHealth(o0, h0);
|
||||
overwriteDeviceHealth(o1, h1);
|
||||
overwriteDeviceHealth(o2, h2);
|
||||
overwriteDeviceHealth(o3, h3);
|
||||
}
|
||||
healthNeedsToBeOverwritten = true;
|
||||
}
|
||||
if (h0 == EXTERNAL_CONTROL or h1 == EXTERNAL_CONTROL or h2 == EXTERNAL_CONTROL or
|
||||
h3 == EXTERNAL_CONTROL) {
|
||||
@ -285,6 +320,7 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
|
||||
if (healthHelper.healthTable->getHealth(helper.healthDevGps0) == PERMANENT_FAULTY and
|
||||
healthHelper.healthTable->getHealth(helper.healthDevGps1) == FAULTY) {
|
||||
overwriteDeviceHealth(helper.healthDevGps1, FAULTY);
|
||||
healthNeedsToBeOverwritten = true;
|
||||
} else if (healthHelper.healthTable->getHealth(helper.healthDevGps1) == PERMANENT_FAULTY and
|
||||
healthHelper.healthTable->getHealth(helper.healthDevGps0) == FAULTY) {
|
||||
overwriteDeviceHealth(helper.healthDevGps0, FAULTY);
|
||||
@ -294,14 +330,24 @@ ReturnValue_t AcsBoardAssembly::checkAndHandleHealthStates(Mode_t deviceMode,
|
||||
healthHelper.healthTable->getHealth(helper.healthDevGps0));
|
||||
overwriteDeviceHealth(helper.healthDevGps1,
|
||||
healthHelper.healthTable->getHealth(helper.healthDevGps1));
|
||||
healthNeedsToBeOverwritten = true;
|
||||
}
|
||||
|
||||
if (deviceSubmode == duallane::DUAL_MODE) {
|
||||
if (commandedSubmode == duallane::DUAL_MODE) {
|
||||
checkAcsBoardSensorGroup(helper.mgm0Lis3IdSideA, helper.mgm1Rm3100IdSideA,
|
||||
helper.mgm2Lis3IdSideB, helper.mgm3Rm3100IdSideB);
|
||||
checkAcsBoardSensorGroup(helper.gyro0AdisIdSideA, helper.gyro1L3gIdSideA,
|
||||
|
||||
helper.gyro2AdisIdSideB, helper.gyro3L3gIdSideB);
|
||||
}
|
||||
if (healthNeedsToBeOverwritten) {
|
||||
// If we are overwriting the health states, we are already in a transition to dual mode,
|
||||
// and we would like that transition to complete. The default behaviour is to go back to the
|
||||
// old mode. We force our behaviour by overwriting the internal modes.
|
||||
mode = commandedMode;
|
||||
submode = commandedSubmode;
|
||||
return NEED_TO_CHANGE_HEALTH;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,8 @@ void DualLaneAssemblyBase::performChildOperation() {
|
||||
void DualLaneAssemblyBase::startTransition(Mode_t mode, Submode_t submode) {
|
||||
using namespace duallane;
|
||||
pwrStateMachine.reset();
|
||||
dualToSingleSideTransition = false;
|
||||
sideSwitchState = SideSwitchState::NONE;
|
||||
|
||||
if (mode != MODE_OFF) {
|
||||
// Special exception: A transition from dual side to single mode must be handled like
|
||||
@ -112,8 +114,11 @@ ReturnValue_t DualLaneAssemblyBase::pwrStateMachineWrapper() {
|
||||
|
||||
ReturnValue_t DualLaneAssemblyBase::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
using namespace duallane;
|
||||
if (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE) {
|
||||
return returnvalue::FAILED;
|
||||
if (mode != MODE_OFF and (submode != A_SIDE and submode != B_SIDE and submode != DUAL_MODE)) {
|
||||
return HasModesIF::INVALID_SUBMODE;
|
||||
}
|
||||
if (mode == MODE_OFF and submode != SUBMODE_NONE) {
|
||||
return HasModesIF::INVALID_SUBMODE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -70,7 +70,8 @@ class DualLaneAssemblyBase : public AssemblyBase, public ConfirmsFailuresIF {
|
||||
* @param submode
|
||||
*/
|
||||
virtual ReturnValue_t pwrStateMachineWrapper();
|
||||
virtual ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
|
||||
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
|
||||
|
||||
/**
|
||||
* Custom recovery implementation to ensure that the power lines are commanded off for a
|
||||
* recovery.
|
||||
|
@ -18,7 +18,7 @@ ReturnValue_t ImtqAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
if (recoveryState == RECOVERY_IDLE) {
|
||||
ReturnValue_t result = checkAndHandleHealthState(mode, submode);
|
||||
if (result == NEED_TO_CHANGE_HEALTH) {
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
HybridIterator<ModeListEntry> iter(commandTable.begin(), commandTable.end());
|
||||
@ -35,9 +35,12 @@ ReturnValue_t ImtqAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wa
|
||||
|
||||
ReturnValue_t ImtqAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_OFF) {
|
||||
if (submode != SUBMODE_NONE) {
|
||||
return HasModesIF::INVALID_SUBMODE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
return returnvalue::FAILED;
|
||||
return HasModesIF::INVALID_MODE;
|
||||
}
|
||||
|
||||
ReturnValue_t ImtqAssembly::checkAndHandleHealthState(Mode_t deviceMode, Submode_t deviceSubmode) {
|
||||
|
@ -56,12 +56,12 @@ ReturnValue_t RwAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t want
|
||||
}
|
||||
}
|
||||
} catch (const std::out_of_range& e) {
|
||||
sif::error << "RwAssembly: Invalid children map: " << e.what() << std::endl;
|
||||
sif::error << "RW ASSY: Invalid children map: " << e.what() << std::endl;
|
||||
}
|
||||
if (devsInCorrectMode < 3) {
|
||||
if (warningSwitch) {
|
||||
sif::warning << "RwAssembly::checkChildrenStateOn: Only " << devsInCorrectMode
|
||||
<< " devices in correct mode" << std::endl;
|
||||
sif::warning << "RW ASSY: Only " << devsInCorrectMode << " devices in correct mode"
|
||||
<< std::endl;
|
||||
warningSwitch = false;
|
||||
}
|
||||
return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
|
||||
@ -106,46 +106,18 @@ void RwAssembly::handleModeReached() {
|
||||
}
|
||||
}
|
||||
|
||||
void RwAssembly::handleChildrenLostMode(ReturnValue_t result) {
|
||||
AssemblyBase::handleChildrenLostMode(result);
|
||||
}
|
||||
|
||||
ReturnValue_t RwAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode) {
|
||||
ReturnValue_t result = returnvalue::OK;
|
||||
bool needsSecondStep = false;
|
||||
Mode_t devMode = 0;
|
||||
object_id_t objId = 0;
|
||||
try {
|
||||
for (uint8_t idx = 0; idx < NUMBER_RWS; idx++) {
|
||||
devMode = childrenMap.at(helper.rwIds[idx]).mode;
|
||||
objId = helper.rwIds[idx];
|
||||
if (mode == devMode) {
|
||||
if (isUseable(objId, mode)) {
|
||||
modeTable[idx].setMode(mode);
|
||||
} else if (mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
if (isUseable(objId, devMode)) {
|
||||
if (devMode == MODE_ON) {
|
||||
modeTable[idx].setMode(mode);
|
||||
modeTable[idx].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
modeTable[idx].setMode(MODE_ON);
|
||||
modeTable[idx].setSubmode(SUBMODE_NONE);
|
||||
if (internalState != STATE_SECOND_STEP) {
|
||||
needsSecondStep = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mode == MODE_ON) {
|
||||
if (isUseable(objId, devMode)) {
|
||||
modeTable[idx].setMode(MODE_ON);
|
||||
modeTable[idx].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
modeTable[idx].setSubmode(submode);
|
||||
}
|
||||
}
|
||||
} catch (const std::out_of_range& e) {
|
||||
sif::error << "TcsBoardAssembly: Invalid children map: " << e.what() << std::endl;
|
||||
}
|
||||
if (needsSecondStep) {
|
||||
result = NEED_SECOND_STEP;
|
||||
sif::error << "RW ASSY: Invalid children map: " << e.what() << std::endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -172,15 +144,3 @@ ReturnValue_t RwAssembly::initialize() {
|
||||
}
|
||||
return AssemblyBase::initialize();
|
||||
}
|
||||
|
||||
void RwAssembly::handleModeTransitionFailed(ReturnValue_t result) {
|
||||
if (targetMode == MODE_OFF) {
|
||||
AssemblyBase::handleModeTransitionFailed(result);
|
||||
} else {
|
||||
if (modeTransitionFailedSwitch) {
|
||||
// To avoid transitioning back to off
|
||||
triggerEvent(MODE_TRANSITION_FAILED, result);
|
||||
modeTransitionFailedSwitch = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,11 +41,6 @@ class RwAssembly : public AssemblyBase {
|
||||
ReturnValue_t isModeCombinationValid(Mode_t mode, Submode_t submode) override;
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
void handleModeReached() override;
|
||||
|
||||
// These two overrides prevent a transition of the whole assembly back to off just because
|
||||
// some devices are not working
|
||||
void handleChildrenLostMode(ReturnValue_t result) override;
|
||||
void handleModeTransitionFailed(ReturnValue_t result) override;
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_RWASS_H_ */
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
#include <eive/objects.h>
|
||||
|
||||
#include "mission/acs/str/strHelpers.h"
|
||||
|
||||
StrAssembly::StrAssembly(object_id_t objectId) : AssemblyBase(objectId) {
|
||||
ModeListEntry entry;
|
||||
entry.setObject(objects::STAR_TRACKER);
|
||||
@ -31,5 +33,12 @@ ReturnValue_t StrAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wan
|
||||
}
|
||||
|
||||
ReturnValue_t StrAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
if ((mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_OFF) and submode != SUBMODE_NONE) {
|
||||
return HasModesIF::INVALID_SUBMODE;
|
||||
}
|
||||
if (mode == MODE_ON and
|
||||
(submode != startracker::SUBMODE_BOOTLOADER and submode != startracker::SUBMODE_FIRMWARE)) {
|
||||
return HasModesIF::INVALID_SUBMODE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
@ -26,8 +26,8 @@ ReturnValue_t SusAssembly::commandChildren(Mode_t mode, Submode_t submode) {
|
||||
}
|
||||
if (recoveryState == RecoveryState::RECOVERY_IDLE) {
|
||||
result = checkAndHandleHealthStates(mode, submode);
|
||||
if (result == NEED_TO_CHANGE_HEALTH) {
|
||||
return returnvalue::OK;
|
||||
if (result != returnvalue::OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (recoveryState != RecoveryState::RECOVERY_STARTED) {
|
||||
@ -47,26 +47,9 @@ ReturnValue_t SusAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t submod
|
||||
bool needsSecondStep = false;
|
||||
handleSideSwitchStates(submode, needsSecondStep);
|
||||
auto cmdSeq = [&](object_id_t objectId, Mode_t devMode, uint8_t tableIdx) {
|
||||
if (mode == devMode) {
|
||||
if (isModeCommandable(objectId, devMode)) {
|
||||
modeTable[tableIdx].setMode(mode);
|
||||
} else if (mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
if (isUseable(objectId, devMode)) {
|
||||
if (devMode == MODE_ON) {
|
||||
modeTable[tableIdx].setMode(mode);
|
||||
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
|
||||
} else {
|
||||
modeTable[tableIdx].setMode(MODE_ON);
|
||||
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
|
||||
if (internalState != STATE_SECOND_STEP) {
|
||||
needsSecondStep = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (mode == MODE_ON) {
|
||||
if (isUseable(objectId, devMode)) {
|
||||
modeTable[tableIdx].setMode(MODE_ON);
|
||||
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
modeTable[tableIdx].setSubmode(SUBMODE_NONE);
|
||||
}
|
||||
};
|
||||
switch (submode) {
|
||||
@ -134,38 +117,31 @@ ReturnValue_t SusAssembly::initialize() {
|
||||
return AssemblyBase::initialize();
|
||||
}
|
||||
|
||||
bool SusAssembly::isUseable(object_id_t object, Mode_t mode) {
|
||||
if (healthHelper.healthTable->isFaulty(object)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if device is already in target mode
|
||||
if (childrenMap[object].mode == mode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (healthHelper.healthTable->isCommandable(object)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SusAssembly::refreshHelperModes() {
|
||||
for (uint8_t idx = 0; idx < helper.susModes.size(); idx++) {
|
||||
helper.susModes[idx] = childrenMap[helper.susIds[idx]].mode;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t deviceMode, Submode_t deviceSubmode) {
|
||||
ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t commandedMode,
|
||||
Submode_t commandedSubmode) {
|
||||
using namespace returnvalue;
|
||||
ReturnValue_t status = returnvalue::OK;
|
||||
bool needsHealthOverwritten = false;
|
||||
auto checkSusGroup = [&](object_id_t devNom, object_id_t devRed) {
|
||||
HealthState healthNom = healthHelper.healthTable->getHealth(devNom);
|
||||
HealthState healthRed = healthHelper.healthTable->getHealth(devRed);
|
||||
if ((healthNom == FAULTY or healthNom == PERMANENT_FAULTY) and
|
||||
(healthRed == FAULTY or healthRed == PERMANENT_FAULTY)) {
|
||||
if (healthNom == PERMANENT_FAULTY and healthRed == FAULTY) {
|
||||
overwriteDeviceHealth(devRed, healthRed);
|
||||
needsHealthOverwritten = true;
|
||||
} else if (healthNom == FAULTY and healthRed == PERMANENT_FAULTY) {
|
||||
overwriteDeviceHealth(devNom, healthNom);
|
||||
needsHealthOverwritten = true;
|
||||
} else if ((healthNom == FAULTY or healthNom == PERMANENT_FAULTY) and
|
||||
(healthRed == FAULTY or healthRed == PERMANENT_FAULTY)) {
|
||||
overwriteDeviceHealth(devNom, healthNom);
|
||||
overwriteDeviceHealth(devRed, healthRed);
|
||||
needsHealthOverwritten = true;
|
||||
}
|
||||
};
|
||||
auto checkHealthForOneDev = [&](object_id_t dev) {
|
||||
@ -174,7 +150,7 @@ ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t deviceMode, Submode
|
||||
modeHelper.setForced(true);
|
||||
}
|
||||
};
|
||||
if (deviceSubmode == duallane::DUAL_MODE) {
|
||||
if (commandedSubmode == duallane::DUAL_MODE) {
|
||||
uint8_t idx = 0;
|
||||
for (idx = 0; idx < 6; idx++) {
|
||||
checkSusGroup(helper.susIds[idx], helper.susIds[idx + 6]);
|
||||
@ -184,5 +160,12 @@ ReturnValue_t SusAssembly::checkAndHandleHealthStates(Mode_t deviceMode, Submode
|
||||
checkHealthForOneDev(helper.susIds[idx]);
|
||||
}
|
||||
}
|
||||
if (needsHealthOverwritten) {
|
||||
mode = commandedMode;
|
||||
submode = commandedSubmode;
|
||||
// We need second step instead of NEED_TO_CHANGE_HEALTH because we do not want recovery
|
||||
// handling.
|
||||
return NEED_TO_CHANGE_HEALTH;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -56,13 +56,6 @@ class SusAssembly : public DualLaneAssemblyBase {
|
||||
ReturnValue_t commandChildren(Mode_t mode, Submode_t submode) override;
|
||||
ReturnValue_t checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) override;
|
||||
|
||||
/**
|
||||
* Check whether it makes sense to send mode commands to the device
|
||||
* @param object
|
||||
* @param mode
|
||||
* @return
|
||||
*/
|
||||
bool isUseable(object_id_t object, Mode_t mode);
|
||||
void powerStateMachine(Mode_t mode, Submode_t submode);
|
||||
ReturnValue_t handleNormalOrOnModeCmd(Mode_t mode, Submode_t submode);
|
||||
void refreshHelperModes();
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "eive/objects.h"
|
||||
#include "mission/acs/defs.h"
|
||||
#include "mission/power/defs.h"
|
||||
#include "mission/system/tree/util.h"
|
||||
#include "mission/system/treeUtil.h"
|
||||
|
||||
AcsSubsystem satsystem::acs::ACS_SUBSYSTEM(objects::ACS_SUBSYSTEM, 12, 24);
|
||||
|
||||
|
@ -228,3 +228,27 @@ bool ComSubsystem::isTxMode(Mode_t mode) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ComSubsystem::announceMode(bool recursive) {
|
||||
const char *modeStr = "UNKNOWN";
|
||||
switch (mode) {
|
||||
case (com::RX_ONLY): {
|
||||
modeStr = "RX_ONLY";
|
||||
break;
|
||||
}
|
||||
case (com::RX_AND_TX_LOW_DATARATE): {
|
||||
modeStr = "RX_AND_TX_LOW_DATARATE";
|
||||
break;
|
||||
}
|
||||
case (com::RX_AND_TX_HIGH_DATARATE): {
|
||||
modeStr = "RX_AND_TX_HIGH_DATARATE";
|
||||
break;
|
||||
}
|
||||
case (com::RX_AND_TX_DEFAULT_DATARATE): {
|
||||
modeStr = "RX_AND_TX_DEFAULT_DATARATE";
|
||||
break;
|
||||
}
|
||||
}
|
||||
sif::info << "COM subsystem is now in " << modeStr << " mode" << std::endl;
|
||||
return Subsystem::announceMode(recursive);
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ class ComSubsystem : public Subsystem, public ReceivesParameterMessagesIF {
|
||||
ReturnValue_t initialize() override;
|
||||
|
||||
void startTransition(Mode_t mode, Submode_t submode) override;
|
||||
void announceMode(bool recursive) override;
|
||||
|
||||
void readEventQueue();
|
||||
void handleEventMessage(EventMessage *eventMessage);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "SyrlinksAssembly.h"
|
||||
|
||||
#include <eive/objects.h>
|
||||
#include <mission/com/defs.h>
|
||||
|
||||
using namespace returnvalue;
|
||||
|
||||
@ -19,7 +20,7 @@ ReturnValue_t SyrlinksAssembly::commandChildren(Mode_t mode, Submode_t submode)
|
||||
if (recoveryState == RECOVERY_IDLE) {
|
||||
ReturnValue_t result = checkAndHandleHealthState(mode, submode);
|
||||
if (result == NEED_TO_CHANGE_HEALTH) {
|
||||
return OK;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
executeTable(iter);
|
||||
@ -34,10 +35,16 @@ ReturnValue_t SyrlinksAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_
|
||||
}
|
||||
|
||||
ReturnValue_t SyrlinksAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
|
||||
if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL or mode == MODE_OFF) {
|
||||
if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||
if (submode >= com::Submode::NUM_SUBMODES or submode < com::Submode::RX_ONLY) {
|
||||
return HasModesIF::INVALID_SUBMODE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
return returnvalue::FAILED;
|
||||
if (mode == MODE_OFF and submode != SUBMODE_NONE) {
|
||||
return HasModesIF::INVALID_SUBMODE;
|
||||
}
|
||||
return returnvalue::OK;
|
||||
}
|
||||
|
||||
ReturnValue_t SyrlinksAssembly::checkAndHandleHealthState(Mode_t deviceMode,
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "eive/objects.h"
|
||||
#include "mission/com/defs.h"
|
||||
#include "mission/system/tree/util.h"
|
||||
#include "mission/system/treeUtil.h"
|
||||
|
||||
const auto check = subsystem::checkInsert;
|
||||
|
||||
|
@ -1,9 +1,4 @@
|
||||
target_sources(
|
||||
${LIB_EIVE_MISSION}
|
||||
PRIVATE EiveSystem.cpp
|
||||
CamSwitcher.cpp
|
||||
TcsSubsystem.cpp
|
||||
PayloadSubsystem.cpp
|
||||
Stack5VHandler.cpp
|
||||
PowerStateMachineBase.cpp
|
||||
TcsBoardAssembly.cpp)
|
||||
PRIVATE CamSwitcher.cpp TcsSubsystem.cpp PayloadSubsystem.cpp
|
||||
Stack5VHandler.cpp PowerStateMachineBase.cpp TcsBoardAssembly.cpp)
|
||||
|
@ -1,111 +0,0 @@
|
||||
#include "EiveSystem.h"
|
||||
|
||||
#include <eive/objects.h>
|
||||
#include <fsfw/events/EventManager.h>
|
||||
#include <fsfw/ipc/QueueFactory.h>
|
||||
#include <mission/acs/defs.h>
|
||||
#include <mission/com/defs.h>
|
||||
#include <mission/controller/tcsDefs.h>
|
||||
|
||||
#include "mission/sysDefs.h"
|
||||
|
||||
EiveSystem::EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences,
|
||||
uint32_t maxNumberOfTables)
|
||||
: Subsystem(setObjectId, maxNumberOfSequences, maxNumberOfTables) {
|
||||
auto mqArgs = MqArgs(SubsystemBase::getObjectId(), static_cast<void*>(this));
|
||||
eventQueue =
|
||||
QueueFactory::instance()->createMessageQueue(10, EventMessage::EVENT_MESSAGE_SIZE, &mqArgs);
|
||||
}
|
||||
|
||||
void EiveSystem::announceMode(bool recursive) {
|
||||
const char* modeStr = "UNKNOWN";
|
||||
switch (mode) {
|
||||
case (satsystem::Mode::BOOT): {
|
||||
modeStr = "OFF/BOOT";
|
||||
break;
|
||||
}
|
||||
case (satsystem::Mode::SAFE): {
|
||||
modeStr = "SAFE";
|
||||
break;
|
||||
}
|
||||
case (satsystem::Mode::PTG_IDLE): {
|
||||
modeStr = "POINTING IDLE";
|
||||
break;
|
||||
}
|
||||
case (acs::AcsMode::PTG_INERTIAL): {
|
||||
modeStr = "POINTING INERTIAL";
|
||||
break;
|
||||
}
|
||||
case (acs::AcsMode::PTG_TARGET): {
|
||||
modeStr = "POINTING TARGET";
|
||||
break;
|
||||
}
|
||||
case (acs::AcsMode::PTG_TARGET_GS): {
|
||||
modeStr = "POINTING TARGET GS";
|
||||
break;
|
||||
}
|
||||
}
|
||||
sif::info << "EIVE system is now in " << modeStr << " mode" << std::endl;
|
||||
return Subsystem::announceMode(recursive);
|
||||
}
|
||||
|
||||
void EiveSystem::performChildOperation() {
|
||||
Subsystem::performChildOperation();
|
||||
handleEventMessages();
|
||||
if (not isInTransition and performSafeRecovery) {
|
||||
commandSelfToSafe();
|
||||
performSafeRecovery = false;
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t EiveSystem::initialize() {
|
||||
auto* manager = ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||
if (manager == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::error << "AcsSubsystem::initialize: Invalid event manager" << std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
ReturnValue_t result = manager->registerListener(eventQueue->getId());
|
||||
if (result != returnvalue::OK) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "AcsSubsystem::registerListener: Failed to register as "
|
||||
"listener"
|
||||
<< std::endl;
|
||||
#endif
|
||||
return ObjectManagerIF::CHILD_INIT_FAILED;
|
||||
}
|
||||
manager->subscribeToEvent(eventQueue->getId(),
|
||||
event::getEventId(tcsCtrl::PCDU_SYSTEM_OVERHEATING));
|
||||
manager->subscribeToEvent(eventQueue->getId(), event::getEventId(tcsCtrl::OBC_OVERHEATING));
|
||||
|
||||
return Subsystem::initialize();
|
||||
}
|
||||
|
||||
void EiveSystem::handleEventMessages() {
|
||||
EventMessage event;
|
||||
for (ReturnValue_t status = eventQueue->receiveMessage(&event); status == returnvalue::OK;
|
||||
status = eventQueue->receiveMessage(&event)) {
|
||||
switch (event.getMessageId()) {
|
||||
case EventMessage::EVENT_MESSAGE:
|
||||
switch (event.getEvent()) {
|
||||
case tcsCtrl::OBC_OVERHEATING:
|
||||
case tcsCtrl::PCDU_SYSTEM_OVERHEATING: {
|
||||
if (isInTransition) {
|
||||
performSafeRecovery = true;
|
||||
return;
|
||||
}
|
||||
|
||||
commandSelfToSafe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sif::debug << "EiveSystem: Did not subscribe to event " << event.getEvent() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EiveSystem::commandSelfToSafe() { startTransition(satsystem::Mode::SAFE, 0); }
|
@ -1,21 +0,0 @@
|
||||
#ifndef MISSION_SYSTEM_EIVESYSTEM_H_
|
||||
#define MISSION_SYSTEM_EIVESYSTEM_H_
|
||||
|
||||
#include <fsfw/subsystem/Subsystem.h>
|
||||
|
||||
class EiveSystem : public Subsystem {
|
||||
public:
|
||||
EiveSystem(object_id_t setObjectId, uint32_t maxNumberOfSequences, uint32_t maxNumberOfTables);
|
||||
|
||||
private:
|
||||
MessageQueueIF* eventQueue = nullptr;
|
||||
bool performSafeRecovery = false;
|
||||
|
||||
ReturnValue_t initialize() override;
|
||||
void performChildOperation() override;
|
||||
void announceMode(bool recursive) override;
|
||||
void handleEventMessages();
|
||||
void commandSelfToSafe();
|
||||
};
|
||||
|
||||
#endif /* MISSION_SYSTEM_EIVESYSTEM_H_ */
|
@ -1,5 +1,7 @@
|
||||
#include "PowerStateMachineBase.h"
|
||||
|
||||
#include "fsfw/serviceinterface.h"
|
||||
|
||||
PowerStateMachineBase::PowerStateMachineBase(PowerSwitchIF *pwrSwitcher, dur_millis_t checkTimeout)
|
||||
: pwrSwitcher(pwrSwitcher), checkTimeout(checkTimeout) {}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "system.h"
|
||||
#include "systemTree.h"
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
|
||||
#include <fsfw/subsystem/Subsystem.h>
|
||||
@ -6,12 +6,14 @@
|
||||
#include <mission/sysDefs.h>
|
||||
#include <mission/system/com/comModeTree.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "eive/objects.h"
|
||||
#include "mission/com/defs.h"
|
||||
#include "mission/system/acs/acsModeTree.h"
|
||||
#include "payloadModeTree.h"
|
||||
#include "tcsModeTree.h"
|
||||
#include "util.h"
|
||||
#include "mission/system/tree/payloadModeTree.h"
|
||||
#include "mission/system/tree/tcsModeTree.h"
|
||||
#include "treeUtil.h"
|
||||
|
||||
namespace {
|
||||
// Alias for checker function
|
||||
@ -41,7 +43,7 @@ void satsystem::init() {
|
||||
EIVE_SYSTEM.setInitialMode(satsystem::Mode::BOOT, 0);
|
||||
}
|
||||
|
||||
EiveSystem satsystem::EIVE_SYSTEM = EiveSystem(objects::EIVE_SYSTEM, 12, 24);
|
||||
EiveSystem satsystem::EIVE_SYSTEM = EiveSystem(objects::EIVE_SYSTEM, 12, 24, I2C_FATAL_ERRORS);
|
||||
|
||||
auto EIVE_SEQUENCE_BOOT = std::make_pair(satsystem::Mode::BOOT, FixedArrayList<ModeListEntry, 5>());
|
||||
auto EIVE_TABLE_BOOT_TGT =
|
@ -1,7 +1,7 @@
|
||||
#ifndef MISSION_SYSTEM_TREE_SYSTEM_H_
|
||||
#define MISSION_SYSTEM_TREE_SYSTEM_H_
|
||||
|
||||
#include <mission/system/objects/EiveSystem.h>
|
||||
#include <mission/system/EiveSystem.h>
|
||||
|
||||
namespace satsystem {
|
||||
|
@ -1,2 +1 @@
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE payloadModeTree.cpp tcsModeTree.cpp
|
||||
system.cpp util.cpp)
|
||||
target_sources(${LIB_EIVE_MISSION} PRIVATE payloadModeTree.cpp tcsModeTree.cpp)
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "eive/objects.h"
|
||||
#include "mission/power/defs.h"
|
||||
#include "mission/system/objects/PayloadSubsystem.h"
|
||||
#include "util.h"
|
||||
#include "mission/system/treeUtil.h"
|
||||
|
||||
namespace {
|
||||
void initOffSequence(Subsystem& ss, ModeListEntry& eh);
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "eive/objects.h"
|
||||
#include "fsfw/devicehandlers/DeviceHandlerIF.h"
|
||||
#include "fsfw/subsystem/Subsystem.h"
|
||||
#include "mission/system/tree/util.h"
|
||||
#include "mission/system/treeUtil.h"
|
||||
|
||||
TcsSubsystem satsystem::tcs::SUBSYSTEM(objects::TCS_SUBSYSTEM, 12, 24);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#include "util.h"
|
||||
#include "treeUtil.h"
|
||||
|
||||
#include "fsfw/container/FixedMap.h"
|
||||
#include "fsfw/serviceinterface.h"
|
@ -331,7 +331,6 @@ void HeaterHandler::handleSwitchOffCommand(heater::Switchers heaterIdx) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sif::info << "HeaterHandler::handleSwitchOffCommand: Switch already off" << std::endl;
|
||||
triggerEvent(SWITCH_ALREADY_OFF, heaterIdx);
|
||||
}
|
||||
if (heater.replyQueue != NO_COMMANDER) {
|
||||
|
@ -101,8 +101,8 @@ class HeaterHandler : public ExecutableObjectIF,
|
||||
static constexpr Event GPIO_PULL_LOW_FAILED = MAKE_EVENT(1, severity::LOW);
|
||||
static constexpr Event HEATER_WENT_ON = event::makeEvent(SUBSYSTEM_ID, 2, severity::INFO);
|
||||
static constexpr Event HEATER_WENT_OFF = event::makeEvent(SUBSYSTEM_ID, 3, severity::INFO);
|
||||
static constexpr Event SWITCH_ALREADY_ON = MAKE_EVENT(4, severity::LOW);
|
||||
static constexpr Event SWITCH_ALREADY_OFF = MAKE_EVENT(5, severity::LOW);
|
||||
static constexpr Event SWITCH_ALREADY_ON = MAKE_EVENT(4, severity::INFO);
|
||||
static constexpr Event SWITCH_ALREADY_OFF = MAKE_EVENT(5, severity::INFO);
|
||||
static constexpr Event MAIN_SWITCH_TIMEOUT = MAKE_EVENT(6, severity::MEDIUM);
|
||||
//! A faulty heater was one. The SW will autonomously attempt to shut it down. P1: Heater Index
|
||||
static constexpr Event FAULTY_HEATER_WAS_ON = event::makeEvent(SUBSYSTEM_ID, 7, severity::LOW);
|
||||
|
2
tmtc
2
tmtc
Submodule tmtc updated: 50668ca7a7...9edbdf1a8d
Reference in New Issue
Block a user