WIP: PL PCDU #142

Closed
muellerr wants to merge 118 commits from mueller/plpcdu-sus-updates into develop
9 changed files with 194 additions and 35 deletions
Showing only changes of commit cd2097850e - Show all commits

2
fsfw

@ -1 +1 @@
Subproject commit d74a373f1d6bc341c11d7ad89f369da5ff957928
Subproject commit c4a055986c30526d15dbb227e00bb131f22a7365

View File

@ -1,6 +1,5 @@
target_sources(${OBSW_NAME} PRIVATE
SolarArrayDeploymentHandler.cpp
PayloadPcduHandler.cpp
SusHandler.cpp
)

View File

@ -1,12 +0,0 @@
#ifndef LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_
#define LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_
#include <cstddef>
namespace plpcdu {
static constexpr size_t MAX_ADC_REPLY_SIZE = 32;
}
#endif /* LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_ */

View File

@ -9,6 +9,7 @@ target_sources(${LIB_EIVE_MISSION} PRIVATE
ACUHandler.cpp
SyrlinksHkHandler.cpp
Max31865PT1000Handler.cpp
PayloadPcduHandler.cpp
IMTQHandler.cpp
HeaterHandler.cpp
PlocMPSoCHandler.cpp

View File

@ -1,10 +1,9 @@
#include "PayloadPcduHandler.h"
#include "devices/gpioIds.h"
PayloadPcduHandler::PayloadPcduHandler(object_id_t objectId, object_id_t comIF, CookieIF* cookie,
GpioIF* gpioIF)
: DeviceHandlerBase(objectId, comIF, cookie), gpioIF(gpioIF) {}
: DeviceHandlerBase(objectId, comIF, cookie), adcSet(this), gpioIF(gpioIF) {}
void PayloadPcduHandler::doStartUp() {
if ((state != States::PCDU_OFF) and (state != States::ON_TRANS_SSR)) {
@ -24,6 +23,7 @@ void PayloadPcduHandler::doStartUp() {
transitionOk = false;
// We are now in ON mode
setMode(MODE_ON);
adcState = AdcStates::BOOT_DELAY;
// The ADC can now be read. If the values are not close to zero, we should not allow
// transition
monMode = MonitoringMode::CLOSE_TO_ZERO;
@ -33,6 +33,18 @@ void PayloadPcduHandler::doStartUp() {
void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
if (mode == _MODE_TO_NORMAL) {
if(adcState == AdcStates::BOOT_DELAY) {
if (adcCountdown.hasTimedOut()) {
adcState = AdcStates::SEND_SETUP;
adcCmdExecuted = false;
}
}
if(adcState == AdcStates::SEND_SETUP) {
if(adcCmdExecuted) {
adcState = AdcStates::NORMAL;
adcCmdExecuted = false;
}
}
if (state == States::ON_TRANS_ADC_CLOSE_ZERO) {
if (not commandExecuted) {
countdown.resetTimer();
@ -125,28 +137,86 @@ void PayloadPcduHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
void PayloadPcduHandler::doShutDown() {}
ReturnValue_t PayloadPcduHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
return HasReturnvaluesIF::RETURN_OK;
switch(adcState) {
case(AdcStates::SEND_SETUP): {
*id = plpcdu::SETUP_CMD;
buildCommandFromCommand(*id, nullptr, 0);
break;
}
case(AdcStates::NORMAL): {
*id = plpcdu::READ_WITH_TEMP;
buildCommandFromCommand(*id, nullptr, 0);
break;
}
default: {
break;
}
}
return NOTHING_TO_SEND;
}
ReturnValue_t PayloadPcduHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
if(adcState == AdcStates::SEND_SETUP) {
*id = plpcdu::SETUP_CMD;
buildCommandFromCommand(*id, nullptr, 0);
}
return HasReturnvaluesIF::RETURN_OK;
}
void PayloadPcduHandler::fillCommandAndReplyMap() {}
void PayloadPcduHandler::fillCommandAndReplyMap() {
insertInCommandAndReplyMap(plpcdu::READ_CMD, 2, &adcSet);
insertInCommandAndReplyMap(plpcdu::READ_TEMP, 1, &adcSet);
insertInCommandAndReplyMap(plpcdu::READ_WITH_TEMP, 1, &adcSet);
insertInCommandAndReplyMap(plpcdu::SETUP_CMD, 1);
}
ReturnValue_t PayloadPcduHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
const uint8_t* commandData,
size_t commandDataLen) {
return HasReturnvaluesIF::RETURN_OK;
switch(deviceCommand) {
case(plpcdu::SETUP_CMD): {
cmdBuf[0] = plpcdu::SETUP_BYTE;
rawPacket = cmdBuf.data();
rawPacketLen = 1;
break;
}
case(plpcdu::READ_CMD): {
max1227::prepareExternallyClockedRead0ToN(cmdBuf.data(), plpcdu::CHANNEL_N, rawPacketLen);
rawPacket = cmdBuf.data();
break;
}
case(plpcdu::READ_TEMP): {
max1227::prepareExternallyClockedTemperatureRead(cmdBuf.data(), rawPacketLen);
rawPacket = cmdBuf.data();
break;
}
case(plpcdu::READ_WITH_TEMP): {
size_t sz = 0;
max1227::prepareExternallyClockedRead0ToN(cmdBuf.data(), plpcdu::CHANNEL_N, sz);
max1227::prepareExternallyClockedTemperatureRead(cmdBuf.data() + sz, sz);
rawPacketLen = sz;
rawPacket = cmdBuf.data();
}
}
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
ReturnValue_t PayloadPcduHandler::scanForReply(const uint8_t* start, size_t remainingSize,
DeviceCommandId_t* foundId, size_t* foundLen) {
// SPI is full duplex
*foundId = getPendingCommand();
*foundLen = remainingSize;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t PayloadPcduHandler::interpretDeviceReply(DeviceCommandId_t id,
const uint8_t* packet) {
using namespace plpcdu;
switch(id) {
case(SETUP_CMD): {
break;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
@ -157,5 +227,18 @@ uint32_t PayloadPcduHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo
ReturnValue_t PayloadPcduHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_0, &ain0);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_1, &ain1);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_2, &ain2);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_3, &ain3);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_4, &ain4);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_5, &ain5);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_6, &ain6);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_7, &ain7);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_8, &ain8);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_9, &ain9);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_10, &ain10);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::AIN_11, &ain11);
localDataPoolMap.emplace(plpcdu::PlPcduPoolIds::TEMP, &tempC);
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -3,7 +3,7 @@
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <fsfw/timemanager/Countdown.h>
#include "devicedefinitions/payloadPcduDefinitions.h"
#include "fsfw_hal/common/gpio/GpioIF.h"
/**
@ -48,13 +48,34 @@ class PayloadPcduHandler : DeviceHandlerBase {
enum class MonitoringMode { NONE, CLOSE_TO_ZERO, NEGATIVE } monMode = MonitoringMode::NONE;
enum class AdcStates { OFF, BOOT_DELAY, SEND_SETUP, NORMAL } adcState = AdcStates::OFF;
plpcdu::PlPcduAdcSet adcSet;
std::array<uint8_t, plpcdu::MAX_ADC_REPLY_SIZE> cmdBuf = {};
// This variable is tied to DRO +6 V voltage. Voltages, currents are monitored and the experiment
// is shut down immediately if there is a negative voltage.
bool transitionOk = false;
bool commandExecuted = false;
bool adcCmdExecuted = false;
uint8_t tempReadDivisor = 1;
Countdown countdown = Countdown(5000);
Countdown adcCountdown = Countdown(50);
GpioIF* gpioIF;
PoolEntry<uint16_t> ain0 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain1 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain2 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain3 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain4 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain5 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain6 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain7 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain8 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain9 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain10 = PoolEntry<uint16_t>({0});
PoolEntry<uint16_t> ain11 = PoolEntry<uint16_t>({0});
PoolEntry<float> tempC = PoolEntry<float>({0.0});
void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
void doStartUp() override;
void doShutDown() override;

View File

@ -0,0 +1,69 @@
#ifndef LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_
#define LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_
#include <fsfw/datapoollocal/StaticLocalDataSet.h>
#include <fsfw/devicehandlers/DeviceHandlerIF.h>
#include "mission/devices/max1227.h"
#include <cstddef>
namespace plpcdu {
using namespace max1227;
enum PlPcduPoolIds: uint32_t {
AIN_0 = 0,
AIN_1 = 1,
AIN_2 = 2,
AIN_3 = 3,
AIN_4 = 4,
AIN_5 = 5,
AIN_6 = 6,
AIN_7 = 7,
AIN_8 = 8,
AIN_9 = 9,
AIN_10 = 10,
AIN_11 = 11,
TEMP = 12
};
static constexpr size_t MAX_ADC_REPLY_SIZE = 64;
static constexpr DeviceCommandId_t READ_CMD = 0;
static constexpr DeviceCommandId_t SETUP_CMD = 1;
static constexpr DeviceCommandId_t READ_TEMP = 2;
static constexpr DeviceCommandId_t READ_WITH_TEMP = 3;
static constexpr uint8_t SETUP_BYTE = max1227::buildSetupByte(ClkSel::EXT_CONV_EXT_TIMED,
RefSel::INT_REF_NO_WAKEUP, DiffSel::NONE_0);
static constexpr uint32_t ADC_SET_ID = READ_CMD;
static constexpr uint8_t CHANNELS_NUM = 12;
static constexpr uint8_t CHANNEL_N = CHANNELS_NUM - 1;
// Store temperature as well
static constexpr size_t DATASET_ENTRIES = CHANNELS_NUM + 1;
class PlPcduAdcSet : public StaticLocalDataSet<DATASET_ENTRIES> {
public:
PlPcduAdcSet(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, ADC_SET_ID) {}
PlPcduAdcSet(object_id_t objectId)
: StaticLocalDataSet(sid_t(objectId, ADC_SET_ID)) {}
lp_var_t<uint16_t> ain0 = lp_var_t<uint16_t>(sid.objectId, AIN_0, this);
lp_var_t<uint16_t> ain1 = lp_var_t<uint16_t>(sid.objectId, AIN_1, this);
lp_var_t<uint16_t> ain2= lp_var_t<uint16_t>(sid.objectId, AIN_2, this);
lp_var_t<uint16_t> ain3 = lp_var_t<uint16_t>(sid.objectId, AIN_3, this);
lp_var_t<uint16_t> ain4 = lp_var_t<uint16_t>(sid.objectId, AIN_4, this);
lp_var_t<uint16_t> ain5 = lp_var_t<uint16_t>(sid.objectId, AIN_5, this);
lp_var_t<uint16_t> ain6 = lp_var_t<uint16_t>(sid.objectId, AIN_6, this);
lp_var_t<uint16_t> ain7 = lp_var_t<uint16_t>(sid.objectId, AIN_7, this);
lp_var_t<uint16_t> ain8 = lp_var_t<uint16_t>(sid.objectId, AIN_8, this);
lp_var_t<uint16_t> ain9 = lp_var_t<uint16_t>(sid.objectId, AIN_9, this);
lp_var_t<uint16_t> ain10 = lp_var_t<uint16_t>(sid.objectId, AIN_10, this);
lp_var_t<uint16_t> ain11 = lp_var_t<uint16_t>(sid.objectId, AIN_11, this);
lp_var_t<float> tempC = lp_var_t<float>(sid.objectId, TEMP, this);
};
}
#endif /* LINUX_DEVICES_DEVICEDEFINITIONS_PAYLOADPCDUDEFINITIONS_H_ */

