Merge branch 'master' into meier/master

This commit is contained in:
Jakob Meier 2021-06-21 17:00:35 +02:00
commit 8fe5d0afa0
5 changed files with 361 additions and 199 deletions

View File

@ -1,6 +1,7 @@
#include "UartComIF.h" #include "UartComIF.h"
#include "OBSWConfig.h"
#include <fsfw/serviceinterface/ServiceInterface.h> #include "fsfw/serviceinterface/ServiceInterface.h"
#include <cstring> #include <cstring>
#include <fcntl.h> #include <fcntl.h>
@ -13,14 +14,14 @@ UartComIF::UartComIF(object_id_t objectId): SystemObject(objectId){
UartComIF::~UartComIF() {} UartComIF::~UartComIF() {}
ReturnValue_t UartComIF::initializeInterface(CookieIF * cookie) { ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) {
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; UartDeviceMapIter uartDeviceMapIter;
if(cookie == nullptr) { if(cookie == nullptr) {
return NULLPOINTER; return NULLPOINTER;
} }
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie); UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
if (uartCookie == nullptr) { if (uartCookie == nullptr) {
@ -31,45 +32,45 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF * cookie) {
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if(uartDeviceMapIter == uartDeviceMap.end()) { if(uartDeviceMapIter == uartDeviceMap.end()) {
int fileDescriptor = configureUartPort(uartCookie); int fileDescriptor = configureUartPort(uartCookie);
if (fileDescriptor < 0) { if (fileDescriptor < 0) {
return RETURN_FAILED;
}
size_t maxReplyLen = uartCookie->getMaxReplyLen();
UartElements_t uartElements = {fileDescriptor, std::vector<uint8_t>(maxReplyLen), 0};
auto status = uartDeviceMap.emplace(deviceFile, uartElements);
if (status.second == false) {
sif::debug << "UartComIF::initializeInterface: Failed to insert device " << deviceFile
<< "to UART device map" << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
} size_t maxReplyLen = uartCookie->getMaxReplyLen();
else { UartElements uartElements = {fileDescriptor, std::vector<uint8_t>(maxReplyLen), 0};
sif::debug << "UartComIF::initializeInterface: UART device " << deviceFile << " already in " auto status = uartDeviceMap.emplace(deviceFile, uartElements);
<< "use" << std::endl; if (status.second == false) {
return RETURN_FAILED; sif::warning << "UartComIF::initializeInterface: Failed to insert device " <<
} deviceFile << "to UART device map" << std::endl;
return RETURN_FAILED;
}
}
else {
sif::warning << "UartComIF::initializeInterface: UART device " << deviceFile <<
" already in use" << std::endl;
return RETURN_FAILED;
}
return RETURN_OK; return RETURN_OK;
} }
int UartComIF::configureUartPort(UartCookie* uartCookie) { int UartComIF::configureUartPort(UartCookie* uartCookie) {
struct termios options; struct termios options = {};
std::string deviceFile = uartCookie->getDeviceFile(); std::string deviceFile = uartCookie->getDeviceFile();
int fd = open(deviceFile.c_str(), O_RDWR); int fd = open(deviceFile.c_str(), O_RDWR);
if (fd < 0) { if (fd < 0) {
sif::debug << "UartComIF::configureUartPort: Failed to open uart " << deviceFile << "with" sif::warning << "UartComIF::configureUartPort: Failed to open uart " << deviceFile <<
<< " error code " << errno << strerror(errno) << std::endl; "with error code " << errno << strerror(errno) << std::endl;
return fd; return fd;
} }
/* Read in existing settings */ /* Read in existing settings */
if(tcgetattr(fd, &options) != 0) { if(tcgetattr(fd, &options) != 0) {
sif::debug << "UartComIF::configureUartPort: Error " << errno << "from tcgetattr: " sif::warning << "UartComIF::configureUartPort: Error " << errno << "from tcgetattr: "
<< strerror(errno) << std::endl; << strerror(errno) << std::endl;
return fd; return fd;
} }
@ -78,6 +79,9 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
setStopBitOptions(&options, uartCookie); setStopBitOptions(&options, uartCookie);
setDatasizeOptions(&options, uartCookie); setDatasizeOptions(&options, uartCookie);
setFixedOptions(&options); setFixedOptions(&options);
if(uartCookie->getInputShouldBeFlushed()) {
tcflush(fd, TCIFLUSH);
}
/* Sets uart to non-blocking mode. Read returns immediately when there are no data available */ /* Sets uart to non-blocking mode. Read returns immediately when there are no data available */
options.c_cc[VTIME] = 0; options.c_cc[VTIME] = 0;
@ -87,8 +91,8 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) {
/* Save option settings */ /* Save option settings */
if (tcsetattr(fd, TCSANOW, &options) != 0) { if (tcsetattr(fd, TCSANOW, &options) != 0) {
sif::debug << "UartComIF::configureUartPort: Failed to set options with error " << errno sif::warning << "UartComIF::configureUartPort: Failed to set options with error " <<
<< ": " << strerror(errno); errno << ": " << strerror(errno);
return fd; return fd;
} }
return fd; return fd;
@ -140,7 +144,7 @@ void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCook
options->c_cflag |= CS8; options->c_cflag |= CS8;
break; break;
default: default:
sif::debug << "UartComIF::setDatasizeOptions: Invalid size specified" << std::endl; sif::warning << "UartComIF::setDatasizeOptions: Invalid size specified" << std::endl;
break; break;
} }
} }
@ -150,8 +154,6 @@ void UartComIF::setFixedOptions(struct termios* options) {
options->c_cflag &= ~CRTSCTS; options->c_cflag &= ~CRTSCTS;
/* Turn on READ & ignore ctrl lines (CLOCAL = 1) */ /* Turn on READ & ignore ctrl lines (CLOCAL = 1) */
options->c_cflag |= CREAD | CLOCAL; options->c_cflag |= CREAD | CLOCAL;
/* Disable canonical mode */
options->c_lflag &= ~ICANON;
/* Disable echo */ /* Disable echo */
options->c_lflag &= ~ECHO; options->c_lflag &= ~ECHO;
/* Disable erasure */ /* Disable erasure */
@ -257,55 +259,51 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki
ReturnValue_t UartComIF::sendMessage(CookieIF *cookie, ReturnValue_t UartComIF::sendMessage(CookieIF *cookie,
const uint8_t *sendData, size_t sendLen) { const uint8_t *sendData, size_t sendLen) {
int fd = 0;
std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter;
if(sendData == nullptr) {
sif::debug << "UartComIF::sendMessage: Send Data is nullptr" << std::endl;
return RETURN_FAILED;
}
if(sendLen == 0) {
return RETURN_OK;
}
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
if(uartCookie == nullptr) {
sif::debug << "UartComIF::sendMessasge: Invalid Uart Cookie!" << std::endl;
return NULLPOINTER;
}
deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter == uartDeviceMap.end()) {
sif::debug << "UartComIF::sendMessage: Device file " << deviceFile << "not in uart map"
<< std::endl;
return RETURN_FAILED;
}
fd = uartDeviceMapIter->second.fileDescriptor;
if (write(fd, sendData, sendLen) != (int)sendLen) {
sif::error << "UartComIF::sendMessage: Failed to send data with error code " << errno
<< ": Error description: " << strerror(errno) << std::endl;
return RETURN_FAILED;
}
return RETURN_OK;
}
ReturnValue_t UartComIF::getSendSuccess(CookieIF *cookie) {
return RETURN_OK;
}
ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie,
size_t requestLen) {
int fd = 0; int fd = 0;
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; UartDeviceMapIter uartDeviceMapIter;
uint8_t* bufferPtr;
if(sendData == nullptr) {
sif::debug << "UartComIF::sendMessage: Send Data is nullptr" << std::endl;
return RETURN_FAILED;
}
if(sendLen == 0) {
return RETURN_OK;
}
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
if(uartCookie == nullptr) {
sif::debug << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl;
return NULLPOINTER;
}
deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter == uartDeviceMap.end()) {
sif::debug << "UartComIF::sendMessage: Device file " << deviceFile <<
"not in UART map" << std::endl;
return RETURN_FAILED;
}
fd = uartDeviceMapIter->second.fileDescriptor;
if (write(fd, sendData, sendLen) != (int)sendLen) {
sif::error << "UartComIF::sendMessage: Failed to send data with error code " <<
errno << ": Error description: " << strerror(errno) << std::endl;
return RETURN_FAILED;
}
return RETURN_OK;
}
ReturnValue_t UartComIF::getSendSuccess(CookieIF *cookie) {
return RETURN_OK;
}
ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, size_t requestLen) {
std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter;
if(requestLen == 0) { if(requestLen == 0) {
return RETURN_OK; return RETURN_OK;
@ -317,6 +315,7 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie,
return NULLPOINTER; return NULLPOINTER;
} }
UartModes uartMode = uartCookie->getUartMode();
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter == uartDeviceMap.end()) { if (uartDeviceMapIter == uartDeviceMap.end()) {
@ -325,46 +324,135 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie,
return RETURN_FAILED; return RETURN_FAILED;
} }
fd = uartDeviceMapIter->second.fileDescriptor; if (uartMode == UartModes::CANONICAL) {
bufferPtr = uartDeviceMapIter->second.replyBuffer.data(); return handleCanonicalRead(*uartCookie, uartDeviceMapIter, requestLen);
}
else if (uartMode == UartModes::NON_CANONICAL) {
return handleNoncanonicalRead(*uartCookie, uartDeviceMapIter, requestLen);
}
else {
return HasReturnvaluesIF::RETURN_FAILED;
}
}
ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
size_t requestLen) {
ReturnValue_t result = HasReturnvaluesIF::RETURN_OK;
uint8_t maxReadCycles = uartCookie.getReadCycles();
uint8_t currentReadCycles = 0;
int bytesRead = 0;
size_t currentBytesRead = 0;
size_t maxReplySize = uartCookie.getMaxReplyLen();
int fd = iter->second.fileDescriptor;
auto bufferPtr = iter->second.replyBuffer.data();
do {
size_t allowedReadSize = 0;
if(currentBytesRead >= maxReplySize) {
// Overflow risk. Emit warning, trigger event and break. If this happens,
// the reception buffer is not large enough or data is not polled often enough.
#if OBSW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!"
<< std::endl;
#else
sif::printWarning("UartComIF::requestReceiveMessage: "
"Next read would cause overflow!");
#endif
#endif
result = UART_RX_BUFFER_TOO_SMALL;
break;
}
else {
allowedReadSize = maxReplySize - currentBytesRead;
}
bytesRead = read(fd, bufferPtr, allowedReadSize);
if (bytesRead < 0) {
return RETURN_FAILED;
}
else if (bytesRead != static_cast<int>(requestLen)) {
sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead <<
" of " << requestLen << " bytes" << std::endl;
return RETURN_FAILED;
}
else if(bytesRead > 0) {
iter->second.replyLen += bytesRead;
bufferPtr += bytesRead;
currentBytesRead += bytesRead;
}
currentReadCycles++;
} while(bytesRead > 0 and currentReadCycles < maxReadCycles);
return result;
}
ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie &uartCookie, UartDeviceMapIter &iter,
size_t requestLen) {
int fd = iter->second.fileDescriptor;
auto bufferPtr = iter->second.replyBuffer.data();
// Size check to prevent buffer overflow
if(requestLen > uartCookie.getMaxReplyLen()) {
#if OBSW_VERBOSE_LEVEL >= 1
#if FSFW_CPP_OSTREAM_ENABLED == 1
sif::warning << "UartComIF::requestReceiveMessage: Next read would cause overflow!"
<< std::endl;
#else
sif::printWarning("UartComIF::requestReceiveMessage: "
"Next read would cause overflow!");
#endif
#endif
return UART_RX_BUFFER_TOO_SMALL;
}
int bytesRead = read(fd, bufferPtr, requestLen); int bytesRead = read(fd, bufferPtr, requestLen);
if (bytesRead != static_cast<int>(requestLen)) { if (bytesRead < 0) {
sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead return RETURN_FAILED;
<< " of " << requestLen << " bytes" << std::endl; }
else if (bytesRead != static_cast<int>(requestLen)) {
sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead <<
" of " << requestLen << " bytes" << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
else { else {
uartDeviceMapIter->second.replyLen = bytesRead; iter->second.replyLen = bytesRead;
} }
return HasReturnvaluesIF::RETURN_OK;
return RETURN_OK;
} }
ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie, ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie,
uint8_t **buffer, size_t* size) { uint8_t **buffer, size_t* size) {
std::string deviceFile; std::string deviceFile;
UartDeviceMapIter uartDeviceMapIter; UartDeviceMapIter uartDeviceMapIter;
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie); UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
if(uartCookie == nullptr) { if(uartCookie == nullptr) {
sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl; sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl;
return NULLPOINTER; return NULLPOINTER;
} }
deviceFile = uartCookie->getDeviceFile(); deviceFile = uartCookie->getDeviceFile();
uartDeviceMapIter = uartDeviceMap.find(deviceFile); uartDeviceMapIter = uartDeviceMap.find(deviceFile);
if (uartDeviceMapIter == uartDeviceMap.end()) { if (uartDeviceMapIter == uartDeviceMap.end()) {
sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile <<
<< " not in uart map" << std::endl; " not in uart map" << std::endl;
return RETURN_FAILED; return RETURN_FAILED;
} }
*buffer = uartDeviceMapIter->second.replyBuffer.data(); *buffer = uartDeviceMapIter->second.replyBuffer.data();
*size = uartDeviceMapIter->second.replyLen; *size = uartDeviceMapIter->second.replyLen;
/* Length is reset to 0 to prevent reading the same data twice */ /* Length is reset to 0 to prevent reading the same data twice */
uartDeviceMapIter->second.replyLen = 0; uartDeviceMapIter->second.replyLen = 0;
return RETURN_OK; return RETURN_OK;
}
void UartComIF::setUartMode(struct termios *options, UartCookie &uartCookie) {
UartModes uartMode = uartCookie.getUartMode();
if(uartMode == UartModes::NON_CANONICAL) {
/* Disable canonical mode */
options->c_lflag &= ~ICANON;
}
else if(uartMode == UartModes::CANONICAL) {
options->c_lflag |= ICANON;
}
} }

