BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
9418df2
Branches
Tags
master
Blinker
src
linux
Device.cpp
added buffer to serial device output dropping frames on serial output if buffer gets too full (more than 10 frames) added support for high baudrates
Stefan Schuermans
commited
9418df2
at 2011-12-27 08:02:03
Device.cpp
Blame
History
Raw
/* Blinker Copyright 2011 Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <errno.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <string> #include <strings.h> #include <termios.h> #include <unistd.h> #include "Device.h" #include "Io.h" #include "SerCfg.h" namespace Blinker { /** * @brief constructor * @param[in] path path to device */ Device::Device(const std::string &path) { // open device m_fd = open(path.c_str(), O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK); } /// destructor Device::~Device() { // exit if not initialized if (m_fd == -1) return; // close device close(m_fd); } /** * @brief set serial port configuration * @param[in] serCfg serial port configuration * @return if configuration succeeded * * This function should only be used if device is a serial port. */ bool Device::setSerCfg(const SerCfg& serCfg) { struct termios tio; // exit if not initialized if (m_fd == -1) return false; // set up serial port configuration structure bzero(&tio, sizeof(tio)); tio.c_cflag = CLOCAL | HUPCL | CREAD; tio.c_iflag = IGNBRK | IGNPAR; tio.c_oflag = 0; tio.c_lflag = 0; tio.c_cc[VTIME] = 1; // 0.1 sec timeout tio.c_cc[VMIN] = 0; // return on single char read switch (serCfg.m_baud) { case 300: tio.c_cflag |= B300; break; case 600: tio.c_cflag |= B600; break; case 1200: tio.c_cflag |= B1200; break; case 2400: tio.c_cflag |= B2400; break; case 4800: tio.c_cflag |= B4800; break; case 9600: tio.c_cflag |= B9600; break; case 19200: tio.c_cflag |= B19200; break; case 38400: tio.c_cflag |= B38400; break; #ifdef B57600 case 57600: tio.c_cflag |= B57600; break; #endif #ifdef B115200 case 115200: tio.c_cflag |= B115200; break; #endif #ifdef B230400 case 230400: tio.c_cflag |= B230400; break; #endif #ifdef B460800 case 460800: tio.c_cflag |= B460800; break; #endif #ifdef B500000 case 500000: tio.c_cflag |= B500000; break; #endif #ifdef B576000 case 576000: tio.c_cflag |= B576000; break; #endif #ifdef B921600 case 921600: tio.c_cflag |= B921600; break; #endif #ifdef B1000000 case 1000000: tio.c_cflag |= B1000000; break; #endif #ifdef B1152000 case 1152000: tio.c_cflag |= B1152000; break; #endif #ifdef B1500000 case 1500000: tio.c_cflag |= B1500000; break; #endif #ifdef B2000000 case 2000000: tio.c_cflag |= B2000000; break; #endif #ifdef B2500000 case 2500000: tio.c_cflag |= B2500000; break; #endif #ifdef B3000000 case 3000000: tio.c_cflag |= B3000000; break; #endif #ifdef B3500000 case 3500000: tio.c_cflag |= B3500000; break; #endif #ifdef B4000000 case 4000000: tio.c_cflag |= B4000000; break; #endif default: return false; // invalid setting } switch (serCfg.m_data) { case 5: tio.c_cflag |= CS5; break; case 6: tio.c_cflag |= CS6; break; case 7: tio.c_cflag |= CS7; break; case 8: tio.c_cflag |= CS8; break; default: return false; // invalid setting } switch (serCfg.m_parity) { case SerCfg::ParityNone: break; case SerCfg::ParityEven: tio.c_cflag |= PARENB; break; case SerCfg::ParityOdd: tio.c_cflag |= PARENB | PARODD; break; default: return false; // invalid setting } switch (serCfg.m_stop) { case 1: break; case 2: tio.c_cflag |= CSTOPB; break; default: return false; // invalid setting } // configure serial port return tcsetattr(m_fd, TCSANOW, &tio) != -1; } /** * @brief write data to device * @param[in] data data to write * @param[out] len number of byte written to device * @return if some (or zero) data could be written, * i.e. if the device is still operational */ bool Device::write(const std::string &data, std::string::size_type &len) { // exit if not initialized if (m_fd == -1) return false; // write data ssize_t res = ::write(m_fd, data.c_str(), data.size()); // write failed if (res < 0) { // real error if (errno != EAGAIN && errno != EWOULDBLOCK) { len = 0; return false; // report error } // device busy (e.g. serial device buffer full) else { len = 0; return true; // do not report error, device is still working } } // write succeeded else { len = res; return true; // success } } } // namespace Blinker