View File

@ -2,14 +2,6 @@
#include <cstring>
uint8_t max1227::buildConvByte(ScanModes scanMode, uint8_t channel, bool readTemp) {
return (1 << 7) | (channel << 3) | (scanMode << 1) | readTemp;
}
uint8_t max1227::buildSetupByte(ClkSel clkSel, RefSel refSel, DiffSel diffSel) {
return (1 << 6) | (clkSel << 4) | (refSel << 2) | diffSel;
}
void max1227::prepareExternallyClockedSingleChannelRead(uint8_t *spiBuf, uint8_t channel,
size_t &sz) {
spiBuf[0] = buildConvByte(ScanModes::N_ONCE, channel, false);
@ -18,21 +10,19 @@ void max1227::prepareExternallyClockedSingleChannelRead(uint8_t *spiBuf, uint8_t
sz = 3;
}
uint8_t max1227::buildResetByte(bool fifoOnly) { return (1 << 4) | (fifoOnly << 3); }
void max1227::prepareExternallyClockedRead0ToN(uint8_t *spiBuf, uint8_t n, size_t &sz) {
for (uint8_t idx = 0; idx <= n; idx++) {
spiBuf[idx * 2] = buildConvByte(ScanModes::N_ONCE, idx, false);
spiBuf[idx * 2 + 1] = 0x00;
}
spiBuf[(n + 1) * 2] = 0x00;
sz = (n + 1) * 2 + 1;
sz += (n + 1) * 2 + 1;
}
void max1227::prepareExternallyClockedTemperatureRead(uint8_t *spiBuf, size_t &sz) {
spiBuf[0] = buildConvByte(ScanModes::N_ONCE, 0, true);
std::memset(spiBuf + 1, 0, 24);
sz = 25;
sz += 25;
}
float max1227::getTemperature(int16_t temp) { return static_cast<float>(temp) * 0.125; }

View File

@ -40,9 +40,17 @@ enum DiffSel : uint8_t {
BIPOLAR_CFG = 0b11
};
uint8_t buildResetByte(bool fifoOnly);
uint8_t buildConvByte(ScanModes scanMode, uint8_t channel, bool readTemp);
uint8_t buildSetupByte(ClkSel clkSel, RefSel refSel, DiffSel diffSel);
constexpr uint8_t buildResetByte(bool fifoOnly) {
return (1 << 4) | (fifoOnly << 3);
}
constexpr uint8_t buildConvByte(ScanModes scanMode, uint8_t channel, bool readTemp) {
return (1 << 7) | (channel << 3) | (scanMode << 1) | readTemp;
}
constexpr uint8_t buildSetupByte(ClkSel clkSel, RefSel refSel, DiffSel diffSel) {
return (1 << 6) | (clkSel << 4) | (refSel << 2) | diffSel;
}
/**
* If there is a wakeup delay, there needs to be a 65 us delay between sending