View File

@ -1,14 +1,13 @@
#ifndef BSP_Q7S_COMIF_UARTCOMIF_H_ #ifndef BSP_Q7S_COMIF_UARTCOMIF_H_
#define BSP_Q7S_COMIF_UARTCOMIF_H_ #define BSP_Q7S_COMIF_UARTCOMIF_H_
#include "UartCookie.h"
#include <fsfw/objectmanager/SystemObject.h> #include <fsfw/objectmanager/SystemObject.h>
#include <fsfw/devicehandlers/DeviceCommunicationIF.h> #include <fsfw/devicehandlers/DeviceCommunicationIF.h>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "UartCookie.h"
/** /**
* @brief This is the communication interface to access serial ports on linux based operating * @brief This is the communication interface to access serial ports on linux based operating
* systems. * systems.
@ -20,75 +19,92 @@
*/ */
class UartComIF: public DeviceCommunicationIF, public SystemObject { class UartComIF: public DeviceCommunicationIF, public SystemObject {
public: public:
UartComIF(object_id_t objectId); static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART;
virtual ~UartComIF(); static constexpr ReturnValue_t UART_READ_FAILURE =
HasReturnvaluesIF::makeReturnCode(uartRetvalId, 1);
static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH =
HasReturnvaluesIF::makeReturnCode(uartRetvalId, 2);
static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL =
HasReturnvaluesIF::makeReturnCode(uartRetvalId, 3);
ReturnValue_t initializeInterface(CookieIF * cookie) override; UartComIF(object_id_t objectId);
ReturnValue_t sendMessage(CookieIF *cookie,const uint8_t *sendData,
size_t sendLen) override; virtual ~UartComIF();
ReturnValue_t getSendSuccess(CookieIF *cookie) override;
ReturnValue_t requestReceiveMessage(CookieIF *cookie, ReturnValue_t initializeInterface(CookieIF * cookie) override;
size_t requestLen) override; ReturnValue_t sendMessage(CookieIF *cookie,const uint8_t *sendData,
ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, size_t sendLen) override;
size_t *size) 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;
private: private:
using UartDeviceFile_t = std::string; using UartDeviceFile_t = std::string;
typedef struct UartElements { struct UartElements {
int fileDescriptor; int fileDescriptor;
std::vector<uint8_t> replyBuffer; std::vector<uint8_t> replyBuffer;
/** Number of bytes read will be written to this variable */ /** Number of bytes read will be written to this variable */
size_t replyLen; size_t replyLen;
} UartElements_t; };
using UartDeviceMap = std::unordered_map<UartDeviceFile_t, UartElements_t>; using UartDeviceMap = std::unordered_map<UartDeviceFile_t, UartElements>;
using UartDeviceMapIter = UartDeviceMap::iterator; using UartDeviceMapIter = UartDeviceMap::iterator;
/** /**
* The uart devie map stores informations of initialized uart ports. * The uart devie map stores informations of initialized uart ports.
*/ */
UartDeviceMap uartDeviceMap; UartDeviceMap uartDeviceMap;
/** /**
* @brief This function opens and configures a uart device by using the information stored * @brief This function opens and configures a uart device by using the information stored
* in the uart cookie. * in the uart cookie.
* @param uartCookie Pointer to uart cookie with information about the uart. Contains the * @param uartCookie Pointer to uart cookie with information about the uart. Contains the
* uart device file, baudrate, parity, stopbits etc. * uart device file, baudrate, parity, stopbits etc.
* @return The file descriptor of the configured uart. * @return The file descriptor of the configured uart.
*/ */
int configureUartPort(UartCookie* uartCookie); int configureUartPort(UartCookie* uartCookie);
/** /**
* @brief This function adds the parity settings to the termios options struct. * @brief This function adds the parity settings to the termios options struct.
* *
* @param options Pointer to termios options struct which will be modified to enable or disable * @param options Pointer to termios options struct which will be modified to enable or disable
* parity checking. * parity checking.
* @param uartCookie Pointer to uart cookie containing the information about the desired * @param uartCookie Pointer to uart cookie containing the information about the desired
* parity settings. * parity settings.
* *
*/ */
void setParityOptions(struct termios* options, UartCookie* uartCookie); void setParityOptions(struct termios* options, UartCookie* uartCookie);
void setStopBitOptions(struct termios* options, UartCookie* uartCookie); void setStopBitOptions(struct termios* options, UartCookie* uartCookie);
/** /**
* @brief This function sets options which are not configurable by the uartCookie. * @brief This function sets options which are not configurable by the uartCookie.
*/ */
void setFixedOptions(struct termios* options); void setFixedOptions(struct termios* options);
/** /**
* @brief With this function the datasize settings are added to the termios options struct. * @brief With this function the datasize settings are added to the termios options struct.
*/ */
void setDatasizeOptions(struct termios* options, UartCookie* uartCookie); void setDatasizeOptions(struct termios* options, UartCookie* uartCookie);
/**
* @brief This functions adds the baudrate specified in the uartCookie to the termios options
* struct.
*/
void configureBaudrate(struct termios* options, UartCookie* uartCookie);
void setUartMode(struct termios* options, UartCookie& uartCookie);
ReturnValue_t handleCanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
size_t requestLen);
ReturnValue_t handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter,
size_t requestLen);
/**
* @brief This functions adds the baudrate specified in the uartCookie to the termios options
* struct.
*/
void configureBaudrate(struct termios* options, UartCookie* uartCookie);
}; };
#endif /* BSP_Q7S_COMIF_UARTCOMIF_H_ */ #endif /* BSP_Q7S_COMIF_UARTCOMIF_H_ */

