Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
0e9035d6c1
|
|||
c80eff4922 | |||
a5c9e1481b
|
|||
e19ddcfbd8
|
|||
f3aab775f3 | |||
59d542ab39 | |||
7b0285c4ce | |||
0a77ee0508 | |||
51cbe46cf5 | |||
26fc4b8add | |||
825de04f3b
|
|||
33985937b7
|
|||
0a12dbf2be
|
|||
ad3c0e2a0e
|
|||
87c05705ec | |||
4d17184fba | |||
4c63fed69d | |||
eb27ab4bb0 | |||
b0a38136c1 | |||
b5cc430b5b | |||
1cc62238c2 |
17
CHANGELOG.md
17
CHANGELOG.md
@ -20,7 +20,22 @@ will consitute of a breaking change warranting a new major release:
|
|||||||
|
|
||||||
- Important bugfixes for PTME. See `q7s-package` CHANGELOG.
|
- Important bugfixes for PTME. See `q7s-package` CHANGELOG.
|
||||||
|
|
||||||
# [v5.1.0] to be released
|
# [v5.2.0] 2023-07-02
|
||||||
|
|
||||||
|
## Fixed
|
||||||
|
|
||||||
|
- The firmware information event was not triggered even when possible because of an ordering
|
||||||
|
bug in the initializer function.
|
||||||
|
- Empty dumps (no TM in time range) will now correctly be completed immediately
|
||||||
|
|
||||||
|
## Changed
|
||||||
|
|
||||||
|
- PTME was always reset on submode changes. The reset will now only be performed if the actual data
|
||||||
|
rate changes.
|
||||||
|
- Add back ACS board code for the EM. Now that the radiation sensor was removed, the image switching
|
||||||
|
issue has disappeared and adding back the ACS board is worth it for the GPS timekeeping.
|
||||||
|
|
||||||
|
# [v5.1.0] 2023-06-28
|
||||||
|
|
||||||
- `eive-tmtc` version v5.1.0
|
- `eive-tmtc` version v5.1.0
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
set(OBSW_VERSION_MAJOR 5)
|
set(OBSW_VERSION_MAJOR 5)
|
||||||
set(OBSW_VERSION_MINOR 1)
|
set(OBSW_VERSION_MINOR 2)
|
||||||
set(OBSW_VERSION_REVISION 0)
|
set(OBSW_VERSION_REVISION 0)
|
||||||
|
|
||||||
# set(CMAKE_VERBOSE TRUE)
|
# set(CMAKE_VERBOSE TRUE)
|
||||||
@ -105,7 +105,7 @@ set(OBSW_ADD_THERMAL_TEMP_INSERTER
|
|||||||
${OBSW_Q7S_EM}
|
${OBSW_Q7S_EM}
|
||||||
CACHE STRING "Add thermal sensor temperature inserter")
|
CACHE STRING "Add thermal sensor temperature inserter")
|
||||||
set(OBSW_ADD_ACS_BOARD
|
set(OBSW_ADD_ACS_BOARD
|
||||||
${INIT_VAL}
|
1
|
||||||
CACHE STRING "Add ACS board module")
|
CACHE STRING "Add ACS board module")
|
||||||
set(OBSW_ADD_GPS_CTRL
|
set(OBSW_ADD_GPS_CTRL
|
||||||
${INIT_VAL}
|
${INIT_VAL}
|
||||||
|
@ -170,9 +170,6 @@ ReturnValue_t CoreController::initialize() {
|
|||||||
|
|
||||||
sdStateMachine();
|
sdStateMachine();
|
||||||
|
|
||||||
triggerEvent(core::REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
|
|
||||||
announceCurrentImageInfo();
|
|
||||||
announceVersionInfo();
|
|
||||||
EventManagerIF *eventManager =
|
EventManagerIF *eventManager =
|
||||||
ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
ObjectManager::instance()->get<EventManagerIF>(objects::EVENT_MANAGER);
|
||||||
if (eventManager == nullptr or eventQueue == nullptr) {
|
if (eventManager == nullptr or eventQueue == nullptr) {
|
||||||
@ -189,17 +186,22 @@ ReturnValue_t CoreController::initialize() {
|
|||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::warning << "Subscribing for GPS GPS_FIX_CHANGE event failed" << std::endl;
|
sif::warning << "Subscribing for GPS GPS_FIX_CHANGE event failed" << std::endl;
|
||||||
}
|
}
|
||||||
|
triggerEvent(core::REBOOT_SW, CURRENT_CHIP, CURRENT_COPY);
|
||||||
|
announceCurrentImageInfo();
|
||||||
|
// This has to come before the version announce because it might be required for retrieving
|
||||||
|
// the firmware version.
|
||||||
if (common::OBSW_VERSION_MAJOR >= 6 or common::OBSW_VERSION_MAJOR == 4) {
|
if (common::OBSW_VERSION_MAJOR >= 6 or common::OBSW_VERSION_MAJOR == 4) {
|
||||||
UioMapper sysRomMapper(q7s::UIO_SYS_ROM);
|
UioMapper sysRomMapper(q7s::UIO_SYS_ROM);
|
||||||
result = sysRomMapper.getMappedAdress(&mappedSysRomAddr, UioMapper::Permissions::READ_ONLY);
|
result = sysRomMapper.getMappedAdress(&mappedSysRomAddr, UioMapper::Permissions::READ_ONLY);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
// TODO: This might be a reason to switch to another image..
|
// TODO: This might be a reason to switch to another image..
|
||||||
sif::error << "Getting mapped SYS ROM UIO address failed" << std::endl;
|
sif::error << "Getting mapped SYS ROM UIO address failed" << std::endl;
|
||||||
return ObjectManager::CHILD_INIT_FAILED;
|
result = ObjectManager::CHILD_INIT_FAILED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
announceVersionInfo();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t CoreController::initializeAfterTaskCreation() {
|
ReturnValue_t CoreController::initializeAfterTaskCreation() {
|
||||||
|
@ -84,9 +84,10 @@ void ObjectFactory::produce(void* args) {
|
|||||||
|
|
||||||
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
new CoreController(objects::CORE_CONTROLLER, enableHkSets);
|
||||||
|
|
||||||
#if OBSW_ADD_ACS_BOARD == 1
|
// Initialize chip select to avoid SPI bus issues.
|
||||||
// Still initialize chip select to avoid SPI bus issues.
|
|
||||||
createRadSensorChipSelect(gpioComIF);
|
createRadSensorChipSelect(gpioComIF);
|
||||||
|
|
||||||
|
#if OBSW_ADD_ACS_BOARD == 1
|
||||||
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher, true,
|
createAcsBoardComponents(*spiMainComIF, gpioComIF, uartComIF, *pwrSwitcher, true,
|
||||||
adis1650x::Type::ADIS16507);
|
adis1650x::Type::ADIS16507);
|
||||||
#else
|
#else
|
||||||
|
@ -16,9 +16,9 @@ AxiPtmeConfig::AxiPtmeConfig(object_id_t objectId, std::string axiUio, int mapNu
|
|||||||
AxiPtmeConfig::~AxiPtmeConfig() {}
|
AxiPtmeConfig::~AxiPtmeConfig() {}
|
||||||
|
|
||||||
ReturnValue_t AxiPtmeConfig::initialize() {
|
ReturnValue_t AxiPtmeConfig::initialize() {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
|
||||||
UioMapper uioMapper(axiUio, mapNum);
|
UioMapper uioMapper(axiUio, mapNum);
|
||||||
result = uioMapper.getMappedAdress(&baseAddress, UioMapper::Permissions::READ_WRITE);
|
ReturnValue_t result =
|
||||||
|
uioMapper.getMappedAdress(&baseAddress, UioMapper::Permissions::READ_WRITE);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -26,8 +26,7 @@ ReturnValue_t AxiPtmeConfig::initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t AxiPtmeConfig::writeCaduRateReg(uint8_t rateVal) {
|
ReturnValue_t AxiPtmeConfig::writeCaduRateReg(uint8_t rateVal) {
|
||||||
ReturnValue_t result = returnvalue::OK;
|
ReturnValue_t result = mutex->lockMutex(timeoutType, mutexTimeout);
|
||||||
result = mutex->lockMutex(timeoutType, mutexTimeout);
|
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
sif::warning << "AxiPtmeConfig::writeCaduRateReg: Failed to lock mutex" << std::endl;
|
sif::warning << "AxiPtmeConfig::writeCaduRateReg: Failed to lock mutex" << std::endl;
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
@ -41,6 +40,11 @@ ReturnValue_t AxiPtmeConfig::writeCaduRateReg(uint8_t rateVal) {
|
|||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t AxiPtmeConfig::readCaduRateReg() {
|
||||||
|
MutexGuard mg(mutex);
|
||||||
|
return static_cast<uint8_t>(*(baseAddress + CADU_BITRATE_REG));
|
||||||
|
}
|
||||||
|
|
||||||
void AxiPtmeConfig::enableTxclockManipulator() {
|
void AxiPtmeConfig::enableTxclockManipulator() {
|
||||||
writeBit(COMMON_CONFIG_REG, true, BitPos::EN_TX_CLK_MANIPULATOR);
|
writeBit(COMMON_CONFIG_REG, true, BitPos::EN_TX_CLK_MANIPULATOR);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ class AxiPtmeConfig : public SystemObject {
|
|||||||
* frequency of the clock connected to the bit clock input of PTME.
|
* frequency of the clock connected to the bit clock input of PTME.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t writeCaduRateReg(uint8_t rateVal);
|
ReturnValue_t writeCaduRateReg(uint8_t rateVal);
|
||||||
|
uint8_t readCaduRateReg();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Next to functions control the tx clock manipulator component
|
* @brief Next to functions control the tx clock manipulator component
|
||||||
|
@ -26,6 +26,11 @@ ReturnValue_t PtmeConfig::setRate(uint32_t bitRate) {
|
|||||||
return axiPtmeConfig->writeCaduRateReg(static_cast<uint8_t>(rateVal));
|
return axiPtmeConfig->writeCaduRateReg(static_cast<uint8_t>(rateVal));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t PtmeConfig::getRate() {
|
||||||
|
uint8_t rateReg = axiPtmeConfig->readCaduRateReg();
|
||||||
|
return (BIT_CLK_FREQ / (rateReg + 1));
|
||||||
|
}
|
||||||
|
|
||||||
void PtmeConfig::invertTxClock(bool invert) {
|
void PtmeConfig::invertTxClock(bool invert) {
|
||||||
if (invert) {
|
if (invert) {
|
||||||
axiPtmeConfig->enableTxclockInversion();
|
axiPtmeConfig->enableTxclockInversion();
|
||||||
|
@ -32,6 +32,7 @@ class PtmeConfig : public SystemObject {
|
|||||||
* of the CADU clock due to the convolutional code added by the s-Band transceiver.
|
* of the CADU clock due to the convolutional code added by the s-Band transceiver.
|
||||||
*/
|
*/
|
||||||
ReturnValue_t setRate(uint32_t bitRate);
|
ReturnValue_t setRate(uint32_t bitRate);
|
||||||
|
uint32_t getRate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Will change the time the tx data signal is updated with respect to the tx clock
|
* @brief Will change the time the tx data signal is updated with respect to the tx clock
|
||||||
|
@ -246,7 +246,13 @@ ReturnValue_t CcsdsIpCoreHandler::checkModeCommand(Mode_t mode, Submode_t submod
|
|||||||
void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
|
void CcsdsIpCoreHandler::startTransition(Mode_t mode, Submode_t submode) {
|
||||||
triggerEvent(CHANGING_MODE, mode, submode);
|
triggerEvent(CHANGING_MODE, mode, submode);
|
||||||
if (mode == HasModesIF::MODE_ON) {
|
if (mode == HasModesIF::MODE_ON) {
|
||||||
if (this->submode != submode) {
|
uint32_t currentRate = ptmeConfig.getRate();
|
||||||
|
// Check whether the rate actually changes.
|
||||||
|
if ((this->submode != submode) and
|
||||||
|
(((submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_LOW) and
|
||||||
|
(currentRate != RATE_100KBPS))) or
|
||||||
|
((submode == static_cast<Submode_t>(com::CcsdsSubmode::DATARATE_HIGH) and
|
||||||
|
(currentRate != RATE_500KBPS))))) {
|
||||||
initPtmeUpdateAfterXCycles();
|
initPtmeUpdateAfterXCycles();
|
||||||
updateContext.enableTransmitAfterPtmeUpdate = true;
|
updateContext.enableTransmitAfterPtmeUpdate = true;
|
||||||
updateContext.updateClockRate = true;
|
updateContext.updateClockRate = true;
|
||||||
|
@ -45,13 +45,19 @@ bool TmStoreTaskBase::handleOneStore(PersistentTmStoreWithTmQueue& store,
|
|||||||
} else {
|
} else {
|
||||||
Command_t execCmd;
|
Command_t execCmd;
|
||||||
// Handle TC requests, for example deletion or retrieval requests.
|
// Handle TC requests, for example deletion or retrieval requests.
|
||||||
|
// TODO: Not really clean here.. would be better if the executed command is returns as an
|
||||||
|
// enumeration.
|
||||||
result = store.handleCommandQueue(ipcStore, execCmd);
|
result = store.handleCommandQueue(ipcStore, execCmd);
|
||||||
if (result == returnvalue::OK) {
|
|
||||||
if (execCmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) {
|
if (execCmd == TmStoreMessage::DOWNLINK_STORE_CONTENT_TIME) {
|
||||||
|
if (result == PersistentTmStore::DUMP_DONE) {
|
||||||
|
dumpDoneHandler(store, dumpContext);
|
||||||
|
} else if (result == returnvalue::OK) {
|
||||||
cancelDumpCd.resetTimer();
|
cancelDumpCd.resetTimer();
|
||||||
tmSinkBusyCd.resetTimer();
|
tmSinkBusyCd.resetTimer();
|
||||||
dumpContext.reset();
|
dumpContext.reset();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (execCmd != CommandMessageIF::CMD_NONE) {
|
||||||
tcRequestReceived = true;
|
tcRequestReceived = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,21 +125,13 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
|
|||||||
DumpContext& dumpContext, bool& dumpPerformed) {
|
DumpContext& dumpContext, bool& dumpPerformed) {
|
||||||
size_t dumpedLen = 0;
|
size_t dumpedLen = 0;
|
||||||
|
|
||||||
auto dumpDoneHandler = [&]() {
|
|
||||||
uint32_t startTime;
|
|
||||||
uint32_t endTime;
|
|
||||||
store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime);
|
|
||||||
triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets,
|
|
||||||
dumpContext.dumpedBytes);
|
|
||||||
dumpContext.reset();
|
|
||||||
};
|
|
||||||
// Dump the next packet into the PTME.
|
// Dump the next packet into the PTME.
|
||||||
dumpContext.ptmeBusyCounter = 0;
|
dumpContext.ptmeBusyCounter = 0;
|
||||||
tmSinkBusyCd.resetTimer();
|
tmSinkBusyCd.resetTimer();
|
||||||
ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped);
|
ReturnValue_t result = store.getNextDumpPacket(tmReader, fileHasSwapped);
|
||||||
if (fileHasSwapped and result == PersistentTmStore::DUMP_DONE) {
|
if (fileHasSwapped and result == PersistentTmStore::DUMP_DONE) {
|
||||||
// This can happen if a file is corrupted and the next file swap completes the dump.
|
// This can happen if a file is corrupted and the next file swap completes the dump.
|
||||||
dumpDoneHandler();
|
dumpDoneHandler(store, dumpContext);
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
} else if (result != returnvalue::OK) {
|
} else if (result != returnvalue::OK) {
|
||||||
sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl;
|
sif::error << "PersistentTmStore: Getting next dump packet failed" << std::endl;
|
||||||
@ -157,7 +155,7 @@ ReturnValue_t TmStoreTaskBase::performDump(PersistentTmStoreWithTmQueue& store,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result == PersistentTmStore::DUMP_DONE) {
|
if (result == PersistentTmStore::DUMP_DONE) {
|
||||||
dumpDoneHandler();
|
dumpDoneHandler(store, dumpContext);
|
||||||
}
|
}
|
||||||
return returnvalue::OK;
|
return returnvalue::OK;
|
||||||
}
|
}
|
||||||
@ -198,6 +196,14 @@ ReturnValue_t TmStoreTaskBase::connectModeTreeParent(HasModeTreeChildrenIF& pare
|
|||||||
return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper);
|
return modetree::connectModeTreeParent(parent, *this, nullptr, modeHelper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TmStoreTaskBase::dumpDoneHandler(PersistentTmStore& store, DumpContext& dumpContext) {
|
||||||
|
uint32_t startTime;
|
||||||
|
uint32_t endTime;
|
||||||
|
store.getStartAndEndTimeCurrentOrLastDump(startTime, endTime);
|
||||||
|
triggerEvent(dumpContext.eventIfDone, dumpContext.numberOfDumpedPackets, dumpContext.dumpedBytes);
|
||||||
|
dumpContext.reset();
|
||||||
|
}
|
||||||
|
|
||||||
ModeTreeChildIF& TmStoreTaskBase::getModeTreeChildIF() { return *this; }
|
ModeTreeChildIF& TmStoreTaskBase::getModeTreeChildIF() { return *this; }
|
||||||
|
|
||||||
void TmStoreTaskBase::readCommandQueue(void) {
|
void TmStoreTaskBase::readCommandQueue(void) {
|
||||||
|
@ -96,6 +96,8 @@ class TmStoreTaskBase : public SystemObject,
|
|||||||
|
|
||||||
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
|
||||||
uint32_t* msToReachTheMode) override;
|
uint32_t* msToReachTheMode) override;
|
||||||
|
void dumpDoneHandler(PersistentTmStore& store, DumpContext& dumpContext);
|
||||||
|
|
||||||
void announceMode(bool recursive) override;
|
void announceMode(bool recursive) override;
|
||||||
object_id_t getObjectId() const override;
|
object_id_t getObjectId() const override;
|
||||||
const HasHealthIF* getOptHealthIF() const override;
|
const HasHealthIF* getOptHealthIF() const override;
|
||||||
|
@ -128,6 +128,7 @@ ReturnValue_t PersistentTmStore::assignAndOrCreateMostRecentFile() {
|
|||||||
|
|
||||||
ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore,
|
ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore,
|
||||||
Command_t& execCmd) {
|
Command_t& execCmd) {
|
||||||
|
execCmd = CommandMessageIF::CMD_NONE;
|
||||||
CommandMessage cmdMessage;
|
CommandMessage cmdMessage;
|
||||||
ReturnValue_t result = tcQueue->receiveMessage(&cmdMessage);
|
ReturnValue_t result = tcQueue->receiveMessage(&cmdMessage);
|
||||||
if (result != returnvalue::OK) {
|
if (result != returnvalue::OK) {
|
||||||
@ -162,9 +163,9 @@ ReturnValue_t PersistentTmStore::handleCommandQueue(StorageManagerIF& ipcStore,
|
|||||||
result = startDumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds);
|
result = startDumpFromUpTo(dumpFromUnixSeconds, dumpUntilUnixSeconds);
|
||||||
if (result == BUSY_DUMPING) {
|
if (result == BUSY_DUMPING) {
|
||||||
triggerEvent(persTmStore::BUSY_DUMPING_EVENT);
|
triggerEvent(persTmStore::BUSY_DUMPING_EVENT);
|
||||||
} else {
|
return result;
|
||||||
execCmd = cmd;
|
|
||||||
}
|
}
|
||||||
|
execCmd = cmd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -359,7 +360,10 @@ ReturnValue_t PersistentTmStore::loadNextDumpFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t PersistentTmStore::getNextDumpPacket(PusTmReader& reader, bool& fileHasSwapped) {
|
ReturnValue_t PersistentTmStore::getNextDumpPacket(PusTmReader& reader, bool& fileHasSwapped) {
|
||||||
if (state == State::IDLE or dumpParams.pendingPacketDump) {
|
if (state == State::IDLE) {
|
||||||
|
return DUMP_DONE;
|
||||||
|
}
|
||||||
|
if (dumpParams.pendingPacketDump) {
|
||||||
return returnvalue::FAILED;
|
return returnvalue::FAILED;
|
||||||
}
|
}
|
||||||
fileHasSwapped = false;
|
fileHasSwapped = false;
|
||||||
|
Reference in New Issue
Block a user