v1.12.0 #269
@ -4,6 +4,8 @@
|
|||||||
namespace q7s {
|
namespace q7s {
|
||||||
|
|
||||||
static constexpr char SPI_DEFAULT_DEV[] = "/dev/spi-main";
|
static constexpr char SPI_DEFAULT_DEV[] = "/dev/spi-main";
|
||||||
|
static constexpr uint32_t SPI_MAIN_BUS_LOCK_TIMEOUT = 50;
|
||||||
|
|
||||||
static constexpr char SPI_RW_DEV[] = "/dev/spi-rw";
|
static constexpr char SPI_RW_DEV[] = "/dev/spi-rw";
|
||||||
|
|
||||||
static constexpr char I2C_DEFAULT_DEV[] = "/dev/i2c-eive";
|
static constexpr char I2C_DEFAULT_DEV[] = "/dev/i2c-eive";
|
||||||
|
@ -44,8 +44,8 @@ ReturnValue_t spiCallback(SpiComIF* comIf, SpiCookie* cookie, const uint8_t* sen
|
|||||||
GpioIF* gpioIF = comIf->getGpioInterface();
|
GpioIF* gpioIF = comIf->getGpioInterface();
|
||||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
uint32_t timeoutMs = 0;
|
uint32_t timeoutMs = 0;
|
||||||
cookie->getMutexParams(timeoutType, timeoutMs);
|
|
||||||
MutexIF* mutex = comIf->getCsMutex();
|
MutexIF* mutex = comIf->getCsMutex();
|
||||||
|
cookie->getMutexParams(timeoutType, timeoutMs);
|
||||||
if (mutex == nullptr or gpioIF == nullptr) {
|
if (mutex == nullptr or gpioIF == nullptr) {
|
||||||
sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl;
|
sif::debug << "rwSpiCallback::spiCallback: Mutex or GPIO interface invalid" << std::endl;
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#include "bsp_q7s/core/InitMission.h"
|
#include "bsp_q7s/core/InitMission.h"
|
||||||
|
|
||||||
|
#include <fsfw/devicehandlers/DeviceCommunicationIF.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -13,6 +15,7 @@
|
|||||||
#include "fsfw/tasks/FixedTimeslotTaskIF.h"
|
#include "fsfw/tasks/FixedTimeslotTaskIF.h"
|
||||||
#include "fsfw/tasks/PeriodicTaskIF.h"
|
#include "fsfw/tasks/PeriodicTaskIF.h"
|
||||||
#include "fsfw/tasks/TaskFactory.h"
|
#include "fsfw/tasks/TaskFactory.h"
|
||||||
|
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
|
||||||
#include "mission/utility/InitMission.h"
|
#include "mission/utility/InitMission.h"
|
||||||
#include "pollingsequence/pollingSequenceFactory.h"
|
#include "pollingsequence/pollingSequenceFactory.h"
|
||||||
|
|
||||||
@ -123,7 +126,7 @@ void initmission::initTasks() {
|
|||||||
|
|
||||||
#if OBSW_ADD_ACS_HANDLERS == 1
|
#if OBSW_ADD_ACS_HANDLERS == 1
|
||||||
PeriodicTaskIF* acsTask = factory->createPeriodicTask(
|
PeriodicTaskIF* acsTask = factory->createPeriodicTask(
|
||||||
"ACS_CTRL", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc);
|
"ACS_TASK", 50, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.4, missedDeadlineFunc);
|
||||||
result = acsTask->addComponent(objects::GPS_CONTROLLER);
|
result = acsTask->addComponent(objects::GPS_CONTROLLER);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("GPS_CTRL", objects::GPS_CONTROLLER);
|
initmission::printAddObjectError("GPS_CTRL", objects::GPS_CONTROLLER);
|
||||||
@ -145,19 +148,49 @@ void initmission::initTasks() {
|
|||||||
initmission::printAddObjectError("RW_ASS", objects::RW_ASS);
|
initmission::printAddObjectError("RW_ASS", objects::RW_ASS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OBSW_ADD_SUS_BOARD_ASS == 1
|
#if OBSW_ADD_SUS_BOARD_ASS == 1
|
||||||
result = sysTask->addComponent(objects::SUS_BOARD_ASS);
|
result = sysTask->addComponent(objects::SUS_BOARD_ASS);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("SUS_BOARD_ASS", objects::SUS_BOARD_ASS);
|
initmission::printAddObjectError("SUS_BOARD_ASS", objects::SUS_BOARD_ASS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_RTD_DEVICES == 1
|
|
||||||
result = sysTask->addComponent(objects::TCS_BOARD_ASS);
|
PeriodicTaskIF* tcsPollingTask = factory->createPeriodicTask(
|
||||||
|
"TCS_POLLING_TASK", 70, PeriodicTaskIF::MINIMUM_STACK_SIZE * 2, 0.5, missedDeadlineFunc);
|
||||||
|
result = tcsPollingTask->addComponent(objects::SPI_RTD_COM_IF);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
initmission::printAddObjectError("TCS_BOARD_ASS", objects::TCS_BOARD_ASS);
|
initmission::printAddObjectError("SPI_RTD_POLLING", objects::SPI_RTD_COM_IF);
|
||||||
}
|
}
|
||||||
#endif /* OBSW_ADD_RTD_DEVICES == 1 */
|
PeriodicTaskIF* tcsTask = factory->createPeriodicTask(
|
||||||
|
"TCS_TASK", 45, PeriodicTaskIF::MINIMUM_STACK_SIZE, 0.8, missedDeadlineFunc);
|
||||||
|
std::array<object_id_t, EiveMax31855::NUM_RTDS> rtdIds = {
|
||||||
|
objects::RTD_0_IC3_PLOC_HEATSPREADER,
|
||||||
|
objects::RTD_1_IC4_PLOC_MISSIONBOARD,
|
||||||
|
objects::RTD_2_IC5_4K_CAMERA,
|
||||||
|
objects::RTD_3_IC6_DAC_HEATSPREADER,
|
||||||
|
objects::RTD_4_IC7_STARTRACKER,
|
||||||
|
objects::RTD_5_IC8_RW1_MX_MY,
|
||||||
|
objects::RTD_6_IC9_DRO,
|
||||||
|
objects::RTD_7_IC10_SCEX,
|
||||||
|
objects::RTD_8_IC11_X8,
|
||||||
|
objects::RTD_9_IC12_HPA,
|
||||||
|
objects::RTD_10_IC13_PL_TX,
|
||||||
|
objects::RTD_11_IC14_MPA,
|
||||||
|
objects::RTD_12_IC15_ACU,
|
||||||
|
objects::RTD_13_IC16_PLPCDU_HEATSPREADER,
|
||||||
|
objects::RTD_14_IC17_TCS_BOARD,
|
||||||
|
objects::RTD_15_IC18_IMTQ,
|
||||||
|
};
|
||||||
|
#if OBSW_ADD_RTD_DEVICES == 1
|
||||||
|
tcsTask->addComponent(objects::TCS_BOARD_ASS);
|
||||||
|
for (const auto& rtd : rtdIds) {
|
||||||
|
tcsTask->addComponent(rtd, DeviceHandlerIF::PERFORM_OPERATION);
|
||||||
|
tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_WRITE);
|
||||||
|
tcsTask->addComponent(rtd, DeviceHandlerIF::GET_WRITE);
|
||||||
|
tcsTask->addComponent(rtd, DeviceHandlerIF::SEND_READ);
|
||||||
|
tcsTask->addComponent(rtd, DeviceHandlerIF::GET_READ);
|
||||||
|
}
|
||||||
|
#endif /* OBSW_ADD_RTD_DEVICES */
|
||||||
|
|
||||||
// FS task, task interval does not matter because it runs in permanent loop, priority low
|
// FS task, task interval does not matter because it runs in permanent loop, priority low
|
||||||
// because it is a non-essential background task
|
// because it is a non-essential background task
|
||||||
@ -254,12 +287,10 @@ void initmission::initTasks() {
|
|||||||
strHelperTask->startTask();
|
strHelperTask->startTask();
|
||||||
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
#endif /* OBSW_ADD_STAR_TRACKER == 1 */
|
||||||
|
|
||||||
#if OBSW_ADD_ACS_HANDLERS == 1
|
|
||||||
acsTask->startTask();
|
acsTask->startTask();
|
||||||
#endif
|
|
||||||
#if OBSW_ADD_RTD_DEVICES == 1
|
|
||||||
sysTask->startTask();
|
sysTask->startTask();
|
||||||
#endif
|
tcsPollingTask->startTask();
|
||||||
|
tcsTask->startTask();
|
||||||
#if OBSW_ADD_PLOC_SUPERVISOR == 1
|
#if OBSW_ADD_PLOC_SUPERVISOR == 1
|
||||||
supvHelperTask->startTask();
|
supvHelperTask->startTask();
|
||||||
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
|
#endif /* OBSW_ADD_PLOC_SUPERVISOR == 1 */
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "fsfw/tasks/Typedef.h"
|
#include "fsfw/tasks/definitions.h"
|
||||||
|
|
||||||
class PeriodicTaskIF;
|
class PeriodicTaskIF;
|
||||||
class TaskFactory;
|
class TaskFactory;
|
||||||
|
@ -214,6 +214,7 @@ void ObjectFactory::createRadSensorComponent(LinuxLibgpioIF* gpioComIF) {
|
|||||||
SpiCookie* spiCookieRadSensor =
|
SpiCookie* spiCookieRadSensor =
|
||||||
new SpiCookie(addresses::RAD_SENSOR, gpioIds::CS_RAD_SENSOR, RAD_SENSOR::READ_SIZE,
|
new SpiCookie(addresses::RAD_SENSOR, gpioIds::CS_RAD_SENSOR, RAD_SENSOR::READ_SIZE,
|
||||||
spi::DEFAULT_MAX_1227_MODE, spi::DEFAULT_MAX_1227_SPEED);
|
spi::DEFAULT_MAX_1227_MODE, spi::DEFAULT_MAX_1227_SPEED);
|
||||||
|
spiCookieRadSensor->setMutexParams(MutexIF::TimeoutType::WAITING, spi::RAD_SENSOR_CS_TIMEOUT);
|
||||||
auto radSensor = new RadiationSensorHandler(objects::RAD_SENSOR, objects::SPI_MAIN_COM_IF,
|
auto radSensor = new RadiationSensorHandler(objects::RAD_SENSOR, objects::SPI_MAIN_COM_IF,
|
||||||
spiCookieRadSensor, gpioComIF);
|
spiCookieRadSensor, gpioComIF);
|
||||||
static_cast<void>(radSensor);
|
static_cast<void>(radSensor);
|
||||||
|
@ -38,7 +38,7 @@ void ObjectFactory::produce(void* args) {
|
|||||||
#if OBSW_ADD_SYRLINKS == 1
|
#if OBSW_ADD_SYRLINKS == 1
|
||||||
createSyrlinksComponents(pwrSwitcher);
|
createSyrlinksComponents(pwrSwitcher);
|
||||||
#endif /* OBSW_ADD_SYRLINKS == 1 */
|
#endif /* OBSW_ADD_SYRLINKS == 1 */
|
||||||
createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher);
|
createRtdComponents(q7s::SPI_DEFAULT_DEV, gpioComIF, pwrSwitcher, spiMainComIF);
|
||||||
createPayloadComponents(gpioComIF);
|
createPayloadComponents(gpioComIF);
|
||||||
|
|
||||||
#if OBSW_ADD_MGT == 1
|
#if OBSW_ADD_MGT == 1
|
||||||
|
@ -32,6 +32,7 @@ static constexpr spi::SpiModes DEFAULT_L3G_MODE = spi::SpiModes::MODE_3;
|
|||||||
static const uint32_t SUS_MAX1227_SPI_FREQ = 976'000;
|
static const uint32_t SUS_MAX1227_SPI_FREQ = 976'000;
|
||||||
static constexpr spi::SpiModes SUS_MAX_1227_MODE = spi::SpiModes::MODE_3;
|
static constexpr spi::SpiModes SUS_MAX_1227_MODE = spi::SpiModes::MODE_3;
|
||||||
|
|
||||||
|
static constexpr dur_millis_t RAD_SENSOR_CS_TIMEOUT = 120;
|
||||||
static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 976'000;
|
static constexpr uint32_t DEFAULT_MAX_1227_SPEED = 976'000;
|
||||||
static constexpr spi::SpiModes DEFAULT_MAX_1227_MODE = spi::SpiModes::MODE_3;
|
static constexpr spi::SpiModes DEFAULT_MAX_1227_MODE = spi::SpiModes::MODE_3;
|
||||||
|
|
||||||
@ -43,6 +44,7 @@ static constexpr spi::SpiModes DEFAULT_ADIS16507_MODE = spi::SpiModes::MODE_3;
|
|||||||
static constexpr uint32_t RW_SPEED = 300'000;
|
static constexpr uint32_t RW_SPEED = 300'000;
|
||||||
static constexpr spi::SpiModes RW_MODE = spi::SpiModes::MODE_0;
|
static constexpr spi::SpiModes RW_MODE = spi::SpiModes::MODE_0;
|
||||||
|
|
||||||
|
static constexpr dur_millis_t RTD_CS_TIMEOUT = 50;
|
||||||
static constexpr uint32_t RTD_SPEED = 2'000'000;
|
static constexpr uint32_t RTD_SPEED = 2'000'000;
|
||||||
static constexpr spi::SpiModes RTD_MODE = spi::SpiModes::MODE_3;
|
static constexpr spi::SpiModes RTD_MODE = spi::SpiModes::MODE_3;
|
||||||
|
|
||||||
|
2
fsfw
2
fsfw
@ -1 +1 @@
|
|||||||
Subproject commit e758f0be2e8864c761877a4dcbdf461df52072f7
|
Subproject commit f35b0ffbbd6e0e9cc1a760d0aeb69931907f1d62
|
@ -7,6 +7,8 @@
|
|||||||
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||||
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||||
#include <linux/callbacks/gpioCallbacks.h>
|
#include <linux/callbacks/gpioCallbacks.h>
|
||||||
|
#include <linux/devices/Max31865RtdLowlevelHandler.h>
|
||||||
|
#include <mission/devices/Max31865EiveHandler.h>
|
||||||
#include <mission/devices/Max31865PT1000Handler.h>
|
#include <mission/devices/Max31865PT1000Handler.h>
|
||||||
#include <mission/devices/SusHandler.h>
|
#include <mission/devices/SusHandler.h>
|
||||||
#include <mission/system/SusAssembly.h>
|
#include <mission/system/SusAssembly.h>
|
||||||
@ -189,7 +191,7 @@ void ObjectFactory::createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF,
|
void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF,
|
||||||
PowerSwitchIF* pwrSwitcher) {
|
PowerSwitchIF* pwrSwitcher, SpiComIF* comIF) {
|
||||||
using namespace gpio;
|
using namespace gpio;
|
||||||
GpioCookie* rtdGpioCookie = new GpioCookie;
|
GpioCookie* rtdGpioCookie = new GpioCookie;
|
||||||
|
|
||||||
@ -245,8 +247,8 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF,
|
|||||||
gpioChecker(gpioComIF->addGpios(rtdGpioCookie), "RTDs");
|
gpioChecker(gpioComIF->addGpios(rtdGpioCookie), "RTDs");
|
||||||
|
|
||||||
#if OBSW_ADD_RTD_DEVICES == 1
|
#if OBSW_ADD_RTD_DEVICES == 1
|
||||||
static constexpr uint8_t NUMBER_RTDS = 16;
|
using namespace EiveMax31855;
|
||||||
std::array<std::pair<address_t, gpioId_t>, NUMBER_RTDS> cookieArgs = {{
|
std::array<std::pair<address_t, gpioId_t>, NUM_RTDS> cookieArgs = {{
|
||||||
{addresses::RTD_IC_3, gpioIds::RTD_IC_3},
|
{addresses::RTD_IC_3, gpioIds::RTD_IC_3},
|
||||||
{addresses::RTD_IC_4, gpioIds::RTD_IC_4},
|
{addresses::RTD_IC_4, gpioIds::RTD_IC_4},
|
||||||
{addresses::RTD_IC_5, gpioIds::RTD_IC_5},
|
{addresses::RTD_IC_5, gpioIds::RTD_IC_5},
|
||||||
@ -264,48 +266,52 @@ void ObjectFactory::createRtdComponents(std::string spiDev, GpioIF* gpioComIF,
|
|||||||
{addresses::RTD_IC_17, gpioIds::RTD_IC_17},
|
{addresses::RTD_IC_17, gpioIds::RTD_IC_17},
|
||||||
{addresses::RTD_IC_18, gpioIds::RTD_IC_18},
|
{addresses::RTD_IC_18, gpioIds::RTD_IC_18},
|
||||||
}};
|
}};
|
||||||
std::array<object_id_t, NUMBER_RTDS> rtdIds = {objects::RTD_0_IC3_PLOC_HEATSPREADER,
|
// HSPD: Heatspreader
|
||||||
objects::RTD_1_IC4_PLOC_MISSIONBOARD,
|
std::array<std::pair<object_id_t, std::string>, NUM_RTDS> rtdInfos = {{
|
||||||
objects::RTD_2_IC5_4K_CAMERA,
|
{objects::RTD_0_IC3_PLOC_HEATSPREADER, "RTD_0_PLOC_HSPD"},
|
||||||
objects::RTD_3_IC6_DAC_HEATSPREADER,
|
{objects::RTD_1_IC4_PLOC_MISSIONBOARD, "RTD_1_PLOC_MISSIONBRD"},
|
||||||
objects::RTD_4_IC7_STARTRACKER,
|
{objects::RTD_2_IC5_4K_CAMERA, "RTD_2_4K_CAMERA"},
|
||||||
objects::RTD_5_IC8_RW1_MX_MY,
|
{objects::RTD_3_IC6_DAC_HEATSPREADER, "RTD_3_DAC_HSPD"},
|
||||||
objects::RTD_6_IC9_DRO,
|
{objects::RTD_4_IC7_STARTRACKER, "RTD_4_STARTRACKER"},
|
||||||
objects::RTD_7_IC10_SCEX,
|
{objects::RTD_5_IC8_RW1_MX_MY, "RTD_5_RW1_MX_MY"},
|
||||||
objects::RTD_8_IC11_X8,
|
{objects::RTD_6_IC9_DRO, "RTD_6_DRO"},
|
||||||
objects::RTD_9_IC12_HPA,
|
{objects::RTD_7_IC10_SCEX, "RTD_7_SCEX"},
|
||||||
objects::RTD_10_IC13_PL_TX,
|
{objects::RTD_8_IC11_X8, "RTD_8_X8"},
|
||||||
objects::RTD_11_IC14_MPA,
|
{objects::RTD_9_IC12_HPA, "RTD_9_HPA"},
|
||||||
objects::RTD_12_IC15_ACU,
|
{objects::RTD_10_IC13_PL_TX, "RTD_10_PL_TX,"},
|
||||||
objects::RTD_13_IC16_PLPCDU_HEATSPREADER,
|
{objects::RTD_11_IC14_MPA, "RTD_11_MPA"},
|
||||||
objects::RTD_14_IC17_TCS_BOARD,
|
{objects::RTD_12_IC15_ACU, "RTD_12_ACU"},
|
||||||
objects::RTD_15_IC18_IMTQ};
|
{objects::RTD_13_IC16_PLPCDU_HEATSPREADER, "RTD_13_PLPCDU_HSPD"},
|
||||||
std::array<SpiCookie*, NUMBER_RTDS> rtdCookies = {};
|
{objects::RTD_14_IC17_TCS_BOARD, "RTD_14_TCS_BOARD"},
|
||||||
std::array<Max31865PT1000Handler*, NUMBER_RTDS> rtds = {};
|
{objects::RTD_15_IC18_IMTQ, "RTD_15_IMTQ"},
|
||||||
|
}};
|
||||||
|
std::array<SpiCookie*, NUM_RTDS> rtdCookies = {};
|
||||||
|
std::array<Max31865EiveHandler*, NUM_RTDS> rtds = {};
|
||||||
RtdFdir* rtdFdir = nullptr;
|
RtdFdir* rtdFdir = nullptr;
|
||||||
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
// Create special low level reader communication interface
|
||||||
rtdCookies[idx] =
|
new Max31865RtdReader(objects::SPI_RTD_COM_IF, comIF, gpioComIF);
|
||||||
new SpiCookie(cookieArgs[idx].first, cookieArgs[idx].second,
|
for (uint8_t idx = 0; idx < NUM_RTDS; idx++) {
|
||||||
Max31865Definitions::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED);
|
rtdCookies[idx] = new SpiCookie(cookieArgs[idx].first, cookieArgs[idx].second,
|
||||||
rtds[idx] = new Max31865PT1000Handler(rtdIds[idx], objects::SPI_MAIN_COM_IF, rtdCookies[idx]);
|
MAX31865::MAX_REPLY_SIZE, spi::RTD_MODE, spi::RTD_SPEED);
|
||||||
|
rtdCookies[idx]->setMutexParams(MutexIF::TimeoutType::WAITING, spi::RTD_CS_TIMEOUT);
|
||||||
|
Max31865ReaderCookie* rtdLowLevelCookie =
|
||||||
|
new Max31865ReaderCookie(rtdInfos[idx].first, idx, rtdInfos[idx].second, rtdCookies[idx]);
|
||||||
|
rtds[idx] =
|
||||||
|
new Max31865EiveHandler(rtdInfos[idx].first, objects::SPI_RTD_COM_IF, rtdLowLevelCookie);
|
||||||
|
rtds[idx]->setDeviceInfo(idx, rtdInfos[idx].second);
|
||||||
rtds[idx]->setParent(objects::TCS_BOARD_ASS);
|
rtds[idx]->setParent(objects::TCS_BOARD_ASS);
|
||||||
rtdFdir = new RtdFdir(rtdIds[idx]);
|
rtdFdir = new RtdFdir(rtdInfos[idx].first);
|
||||||
rtds[idx]->setCustomFdir(rtdFdir);
|
rtds[idx]->setCustomFdir(rtdFdir);
|
||||||
rtds[idx]->setDeviceIdx(idx + 3);
|
|
||||||
#if OBSW_DEBUG_RTD == 1
|
#if OBSW_DEBUG_RTD == 1
|
||||||
rtds[idx]->setDebugMode(true);
|
rtds[idx]->setDebugMode(true, 5);
|
||||||
|
#endif
|
||||||
|
#if OBSW_TEST_RTD == 1
|
||||||
|
rtds[idx]->setInstantNormal(true);
|
||||||
|
rtds[idx]->setStartUpImmediately();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OBSW_TEST_RTD == 1
|
TcsBoardHelper helper(rtdInfos);
|
||||||
for (auto& rtd : rtds) {
|
|
||||||
if (rtd != nullptr) {
|
|
||||||
rtd->setStartUpImmediately();
|
|
||||||
rtd->setInstantNormal(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // OBSW_TEST_RTD == 1
|
|
||||||
TcsBoardHelper helper(rtdIds);
|
|
||||||
TcsBoardAssembly* tcsBoardAss =
|
TcsBoardAssembly* tcsBoardAss =
|
||||||
new TcsBoardAssembly(objects::TCS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher,
|
new TcsBoardAssembly(objects::TCS_BOARD_ASS, objects::NO_OBJECT, pwrSwitcher,
|
||||||
pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
|
pcdu::Switches::PDU1_CH0_TCS_BOARD_3V3, helper);
|
||||||
|
@ -12,7 +12,8 @@ namespace ObjectFactory {
|
|||||||
|
|
||||||
void createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, PowerSwitchIF* pwrSwitcher,
|
void createSunSensorComponents(GpioIF* gpioComIF, SpiComIF* spiComIF, PowerSwitchIF* pwrSwitcher,
|
||||||
std::string spiDev);
|
std::string spiDev);
|
||||||
void createRtdComponents(std::string spiDev, GpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher);
|
void createRtdComponents(std::string spiDev, GpioIF* gpioComIF, PowerSwitchIF* pwrSwitcher,
|
||||||
|
SpiComIF* comIF);
|
||||||
|
|
||||||
void gpioChecker(ReturnValue_t result, std::string output);
|
void gpioChecker(ReturnValue_t result, std::string output);
|
||||||
|
|
||||||
|
@ -2,5 +2,9 @@ if(EIVE_BUILD_GPSD_GPS_HANDLER)
|
|||||||
target_sources(${OBSW_NAME} PRIVATE GPSHyperionLinuxController.cpp)
|
target_sources(${OBSW_NAME} PRIVATE GPSHyperionLinuxController.cpp)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
target_sources(${OBSW_NAME} PRIVATE
|
||||||
|
Max31865RtdLowlevelHandler.cpp
|
||||||
|
)
|
||||||
|
|
||||||
add_subdirectory(ploc)
|
add_subdirectory(ploc)
|
||||||
add_subdirectory(startracker)
|
add_subdirectory(startracker)
|
||||||
|
465
linux/devices/Max31865RtdLowlevelHandler.cpp
Normal file
465
linux/devices/Max31865RtdLowlevelHandler.cpp
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
#include "Max31865RtdLowlevelHandler.h"
|
||||||
|
|
||||||
|
#include <fsfw/tasks/TaskFactory.h>
|
||||||
|
#include <fsfw/timemanager/Stopwatch.h>
|
||||||
|
#include <fsfw_hal/linux/spi/ManualCsLockGuard.h>
|
||||||
|
|
||||||
|
#define OBSW_RTD_AUTO_MODE 1
|
||||||
|
|
||||||
|
#if OBSW_RTD_AUTO_MODE == 1
|
||||||
|
static constexpr uint8_t BASE_CFG = (MAX31865::Bias::ON << MAX31865::CfgBitPos::BIAS_SEL) |
|
||||||
|
(MAX31865::Wires::FOUR_WIRE << MAX31865::CfgBitPos::WIRE_SEL) |
|
||||||
|
(MAX31865::ConvMode::AUTO << MAX31865::CfgBitPos::CONV_MODE);
|
||||||
|
#else
|
||||||
|
static constexpr uint8_t BASE_CFG =
|
||||||
|
(MAX31865::Bias::OFF << MAX31865::CfgBitPos::BIAS_SEL) |
|
||||||
|
(MAX31865::Wires::FOUR_WIRE << MAX31865::CfgBitPos::WIRE_SEL) |
|
||||||
|
(MAX31865::ConvMode::NORM_OFF << MAX31865::CfgBitPos::CONV_MODE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Max31865RtdReader::Max31865RtdReader(object_id_t objectId, SpiComIF* lowLevelComIF, GpioIF* gpioIF)
|
||||||
|
: SystemObject(objectId), rtds(EiveMax31855::NUM_RTDS), comIF(lowLevelComIF), gpioIF(gpioIF) {
|
||||||
|
readerMutex = MutexFactory::instance()->createMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::performOperation(uint8_t operationCode) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
static_cast<void>(result);
|
||||||
|
// Stopwatch watch;
|
||||||
|
if (periodicInitHandling()) {
|
||||||
|
#if OBSW_RTD_AUTO_MODE == 0
|
||||||
|
// 10 ms delay for VBIAS startup
|
||||||
|
TaskFactory::delayTask(10);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
// No devices usable (e.g. TCS board off)
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if OBSW_RTD_AUTO_MODE == 0
|
||||||
|
result = periodicReadReqHandling();
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// After requesting, 65 milliseconds delay required
|
||||||
|
TaskFactory::delayTask(65);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return periodicReadHandling();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Max31865RtdReader::rtdIsActive(uint8_t idx) {
|
||||||
|
if (rtds[idx]->on and rtds[idx]->active and rtds[idx]->configured) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Max31865RtdReader::periodicInitHandling() {
|
||||||
|
using namespace MAX31865;
|
||||||
|
MutexGuard mg(readerMutex);
|
||||||
|
ReturnValue_t result = RETURN_OK;
|
||||||
|
if (mg.getLockResult() != RETURN_OK) {
|
||||||
|
sif::warning << "Max31865RtdReader::periodicInitHandling: Mutex lock failed" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& rtd : rtds) {
|
||||||
|
if (rtd == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((rtd->on or rtd->active) and not rtd->configured and rtd->cd.hasTimedOut()) {
|
||||||
|
ManualCsLockWrapper mg(csLock, gpioIF, rtd->spiCookie, csTimeoutType, csTimeoutMs);
|
||||||
|
if (mg.lockResult != RETURN_OK or mg.gpioResult != RETURN_OK) {
|
||||||
|
sif::error << "Max31865RtdReader::periodicInitHandling: Manual CS lock failed" << std::endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = writeCfgReg(rtd->spiCookie, BASE_CFG);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
handleSpiError(rtd, result, "writeCfgReg");
|
||||||
|
}
|
||||||
|
if (rtd->writeLowThreshold) {
|
||||||
|
result = writeLowThreshold(rtd->spiCookie, rtd->lowThreshold);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
handleSpiError(rtd, result, "writeLowThreshold");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rtd->writeHighThreshold) {
|
||||||
|
result = writeHighThreshold(rtd->spiCookie, rtd->highThreshold);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
handleSpiError(rtd, result, "writeHighThreshold");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = clearFaultStatus(rtd->spiCookie);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
handleSpiError(rtd, result, "clearFaultStatus");
|
||||||
|
}
|
||||||
|
rtd->configured = true;
|
||||||
|
rtd->db.configured = true;
|
||||||
|
if (rtd->active) {
|
||||||
|
rtd->db.active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rtd->active and rtd->configured and not rtd->db.active) {
|
||||||
|
rtd->db.active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool someRtdUsable = false;
|
||||||
|
for (auto& rtd : rtds) {
|
||||||
|
if (rtd == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (rtdIsActive(rtd->idx)) {
|
||||||
|
#if OBSW_RTD_AUTO_MODE == 0
|
||||||
|
someRtdUsable = true;
|
||||||
|
result = writeBiasSel(Bias::ON, rtd->spiCookie, BASE_CFG);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return someRtdUsable;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::periodicReadReqHandling() {
|
||||||
|
using namespace MAX31865;
|
||||||
|
MutexGuard mg(readerMutex);
|
||||||
|
if (mg.getLockResult() != RETURN_OK) {
|
||||||
|
sif::warning << "Max31865RtdReader::periodicReadReqHandling: Mutex lock failed" << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
// Now request one shot config for all active RTDs
|
||||||
|
for (auto& rtd : rtds) {
|
||||||
|
if (rtd == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (rtdIsActive(rtd->idx)) {
|
||||||
|
ReturnValue_t result = writeCfgReg(rtd->spiCookie, BASE_CFG | (1 << CfgBitPos::ONE_SHOT));
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
handleSpiError(rtd, result, "writeCfgReg");
|
||||||
|
// Release mutex ASAP
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::periodicReadHandling() {
|
||||||
|
using namespace MAX31865;
|
||||||
|
auto result = RETURN_OK;
|
||||||
|
MutexGuard mg(readerMutex);
|
||||||
|
if (mg.getLockResult() != RETURN_OK) {
|
||||||
|
sif::warning << "Max31865RtdReader::periodicReadReqHandling: Mutex lock failed" << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
// Now read the RTD values
|
||||||
|
for (auto& rtd : rtds) {
|
||||||
|
if (rtd == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (rtdIsActive(rtd->idx)) {
|
||||||
|
uint16_t rtdVal = 0;
|
||||||
|
bool faultBitSet = false;
|
||||||
|
result = readRtdVal(rtd->spiCookie, rtdVal, faultBitSet);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
handleSpiError(rtd, result, "readRtdVal");
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
if (faultBitSet) {
|
||||||
|
rtd->db.faultBitSet = faultBitSet;
|
||||||
|
}
|
||||||
|
rtd->db.adcCode = rtdVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if OBSW_RTD_AUTO_MODE == 0
|
||||||
|
for (auto& rtd : rtds) {
|
||||||
|
if (rtd == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Even if a device was made inactive, turn off the bias here. If it was turned off, not
|
||||||
|
// necessary anymore..
|
||||||
|
if (rtd->on) {
|
||||||
|
result = writeBiasSel(Bias::OFF, rtd->spiCookie, BASE_CFG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::initializeInterface(CookieIF* cookie) {
|
||||||
|
if (cookie == nullptr) {
|
||||||
|
throw std::invalid_argument("Invalid MAX31865 Reader Cookie");
|
||||||
|
}
|
||||||
|
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
|
||||||
|
ReturnValue_t result = comIF->initializeInterface(rtdCookie->spiCookie);
|
||||||
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (rtdCookie->idx > EiveMax31855::NUM_RTDS) {
|
||||||
|
throw std::invalid_argument("Invalid RTD index");
|
||||||
|
}
|
||||||
|
rtds[rtdCookie->idx] = rtdCookie;
|
||||||
|
MutexGuard mg(readerMutex);
|
||||||
|
if (dbLen == 0) {
|
||||||
|
dbLen = rtdCookie->db.getSerializedSize();
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
||||||
|
size_t sendLen) {
|
||||||
|
if (cookie == nullptr) {
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
// Empty command.. don't fail for now
|
||||||
|
if (sendLen < 1) {
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
MutexGuard mg(readerMutex);
|
||||||
|
if (mg.getLockResult() != RETURN_OK) {
|
||||||
|
sif::warning << "Max31865RtdReader::sendMessage: Mutex lock failed" << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
|
||||||
|
uint8_t cmdRaw = sendData[0];
|
||||||
|
if (cmdRaw > EiveMax31855::RtdCommands::NUM_CMDS) {
|
||||||
|
sif::warning << "Max31865RtdReader::sendMessage: Invalid command" << std::endl;
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto thresholdHandler = [](Max31865ReaderCookie* rtdCookie, const uint8_t* sendData) {
|
||||||
|
rtdCookie->lowThreshold = (sendData[1] << 8) | sendData[2];
|
||||||
|
rtdCookie->highThreshold = (sendData[3] << 8) | sendData[4];
|
||||||
|
rtdCookie->writeLowThreshold = true;
|
||||||
|
rtdCookie->writeHighThreshold = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto cmd = static_cast<EiveMax31855::RtdCommands>(sendData[0]);
|
||||||
|
switch (cmd) {
|
||||||
|
case (EiveMax31855::RtdCommands::ON): {
|
||||||
|
if (not rtdCookie->on) {
|
||||||
|
rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS);
|
||||||
|
rtdCookie->cd.resetTimer();
|
||||||
|
rtdCookie->on = true;
|
||||||
|
rtdCookie->active = false;
|
||||||
|
rtdCookie->configured = false;
|
||||||
|
if (sendLen == 5) {
|
||||||
|
thresholdHandler(rtdCookie, sendData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (EiveMax31855::RtdCommands::ACTIVE): {
|
||||||
|
if (not rtdCookie->on) {
|
||||||
|
rtdCookie->cd.setTimeout(MAX31865::WARMUP_MS);
|
||||||
|
rtdCookie->cd.resetTimer();
|
||||||
|
rtdCookie->on = true;
|
||||||
|
rtdCookie->active = true;
|
||||||
|
rtdCookie->configured = false;
|
||||||
|
} else {
|
||||||
|
rtdCookie->active = true;
|
||||||
|
}
|
||||||
|
if (sendLen == 5) {
|
||||||
|
thresholdHandler(rtdCookie, sendData);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (EiveMax31855::RtdCommands::OFF): {
|
||||||
|
rtdCookie->on = false;
|
||||||
|
rtdCookie->active = false;
|
||||||
|
rtdCookie->configured = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (EiveMax31855::RtdCommands::HIGH_TRESHOLD): {
|
||||||
|
if (sendLen == 3) {
|
||||||
|
rtdCookie->highThreshold = (sendData[1] << 8) | sendData[2];
|
||||||
|
rtdCookie->writeHighThreshold = true;
|
||||||
|
} else {
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (EiveMax31855::RtdCommands::LOW_THRESHOLD): {
|
||||||
|
if (sendLen == 3) {
|
||||||
|
rtdCookie->lowThreshold = (sendData[1] << 8) | sendData[2];
|
||||||
|
rtdCookie->writeLowThreshold = true;
|
||||||
|
} else {
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (EiveMax31855::RtdCommands::CFG):
|
||||||
|
default: {
|
||||||
|
// TODO: Only implement if needed
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::getSendSuccess(CookieIF* cookie) { return RETURN_OK; }
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
||||||
|
size_t* size) {
|
||||||
|
MutexGuard mg(readerMutex);
|
||||||
|
if (mg.getLockResult() != RETURN_OK) {
|
||||||
|
// TODO: Emit warning
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
auto* rtdCookie = dynamic_cast<Max31865ReaderCookie*>(cookie);
|
||||||
|
uint8_t* exchangePtr = rtdCookie->exchangeBuf.data();
|
||||||
|
size_t serLen = 0;
|
||||||
|
auto result = rtdCookie->db.serialize(&exchangePtr, &serLen, rtdCookie->exchangeBuf.size(),
|
||||||
|
SerializeIF::Endianness::MACHINE);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
// TODO: Emit warning
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
*buffer = reinterpret_cast<uint8_t*>(rtdCookie->exchangeBuf.data());
|
||||||
|
*size = serLen;
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::writeCfgReg(SpiCookie* cookie, uint8_t cfg) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
return writeNToReg(cookie, CONFIG, 1, &cfg, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::writeBiasSel(MAX31865::Bias bias, SpiCookie* cookie,
|
||||||
|
uint8_t baseCfg) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
if (bias == MAX31865::Bias::OFF) {
|
||||||
|
baseCfg &= ~(1 << CfgBitPos::BIAS_SEL);
|
||||||
|
} else {
|
||||||
|
baseCfg |= (1 << CfgBitPos::BIAS_SEL);
|
||||||
|
}
|
||||||
|
return writeCfgReg(cookie, baseCfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::clearFaultStatus(SpiCookie* cookie) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
// Read back the current configuration to avoid overwriting it when clearing te fault status
|
||||||
|
uint8_t currentCfg = 0;
|
||||||
|
auto result = readCfgReg(cookie, currentCfg);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// Clear bytes 5, 3 and 2 which need to be 0
|
||||||
|
currentCfg &= ~0x2C;
|
||||||
|
currentCfg |= (1 << CfgBitPos::FAULT_STATUS_CLEAR);
|
||||||
|
return writeCfgReg(cookie, currentCfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::readCfgReg(SpiCookie* cookie, uint8_t& cfg) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
uint8_t* replyPtr = nullptr;
|
||||||
|
auto result = readNFromReg(cookie, CONFIG, 1, &replyPtr);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
cfg = replyPtr[0];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::writeLowThreshold(SpiCookie* cookie, uint16_t val) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
uint8_t cmd[2] = {static_cast<uint8_t>((val >> 8) & 0xff), static_cast<uint8_t>(val & 0xff)};
|
||||||
|
return writeNToReg(cookie, LOW_THRESHOLD, 2, cmd, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::writeHighThreshold(SpiCookie* cookie, uint16_t val) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
uint8_t cmd[2] = {static_cast<uint8_t>((val >> 8) & 0xff), static_cast<uint8_t>(val & 0xff)};
|
||||||
|
return writeNToReg(cookie, HIGH_THRESHOLD, 2, cmd, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::readLowThreshold(SpiCookie* cookie, uint16_t& lowThreshold) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
uint8_t* replyPtr = nullptr;
|
||||||
|
auto result = readNFromReg(cookie, LOW_THRESHOLD, 2, &replyPtr);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
lowThreshold = (replyPtr[0] << 8) | replyPtr[1];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::readHighThreshold(SpiCookie* cookie, uint16_t& highThreshold) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
uint8_t* replyPtr = nullptr;
|
||||||
|
auto result = readNFromReg(cookie, HIGH_THRESHOLD, 2, &replyPtr);
|
||||||
|
if (result == RETURN_OK) {
|
||||||
|
highThreshold = (replyPtr[0] << 8) | replyPtr[1];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::writeNToReg(SpiCookie* cookie, uint8_t reg, size_t n, uint8_t* cmd,
|
||||||
|
uint8_t** reply) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
if (n > cmdBuf.size() - 1) {
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
cmdBuf[0] = reg | WRITE_BIT;
|
||||||
|
for (size_t idx = 0; idx < n; idx++) {
|
||||||
|
cmdBuf[idx + 1] = cmd[idx];
|
||||||
|
}
|
||||||
|
return comIF->sendMessage(cookie, cmdBuf.data(), n + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::readRtdVal(SpiCookie* cookie, uint16_t& val, bool& faultBitSet) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
uint8_t* replyPtr = nullptr;
|
||||||
|
auto result = readNFromReg(cookie, RTD, 2, &replyPtr);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (replyPtr[1] & 0b0000'0001) {
|
||||||
|
faultBitSet = true;
|
||||||
|
}
|
||||||
|
// Shift 1 to the right to remove fault bit
|
||||||
|
val = ((replyPtr[0] << 8) | replyPtr[1]) >> 1;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::readNFromReg(SpiCookie* cookie, uint8_t reg, size_t n,
|
||||||
|
uint8_t** reply) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
if (n > 4) {
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
// Clear write bit in any case
|
||||||
|
reg &= ~WRITE_BIT;
|
||||||
|
cmdBuf[0] = reg;
|
||||||
|
std::memset(cmdBuf.data() + 1, 0, n);
|
||||||
|
ReturnValue_t result = comIF->sendMessage(cookie, cmdBuf.data(), n + 1);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return RETURN_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t dummyLen = 0;
|
||||||
|
uint8_t* replyPtr = nullptr;
|
||||||
|
result = comIF->readReceivedMessage(cookie, &replyPtr, &dummyLen);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (reply != nullptr) {
|
||||||
|
*reply = replyPtr + 1;
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::handleSpiError(Max31865ReaderCookie* cookie, ReturnValue_t result,
|
||||||
|
const char* ctx) {
|
||||||
|
cookie->db.spiErrorCount.value += 1;
|
||||||
|
sif::warning << "Max31865RtdReader::handleSpiError: " << ctx << " | Failed with result " << result
|
||||||
|
<< std::endl;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865RtdReader::initialize() {
|
||||||
|
csLock = comIF->getCsMutex();
|
||||||
|
return SystemObject::initialize();
|
||||||
|
}
|
87
linux/devices/Max31865RtdLowlevelHandler.h
Normal file
87
linux/devices/Max31865RtdLowlevelHandler.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#ifndef LINUX_DEVICES_MAX31865RTDREADER_H_
|
||||||
|
#define LINUX_DEVICES_MAX31865RTDREADER_H_
|
||||||
|
|
||||||
|
#include <fsfw/ipc/MutexIF.h>
|
||||||
|
#include <fsfw/tasks/ExecutableObjectIF.h>
|
||||||
|
#include <fsfw_hal/linux/spi/SpiComIF.h>
|
||||||
|
#include <fsfw_hal/linux/spi/SpiCookie.h>
|
||||||
|
|
||||||
|
#include "fsfw/devicehandlers/DeviceCommunicationIF.h"
|
||||||
|
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
|
||||||
|
|
||||||
|
struct Max31865ReaderCookie : public CookieIF {
|
||||||
|
Max31865ReaderCookie(){};
|
||||||
|
Max31865ReaderCookie(object_id_t handlerId_, uint8_t idx_, const std::string& locString_,
|
||||||
|
SpiCookie* spiCookie_)
|
||||||
|
: idx(idx_), handlerId(handlerId_), locString(locString_), spiCookie(spiCookie_) {}
|
||||||
|
|
||||||
|
uint8_t idx = 0;
|
||||||
|
object_id_t handlerId = objects::NO_OBJECT;
|
||||||
|
|
||||||
|
std::string locString = "";
|
||||||
|
std::array<uint8_t, 12> exchangeBuf{};
|
||||||
|
Countdown cd = Countdown(MAX31865::WARMUP_MS);
|
||||||
|
|
||||||
|
bool on = false;
|
||||||
|
bool configured = false;
|
||||||
|
bool active = false;
|
||||||
|
bool writeLowThreshold = false;
|
||||||
|
bool writeHighThreshold = false;
|
||||||
|
uint16_t lowThreshold = 0;
|
||||||
|
uint16_t highThreshold = 0;
|
||||||
|
SpiCookie* spiCookie = nullptr;
|
||||||
|
|
||||||
|
// Exchange data buffer struct
|
||||||
|
EiveMax31855::ReadOutStruct db;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Max31865RtdReader : public SystemObject,
|
||||||
|
public ExecutableObjectIF,
|
||||||
|
public DeviceCommunicationIF {
|
||||||
|
public:
|
||||||
|
Max31865RtdReader(object_id_t objectId, SpiComIF* lowLevelComIF, GpioIF* gpioIF);
|
||||||
|
|
||||||
|
ReturnValue_t performOperation(uint8_t operationCode) override;
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<Max31865ReaderCookie*> rtds;
|
||||||
|
std::array<uint8_t, 4> cmdBuf = {};
|
||||||
|
size_t dbLen = 0;
|
||||||
|
MutexIF* readerMutex;
|
||||||
|
|
||||||
|
SpiComIF* comIF;
|
||||||
|
GpioIF* gpioIF;
|
||||||
|
MutexIF::TimeoutType csTimeoutType = MutexIF::TimeoutType::BLOCKING;
|
||||||
|
uint32_t csTimeoutMs = 0;
|
||||||
|
MutexIF* csLock = nullptr;
|
||||||
|
|
||||||
|
bool periodicInitHandling();
|
||||||
|
ReturnValue_t periodicReadReqHandling();
|
||||||
|
ReturnValue_t periodicReadHandling();
|
||||||
|
|
||||||
|
bool rtdIsActive(uint8_t idx);
|
||||||
|
ReturnValue_t writeCfgReg(SpiCookie* cookie, uint8_t cfg);
|
||||||
|
ReturnValue_t writeBiasSel(MAX31865::Bias bias, SpiCookie* cookie, uint8_t baseCfg);
|
||||||
|
ReturnValue_t readCfgReg(SpiCookie* cookie, uint8_t& cfg);
|
||||||
|
ReturnValue_t readRtdVal(SpiCookie* cookie, uint16_t& val, bool& faultBitSet);
|
||||||
|
ReturnValue_t writeLowThreshold(SpiCookie* cookie, uint16_t val);
|
||||||
|
ReturnValue_t writeHighThreshold(SpiCookie* cookie, uint16_t val);
|
||||||
|
ReturnValue_t readLowThreshold(SpiCookie* cookie, uint16_t& val);
|
||||||
|
ReturnValue_t readHighThreshold(SpiCookie* cookie, uint16_t& val);
|
||||||
|
ReturnValue_t clearFaultStatus(SpiCookie* cookie);
|
||||||
|
|
||||||
|
ReturnValue_t readNFromReg(SpiCookie* cookie, uint8_t reg, size_t n, uint8_t** reply);
|
||||||
|
ReturnValue_t writeNToReg(SpiCookie* cookie, uint8_t reg, size_t n, uint8_t* cmd,
|
||||||
|
uint8_t** reply);
|
||||||
|
|
||||||
|
ReturnValue_t initializeInterface(CookieIF* cookie) override;
|
||||||
|
ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override;
|
||||||
|
ReturnValue_t getSendSuccess(CookieIF* cookie) override;
|
||||||
|
ReturnValue_t requestReceiveMessage(CookieIF* cookie, size_t requestLen) override;
|
||||||
|
ReturnValue_t readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) override;
|
||||||
|
|
||||||
|
ReturnValue_t handleSpiError(Max31865ReaderCookie* cookie, ReturnValue_t result, const char* ctx);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LINUX_DEVICES_MAX31865RTDREADER_H_ */
|
@ -50,6 +50,7 @@ enum sourceObjects : uint32_t {
|
|||||||
SPI_MAIN_COM_IF = 0x49020004,
|
SPI_MAIN_COM_IF = 0x49020004,
|
||||||
GPIO_IF = 0x49010005,
|
GPIO_IF = 0x49010005,
|
||||||
SPI_RW_COM_IF = 0x49020005,
|
SPI_RW_COM_IF = 0x49020005,
|
||||||
|
SPI_RTD_COM_IF = 0x49020006,
|
||||||
|
|
||||||
/* 0x54 ('T') for test handlers */
|
/* 0x54 ('T') for test handlers */
|
||||||
TEST_TASK = 0x54694269,
|
TEST_TASK = 0x54694269,
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
#include <fsfw/serviceinterface/ServiceInterfaceStream.h>
|
||||||
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
#include <fsfw/tasks/FixedTimeslotTaskIF.h>
|
||||||
|
|
||||||
|
#include "mission/devices/devicedefinitions/Max31865Definitions.h"
|
||||||
|
|
||||||
#ifndef RPI_TEST_ADIS16507
|
#ifndef RPI_TEST_ADIS16507
|
||||||
#define RPI_TEST_ADIS16507 0
|
#define RPI_TEST_ADIS16507 0
|
||||||
#endif
|
#endif
|
||||||
@ -64,157 +66,34 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) {
|
|||||||
static_cast<void>(length);
|
static_cast<void>(length);
|
||||||
#if OBSW_ADD_PL_PCDU == 1
|
#if OBSW_ADD_PL_PCDU == 1
|
||||||
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||||
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::SEND_WRITE);
|
||||||
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::GET_WRITE);
|
||||||
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.6, DeviceHandlerIF::SEND_READ);
|
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::SEND_READ);
|
||||||
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0.8, DeviceHandlerIF::GET_READ);
|
thisSequence->addSlot(objects::PLPCDU_HANDLER, length * 0, DeviceHandlerIF::GET_READ);
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_TMP_DEVICES == 1
|
#if OBSW_ADD_TMP_DEVICES == 1
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_RTD_DEVICES == 1
|
|
||||||
thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0,
|
|
||||||
DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0,
|
|
||||||
DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0,
|
|
||||||
DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0,
|
|
||||||
DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0,
|
|
||||||
DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0,
|
|
||||||
DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0,
|
|
||||||
DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0,
|
|
||||||
DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
#endif /* OBSW_ADD_RTD_DEVICES */
|
|
||||||
|
|
||||||
#if OBSW_ADD_TMP_DEVICES == 1
|
#if OBSW_ADD_TMP_DEVICES == 1
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_RTD_DEVICES == 1
|
|
||||||
thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0.2,
|
|
||||||
DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0.2,
|
|
||||||
DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0.2,
|
|
||||||
DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0.2,
|
|
||||||
DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
#endif /* OBSW_ADD_RTD_DEVICES */
|
|
||||||
|
|
||||||
#if OBSW_ADD_TMP_DEVICES == 1
|
#if OBSW_ADD_TMP_DEVICES == 1
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::GET_WRITE);
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::GET_WRITE);
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_RTD_DEVICES == 1
|
|
||||||
thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0.4,
|
|
||||||
DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0.4,
|
|
||||||
DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0.4,
|
|
||||||
DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0.4,
|
|
||||||
DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
#endif /* OBSW_ADD_RTD_DEVICES */
|
|
||||||
|
|
||||||
#if OBSW_ADD_TMP_DEVICES == 1
|
#if OBSW_ADD_TMP_DEVICES == 1
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.6, DeviceHandlerIF::SEND_READ);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::SEND_READ);
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.6, DeviceHandlerIF::SEND_READ);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::SEND_READ);
|
||||||
#endif
|
#endif
|
||||||
#if OBSW_ADD_RTD_DEVICES == 1
|
|
||||||
thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0.6,
|
|
||||||
DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0.6,
|
|
||||||
DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0.6,
|
|
||||||
DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0.6,
|
|
||||||
DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
#endif /* OBSW_ADD_RTD_DEVICES */
|
|
||||||
|
|
||||||
#if OBSW_ADD_TMP_DEVICES == 1
|
#if OBSW_ADD_TMP_DEVICES == 1
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.8, DeviceHandlerIF::GET_READ);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_1, length * 0.2, DeviceHandlerIF::GET_READ);
|
||||||
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.8, DeviceHandlerIF::GET_READ);
|
thisSequence->addSlot(objects::TMP1075_HANDLER_2, length * 0.2, DeviceHandlerIF::GET_READ);
|
||||||
#endif
|
|
||||||
#if OBSW_ADD_RTD_DEVICES == 1
|
|
||||||
thisSequence->addSlot(objects::RTD_0_IC3_PLOC_HEATSPREADER, length * 0.8,
|
|
||||||
DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_1_IC4_PLOC_MISSIONBOARD, length * 0.8,
|
|
||||||
DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_2_IC5_4K_CAMERA, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_3_IC6_DAC_HEATSPREADER, length * 0.8,
|
|
||||||
DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_4_IC7_STARTRACKER, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_5_IC8_RW1_MX_MY, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_6_IC9_DRO, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_7_IC10_SCEX, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_8_IC11_X8, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_9_IC12_HPA, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_10_IC13_PL_TX, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_11_IC14_MPA, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_12_IC15_ACU, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_13_IC16_PLPCDU_HEATSPREADER, length * 0.8,
|
|
||||||
DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_14_IC17_TCS_BOARD, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
thisSequence->addSlot(objects::RTD_15_IC18_IMTQ, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
#endif /* OBSW_ADD_RTD_DEVICES */
|
|
||||||
|
|
||||||
#if OBSW_ADD_RAD_SENSORS == 1
|
|
||||||
/* Radiation sensor */
|
|
||||||
thisSequence->addSlot(objects::RAD_SENSOR, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
|
||||||
thisSequence->addSlot(objects::RAD_SENSOR, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RAD_SENSOR, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
|
||||||
thisSequence->addSlot(objects::RAD_SENSOR, length * 0.6, DeviceHandlerIF::SEND_READ);
|
|
||||||
thisSequence->addSlot(objects::RAD_SENSOR, length * 0.8, DeviceHandlerIF::GET_READ);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if OBSW_ADD_SUN_SENSORS == 1
|
#if OBSW_ADD_SUN_SENSORS == 1
|
||||||
@ -482,6 +361,15 @@ ReturnValue_t pst::pstSpi(FixedTimeslotTaskIF *thisSequence) {
|
|||||||
}
|
}
|
||||||
#endif /* OBSW_ADD_SUN_SENSORS == 1 */
|
#endif /* OBSW_ADD_SUN_SENSORS == 1 */
|
||||||
|
|
||||||
|
#if OBSW_ADD_RAD_SENSORS == 1
|
||||||
|
/* Radiation sensor */
|
||||||
|
thisSequence->addSlot(objects::RAD_SENSOR, length * 0, DeviceHandlerIF::PERFORM_OPERATION);
|
||||||
|
thisSequence->addSlot(objects::RAD_SENSOR, length * 0.2, DeviceHandlerIF::SEND_WRITE);
|
||||||
|
thisSequence->addSlot(objects::RAD_SENSOR, length * 0.4, DeviceHandlerIF::GET_WRITE);
|
||||||
|
thisSequence->addSlot(objects::RAD_SENSOR, length * 0.6, DeviceHandlerIF::SEND_READ);
|
||||||
|
thisSequence->addSlot(objects::RAD_SENSOR, length * 0.8, DeviceHandlerIF::GET_READ);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1
|
#if OBSW_ADD_ACS_BOARD == 1 && OBSW_ADD_ACS_HANDLERS == 1
|
||||||
bool enableAside = true;
|
bool enableAside = true;
|
||||||
bool enableBside = true;
|
bool enableBside = true;
|
||||||
|
@ -10,6 +10,7 @@ target_sources(
|
|||||||
ACUHandler.cpp
|
ACUHandler.cpp
|
||||||
SyrlinksHkHandler.cpp
|
SyrlinksHkHandler.cpp
|
||||||
Max31865PT1000Handler.cpp
|
Max31865PT1000Handler.cpp
|
||||||
|
Max31865EiveHandler.cpp
|
||||||
IMTQHandler.cpp
|
IMTQHandler.cpp
|
||||||
HeaterHandler.cpp
|
HeaterHandler.cpp
|
||||||
RadiationSensorHandler.cpp
|
RadiationSensorHandler.cpp
|
||||||
|
@ -424,8 +424,8 @@ ReturnValue_t GyroADIS1650XHandler::spiSendCallback(SpiComIF *comIf, SpiCookie *
|
|||||||
GpioIF *gpioIF = comIf->getGpioInterface();
|
GpioIF *gpioIF = comIf->getGpioInterface();
|
||||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
uint32_t timeoutMs = 0;
|
uint32_t timeoutMs = 0;
|
||||||
cookie->getMutexParams(timeoutType, timeoutMs);
|
|
||||||
MutexIF *mutex = comIf->getCsMutex();
|
MutexIF *mutex = comIf->getCsMutex();
|
||||||
|
cookie->getMutexParams(timeoutType, timeoutMs);
|
||||||
if (mutex == nullptr or gpioIF == nullptr) {
|
if (mutex == nullptr or gpioIF == nullptr) {
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
sif::warning << "GyroADIS16507Handler::spiSendCallback: "
|
sif::warning << "GyroADIS16507Handler::spiSendCallback: "
|
||||||
|
180
mission/devices/Max31865EiveHandler.cpp
Normal file
180
mission/devices/Max31865EiveHandler.cpp
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
#include "Max31865EiveHandler.h"
|
||||||
|
|
||||||
|
Max31865EiveHandler::Max31865EiveHandler(object_id_t objectId, object_id_t comIF,
|
||||||
|
CookieIF* comCookie)
|
||||||
|
: DeviceHandlerBase(objectId, comIF, comCookie, nullptr),
|
||||||
|
sensorDataset(this, EiveMax31855::RtdCommands::EXCHANGE_SET_ID),
|
||||||
|
debugDivider(5) {
|
||||||
|
structLen = exchangeStruct.getSerializedSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Max31865EiveHandler::doStartUp() {
|
||||||
|
updatePeriodicReply(true, EiveMax31855::RtdCommands::EXCHANGE_SET_ID);
|
||||||
|
if (state == InternalState::NONE or state == InternalState::INACTIVE) {
|
||||||
|
if (instantNormal) {
|
||||||
|
state = InternalState::ACTIVE;
|
||||||
|
} else {
|
||||||
|
state = InternalState::ON;
|
||||||
|
}
|
||||||
|
transitionOk = false;
|
||||||
|
}
|
||||||
|
if ((state == InternalState::ON or state == InternalState::ACTIVE) and transitionOk) {
|
||||||
|
if (instantNormal) {
|
||||||
|
setMode(MODE_NORMAL);
|
||||||
|
} else {
|
||||||
|
setMode(MODE_ON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Max31865EiveHandler::doShutDown() {
|
||||||
|
updatePeriodicReply(false, EiveMax31855::RtdCommands::EXCHANGE_SET_ID);
|
||||||
|
if (state == InternalState::NONE or state == InternalState::ACTIVE or
|
||||||
|
state == InternalState::ON) {
|
||||||
|
state = InternalState::INACTIVE;
|
||||||
|
transitionOk = false;
|
||||||
|
} else {
|
||||||
|
transitionOk = true;
|
||||||
|
}
|
||||||
|
if (state == InternalState::INACTIVE and transitionOk) {
|
||||||
|
setMode(_MODE_POWER_DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865EiveHandler::buildNormalDeviceCommand(DeviceCommandId_t* id) {
|
||||||
|
//*id = EiveMax31855::RtdCommands::EXCHANGE_SET_ID;
|
||||||
|
return NOTHING_TO_SEND;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865EiveHandler::buildTransitionDeviceCommand(DeviceCommandId_t* id) {
|
||||||
|
ReturnValue_t result = NOTHING_TO_SEND;
|
||||||
|
if (state == InternalState::ON) {
|
||||||
|
*id = EiveMax31855::RtdCommands::ON;
|
||||||
|
result = buildCommandFromCommand(*id, nullptr, 0);
|
||||||
|
}
|
||||||
|
if (state == InternalState::ACTIVE) {
|
||||||
|
*id = EiveMax31855::RtdCommands::ACTIVE;
|
||||||
|
result = buildCommandFromCommand(*id, nullptr, 0);
|
||||||
|
}
|
||||||
|
if (state == InternalState::INACTIVE) {
|
||||||
|
*id = EiveMax31855::RtdCommands::OFF;
|
||||||
|
result = buildCommandFromCommand(*id, nullptr, 0);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865EiveHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||||
|
const uint8_t* commandData,
|
||||||
|
size_t commandDataLen) {
|
||||||
|
auto cmdTyped = static_cast<EiveMax31855::RtdCommands>(deviceCommand);
|
||||||
|
switch (cmdTyped) {
|
||||||
|
case (EiveMax31855::RtdCommands::ON):
|
||||||
|
case (EiveMax31855::RtdCommands::ACTIVE):
|
||||||
|
case (EiveMax31855::RtdCommands::OFF): {
|
||||||
|
simpleCommand(cmdTyped);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (EiveMax31855::RtdCommands::LOW_THRESHOLD):
|
||||||
|
case (EiveMax31855::RtdCommands::HIGH_TRESHOLD): {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case (EiveMax31855::RtdCommands::CFG): {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return NOTHING_TO_SEND;
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Max31865EiveHandler::setInstantNormal(bool instantNormal) {
|
||||||
|
this->instantNormal = instantNormal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Max31865EiveHandler::setDebugMode(bool enable, uint32_t divider) {
|
||||||
|
this->debugMode = enable;
|
||||||
|
debugDivider.setDivider(divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Max31865EiveHandler::simpleCommand(EiveMax31855::RtdCommands cmd) {
|
||||||
|
cmdBuf[0] = static_cast<uint8_t>(cmd);
|
||||||
|
rawPacket = cmdBuf.data();
|
||||||
|
rawPacketLen = 1;
|
||||||
|
}
|
||||||
|
void Max31865EiveHandler::doTransition(Mode_t modeFrom, Submode_t subModeFrom) {
|
||||||
|
if (mode == _MODE_TO_NORMAL) {
|
||||||
|
if (state != InternalState::ACTIVE) {
|
||||||
|
state = InternalState::ACTIVE;
|
||||||
|
transitionOk = false;
|
||||||
|
} else if (transitionOk) {
|
||||||
|
setMode(MODE_NORMAL);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DeviceHandlerBase::doTransition(modeFrom, subModeFrom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Max31865EiveHandler::fillCommandAndReplyMap() {
|
||||||
|
insertInCommandMap(EiveMax31855::RtdCommands::ON);
|
||||||
|
insertInCommandMap(EiveMax31855::RtdCommands::ACTIVE);
|
||||||
|
insertInCommandMap(EiveMax31855::RtdCommands::OFF);
|
||||||
|
insertInReplyMap(EiveMax31855::RtdCommands::EXCHANGE_SET_ID, 200, &sensorDataset, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865EiveHandler::scanForReply(const uint8_t* start, size_t remainingSize,
|
||||||
|
DeviceCommandId_t* foundId, size_t* foundLen) {
|
||||||
|
if (remainingSize != structLen) {
|
||||||
|
sif::error << "Invalid reply from RTD reader detected, reply size " << remainingSize
|
||||||
|
<< " not equal to exchange struct size " << structLen << std::endl;
|
||||||
|
return DeviceHandlerIF::INVALID_DATA;
|
||||||
|
}
|
||||||
|
*foundId = EiveMax31855::RtdCommands::EXCHANGE_SET_ID;
|
||||||
|
*foundLen = remainingSize;
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865EiveHandler::interpretDeviceReply(DeviceCommandId_t id,
|
||||||
|
const uint8_t* packet) {
|
||||||
|
size_t deserTmp = structLen;
|
||||||
|
auto result = exchangeStruct.deSerialize(&packet, &deserTmp, SerializeIF::Endianness::MACHINE);
|
||||||
|
if (result != RETURN_OK) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (mode == _MODE_TO_NORMAL and exchangeStruct.active and state == InternalState::ACTIVE) {
|
||||||
|
transitionOk = true;
|
||||||
|
}
|
||||||
|
if (mode == _MODE_START_UP and exchangeStruct.configured and state == InternalState::ON) {
|
||||||
|
transitionOk = true;
|
||||||
|
}
|
||||||
|
// Calculate resistance
|
||||||
|
float rtdValue = exchangeStruct.adcCode * EiveMax31855::RTD_RREF_PT1000 / INT16_MAX;
|
||||||
|
// calculate approximation
|
||||||
|
float approxTemp = exchangeStruct.adcCode / 32.0 - 256.0;
|
||||||
|
|
||||||
|
if (debugMode) {
|
||||||
|
if (debugDivider.checkAndIncrement()) {
|
||||||
|
sif::info << "Max31865: " << std::setw(20) << std::left << locString << std::right
|
||||||
|
<< " | R[Ohm] " << rtdValue << " Ohms | Approx T[C]: " << approxTemp << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Max31865EiveHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) { return 2000; }
|
||||||
|
|
||||||
|
ReturnValue_t Max31865EiveHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
|
LocalDataPoolManager& poolManager) {
|
||||||
|
using namespace MAX31865;
|
||||||
|
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::RTD_VALUE), new PoolEntry<float>({0}));
|
||||||
|
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::TEMPERATURE_C), new PoolEntry<float>({0}));
|
||||||
|
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::FAULT_BYTE), new PoolEntry<uint8_t>({0}));
|
||||||
|
poolManager.subscribeForPeriodicPacket(sensorDataset.getSid(), false, 30.0, false);
|
||||||
|
return RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Max31865EiveHandler::setDeviceInfo(uint8_t idx_, std::string location_) {
|
||||||
|
idx = idx_;
|
||||||
|
locString = std::move(location_);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t Max31865EiveHandler::initialize() { return DeviceHandlerBase::initialize(); }
|
47
mission/devices/Max31865EiveHandler.h
Normal file
47
mission/devices/Max31865EiveHandler.h
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef MISSION_DEVICES_MAX31865EIVEHANDLER_H_
|
||||||
|
#define MISSION_DEVICES_MAX31865EIVEHANDLER_H_
|
||||||
|
|
||||||
|
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||||
|
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||||
|
|
||||||
|
#include "devicedefinitions/Max31865Definitions.h"
|
||||||
|
|
||||||
|
class Max31865EiveHandler : public DeviceHandlerBase {
|
||||||
|
public:
|
||||||
|
Max31865EiveHandler(object_id_t objectId, object_id_t comIF, CookieIF* comCookie);
|
||||||
|
void setInstantNormal(bool instantNormal);
|
||||||
|
void setDebugMode(bool enable, uint32_t divider);
|
||||||
|
void setDeviceInfo(uint8_t idx, std::string location);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void doStartUp() override;
|
||||||
|
void doShutDown() override;
|
||||||
|
void doTransition(Mode_t modeFrom, Submode_t subModeFrom) override;
|
||||||
|
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t* id) override;
|
||||||
|
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t* id) override;
|
||||||
|
void fillCommandAndReplyMap() override;
|
||||||
|
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t* commandData,
|
||||||
|
size_t commandDataLen) override;
|
||||||
|
ReturnValue_t scanForReply(const uint8_t* start, size_t remainingSize, DeviceCommandId_t* foundId,
|
||||||
|
size_t* foundLen) override;
|
||||||
|
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t* packet) override;
|
||||||
|
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||||
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
|
||||||
|
LocalDataPoolManager& poolManager) override;
|
||||||
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
|
void simpleCommand(EiveMax31855::RtdCommands cmd);
|
||||||
|
std::array<uint8_t, 12> cmdBuf = {};
|
||||||
|
uint8_t idx = 0;
|
||||||
|
std::string locString = "Unknown";
|
||||||
|
EiveMax31855::ReadOutStruct exchangeStruct;
|
||||||
|
bool debugMode = false;
|
||||||
|
size_t structLen = 0;
|
||||||
|
bool instantNormal = false;
|
||||||
|
MAX31865::Max31865Set sensorDataset;
|
||||||
|
PeriodicOperationDivider debugDivider;
|
||||||
|
enum class InternalState { NONE, ON, ACTIVE, INACTIVE } state = InternalState::NONE;
|
||||||
|
bool transitionOk = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* MISSION_DEVICES_MAX31865EIVEHANDLER_H_ */
|
@ -8,7 +8,7 @@
|
|||||||
Max31865PT1000Handler::Max31865PT1000Handler(object_id_t objectId, object_id_t comIF,
|
Max31865PT1000Handler::Max31865PT1000Handler(object_id_t objectId, object_id_t comIF,
|
||||||
CookieIF *comCookie)
|
CookieIF *comCookie)
|
||||||
: DeviceHandlerBase(objectId, comIF, comCookie),
|
: DeviceHandlerBase(objectId, comIF, comCookie),
|
||||||
sensorDataset(this),
|
sensorDataset(this, MAX31865::REQUEST_RTD),
|
||||||
sensorDatasetSid(sensorDataset.getSid()) {
|
sensorDatasetSid(sensorDataset.getSid()) {
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
debugDivider = new PeriodicOperationDivider(10);
|
debugDivider = new PeriodicOperationDivider(10);
|
||||||
@ -93,13 +93,13 @@ void Max31865PT1000Handler::doShutDown() {
|
|||||||
|
|
||||||
ReturnValue_t Max31865PT1000Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
ReturnValue_t Max31865PT1000Handler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||||
if (internalState == InternalState::RUNNING) {
|
if (internalState == InternalState::RUNNING) {
|
||||||
*id = Max31865Definitions::REQUEST_RTD;
|
*id = MAX31865::REQUEST_RTD;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
} else if (internalState == InternalState::REQUEST_FAULT_BYTE) {
|
} else if (internalState == InternalState::REQUEST_FAULT_BYTE) {
|
||||||
*id = Max31865Definitions::REQUEST_FAULT_BYTE;
|
*id = MAX31865::REQUEST_FAULT_BYTE;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
} else if (internalState == InternalState::CLEAR_FAULT_BYTE) {
|
} else if (internalState == InternalState::CLEAR_FAULT_BYTE) {
|
||||||
*id = Max31865Definitions::CLEAR_FAULT_BYTE;
|
*id = MAX31865::CLEAR_FAULT_BYTE;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
} else {
|
} else {
|
||||||
return DeviceHandlerBase::NOTHING_TO_SEND;
|
return DeviceHandlerBase::NOTHING_TO_SEND;
|
||||||
@ -113,32 +113,32 @@ ReturnValue_t Max31865PT1000Handler::buildTransitionDeviceCommand(DeviceCommandI
|
|||||||
case (InternalState::RUNNING):
|
case (InternalState::RUNNING):
|
||||||
return DeviceHandlerBase::NOTHING_TO_SEND;
|
return DeviceHandlerBase::NOTHING_TO_SEND;
|
||||||
case (InternalState::CONFIGURE): {
|
case (InternalState::CONFIGURE): {
|
||||||
*id = Max31865Definitions::CONFIG_CMD;
|
*id = MAX31865::CONFIG_CMD;
|
||||||
uint8_t config[1] = {DEFAULT_CONFIG};
|
uint8_t config[1] = {DEFAULT_CONFIG};
|
||||||
return buildCommandFromCommand(*id, config, 1);
|
return buildCommandFromCommand(*id, config, 1);
|
||||||
}
|
}
|
||||||
case (InternalState::REQUEST_CONFIG): {
|
case (InternalState::REQUEST_CONFIG): {
|
||||||
*id = Max31865Definitions::REQUEST_CONFIG;
|
*id = MAX31865::REQUEST_CONFIG;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
case (InternalState::CONFIG_HIGH_THRESHOLD): {
|
case (InternalState::CONFIG_HIGH_THRESHOLD): {
|
||||||
*id = Max31865Definitions::WRITE_HIGH_THRESHOLD;
|
*id = MAX31865::WRITE_HIGH_THRESHOLD;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
case (InternalState::REQUEST_HIGH_THRESHOLD): {
|
case (InternalState::REQUEST_HIGH_THRESHOLD): {
|
||||||
*id = Max31865Definitions::REQUEST_HIGH_THRESHOLD;
|
*id = MAX31865::REQUEST_HIGH_THRESHOLD;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
case (InternalState::CONFIG_LOW_THRESHOLD): {
|
case (InternalState::CONFIG_LOW_THRESHOLD): {
|
||||||
*id = Max31865Definitions::WRITE_LOW_THRESHOLD;
|
*id = MAX31865::WRITE_LOW_THRESHOLD;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
case (InternalState::REQUEST_LOW_THRESHOLD): {
|
case (InternalState::REQUEST_LOW_THRESHOLD): {
|
||||||
*id = Max31865Definitions::REQUEST_LOW_THRESHOLD;
|
*id = MAX31865::REQUEST_LOW_THRESHOLD;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
case (InternalState::CLEAR_FAULT_BYTE): {
|
case (InternalState::CLEAR_FAULT_BYTE): {
|
||||||
*id = Max31865Definitions::CLEAR_FAULT_BYTE;
|
*id = MAX31865::CLEAR_FAULT_BYTE;
|
||||||
return buildCommandFromCommand(*id, nullptr, 0);
|
return buildCommandFromCommand(*id, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,10 +156,11 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d
|
|||||||
const uint8_t *commandData,
|
const uint8_t *commandData,
|
||||||
size_t commandDataLen) {
|
size_t commandDataLen) {
|
||||||
switch (deviceCommand) {
|
switch (deviceCommand) {
|
||||||
case (Max31865Definitions::CONFIG_CMD): {
|
case (MAX31865::CONFIG_CMD): {
|
||||||
commandBuffer[0] = static_cast<uint8_t>(Max31865Definitions::CONFIG_CMD);
|
commandBuffer[0] = static_cast<uint8_t>(MAX31865::CONFIG_CMD);
|
||||||
if (commandDataLen == 1) {
|
if (commandDataLen == 1) {
|
||||||
commandBuffer[1] = commandData[0];
|
commandBuffer[1] = commandData[0];
|
||||||
|
currentCfg = commandData[0];
|
||||||
DeviceHandlerBase::rawPacketLen = 2;
|
DeviceHandlerBase::rawPacketLen = 2;
|
||||||
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
@ -167,54 +168,54 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d
|
|||||||
return DeviceHandlerIF::NO_COMMAND_DATA;
|
return DeviceHandlerIF::NO_COMMAND_DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::CLEAR_FAULT_BYTE): {
|
case (MAX31865::CLEAR_FAULT_BYTE): {
|
||||||
commandBuffer[0] = static_cast<uint8_t>(Max31865Definitions::CONFIG_CMD);
|
commandBuffer[0] = static_cast<uint8_t>(MAX31865::CONFIG_CMD);
|
||||||
commandBuffer[1] = Max31865Definitions::CLEAR_FAULT_BIT_VAL;
|
commandBuffer[1] = currentCfg | MAX31865::CLEAR_FAULT_BIT_VAL;
|
||||||
DeviceHandlerBase::rawPacketLen = 2;
|
DeviceHandlerBase::rawPacketLen = 2;
|
||||||
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::REQUEST_CONFIG): {
|
case (MAX31865::REQUEST_CONFIG): {
|
||||||
commandBuffer[0] = static_cast<uint8_t>(Max31865Definitions::REQUEST_CONFIG);
|
commandBuffer[0] = static_cast<uint8_t>(MAX31865::REQUEST_CONFIG);
|
||||||
commandBuffer[1] = 0x00; // dummy byte
|
commandBuffer[1] = 0x00; // dummy byte
|
||||||
DeviceHandlerBase::rawPacketLen = 2;
|
DeviceHandlerBase::rawPacketLen = 2;
|
||||||
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::WRITE_HIGH_THRESHOLD): {
|
case (MAX31865::WRITE_HIGH_THRESHOLD): {
|
||||||
commandBuffer[0] = static_cast<uint8_t>(Max31865Definitions::WRITE_HIGH_THRESHOLD);
|
commandBuffer[0] = static_cast<uint8_t>(MAX31865::WRITE_HIGH_THRESHOLD);
|
||||||
commandBuffer[1] = static_cast<uint8_t>(HIGH_THRESHOLD >> 8);
|
commandBuffer[1] = static_cast<uint8_t>(HIGH_THRESHOLD >> 8);
|
||||||
commandBuffer[2] = static_cast<uint8_t>(HIGH_THRESHOLD & 0xFF);
|
commandBuffer[2] = static_cast<uint8_t>(HIGH_THRESHOLD & 0xFF);
|
||||||
DeviceHandlerBase::rawPacketLen = 3;
|
DeviceHandlerBase::rawPacketLen = 3;
|
||||||
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::REQUEST_HIGH_THRESHOLD): {
|
case (MAX31865::REQUEST_HIGH_THRESHOLD): {
|
||||||
commandBuffer[0] = static_cast<uint8_t>(Max31865Definitions::REQUEST_HIGH_THRESHOLD);
|
commandBuffer[0] = static_cast<uint8_t>(MAX31865::REQUEST_HIGH_THRESHOLD);
|
||||||
commandBuffer[1] = 0x00; // dummy byte
|
commandBuffer[1] = 0x00; // dummy byte
|
||||||
commandBuffer[2] = 0x00; // dummy byte
|
commandBuffer[2] = 0x00; // dummy byte
|
||||||
DeviceHandlerBase::rawPacketLen = 3;
|
DeviceHandlerBase::rawPacketLen = 3;
|
||||||
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::WRITE_LOW_THRESHOLD): {
|
case (MAX31865::WRITE_LOW_THRESHOLD): {
|
||||||
commandBuffer[0] = static_cast<uint8_t>(Max31865Definitions::WRITE_LOW_THRESHOLD);
|
commandBuffer[0] = static_cast<uint8_t>(MAX31865::WRITE_LOW_THRESHOLD);
|
||||||
commandBuffer[1] = static_cast<uint8_t>(LOW_THRESHOLD >> 8);
|
commandBuffer[1] = static_cast<uint8_t>(LOW_THRESHOLD >> 8);
|
||||||
commandBuffer[2] = static_cast<uint8_t>(LOW_THRESHOLD & 0xFF);
|
commandBuffer[2] = static_cast<uint8_t>(LOW_THRESHOLD & 0xFF);
|
||||||
DeviceHandlerBase::rawPacketLen = 3;
|
DeviceHandlerBase::rawPacketLen = 3;
|
||||||
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::REQUEST_LOW_THRESHOLD): {
|
case (MAX31865::REQUEST_LOW_THRESHOLD): {
|
||||||
commandBuffer[0] = static_cast<uint8_t>(Max31865Definitions::REQUEST_LOW_THRESHOLD);
|
commandBuffer[0] = static_cast<uint8_t>(MAX31865::REQUEST_LOW_THRESHOLD);
|
||||||
commandBuffer[1] = 0x00; // dummy byte
|
commandBuffer[1] = 0x00; // dummy byte
|
||||||
commandBuffer[2] = 0x00; // dummy byte
|
commandBuffer[2] = 0x00; // dummy byte
|
||||||
DeviceHandlerBase::rawPacketLen = 3;
|
DeviceHandlerBase::rawPacketLen = 3;
|
||||||
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::REQUEST_RTD): {
|
case (MAX31865::REQUEST_RTD): {
|
||||||
commandBuffer[0] = static_cast<uint8_t>(Max31865Definitions::REQUEST_RTD);
|
commandBuffer[0] = static_cast<uint8_t>(MAX31865::REQUEST_RTD);
|
||||||
// two dummy bytes
|
// two dummy bytes
|
||||||
commandBuffer[1] = 0x00;
|
commandBuffer[1] = 0x00;
|
||||||
commandBuffer[2] = 0x00;
|
commandBuffer[2] = 0x00;
|
||||||
@ -222,8 +223,8 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d
|
|||||||
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::REQUEST_FAULT_BYTE): {
|
case (MAX31865::REQUEST_FAULT_BYTE): {
|
||||||
commandBuffer[0] = static_cast<uint8_t>(Max31865Definitions::REQUEST_FAULT_BYTE);
|
commandBuffer[0] = static_cast<uint8_t>(MAX31865::REQUEST_FAULT_BYTE);
|
||||||
commandBuffer[1] = 0x00;
|
commandBuffer[1] = 0x00;
|
||||||
DeviceHandlerBase::rawPacketLen = 2;
|
DeviceHandlerBase::rawPacketLen = 2;
|
||||||
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
DeviceHandlerBase::rawPacket = commandBuffer.data();
|
||||||
@ -236,15 +237,15 @@ ReturnValue_t Max31865PT1000Handler::buildCommandFromCommand(DeviceCommandId_t d
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Max31865PT1000Handler::fillCommandAndReplyMap() {
|
void Max31865PT1000Handler::fillCommandAndReplyMap() {
|
||||||
insertInCommandAndReplyMap(Max31865Definitions::CONFIG_CMD, 3);
|
insertInCommandAndReplyMap(MAX31865::CONFIG_CMD, 3);
|
||||||
insertInCommandAndReplyMap(Max31865Definitions::REQUEST_CONFIG, 3);
|
insertInCommandAndReplyMap(MAX31865::REQUEST_CONFIG, 3);
|
||||||
insertInCommandAndReplyMap(Max31865Definitions::WRITE_LOW_THRESHOLD, 3);
|
insertInCommandAndReplyMap(MAX31865::WRITE_LOW_THRESHOLD, 3);
|
||||||
insertInCommandAndReplyMap(Max31865Definitions::REQUEST_LOW_THRESHOLD, 3);
|
insertInCommandAndReplyMap(MAX31865::REQUEST_LOW_THRESHOLD, 3);
|
||||||
insertInCommandAndReplyMap(Max31865Definitions::WRITE_HIGH_THRESHOLD, 3);
|
insertInCommandAndReplyMap(MAX31865::WRITE_HIGH_THRESHOLD, 3);
|
||||||
insertInCommandAndReplyMap(Max31865Definitions::REQUEST_HIGH_THRESHOLD, 3);
|
insertInCommandAndReplyMap(MAX31865::REQUEST_HIGH_THRESHOLD, 3);
|
||||||
insertInCommandAndReplyMap(Max31865Definitions::REQUEST_RTD, 3, &sensorDataset);
|
insertInCommandAndReplyMap(MAX31865::REQUEST_RTD, 3, &sensorDataset);
|
||||||
insertInCommandAndReplyMap(Max31865Definitions::REQUEST_FAULT_BYTE, 3);
|
insertInCommandAndReplyMap(MAX31865::REQUEST_FAULT_BYTE, 3);
|
||||||
insertInCommandAndReplyMap(Max31865Definitions::CLEAR_FAULT_BYTE, 3);
|
insertInCommandAndReplyMap(MAX31865::CLEAR_FAULT_BYTE, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t remainingSize,
|
ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t remainingSize,
|
||||||
@ -253,7 +254,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r
|
|||||||
size_t configReplySize = 2;
|
size_t configReplySize = 2;
|
||||||
|
|
||||||
if (remainingSize == rtdReplySize and internalState == InternalState::RUNNING) {
|
if (remainingSize == rtdReplySize and internalState == InternalState::RUNNING) {
|
||||||
*foundId = Max31865Definitions::REQUEST_RTD;
|
*foundId = MAX31865::REQUEST_RTD;
|
||||||
*foundLen = rtdReplySize;
|
*foundLen = rtdReplySize;
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -262,24 +263,24 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r
|
|||||||
switch (internalState) {
|
switch (internalState) {
|
||||||
case (InternalState::CONFIG_HIGH_THRESHOLD): {
|
case (InternalState::CONFIG_HIGH_THRESHOLD): {
|
||||||
*foundLen = 3;
|
*foundLen = 3;
|
||||||
*foundId = Max31865Definitions::WRITE_HIGH_THRESHOLD;
|
*foundId = MAX31865::WRITE_HIGH_THRESHOLD;
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
case (InternalState::REQUEST_HIGH_THRESHOLD): {
|
case (InternalState::REQUEST_HIGH_THRESHOLD): {
|
||||||
*foundLen = 3;
|
*foundLen = 3;
|
||||||
*foundId = Max31865Definitions::REQUEST_HIGH_THRESHOLD;
|
*foundId = MAX31865::REQUEST_HIGH_THRESHOLD;
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
case (InternalState::CONFIG_LOW_THRESHOLD): {
|
case (InternalState::CONFIG_LOW_THRESHOLD): {
|
||||||
*foundLen = 3;
|
*foundLen = 3;
|
||||||
*foundId = Max31865Definitions::WRITE_LOW_THRESHOLD;
|
*foundId = MAX31865::WRITE_LOW_THRESHOLD;
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
case (InternalState::REQUEST_LOW_THRESHOLD): {
|
case (InternalState::REQUEST_LOW_THRESHOLD): {
|
||||||
*foundLen = 3;
|
*foundLen = 3;
|
||||||
*foundId = Max31865Definitions::REQUEST_LOW_THRESHOLD;
|
*foundId = MAX31865::REQUEST_LOW_THRESHOLD;
|
||||||
return RETURN_OK;
|
return RETURN_OK;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -293,13 +294,13 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r
|
|||||||
if (internalState == InternalState::CONFIGURE) {
|
if (internalState == InternalState::CONFIGURE) {
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
*foundLen = configReplySize;
|
*foundLen = configReplySize;
|
||||||
*foundId = Max31865Definitions::CONFIG_CMD;
|
*foundId = MAX31865::CONFIG_CMD;
|
||||||
} else if (internalState == InternalState::REQUEST_FAULT_BYTE) {
|
} else if (internalState == InternalState::REQUEST_FAULT_BYTE) {
|
||||||
*foundId = Max31865Definitions::REQUEST_FAULT_BYTE;
|
*foundId = MAX31865::REQUEST_FAULT_BYTE;
|
||||||
*foundLen = 2;
|
*foundLen = 2;
|
||||||
internalState = InternalState::RUNNING;
|
internalState = InternalState::RUNNING;
|
||||||
} else if (internalState == InternalState::CLEAR_FAULT_BYTE) {
|
} else if (internalState == InternalState::CLEAR_FAULT_BYTE) {
|
||||||
*foundId = Max31865Definitions::CLEAR_FAULT_BYTE;
|
*foundId = MAX31865::CLEAR_FAULT_BYTE;
|
||||||
*foundLen = 2;
|
*foundLen = 2;
|
||||||
if (mode == _MODE_START_UP) {
|
if (mode == _MODE_START_UP) {
|
||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
@ -307,7 +308,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r
|
|||||||
internalState = InternalState::RUNNING;
|
internalState = InternalState::RUNNING;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*foundId = Max31865Definitions::REQUEST_CONFIG;
|
*foundId = MAX31865::REQUEST_CONFIG;
|
||||||
*foundLen = configReplySize;
|
*foundLen = configReplySize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,7 +319,7 @@ ReturnValue_t Max31865PT1000Handler::scanForReply(const uint8_t *start, size_t r
|
|||||||
ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
|
ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
|
||||||
const uint8_t *packet) {
|
const uint8_t *packet) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case (Max31865Definitions::REQUEST_CONFIG): {
|
case (MAX31865::REQUEST_CONFIG): {
|
||||||
if (packet[1] != DEFAULT_CONFIG) {
|
if (packet[1] != DEFAULT_CONFIG) {
|
||||||
if (warningSwitch) {
|
if (warningSwitch) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@ -342,7 +343,7 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::REQUEST_LOW_THRESHOLD): {
|
case (MAX31865::REQUEST_LOW_THRESHOLD): {
|
||||||
uint16_t readLowThreshold = packet[1] << 8 | packet[2];
|
uint16_t readLowThreshold = packet[1] << 8 | packet[2];
|
||||||
if (readLowThreshold != LOW_THRESHOLD) {
|
if (readLowThreshold != LOW_THRESHOLD) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
@ -360,8 +361,8 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::REQUEST_HIGH_THRESHOLD): {
|
case (MAX31865::REQUEST_HIGH_THRESHOLD): {
|
||||||
uint16_t readHighThreshold = packet[1] << 8 | packet[2];
|
uint16_t readHighThreshold = (packet[1] << 8) | packet[2];
|
||||||
if (readHighThreshold != HIGH_THRESHOLD) {
|
if (readHighThreshold != HIGH_THRESHOLD) {
|
||||||
#if FSFW_VERBOSE_LEVEL >= 1
|
#if FSFW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@ -378,13 +379,13 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
commandExecuted = true;
|
commandExecuted = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::REQUEST_RTD): {
|
case (MAX31865::REQUEST_RTD): {
|
||||||
// first bit of LSB reply byte is the fault bit
|
// first bit of LSB reply byte is the fault bit
|
||||||
uint8_t faultBit = packet[2] & 0b0000'0001;
|
bool faultBit = packet[2] & 0b0000'0001;
|
||||||
if (resetFaultBit) {
|
if (resetFaultBit) {
|
||||||
internalState = InternalState::CLEAR_FAULT_BYTE;
|
internalState = InternalState::CLEAR_FAULT_BYTE;
|
||||||
resetFaultBit = false;
|
resetFaultBit = false;
|
||||||
} else if (faultBit == 1) {
|
} else if (shouldFaultStatusBeRequested(faultBit)) {
|
||||||
// Maybe we should attempt to restart it?
|
// Maybe we should attempt to restart it?
|
||||||
internalState = InternalState::REQUEST_FAULT_BYTE;
|
internalState = InternalState::REQUEST_FAULT_BYTE;
|
||||||
resetFaultBit = true;
|
resetFaultBit = true;
|
||||||
@ -393,9 +394,8 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
// RTD value consists of last seven bits of the LSB reply byte and
|
// RTD value consists of last seven bits of the LSB reply byte and
|
||||||
// the MSB reply byte
|
// the MSB reply byte
|
||||||
uint16_t adcCode = ((packet[1] << 8) | packet[2]) >> 1;
|
uint16_t adcCode = ((packet[1] << 8) | packet[2]) >> 1;
|
||||||
// do something with rtd value, will propably be stored in
|
// Calculate resistance
|
||||||
// dataset.
|
float rtdValue = adcCode * EiveMax31855::RTD_RREF_PT1000 / INT16_MAX;
|
||||||
float rtdValue = adcCode * RTD_RREF_PT1000 / INT16_MAX;
|
|
||||||
// calculate approximation
|
// calculate approximation
|
||||||
float approxTemp = adcCode / 32.0 - 256.0;
|
float approxTemp = adcCode / 32.0 - 256.0;
|
||||||
|
|
||||||
@ -403,9 +403,9 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
if (debugDivider->checkAndIncrement()) {
|
if (debugDivider->checkAndIncrement()) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::info << "Max31865: ObjID " << std::hex << this->getObjectId() << " | RTD "
|
sif::info << "Max31865: " << std::setw(24) << std::left << locString << std::right
|
||||||
<< std::dec << static_cast<int>(deviceIdx) << ": R[Ohm] " << rtdValue
|
<< " | R[Ohm] " << rtdValue << " Ohms | Approx T[C]: " << approxTemp
|
||||||
<< " Ohms | Approx T[C]: " << approxTemp << std::endl;
|
<< std::endl;
|
||||||
#else
|
#else
|
||||||
sif::printInfo("Max31685: Measured resistance is %f Ohms\n", rtdValue);
|
sif::printInfo("Max31685: Measured resistance is %f Ohms\n", rtdValue);
|
||||||
sif::printInfo("Approximated temperature is %f C\n", approxTemp);
|
sif::printInfo("Approximated temperature is %f C\n", approxTemp);
|
||||||
@ -438,58 +438,57 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
sensorDataset.temperatureCelcius = approxTemp;
|
sensorDataset.temperatureCelcius = approxTemp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case (Max31865Definitions::REQUEST_FAULT_BYTE): {
|
case (MAX31865::REQUEST_FAULT_BYTE): {
|
||||||
faultByte = packet[1];
|
currentFaultStatus = packet[1];
|
||||||
|
bool faultStatusChanged = (currentFaultStatus != lastFaultStatus);
|
||||||
|
// Spam protection
|
||||||
|
if (faultStatusChanged or
|
||||||
|
((currentFaultStatus == lastFaultStatus) and (sameFaultStatusCounter < 3))) {
|
||||||
|
// TODO: Think about triggering an event here
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex
|
sif::warning << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex
|
||||||
<< this->getObjectId()
|
<< this->getObjectId() << ": Fault byte is: 0b"
|
||||||
<< ": Fault byte"
|
<< std::bitset<8>(currentFaultStatus) << std::endl;
|
||||||
" is: 0b"
|
|
||||||
<< std::bitset<8>(faultByte) << std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printWarning(
|
sif::printWarning(
|
||||||
"Max31865PT1000Handler::interpretDeviceReply: Fault byte"
|
"Max31865PT1000Handler::interpretDeviceReply: Fault byte"
|
||||||
" is: 0b" BYTE_TO_BINARY_PATTERN "\n",
|
" is: 0b" BYTE_TO_BINARY_PATTERN "\n",
|
||||||
BYTE_TO_BINARY(faultByte));
|
BYTE_TO_BINARY(faultByte));
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
ReturnValue_t result = sensorDataset.read();
|
if (faultStatusChanged) {
|
||||||
|
sameFaultStatusCounter = 0;
|
||||||
|
} else {
|
||||||
|
sameFaultStatusCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (faultStatusChanged) {
|
||||||
|
lastFaultStatus = currentFaultStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
PoolReadGuard pg(&sensorDataset);
|
||||||
|
auto result = pg.getReadResult();
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
// Configuration error
|
// Configuration error
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::debug << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex
|
sif::warning << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex
|
||||||
<< this->getObjectId()
|
<< this->getObjectId() << ": Error reading dataset" << std::endl;
|
||||||
<< ":"
|
|
||||||
"Error reading dataset!"
|
|
||||||
<< std::endl;
|
|
||||||
#else
|
#else
|
||||||
sif::printDebug(
|
sif::printWarning("Max31865PT1000Handler::interpretDeviceReply: Error reading dataset\n");
|
||||||
"Max31865PT1000Handler::interpretDeviceReply: "
|
|
||||||
"Error reading dataset!\n");
|
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if (faultStatusChanged) {
|
||||||
|
sensorDataset.lastErrorByte.setValid(true);
|
||||||
|
sensorDataset.lastErrorByte = lastFaultStatus;
|
||||||
|
}
|
||||||
sensorDataset.errorByte.setValid(true);
|
sensorDataset.errorByte.setValid(true);
|
||||||
sensorDataset.errorByte = faultByte;
|
sensorDataset.errorByte = currentFaultStatus;
|
||||||
if (faultByte != 0) {
|
|
||||||
|
if (currentFaultStatus != 0) {
|
||||||
sensorDataset.temperatureCelcius.setValid(false);
|
sensorDataset.temperatureCelcius.setValid(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = sensorDataset.commit();
|
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
|
||||||
// Configuration error
|
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
|
||||||
sif::debug << "Max31865PT1000Handler::interpretDeviceReply: Object ID: " << std::hex
|
|
||||||
<< this->getObjectId() << ": Error commiting dataset!" << std::endl;
|
|
||||||
#else
|
|
||||||
sif::printDebug(
|
|
||||||
"Max31865PT1000Handler::interpretDeviceReply: "
|
|
||||||
"Error commiting dataset!\n");
|
|
||||||
#endif
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -498,11 +497,8 @@ ReturnValue_t Max31865PT1000Handler::interpretDeviceReply(DeviceCommandId_t id,
|
|||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Max31865PT1000Handler::debugInterface(uint8_t positionTracker, object_id_t objectId,
|
|
||||||
uint32_t parameter) {}
|
|
||||||
|
|
||||||
uint32_t Max31865PT1000Handler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) {
|
uint32_t Max31865PT1000Handler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) {
|
||||||
return 25000;
|
return 5000;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t Max31865PT1000Handler::getSwitches(const uint8_t **switches,
|
ReturnValue_t Max31865PT1000Handler::getSwitches(const uint8_t **switches,
|
||||||
@ -512,10 +508,12 @@ ReturnValue_t Max31865PT1000Handler::getSwitches(const uint8_t **switches,
|
|||||||
|
|
||||||
ReturnValue_t Max31865PT1000Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t Max31865PT1000Handler::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) {
|
LocalDataPoolManager &poolManager) {
|
||||||
localDataPoolMap.emplace(Max31865Definitions::PoolIds::RTD_VALUE, new PoolEntry<float>({0}));
|
using namespace MAX31865;
|
||||||
localDataPoolMap.emplace(Max31865Definitions::PoolIds::TEMPERATURE_C,
|
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::RTD_VALUE), new PoolEntry<float>({0}));
|
||||||
new PoolEntry<float>({0}, 1, true));
|
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::TEMPERATURE_C), new PoolEntry<float>({0}));
|
||||||
localDataPoolMap.emplace(Max31865Definitions::PoolIds::FAULT_BYTE, new PoolEntry<uint8_t>({0}));
|
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::LAST_FAULT_BYTE),
|
||||||
|
new PoolEntry<uint8_t>({0}));
|
||||||
|
localDataPoolMap.emplace(static_cast<lp_id_t>(PoolIds::FAULT_BYTE), new PoolEntry<uint8_t>({0}));
|
||||||
poolManager.subscribeForPeriodicPacket(sensorDataset.getSid(), false, 30.0, false);
|
poolManager.subscribeForPeriodicPacket(sensorDataset.getSid(), false, 30.0, false);
|
||||||
return HasReturnvaluesIF::RETURN_OK;
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
}
|
}
|
||||||
@ -526,10 +524,23 @@ void Max31865PT1000Handler::setInstantNormal(bool instantNormal) {
|
|||||||
|
|
||||||
void Max31865PT1000Handler::modeChanged() {
|
void Max31865PT1000Handler::modeChanged() {
|
||||||
if (mode == MODE_OFF) {
|
if (mode == MODE_OFF) {
|
||||||
|
lastFaultStatus = 0;
|
||||||
|
currentFaultStatus = 0;
|
||||||
|
sameFaultStatusCounter = 0;
|
||||||
internalState = InternalState::NONE;
|
internalState = InternalState::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Max31865PT1000Handler::setDeviceIdx(uint8_t idx) { deviceIdx = idx; }
|
void Max31865PT1000Handler::setDeviceInfo(uint8_t idx, std::string locString_) {
|
||||||
|
deviceIdx = idx;
|
||||||
|
locString = std::move(locString_);
|
||||||
|
}
|
||||||
|
|
||||||
void Max31865PT1000Handler::setDebugMode(bool enable) { this->debugMode = enable; }
|
void Max31865PT1000Handler::setDebugMode(bool enable) { this->debugMode = enable; }
|
||||||
|
|
||||||
|
bool Max31865PT1000Handler::shouldFaultStatusBeRequested(bool faultBit) {
|
||||||
|
if ((sameFaultStatusCounter < 3) and faultBit) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -48,7 +48,7 @@ class Max31865PT1000Handler : public DeviceHandlerBase {
|
|||||||
static constexpr uint8_t DEFAULT_CONFIG = 0b11000001;
|
static constexpr uint8_t DEFAULT_CONFIG = 0b11000001;
|
||||||
|
|
||||||
void setInstantNormal(bool instantNormal);
|
void setInstantNormal(bool instantNormal);
|
||||||
void setDeviceIdx(uint8_t idx);
|
void setDeviceInfo(uint8_t idx, std::string locString);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expected temperature range is -100 C and 100 C.
|
* Expected temperature range is -100 C and 100 C.
|
||||||
@ -61,7 +61,6 @@ class Max31865PT1000Handler : public DeviceHandlerBase {
|
|||||||
static constexpr uint16_t HIGH_THRESHOLD = 11298; // = 100 C
|
static constexpr uint16_t HIGH_THRESHOLD = 11298; // = 100 C
|
||||||
static constexpr uint16_t LOW_THRESHOLD = 4902; // = -100 C
|
static constexpr uint16_t LOW_THRESHOLD = 4902; // = -100 C
|
||||||
|
|
||||||
static constexpr float RTD_RREF_PT1000 = 4020.0; //!< Ohm
|
|
||||||
static constexpr float RTD_RESISTANCE0_PT1000 = 1000.0; //!< Ohm
|
static constexpr float RTD_RESISTANCE0_PT1000 = 1000.0; //!< Ohm
|
||||||
protected:
|
protected:
|
||||||
// DeviceHandlerBase abstract function implementation
|
// DeviceHandlerBase abstract function implementation
|
||||||
@ -77,12 +76,10 @@ class Max31865PT1000Handler : public DeviceHandlerBase {
|
|||||||
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
||||||
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
uint32_t getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo) override;
|
||||||
ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override;
|
ReturnValue_t getSwitches(const uint8_t **switches, uint8_t *numberOfSwitches) override;
|
||||||
|
|
||||||
void debugInterface(uint8_t positionTracker = 0, object_id_t objectId = 0,
|
|
||||||
uint32_t parameter = 0) override;
|
|
||||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||||
LocalDataPoolManager &poolManager) override;
|
LocalDataPoolManager &poolManager) override;
|
||||||
void modeChanged() override;
|
void modeChanged() override;
|
||||||
|
bool shouldFaultStatusBeRequested(bool faultBit);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t switchId = 0;
|
uint8_t switchId = 0;
|
||||||
@ -109,11 +106,15 @@ class Max31865PT1000Handler : public DeviceHandlerBase {
|
|||||||
|
|
||||||
bool resetFaultBit = false;
|
bool resetFaultBit = false;
|
||||||
dur_millis_t startTime = 0;
|
dur_millis_t startTime = 0;
|
||||||
uint8_t faultByte = 0;
|
uint8_t currentCfg = 0;
|
||||||
|
uint8_t currentFaultStatus = 0;
|
||||||
|
uint8_t lastFaultStatus = 0;
|
||||||
|
uint16_t sameFaultStatusCounter = 0;
|
||||||
|
std::string locString;
|
||||||
uint8_t deviceIdx = 0;
|
uint8_t deviceIdx = 0;
|
||||||
std::array<uint8_t, 3> commandBuffer{0};
|
std::array<uint8_t, 3> commandBuffer{0};
|
||||||
|
|
||||||
Max31865Definitions::Max31865Set sensorDataset;
|
MAX31865::Max31865Set sensorDataset;
|
||||||
sid_t sensorDatasetSid;
|
sid_t sensorDatasetSid;
|
||||||
|
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
|
@ -716,7 +716,6 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
|
|||||||
GpioIF* gpioIF = comIf->getGpioInterface();
|
GpioIF* gpioIF = comIf->getGpioInterface();
|
||||||
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
MutexIF::TimeoutType timeoutType = MutexIF::TimeoutType::WAITING;
|
||||||
uint32_t timeoutMs = 0;
|
uint32_t timeoutMs = 0;
|
||||||
cookie->getMutexParams(timeoutType, timeoutMs);
|
|
||||||
MutexIF* mutex = comIf->getCsMutex();
|
MutexIF* mutex = comIf->getCsMutex();
|
||||||
if (mutex == nullptr or gpioIF == nullptr) {
|
if (mutex == nullptr or gpioIF == nullptr) {
|
||||||
#if OBSW_VERBOSE_LEVEL >= 1
|
#if OBSW_VERBOSE_LEVEL >= 1
|
||||||
@ -728,6 +727,7 @@ ReturnValue_t PayloadPcduHandler::transferAsTwo(SpiComIF* comIf, SpiCookie* cook
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (gpioId != gpio::NO_GPIO) {
|
if (gpioId != gpio::NO_GPIO) {
|
||||||
|
cookie->getMutexParams(timeoutType, timeoutMs);
|
||||||
result = mutex->lockMutex(timeoutType, timeoutMs);
|
result = mutex->lockMutex(timeoutType, timeoutMs);
|
||||||
if (result != RETURN_OK) {
|
if (result != RETURN_OK) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
|
@ -7,20 +7,48 @@
|
|||||||
|
|
||||||
#include "objects/systemObjectList.h"
|
#include "objects/systemObjectList.h"
|
||||||
|
|
||||||
namespace Max31865Definitions {
|
namespace MAX31865 {
|
||||||
|
|
||||||
enum PoolIds : lp_id_t { RTD_VALUE, TEMPERATURE_C, FAULT_BYTE };
|
enum class PoolIds : lp_id_t { RTD_VALUE, TEMPERATURE_C, LAST_FAULT_BYTE, FAULT_BYTE };
|
||||||
|
enum Wires : unsigned int { TWO_WIRE = 0, THREE_WIRE = 1, FOUR_WIRE = 0 };
|
||||||
|
|
||||||
|
enum ConvMode : unsigned int { NORM_OFF = 0, AUTO = 1 };
|
||||||
|
|
||||||
|
enum Bias : unsigned int { OFF = 0, ON = 1 };
|
||||||
|
|
||||||
|
enum FilterSel : unsigned int { FIFTY_HERTZ = 1, SIXTY_HERTZ = 0 };
|
||||||
|
|
||||||
|
enum CfgBitPos {
|
||||||
|
FILTER_SEL = 0,
|
||||||
|
FAULT_STATUS_CLEAR = 1,
|
||||||
|
FDCC = 2,
|
||||||
|
WIRE_SEL = 4,
|
||||||
|
ONE_SHOT = 5,
|
||||||
|
CONV_MODE = 6,
|
||||||
|
BIAS_SEL = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr uint32_t WARMUP_MS = 100;
|
||||||
|
|
||||||
|
static constexpr uint8_t WRITE_BIT = 0b10000000;
|
||||||
|
|
||||||
|
enum Regs : uint8_t {
|
||||||
|
CONFIG = 0x00,
|
||||||
|
RTD = 0x01,
|
||||||
|
HIGH_THRESHOLD = 0x03,
|
||||||
|
LOW_THRESHOLD = 0x05,
|
||||||
|
FAULT_BYTE = 0x07
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr DeviceCommandId_t CONFIG_CMD = 0x80;
|
static constexpr DeviceCommandId_t CONFIG_CMD = 0x80;
|
||||||
static constexpr DeviceCommandId_t WRITE_HIGH_THRESHOLD = 0x83;
|
static constexpr DeviceCommandId_t WRITE_HIGH_THRESHOLD = 0x83;
|
||||||
static constexpr DeviceCommandId_t WRITE_LOW_THRESHOLD = 0x85;
|
static constexpr DeviceCommandId_t WRITE_LOW_THRESHOLD = 0x85;
|
||||||
|
|
||||||
static constexpr DeviceCommandId_t REQUEST_CONFIG = 0x00;
|
static constexpr DeviceCommandId_t REQUEST_CONFIG = CONFIG;
|
||||||
static constexpr DeviceCommandId_t REQUEST_RTD = 0x01;
|
static constexpr DeviceCommandId_t REQUEST_RTD = RTD;
|
||||||
static constexpr DeviceCommandId_t REQUEST_HIGH_THRESHOLD = 0x03;
|
static constexpr DeviceCommandId_t REQUEST_HIGH_THRESHOLD = HIGH_THRESHOLD;
|
||||||
static constexpr DeviceCommandId_t REQUEST_LOW_THRESHOLD = 0x05;
|
static constexpr DeviceCommandId_t REQUEST_LOW_THRESHOLD = LOW_THRESHOLD;
|
||||||
static constexpr DeviceCommandId_t REQUEST_FAULT_BYTE = 0x07;
|
static constexpr DeviceCommandId_t REQUEST_FAULT_BYTE = FAULT_BYTE;
|
||||||
|
|
||||||
static constexpr DeviceCommandId_t CLEAR_FAULT_BYTE = 0x08;
|
static constexpr DeviceCommandId_t CLEAR_FAULT_BYTE = 0x08;
|
||||||
|
|
||||||
static constexpr uint32_t MAX31865_SET_ID = REQUEST_RTD;
|
static constexpr uint32_t MAX31865_SET_ID = REQUEST_RTD;
|
||||||
@ -28,26 +56,82 @@ static constexpr uint8_t CLEAR_FAULT_BIT_VAL = 0b0000'0010;
|
|||||||
|
|
||||||
static constexpr size_t MAX_REPLY_SIZE = 5;
|
static constexpr size_t MAX_REPLY_SIZE = 5;
|
||||||
|
|
||||||
class Max31865Set : public StaticLocalDataSet<sizeof(float) + sizeof(uint8_t)> {
|
class Max31865Set : public StaticLocalDataSet<4> {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor used by owner and data creators like device handlers.
|
* Constructor used by owner and data creators like device handlers.
|
||||||
* @param owner
|
* @param owner
|
||||||
* @param setId
|
* @param setId
|
||||||
*/
|
*/
|
||||||
Max31865Set(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, MAX31865_SET_ID) {}
|
Max31865Set(HasLocalDataPoolIF* owner, uint32_t setId) : StaticLocalDataSet(owner, setId) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used by data users like controllers.
|
* Constructor used by data users like controllers.
|
||||||
* @param sid
|
* @param sid
|
||||||
*/
|
*/
|
||||||
Max31865Set(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, MAX31865_SET_ID)) {}
|
Max31865Set(object_id_t objectId, uint32_t setId) : StaticLocalDataSet(sid_t(objectId, setId)) {}
|
||||||
|
|
||||||
lp_var_t<float> rtdValue = lp_var_t<float>(sid.objectId, PoolIds::RTD_VALUE, this);
|
lp_var_t<float> rtdValue =
|
||||||
lp_var_t<float> temperatureCelcius = lp_var_t<float>(sid.objectId, PoolIds::TEMPERATURE_C, this);
|
lp_var_t<float>(sid.objectId, static_cast<lp_id_t>(PoolIds::RTD_VALUE), this);
|
||||||
lp_var_t<uint8_t> errorByte = lp_var_t<uint8_t>(sid.objectId, PoolIds::FAULT_BYTE, this);
|
lp_var_t<float> temperatureCelcius =
|
||||||
|
lp_var_t<float>(sid.objectId, static_cast<lp_id_t>(PoolIds::TEMPERATURE_C), this);
|
||||||
|
lp_var_t<uint8_t> lastErrorByte =
|
||||||
|
lp_var_t<uint8_t>(sid.objectId, static_cast<lp_id_t>(PoolIds::LAST_FAULT_BYTE), this);
|
||||||
|
lp_var_t<uint8_t> errorByte =
|
||||||
|
lp_var_t<uint8_t>(sid.objectId, static_cast<lp_id_t>(PoolIds::FAULT_BYTE), this);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Max31865Definitions
|
} // namespace MAX31865
|
||||||
|
|
||||||
|
namespace EiveMax31855 {
|
||||||
|
|
||||||
|
static constexpr float RTD_RREF_PT1000 = 4020.0; //!< Ohm
|
||||||
|
static constexpr uint8_t NUM_RTDS = 16;
|
||||||
|
|
||||||
|
enum RtdCommands : DeviceCommandId_t {
|
||||||
|
ON = 0,
|
||||||
|
EXCHANGE_SET_ID = MAX31865::REQUEST_RTD,
|
||||||
|
ACTIVE = 2,
|
||||||
|
LOW_THRESHOLD = 3,
|
||||||
|
HIGH_TRESHOLD = 4,
|
||||||
|
OFF = 5,
|
||||||
|
CFG = 6,
|
||||||
|
NUM_CMDS
|
||||||
|
};
|
||||||
|
|
||||||
|
class ReadOutStruct : public SerialLinkedListAdapter<SerializeIF> {
|
||||||
|
public:
|
||||||
|
ReadOutStruct() { setLinks(); }
|
||||||
|
ReadOutStruct(bool active, uint32_t spiErrCnt, bool faultBitSet, uint8_t faultVal,
|
||||||
|
uint16_t rtdVal)
|
||||||
|
: active(active),
|
||||||
|
adcCode(rtdVal),
|
||||||
|
faultBitSet(faultBitSet),
|
||||||
|
faultValue(faultVal),
|
||||||
|
spiErrorCount(spiErrCnt) {
|
||||||
|
setLinks();
|
||||||
|
}
|
||||||
|
|
||||||
|
//! RTD was set on and is configured, but is not periodically polled
|
||||||
|
SerializeElement<bool> configured = false;
|
||||||
|
//! RTD is active and polled periodically
|
||||||
|
SerializeElement<bool> active = false;
|
||||||
|
SerializeElement<uint16_t> adcCode = 0;
|
||||||
|
SerializeElement<bool> faultBitSet = false;
|
||||||
|
SerializeElement<uint8_t> faultValue = 0;
|
||||||
|
SerializeElement<uint32_t> spiErrorCount = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setLinks() {
|
||||||
|
setStart(&configured);
|
||||||
|
configured.setNext(&active);
|
||||||
|
active.setNext(&adcCode);
|
||||||
|
adcCode.setNext(&faultBitSet);
|
||||||
|
faultBitSet.setNext(&faultValue);
|
||||||
|
faultValue.setNext(&spiErrorCount);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}; // namespace EiveMax31855
|
||||||
|
|
||||||
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MAX13865DEFINITIONS_H_ */
|
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MAX13865DEFINITIONS_H_ */
|
||||||
|
@ -10,7 +10,7 @@ TcsBoardAssembly::TcsBoardAssembly(object_id_t objectId, object_id_t parentId,
|
|||||||
eventQueue = QueueFactory::instance()->createMessageQueue(24);
|
eventQueue = QueueFactory::instance()->createMessageQueue(24);
|
||||||
ModeListEntry entry;
|
ModeListEntry entry;
|
||||||
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
||||||
entry.setObject(helper.rtdIds[idx]);
|
entry.setObject(helper.rtdInfos[idx].first);
|
||||||
entry.setMode(MODE_OFF);
|
entry.setMode(MODE_OFF);
|
||||||
entry.setSubmode(SUBMODE_NONE);
|
entry.setSubmode(SUBMODE_NONE);
|
||||||
entry.setInheritSubmode(false);
|
entry.setInheritSubmode(false);
|
||||||
@ -56,7 +56,7 @@ ReturnValue_t TcsBoardAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_
|
|||||||
int devsInWrongMode = 0;
|
int devsInWrongMode = 0;
|
||||||
try {
|
try {
|
||||||
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
||||||
if (childrenMap.at(helper.rtdIds[idx]).mode != wantedMode) {
|
if (childrenMap.at(helper.rtdInfos[idx].first).mode != wantedMode) {
|
||||||
devsInWrongMode++;
|
devsInWrongMode++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,8 +92,8 @@ ReturnValue_t TcsBoardAssembly::isModeCombinationValid(Mode_t mode, Submode_t su
|
|||||||
|
|
||||||
ReturnValue_t TcsBoardAssembly::initialize() {
|
ReturnValue_t TcsBoardAssembly::initialize() {
|
||||||
ReturnValue_t result = RETURN_OK;
|
ReturnValue_t result = RETURN_OK;
|
||||||
for (const auto& obj : helper.rtdIds) {
|
for (const auto& obj : helper.rtdInfos) {
|
||||||
result = registerChild(obj);
|
result = registerChild(obj.first);
|
||||||
if (result != HasReturnvaluesIF::RETURN_OK) {
|
if (result != HasReturnvaluesIF::RETURN_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -125,8 +125,8 @@ ReturnValue_t TcsBoardAssembly::handleNormalOrOnModeCmd(Mode_t mode, Submode_t s
|
|||||||
object_id_t objId = 0;
|
object_id_t objId = 0;
|
||||||
try {
|
try {
|
||||||
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
for (uint8_t idx = 0; idx < NUMBER_RTDS; idx++) {
|
||||||
devMode = childrenMap.at(helper.rtdIds[idx]).mode;
|
devMode = childrenMap.at(helper.rtdInfos[idx].first).mode;
|
||||||
objId = helper.rtdIds[idx];
|
objId = helper.rtdInfos[idx].first;
|
||||||
if (mode == devMode) {
|
if (mode == devMode) {
|
||||||
modeTable[idx].setMode(mode);
|
modeTable[idx].setMode(mode);
|
||||||
} else if (mode == DeviceHandlerIF::MODE_NORMAL) {
|
} else if (mode == DeviceHandlerIF::MODE_NORMAL) {
|
||||||
|
@ -6,9 +6,10 @@
|
|||||||
#include <fsfw/power/PowerSwitcher.h>
|
#include <fsfw/power/PowerSwitcher.h>
|
||||||
|
|
||||||
struct TcsBoardHelper {
|
struct TcsBoardHelper {
|
||||||
TcsBoardHelper(std::array<object_id_t, 16> rtdIds) : rtdIds(rtdIds) {}
|
TcsBoardHelper(std::array<std::pair<object_id_t, std::string>, 16> rtdInfos)
|
||||||
|
: rtdInfos(std::move(rtdInfos)) {}
|
||||||
|
|
||||||
std::array<object_id_t, 16> rtdIds = {};
|
std::array<std::pair<object_id_t, std::string>, 16> rtdInfos = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
class TcsBoardAssembly : public AssemblyBase, public ConfirmsFailuresIF {
|
class TcsBoardAssembly : public AssemblyBase, public ConfirmsFailuresIF {
|
||||||
|
2
tmtc
2
tmtc
@ -1 +1 @@
|
|||||||
Subproject commit 480e0f07e03edeb55a3d6e3d629e7601b6bf90a2
|
Subproject commit 648e0b781483119e17799e34d669f554559692f0
|
Loading…
Reference in New Issue
Block a user