Commit 0528cdd1398fae482c270c2baf065d0a809fe78c

Authored by Geoffrey Hunter
2 parents 7ceed20b 18eb9073

Merge branch 'develop'

.gitignore
... ... @@ -4,4 +4,7 @@ cmake-build-debug/
4 4 .vscode/
5 5  
6 6 # Sphinx build dir
7   -docs/_build/
8 7 \ No newline at end of file
  8 +docs/_build/
  9 +
  10 +# Build artifacts
  11 +a.out
9 12 \ No newline at end of file
... ...
.vscode/c_cpp_properties.json
... ... @@ -60,7 +60,8 @@
60 60 },
61 61 "compilerPath": "/usr/bin/gcc",
62 62 "cStandard": "c11",
63   - "cppStandard": "c++17"
  63 + "cppStandard": "c++17",
  64 + "configurationProvider": "ms-vscode.cmake-tools"
64 65 },
65 66 {
66 67 "name": "Win32",
... ...
CHANGELOG.md
... ... @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7 7  
8 8 ## [Unreleased]
9 9  
  10 +## [v2.1.0] - 2020-11-08
  11 +
  12 +### Added
  13 +- Support for custom baud rates.
  14 +- Support for all standard UNIX baud rates.
  15 +- Improved Doxygen documentation.
  16 +- Improved README.md documentation.
  17 +
  18 +### Removed
  19 +- Dependencies from the README, they weren't that useful and were not accurate anyway.
  20 +
10 21 ## [v2.0.3] - 2020-10-13
11 22  
12 23 ### Added
... ...
README.md
1 1 # CppLinuxSerial
2 2  
3   -Serial port library written in C++
  3 +Linux serial port library written in C++.
4 4  
5 5 [![Build Status](https://travis-ci.org/gbmhunter/CppLinuxSerial.svg?branch=master)](https://travis-ci.org/gbmhunter/CppLinuxSerial)
6 6  
... ... @@ -8,7 +8,9 @@ Serial port library written in C++
8 8  
9 9 Library for communicating with COM ports on a Linux system.
10 10  
11   -Uses fstream to the file I/O.
  11 +* Simple API
  12 +* Supports custom baud rates
  13 +* cmake based build system
12 14  
13 15 ## Installation
14 16  
... ... @@ -66,18 +68,20 @@ using namespace mn::CppLinuxSerial;
66 68  
67 69 int main() {
68 70 // Create serial port object and open serial port
69   - SerialPort serialPort0("/dev/ttyUSB0", BaudRate::B_57600);
70   - serialPort0.Open();
  71 + SerialPort serialPort("/dev/ttyUSB0", BaudRate::B_57600);
  72 + // Use SerialPort serialPort("/dev/ttyACM0", 13000); instead if you want to provide a custom baud rate
  73 + serialPort.SetTimeout(-1); // Block when reading until any data is received
  74 + serialPort.Open();
71 75  
72 76 // Write some ASCII datae
73   - serialPort0.Write("Hello");
  77 + serialPort.Write("Hello");
74 78  
75   - // Read some data back
  79 + // Read some data back (will block until at least 1 byte is received due to the SetTimeout(-1) call above)
76 80 std::string readData;
77   - serialPort0.Read(readData);
  81 + serialPort.Read(readData);
78 82  
79 83 // Close the serial port
80   - serialPort0.Close();
  84 + serialPort.Close();
81 85 }
82 86 ```
83 87  
... ... @@ -87,34 +91,7 @@ If the above code was in a file called `main.cpp` and you had installed `CppLinu
87 91 g++ main.cpp -lCppLinuxSerial
88 92 ```
89 93  
90   -For more examples, see the `.cpp` files in `test/unit/`.
91   -
92   -## Dependencies
93   -
94   -The following table lists all of the libraries dependencies.
95   -
96   -<table>
97   - <thead>
98   - <tr>
99   - <td>Dependency</td>
100   - <td>Comments</td>
101   - </tr>
102   - </thead>
103   - <tbody>
104   - <tr>
105   - <td>C++14</td>
106   - <td>C++14 used for strongly typed enums, `std::chrono` and literals.</td>
107   - </tr>
108   - <tr>
109   - <td>stdio.h</td>
110   - <td>snprintf()</td>
111   - </tr>
112   - <tr>
113   - <td>stty</td>
114   - <td>Used in unit tests to verify the serial port is configured correctly.</td>
115   - </tr>
116   - </tbody>
117   -</table>
  94 +For more examples, see the files in `test/`.
118 95  
119 96 ## Issues
120 97  
... ... @@ -122,7 +99,7 @@ See GitHub Issues.
122 99  
123 100 ## FAQ
124 101  
125   -1. My code stalls when calling functions like `SerialPort::Read()`. This is probably because the library is set up to do a blocking read, and not enough characters have been received to allow `SerialPort::Read()` to return. Use `SerialPort::SetNumCharsToWait()` to determine how many characters to wait for before returning (set to 0 for non-blocking mode).
  102 +1. My code stalls when calling functions like `SerialPort::Read()`. This is probably because the library is set up to do a blocking read, and not enough characters have been received to allow `SerialPort::Read()` to return. Call `SerialPort::SetTimeout(0)` before the serial port is open to set a non-blocking mode.
126 103  
127 104 ## Changelog
128 105  
... ...
include/CppLinuxSerial/SerialPort.hpp
... ... @@ -15,8 +15,11 @@
15 15 #include <string>
16 16 #include <fstream> // For file I/O (reading/writing to COM port)
17 17 #include <sstream>
18   -#include <termios.h> // POSIX terminal control definitions (struct termios)
  18 +// #include <termios.h> // POSIX terminal control definitions (struct termios)
  19 +// #include <asm/termios.h> // Terminal control definitions (struct termios)
19 20 #include <vector>
  21 +#include <asm/ioctls.h>
  22 +#include <asm/termbits.h>
20 23  
21 24 // User headers
22 25 #include "Exception.hpp"
... ... @@ -24,18 +27,44 @@
24 27 namespace mn {
25 28 namespace CppLinuxSerial {
26 29  
  30 + /// \brief Represents the baud rate "types" that can be used with the serial port. STANDARD represents all
  31 + /// the standard baud rates as provided by UNIX, CUSTOM represents a baud rate defined by an arbitray integer.
  32 + enum class BaudRateType {
  33 + STANDARD,
  34 + CUSTOM,
  35 + };
  36 +
27 37 /// \brief Strongly-typed enumeration of baud rates for use with the SerialPort class
  38 + /// \details Specifies all the same baud rates as UNIX, as well as B_CUSTOM to specify your
  39 + /// own. See https://linux.die.net/man/3/cfsetispeed for list of supported UNIX baud rates.
28 40 enum class BaudRate {
  41 + B_0,
  42 + B_50,
  43 + B_75,
  44 + B_110,
  45 + B_134,
  46 + B_150,
  47 + B_200,
  48 + B_300,
  49 + B_600,
  50 + B_1200,
  51 + B_1800,
  52 + B_2400,
  53 + B_4800,
29 54 B_9600,
  55 + B_19200,
30 56 B_38400,
31 57 B_57600,
32 58 B_115200,
33   - CUSTOM
  59 + B_230400,
  60 + B_460800,
  61 + B_CUSTOM, // Placeholder
34 62 };
35 63  
  64 + /// \brief Represents the state of the serial port.
36 65 enum class State {
37 66 CLOSED,
38   - OPEN
  67 + OPEN,
39 68 };
40 69  
41 70 /// \brief SerialPort object is used to perform rx/tx serial communication.
... ... @@ -48,15 +77,22 @@ namespace mn {
48 77 /// \brief Constructor that sets up serial port with the basic (required) parameters.
49 78 SerialPort(const std::string &device, BaudRate baudRate);
50 79  
51   - //! @brief Destructor. Closes serial port if still open.
  80 + /// \brief Constructor that sets up serial port with the basic (required) parameters.
  81 + SerialPort(const std::string &device, speed_t baudRate);
  82 +
  83 + /// \brief Destructor. Closes serial port if still open.
52 84 virtual ~SerialPort();
53 85  
54 86 /// \brief Sets the device to use for serial port communications.
55 87 /// \details Method can be called when serial port is in any state.
56 88 void SetDevice(const std::string &device);
57 89  
  90 + /// \brief Allows the user to set a standard baud rate.
58 91 void SetBaudRate(BaudRate baudRate);
59 92  
  93 + /// \brief Allows the user to set a custom baud rate.
  94 + void SetBaudRate(speed_t baudRate);
  95 +
60 96 /// \brief Sets the read timeout (in milliseconds)/blocking mode.
61 97 /// \details Only call when state != OPEN. This method manupulates VMIN and VTIME.
62 98 /// \param timeout_ms Set to -1 to infinite timeout, 0 to return immediately with any data (non
... ... @@ -92,13 +128,19 @@ namespace mn {
92 128 private:
93 129  
94 130 /// \brief Returns a populated termios structure for the passed in file descriptor.
95   - termios GetTermios();
  131 + // termios GetTermios();
96 132  
97 133 /// \brief Configures the tty device as a serial port.
98 134 /// \warning Device must be open (valid file descriptor) when this is called.
99 135 void ConfigureTermios();
100 136  
101   - void SetTermios(termios myTermios);
  137 + // void SetTermios(termios myTermios);
  138 +
  139 + /// \brief Returns a populated termios2 structure for the serial port pointed to by the file descriptor.
  140 + termios2 GetTermios2();
  141 +
  142 + /// \brief Assigns the provided tty settings to the serial port pointed to by the file descriptor.
  143 + void SetTermios2(termios2 tty);
102 144  
103 145 /// \brief Keeps track of the serial port's state.
104 146 State state_;
... ... @@ -106,8 +148,14 @@ namespace mn {
106 148 /// \brief The file path to the serial port device (e.g. "/dev/ttyUSB0").
107 149 std::string device_;
108 150  
109   - /// \brief The current baud rate.
110   - BaudRate baudRate_;
  151 + /// \brief The type of baud rate that the user has specified.
  152 + BaudRateType baudRateType_;
  153 +
  154 + /// \brief The current baud rate if baudRateType_ == STANDARD.
  155 + BaudRate baudRateStandard_;
  156 +
  157 + /// \brief The current baud rate if baudRateType_ == CUSTOM.
  158 + speed_t baudRateCustom_;
111 159  
112 160 /// \brief The file descriptor for the open file. This gets written to when Open() is called.
113 161 int fileDesc_;
... ...
src/SerialPort.cpp
... ... @@ -15,20 +15,28 @@
15 15 #include <unistd.h> // UNIX standard function definitions
16 16 #include <fcntl.h> // File control definitions
17 17 #include <errno.h> // Error number definitions
18   -#include <termios.h> // POSIX terminal control definitions (struct termios)
  18 +// #include <termios.h> // POSIX terminal control definitions (struct termios)
19 19 #include <system_error> // For throwing std::system_error
  20 +#include <sys/ioctl.h> // Used for TCGETS2, which is required for custom baud rates
  21 +#include <cassert>
  22 +// #include <asm/termios.h> // Terminal control definitions (struct termios)
  23 +#include <asm/ioctls.h>
  24 +#include <asm/termbits.h>
20 25  
21 26 // User includes
22 27 #include "CppLinuxSerial/Exception.hpp"
23 28 #include "CppLinuxSerial/SerialPort.hpp"
24 29  
  30 +#define BOTHER 0010000
  31 +
25 32 namespace mn {
26 33 namespace CppLinuxSerial {
27 34  
28 35 SerialPort::SerialPort() {
29 36 echo_ = false;
30 37 timeout_ms_ = defaultTimeout_ms_;
31   - baudRate_ = defaultBaudRate_;
  38 + baudRateType_ = BaudRateType::STANDARD;
  39 + baudRateStandard_ = defaultBaudRate_;
32 40 readBufferSize_B_ = defaultReadBufferSize_B_;
33 41 readBuffer_.reserve(readBufferSize_B_);
34 42 state_ = State::CLOSED;
... ... @@ -37,7 +45,15 @@ namespace CppLinuxSerial {
37 45 SerialPort::SerialPort(const std::string& device, BaudRate baudRate) :
38 46 SerialPort() {
39 47 device_ = device;
40   - baudRate_ = baudRate;
  48 + baudRateType_ = BaudRateType::STANDARD;
  49 + baudRateStandard_ = baudRate;
  50 + }
  51 +
  52 + SerialPort::SerialPort(const std::string& device, speed_t baudRate) :
  53 + SerialPort() {
  54 + device_ = device;
  55 + baudRateType_ = BaudRateType::CUSTOM;
  56 + baudRateCustom_ = baudRate;
41 57 }
42 58  
43 59 SerialPort::~SerialPort() {
... ... @@ -52,13 +68,21 @@ namespace CppLinuxSerial {
52 68 void SerialPort::SetDevice(const std::string& device) {
53 69 device_ = device;
54 70 if(state_ == State::OPEN)
55   -
56   -
57   - ConfigureTermios();
  71 + ConfigureTermios();
58 72 }
59 73  
60 74 void SerialPort::SetBaudRate(BaudRate baudRate) {
61   - baudRate_ = baudRate;
  75 + std::cout << "standard called\n";
  76 + baudRateType_ = BaudRateType::STANDARD;
  77 + baudRateStandard_ = baudRate;
  78 + if(state_ == State::OPEN)
  79 + ConfigureTermios();
  80 + }
  81 +
  82 + void SerialPort::SetBaudRate(speed_t baudRate) {
  83 + std::cout << " custom called\n";
  84 + baudRateType_ = BaudRateType::CUSTOM;
  85 + baudRateCustom_ = baudRate;
62 86 if(state_ == State::OPEN)
63 87 ConfigureTermios();
64 88 }
... ... @@ -66,7 +90,7 @@ namespace CppLinuxSerial {
66 90 void SerialPort::Open()
67 91 {
68 92  
69   - std::cout << "Attempting to open COM port \"" << device_ << "\"." << std::endl;
  93 + // std::cout << "Attempting to open COM port \"" << device_ << "\"." << std::endl;
70 94  
71 95 if(device_.empty()) {
72 96 THROW_EXCEPT("Attempted to open file when file path has not been assigned to.");
... ... @@ -86,7 +110,7 @@ namespace CppLinuxSerial {
86 110  
87 111 ConfigureTermios();
88 112  
89   - std::cout << "COM port opened successfully." << std::endl;
  113 + // std::cout << "COM port opened successfully." << std::endl;
90 114 state_ = State::OPEN;
91 115 }
92 116  
... ... @@ -97,11 +121,12 @@ namespace CppLinuxSerial {
97 121  
98 122 void SerialPort::ConfigureTermios()
99 123 {
100   - std::cout << "Configuring COM port \"" << device_ << "\"." << std::endl;
  124 + // std::cout << "Configuring COM port \"" << device_ << "\"." << std::endl;
101 125  
102 126 //================== CONFIGURE ==================//
103 127  
104   - termios tty = GetTermios();
  128 + // termios tty = GetTermios();
  129 + termios2 tty = GetTermios2();
105 130  
106 131 //================= (.c_cflag) ===============//
107 132  
... ... @@ -115,29 +140,171 @@ namespace CppLinuxSerial {
115 140  
116 141 //===================== BAUD RATE =================//
117 142  
118   - switch(baudRate_) {
119   - case BaudRate::B_9600:
120   - cfsetispeed(&tty, B9600);
121   - cfsetospeed(&tty, B9600);
122   - break;
123   - case BaudRate::B_38400:
124   - cfsetispeed(&tty, B38400);
125   - cfsetospeed(&tty, B38400);
126   - break;
127   - case BaudRate::B_57600:
128   - cfsetispeed(&tty, B57600);
129   - cfsetospeed(&tty, B57600);
130   - break;
131   - case BaudRate::B_115200:
132   - cfsetispeed(&tty, B115200);
133   - cfsetospeed(&tty, B115200);
134   - break;
135   - case BaudRate::CUSTOM:
136   - // See https://gist.github.com/kennethryerson/f7d1abcf2633b7c03cf0
137   - throw std::runtime_error("Custom baud rate not yet supported.");
138   - default:
139   - throw std::runtime_error(std::string() + "baudRate passed to " + __PRETTY_FUNCTION__ + " unrecognized.");
140   - }
  143 + // We used to use cfsetispeed() and cfsetospeed() with the B... macros, but this didn't allow
  144 + // us to set custom baud rates. So now to support both standard and custom baud rates lets
  145 + // just make everything "custom". This giant switch statement could be replaced with a map/lookup
  146 + // in the future
  147 + if (baudRateType_ == BaudRateType::STANDARD) {
  148 + tty.c_cflag &= ~CBAUD;
  149 + tty.c_cflag |= CBAUDEX;
  150 + switch(baudRateStandard_) {
  151 + case BaudRate::B_0:
  152 + // cfsetispeed(&tty, B0);
  153 + // cfsetospeed(&tty, B0);
  154 + tty.c_ispeed = 0;
  155 + tty.c_ospeed = 0;
  156 + break;
  157 + case BaudRate::B_50:
  158 + // cfsetispeed(&tty, B50);
  159 + // cfsetospeed(&tty, B50);
  160 + tty.c_ispeed = 50;
  161 + tty.c_ospeed = 50;
  162 + break;
  163 + case BaudRate::B_75:
  164 + // cfsetispeed(&tty, B75);
  165 + // cfsetospeed(&tty, B75);
  166 + tty.c_ispeed = 75;
  167 + tty.c_ospeed = 75;
  168 + break;
  169 + case BaudRate::B_110:
  170 + // cfsetispeed(&tty, B110);
  171 + // cfsetospeed(&tty, B110);
  172 + tty.c_ispeed = 110;
  173 + tty.c_ospeed = 110;
  174 + break;
  175 + case BaudRate::B_134:
  176 + // cfsetispeed(&tty, B134);
  177 + // cfsetospeed(&tty, B134);
  178 + tty.c_ispeed = 134;
  179 + tty.c_ospeed = 134;
  180 + break;
  181 + case BaudRate::B_150:
  182 + // cfsetispeed(&tty, B150);
  183 + // cfsetospeed(&tty, B150);
  184 + tty.c_ispeed = 150;
  185 + tty.c_ospeed = 150;
  186 + break;
  187 + case BaudRate::B_200:
  188 + // cfsetispeed(&tty, B200);
  189 + // cfsetospeed(&tty, B200);
  190 + tty.c_ispeed = 200;
  191 + tty.c_ospeed = 200;
  192 + break;
  193 + case BaudRate::B_300:
  194 + // cfsetispeed(&tty, B300);
  195 + // cfsetospeed(&tty, B300);
  196 + tty.c_ispeed = 300;
  197 + tty.c_ospeed = 300;
  198 + break;
  199 + case BaudRate::B_600:
  200 + // cfsetispeed(&tty, B600);
  201 + // cfsetospeed(&tty, B600);
  202 + tty.c_ispeed = 600;
  203 + tty.c_ospeed = 600;
  204 + break;
  205 + case BaudRate::B_1200:
  206 + // cfsetispeed(&tty, B1200);
  207 + // cfsetospeed(&tty, B1200);
  208 + tty.c_ispeed = 1200;
  209 + tty.c_ospeed = 1200;
  210 + break;
  211 + case BaudRate::B_1800:
  212 + // cfsetispeed(&tty, B1800);
  213 + // cfsetospeed(&tty, B1800);
  214 + tty.c_ispeed = 1800;
  215 + tty.c_ospeed = 1800;
  216 + break;
  217 + case BaudRate::B_2400:
  218 + // cfsetispeed(&tty, B2400);
  219 + // cfsetospeed(&tty, B2400);
  220 + tty.c_ispeed = 2400;
  221 + tty.c_ospeed = 2400;
  222 + break;
  223 + case BaudRate::B_4800:
  224 + // cfsetispeed(&tty, B4800);
  225 + // cfsetospeed(&tty, B4800);
  226 + tty.c_ispeed = 4800;
  227 + tty.c_ospeed = 4800;
  228 + break;
  229 + case BaudRate::B_9600:
  230 + // cfsetispeed(&tty, B9600);
  231 + // cfsetospeed(&tty, B9600);
  232 + tty.c_ispeed = 9600;
  233 + tty.c_ospeed = 9600;
  234 + break;
  235 + case BaudRate::B_19200:
  236 + // cfsetispeed(&tty, B19200);
  237 + // cfsetospeed(&tty, B19200);
  238 + tty.c_ispeed = 19200;
  239 + tty.c_ospeed = 19200;
  240 + break;
  241 + case BaudRate::B_38400:
  242 + // cfsetispeed(&tty, B38400);
  243 + // cfsetospeed(&tty, B38400);
  244 + tty.c_ispeed = 38400;
  245 + tty.c_ospeed = 38400;
  246 + break;
  247 + case BaudRate::B_57600:
  248 + // cfsetispeed(&tty, B57600);
  249 + // cfsetospeed(&tty, B57600);
  250 + tty.c_ispeed = 57600;
  251 + tty.c_ospeed = 57600;
  252 + break;
  253 + case BaudRate::B_115200:
  254 + // cfsetispeed(&tty, B115200);
  255 + // cfsetospeed(&tty, B115200);
  256 + tty.c_ispeed = 115200;
  257 + tty.c_ospeed = 115200;
  258 + break;
  259 + case BaudRate::B_230400:
  260 + // cfsetispeed(&tty, B230400);
  261 + // cfsetospeed(&tty, B230400);
  262 + tty.c_ispeed = 230400;
  263 + tty.c_ospeed = 230400;
  264 + break;
  265 + case BaudRate::B_460800:
  266 + // cfsetispeed(&tty, B460800);
  267 + // cfsetospeed(&tty, B460800);
  268 + tty.c_ispeed = 460800;
  269 + tty.c_ospeed = 460800;
  270 + break;
  271 + default:
  272 + throw std::runtime_error(std::string() + "baudRate passed to " + __PRETTY_FUNCTION__ + " unrecognized.");
  273 + }
  274 + }
  275 + // This does no different than STANDARD atm, but let's keep
  276 + // them separate for now....
  277 + else if (baudRateType_ == BaudRateType::CUSTOM)
  278 + {
  279 + tty.c_cflag &= ~CBAUD;
  280 + tty.c_cflag |= CBAUDEX;
  281 + // tty.c_cflag |= BOTHER;
  282 + tty.c_ispeed = baudRateCustom_;
  283 + tty.c_ospeed = baudRateCustom_;
  284 +
  285 +
  286 + // #include <linux/serial.h>
  287 + // // configure port to use custom speed instead of 38400
  288 + // struct serial_struct ss;
  289 + // ioctl(fileDesc_, TIOCGSERIAL, &ss);
  290 + // ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
  291 + // ss.custom_divisor = (ss.baud_base + (baudRateCustom_ / 2)) / baudRateCustom_;
  292 + // int closestSpeed = ss.baud_base / ss.custom_divisor;
  293 +
  294 + // if (closestSpeed < baudRateCustom_ * 98 / 100 || closestSpeed > baudRateCustom_ * 102 / 100) {
  295 + // printf("Cannot set serial port speed to %d. Closest possible is %d\n", baudRateCustom_, closestSpeed);
  296 + // }
  297 +
  298 + // ioctl(fileDesc_, TIOCSSERIAL, &ss);
  299 +
  300 + // cfsetispeed(&tty, B38400);
  301 + // cfsetospeed(&tty, B38400);
  302 + }
  303 + else
  304 + {
  305 + // Should never get here, bug in this libraries code!
  306 + assert(false);
  307 + }
141 308  
142 309 //===================== (.c_oflag) =================//
143 310  
... ... @@ -170,14 +337,11 @@ namespace CppLinuxSerial {
170 337 tty.c_cc[VMIN] = 0;
171 338 }
172 339  
173   -
174 340 //======================== (.c_iflag) ====================//
175 341  
176 342 tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
177 343 tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL);
178 344  
179   -
180   -
181 345 //=========================== LOCAL MODES (c_lflag) =======================//
182 346  
183 347 // Canonical input is when read waits for EOL or EOF characters before returning. In non-canonical mode, the rate at which
... ... @@ -189,11 +353,11 @@ namespace CppLinuxSerial {
189 353 tty.c_lflag &= ~ISIG; // Disables recognition of INTR (interrupt), QUIT and SUSP (suspend) characters
190 354  
191 355  
192   -
193 356 // Try and use raw function call
194 357 //cfmakeraw(&tty);
195 358  
196   - this->SetTermios(tty);
  359 + // this->SetTermios(tty);
  360 + this->SetTermios2(tty);
197 361  
198 362 /*
199 363 // Flush port, then apply attributes
... ... @@ -262,39 +426,60 @@ namespace CppLinuxSerial {
262 426 // If code reaches here, read must of been successful
263 427 }
264 428  
265   - termios SerialPort::GetTermios() {
266   - if(fileDesc_ == -1)
267   - throw std::runtime_error("GetTermios() called but file descriptor was not valid.");
  429 + // termios SerialPort::GetTermios() {
  430 + // if(fileDesc_ == -1)
  431 + // throw std::runtime_error("GetTermios() called but file descriptor was not valid.");
268 432  
269   - struct termios tty;
270   - memset(&tty, 0, sizeof(tty));
  433 + // struct termios tty;
  434 + // memset(&tty, 0, sizeof(tty));
271 435  
272   - // Get current settings (will be stored in termios structure)
273   - if(tcgetattr(fileDesc_, &tty) != 0)
274   - {
275   - // Error occurred
276   - std::cout << "Could not get terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl;
277   - throw std::system_error(EFAULT, std::system_category());
278   - //return false;
279   - }
  436 + // // Get current settings (will be stored in termios structure)
  437 + // if(tcgetattr(fileDesc_, &tty) != 0)
  438 + // {
  439 + // // Error occurred
  440 + // std::cout << "Could not get terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl;
  441 + // throw std::system_error(EFAULT, std::system_category());
  442 + // //return false;
  443 + // }
280 444  
281   - return tty;
282   - }
  445 + // return tty;
  446 + // }
283 447  
284   - void SerialPort::SetTermios(termios myTermios)
285   - {
286   - // Flush port, then apply attributes
287   - tcflush(fileDesc_, TCIFLUSH);
  448 + // void SerialPort::SetTermios(termios myTermios)
  449 + // {
  450 + // // Flush port, then apply attributes
  451 + // tcflush(fileDesc_, TCIFLUSH);
288 452  
289   - if(tcsetattr(fileDesc_, TCSANOW, &myTermios) != 0)
290   - {
291   - // Error occurred
292   - std::cout << "Could not apply terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl;
293   - throw std::system_error(EFAULT, std::system_category());
  453 + // if(tcsetattr(fileDesc_, TCSANOW, &myTermios) != 0)
  454 + // {
  455 + // // Error occurred
  456 + // std::cout << "Could not apply terminal attributes for \"" << device_ << "\" - " << strerror(errno) << std::endl;
  457 + // throw std::system_error(EFAULT, std::system_category());
294 458  
295   - }
  459 + // }
  460 +
  461 + // // Successful!
  462 + // }
296 463  
297   - // Successful!
  464 + termios2 SerialPort::GetTermios2()
  465 + {
  466 + struct termios2 term2;
  467 +
  468 + ioctl(fileDesc_, TCGETS2, &term2);
  469 +
  470 + return term2;
  471 +
  472 + // term2.c_cflag &= ~CBAUD; /* Remove current BAUD rate */
  473 + // term2.c_cflag |= BOTHER; /* Allow custom BAUD rate using int input */
  474 + // term2.c_ispeed = speed; /* Set the input BAUD rate */
  475 + // term2.c_ospeed = speed; /* Set the output BAUD rate */
  476 +
  477 + // ioctl(fd, TCSETS2, &term2);
  478 + }
  479 +
  480 + void SerialPort::SetTermios2(termios2 tty)
  481 + {
  482 + ioctl(fileDesc_, TCSETS2, &tty);
298 483 }
299 484  
300 485 void SerialPort::Close() {
... ...
test/arduino/Basic/Basic.ino 0 → 100644
  1 +/*
  2 + AnalogReadSerial
  3 +
  4 + Reads an analog input on pin 0, prints the result to the Serial Monitor.
  5 + Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  6 + Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.
  7 +
  8 + This example code is in the public domain.
  9 +
  10 + http://www.arduino.cc/en/Tutorial/AnalogReadSerial
  11 +*/
  12 +
  13 +// the setup routine runs once when you press reset:
  14 +void setup() {
  15 + // initialize serial communication at 9600 bits per second:
  16 + Serial.begin(9600);
  17 +// Serial.begin(81234); // Used to test custom baud rates
  18 +}
  19 +
  20 +// the loop routine runs over and over again forever:
  21 +void loop() {
  22 + Serial.println("Hello");
  23 + delay(100); // delay in between reads for stability
  24 +}
... ...
test/arduino/main.cpp 0 → 100644
  1 +#include <CppLinuxSerial/SerialPort.hpp>
  2 +
  3 +using namespace mn::CppLinuxSerial;
  4 +
  5 +int main() {
  6 + // Create serial port object and open serial port
  7 + SerialPort serialPort("/dev/ttyACM0", BaudRate::B_9600);
  8 + // SerialPort serialPort("/dev/ttyACM0", 13000);
  9 + serialPort.SetTimeout(-1); // Block when reading until any data is received
  10 + serialPort.Open();
  11 +
  12 + // Write some ASCII datae
  13 + // serialPort0.Write("Hello");
  14 +
  15 + // Read some data back
  16 + while(1) {
  17 + std::string readData;
  18 + serialPort.Read(readData);
  19 + std::cout << "Received data: " << readData;
  20 + }
  21 +
  22 + // Close the serial port
  23 + serialPort.Close();
  24 +}
0 25 \ No newline at end of file
... ...