33a7385212989238980c7aefe6a1bb9db5ea09ad
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/>.
19 #include <iostream>//debug
25 #include "../serialport.h"
26 #include "../baudrate.h"
27 #include "../../util/misc.h"
28 #include "../../util/timeutils.h"
32 CSerialPort::CSerialPort()
37 CSerialPort::~CSerialPort()
42 int CSerialPort::Write(uint8_t* data
, int len
)
48 m_error
= "port closed";
54 while (byteswritten
< len
)
58 int returnv
= select(m_fd
+ 1, NULL
, &port
, NULL
, NULL
);
65 returnv
= write(m_fd
, data
+ byteswritten
, len
- byteswritten
);
71 byteswritten
+= returnv
;
74 //print what's written to stdout for debugging
77 // printf("%s write:", m_name.c_str());
78 // for (int i = 0; i < byteswritten; i++)
79 // printf(" %02x", (unsigned int)data[i]);
87 int CSerialPort::Read(uint8_t* data
, int len
, int iTimeoutMs
/*= -1*/)
90 struct timeval timeout
, *tv
;
96 m_error
= "port closed";
103 target
= now
+ (int64_t) iTimeoutMs
;
106 while (bytesread
< len
&& (iTimeoutMs
< 0 || target
> now
))
114 timeout
.tv_sec
= ((long int)target
- (long int)now
) / (long int)1000.;
115 timeout
.tv_usec
= ((long int)target
- (long int)now
) % (long int)1000.;
121 int returnv
= select(m_fd
+ 1, &port
, NULL
, NULL
, tv
);
125 m_error
= GetErrno();
128 else if (returnv
== 0)
130 break; //nothing to read
133 returnv
= read(m_fd
, data
+ bytesread
, len
- bytesread
);
136 m_error
= GetErrno();
140 bytesread
+= returnv
;
146 //print what's read to stdout for debugging
147 // if (m_tostdout && bytesread > 0)
149 // printf("%s read:", m_name.c_str());
150 // for (int i = 0; i < bytesread; i++)
151 // printf(" %02x", (unsigned int)data[i]);
159 //setting all this stuff up is a pain in the ass
160 bool CSerialPort::Open(string name
, int baudrate
, int databits
/* = 8*/, int stopbits
/* = 1*/, int parity
/* = PAR_NONE*/)
163 m_error
= GetErrno();
165 if (databits
< 5 || databits
> 8)
167 m_error
= "Databits has to be between 5 and 8";
171 if (stopbits
!= 1 && stopbits
!= 2)
173 m_error
= "Stopbits has to be 1 or 2";
177 if (parity
!= PAR_NONE
&& parity
!= PAR_EVEN
&& parity
!= PAR_ODD
)
179 m_error
= "Parity has to be none, even or odd";
183 m_fd
= open(name
.c_str(), O_RDWR
| O_NOCTTY
| O_NDELAY
);
187 m_error
= GetErrno();
191 fcntl(m_fd
, F_SETFL
, 0);
193 if (!SetBaudRate(baudrate
))
198 m_options
.c_cflag
|= (CLOCAL
| CREAD
);
199 m_options
.c_cflag
&= ~HUPCL
;
201 m_options
.c_cflag
&= ~CSIZE
;
202 if (databits
== 5) m_options
.c_cflag
|= CS5
;
203 if (databits
== 6) m_options
.c_cflag
|= CS6
;
204 if (databits
== 7) m_options
.c_cflag
|= CS7
;
205 if (databits
== 8) m_options
.c_cflag
|= CS8
;
207 m_options
.c_cflag
&= ~PARENB
;
208 if (parity
== PAR_EVEN
|| parity
== PAR_ODD
)
209 m_options
.c_cflag
|= PARENB
;
210 if (parity
== PAR_ODD
)
211 m_options
.c_cflag
|= PARODD
;
214 m_options
.c_cflag
&= ~CRTSCTS
;
215 #elif defined(CNEW_RTSCTS)
216 m_options
.c_cflag
&= ~CNEW_RTSCTS
;
219 if (stopbits
== 1) m_options
.c_cflag
&= ~CSTOPB
;
220 else m_options
.c_cflag
|= CSTOPB
;
222 //I guessed a little here
223 m_options
.c_lflag
&= ~(ICANON
| ECHO
| ECHOE
| ISIG
| XCASE
| ECHOK
| ECHONL
| ECHOCTL
| ECHOPRT
| ECHOKE
| TOSTOP
);
225 if (parity
== PAR_NONE
)
227 m_options
.c_iflag
&= ~INPCK
;
231 m_options
.c_iflag
|= INPCK
| ISTRIP
;
234 m_options
.c_iflag
&= ~(IXON
| IXOFF
| IXANY
| BRKINT
| INLCR
| IGNCR
| ICRNL
| IUCLC
| IMAXBEL
);
235 m_options
.c_oflag
&= ~(OPOST
| ONLCR
| OCRNL
);
237 if (tcsetattr(m_fd
, TCSANOW
, &m_options
) != 0)
239 m_error
= GetErrno();
244 fcntl(m_fd
, F_SETFL
, FNDELAY
);
249 void CSerialPort::Close()
260 bool CSerialPort::SetBaudRate(int baudrate
)
262 int rate
= IntToRate(baudrate
);
266 sprintf(buff
, "%i is not a valid baudrate", baudrate
);
271 //get the current port attributes
272 if (tcgetattr(m_fd
, &m_options
) != 0)
274 m_error
= GetErrno();
278 if (cfsetispeed(&m_options
, rate
) != 0)
280 m_error
= GetErrno();
284 if (cfsetospeed(&m_options
, rate
) != 0)
286 m_error
= GetErrno();