Merge remote-tracking branch 'origin/development' into mueller/update-changelog
This commit is contained in:
commit
51add8a8ad
@ -1,50 +1,48 @@
|
||||
#include "fsfw_hal/common/gpio/GpioCookie.h"
|
||||
|
||||
#include "fsfw/serviceinterface/ServiceInterface.h"
|
||||
|
||||
GpioCookie::GpioCookie() {
|
||||
}
|
||||
GpioCookie::GpioCookie() {}
|
||||
|
||||
ReturnValue_t GpioCookie::addGpio(gpioId_t gpioId, GpioBase* gpioConfig) {
|
||||
if (gpioConfig == nullptr) {
|
||||
if (gpioConfig == nullptr) {
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "GpioCookie::addGpio: gpioConfig is nullpointer" << std::endl;
|
||||
sif::warning << "GpioCookie::addGpio: gpioConfig is nullpointer" << std::endl;
|
||||
#else
|
||||
sif::printWarning("GpioCookie::addGpio: gpioConfig is nullpointer\n");
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
auto gpioMapIter = gpioMap.find(gpioId);
|
||||
if(gpioMapIter == gpioMap.end()) {
|
||||
auto statusPair = gpioMap.emplace(gpioId, gpioConfig);
|
||||
if (statusPair.second == false) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "GpioCookie::addGpio: Failed to add GPIO " << gpioId <<
|
||||
" to GPIO map" << std::endl;
|
||||
#else
|
||||
sif::printWarning("GpioCookie::addGpio: Failed to add GPIO %d to GPIO map\n", gpioId);
|
||||
#endif
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl;
|
||||
#else
|
||||
sif::printWarning("GpioCookie::addGpio: GPIO already exists in GPIO map\n");
|
||||
#endif
|
||||
sif::printWarning("GpioCookie::addGpio: gpioConfig is nullpointer\n");
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
auto gpioMapIter = gpioMap.find(gpioId);
|
||||
if (gpioMapIter == gpioMap.end()) {
|
||||
auto statusPair = gpioMap.emplace(gpioId, gpioConfig);
|
||||
if (statusPair.second == false) {
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "GpioCookie::addGpio: Failed to add GPIO " << gpioId << " to GPIO map"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("GpioCookie::addGpio: Failed to add GPIO %d to GPIO map\n", gpioId);
|
||||
#endif
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
#if FSFW_VERBOSE_LEVEL >= 1
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "GpioCookie::addGpio: GPIO already exists in GPIO map " << std::endl;
|
||||
#else
|
||||
sif::printWarning("GpioCookie::addGpio: GPIO already exists in GPIO map\n");
|
||||
#endif
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_FAILED;
|
||||
}
|
||||
|
||||
GpioMap GpioCookie::getGpioMap() const {
|
||||
return gpioMap;
|
||||
}
|
||||
GpioMap GpioCookie::getGpioMap() const { return gpioMap; }
|
||||
|
||||
GpioCookie::~GpioCookie() {
|
||||
for(auto& config: gpioMap) {
|
||||
delete(config.second);
|
||||
}
|
||||
for (auto& config : gpioMap) {
|
||||
delete (config.second);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
#ifndef COMMON_GPIO_GPIOCOOKIE_H_
|
||||
#define COMMON_GPIO_GPIOCOOKIE_H_
|
||||
|
||||
#include "GpioIF.h"
|
||||
#include "gpioDefinitions.h"
|
||||
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include "GpioIF.h"
|
||||
#include "gpioDefinitions.h"
|
||||
|
||||
/**
|
||||
* @brief Cookie for the GpioIF. Allows the GpioIF to determine which
|
||||
* GPIOs to initialize and whether they should be configured as in- or
|
||||
@ -17,25 +17,24 @@
|
||||
*
|
||||
* @author J. Meier
|
||||
*/
|
||||
class GpioCookie: public CookieIF {
|
||||
public:
|
||||
class GpioCookie : public CookieIF {
|
||||
public:
|
||||
GpioCookie();
|
||||
|
||||
GpioCookie();
|
||||
virtual ~GpioCookie();
|
||||
|
||||
virtual ~GpioCookie();
|
||||
ReturnValue_t addGpio(gpioId_t gpioId, GpioBase* gpioConfig);
|
||||
|
||||
ReturnValue_t addGpio(gpioId_t gpioId, GpioBase* gpioConfig);
|
||||
/**
|
||||
* @brief Get map with registered GPIOs.
|
||||
*/
|
||||
GpioMap getGpioMap() const;
|
||||
|
||||
/**
|
||||
* @brief Get map with registered GPIOs.
|
||||
*/
|
||||
GpioMap getGpioMap() const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Returns a copy of the internal GPIO map.
|
||||
*/
|
||||
GpioMap gpioMap;
|
||||
private:
|
||||
/**
|
||||
* Returns a copy of the internal GPIO map.
|
||||
*/
|
||||
GpioMap gpioMap;
|
||||
};
|
||||
|
||||
#endif /* COMMON_GPIO_GPIOCOOKIE_H_ */
|
||||
|
@ -1,9 +1,10 @@
|
||||
#ifndef COMMON_GPIO_GPIOIF_H_
|
||||
#define COMMON_GPIO_GPIOIF_H_
|
||||
|
||||
#include "gpioDefinitions.h"
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
#include <fsfw/devicehandlers/CookieIF.h>
|
||||
#include <fsfw/returnvalues/HasReturnvaluesIF.h>
|
||||
|
||||
#include "gpioDefinitions.h"
|
||||
|
||||
class GpioCookie;
|
||||
|
||||
@ -13,42 +14,41 @@ class GpioCookie;
|
||||
* @author J. Meier
|
||||
*/
|
||||
class GpioIF : public HasReturnvaluesIF {
|
||||
public:
|
||||
public:
|
||||
virtual ~GpioIF(){};
|
||||
|
||||
virtual ~GpioIF() {};
|
||||
/**
|
||||
* @brief Called by the GPIO using object.
|
||||
* @param cookie Cookie specifying informations of the GPIOs required
|
||||
* by a object.
|
||||
*/
|
||||
virtual ReturnValue_t addGpios(GpioCookie* cookie) = 0;
|
||||
|
||||
/**
|
||||
* @brief Called by the GPIO using object.
|
||||
* @param cookie Cookie specifying informations of the GPIOs required
|
||||
* by a object.
|
||||
*/
|
||||
virtual ReturnValue_t addGpios(GpioCookie* cookie) = 0;
|
||||
/**
|
||||
* @brief By implementing this function a child must provide the
|
||||
* functionality to pull a certain GPIO to high logic level.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||
* @return Returns RETURN_OK for success. This should never return RETURN_FAILED.
|
||||
*/
|
||||
virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0;
|
||||
|
||||
/**
|
||||
* @brief By implementing this function a child must provide the
|
||||
* functionality to pull a certain GPIO to high logic level.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||
* @return Returns RETURN_OK for success. This should never return RETURN_FAILED.
|
||||
*/
|
||||
virtual ReturnValue_t pullHigh(gpioId_t gpioId) = 0;
|
||||
/**
|
||||
* @brief By implementing this function a child must provide the
|
||||
* functionality to pull a certain GPIO to low logic level.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||
*/
|
||||
virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0;
|
||||
|
||||
/**
|
||||
* @brief By implementing this function a child must provide the
|
||||
* functionality to pull a certain GPIO to low logic level.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to drive.
|
||||
*/
|
||||
virtual ReturnValue_t pullLow(gpioId_t gpioId) = 0;
|
||||
|
||||
/**
|
||||
* @brief This function requires a child to implement the functionality to read the state of
|
||||
* an ouput or input gpio.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to read.
|
||||
* @param gpioState State of GPIO will be written to this pointer.
|
||||
*/
|
||||
virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0;
|
||||
/**
|
||||
* @brief This function requires a child to implement the functionality to read the state of
|
||||
* an ouput or input gpio.
|
||||
*
|
||||
* @param gpioId A unique number which specifies the GPIO to read.
|
||||
* @param gpioState State of GPIO will be written to this pointer.
|
||||
*/
|
||||
virtual ReturnValue_t readGpio(gpioId_t gpioId, int* gpioState) = 0;
|
||||
};
|
||||
|
||||
#endif /* COMMON_GPIO_GPIOIF_H_ */
|
||||
|
@ -1,44 +1,34 @@
|
||||
#ifndef COMMON_GPIO_GPIODEFINITIONS_H_
|
||||
#define COMMON_GPIO_GPIODEFINITIONS_H_
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
using gpioId_t = uint16_t;
|
||||
|
||||
namespace gpio {
|
||||
|
||||
enum Levels: uint8_t {
|
||||
LOW = 0,
|
||||
HIGH = 1,
|
||||
NONE = 99
|
||||
};
|
||||
enum Levels : uint8_t { LOW = 0, HIGH = 1, NONE = 99 };
|
||||
|
||||
enum Direction: uint8_t {
|
||||
IN = 0,
|
||||
OUT = 1
|
||||
};
|
||||
enum Direction : uint8_t { IN = 0, OUT = 1 };
|
||||
|
||||
enum GpioOperation {
|
||||
READ,
|
||||
WRITE
|
||||
};
|
||||
enum GpioOperation { READ, WRITE };
|
||||
|
||||
enum class GpioTypes {
|
||||
NONE,
|
||||
GPIO_REGULAR_BY_CHIP,
|
||||
GPIO_REGULAR_BY_LABEL,
|
||||
GPIO_REGULAR_BY_LINE_NAME,
|
||||
CALLBACK
|
||||
NONE,
|
||||
GPIO_REGULAR_BY_CHIP,
|
||||
GPIO_REGULAR_BY_LABEL,
|
||||
GPIO_REGULAR_BY_LINE_NAME,
|
||||
CALLBACK
|
||||
};
|
||||
|
||||
static constexpr gpioId_t NO_GPIO = -1;
|
||||
|
||||
using gpio_cb_t = void (*) (gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Levels value,
|
||||
void* args);
|
||||
using gpio_cb_t = void (*)(gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::Levels value,
|
||||
void* args);
|
||||
|
||||
}
|
||||
} // namespace gpio
|
||||
|
||||
/**
|
||||
* @brief Struct containing information about the GPIO to use. This is
|
||||
@ -55,78 +45,71 @@ using gpio_cb_t = void (*) (gpioId_t gpioId, gpio::GpioOperation gpioOp, gpio::L
|
||||
* pointer.
|
||||
*/
|
||||
class GpioBase {
|
||||
public:
|
||||
public:
|
||||
GpioBase() = default;
|
||||
|
||||
GpioBase() = default;
|
||||
GpioBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
|
||||
gpio::Levels initValue)
|
||||
: gpioType(gpioType), consumer(consumer), direction(direction), initValue(initValue) {}
|
||||
|
||||
GpioBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
|
||||
gpio::Levels initValue):
|
||||
gpioType(gpioType), consumer(consumer),direction(direction), initValue(initValue) {}
|
||||
virtual ~GpioBase(){};
|
||||
|
||||
virtual~ GpioBase() {};
|
||||
|
||||
// Can be used to cast GpioBase to a concrete child implementation
|
||||
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
|
||||
std::string consumer;
|
||||
gpio::Direction direction = gpio::Direction::IN;
|
||||
gpio::Levels initValue = gpio::Levels::NONE;
|
||||
// Can be used to cast GpioBase to a concrete child implementation
|
||||
gpio::GpioTypes gpioType = gpio::GpioTypes::NONE;
|
||||
std::string consumer;
|
||||
gpio::Direction direction = gpio::Direction::IN;
|
||||
gpio::Levels initValue = gpio::Levels::NONE;
|
||||
};
|
||||
|
||||
class GpiodRegularBase: public GpioBase {
|
||||
public:
|
||||
GpiodRegularBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
|
||||
gpio::Levels initValue, int lineNum):
|
||||
GpioBase(gpioType, consumer, direction, initValue), lineNum(lineNum) {
|
||||
}
|
||||
class GpiodRegularBase : public GpioBase {
|
||||
public:
|
||||
GpiodRegularBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
|
||||
gpio::Levels initValue, int lineNum)
|
||||
: GpioBase(gpioType, consumer, direction, initValue), lineNum(lineNum) {}
|
||||
|
||||
// line number will be configured at a later point for the open by line name configuration
|
||||
GpiodRegularBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
|
||||
gpio::Levels initValue): GpioBase(gpioType, consumer, direction, initValue) {
|
||||
}
|
||||
// line number will be configured at a later point for the open by line name configuration
|
||||
GpiodRegularBase(gpio::GpioTypes gpioType, std::string consumer, gpio::Direction direction,
|
||||
gpio::Levels initValue)
|
||||
: GpioBase(gpioType, consumer, direction, initValue) {}
|
||||
|
||||
int lineNum = 0;
|
||||
struct gpiod_line* lineHandle = nullptr;
|
||||
int lineNum = 0;
|
||||
struct gpiod_line* lineHandle = nullptr;
|
||||
};
|
||||
|
||||
class GpiodRegularByChip: public GpiodRegularBase {
|
||||
public:
|
||||
GpiodRegularByChip() :
|
||||
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP,
|
||||
std::string(), gpio::Direction::IN, gpio::LOW, 0) {
|
||||
}
|
||||
class GpiodRegularByChip : public GpiodRegularBase {
|
||||
public:
|
||||
GpiodRegularByChip()
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, std::string(), gpio::Direction::IN,
|
||||
gpio::LOW, 0) {}
|
||||
|
||||
GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_,
|
||||
gpio::Direction direction_, gpio::Levels initValue_) :
|
||||
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP,
|
||||
consumer_, direction_, initValue_, lineNum_),
|
||||
chipname(chipname_){
|
||||
}
|
||||
GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_,
|
||||
gpio::Direction direction_, gpio::Levels initValue_)
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, consumer_, direction_, initValue_,
|
||||
lineNum_),
|
||||
chipname(chipname_) {}
|
||||
|
||||
GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_) :
|
||||
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, consumer_,
|
||||
gpio::Direction::IN, gpio::LOW, lineNum_),
|
||||
chipname(chipname_) {
|
||||
}
|
||||
GpiodRegularByChip(std::string chipname_, int lineNum_, std::string consumer_)
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_CHIP, consumer_, gpio::Direction::IN,
|
||||
gpio::LOW, lineNum_),
|
||||
chipname(chipname_) {}
|
||||
|
||||
std::string chipname;
|
||||
std::string chipname;
|
||||
};
|
||||
|
||||
class GpiodRegularByLabel: public GpiodRegularBase {
|
||||
public:
|
||||
GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_,
|
||||
gpio::Direction direction_, gpio::Levels initValue_) :
|
||||
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_,
|
||||
direction_, initValue_, lineNum_),
|
||||
label(label_) {
|
||||
}
|
||||
class GpiodRegularByLabel : public GpiodRegularBase {
|
||||
public:
|
||||
GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_,
|
||||
gpio::Direction direction_, gpio::Levels initValue_)
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_, direction_, initValue_,
|
||||
lineNum_),
|
||||
label(label_) {}
|
||||
|
||||
GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_) :
|
||||
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_,
|
||||
gpio::Direction::IN, gpio::LOW, lineNum_),
|
||||
label(label_) {
|
||||
}
|
||||
GpiodRegularByLabel(std::string label_, int lineNum_, std::string consumer_)
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LABEL, consumer_, gpio::Direction::IN,
|
||||
gpio::LOW, lineNum_),
|
||||
label(label_) {}
|
||||
|
||||
std::string label;
|
||||
std::string label;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -134,34 +117,34 @@ public:
|
||||
* line name. This line name can be set in the device tree and must be unique. Otherwise
|
||||
* the driver will open the first line with the given name.
|
||||
*/
|
||||
class GpiodRegularByLineName: public GpiodRegularBase {
|
||||
public:
|
||||
GpiodRegularByLineName(std::string lineName_, std::string consumer_, gpio::Direction direction_,
|
||||
gpio::Levels initValue_) :
|
||||
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, direction_,
|
||||
initValue_), lineName(lineName_) {
|
||||
}
|
||||
class GpiodRegularByLineName : public GpiodRegularBase {
|
||||
public:
|
||||
GpiodRegularByLineName(std::string lineName_, std::string consumer_, gpio::Direction direction_,
|
||||
gpio::Levels initValue_)
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, direction_,
|
||||
initValue_),
|
||||
lineName(lineName_) {}
|
||||
|
||||
GpiodRegularByLineName(std::string lineName_, std::string consumer_) :
|
||||
GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_,
|
||||
gpio::Direction::IN, gpio::LOW), lineName(lineName_) {
|
||||
}
|
||||
GpiodRegularByLineName(std::string lineName_, std::string consumer_)
|
||||
: GpiodRegularBase(gpio::GpioTypes::GPIO_REGULAR_BY_LINE_NAME, consumer_, gpio::Direction::IN,
|
||||
gpio::LOW),
|
||||
lineName(lineName_) {}
|
||||
|
||||
std::string lineName;
|
||||
std::string lineName;
|
||||
};
|
||||
|
||||
class GpioCallback: public GpioBase {
|
||||
public:
|
||||
GpioCallback(std::string consumer, gpio::Direction direction_, gpio::Levels initValue_,
|
||||
gpio::gpio_cb_t callback, void* callbackArgs):
|
||||
GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_),
|
||||
callback(callback), callbackArgs(callbackArgs) {}
|
||||
class GpioCallback : public GpioBase {
|
||||
public:
|
||||
GpioCallback(std::string consumer, gpio::Direction direction_, gpio::Levels initValue_,
|
||||
gpio::gpio_cb_t callback, void* callbackArgs)
|
||||
: GpioBase(gpio::GpioTypes::CALLBACK, consumer, direction_, initValue_),
|
||||
callback(callback),
|
||||
callbackArgs(callbackArgs) {}
|
||||
|
||||
gpio::gpio_cb_t callback = nullptr;
|
||||
void* callbackArgs = nullptr;
|
||||
gpio::gpio_cb_t callback = nullptr;
|
||||
void* callbackArgs = nullptr;
|
||||
};
|
||||
|
||||
|
||||
using GpioMap = std::map<gpioId_t, GpioBase*>;
|
||||
using GpioUnorderedMap = std::unordered_map<gpioId_t, GpioBase*>;
|
||||
using GpioMapIter = GpioMap::iterator;
|
||||
|
@ -5,12 +5,7 @@
|
||||
|
||||
namespace spi {
|
||||
|
||||
enum SpiModes: uint8_t {
|
||||
MODE_0,
|
||||
MODE_1,
|
||||
MODE_2,
|
||||
MODE_3
|
||||
};
|
||||
enum SpiModes : uint8_t { MODE_0, MODE_1, MODE_2, MODE_3 };
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,287 +1,274 @@
|
||||
#include "GyroL3GD20Handler.h"
|
||||
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "fsfw/datapool/PoolReadGuard.h"
|
||||
|
||||
GyroHandlerL3GD20H::GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication,
|
||||
CookieIF *comCookie, uint32_t transitionDelayMs):
|
||||
DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||
transitionDelayMs(transitionDelayMs), dataset(this) {
|
||||
CookieIF *comCookie, uint32_t transitionDelayMs)
|
||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||
transitionDelayMs(transitionDelayMs),
|
||||
dataset(this) {
|
||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
||||
debugDivider = new PeriodicOperationDivider(3);
|
||||
debugDivider = new PeriodicOperationDivider(3);
|
||||
#endif
|
||||
}
|
||||
|
||||
GyroHandlerL3GD20H::~GyroHandlerL3GD20H() {}
|
||||
|
||||
void GyroHandlerL3GD20H::doStartUp() {
|
||||
if(internalState == InternalState::NONE) {
|
||||
internalState = InternalState::CONFIGURE;
|
||||
}
|
||||
if (internalState == InternalState::NONE) {
|
||||
internalState = InternalState::CONFIGURE;
|
||||
}
|
||||
|
||||
if(internalState == InternalState::CONFIGURE) {
|
||||
if(commandExecuted) {
|
||||
internalState = InternalState::CHECK_REGS;
|
||||
commandExecuted = false;
|
||||
}
|
||||
if (internalState == InternalState::CONFIGURE) {
|
||||
if (commandExecuted) {
|
||||
internalState = InternalState::CHECK_REGS;
|
||||
commandExecuted = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(internalState == InternalState::CHECK_REGS) {
|
||||
if(commandExecuted) {
|
||||
internalState = InternalState::NORMAL;
|
||||
if(goNormalModeImmediately) {
|
||||
setMode(MODE_NORMAL);
|
||||
}
|
||||
else {
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
commandExecuted = false;
|
||||
}
|
||||
if (internalState == InternalState::CHECK_REGS) {
|
||||
if (commandExecuted) {
|
||||
internalState = InternalState::NORMAL;
|
||||
if (goNormalModeImmediately) {
|
||||
setMode(MODE_NORMAL);
|
||||
} else {
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
commandExecuted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GyroHandlerL3GD20H::doShutDown() {
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
}
|
||||
void GyroHandlerL3GD20H::doShutDown() { setMode(_MODE_POWER_DOWN); }
|
||||
|
||||
ReturnValue_t GyroHandlerL3GD20H::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
||||
switch(internalState) {
|
||||
case(InternalState::NONE):
|
||||
case(InternalState::NORMAL): {
|
||||
return NOTHING_TO_SEND;
|
||||
switch (internalState) {
|
||||
case (InternalState::NONE):
|
||||
case (InternalState::NORMAL): {
|
||||
return NOTHING_TO_SEND;
|
||||
}
|
||||
case(InternalState::CONFIGURE): {
|
||||
*id = L3GD20H::CONFIGURE_CTRL_REGS;
|
||||
uint8_t command [5];
|
||||
command[0] = L3GD20H::CTRL_REG_1_VAL;
|
||||
command[1] = L3GD20H::CTRL_REG_2_VAL;
|
||||
command[2] = L3GD20H::CTRL_REG_3_VAL;
|
||||
command[3] = L3GD20H::CTRL_REG_4_VAL;
|
||||
command[4] = L3GD20H::CTRL_REG_5_VAL;
|
||||
return buildCommandFromCommand(*id, command, 5);
|
||||
case (InternalState::CONFIGURE): {
|
||||
*id = L3GD20H::CONFIGURE_CTRL_REGS;
|
||||
uint8_t command[5];
|
||||
command[0] = L3GD20H::CTRL_REG_1_VAL;
|
||||
command[1] = L3GD20H::CTRL_REG_2_VAL;
|
||||
command[2] = L3GD20H::CTRL_REG_3_VAL;
|
||||
command[3] = L3GD20H::CTRL_REG_4_VAL;
|
||||
command[4] = L3GD20H::CTRL_REG_5_VAL;
|
||||
return buildCommandFromCommand(*id, command, 5);
|
||||
}
|
||||
case(InternalState::CHECK_REGS): {
|
||||
*id = L3GD20H::READ_REGS;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
case (InternalState::CHECK_REGS): {
|
||||
*id = L3GD20H::READ_REGS;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
default:
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
/* Might be a configuration error. */
|
||||
sif::warning << "GyroL3GD20Handler::buildTransitionDeviceCommand: "
|
||||
"Unknown internal state!" << std::endl;
|
||||
/* Might be a configuration error. */
|
||||
sif::warning << "GyroL3GD20Handler::buildTransitionDeviceCommand: "
|
||||
"Unknown internal state!"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printDebug("GyroL3GD20Handler::buildTransitionDeviceCommand: "
|
||||
"Unknown internal state!\n");
|
||||
sif::printDebug(
|
||||
"GyroL3GD20Handler::buildTransitionDeviceCommand: "
|
||||
"Unknown internal state!\n");
|
||||
#endif
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t GyroHandlerL3GD20H::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||
*id = L3GD20H::READ_REGS;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
*id = L3GD20H::READ_REGS;
|
||||
return buildCommandFromCommand(*id, nullptr, 0);
|
||||
}
|
||||
|
||||
ReturnValue_t GyroHandlerL3GD20H::buildCommandFromCommand(
|
||||
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
switch(deviceCommand) {
|
||||
case(L3GD20H::READ_REGS): {
|
||||
commandBuffer[0] = L3GD20H::READ_START | L3GD20H::AUTO_INCREMENT_MASK | L3GD20H::READ_MASK;
|
||||
std::memset(commandBuffer + 1, 0, L3GD20H::READ_LEN);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = L3GD20H::READ_LEN + 1;
|
||||
break;
|
||||
ReturnValue_t GyroHandlerL3GD20H::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
switch (deviceCommand) {
|
||||
case (L3GD20H::READ_REGS): {
|
||||
commandBuffer[0] = L3GD20H::READ_START | L3GD20H::AUTO_INCREMENT_MASK | L3GD20H::READ_MASK;
|
||||
std::memset(commandBuffer + 1, 0, L3GD20H::READ_LEN);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = L3GD20H::READ_LEN + 1;
|
||||
break;
|
||||
}
|
||||
case(L3GD20H::CONFIGURE_CTRL_REGS): {
|
||||
commandBuffer[0] = L3GD20H::CTRL_REG_1 | L3GD20H::AUTO_INCREMENT_MASK;
|
||||
if(commandData == nullptr or commandDataLen != 5) {
|
||||
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
|
||||
}
|
||||
case (L3GD20H::CONFIGURE_CTRL_REGS): {
|
||||
commandBuffer[0] = L3GD20H::CTRL_REG_1 | L3GD20H::AUTO_INCREMENT_MASK;
|
||||
if (commandData == nullptr or commandDataLen != 5) {
|
||||
return DeviceHandlerIF::INVALID_COMMAND_PARAMETER;
|
||||
}
|
||||
|
||||
ctrlReg1Value = commandData[0];
|
||||
ctrlReg2Value = commandData[1];
|
||||
ctrlReg3Value = commandData[2];
|
||||
ctrlReg4Value = commandData[3];
|
||||
ctrlReg5Value = commandData[4];
|
||||
ctrlReg1Value = commandData[0];
|
||||
ctrlReg2Value = commandData[1];
|
||||
ctrlReg3Value = commandData[2];
|
||||
ctrlReg4Value = commandData[3];
|
||||
ctrlReg5Value = commandData[4];
|
||||
|
||||
bool fsH = ctrlReg4Value & L3GD20H::SET_FS_1;
|
||||
bool fsL = ctrlReg4Value & L3GD20H::SET_FS_0;
|
||||
bool fsH = ctrlReg4Value & L3GD20H::SET_FS_1;
|
||||
bool fsL = ctrlReg4Value & L3GD20H::SET_FS_0;
|
||||
|
||||
if(not fsH and not fsL) {
|
||||
sensitivity = L3GD20H::SENSITIVITY_00;
|
||||
}
|
||||
else if(not fsH and fsL) {
|
||||
sensitivity = L3GD20H::SENSITIVITY_01;
|
||||
}
|
||||
else {
|
||||
sensitivity = L3GD20H::SENSITIVITY_11;
|
||||
}
|
||||
if (not fsH and not fsL) {
|
||||
sensitivity = L3GD20H::SENSITIVITY_00;
|
||||
} else if (not fsH and fsL) {
|
||||
sensitivity = L3GD20H::SENSITIVITY_01;
|
||||
} else {
|
||||
sensitivity = L3GD20H::SENSITIVITY_11;
|
||||
}
|
||||
|
||||
commandBuffer[1] = ctrlReg1Value;
|
||||
commandBuffer[2] = ctrlReg2Value;
|
||||
commandBuffer[3] = ctrlReg3Value;
|
||||
commandBuffer[4] = ctrlReg4Value;
|
||||
commandBuffer[5] = ctrlReg5Value;
|
||||
commandBuffer[1] = ctrlReg1Value;
|
||||
commandBuffer[2] = ctrlReg2Value;
|
||||
commandBuffer[3] = ctrlReg3Value;
|
||||
commandBuffer[4] = ctrlReg4Value;
|
||||
commandBuffer[5] = ctrlReg5Value;
|
||||
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = 6;
|
||||
break;
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = 6;
|
||||
break;
|
||||
}
|
||||
case(L3GD20H::READ_CTRL_REGS): {
|
||||
commandBuffer[0] = L3GD20H::READ_START | L3GD20H::AUTO_INCREMENT_MASK |
|
||||
L3GD20H::READ_MASK;
|
||||
case (L3GD20H::READ_CTRL_REGS): {
|
||||
commandBuffer[0] = L3GD20H::READ_START | L3GD20H::AUTO_INCREMENT_MASK | L3GD20H::READ_MASK;
|
||||
|
||||
std::memset(commandBuffer + 1, 0, 5);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = 6;
|
||||
break;
|
||||
std::memset(commandBuffer + 1, 0, 5);
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = 6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t GyroHandlerL3GD20H::scanForReply(const uint8_t *start, size_t len,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
// For SPI, the ID will always be the one of the last sent command
|
||||
*foundId = this->getPendingCommand();
|
||||
*foundLen = this->rawPacketLen;
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) {
|
||||
// For SPI, the ID will always be the one of the last sent command
|
||||
*foundId = this->getPendingCommand();
|
||||
*foundLen = this->rawPacketLen;
|
||||
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
ReturnValue_t GyroHandlerL3GD20H::interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
switch(id) {
|
||||
case(L3GD20H::CONFIGURE_CTRL_REGS): {
|
||||
const uint8_t *packet) {
|
||||
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
|
||||
switch (id) {
|
||||
case (L3GD20H::CONFIGURE_CTRL_REGS): {
|
||||
commandExecuted = true;
|
||||
break;
|
||||
}
|
||||
case (L3GD20H::READ_CTRL_REGS): {
|
||||
if (packet[1] == ctrlReg1Value and packet[2] == ctrlReg2Value and
|
||||
packet[3] == ctrlReg3Value and packet[4] == ctrlReg4Value and
|
||||
packet[5] == ctrlReg5Value) {
|
||||
commandExecuted = true;
|
||||
break;
|
||||
} else {
|
||||
// Attempt reconfiguration
|
||||
internalState = InternalState::CONFIGURE;
|
||||
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(L3GD20H::READ_CTRL_REGS): {
|
||||
if(packet[1] == ctrlReg1Value and packet[2] == ctrlReg2Value and
|
||||
packet[3] == ctrlReg3Value and packet[4] == ctrlReg4Value and
|
||||
packet[5] == ctrlReg5Value) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
else {
|
||||
// Attempt reconfiguration
|
||||
internalState = InternalState::CONFIGURE;
|
||||
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(L3GD20H::READ_REGS): {
|
||||
if(packet[1] != ctrlReg1Value and packet[2] != ctrlReg2Value and
|
||||
packet[3] != ctrlReg3Value and packet[4] != ctrlReg4Value and
|
||||
packet[5] != ctrlReg5Value) {
|
||||
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
|
||||
}
|
||||
else {
|
||||
if(internalState == InternalState::CHECK_REGS) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
case (L3GD20H::READ_REGS): {
|
||||
if (packet[1] != ctrlReg1Value and packet[2] != ctrlReg2Value and
|
||||
packet[3] != ctrlReg3Value and packet[4] != ctrlReg4Value and
|
||||
packet[5] != ctrlReg5Value) {
|
||||
return DeviceHandlerIF::DEVICE_REPLY_INVALID;
|
||||
} else {
|
||||
if (internalState == InternalState::CHECK_REGS) {
|
||||
commandExecuted = true;
|
||||
}
|
||||
}
|
||||
|
||||
statusReg = packet[L3GD20H::STATUS_IDX];
|
||||
statusReg = packet[L3GD20H::STATUS_IDX];
|
||||
|
||||
int16_t angVelocXRaw = packet[L3GD20H::OUT_X_H] << 8 | packet[L3GD20H::OUT_X_L];
|
||||
int16_t angVelocYRaw = packet[L3GD20H::OUT_Y_H] << 8 | packet[L3GD20H::OUT_Y_L];
|
||||
int16_t angVelocZRaw = packet[L3GD20H::OUT_Z_H] << 8 | packet[L3GD20H::OUT_Z_L];
|
||||
float angVelocX = angVelocXRaw * sensitivity;
|
||||
float angVelocY = angVelocYRaw * sensitivity;
|
||||
float angVelocZ = angVelocZRaw * sensitivity;
|
||||
int16_t angVelocXRaw = packet[L3GD20H::OUT_X_H] << 8 | packet[L3GD20H::OUT_X_L];
|
||||
int16_t angVelocYRaw = packet[L3GD20H::OUT_Y_H] << 8 | packet[L3GD20H::OUT_Y_L];
|
||||
int16_t angVelocZRaw = packet[L3GD20H::OUT_Z_H] << 8 | packet[L3GD20H::OUT_Z_L];
|
||||
float angVelocX = angVelocXRaw * sensitivity;
|
||||
float angVelocY = angVelocYRaw * sensitivity;
|
||||
float angVelocZ = angVelocZRaw * sensitivity;
|
||||
|
||||
int8_t temperaturOffset = (-1) * packet[L3GD20H::TEMPERATURE_IDX];
|
||||
float temperature = 25.0 + temperaturOffset;
|
||||
int8_t temperaturOffset = (-1) * packet[L3GD20H::TEMPERATURE_IDX];
|
||||
float temperature = 25.0 + temperaturOffset;
|
||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
||||
if(debugDivider->checkAndIncrement()) {
|
||||
/* Set terminal to utf-8 if there is an issue with micro printout. */
|
||||
if (debugDivider->checkAndIncrement()) {
|
||||
/* Set terminal to utf-8 if there is an issue with micro printout. */
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::info << "GyroHandlerL3GD20H: Angular velocities (deg/s):" << std::endl;
|
||||
sif::info << "X: " << angVelocX << std::endl;
|
||||
sif::info << "Y: " << angVelocY << std::endl;
|
||||
sif::info << "Z: " << angVelocZ << std::endl;
|
||||
sif::info << "GyroHandlerL3GD20H: Angular velocities (deg/s):" << std::endl;
|
||||
sif::info << "X: " << angVelocX << std::endl;
|
||||
sif::info << "Y: " << angVelocY << std::endl;
|
||||
sif::info << "Z: " << angVelocZ << std::endl;
|
||||
#else
|
||||
sif::printInfo("GyroHandlerL3GD20H: Angular velocities (deg/s):\n");
|
||||
sif::printInfo("X: %f\n", angVelocX);
|
||||
sif::printInfo("Y: %f\n", angVelocY);
|
||||
sif::printInfo("Z: %f\n", angVelocZ);
|
||||
sif::printInfo("GyroHandlerL3GD20H: Angular velocities (deg/s):\n");
|
||||
sif::printInfo("X: %f\n", angVelocX);
|
||||
sif::printInfo("Y: %f\n", angVelocY);
|
||||
sif::printInfo("Z: %f\n", angVelocZ);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PoolReadGuard readSet(&dataset);
|
||||
if(readSet.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
|
||||
if(std::abs(angVelocX) < this->absLimitX) {
|
||||
dataset.angVelocX = angVelocX;
|
||||
dataset.angVelocX.setValid(true);
|
||||
}
|
||||
else {
|
||||
dataset.angVelocX.setValid(false);
|
||||
}
|
||||
|
||||
if(std::abs(angVelocY) < this->absLimitY) {
|
||||
dataset.angVelocY = angVelocY;
|
||||
dataset.angVelocY.setValid(true);
|
||||
}
|
||||
else {
|
||||
dataset.angVelocY.setValid(false);
|
||||
}
|
||||
|
||||
if(std::abs(angVelocZ) < this->absLimitZ) {
|
||||
dataset.angVelocZ = angVelocZ;
|
||||
dataset.angVelocZ.setValid(true);
|
||||
}
|
||||
else {
|
||||
dataset.angVelocZ.setValid(false);
|
||||
}
|
||||
|
||||
dataset.temperature = temperature;
|
||||
dataset.temperature.setValid(true);
|
||||
PoolReadGuard readSet(&dataset);
|
||||
if (readSet.getReadResult() == HasReturnvaluesIF::RETURN_OK) {
|
||||
if (std::abs(angVelocX) < this->absLimitX) {
|
||||
dataset.angVelocX = angVelocX;
|
||||
dataset.angVelocX.setValid(true);
|
||||
} else {
|
||||
dataset.angVelocX.setValid(false);
|
||||
}
|
||||
break;
|
||||
|
||||
if (std::abs(angVelocY) < this->absLimitY) {
|
||||
dataset.angVelocY = angVelocY;
|
||||
dataset.angVelocY.setValid(true);
|
||||
} else {
|
||||
dataset.angVelocY.setValid(false);
|
||||
}
|
||||
|
||||
if (std::abs(angVelocZ) < this->absLimitZ) {
|
||||
dataset.angVelocZ = angVelocZ;
|
||||
dataset.angVelocZ.setValid(true);
|
||||
} else {
|
||||
dataset.angVelocZ.setValid(false);
|
||||
}
|
||||
|
||||
dataset.temperature = temperature;
|
||||
dataset.temperature.setValid(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
return result;
|
||||
return DeviceHandlerIF::COMMAND_NOT_IMPLEMENTED;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
uint32_t GyroHandlerL3GD20H::getTransitionDelayMs(Mode_t from, Mode_t to) {
|
||||
return this->transitionDelayMs;
|
||||
return this->transitionDelayMs;
|
||||
}
|
||||
|
||||
void GyroHandlerL3GD20H::setToGoToNormalMode(bool enable) {
|
||||
this->goNormalModeImmediately = true;
|
||||
}
|
||||
void GyroHandlerL3GD20H::setToGoToNormalMode(bool enable) { this->goNormalModeImmediately = true; }
|
||||
|
||||
ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool(
|
||||
localpool::DataPool &localDataPoolMap, LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_X, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Z, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::TEMPERATURE, new PoolEntry<float>({0.0}));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
ReturnValue_t GyroHandlerL3GD20H::initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) {
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_X, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Y, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::ANG_VELOC_Z, new PoolEntry<float>({0.0}));
|
||||
localDataPoolMap.emplace(L3GD20H::TEMPERATURE, new PoolEntry<float>({0.0}));
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
void GyroHandlerL3GD20H::fillCommandAndReplyMap() {
|
||||
insertInCommandAndReplyMap(L3GD20H::READ_REGS, 1, &dataset);
|
||||
insertInCommandAndReplyMap(L3GD20H::CONFIGURE_CTRL_REGS, 1);
|
||||
insertInCommandAndReplyMap(L3GD20H::READ_CTRL_REGS, 1);
|
||||
insertInCommandAndReplyMap(L3GD20H::READ_REGS, 1, &dataset);
|
||||
insertInCommandAndReplyMap(L3GD20H::CONFIGURE_CTRL_REGS, 1);
|
||||
insertInCommandAndReplyMap(L3GD20H::READ_CTRL_REGS, 1);
|
||||
}
|
||||
|
||||
void GyroHandlerL3GD20H::modeChanged() {
|
||||
internalState = InternalState::NONE;
|
||||
}
|
||||
void GyroHandlerL3GD20H::modeChanged() { internalState = InternalState::NONE; }
|
||||
|
||||
void GyroHandlerL3GD20H::setAbsoluteLimits(float limitX, float limitY, float limitZ) {
|
||||
this->absLimitX = limitX;
|
||||
this->absLimitY = limitY;
|
||||
this->absLimitZ = limitZ;
|
||||
this->absLimitX = limitX;
|
||||
this->absLimitY = limitY;
|
||||
this->absLimitZ = limitZ;
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
#ifndef MISSION_DEVICES_GYROL3GD20HANDLER_H_
|
||||
#define MISSION_DEVICES_GYROL3GD20HANDLER_H_
|
||||
|
||||
#include "fsfw/FSFW.h"
|
||||
#include "devicedefinitions/GyroL3GD20Definitions.h"
|
||||
|
||||
#include <fsfw/devicehandlers/DeviceHandlerBase.h>
|
||||
#include <fsfw/globalfunctions/PeriodicOperationDivider.h>
|
||||
|
||||
#include "devicedefinitions/GyroL3GD20Definitions.h"
|
||||
#include "fsfw/FSFW.h"
|
||||
|
||||
/**
|
||||
* @brief Device Handler for the L3GD20H gyroscope sensor
|
||||
* (https://www.st.com/en/mems-and-sensors/l3gd20h.html)
|
||||
@ -16,84 +16,73 @@
|
||||
*
|
||||
* Data is read big endian with the smallest possible range of 245 degrees per second.
|
||||
*/
|
||||
class GyroHandlerL3GD20H: public DeviceHandlerBase {
|
||||
public:
|
||||
GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication,
|
||||
CookieIF* comCookie, uint32_t transitionDelayMs);
|
||||
virtual ~GyroHandlerL3GD20H();
|
||||
class GyroHandlerL3GD20H : public DeviceHandlerBase {
|
||||
public:
|
||||
GyroHandlerL3GD20H(object_id_t objectId, object_id_t deviceCommunication, CookieIF *comCookie,
|
||||
uint32_t transitionDelayMs);
|
||||
virtual ~GyroHandlerL3GD20H();
|
||||
|
||||
/**
|
||||
* Set the absolute limit for the values on the axis in degrees per second.
|
||||
* The dataset values will be marked as invalid if that limit is exceeded
|
||||
* @param xLimit
|
||||
* @param yLimit
|
||||
* @param zLimit
|
||||
*/
|
||||
void setAbsoluteLimits(float limitX, float limitY, float limitZ);
|
||||
/**
|
||||
* Set the absolute limit for the values on the axis in degrees per second.
|
||||
* The dataset values will be marked as invalid if that limit is exceeded
|
||||
* @param xLimit
|
||||
* @param yLimit
|
||||
* @param zLimit
|
||||
*/
|
||||
void setAbsoluteLimits(float limitX, float limitY, float limitZ);
|
||||
|
||||
/**
|
||||
* @brief Configure device handler to go to normal mode immediately
|
||||
*/
|
||||
void setToGoToNormalMode(bool enable);
|
||||
protected:
|
||||
/**
|
||||
* @brief Configure device handler to go to normal mode immediately
|
||||
*/
|
||||
void setToGoToNormalMode(bool enable);
|
||||
|
||||
/* DeviceHandlerBase overrides */
|
||||
ReturnValue_t buildTransitionDeviceCommand(
|
||||
DeviceCommandId_t *id) override;
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
ReturnValue_t buildNormalDeviceCommand(
|
||||
DeviceCommandId_t *id) override;
|
||||
ReturnValue_t buildCommandFromCommand(
|
||||
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
||||
size_t commandDataLen) override;
|
||||
ReturnValue_t scanForReply(const uint8_t *start, size_t len,
|
||||
DeviceCommandId_t *foundId, size_t *foundLen) override;
|
||||
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id,
|
||||
const uint8_t *packet) override;
|
||||
protected:
|
||||
/* DeviceHandlerBase overrides */
|
||||
ReturnValue_t buildTransitionDeviceCommand(DeviceCommandId_t *id) override;
|
||||
void doStartUp() override;
|
||||
void doShutDown() override;
|
||||
ReturnValue_t buildNormalDeviceCommand(DeviceCommandId_t *id) override;
|
||||
ReturnValue_t buildCommandFromCommand(DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
||||
size_t commandDataLen) override;
|
||||
ReturnValue_t scanForReply(const uint8_t *start, size_t len, DeviceCommandId_t *foundId,
|
||||
size_t *foundLen) override;
|
||||
virtual ReturnValue_t interpretDeviceReply(DeviceCommandId_t id, const uint8_t *packet) override;
|
||||
|
||||
void fillCommandAndReplyMap() override;
|
||||
void modeChanged() override;
|
||||
virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) override;
|
||||
void fillCommandAndReplyMap() override;
|
||||
void modeChanged() override;
|
||||
virtual uint32_t getTransitionDelayMs(Mode_t from, Mode_t to) override;
|
||||
ReturnValue_t initializeLocalDataPool(localpool::DataPool &localDataPoolMap,
|
||||
LocalDataPoolManager &poolManager) override;
|
||||
|
||||
private:
|
||||
uint32_t transitionDelayMs = 0;
|
||||
GyroPrimaryDataset dataset;
|
||||
private:
|
||||
uint32_t transitionDelayMs = 0;
|
||||
GyroPrimaryDataset dataset;
|
||||
|
||||
float absLimitX = L3GD20H::RANGE_DPS_00;
|
||||
float absLimitY = L3GD20H::RANGE_DPS_00;
|
||||
float absLimitZ = L3GD20H::RANGE_DPS_00;
|
||||
float absLimitX = L3GD20H::RANGE_DPS_00;
|
||||
float absLimitY = L3GD20H::RANGE_DPS_00;
|
||||
float absLimitZ = L3GD20H::RANGE_DPS_00;
|
||||
|
||||
enum class InternalState {
|
||||
NONE,
|
||||
CONFIGURE,
|
||||
CHECK_REGS,
|
||||
NORMAL
|
||||
};
|
||||
InternalState internalState = InternalState::NONE;
|
||||
bool commandExecuted = false;
|
||||
enum class InternalState { NONE, CONFIGURE, CHECK_REGS, NORMAL };
|
||||
InternalState internalState = InternalState::NONE;
|
||||
bool commandExecuted = false;
|
||||
|
||||
uint8_t statusReg = 0;
|
||||
bool goNormalModeImmediately = false;
|
||||
uint8_t statusReg = 0;
|
||||
bool goNormalModeImmediately = false;
|
||||
|
||||
uint8_t ctrlReg1Value = L3GD20H::CTRL_REG_1_VAL;
|
||||
uint8_t ctrlReg2Value = L3GD20H::CTRL_REG_2_VAL;
|
||||
uint8_t ctrlReg3Value = L3GD20H::CTRL_REG_3_VAL;
|
||||
uint8_t ctrlReg4Value = L3GD20H::CTRL_REG_4_VAL;
|
||||
uint8_t ctrlReg5Value = L3GD20H::CTRL_REG_5_VAL;
|
||||
uint8_t ctrlReg1Value = L3GD20H::CTRL_REG_1_VAL;
|
||||
uint8_t ctrlReg2Value = L3GD20H::CTRL_REG_2_VAL;
|
||||
uint8_t ctrlReg3Value = L3GD20H::CTRL_REG_3_VAL;
|
||||
uint8_t ctrlReg4Value = L3GD20H::CTRL_REG_4_VAL;
|
||||
uint8_t ctrlReg5Value = L3GD20H::CTRL_REG_5_VAL;
|
||||
|
||||
uint8_t commandBuffer[L3GD20H::READ_LEN + 1];
|
||||
uint8_t commandBuffer[L3GD20H::READ_LEN + 1];
|
||||
|
||||
// Set default value
|
||||
float sensitivity = L3GD20H::SENSITIVITY_00;
|
||||
// Set default value
|
||||
float sensitivity = L3GD20H::SENSITIVITY_00;
|
||||
|
||||
#if FSFW_HAL_L3GD20_GYRO_DEBUG == 1
|
||||
PeriodicOperationDivider* debugDivider = nullptr;
|
||||
PeriodicOperationDivider *debugDivider = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* MISSION_DEVICES_GYROL3GD20HANDLER_H_ */
|
||||
|
@ -8,513 +8,477 @@
|
||||
#include <cmath>
|
||||
|
||||
MgmLIS3MDLHandler::MgmLIS3MDLHandler(object_id_t objectId, object_id_t deviceCommunication,
|
||||
CookieIF* comCookie, uint32_t transitionDelay):
|
||||
DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||
dataset(this), transitionDelay(transitionDelay) {
|
||||
CookieIF *comCookie, uint32_t transitionDelay)
|
||||
: DeviceHandlerBase(objectId, deviceCommunication, comCookie),
|
||||
dataset(this),
|
||||
transitionDelay(transitionDelay) {
|
||||
#if FSFW_HAL_LIS3MDL_MGM_DEBUG == 1
|
||||
debugDivider = new PeriodicOperationDivider(3);
|
||||
debugDivider = new PeriodicOperationDivider(3);
|
||||
#endif
|
||||
// Set to default values right away
|
||||
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
|
||||
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
|
||||
registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT;
|
||||
registers[3] = MGMLIS3MDL::CTRL_REG4_DEFAULT;
|
||||
registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT;
|
||||
|
||||
}
|
||||
|
||||
MgmLIS3MDLHandler::~MgmLIS3MDLHandler() {
|
||||
// Set to default values right away
|
||||
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
|
||||
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
|
||||
registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT;
|
||||
registers[3] = MGMLIS3MDL::CTRL_REG4_DEFAULT;
|
||||
registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT;
|
||||
}
|
||||
|
||||
MgmLIS3MDLHandler::~MgmLIS3MDLHandler() {}
|
||||
|
||||
void MgmLIS3MDLHandler::doStartUp() {
|
||||
switch (internalState) {
|
||||
case(InternalState::STATE_NONE): {
|
||||
internalState = InternalState::STATE_FIRST_CONTACT;
|
||||
break;
|
||||
switch (internalState) {
|
||||
case (InternalState::STATE_NONE): {
|
||||
internalState = InternalState::STATE_FIRST_CONTACT;
|
||||
break;
|
||||
}
|
||||
case(InternalState::STATE_FIRST_CONTACT): {
|
||||
/* Will be set by checking device ID (WHO AM I register) */
|
||||
if(commandExecuted) {
|
||||
commandExecuted = false;
|
||||
internalState = InternalState::STATE_SETUP;
|
||||
case (InternalState::STATE_FIRST_CONTACT): {
|
||||
/* Will be set by checking device ID (WHO AM I register) */
|
||||
if (commandExecuted) {
|
||||
commandExecuted = false;
|
||||
internalState = InternalState::STATE_SETUP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (InternalState::STATE_SETUP): {
|
||||
internalState = InternalState::STATE_CHECK_REGISTERS;
|
||||
break;
|
||||
}
|
||||
case (InternalState::STATE_CHECK_REGISTERS): {
|
||||
/* Set up cached registers which will be used to configure the MGM. */
|
||||
if (commandExecuted) {
|
||||
commandExecuted = false;
|
||||
if (goToNormalMode) {
|
||||
setMode(MODE_NORMAL);
|
||||
} else {
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case(InternalState::STATE_SETUP): {
|
||||
internalState = InternalState::STATE_CHECK_REGISTERS;
|
||||
break;
|
||||
}
|
||||
case(InternalState::STATE_CHECK_REGISTERS): {
|
||||
/* Set up cached registers which will be used to configure the MGM. */
|
||||
if(commandExecuted) {
|
||||
commandExecuted = false;
|
||||
if(goToNormalMode) {
|
||||
setMode(MODE_NORMAL);
|
||||
}
|
||||
else {
|
||||
setMode(_MODE_TO_ON);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MgmLIS3MDLHandler::doShutDown() {
|
||||
setMode(_MODE_POWER_DOWN);
|
||||
}
|
||||
void MgmLIS3MDLHandler::doShutDown() { setMode(_MODE_POWER_DOWN); }
|
||||
|
||||
ReturnValue_t MgmLIS3MDLHandler::buildTransitionDeviceCommand(
|
||||
DeviceCommandId_t *id) {
|
||||
switch (internalState) {
|
||||
case(InternalState::STATE_NONE):
|
||||
case(InternalState::STATE_NORMAL): {
|
||||
return DeviceHandlerBase::NOTHING_TO_SEND;
|
||||
ReturnValue_t MgmLIS3MDLHandler::buildTransitionDeviceCommand(DeviceCommandId_t *id) {
|
||||
switch (internalState) {
|
||||
case (InternalState::STATE_NONE):
|
||||
case (InternalState::STATE_NORMAL): {
|
||||
return DeviceHandlerBase::NOTHING_TO_SEND;
|
||||
}
|
||||
case(InternalState::STATE_FIRST_CONTACT): {
|
||||
*id = MGMLIS3MDL::IDENTIFY_DEVICE;
|
||||
break;
|
||||
case (InternalState::STATE_FIRST_CONTACT): {
|
||||
*id = MGMLIS3MDL::IDENTIFY_DEVICE;
|
||||
break;
|
||||
}
|
||||
case(InternalState::STATE_SETUP): {
|
||||
*id = MGMLIS3MDL::SETUP_MGM;
|
||||
break;
|
||||
case (InternalState::STATE_SETUP): {
|
||||
*id = MGMLIS3MDL::SETUP_MGM;
|
||||
break;
|
||||
}
|
||||
case(InternalState::STATE_CHECK_REGISTERS): {
|
||||
*id = MGMLIS3MDL::READ_CONFIG_AND_DATA;
|
||||
break;
|
||||
case (InternalState::STATE_CHECK_REGISTERS): {
|
||||
*id = MGMLIS3MDL::READ_CONFIG_AND_DATA;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
/* might be a configuration error. */
|
||||
/* might be a configuration error. */
|
||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||
sif::warning << "GyroHandler::buildTransitionDeviceCommand: Unknown internal state!" <<
|
||||
std::endl;
|
||||
sif::warning << "GyroHandler::buildTransitionDeviceCommand: Unknown internal state!"
|
||||
<< std::endl;
|
||||
#else
|
||||
sif::printWarning("GyroHandler::buildTransitionDeviceCommand: Unknown internal state!\n");
|
||||
sif::printWarning("GyroHandler::buildTransitionDeviceCommand: Unknown internal state!\n");
|
||||
#endif /* FSFW_CPP_OSTREAM_ENABLED == 1 */
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
return HasReturnvaluesIF::RETURN_OK;
|
||||
}
|
||||
|
||||
}
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
}
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
}
|
||||
|
||||
uint8_t MgmLIS3MDLHandler::readCommand(uint8_t command, bool continuousCom) {
|
||||
command |= (1 << MGMLIS3MDL::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
command |= (1 << MGMLIS3MDL::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
command |= (1 << MGMLIS3MDL::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
command |= (1 << MGMLIS3MDL::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
uint8_t MgmLIS3MDLHandler::writeCommand(uint8_t command, bool continuousCom) {
|
||||
command &= ~(1 << MGMLIS3MDL::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
command |= (1 << MGMLIS3MDL::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
command &= ~(1 << MGMLIS3MDL::RW_BIT);
|
||||
if (continuousCom == true) {
|
||||
command |= (1 << MGMLIS3MDL::MS_BIT);
|
||||
}
|
||||
return command;
|
||||
}
|
||||
|
||||
void MgmLIS3MDLHandler::setupMgm() {
|
||||
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
|
||||
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
|
||||
registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT;
|
||||
registers[3] = MGMLIS3MDL::CTRL_REG4_DEFAULT;
|
||||
registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT;
|
||||
|
||||
registers[0] = MGMLIS3MDL::CTRL_REG1_DEFAULT;
|
||||
registers[1] = MGMLIS3MDL::CTRL_REG2_DEFAULT;
|
||||
registers[2] = MGMLIS3MDL::CTRL_REG3_DEFAULT;
|
||||
registers[3] = MGMLIS3MDL::CTRL_REG4_DEFAULT;
|
||||
registers[4] = MGMLIS3MDL::CTRL_REG5_DEFAULT;
|
||||
|
||||
prepareCtrlRegisterWrite();
|
||||
prepareCtrlRegisterWrite();
|
||||
}
|
||||
|
||||
ReturnValue_t MgmLIS3MDLHandler::buildNormalDeviceCommand(
|
||||
DeviceCommandId_t *id) {
|
||||
// Data/config register will be read in an alternating manner.
|
||||
if(communicationStep == CommunicationStep::DATA) {
|
||||
*id = MGMLIS3MDL::READ_CONFIG_AND_DATA;
|
||||
communicationStep = CommunicationStep::TEMPERATURE;
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
}
|
||||
else {
|
||||
*id = MGMLIS3MDL::READ_TEMPERATURE;
|
||||
communicationStep = CommunicationStep::DATA;
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
}
|
||||
|
||||
ReturnValue_t MgmLIS3MDLHandler::buildNormalDeviceCommand(DeviceCommandId_t *id) {
|
||||
// Data/config register will be read in an alternating manner.
|
||||
if (communicationStep == CommunicationStep::DATA) {
|
||||
*id = MGMLIS3MDL::READ_CONFIG_AND_DATA;
|
||||
communicationStep = CommunicationStep::TEMPERATURE;
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
} else {
|
||||
*id = MGMLIS3MDL::READ_TEMPERATURE;
|
||||
communicationStep = CommunicationStep::DATA;
|
||||
return buildCommandFromCommand(*id, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
ReturnValue_t MgmLIS3MDLHandler::buildCommandFromCommand(
|
||||
DeviceCommandId_t deviceCommand, const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
switch(deviceCommand) {
|
||||
case(MGMLIS3MDL::READ_CONFIG_AND_DATA): {
|
||||
std::memset(commandBuffer, 0, sizeof(commandBuffer));
|
||||
commandBuffer[0] = readCommand(MGMLIS3MDL::CTRL_REG1, true);
|
||||
ReturnValue_t MgmLIS3MDLHandler::buildCommandFromCommand(DeviceCommandId_t deviceCommand,
|
||||
const uint8_t *commandData,
|
||||
size_t commandDataLen) {
|
||||
switch (deviceCommand) {
|
||||
case (MGMLIS3MDL::READ_CONFIG_AND_DATA): {
|
||||
std::memset(commandBuffer, 0, sizeof(commandBuffer));
|
||||
commandBuffer[0] = readCommand(MGMLIS3MDL::CTRL_REG1, true);
|
||||
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = MGMLIS3MDL::NR_OF_DATA_AND_CFG_REGISTERS + 1;
|
||||
return RETURN_OK;
|
||||
rawPacket = commandBuffer;
|
||||
rawPacketLen = MGMLIS3MDL: |