View File

@ -2,22 +2,24 @@
#include <fsfw/serviceinterface/ServiceInterface.h> #include <fsfw/serviceinterface/ServiceInterface.h>
UartCookie::UartCookie(std::string deviceFile, uint32_t baudrate, size_t maxReplyLen) : UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
deviceFile(deviceFile), baudrate(baudrate), maxReplyLen(maxReplyLen) { uint32_t baudrate, size_t maxReplyLen):
handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate),
maxReplyLen(maxReplyLen) {
} }
UartCookie::~UartCookie() {} UartCookie::~UartCookie() {}
uint32_t UartCookie::getBaudrate() const { uint32_t UartCookie::getBaudrate() const {
return baudrate; return baudrate;
} }
size_t UartCookie::getMaxReplyLen() const { size_t UartCookie::getMaxReplyLen() const {
return maxReplyLen; return maxReplyLen;
} }
std::string UartCookie::getDeviceFile() const { std::string UartCookie::getDeviceFile() const {
return deviceFile; return deviceFile;
} }
void UartCookie::setParityOdd() { void UartCookie::setParityOdd() {
@ -61,3 +63,27 @@ void UartCookie::setTwoStopBits() {
void UartCookie::setOneStopBit() { void UartCookie::setOneStopBit() {
stopBits = StopBits::ONE_STOP_BIT; stopBits = StopBits::ONE_STOP_BIT;
} }
UartModes UartCookie::getUartMode() const {
return uartMode;
}
void UartCookie::setReadCycles(uint8_t readCycles) {
this->readCycles = readCycles;
}
void UartCookie::setToFlushInput(bool enable) {
this->flushInput = enable;
}
uint8_t UartCookie::getReadCycles() const {
return readCycles;
}
bool UartCookie::getInputShouldBeFlushed() {
return this->flushInput;
}
object_id_t UartCookie::getHandlerId() const {
return this->handlerId;
}

View File

@ -2,6 +2,8 @@
#define SAM9G20_COMIF_COOKIES_UART_COOKIE_H_ #define SAM9G20_COMIF_COOKIES_UART_COOKIE_H_
#include <fsfw/devicehandlers/CookieIF.h> #include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw/objectmanager/SystemObjectIF.h>
#include <string> #include <string>
enum class Parity { enum class Parity {
@ -15,8 +17,13 @@ enum class StopBits {
TWO_STOP_BITS TWO_STOP_BITS
}; };
enum class UartModes {
CANONICAL,
NON_CANONICAL
};
/** /**
* @brief Cookie for the UartComIF. There are many options available to configure the uart driver. * @brief Cookie for the UartComIF. There are many options available to configure the UART driver.
* The constructor only requests for common options like the baudrate. Other options can * The constructor only requests for common options like the baudrate. Other options can
* be set by member functions. * be set by member functions.
* *
@ -25,57 +32,81 @@ enum class StopBits {
class UartCookie: public CookieIF { class UartCookie: public CookieIF {
public: public:
/** /**
* @brief Constructor for the uart cookie. * @brief Constructor for the uart cookie.
* @param deviceFile The device file specifying the uart to use. E.g. "/dev/ttyPS1". * @param deviceFile The device file specifying the uart to use, e.g. "/dev/ttyPS1"
* @param uartMode Specify the UART mode. The canonical mode should be used if the
* messages are separated by a delimited character like '\n'. See the
* termios documentation for more information
* @param baudrate The baudrate to use for input and output. Possible Baudrates are: 50, * @param baudrate The baudrate to use for input and output. Possible Baudrates are: 50,
* 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, B19200, * 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, B19200,
* 38400, 57600, 115200, 230400, 460800 * 38400, 57600, 115200, 230400, 460800
* @param maxReplyLen The maximum size an object using this cookie expects. * @param maxReplyLen The maximum size an object using this cookie expects
* * @details
* @details Default configuration: No parity * Default configuration: No parity
* 8 databits (number of bits transfered with one uart frame) * 8 databits (number of bits transfered with one uart frame)
* One stop bit * One stop bit
* */
* UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode,
*/ uint32_t baudrate, size_t maxReplyLen);
UartCookie(std::string deviceFile, uint32_t baudrate, size_t maxReplyLen);
virtual ~UartCookie(); virtual ~UartCookie();
uint32_t getBaudrate() const; uint32_t getBaudrate() const;
size_t getMaxReplyLen() const; size_t getMaxReplyLen() const;
std::string getDeviceFile() const; std::string getDeviceFile() const;
Parity getParity() const; Parity getParity() const;
uint8_t getBitsPerWord() const; uint8_t getBitsPerWord() const;
StopBits getStopBits() const; StopBits getStopBits() const;
UartModes getUartMode() const;
object_id_t getHandlerId() const;
/** /**
* Functions two enable parity checking. * The UART ComIF will only perform a specified number of read cycles for the canonical mode.
*/ * The user can specify how many of those read cycles are performed for one device handler
void setParityOdd(); * communication cycle. An example use-case would be to read all available GPS NMEA strings
* at once.
* @param readCycles
*/
void setReadCycles(uint8_t readCycles);
uint8_t getReadCycles() const;
/**
* Allows to flush the data which was received but has not been read yet. This is useful
* to discard obsolete data at software startup.
*/
void setToFlushInput(bool enable);
bool getInputShouldBeFlushed();
/**
* Functions two enable parity checking.
*/
void setParityOdd();
void setParityEven(); void setParityEven();
/** /**
* Function two set number of bits per UART frame. * Function two set number of bits per UART frame.
*/ */
void setBitsPerWord(uint8_t bitsPerWord_); void setBitsPerWord(uint8_t bitsPerWord_);
/**
* Function to specify the number of stopbits.
*/
void setTwoStopBits();
void setOneStopBit();
/**
* Function to specify the number of stopbits.
*/
void setTwoStopBits();
void setOneStopBit();
private: private:
std::string deviceFile; const object_id_t handlerId;
uint32_t baudrate; std::string deviceFile;
size_t maxReplyLen = 0; const UartModes uartMode;
Parity parity = Parity::NONE; bool flushInput = false;
uint8_t bitsPerWord = 8; uint32_t baudrate;
StopBits stopBits = StopBits::ONE_STOP_BIT; size_t maxReplyLen = 0;
Parity parity = Parity::NONE;
uint8_t bitsPerWord = 8;
uint8_t readCycles = 1;
StopBits stopBits = StopBits::ONE_STOP_BIT;
}; };
#endif #endif

View File

@ -28,6 +28,7 @@ GyroL3GD20H::GyroL3GD20H(SPI_HandleTypeDef *spiHandle, spi::TransferModes transf
txDmaHandle = new DMA_HandleTypeDef(); txDmaHandle = new DMA_HandleTypeDef();
rxDmaHandle = new DMA_HandleTypeDef(); rxDmaHandle = new DMA_HandleTypeDef();
spi::setSpiHandle(spiHandle); spi::setSpiHandle(spiHandle);
spi::assignSpiUserArgs(spi::SpiBus::SPI_1, spiHandle);
transferMode = transferMode_; transferMode = transferMode_;
if(transferMode == spi::TransferModes::DMA) { if(transferMode == spi::TransferModes::DMA) {
mspCfg = new spi::MspDmaConfigStruct(); mspCfg = new spi::MspDmaConfigStruct();