spi decoder callbacks wip

This commit is contained in:
2021-05-02 13:48:39 +02:00
parent fef6cf4abe
commit b708028c61
17 changed files with 447 additions and 312 deletions

View File

@ -14,6 +14,7 @@ target_sources(${TARGET_NAME} PUBLIC
Max31865PT1000Handler.cpp
IMTQHandler.cpp
PlocHandler.cpp
RadiationSensorHandler.cpp
)

View File

@ -1,145 +0,0 @@
#include <mission/devices/Max1227Handler.h>
#include <mission/devices/devicedefinitions/Tmp1075Definitions.h>
#include <OBSWConfig.h>
Max1227Handler::Max1227Handler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie) :
DeviceHandlerBase(objectId, comIF, comCookie), dataset(
this) {
if (comCookie == NULL) {
sif::error << "Max1227Handler: Invalid com cookie" << std::endl;
}
}
Max1227Handler::~Max1227Handler() {
}
void Max1227Handler::doStartUp(){
if(mode == _MODE_START_UP){
setMode(MODE_ON);
}
}
void Max1227Handler::doShutDown(){
}
ReturnValue_t Max1227Handler::buildNormalDeviceCommand(
DeviceCommandId_t * id) {
if(communicationStep == CommunicationStep::START_ADC_CONVERSION) {
*id = TMP1075::START_ADC_CONVERSION;
communicationStep = CommunicationStep::GET_TEMPERATURE;
return buildCommandFromCommand(*id, NULL, 0);
}
else {
*id = TMP1075::GET_TEMP;
communicationStep = CommunicationStep::START_ADC_CONVERSION;
return buildCommandFromCommand(*id, NULL, 0);
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Max1227Handler::buildTransitionDeviceCommand(
DeviceCommandId_t * id){
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Max1227Handler::buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t * commandData,
size_t commandDataLen) {
switch(deviceCommand) {
case(TMP1075::START_ADC_CONVERSION): {
std::memset(cmdBuffer, 0, sizeof(cmdBuffer));
prepareAdcConversionCommand();
rawPacket = cmdBuffer;
rawPacketLen = TMP1075::CFGR_CMD_SIZE;
return RETURN_OK;
}
case(TMP1075::GET_TEMP): {
std::memset(cmdBuffer, 0, sizeof(cmdBuffer));
prepareGetTempCommand();
rawPacket = cmdBuffer;
rawPacketLen = TMP1075::POINTER_REG_SIZE;
rememberCommandId = TMP1075::GET_TEMP;
return RETURN_OK;
}
default:
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
void Max1227Handler::fillCommandAndReplyMap(){
this->insertInCommandMap(TMP1075::START_ADC_CONVERSION);
this->insertInCommandAndReplyMap(TMP1075::GET_TEMP, 1, &dataset,
TMP1075::GET_TEMP_REPLY_SIZE);
}
ReturnValue_t Max1227Handler::scanForReply(const uint8_t *start,
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
switch(rememberCommandId) {
case(TMP1075::GET_TEMP):
*foundId = TMP1075::GET_TEMP;
*foundLen = TMP1075::GET_TEMP_REPLY_SIZE;
rememberCommandId = TMP1075::NONE;
break;
default:
return IGNORE_REPLY_DATA;
}
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t Max1227Handler::interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) {
switch (id) {
case TMP1075::GET_TEMP: {
int16_t tempValueRaw = 0;
tempValueRaw = packet[0] << 4 | packet[1] >> 4;
float tempValue = ((static_cast<float>(tempValueRaw)) * 0.0625);
#if OBSW_VERBOSE_LEVEL >= 1
sif::info << "Tmp1075 with object id: 0x" << std::hex << getObjectId()
<< ": Temperature: " << tempValue<< " °C"
<< std::endl;
#endif
ReturnValue_t result = dataset.read();
if(result == HasReturnvaluesIF::RETURN_OK) {
dataset.temperatureCelcius = tempValue;
dataset.commit();
}
break;
}
default: {
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
void Max1227Handler::setNormalDatapoolEntriesInvalid(){
}
void Max1227Handler::prepareAdcConversionCommand(){
cmdBuffer[0] = TMP1075::CFGR_ADDR;
cmdBuffer[1] = TMP1075::ONE_SHOT_MODE >> 8;
cmdBuffer[2] = TMP1075::ONE_SHOT_MODE & 0xFF;
}
void Max1227Handler::prepareGetTempCommand(){
cmdBuffer[0] = TMP1075::TEMP_REG_ADDR;
}
uint32_t Max1227Handler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){
return 500;
}
ReturnValue_t Max1227Handler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
localDataPoolMap.emplace(TMP1075::TEMPERATURE_C_TMP1075_1, new PoolEntry<float>( { 0.0 }));
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -0,0 +1,158 @@
#include <fsfw/datapool/PoolReadGuard.h>
#include <mission/devices/RadiationSensorHandler.h>
#include <OBSWConfig.h>
RadiationSensorHandler::RadiationSensorHandler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie) :
DeviceHandlerBase(objectId, comIF, comCookie), dataset(
this) {
if (comCookie == NULL) {
sif::error << "RadiationSensorHandler: Invalid com cookie" << std::endl;
}
}
RadiationSensorHandler::~RadiationSensorHandler() {
}
void RadiationSensorHandler::doStartUp(){
if (internalState == InternalState::CONFIGURED) {
#if OBSW_SWITCH_TO_NORMAL_MODE_AFTER_STARTUP == 1
setMode(MODE_NORMAL);
#else
setMode(_MODE_TO_ON);
#endif
}
}
void RadiationSensorHandler::doShutDown(){
setMode(_MODE_POWER_DOWN);
}
ReturnValue_t RadiationSensorHandler::buildNormalDeviceCommand(
DeviceCommandId_t * id) {
switch (communicationStep) {
case CommunicationStep::START_CONVERSION: {
*id = RAD_SENSOR::START_CONVERSION;
communicationStep = CommunicationStep::READ_CONVERSIONS;
break;
}
case CommunicationStep::READ_CONVERSIONS: {
*id = RAD_SENSOR::READ_CONVERSIONS;
// communicationStep = CommunicationStep::START_CONVERSION;
communicationStep = CommunicationStep::READ_CONVERSIONS;
break;
}
default: {
sif::debug << "RadiationSensorHandler::buildNormalDeviceCommand: Unknwon communication "
<< "step" << std::endl;
return HasReturnvaluesIF::RETURN_OK;
}
}
return buildCommandFromCommand(*id, nullptr, 0);
}
ReturnValue_t RadiationSensorHandler::buildTransitionDeviceCommand(
DeviceCommandId_t * id){
if (internalState == InternalState::SETUP) {
*id = RAD_SENSOR::WRITE_SETUP;
}
else {
return HasReturnvaluesIF::RETURN_OK;
}
buildCommandFromCommand(*id, nullptr, 0);
}
ReturnValue_t RadiationSensorHandler::buildCommandFromCommand(
DeviceCommandId_t deviceCommand, const uint8_t * commandData,
size_t commandDataLen) {
switch(deviceCommand) {
case(RAD_SENSOR::WRITE_SETUP): {
cmdBuffer[0] = RAD_SENSOR::SETUP_DEFINITION;
rawPacket = cmdBuffer;
rawPacketLen = 1;
internalState = InternalState::CONFIGURED;
return RETURN_OK;
}
case(RAD_SENSOR::START_CONVERSION): {
cmdBuffer[0] = RAD_SENSOR::CONVERSION_DEFINITION;
rawPacket = cmdBuffer;
rawPacketLen = 1;
return RETURN_OK;
}
case(RAD_SENSOR::READ_CONVERSIONS): {
cmdBuffer[0] = RAD_SENSOR::DUMMY_BYTE;
cmdBuffer[1] = RAD_SENSOR::DUMMY_BYTE;
cmdBuffer[2] = RAD_SENSOR::DUMMY_BYTE;
cmdBuffer[3] = RAD_SENSOR::DUMMY_BYTE;
cmdBuffer[4] = RAD_SENSOR::DUMMY_BYTE;
cmdBuffer[5] = RAD_SENSOR::DUMMY_BYTE;
cmdBuffer[6] = RAD_SENSOR::DUMMY_BYTE;
rawPacket = cmdBuffer;
rawPacketLen = RAD_SENSOR::READ_SIZE;
return RETURN_OK;
}
default:
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
}
return HasReturnvaluesIF::RETURN_FAILED;
}
void RadiationSensorHandler::fillCommandAndReplyMap() {
this->insertInCommandMap(RAD_SENSOR::WRITE_SETUP);
this->insertInCommandMap(RAD_SENSOR::START_CONVERSION);
this->insertInCommandAndReplyMap(RAD_SENSOR::READ_CONVERSIONS, 1, &dataset,
RAD_SENSOR::READ_SIZE);
}
ReturnValue_t RadiationSensorHandler::scanForReply(const uint8_t *start,
size_t remainingSize, DeviceCommandId_t *foundId, size_t *foundLen) {
*foundId = this->getPendingCommand();
*foundLen = remainingSize;
return HasReturnvaluesIF::RETURN_OK;
}
ReturnValue_t RadiationSensorHandler::interpretDeviceReply(DeviceCommandId_t id,
const uint8_t *packet) {
switch (id) {
case RAD_SENSOR::READ_CONVERSIONS: {
PoolReadGuard readSet(&dataset);
dataset.temperatureCelcius = (*(packet) << 8 | *(packet + 1)) * 0.125;
dataset.channel0 = (*(packet + 2) << 8 | *(packet + 3));
dataset.channel1 = (*(packet + 4) << 8 | *(packet + 5));
#if OBSW_VERBOSE_LEVEL >= 1 && DEBUG_RAD_SENSOR
sif::info << "Radiation sensor temperature: " << dataset.temperatureCelcius << " °C"
<< std::endl;
sif::info << "Radiation sensor temperature ADC value channel 0: " << dataset.channel0
<< std::endl;
sif::info << "Radiation sensor temperature ADC value channel 1: " << dataset.channel1
<< std::endl;
#endif
break;
}
default: {
sif::debug << "RadiationSensorHandler::interpretDeviceReply: Unknown reply id" << std::endl;
return DeviceHandlerIF::UNKNOWN_DEVICE_REPLY;
}
}
return HasReturnvaluesIF::RETURN_OK;
}
void RadiationSensorHandler::setNormalDatapoolEntriesInvalid(){
}
uint32_t RadiationSensorHandler::getTransitionDelayMs(Mode_t modeFrom, Mode_t modeTo){
return 5000;
}
ReturnValue_t RadiationSensorHandler::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
LocalDataPoolManager& poolManager) {
localDataPoolMap.emplace(RAD_SENSOR::TEMPERATURE_C, new PoolEntry<float>( { 0.0 }));
localDataPoolMap.emplace(RAD_SENSOR::CHANNEL_0, new PoolEntry<uint16_t>( { 0 }));
localDataPoolMap.emplace(RAD_SENSOR::CHANNEL_1, new PoolEntry<uint16_t>( { 0 }));
return HasReturnvaluesIF::RETURN_OK;
}

View File

@ -1,22 +1,23 @@
#ifndef MISSION_DEVICES_MAX1227HANDLER_H_
#define MISSION_DEVICES_MAX1227HANDLER_H_
#ifndef MISSION_DEVICES_RADIATIONSENSORHANDLER_H_
#define MISSION_DEVICES_RADIATIONSENSORHANDLER_H_
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
#include <mission/devices/devicedefinitions/Tmp1075Definitions.h>
#include <mission/devices/devicedefinitions/RadSensorDefinitions.h>
/**
* @brief This is the device handler class for the MAX1227 ADC converter.
* @brief This is the device handler class for radiation sensor on the OBC IF Board. The sensor
* is based on the MAX1227 ADC converter.
*
* @details Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX1227-MAX1231.pdf
* @details Datasheet of MAX1227: https://datasheets.maximintegrated.com/en/ds/MAX1227-MAX1231.pdf
*
* @author J. Meier
*/
class Max1227Handler: public DeviceHandlerBase {
class RadiationSensorHandler: public DeviceHandlerBase {
public:
Max1227Handler(object_id_t objectId, object_id_t comIF,
RadiationSensorHandler(object_id_t objectId, object_id_t comIF,
CookieIF * comCookie);
virtual ~Max1227Handler();
virtual ~RadiationSensorHandler();
protected:
void doStartUp() override;
@ -37,28 +38,23 @@ protected:
private:
/**
* @brief Function fills cmdBuffer with command to start the adc
* conversion for a new temperature value.
*/
void prepareAdcConversionCommand();
void prepareGetTempCommand();
enum class CommunicationStep {
START_ADC_CONVERSION,
GET_TEMPERATURE
START_CONVERSION,
READ_CONVERSIONS
};
TMP1075::Tmp1075Dataset dataset;
enum class InternalState {
SETUP,
CONFIGURED
};
static const uint8_t MAX_CMD_LEN = 3;
RAD_SENSOR::RadSensorDataset dataset;
static const uint8_t MAX_CMD_LEN = RAD_SENSOR::READ_SIZE;
uint8_t rememberRequestedSize = 0;
uint8_t rememberCommandId = TMP1075::NONE;
uint8_t cmdBuffer[MAX_CMD_LEN];
CommunicationStep communicationStep =
CommunicationStep::START_ADC_CONVERSION;
InternalState internalState = InternalState::SETUP;
CommunicationStep communicationStep = CommunicationStep::START_CONVERSION;
};
#endif /* MISSION_DEVICES_MAX1227HANDLER_H_ */
#endif /* MISSION_DEVICES_RADIATIONSENSORHANDLER_H_ */

View File

@ -1,47 +0,0 @@
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_MAX1227_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_MAX1227_H_
namespace MAX1227 {
static const uint8_t TEMP_REG_ADDR = 0x0;
static const uint8_t CFGR_ADDR = 0x1;
/* Writing this information to the configuration register sets the tmp1075
* to shutdown mode and starts a single temperature conversion */
static const uint16_t ONE_SHOT_MODE = 0x8100;
static const DeviceCommandId_t NONE = 0x0; // Set when no command is pending
static const DeviceCommandId_t GET_TEMP = 0x1;
static const DeviceCommandId_t START_ADC_CONVERSION = 0x2;
static const uint8_t GET_TEMP_REPLY_SIZE = 2;
static const uint8_t CFGR_CMD_SIZE = 3;
static const uint8_t POINTER_REG_SIZE = 1;
static const uint32_t TMP1075_DATA_SET_ID = GET_TEMP;
static const uint8_t MAX_REPLY_LENGTH = GET_TEMP_REPLY_SIZE;
enum Tmp1075PoolIds: lp_id_t {
TEMPERATURE_C_TMP1075_1,
TEMPERATURE_C_TMP1075_2
};
class Tmp1075Dataset:
public StaticLocalDataSet<sizeof(float)> {
public:
Tmp1075Dataset(HasLocalDataPoolIF* owner):
StaticLocalDataSet(owner, TMP1075_DATA_SET_ID) {
}
Tmp1075Dataset(object_id_t objectId):
StaticLocalDataSet(sid_t(objectId, TMP1075_DATA_SET_ID)) {
}
lp_var_t<float> temperatureCelcius = lp_var_t<float>(sid.objectId,
TEMPERATURE_C_TMP1075_1, this);
};
}
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_MAX1227_H_ */

View File

@ -0,0 +1,79 @@
#ifndef MISSION_DEVICES_DEVICEDEFINITIONS_RADSENSOR_H_
#define MISSION_DEVICES_DEVICEDEFINITIONS_RADSENSOR_H_
namespace RAD_SENSOR {
static const DeviceCommandId_t NONE = 0x0; // Set when no command is pending
/**
* This command initiates the ADC conversion for all channels including the internal
* temperature sensor.
*/
static const DeviceCommandId_t WRITE_SETUP = 0x1;
static const DeviceCommandId_t START_CONVERSION = 0x2;
static const DeviceCommandId_t READ_CONVERSIONS = 0x3;
static const uint32_t MAX1227_DATA_SET_ID = READ_CONVERSIONS;
/**
* @brief This is the configuration byte which will be written to the setup register after
* power on.
*
* @note Bit1 (DIFFSEL1) - Bit0 (DIFFSEL0): 0b00, no data follows the setup byte
* Bit3 (REFSEL1) - Bit2 (REFSEL0): 0b01, external reference single ended
* Bit5 (CLKSEL1) - Bit4 (CLKSEL0): 0b10, MAX1227 uses internal oscillator for timing
* Bit7 - Bit6: 0b01, tells MAX1227 that this is the setup register
*
*/
static const uint8_t SETUP_DEFINITION = 0b01101000;
/**
* @brief This value will always be written to the ADC conversion register to specify the
* conversions to perform.
* @details Bit0: 1 - Enables temperature conversion
* Bit2 (SCAN1) and Bit1 (SCAN0): 0b00 (channel conversion from 0 to N)
* Bit6 - Bit3 defines N: 0b0001 (N = 1)
* Bit7: Always 1. Tells the ADC that this is the conversion register.
*/
static const uint8_t CONVERSION_DEFINITION = 0b10001001;
/**
* Unipolar only required for differential measurement. Unipolar or dipolar determines the
* voltage range.
*/
static const uint8_t UNIPOLAR_SETUP = 0b10000000;
static const uint8_t DUMMY_BYTE = 0xFF;
static const uint8_t RAD_SENSOR_DATA_SET_ID = READ_CONVERSIONS;
/**
* One temperature value, conversion of channel 0 and conversion of channel 1
*/
static const uint8_t READ_SIZE = 6;
enum Max1227PoolIds: lp_id_t {
TEMPERATURE_C,
CHANNEL_0,
CHANNEL_1,
};
class RadSensorDataset: public StaticLocalDataSet<sizeof(float)> {
public:
RadSensorDataset(HasLocalDataPoolIF* owner) :
StaticLocalDataSet(owner, RAD_SENSOR_DATA_SET_ID) {
}
RadSensorDataset(object_id_t objectId) :
StaticLocalDataSet(sid_t(objectId, RAD_SENSOR_DATA_SET_ID)) {
}
lp_var_t<float> temperatureCelcius = lp_var_t<float>(sid.objectId, TEMPERATURE_C, this);
lp_var_t<uint16_t> channel0 = lp_var_t<uint16_t>(sid.objectId, CHANNEL_0, this);
lp_var_t<uint16_t> channel1 = lp_var_t<uint16_t>(sid.objectId, CHANNEL_1, this);
};
}
#endif /* MISSION_DEVICES_DEVICEDEFINITIONS_RADSENSOR_H_ */