diff --git a/linux/uart/UartComIF.cpp b/linux/uart/UartComIF.cpp index 3f389df..d0a78ee 100644 --- a/linux/uart/UartComIF.cpp +++ b/linux/uart/UartComIF.cpp @@ -1,6 +1,7 @@ #include "UartComIF.h" +#include "OBSWConfig.h" -#include +#include "fsfw/serviceinterface/ServiceInterface.h" #include #include @@ -13,14 +14,14 @@ UartComIF::UartComIF(object_id_t objectId): SystemObject(objectId){ UartComIF::~UartComIF() {} -ReturnValue_t UartComIF::initializeInterface(CookieIF * cookie) { +ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) { - std::string deviceFile; - UartDeviceMapIter uartDeviceMapIter; + std::string deviceFile; + UartDeviceMapIter uartDeviceMapIter; - if(cookie == nullptr) { - return NULLPOINTER; - } + if(cookie == nullptr) { + return NULLPOINTER; + } UartCookie* uartCookie = dynamic_cast(cookie); if (uartCookie == nullptr) { @@ -31,45 +32,45 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF * cookie) { deviceFile = uartCookie->getDeviceFile(); uartDeviceMapIter = uartDeviceMap.find(deviceFile); - if(uartDeviceMapIter == uartDeviceMap.end()) { - int fileDescriptor = configureUartPort(uartCookie); - if (fileDescriptor < 0) { - return RETURN_FAILED; - } - size_t maxReplyLen = uartCookie->getMaxReplyLen(); - UartElements_t uartElements = {fileDescriptor, std::vector(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; + if(uartDeviceMapIter == uartDeviceMap.end()) { + int fileDescriptor = configureUartPort(uartCookie); + if (fileDescriptor < 0) { return RETURN_FAILED; } - } - else { - sif::debug << "UartComIF::initializeInterface: UART device " << deviceFile << " already in " - << "use" << std::endl; - return RETURN_FAILED; - } + size_t maxReplyLen = uartCookie->getMaxReplyLen(); + UartElements uartElements = {fileDescriptor, std::vector(maxReplyLen), 0}; + auto status = uartDeviceMap.emplace(deviceFile, uartElements); + if (status.second == false) { + 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) { - struct termios options; + struct termios options = {}; std::string deviceFile = uartCookie->getDeviceFile(); int fd = open(deviceFile.c_str(), O_RDWR); if (fd < 0) { - sif::debug << "UartComIF::configureUartPort: Failed to open uart " << deviceFile << "with" - << " error code " << errno << strerror(errno) << std::endl; + sif::warning << "UartComIF::configureUartPort: Failed to open uart " << deviceFile << + "with error code " << errno << strerror(errno) << std::endl; return fd; } /* Read in existing settings */ 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; return fd; } @@ -78,6 +79,9 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) { setStopBitOptions(&options, uartCookie); setDatasizeOptions(&options, uartCookie); setFixedOptions(&options); + if(uartCookie->getInputShouldBeFlushed()) { + tcflush(fd, TCIFLUSH); + } /* Sets uart to non-blocking mode. Read returns immediately when there are no data available */ options.c_cc[VTIME] = 0; @@ -87,8 +91,8 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) { /* Save option settings */ if (tcsetattr(fd, TCSANOW, &options) != 0) { - sif::debug << "UartComIF::configureUartPort: Failed to set options with error " << errno - << ": " << strerror(errno); + sif::warning << "UartComIF::configureUartPort: Failed to set options with error " << + errno << ": " << strerror(errno); return fd; } return fd; @@ -140,7 +144,7 @@ void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCook options->c_cflag |= CS8; break; default: - sif::debug << "UartComIF::setDatasizeOptions: Invalid size specified" << std::endl; + sif::warning << "UartComIF::setDatasizeOptions: Invalid size specified" << std::endl; break; } } @@ -150,8 +154,6 @@ void UartComIF::setFixedOptions(struct termios* options) { options->c_cflag &= ~CRTSCTS; /* Turn on READ & ignore ctrl lines (CLOCAL = 1) */ options->c_cflag |= CREAD | CLOCAL; - /* Disable canonical mode */ - options->c_lflag &= ~ICANON; /* Disable echo */ options->c_lflag &= ~ECHO; /* Disable erasure */ @@ -257,55 +259,51 @@ void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCooki ReturnValue_t UartComIF::sendMessage(CookieIF *cookie, 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(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; std::string deviceFile; 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(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) { return RETURN_OK; @@ -317,6 +315,7 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, return NULLPOINTER; } + UartModes uartMode = uartCookie->getUartMode(); deviceFile = uartCookie->getDeviceFile(); uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter == uartDeviceMap.end()) { @@ -325,46 +324,135 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF *cookie, return RETURN_FAILED; } - fd = uartDeviceMapIter->second.fileDescriptor; - bufferPtr = uartDeviceMapIter->second.replyBuffer.data(); + if (uartMode == UartModes::CANONICAL) { + 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(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); - if (bytesRead != static_cast(requestLen)) { - sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead - << " of " << requestLen << " bytes" << std::endl; + if (bytesRead < 0) { + return RETURN_FAILED; + } + else if (bytesRead != static_cast(requestLen)) { + sif::debug << "UartComIF::requestReceiveMessage: Only read " << bytesRead << + " of " << requestLen << " bytes" << std::endl; return RETURN_FAILED; } else { - uartDeviceMapIter->second.replyLen = bytesRead; + iter->second.replyLen = bytesRead; } - - return RETURN_OK; + return HasReturnvaluesIF::RETURN_OK; } ReturnValue_t UartComIF::readReceivedMessage(CookieIF *cookie, - uint8_t **buffer, size_t* size) { + uint8_t **buffer, size_t* size) { std::string deviceFile; UartDeviceMapIter uartDeviceMapIter; UartCookie* uartCookie = dynamic_cast(cookie); - if(uartCookie == nullptr) { + if(uartCookie == nullptr) { sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl; - return NULLPOINTER; - } + return NULLPOINTER; + } - deviceFile = uartCookie->getDeviceFile(); + deviceFile = uartCookie->getDeviceFile(); uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter == uartDeviceMap.end()) { - sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile - << " not in uart map" << std::endl; + sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile << + " not in uart map" << std::endl; return RETURN_FAILED; } - *buffer = uartDeviceMapIter->second.replyBuffer.data(); - *size = uartDeviceMapIter->second.replyLen; + *buffer = uartDeviceMapIter->second.replyBuffer.data(); + *size = uartDeviceMapIter->second.replyLen; - /* Length is reset to 0 to prevent reading the same data twice */ - uartDeviceMapIter->second.replyLen = 0; + /* Length is reset to 0 to prevent reading the same data twice */ + 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; + } } diff --git a/linux/uart/UartComIF.h b/linux/uart/UartComIF.h index 9dd854d..e513aa8 100644 --- a/linux/uart/UartComIF.h +++ b/linux/uart/UartComIF.h @@ -1,14 +1,13 @@ #ifndef BSP_Q7S_COMIF_UARTCOMIF_H_ #define BSP_Q7S_COMIF_UARTCOMIF_H_ +#include "UartCookie.h" #include #include #include #include -#include "UartCookie.h" - /** * @brief This is the communication interface to access serial ports on linux based operating * systems. @@ -20,75 +19,92 @@ */ class UartComIF: public DeviceCommunicationIF, public SystemObject { 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; - ReturnValue_t sendMessage(CookieIF *cookie,const uint8_t *sendData, - size_t sendLen) override; - ReturnValue_t getSendSuccess(CookieIF *cookie) override; - ReturnValue_t requestReceiveMessage(CookieIF *cookie, - size_t requestLen) override; - ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, - size_t *size) override; + UartComIF(object_id_t objectId); + + virtual ~UartComIF(); + + ReturnValue_t initializeInterface(CookieIF * cookie) override; + ReturnValue_t sendMessage(CookieIF *cookie,const uint8_t *sendData, + size_t sendLen) override; + ReturnValue_t getSendSuccess(CookieIF *cookie) override; + ReturnValue_t requestReceiveMessage(CookieIF *cookie, + size_t requestLen) override; + ReturnValue_t readReceivedMessage(CookieIF *cookie, uint8_t **buffer, + size_t *size) override; private: - using UartDeviceFile_t = std::string; + using UartDeviceFile_t = std::string; - typedef struct UartElements { - int fileDescriptor; - std::vector replyBuffer; - /** Number of bytes read will be written to this variable */ - size_t replyLen; - } UartElements_t; + struct UartElements { + int fileDescriptor; + std::vector replyBuffer; + /** Number of bytes read will be written to this variable */ + size_t replyLen; + }; - using UartDeviceMap = std::unordered_map; - using UartDeviceMapIter = UartDeviceMap::iterator; + using UartDeviceMap = std::unordered_map; + using UartDeviceMapIter = UartDeviceMap::iterator; - /** - * The uart devie map stores informations of initialized uart ports. - */ - UartDeviceMap uartDeviceMap; + /** + * The uart devie map stores informations of initialized uart ports. + */ + UartDeviceMap uartDeviceMap; - /** - * @brief This function opens and configures a uart device by using the information stored - * in the uart cookie. - * @param uartCookie Pointer to uart cookie with information about the uart. Contains the - * uart device file, baudrate, parity, stopbits etc. - * @return The file descriptor of the configured uart. - */ - int configureUartPort(UartCookie* uartCookie); + /** + * @brief This function opens and configures a uart device by using the information stored + * in the uart cookie. + * @param uartCookie Pointer to uart cookie with information about the uart. Contains the + * uart device file, baudrate, parity, stopbits etc. + * @return The file descriptor of the configured uart. + */ + int configureUartPort(UartCookie* uartCookie); - /** - * @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 - * parity checking. - * @param uartCookie Pointer to uart cookie containing the information about the desired - * parity settings. - * - */ - void setParityOptions(struct termios* options, UartCookie* uartCookie); + /** + * @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 + * parity checking. + * @param uartCookie Pointer to uart cookie containing the information about the desired + * parity settings. + * + */ + 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. - */ - void setFixedOptions(struct termios* options); + /** + * @brief This function sets options which are not configurable by the uartCookie. + */ + void setFixedOptions(struct termios* options); - /** - * @brief With this function the datasize settings are added to the termios options struct. - */ - void setDatasizeOptions(struct termios* options, UartCookie* uartCookie); + /** + * @brief With this function the datasize settings are added to the termios options struct. + */ + 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_ */ diff --git a/linux/uart/UartCookie.cpp b/linux/uart/UartCookie.cpp index b814938..bfd815e 100644 --- a/linux/uart/UartCookie.cpp +++ b/linux/uart/UartCookie.cpp @@ -2,22 +2,24 @@ #include -UartCookie::UartCookie(std::string deviceFile, uint32_t baudrate, size_t maxReplyLen) : - deviceFile(deviceFile), baudrate(baudrate), maxReplyLen(maxReplyLen) { +UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, + uint32_t baudrate, size_t maxReplyLen): + handlerId(handlerId), deviceFile(deviceFile), uartMode(uartMode), baudrate(baudrate), + maxReplyLen(maxReplyLen) { } UartCookie::~UartCookie() {} uint32_t UartCookie::getBaudrate() const { - return baudrate; + return baudrate; } size_t UartCookie::getMaxReplyLen() const { - return maxReplyLen; + return maxReplyLen; } std::string UartCookie::getDeviceFile() const { - return deviceFile; + return deviceFile; } void UartCookie::setParityOdd() { @@ -61,3 +63,27 @@ void UartCookie::setTwoStopBits() { void UartCookie::setOneStopBit() { 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; +} diff --git a/linux/uart/UartCookie.h b/linux/uart/UartCookie.h index 5900471..69f59a5 100644 --- a/linux/uart/UartCookie.h +++ b/linux/uart/UartCookie.h @@ -2,6 +2,8 @@ #define SAM9G20_COMIF_COOKIES_UART_COOKIE_H_ #include +#include + #include enum class Parity { @@ -15,8 +17,13 @@ enum class StopBits { 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 * be set by member functions. * @@ -25,57 +32,81 @@ enum class StopBits { class UartCookie: public CookieIF { public: - /** - * @brief Constructor for the uart cookie. - * @param deviceFile The device file specifying the uart to use. E.g. "/dev/ttyPS1". + /** + * @brief Constructor for the uart cookie. + * @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, * 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, B19200, * 38400, 57600, 115200, 230400, 460800 - * @param maxReplyLen The maximum size an object using this cookie expects. - * - * @details Default configuration: No parity - * 8 databits (number of bits transfered with one uart frame) - * One stop bit - * - * - */ - UartCookie(std::string deviceFile, uint32_t baudrate, size_t maxReplyLen); + * @param maxReplyLen The maximum size an object using this cookie expects + * @details + * Default configuration: No parity + * 8 databits (number of bits transfered with one uart frame) + * One stop bit + */ + UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, + uint32_t baudrate, size_t maxReplyLen); - virtual ~UartCookie(); + virtual ~UartCookie(); - uint32_t getBaudrate() const; - size_t getMaxReplyLen() const; - std::string getDeviceFile() const; - Parity getParity() const; - uint8_t getBitsPerWord() const; - StopBits getStopBits() const; + uint32_t getBaudrate() const; + size_t getMaxReplyLen() const; + std::string getDeviceFile() const; + Parity getParity() const; + uint8_t getBitsPerWord() const; + StopBits getStopBits() const; + UartModes getUartMode() const; + object_id_t getHandlerId() const; - /** - * Functions two enable parity checking. - */ - void setParityOdd(); + /** + * 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 + * 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(); /** * Function two set number of bits per UART frame. */ - void setBitsPerWord(uint8_t bitsPerWord_); - - /** - * Function to specify the number of stopbits. - */ - void setTwoStopBits(); - void setOneStopBit(); + void setBitsPerWord(uint8_t bitsPerWord_); + /** + * Function to specify the number of stopbits. + */ + void setTwoStopBits(); + void setOneStopBit(); private: - std::string deviceFile; - uint32_t baudrate; - size_t maxReplyLen = 0; - Parity parity = Parity::NONE; - uint8_t bitsPerWord = 8; - StopBits stopBits = StopBits::ONE_STOP_BIT; + const object_id_t handlerId; + std::string deviceFile; + const UartModes uartMode; + bool flushInput = false; + uint32_t baudrate; + size_t maxReplyLen = 0; + Parity parity = Parity::NONE; + uint8_t bitsPerWord = 8; + uint8_t readCycles = 1; + StopBits stopBits = StopBits::ONE_STOP_BIT; }; #endif diff --git a/stm32h7/devicetest/GyroL3GD20H.cpp b/stm32h7/devicetest/GyroL3GD20H.cpp index 7abdd5f..c500c3b 100644 --- a/stm32h7/devicetest/GyroL3GD20H.cpp +++ b/stm32h7/devicetest/GyroL3GD20H.cpp @@ -28,6 +28,7 @@ GyroL3GD20H::GyroL3GD20H(SPI_HandleTypeDef *spiHandle, spi::TransferModes transf txDmaHandle = new DMA_HandleTypeDef(); rxDmaHandle = new DMA_HandleTypeDef(); spi::setSpiHandle(spiHandle); + spi::assignSpiUserArgs(spi::SpiBus::SPI_1, spiHandle); transferMode = transferMode_; if(transferMode == spi::TransferModes::DMA) { mspCfg = new spi::MspDmaConfigStruct();