diff options
Diffstat (limited to 'sw-linux/rom-loader/serial.cpp')
-rw-r--r-- | sw-linux/rom-loader/serial.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/sw-linux/rom-loader/serial.cpp b/sw-linux/rom-loader/serial.cpp new file mode 100644 index 0000000..7d25f02 --- /dev/null +++ b/sw-linux/rom-loader/serial.cpp @@ -0,0 +1,89 @@ +#include "serial.hpp" + +#include <ios> + +extern "C" { +#include <fcntl.h> +#include <termios.h> +#include <unistd.h> +} + +serial::serial(const std::string& port, speed_t baud) +{ + m_fd = open(port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); + + if (m_fd < 0) { + throw std::ios_base::failure("Failed to open serial port " + port); + } + + tcgetattr(m_fd, &m_settings); + + // set input and output baudrate + cfsetispeed(&m_settings, baud); + cfsetospeed(&m_settings, baud); + + // disable parity, 1 stop bit, clear data size + m_settings.c_cflag &= ~(PARENB | CSTOPB | CSIZE); + // set data size to 8 + m_settings.c_cflag |= CS8; + + // disable hw flow control + m_settings.c_cflag &= ~CRTSCTS; + // enable receiver and ignore modem lines + m_settings.c_cflag |= CREAD | CLOCAL; + + // disable XON / XOFF flow control + m_settings.c_iflag &= ~(IXON | IXOFF | IXANY); + // non canonical mode + m_settings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG); + + // no output processing + m_settings.c_oflag &= ~OPOST; + + // input buffer of 8 bytes + m_settings.c_cc[VMIN] = 8; + // set indefinite timeout + m_settings.c_cc[VTIME] = 0; + + if ((tcsetattr(m_fd, TCSANOW, &m_settings)) != 0) + throw std::ios_base::failure("Failed to set attributes"); + + // clean rx buffer + tcflush(m_fd, TCIFLUSH); +} + +serial::~serial() +{ + if (m_fd > 0) + close(m_fd); +} + +int serial::write(const std::string& data) const +{ + write(data.c_str(), data.length()); +} + +int serial::write(const char * const data, size_t len) const +{ + return ::write(m_fd, data, len); +} + +char serial::read() const +{ + char ch; + + if (::read(m_fd, &ch, 1) < 0) + throw std::ios_base::failure("Failed to read"); + + return ch; +} + +std::string serial::read(size_t howmany) const +{ + char data[howmany] = {}; + + if (::read(m_fd, data, howmany) < 0) + throw std::ios_base::failure("Failed to read"); + + return std::string(data); +} |