b6b2996b76e1b0f0e403b4be40430a445bc0873c
Stefan Schuermans implemented character devic...

Stefan Schuermans authored 12 years ago

1) /* Blinker
Stefan Schuermans update copyright years

Stefan Schuermans authored 10 years ago

2)    Copyright 2011-2014Stefan Schuermans <stefan@blinkenarea.org>
Stefan Schuermans implemented character devic...

Stefan Schuermans authored 12 years ago

3)    Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
4)    a blinkenarea.org project */
5) 
Stefan Schuermans added buffer to serial devi...

Stefan Schuermans authored 12 years ago

6) #include <errno.h>
Stefan Schuermans implemented character devic...

Stefan Schuermans authored 12 years ago

7) #include <fcntl.h>
8) #include <sys/stat.h>
9) #include <sys/types.h>
10) #include <string>
11) #include <strings.h>
12) #include <termios.h>
13) #include <unistd.h>
14) 
15) #include "Device.h"
16) #include "Io.h"
17) #include "SerCfg.h"
18) 
19) namespace Blinker {
20) 
21) /**
22)  * @brief constructor
23)  * @param[in] path path to device
24)  */
25) Device::Device(const std::string &path)
26) {
27)   // open device
Stefan Schuermans open device also for writing

Stefan Schuermans authored 12 years ago

28)   m_fd = open(path.c_str(), O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK);
Stefan Schuermans implemented character devic...

Stefan Schuermans authored 12 years ago

29) }
30) 
31) /// destructor
32) Device::~Device()
33) {
34)   // exit if not initialized
35)   if (m_fd == -1)
36)     return;
37) 
38)   // close device
39)   close(m_fd);
40) }
41) 
42) /**
43)  * @brief set serial port configuration
44)  * @param[in] serCfg serial port configuration
45)  * @return if configuration succeeded
46)  *
47)  * This function should only be used if device is a serial port.
48)  */
49) bool Device::setSerCfg(const SerCfg& serCfg)
50) {
51)   struct termios tio;
52) 
53)   // exit if not initialized
54)   if (m_fd == -1)
55)     return false;
56) 
57)   // set up serial port configuration structure
58)   bzero(&tio, sizeof(tio));
59)   tio.c_cflag = CLOCAL | HUPCL | CREAD;
60)   tio.c_iflag = IGNBRK | IGNPAR;
61)   tio.c_oflag = 0;
62)   tio.c_lflag = 0;
63)   tio.c_cc[VTIME] = 1; // 0.1 sec timeout
64)   tio.c_cc[VMIN] = 0;  // return on single char read
65)   switch (serCfg.m_baud) {
Stefan Schuermans added buffer to serial devi...

Stefan Schuermans authored 12 years ago

66)     case     300: tio.c_cflag |=     B300; break;
67)     case     600: tio.c_cflag |=     B600; break;
68)     case    1200: tio.c_cflag |=    B1200; break;
69)     case    2400: tio.c_cflag |=    B2400; break;
70)     case    4800: tio.c_cflag |=    B4800; break;
71)     case    9600: tio.c_cflag |=    B9600; break;
72)     case   19200: tio.c_cflag |=   B19200; break;
73)     case   38400: tio.c_cflag |=   B38400; break;
74) #ifdef B57600
75)     case   57600: tio.c_cflag |=   B57600; break;
76) #endif
77) #ifdef B115200
78)     case  115200: tio.c_cflag |=  B115200; break;
79) #endif
80) #ifdef B230400
81)     case  230400: tio.c_cflag |=  B230400; break;
82) #endif
83) #ifdef B460800
84)     case  460800: tio.c_cflag |=  B460800; break;
85) #endif
86) #ifdef B500000
87)     case  500000: tio.c_cflag |=  B500000; break;
88) #endif
89) #ifdef B576000
90)     case  576000: tio.c_cflag |=  B576000; break;
91) #endif
92) #ifdef B921600
93)     case  921600: tio.c_cflag |=  B921600; break;
94) #endif
95) #ifdef B1000000
96)     case 1000000: tio.c_cflag |= B1000000; break;
97) #endif
98) #ifdef B1152000
99)     case 1152000: tio.c_cflag |= B1152000; break;
100) #endif
101) #ifdef B1500000
102)     case 1500000: tio.c_cflag |= B1500000; break;
103) #endif
104) #ifdef B2000000
105)     case 2000000: tio.c_cflag |= B2000000; break;
106) #endif
107) #ifdef B2500000
108)     case 2500000: tio.c_cflag |= B2500000; break;
109) #endif
110) #ifdef B3000000
111)     case 3000000: tio.c_cflag |= B3000000; break;
112) #endif
113) #ifdef B3500000
114)     case 3500000: tio.c_cflag |= B3500000; break;
115) #endif
116) #ifdef B4000000
117)     case 4000000: tio.c_cflag |= B4000000; break;
118) #endif
Stefan Schuermans implemented character devic...

Stefan Schuermans authored 12 years ago

119)     default: return false; // invalid setting
120)   }
121)   switch (serCfg.m_data) {
122)     case 5: tio.c_cflag |= CS5; break;
123)     case 6: tio.c_cflag |= CS6; break;
124)     case 7: tio.c_cflag |= CS7; break;
125)     case 8: tio.c_cflag |= CS8; break;
126)     default: return false; // invalid setting
127)   }
128)   switch (serCfg.m_parity) {
129)     case SerCfg::ParityNone: break;
130)     case SerCfg::ParityEven: tio.c_cflag |= PARENB; break;
131)     case SerCfg::ParityOdd: tio.c_cflag |= PARENB | PARODD; break;
132)     default: return false; // invalid setting
133)   }
134)   switch (serCfg.m_stop) {
135)     case 1: break;
136)     case 2: tio.c_cflag |= CSTOPB; break;
137)     default: return false; // invalid setting
138)   }
139) 
140)   // configure serial port
141)   return tcsetattr(m_fd, TCSANOW, &tio) != -1;
142) }
143) 
144) /**
145)  * @brief write data to device
146)  * @param[in] data data to write
Stefan Schuermans added buffer to serial devi...

Stefan Schuermans authored 12 years ago

147)  * @param[out] len number of byte written to device
148)  * @return if some (or zero) data could be written,
149)  *         i.e. if the device is still operational
Stefan Schuermans implemented character devic...

Stefan Schuermans authored 12 years ago

150)  */
Stefan Schuermans added buffer to serial devi...

Stefan Schuermans authored 12 years ago

151) bool Device::write(const std::string &data, std::string::size_type &len)
Stefan Schuermans implemented character devic...

Stefan Schuermans authored 12 years ago

152) {
153)   // exit if not initialized
154)   if (m_fd == -1)
155)     return false;
156) 
157)   // write data
Stefan Schuermans added buffer to serial devi...

Stefan Schuermans authored 12 years ago

158)   ssize_t res = ::write(m_fd, data.c_str(), data.size());
159)   // write failed
160)   if (res < 0) {
161)     // real error
162)     if (errno != EAGAIN && errno != EWOULDBLOCK) {
163)       len = 0;
164)       return false; // report error
165)     }
166)     // device busy (e.g. serial device buffer full)
167)     else {
168)       len = 0;
169)       return true; // do not report error, device is still working
170)     }
171)   }
172)   // write succeeded
173)   else {
174)     len = res;
175)     return true; // success
176)   }