127 lines
3.9 KiB
C++
127 lines
3.9 KiB
C++
|
#include "SerialCommunicationHelper.h"
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <termios.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
#include <cstring>
|
||
|
|
||
|
#include "fsfw/returnvalues/returnvalue.h"
|
||
|
#include "fsfw_hal/linux/serial/helper.h"
|
||
|
|
||
|
SerialCommunicationHelper::SerialCommunicationHelper(SerialConfig cfg) : cfg(cfg) {}
|
||
|
|
||
|
ReturnValue_t SerialCommunicationHelper::initialize() {
|
||
|
fd = configureUartPort();
|
||
|
if (fd < 0) {
|
||
|
return returnvalue::FAILED;
|
||
|
}
|
||
|
return returnvalue::OK;
|
||
|
}
|
||
|
|
||
|
int SerialCommunicationHelper::rawFd() const { return fd; }
|
||
|
|
||
|
ReturnValue_t SerialCommunicationHelper::send(const uint8_t* data, size_t dataLen) {
|
||
|
if (write(fd, data, dataLen) != static_cast<int>(dataLen)) {
|
||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||
|
sif::error << "UartComIF::sendMessage: Failed to send data with error code " << errno
|
||
|
<< ": Error description: " << strerror(errno) << std::endl;
|
||
|
#endif
|
||
|
return returnvalue::FAILED;
|
||
|
}
|
||
|
return returnvalue::OK;
|
||
|
}
|
||
|
|
||
|
int SerialCommunicationHelper::configureUartPort() {
|
||
|
struct termios options = {};
|
||
|
|
||
|
int flags = O_RDWR;
|
||
|
if (cfg.getUartMode() == UartModes::CANONICAL) {
|
||
|
// In non-canonical mode, don't specify O_NONBLOCK because these properties will be
|
||
|
// controlled by the VTIME and VMIN parameters and O_NONBLOCK would override this
|
||
|
flags |= O_NONBLOCK;
|
||
|
}
|
||
|
int fd = open(cfg.getDeviceFile().c_str(), flags);
|
||
|
|
||
|
if (fd < 0) {
|
||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||
|
sif::warning << "UartComIF::configureUartPort: Failed to open uart "
|
||
|
<< cfg.getDeviceFile().c_str()
|
||
|
|
||
|
<< "with error code " << errno << strerror(errno) << std::endl;
|
||
|
#endif
|
||
|
return fd;
|
||
|
}
|
||
|
|
||
|
/* Read in existing settings */
|
||
|
if (tcgetattr(fd, &options) != 0) {
|
||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||
|
sif::warning << "UartComIF::configureUartPort: Error " << errno
|
||
|
<< "from tcgetattr: " << strerror(errno) << std::endl;
|
||
|
#endif
|
||
|
return fd;
|
||
|
}
|
||
|
|
||
|
serial::setParity(options, cfg.getParity());
|
||
|
serial::setStopbits(options, cfg.getStopBits());
|
||
|
serial::setBitsPerWord(options, cfg.getBitsPerWord());
|
||
|
setFixedOptions(&options);
|
||
|
serial::setMode(options, cfg.getUartMode());
|
||
|
tcflush(fd, TCIFLUSH);
|
||
|
|
||
|
/* Sets uart to non-blocking mode. Read returns immediately when there are no data available */
|
||
|
options.c_cc[VTIME] = 0;
|
||
|
options.c_cc[VMIN] = 0;
|
||
|
|
||
|
serial::setBaudrate(options, cfg.getBaudrate());
|
||
|
|
||
|
/* Save option settings */
|
||
|
if (tcsetattr(fd, TCSANOW, &options) != 0) {
|
||
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||
|
sif::warning << "UartComIF::configureUartPort: Failed to set options with error " << errno
|
||
|
<< ": " << strerror(errno);
|
||
|
#endif
|
||
|
return fd;
|
||
|
}
|
||
|
return fd;
|
||
|
}
|
||
|
|
||
|
void SerialCommunicationHelper::setFixedOptions(struct termios* options) {
|
||
|
/* Disable RTS/CTS hardware flow control */
|
||
|
options->c_cflag &= ~CRTSCTS;
|
||
|
/* Turn on READ & ignore ctrl lines (CLOCAL = 1) */
|
||
|
options->c_cflag |= CREAD | CLOCAL;
|
||
|
/* Disable echo */
|
||
|
options->c_lflag &= ~ECHO;
|
||
|
/* Disable erasure */
|
||
|
options->c_lflag &= ~ECHOE;
|
||
|
/* Disable new-line echo */
|
||
|
options->c_lflag &= ~ECHONL;
|
||
|
/* Disable interpretation of INTR, QUIT and SUSP */
|
||
|
options->c_lflag &= ~ISIG;
|
||
|
/* Turn off s/w flow ctrl */
|
||
|
options->c_iflag &= ~(IXON | IXOFF | IXANY);
|
||
|
/* Disable any special handling of received bytes */
|
||
|
options->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL);
|
||
|
/* Prevent special interpretation of output bytes (e.g. newline chars) */
|
||
|
options->c_oflag &= ~OPOST;
|
||
|
/* Prevent conversion of newline to carriage return/line feed */
|
||
|
options->c_oflag &= ~ONLCR;
|
||
|
}
|
||
|
|
||
|
ReturnValue_t SerialCommunicationHelper::flushUartRxBuffer() {
|
||
|
serial::flushRxBuf(fd);
|
||
|
return returnvalue::OK;
|
||
|
}
|
||
|
|
||
|
ReturnValue_t SerialCommunicationHelper::flushUartTxBuffer() {
|
||
|
serial::flushTxBuf(fd);
|
||
|
return returnvalue::OK;
|
||
|
}
|
||
|
|
||
|
ReturnValue_t SerialCommunicationHelper::flushUartTxAndRxBuf() {
|
||
|
serial::flushTxRxBuf(fd);
|
||
|
return returnvalue::OK;
|
||
|
}
|