diff --git a/CMakeLists.txt b/CMakeLists.txt index e2572b20..c847d47f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,6 +122,7 @@ if(UNIX) option(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS "Add Linux peripheral drivers" OFF) option(FSFW_HAL_LINUX_ADD_LIBGPIOD "Attempt to add Linux GPIOD drivers" OFF) + option(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS "Add serial drivers" ON) endif() # Optional sources diff --git a/src/fsfw_hal/linux/CMakeLists.txt b/src/fsfw_hal/linux/CMakeLists.txt index ffa5f5ee..d22d7ff1 100644 --- a/src/fsfw_hal/linux/CMakeLists.txt +++ b/src/fsfw_hal/linux/CMakeLists.txt @@ -5,11 +5,14 @@ endif() target_sources(${LIB_FSFW_NAME} PRIVATE UnixFileGuard.cpp CommandExecutor.cpp utility.cpp) +if(FSFW_HAL_LINUX_ADD_LIBGPIOD) + add_subdirectory(gpio) +endif() +if(FSFW_HAL_LINUX_ADD_SERIAL_DRIVERS) + add_subdirectory(serial) +endif() + if(FSFW_HAL_LINUX_ADD_PERIPHERAL_DRIVERS) - if(FSFW_HAL_LINUX_ADD_LIBGPIOD) - add_subdirectory(gpio) - endif() - add_subdirectory(uart) # Adding those does not really make sense on Apple systems which are generally # host systems. It won't even compile as the headers are missing if(NOT APPLE) diff --git a/src/fsfw_hal/linux/serial/CMakeLists.txt b/src/fsfw_hal/linux/serial/CMakeLists.txt new file mode 100644 index 00000000..07d20d29 --- /dev/null +++ b/src/fsfw_hal/linux/serial/CMakeLists.txt @@ -0,0 +1,2 @@ +target_sources(${LIB_FSFW_NAME} PUBLIC SerialComIF.cpp SerialCookie.cpp + helper.cpp) diff --git a/src/fsfw_hal/linux/uart/UartComIF.cpp b/src/fsfw_hal/linux/serial/SerialComIF.cpp similarity index 62% rename from src/fsfw_hal/linux/uart/UartComIF.cpp rename to src/fsfw_hal/linux/serial/SerialComIF.cpp index 8947c562..177d74e4 100644 --- a/src/fsfw_hal/linux/uart/UartComIF.cpp +++ b/src/fsfw_hal/linux/serial/SerialComIF.cpp @@ -1,4 +1,4 @@ -#include "UartComIF.h" +#include "SerialComIF.h" #include #include @@ -11,19 +11,18 @@ #include "fsfw/serviceinterface.h" #include "fsfw_hal/linux/utility.h" -UartComIF::UartComIF(object_id_t objectId) : SystemObject(objectId) {} +SerialComIF::SerialComIF(object_id_t objectId) : SystemObject(objectId) {} -UartComIF::~UartComIF() {} +SerialComIF::~SerialComIF() {} -ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) { +ReturnValue_t SerialComIF::initializeInterface(CookieIF* cookie) { std::string deviceFile; - UartDeviceMapIter uartDeviceMapIter; if (cookie == nullptr) { return NULLPOINTER; } - UartCookie* uartCookie = dynamic_cast(cookie); + SerialCookie* uartCookie = dynamic_cast(cookie); if (uartCookie == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::error << "UartComIF::initializeInterface: Invalid UART Cookie!" << std::endl; @@ -33,7 +32,7 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) { deviceFile = uartCookie->getDeviceFile(); - uartDeviceMapIter = uartDeviceMap.find(deviceFile); + auto uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter == uartDeviceMap.end()) { int fileDescriptor = configureUartPort(uartCookie); if (fileDescriptor < 0) { @@ -60,7 +59,7 @@ ReturnValue_t UartComIF::initializeInterface(CookieIF* cookie) { return returnvalue::OK; } -int UartComIF::configureUartPort(UartCookie* uartCookie) { +int SerialComIF::configureUartPort(SerialCookie* uartCookie) { struct termios options = {}; std::string deviceFile = uartCookie->getDeviceFile(); @@ -89,11 +88,11 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) { return fd; } - setParityOptions(&options, uartCookie); + uart::setParity(options, uartCookie->getParity()); setStopBitOptions(&options, uartCookie); setDatasizeOptions(&options, uartCookie); setFixedOptions(&options); - setUartMode(&options, *uartCookie); + uart::setMode(options, uartCookie->getUartMode()); if (uartCookie->getInputShouldBeFlushed()) { tcflush(fd, TCIFLUSH); } @@ -102,7 +101,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) { options.c_cc[VTIME] = 0; options.c_cc[VMIN] = 0; - configureBaudrate(&options, uartCookie); + uart::setBaudrate(options, uartCookie->getBaudrate()); /* Save option settings */ if (tcsetattr(fd, TCSANOW, &options) != 0) { @@ -115,24 +114,7 @@ int UartComIF::configureUartPort(UartCookie* uartCookie) { return fd; } -void UartComIF::setParityOptions(struct termios* options, UartCookie* uartCookie) { - /* Clear parity bit */ - options->c_cflag &= ~PARENB; - switch (uartCookie->getParity()) { - case Parity::EVEN: - options->c_cflag |= PARENB; - options->c_cflag &= ~PARODD; - break; - case Parity::ODD: - options->c_cflag |= PARENB; - options->c_cflag |= PARODD; - break; - default: - break; - } -} - -void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCookie) { +void SerialComIF::setStopBitOptions(struct termios* options, SerialCookie* uartCookie) { /* Clear stop field. Sets stop bit to one bit */ options->c_cflag &= ~CSTOPB; switch (uartCookie->getStopBits()) { @@ -144,7 +126,7 @@ void UartComIF::setStopBitOptions(struct termios* options, UartCookie* uartCooki } } -void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCookie) { +void SerialComIF::setDatasizeOptions(struct termios* options, SerialCookie* uartCookie) { /* Clear size bits */ options->c_cflag &= ~CSIZE; switch (uartCookie->getBitsPerWord()) { @@ -168,7 +150,7 @@ void UartComIF::setDatasizeOptions(struct termios* options, UartCookie* uartCook } } -void UartComIF::setFixedOptions(struct termios* options) { +void SerialComIF::setFixedOptions(struct termios* options) { /* Disable RTS/CTS hardware flow control */ options->c_cflag &= ~CRTSCTS; /* Turn on READ & ignore ctrl lines (CLOCAL = 1) */ @@ -191,142 +173,9 @@ void UartComIF::setFixedOptions(struct termios* options) { options->c_oflag &= ~ONLCR; } -void UartComIF::configureBaudrate(struct termios* options, UartCookie* uartCookie) { - switch (uartCookie->getBaudrate()) { - case UartBaudRate::RATE_50: - cfsetispeed(options, B50); - cfsetospeed(options, B50); - break; - case UartBaudRate::RATE_75: - cfsetispeed(options, B75); - cfsetospeed(options, B75); - break; - case UartBaudRate::RATE_110: - cfsetispeed(options, B110); - cfsetospeed(options, B110); - break; - case UartBaudRate::RATE_134: - cfsetispeed(options, B134); - cfsetospeed(options, B134); - break; - case UartBaudRate::RATE_150: - cfsetispeed(options, B150); - cfsetospeed(options, B150); - break; - case UartBaudRate::RATE_200: - cfsetispeed(options, B200); - cfsetospeed(options, B200); - break; - case UartBaudRate::RATE_300: - cfsetispeed(options, B300); - cfsetospeed(options, B300); - break; - case UartBaudRate::RATE_600: - cfsetispeed(options, B600); - cfsetospeed(options, B600); - break; - case UartBaudRate::RATE_1200: - cfsetispeed(options, B1200); - cfsetospeed(options, B1200); - break; - case UartBaudRate::RATE_1800: - cfsetispeed(options, B1800); - cfsetospeed(options, B1800); - break; - case UartBaudRate::RATE_2400: - cfsetispeed(options, B2400); - cfsetospeed(options, B2400); - break; - case UartBaudRate::RATE_4800: - cfsetispeed(options, B4800); - cfsetospeed(options, B4800); - break; - case UartBaudRate::RATE_9600: - cfsetispeed(options, B9600); - cfsetospeed(options, B9600); - break; - case UartBaudRate::RATE_19200: - cfsetispeed(options, B19200); - cfsetospeed(options, B19200); - break; - case UartBaudRate::RATE_38400: - cfsetispeed(options, B38400); - cfsetospeed(options, B38400); - break; - case UartBaudRate::RATE_57600: - cfsetispeed(options, B57600); - cfsetospeed(options, B57600); - break; - case UartBaudRate::RATE_115200: - cfsetispeed(options, B115200); - cfsetospeed(options, B115200); - break; - case UartBaudRate::RATE_230400: - cfsetispeed(options, B230400); - cfsetospeed(options, B230400); - break; -#ifndef __APPLE__ - case UartBaudRate::RATE_460800: - cfsetispeed(options, B460800); - cfsetospeed(options, B460800); - break; - case UartBaudRate::RATE_500000: - cfsetispeed(options, B500000); - cfsetospeed(options, B500000); - break; - case UartBaudRate::RATE_576000: - cfsetispeed(options, B576000); - cfsetospeed(options, B576000); - break; - case UartBaudRate::RATE_921600: - cfsetispeed(options, B921600); - cfsetospeed(options, B921600); - break; - case UartBaudRate::RATE_1000000: - cfsetispeed(options, B1000000); - cfsetospeed(options, B1000000); - break; - case UartBaudRate::RATE_1152000: - cfsetispeed(options, B1152000); - cfsetospeed(options, B1152000); - break; - case UartBaudRate::RATE_1500000: - cfsetispeed(options, B1500000); - cfsetospeed(options, B1500000); - break; - case UartBaudRate::RATE_2000000: - cfsetispeed(options, B2000000); - cfsetospeed(options, B2000000); - break; - case UartBaudRate::RATE_2500000: - cfsetispeed(options, B2500000); - cfsetospeed(options, B2500000); - break; - case UartBaudRate::RATE_3000000: - cfsetispeed(options, B3000000); - cfsetospeed(options, B3000000); - break; - case UartBaudRate::RATE_3500000: - cfsetispeed(options, B3500000); - cfsetospeed(options, B3500000); - break; - case UartBaudRate::RATE_4000000: - cfsetispeed(options, B4000000); - cfsetospeed(options, B4000000); - break; -#endif // ! __APPLE__ - default: -#if FSFW_CPP_OSTREAM_ENABLED == 1 - sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl; -#endif - break; - } -} - -ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) { +ReturnValue_t SerialComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) { int fd = 0; std::string deviceFile; - UartDeviceMapIter uartDeviceMapIter; if (sendLen == 0) { return returnvalue::OK; @@ -339,7 +188,7 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, return returnvalue::FAILED; } - UartCookie* uartCookie = dynamic_cast(cookie); + SerialCookie* uartCookie = dynamic_cast(cookie); if (uartCookie == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::sendMessasge: Invalid UART Cookie!" << std::endl; @@ -348,7 +197,7 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, } deviceFile = uartCookie->getDeviceFile(); - uartDeviceMapIter = uartDeviceMap.find(deviceFile); + auto uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter == uartDeviceMap.end()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "UartComIF::sendMessage: Device file " << deviceFile << "not in UART map" @@ -370,13 +219,12 @@ ReturnValue_t UartComIF::sendMessage(CookieIF* cookie, const uint8_t* sendData, return returnvalue::OK; } -ReturnValue_t UartComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; } +ReturnValue_t SerialComIF::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; } -ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) { +ReturnValue_t SerialComIF::requestReceiveMessage(CookieIF* cookie, size_t requestLen) { std::string deviceFile; - UartDeviceMapIter uartDeviceMapIter; - UartCookie* uartCookie = dynamic_cast(cookie); + SerialCookie* uartCookie = dynamic_cast(cookie); if (uartCookie == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "UartComIF::requestReceiveMessage: Invalid Uart Cookie!" << std::endl; @@ -386,7 +234,7 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestL UartModes uartMode = uartCookie->getUartMode(); deviceFile = uartCookie->getDeviceFile(); - uartDeviceMapIter = uartDeviceMap.find(deviceFile); + auto uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartMode == UartModes::NON_CANONICAL and requestLen == 0) { return returnvalue::OK; @@ -409,8 +257,8 @@ ReturnValue_t UartComIF::requestReceiveMessage(CookieIF* cookie, size_t requestL } } -ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter, - size_t requestLen) { +ReturnValue_t SerialComIF::handleCanonicalRead(SerialCookie& uartCookie, + UartDeviceMap::iterator& iter, size_t requestLen) { ReturnValue_t result = returnvalue::OK; uint8_t maxReadCycles = uartCookie.getReadCycles(); uint8_t currentReadCycles = 0; @@ -467,8 +315,9 @@ ReturnValue_t UartComIF::handleCanonicalRead(UartCookie& uartCookie, UartDeviceM return result; } -ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter, - size_t requestLen) { +ReturnValue_t SerialComIF::handleNoncanonicalRead(SerialCookie& uartCookie, + UartDeviceMap::iterator& iter, + size_t requestLen) { int fd = iter->second.fileDescriptor; auto bufferPtr = iter->second.replyBuffer.data(); // Size check to prevent buffer overflow @@ -501,11 +350,10 @@ ReturnValue_t UartComIF::handleNoncanonicalRead(UartCookie& uartCookie, UartDevi return returnvalue::OK; } -ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) { +ReturnValue_t SerialComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, size_t* size) { std::string deviceFile; - UartDeviceMapIter uartDeviceMapIter; - UartCookie* uartCookie = dynamic_cast(cookie); + SerialCookie* uartCookie = dynamic_cast(cookie); if (uartCookie == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "UartComIF::readReceivedMessage: Invalid uart cookie!" << std::endl; @@ -514,7 +362,7 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, } deviceFile = uartCookie->getDeviceFile(); - uartDeviceMapIter = uartDeviceMap.find(deviceFile); + auto uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter == uartDeviceMap.end()) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::debug << "UartComIF::readReceivedMessage: Device file " << deviceFile << " not in uart map" @@ -532,10 +380,9 @@ ReturnValue_t UartComIF::readReceivedMessage(CookieIF* cookie, uint8_t** buffer, return returnvalue::OK; } -ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) { +ReturnValue_t SerialComIF::flushUartRxBuffer(CookieIF* cookie) { std::string deviceFile; - UartDeviceMapIter uartDeviceMapIter; - UartCookie* uartCookie = dynamic_cast(cookie); + SerialCookie* uartCookie = dynamic_cast(cookie); if (uartCookie == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::flushUartRxBuffer: Invalid uart cookie!" << std::endl; @@ -543,7 +390,7 @@ ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) { return NULLPOINTER; } deviceFile = uartCookie->getDeviceFile(); - uartDeviceMapIter = uartDeviceMap.find(deviceFile); + auto uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter != uartDeviceMap.end()) { int fd = uartDeviceMapIter->second.fileDescriptor; tcflush(fd, TCIFLUSH); @@ -552,10 +399,9 @@ ReturnValue_t UartComIF::flushUartRxBuffer(CookieIF* cookie) { return returnvalue::FAILED; } -ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) { +ReturnValue_t SerialComIF::flushUartTxBuffer(CookieIF* cookie) { std::string deviceFile; - UartDeviceMapIter uartDeviceMapIter; - UartCookie* uartCookie = dynamic_cast(cookie); + SerialCookie* uartCookie = dynamic_cast(cookie); if (uartCookie == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::flushUartTxBuffer: Invalid uart cookie!" << std::endl; @@ -563,7 +409,7 @@ ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) { return NULLPOINTER; } deviceFile = uartCookie->getDeviceFile(); - uartDeviceMapIter = uartDeviceMap.find(deviceFile); + auto uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter != uartDeviceMap.end()) { int fd = uartDeviceMapIter->second.fileDescriptor; tcflush(fd, TCOFLUSH); @@ -572,10 +418,9 @@ ReturnValue_t UartComIF::flushUartTxBuffer(CookieIF* cookie) { return returnvalue::FAILED; } -ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) { +ReturnValue_t SerialComIF::flushUartTxAndRxBuf(CookieIF* cookie) { std::string deviceFile; - UartDeviceMapIter uartDeviceMapIter; - UartCookie* uartCookie = dynamic_cast(cookie); + SerialCookie* uartCookie = dynamic_cast(cookie); if (uartCookie == nullptr) { #if FSFW_CPP_OSTREAM_ENABLED == 1 sif::warning << "UartComIF::flushUartTxAndRxBuf: Invalid uart cookie!" << std::endl; @@ -583,7 +428,7 @@ ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) { return NULLPOINTER; } deviceFile = uartCookie->getDeviceFile(); - uartDeviceMapIter = uartDeviceMap.find(deviceFile); + auto uartDeviceMapIter = uartDeviceMap.find(deviceFile); if (uartDeviceMapIter != uartDeviceMap.end()) { int fd = uartDeviceMapIter->second.fileDescriptor; tcflush(fd, TCIOFLUSH); @@ -591,13 +436,3 @@ ReturnValue_t UartComIF::flushUartTxAndRxBuf(CookieIF* cookie) { } return returnvalue::FAILED; } - -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/src/fsfw_hal/linux/uart/UartComIF.h b/src/fsfw_hal/linux/serial/SerialComIF.h similarity index 69% rename from src/fsfw_hal/linux/uart/UartComIF.h rename to src/fsfw_hal/linux/serial/SerialComIF.h index 77318166..907da7e0 100644 --- a/src/fsfw_hal/linux/uart/UartComIF.h +++ b/src/fsfw_hal/linux/serial/SerialComIF.h @@ -3,12 +3,12 @@ #include #include +#include +#include #include #include -#include "UartCookie.h" - /** * @brief This is the communication interface to access serial ports on linux based operating * systems. @@ -18,7 +18,7 @@ * * @author J. Meier */ -class UartComIF : public DeviceCommunicationIF, public SystemObject { +class SerialComIF : public DeviceCommunicationIF, public SystemObject { public: static constexpr uint8_t uartRetvalId = CLASS_ID::HAL_UART; @@ -26,9 +26,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject { static constexpr ReturnValue_t UART_READ_SIZE_MISSMATCH = returnvalue::makeCode(uartRetvalId, 2); static constexpr ReturnValue_t UART_RX_BUFFER_TOO_SMALL = returnvalue::makeCode(uartRetvalId, 3); - UartComIF(object_id_t objectId); + SerialComIF(object_id_t objectId); - virtual ~UartComIF(); + virtual ~SerialComIF(); ReturnValue_t initializeInterface(CookieIF* cookie) override; ReturnValue_t sendMessage(CookieIF* cookie, const uint8_t* sendData, size_t sendLen) override; @@ -62,7 +62,6 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject { }; using UartDeviceMap = std::unordered_map; - using UartDeviceMapIter = UartDeviceMap::iterator; /** * The uart devie map stores informations of initialized uart ports. @@ -76,20 +75,9 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject { * uart device file, baudrate, parity, stopbits etc. * @return The file descriptor of the configured uart. */ - int configureUartPort(UartCookie* uartCookie); + int configureUartPort(SerialCookie* 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, SerialCookie* uartCookie); /** * @brief This function sets options which are not configurable by the uartCookie. @@ -99,19 +87,11 @@ class UartComIF : public DeviceCommunicationIF, public SystemObject { /** * @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, SerialCookie* 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, + ReturnValue_t handleCanonicalRead(SerialCookie& uartCookie, UartDeviceMap::iterator& iter, size_t requestLen); - ReturnValue_t handleNoncanonicalRead(UartCookie& uartCookie, UartDeviceMapIter& iter, + ReturnValue_t handleNoncanonicalRead(SerialCookie& uartCookie, UartDeviceMap::iterator& iter, size_t requestLen); }; diff --git a/src/fsfw_hal/linux/serial/SerialCookie.cpp b/src/fsfw_hal/linux/serial/SerialCookie.cpp new file mode 100644 index 00000000..e85d339d --- /dev/null +++ b/src/fsfw_hal/linux/serial/SerialCookie.cpp @@ -0,0 +1,51 @@ +#include "SerialCookie.h" + +#include + +SerialCookie::SerialCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate, + size_t maxReplyLen, UartModes uartMode) + : handlerId(handlerId), + deviceFile(deviceFile), + uartMode(uartMode), + baudrate(baudrate), + maxReplyLen(maxReplyLen) {} + +SerialCookie::~SerialCookie() {} + +UartBaudRate SerialCookie::getBaudrate() const { return baudrate; } + +size_t SerialCookie::getMaxReplyLen() const { return maxReplyLen; } + +std::string SerialCookie::getDeviceFile() const { return deviceFile; } + +void SerialCookie::setParityOdd() { parity = Parity::ODD; } + +void SerialCookie::setParityEven() { parity = Parity::EVEN; } + +Parity SerialCookie::getParity() const { return parity; } + +void SerialCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; } + +BitsPerWord SerialCookie::getBitsPerWord() const { return bitsPerWord; } + +StopBits SerialCookie::getStopBits() const { return stopBits; } + +void SerialCookie::setTwoStopBits() { stopBits = StopBits::TWO_STOP_BITS; } + +void SerialCookie::setOneStopBit() { stopBits = StopBits::ONE_STOP_BIT; } + +UartModes SerialCookie::getUartMode() const { return uartMode; } + +void SerialCookie::setReadCycles(uint8_t readCycles) { this->readCycles = readCycles; } + +void SerialCookie::setToFlushInput(bool enable) { this->flushInput = enable; } + +uint8_t SerialCookie::getReadCycles() const { return readCycles; } + +bool SerialCookie::getInputShouldBeFlushed() { return this->flushInput; } + +object_id_t SerialCookie::getHandlerId() const { return this->handlerId; } + +void SerialCookie::setNoFixedSizeReply() { replySizeFixed = false; } + +bool SerialCookie::isReplySizeFixed() { return replySizeFixed; } diff --git a/src/fsfw_hal/linux/uart/UartCookie.h b/src/fsfw_hal/linux/serial/SerialCookie.h similarity index 78% rename from src/fsfw_hal/linux/uart/UartCookie.h rename to src/fsfw_hal/linux/serial/SerialCookie.h index 6840b352..3916e4ca 100644 --- a/src/fsfw_hal/linux/uart/UartCookie.h +++ b/src/fsfw_hal/linux/serial/SerialCookie.h @@ -3,50 +3,10 @@ #include #include +#include #include -enum class Parity { NONE, EVEN, ODD }; - -enum class StopBits { ONE_STOP_BIT, TWO_STOP_BITS }; - -enum class UartModes { CANONICAL, NON_CANONICAL }; - -enum class BitsPerWord { BITS_5, BITS_6, BITS_7, BITS_8 }; - -enum class UartBaudRate { - RATE_50, - RATE_75, - RATE_110, - RATE_134, - RATE_150, - RATE_200, - RATE_300, - RATE_600, - RATE_1200, - RATE_1800, - RATE_2400, - RATE_4800, - RATE_9600, - RATE_19200, - RATE_38400, - RATE_57600, - RATE_115200, - RATE_230400, - RATE_460800, - RATE_500000, - RATE_576000, - RATE_921600, - RATE_1000000, - RATE_1152000, - RATE_1500000, - RATE_2000000, - RATE_2500000, - RATE_3000000, - RATE_3500000, - RATE_4000000 -}; - /** * @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 @@ -54,7 +14,7 @@ enum class UartBaudRate { * * @author J. Meier */ -class UartCookie : public CookieIF { +class SerialCookie : public CookieIF { public: /** * @brief Constructor for the uart cookie. @@ -69,10 +29,10 @@ class UartCookie : public CookieIF { * 8 databits (number of bits transfered with one uart frame) * One stop bit */ - UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, - UartBaudRate baudrate, size_t maxReplyLen); + SerialCookie(object_id_t handlerId, std::string deviceFile, UartBaudRate baudrate, + size_t maxReplyLen, UartModes uartMode = UartModes::NON_CANONICAL); - virtual ~UartCookie(); + virtual ~SerialCookie(); UartBaudRate getBaudrate() const; size_t getMaxReplyLen() const; diff --git a/src/fsfw_hal/linux/serial/helper.cpp b/src/fsfw_hal/linux/serial/helper.cpp new file mode 100644 index 00000000..ba975f2f --- /dev/null +++ b/src/fsfw_hal/linux/serial/helper.cpp @@ -0,0 +1,163 @@ +#include +#include + +#include "fsfw/serviceinterface.h" + +void uart::setMode(struct termios& options, UartModes mode) { + if (mode == UartModes::NON_CANONICAL) { + /* Disable canonical mode */ + options.c_lflag &= ~ICANON; + } else if (mode == UartModes::CANONICAL) { + options.c_lflag |= ICANON; + } +} + +void uart::setBaudrate(struct termios& options, UartBaudRate baud) { + switch (baud) { + case UartBaudRate::RATE_50: + cfsetspeed(&options, B50); + break; + case UartBaudRate::RATE_75: + cfsetspeed(&options, B75); + break; + case UartBaudRate::RATE_110: + cfsetspeed(&options, B110); + break; + case UartBaudRate::RATE_134: + cfsetspeed(&options, B134); + break; + case UartBaudRate::RATE_150: + cfsetspeed(&options, B150); + break; + case UartBaudRate::RATE_200: + cfsetspeed(&options, B200); + break; + case UartBaudRate::RATE_300: + cfsetspeed(&options, B300); + break; + case UartBaudRate::RATE_600: + cfsetspeed(&options, B600); + break; + case UartBaudRate::RATE_1200: + cfsetspeed(&options, B1200); + break; + case UartBaudRate::RATE_1800: + cfsetspeed(&options, B1800); + break; + case UartBaudRate::RATE_2400: + cfsetspeed(&options, B2400); + break; + case UartBaudRate::RATE_4800: + cfsetspeed(&options, B4800); + break; + case UartBaudRate::RATE_9600: + cfsetspeed(&options, B9600); + break; + case UartBaudRate::RATE_19200: + cfsetspeed(&options, B19200); + break; + case UartBaudRate::RATE_38400: + cfsetspeed(&options, B38400); + break; + case UartBaudRate::RATE_57600: + cfsetspeed(&options, B57600); + break; + case UartBaudRate::RATE_115200: + cfsetspeed(&options, B115200); + break; + case UartBaudRate::RATE_230400: + cfsetspeed(&options, B230400); + break; +#ifndef __APPLE__ + case UartBaudRate::RATE_460800: + cfsetspeed(&options, B460800); + break; + case UartBaudRate::RATE_500000: + cfsetspeed(&options, B500000); + break; + case UartBaudRate::RATE_576000: + cfsetspeed(&options, B576000); + break; + case UartBaudRate::RATE_921600: + cfsetspeed(&options, B921600); + break; + case UartBaudRate::RATE_1000000: + cfsetspeed(&options, B1000000); + break; + case UartBaudRate::RATE_1152000: + cfsetspeed(&options, B1152000); + break; + case UartBaudRate::RATE_1500000: + cfsetspeed(&options, B1500000); + break; + case UartBaudRate::RATE_2000000: + cfsetspeed(&options, B2000000); + break; + case UartBaudRate::RATE_2500000: + cfsetspeed(&options, B2500000); + break; + case UartBaudRate::RATE_3000000: + cfsetspeed(&options, B3000000); + break; + case UartBaudRate::RATE_3500000: + cfsetspeed(&options, B3500000); + break; + case UartBaudRate::RATE_4000000: + cfsetspeed(&options, B4000000); + break; +#endif // ! __APPLE__ + default: +#if FSFW_CPP_OSTREAM_ENABLED == 1 + sif::warning << "UartComIF::configureBaudrate: Baudrate not supported" << std::endl; +#endif + break; + } +} + +void uart::setBitsPerWord(struct termios& options, BitsPerWord bits) { + options.c_cflag &= ~CSIZE; // Clear all the size bits + if (bits == BitsPerWord::BITS_5) { + options.c_cflag |= CS5; + } else if (bits == BitsPerWord::BITS_6) { + options.c_cflag |= CS6; + } else if (bits == BitsPerWord::BITS_7) { + options.c_cflag |= CS7; + } else if (bits == BitsPerWord::BITS_8) { + options.c_cflag |= CS8; + } +} + +void uart::enableRead(struct termios& options) { options.c_cflag |= CREAD; } + +void uart::ignoreCtrlLines(struct termios& options) { options.c_cflag |= CLOCAL; } + +void uart::setParity(struct termios& options, Parity parity) { + /* Clear parity bit */ + options.c_cflag &= ~PARENB; + switch (parity) { + case Parity::EVEN: + options.c_cflag |= PARENB; + options.c_cflag &= ~PARODD; + break; + case Parity::ODD: + options.c_cflag |= PARENB; + options.c_cflag |= PARODD; + break; + default: + break; + } +} + +int uart::readCountersAndErrors(int serialPort, serial_icounter_struct& icounter) { + return ioctl(serialPort, TIOCGICOUNT, &icounter); +} + +void uart::setStopbits(struct termios& options, StopBits bits) { + if (bits == StopBits::TWO_STOP_BITS) { + // Use two stop bits + options.c_cflag |= CSTOPB; + } else { + // Clear stop field, only one stop bit used in communication + options.c_cflag &= ~CSTOPB; + } +} diff --git a/src/fsfw_hal/linux/serial/helper.h b/src/fsfw_hal/linux/serial/helper.h new file mode 100644 index 00000000..7f067d00 --- /dev/null +++ b/src/fsfw_hal/linux/serial/helper.h @@ -0,0 +1,71 @@ +#ifndef FSFW_HAL_LINUX_UART_HELPER_H_ +#define FSFW_HAL_LINUX_UART_HELPER_H_ + +#include +#include + +enum class Parity { NONE, EVEN, ODD }; + +enum class StopBits { ONE_STOP_BIT, TWO_STOP_BITS }; + +enum class UartModes { CANONICAL, NON_CANONICAL }; + +enum class BitsPerWord { BITS_5, BITS_6, BITS_7, BITS_8 }; + +enum class UartBaudRate { + RATE_50, + RATE_75, + RATE_110, + RATE_134, + RATE_150, + RATE_200, + RATE_300, + RATE_600, + RATE_1200, + RATE_1800, + RATE_2400, + RATE_4800, + RATE_9600, + RATE_19200, + RATE_38400, + RATE_57600, + RATE_115200, + RATE_230400, + RATE_460800, + RATE_500000, + RATE_576000, + RATE_921600, + RATE_1000000, + RATE_1152000, + RATE_1500000, + RATE_2000000, + RATE_2500000, + RATE_3000000, + RATE_3500000, + RATE_4000000 +}; + +namespace uart { + +void setMode(struct termios& options, UartModes mode); +/** + * @brief This functions adds the baudrate specified in the uartCookie to the termios options + * struct. + */ +void setBaudrate(struct termios& options, UartBaudRate baud); + +void setStopbits(struct termios& options, StopBits bits); + +void setBitsPerWord(struct termios& options, BitsPerWord bits); + +void enableRead(struct termios& options); + +void setParity(struct termios& options, Parity parity); + +void ignoreCtrlLines(struct termios& options); + +int readCountersAndErrors(int serialPort, serial_icounter_struct& icounter); + +} // namespace uart + +#endif /* FSFW_HAL_LINUX_UART_HELPER_H_ */ diff --git a/src/fsfw_hal/linux/uart/CMakeLists.txt b/src/fsfw_hal/linux/uart/CMakeLists.txt deleted file mode 100644 index 9cad62a4..00000000 --- a/src/fsfw_hal/linux/uart/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -target_sources(${LIB_FSFW_NAME} PUBLIC UartComIF.cpp UartCookie.cpp) diff --git a/src/fsfw_hal/linux/uart/UartCookie.cpp b/src/fsfw_hal/linux/uart/UartCookie.cpp deleted file mode 100644 index 3fedc9d4..00000000 --- a/src/fsfw_hal/linux/uart/UartCookie.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "UartCookie.h" - -#include - -UartCookie::UartCookie(object_id_t handlerId, std::string deviceFile, UartModes uartMode, - UartBaudRate baudrate, size_t maxReplyLen) - : handlerId(handlerId), - deviceFile(deviceFile), - uartMode(uartMode), - baudrate(baudrate), - maxReplyLen(maxReplyLen) {} - -UartCookie::~UartCookie() {} - -UartBaudRate UartCookie::getBaudrate() const { return baudrate; } - -size_t UartCookie::getMaxReplyLen() const { return maxReplyLen; } - -std::string UartCookie::getDeviceFile() const { return deviceFile; } - -void UartCookie::setParityOdd() { parity = Parity::ODD; } - -void UartCookie::setParityEven() { parity = Parity::EVEN; } - -Parity UartCookie::getParity() const { return parity; } - -void UartCookie::setBitsPerWord(BitsPerWord bitsPerWord_) { bitsPerWord = bitsPerWord_; } - -BitsPerWord UartCookie::getBitsPerWord() const { return bitsPerWord; } - -StopBits UartCookie::getStopBits() const { return stopBits; } - -void UartCookie::setTwoStopBits() { stopBits = StopBits::TWO_STOP_BITS; } - -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; } - -void UartCookie::setNoFixedSizeReply() { replySizeFixed = false; } - -bool UartCookie::isReplySizeFixed() { return replySizeFixed; }