e6bfafab44a611397e445f090ffe5669ae21ff3d
3 * Copyright (C) Bob 2009
5 * boblight is free software: you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * boblight is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "../serialport.h"
22 #include "../baudrate.h"
23 #include "../timeutils.h"
28 CSerialPort::CSerialPort()
33 CSerialPort::~CSerialPort()
38 int CSerialPort::Write(uint8_t* data
, int len
)
44 m_error
= "port closed";
50 while (byteswritten
< len
)
54 int returnv
= select(m_fd
+ 1, NULL
, &port
, NULL
, NULL
);
57 m_error
= strerror(errno
);
61 returnv
= write(m_fd
, data
+ byteswritten
, len
- byteswritten
);
64 m_error
= strerror(errno
);
67 byteswritten
+= returnv
;
70 //print what's written to stdout for debugging
73 // printf("%s write:", m_name.c_str());
74 // for (int i = 0; i < byteswritten; i++)
75 // printf(" %02x", (unsigned int)data[i]);
83 int CSerialPort::Read(uint8_t* data
, int len
, int iTimeoutMs
/*= -1*/)
86 struct timeval timeout
, *tv
;
92 m_error
= "port closed";
99 target
= now
+ (int64_t) iTimeoutMs
;
102 while (bytesread
< len
&& (iTimeoutMs
< 0 || target
> now
))
110 timeout
.tv_sec
= ((long int)target
- (long int)now
) / (long int)1000.;
111 timeout
.tv_usec
= ((long int)target
- (long int)now
) % (long int)1000.;
117 int returnv
= select(m_fd
+ 1, &port
, NULL
, NULL
, tv
);
121 m_error
= strerror(errno
);
124 else if (returnv
== 0)
126 break; //nothing to read
129 returnv
= read(m_fd
, data
+ bytesread
, len
- bytesread
);
132 m_error
= strerror(errno
);
136 bytesread
+= returnv
;
142 //print what's read to stdout for debugging
143 // if (m_tostdout && bytesread > 0)
145 // printf("%s read:", m_name.c_str());
146 // for (int i = 0; i < bytesread; i++)
147 // printf(" %02x", (unsigned int)data[i]);
155 //setting all this stuff up is a pain in the ass
156 bool CSerialPort::Open(string name
, int baudrate
, int databits
/* = 8*/, int stopbits
/* = 1*/, int parity
/* = PAR_NONE*/)
159 m_error
= strerror(errno
);
161 if (databits
< 5 || databits
> 8)
163 m_error
= "Databits has to be between 5 and 8";
167 if (stopbits
!= 1 && stopbits
!= 2)
169 m_error
= "Stopbits has to be 1 or 2";
173 if (parity
!= PAR_NONE
&& parity
!= PAR_EVEN
&& parity
!= PAR_ODD
)
175 m_error
= "Parity has to be none, even or odd";
179 m_fd
= open(name
.c_str(), O_RDWR
| O_NOCTTY
| O_NDELAY
);
183 m_error
= strerror(errno
);
187 fcntl(m_fd
, F_SETFL
, 0);
189 if (!SetBaudRate(baudrate
))
194 m_options
.c_cflag
|= (CLOCAL
| CREAD
);
195 m_options
.c_cflag
&= ~HUPCL
;
197 m_options
.c_cflag
&= ~CSIZE
;
198 if (databits
== 5) m_options
.c_cflag
|= CS5
;
199 if (databits
== 6) m_options
.c_cflag
|= CS6
;
200 if (databits
== 7) m_options
.c_cflag
|= CS7
;
201 if (databits
== 8) m_options
.c_cflag
|= CS8
;
203 m_options
.c_cflag
&= ~PARENB
;
204 if (parity
== PAR_EVEN
|| parity
== PAR_ODD
)
205 m_options
.c_cflag
|= PARENB
;
206 if (parity
== PAR_ODD
)
207 m_options
.c_cflag
|= PARODD
;
210 m_options
.c_cflag
&= ~CRTSCTS
;
211 #elif defined(CNEW_RTSCTS)
212 m_options
.c_cflag
&= ~CNEW_RTSCTS
;
215 if (stopbits
== 1) m_options
.c_cflag
&= ~CSTOPB
;
216 else m_options
.c_cflag
|= CSTOPB
;
218 //I guessed a little here
219 m_options
.c_lflag
&= ~(ICANON
| ECHO
| ECHOE
| ISIG
| XCASE
| ECHOK
| ECHONL
| ECHOCTL
| ECHOPRT
| ECHOKE
| TOSTOP
);
221 if (parity
== PAR_NONE
)
223 m_options
.c_iflag
&= ~INPCK
;
227 m_options
.c_iflag
|= INPCK
| ISTRIP
;
230 m_options
.c_iflag
&= ~(IXON
| IXOFF
| IXANY
| BRKINT
| INLCR
| IGNCR
| ICRNL
| IUCLC
| IMAXBEL
);
231 m_options
.c_oflag
&= ~(OPOST
| ONLCR
| OCRNL
);
233 if (tcsetattr(m_fd
, TCSANOW
, &m_options
) != 0)
235 m_error
= strerror(errno
);
240 fcntl(m_fd
, F_SETFL
, FNDELAY
);
245 void CSerialPort::Close()
256 bool CSerialPort::SetBaudRate(int baudrate
)
258 int rate
= IntToBaudrate(baudrate
);
262 sprintf(buff
, "%i is not a valid baudrate", baudrate
);
267 //get the current port attributes
268 if (tcgetattr(m_fd
, &m_options
) != 0)
270 m_error
= strerror(errno
);
274 if (cfsetispeed(&m_options
, rate
) != 0)
276 m_error
= strerror(errno
);
280 if (cfsetospeed(&m_options
, rate
) != 0)
282 m_error
= strerror(errno
);
289 bool CSerialPort::IsOpen() const