comparison Serial.cpp @ 10:9a3c1a6f9833

TODO: FIX HW flow control definitions in case of problem during communication. Background: Flags are not defined in terminos header
author Ideenmodellierer
date Mon, 12 Jan 2026 13:55:38 +0000
parents 177f640940f2
children
comparison
equal deleted inserted replaced
9:971b9fd4cd30 10:9a3c1a6f9833
34 // 34 //
35 ////////////////////////////////////////////////////////////////////////////// 35 //////////////////////////////////////////////////////////////////////////////
36 36
37 #include "Serial.h" 37 #include "Serial.h"
38 38
39 #include "Utils/Exception.h"
39 #include "Utils/Log.h" 40 #include "Utils/Log.h"
40 #include "Utils/Exception.h"
41 41
42 #include <QString> 42 #include <QString>
43 43
44 #ifdef Q_OS_LINUX
45 #include <termios.h>
46 #endif
47
44 #ifdef WIN32 48 #ifdef WIN32
45 # define S_WRITE(p, b, li, lo) WriteFile(p, b, li, &lo, NULL) 49 #define S_WRITE(p, b, li, lo) WriteFile(p, b, li, &lo, NULL)
46 # define S_READ(p, b, li, lo) ReadFile(p, b, li, &lo, NULL) 50 #define S_READ(p, b, li, lo) ReadFile(p, b, li, &lo, NULL)
47 # define S_LEN DWORD 51 #define S_LEN DWORD
48 # define S_FLUSH(p) FlushFileBuffers(p) 52 #define S_FLUSH(p) FlushFileBuffers(p)
49 # define S_PURGE(p) PurgeComm(p, PURGE_RXCLEAR | PURGE_TXCLEAR) 53 #define S_PURGE(p) PurgeComm(p, PURGE_RXCLEAR | PURGE_TXCLEAR)
50 # define S_CLOSE(p) CloseHandle(p) 54 #define S_CLOSE(p) CloseHandle(p)
51 #else 55 #else
52 # include <fcntl.h> 56 #include <fcntl.h>
53 # include <termios.h> 57 #include <sys/ioctl.h>
54 # include <sys/ioctl.h> 58 #include <termios.h>
55 # include <unistd.h> 59 #include <unistd.h>
56 60
57 # define INVALID_HANDLE_VALUE (-1) 61 #define INVALID_HANDLE_VALUE (-1)
58 # define S_WRITE(p, b, li, lo) (lo = write(p, b, li)) 62 #define S_WRITE(p, b, li, lo) (lo = write(p, b, li))
59 # define S_READ(p, b, li, lo) (lo = read (p, b, li)) 63 #define S_READ(p, b, li, lo) (lo = read(p, b, li))
60 # define S_LEN ssize_t 64 #define S_LEN ssize_t
61 # define S_FLUSH(p) tcdrain(p) 65 #define S_FLUSH(p) tcdrain(p)
62 # define S_PURGE(p) tcflush(p,TCIOFLUSH) 66 #define S_PURGE(p) tcflush(p, TCIOFLUSH)
63 # define S_CLOSE(p) ::close(p) 67 #define S_CLOSE(p) ::close(p)
64 #endif 68 #endif
65 69
66 /////////////////////////////////////////////////////////////////////////////// 70 ///////////////////////////////////////////////////////////////////////////////
67 71
68 Serial::~Serial() 72 Serial::~Serial() {}
69 {} 73
70 74 ///////////////////////////////////////////////////////////////////////////////
71 /////////////////////////////////////////////////////////////////////////////// 75
72 76 void Serial::open(const QString &port, const QString &type)
73 void Serial::open(const QString& port, const QString &type) 77 {
74 { 78 if (_isOpen)
75 if( _isOpen ) return; 79 return;
76 LOG_TRACE("Open " << port << " ..."); 80 LOG_TRACE("Open " << port << " ...");
77 81
78 _hSerial = INVALID_HANDLE_VALUE; 82 _hSerial = INVALID_HANDLE_VALUE;
79 83
80 //------------------------------------------------------------------------ 84 //------------------------------------------------------------------------
81 // Sanity checks. 85 // Sanity checks.
82 if( port.isEmpty() ) 86 if (port.isEmpty())
83 LOG_THROW( "Port is not defined." ); 87 LOG_THROW("Port is not defined.");
84 if( type.isEmpty() ) 88 if (type.isEmpty())
85 LOG_THROW( "Port type is not defined." ); 89 LOG_THROW("Port type is not defined.");
86 90
87 bool usbMode = type.contains("ostc2c", Qt::CaseInsensitive) 91 bool usbMode = type.contains("ostc2c", Qt::CaseInsensitive)
88 || ( type.contains("ostc3", Qt::CaseInsensitive) 92 || (type.contains("ostc3", Qt::CaseInsensitive)
89 && !type.contains("ostc3p", Qt::CaseInsensitive)) 93 && !type.contains("ostc3p", Qt::CaseInsensitive))
90 || type.contains("ostc_cr", Qt::CaseInsensitive); 94 || type.contains("ostc_cr", Qt::CaseInsensitive);
91 LOG_TRACE((usbMode ? "Fast USB" : "Slow Bluetooth") << " connection mode."); 95 LOG_TRACE((usbMode ? "Fast USB" : "Slow Bluetooth") << " connection mode.");
92 96
93 //------------------------------------------------------------------------ 97 //------------------------------------------------------------------------
94 #ifdef Q_OS_WIN 98 #ifdef Q_OS_WIN
95 // BUGFIX: COM ports above COM9 are not automatically recognized, 99 // BUGFIX: COM ports above COM9 are not automatically recognized,
96 // hence we have to prepend DEVICE NAMESPACE... 100 // hence we have to prepend DEVICE NAMESPACE...
97 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx 101 // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
98 QByteArray com = port.toLatin1() + "\0"; 102 QByteArray com = port.toLatin1() + "\0";
99 if( !com.startsWith("\\\\.\\") ) 103 if (!com.startsWith("\\\\.\\"))
100 com = "\\\\.\\" + com; 104 com = "\\\\.\\" + com;
101 105
102 _hSerial = CreateFileA(com.data(), 106 _hSerial = CreateFileA(com.data(),
103 GENERIC_READ | GENERIC_WRITE, 107 GENERIC_READ | GENERIC_WRITE,
104 0, // Exclusive access. 108 0, // Exclusive access.
105 NULL, // No security 109 NULL, // No security
106 OPEN_EXISTING, 110 OPEN_EXISTING,
107 FILE_ATTRIBUTE_DEVICE | FILE_FLAG_NO_BUFFERING, 111 FILE_ATTRIBUTE_DEVICE | FILE_FLAG_NO_BUFFERING,
108 0); 112 0);
109 if(_hSerial==INVALID_HANDLE_VALUE) 113 if (_hSerial == INVALID_HANDLE_VALUE) {
110 { 114 if (GetLastError() == ERROR_FILE_NOT_FOUND)
111 if(GetLastError()==ERROR_FILE_NOT_FOUND) 115 LOG_THROW("Unknown port");
112 LOG_THROW( "Unknown port" ); 116 LOG_THROW("Unable to open port");
113 LOG_THROW( "Unable to open port" );
114 } 117 }
115 S_PURGE(_hSerial); 118 S_PURGE(_hSerial);
116 119
117 DCB dcbSerial = {sizeof(dcbSerial), 0}; 120 DCB dcbSerial = {sizeof(dcbSerial), 0};
118 if( !GetCommState(_hSerial, &dcbSerial) ) 121 if (!GetCommState(_hSerial, &dcbSerial))
119 LOG_THROW( "Unable to get COM port config" ); 122 LOG_THROW("Unable to get COM port config");
120 123
121 dcbSerial.BaudRate = CBR_115200; 124 dcbSerial.BaudRate = CBR_115200;
122 dcbSerial.ByteSize = 8; 125 dcbSerial.ByteSize = 8;
123 dcbSerial.Parity = NOPARITY; 126 dcbSerial.Parity = NOPARITY;
124 dcbSerial.StopBits = ONESTOPBIT; 127 dcbSerial.StopBits = ONESTOPBIT;
125 dcbSerial.fOutxCtsFlow = DTR_CONTROL_ENABLE; // NO HARDWARE FLOW CONTROL 128 dcbSerial.fOutxCtsFlow = DTR_CONTROL_ENABLE; // NO HARDWARE FLOW CONTROL
126 dcbSerial.fRtsControl = RTS_CONTROL_ENABLE; //RTS_CONTROL_DISABLE; // NO HARDWARE FLOW CONTROL 129 dcbSerial.fRtsControl = RTS_CONTROL_ENABLE; //RTS_CONTROL_DISABLE; // NO HARDWARE FLOW CONTROL
127 130
128 if( !SetCommState(_hSerial, &dcbSerial) ) 131 if (!SetCommState(_hSerial, &dcbSerial))
129 LOG_THROW( "Unable to set COM port config" ); 132 LOG_THROW("Unable to set COM port config");
130 133
131 COMMTIMEOUTS timeouts={0}; 134 COMMTIMEOUTS timeouts = {0};
132 if( usbMode ) { 135 if (usbMode) {
133 timeouts.ReadTotalTimeoutConstant = 500; // 0.5 sec 136 timeouts.ReadTotalTimeoutConstant = 500; // 0.5 sec
134 timeouts.WriteTotalTimeoutConstant = 1000; // 1.0 sec 137 timeouts.WriteTotalTimeoutConstant = 1000; // 1.0 sec
135 } else { 138 } else {
136 timeouts.ReadTotalTimeoutConstant = 2000; // 2.0 sec timeout. 139 timeouts.ReadTotalTimeoutConstant = 2000; // 2.0 sec timeout.
137 } 140 }
138 if( !SetCommTimeouts(_hSerial, &timeouts) ) 141 if (!SetCommTimeouts(_hSerial, &timeouts))
139 LOG_THROW( "Unable to configure port" ); 142 LOG_THROW("Unable to configure port");
140 143
141 LOG_TRACE("Connection:"); 144 LOG_TRACE("Connection:");
142 LOG_TRACE(" " << dcbSerial.BaudRate << " bauds."); 145 LOG_TRACE(" " << dcbSerial.BaudRate << " bauds.");
143 LOG_TRACE(" " << (int)dcbSerial.ByteSize << " bits, " 146 LOG_TRACE(
144 << (dcbSerial.Parity ? "+parity, " : "no parity, ") 147 " " << (int) dcbSerial.ByteSize << " bits, "
145 << (dcbSerial.StopBits ? QString(" +%1").arg(dcbSerial.StopBits) : QString("no")) << " stops bits."); 148 << (dcbSerial.Parity ? "+parity, " : "no parity, ")
149 << (dcbSerial.StopBits ? QString(" +%1").arg(dcbSerial.StopBits) : QString("no"))
150 << " stops bits.");
146 LOG_TRACE(" CTS is " << (dcbSerial.fOutxCtsFlow ? "ON." : "OFF.")); 151 LOG_TRACE(" CTS is " << (dcbSerial.fOutxCtsFlow ? "ON." : "OFF."));
147 LOG_TRACE(" RTS is " << ((dcbSerial.fRtsControl == RTS_CONTROL_HANDSHAKE) ? "ON." 152 LOG_TRACE(" RTS is " << ((dcbSerial.fRtsControl == RTS_CONTROL_HANDSHAKE) ? "ON."
148 : (dcbSerial.fRtsControl == RTS_CONTROL_ENABLE) ? "FORCED." 153 : (dcbSerial.fRtsControl == RTS_CONTROL_ENABLE) ? "FORCED."
149 : "OFF.")); 154 : "OFF."));
150 LOG_TRACE(" Read timeout " << timeouts.ReadTotalTimeoutConstant << " msec."); 155 LOG_TRACE(" Read timeout " << timeouts.ReadTotalTimeoutConstant << " msec.");
151 LOG_TRACE(" Write timeout " << timeouts.WriteTotalTimeoutConstant << " msec."); 156 LOG_TRACE(" Write timeout " << timeouts.WriteTotalTimeoutConstant << " msec.");
152 #endif 157 #endif
153 158
154 //------------------------------------------------------------------------ 159 //------------------------------------------------------------------------
155 #if defined(Q_OS_MAC) || defined(Q_OS_LINUX) 160 #if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
156 QByteArray p = port.toLatin1(); 161 QByteArray p = port.toLatin1();
157 if( ! p.startsWith("/dev/") ) 162 if (!p.startsWith("/dev/"))
158 p = "/dev/" + p; 163 p = "/dev/" + p;
159 _hSerial = ::open( p.constData(), O_RDWR | O_NOCTTY | O_NONBLOCK, 0); 164 _hSerial = ::open(p.constData(), O_RDWR | O_NOCTTY | O_NONBLOCK, 0);
160 if( _hSerial<0 ) 165 if (_hSerial < 0)
161 LOG_THROW( "Unable to open port " << p); 166 LOG_THROW("Unable to open port " << p);
162 167
163 if( ioctl(_hSerial, TIOCEXCL) < 0 ) 168 if (ioctl(_hSerial, TIOCEXCL) < 0)
164 LOG_THROW( "Port in use" ); 169 LOG_THROW("Port in use");
165 170
166 // Once opened, clearing the O_NONBLOCK flag. 171 // Once opened, clearing the O_NONBLOCK flag.
167 if( fcntl(_hSerial, F_SETFL, 0) < 0 ) 172 if (fcntl(_hSerial, F_SETFL, 0) < 0)
168 LOG_THROW( "Can't reset non-blocking I/O" ); 173 LOG_THROW("Can't reset non-blocking I/O");
169 174
170 struct termios termios; 175 struct termios termios;
171 tcgetattr(_hSerial, &termios); 176 tcgetattr(_hSerial, &termios);
172 177
173 cfmakeraw(&termios); 178 cfmakeraw(&termios);
174 if( cfsetspeed(&termios, B115200) < 0 ) 179 if (cfsetspeed(&termios, B115200) < 0)
175 LOG_THROW( "Bad port speed" ); 180 LOG_THROW("Bad port speed");
176 181
177 termios.c_cflag |= CLOCAL| CS8 | CREAD; // No DTR/DSR/DCD, 8bit. 182 termios.c_cflag |= CLOCAL | CS8 | CREAD; // No DTR/DSR/DCD, 8bit.
178 termios.c_cflag &= ~( PARENB | CSTOPB // No parity, one stop bit. 183 termios.c_cflag &= ~(PARENB | CSTOPB ); // No parity, one stop bit.
179 | CCTS_OFLOW | CRTS_IFLOW); // No hardware flow control. 184 // | CCTS_OFLOW | CRTS_IFLOW); // No hardware flow control.
180 185
181 if( usbMode ) { 186 if (usbMode) {
182 // FAST USB: Fix timeout to 0.5 seconde: 187 // FAST USB: Fix timeout to 0.5 seconde:
183 termios.c_cc[VMIN] = 0; // Pure timout mode (no char needed). 188 termios.c_cc[VMIN] = 0; // Pure timout mode (no char needed).
184 termios.c_cc[VTIME] = 5; // 0.5s timeout after last received byte. 189 termios.c_cc[VTIME] = 5; // 0.5s timeout after last received byte.
185 } else { 190 } else {
186 // SLOW BLUETOOTH: Fix timeout to 2.0 sec: 191 // SLOW BLUETOOTH: Fix timeout to 2.0 sec:
187 termios.c_cc[VMIN] = 0; // Pure timout mode (no char needed). 192 termios.c_cc[VMIN] = 0; // Pure timout mode (no char needed).
188 termios.c_cc[VTIME] = 20; // 2.0sec timeout after last received byte. 193 termios.c_cc[VTIME] = 20; // 2.0sec timeout after last received byte.
189 } 194 }
190 195
191 if( tcsetattr(_hSerial, TCSANOW, &termios) < 0 ) 196 if (tcsetattr(_hSerial, TCSANOW, &termios) < 0)
192 LOG_THROW( "Unable to configure port" ); 197 LOG_THROW("Unable to configure port");
193 #endif 198 #endif
194 199
195 if( _hSerial == INVALID_HANDLE_VALUE ) 200 if (_hSerial == INVALID_HANDLE_VALUE)
196 LOG_THROW( "Port not open" ); 201 LOG_THROW("Port not open");
197 202
198 _isOpen = true; 203 _isOpen = true;
199 LOG_TRACE("Device open successfull."); 204 LOG_TRACE("Device open successfull.");
200 } 205 }
201 206
202 /////////////////////////////////////////////////////////////////////////////// 207 ///////////////////////////////////////////////////////////////////////////////
203 208
204 void Serial::close() 209 void Serial::close()
205 { 210 {
206 if( !_isOpen ) return; 211 if (!_isOpen)
212 return;
207 LOG_TRACE("Device close ..."); 213 LOG_TRACE("Device close ...");
208 214
209 #ifdef Q_OS_MAC 215 #ifdef Q_OS_MAC
210 if( ioctl(_hSerial, TIOCNXCL) < 0 ) 216 if (ioctl(_hSerial, TIOCNXCL) < 0)
211 LOG_THROW( "Port in use" ); 217 LOG_THROW("Port in use");
212 #endif 218 #endif
213 219
214 if( _hSerial == INVALID_HANDLE_VALUE ) 220 if (_hSerial == INVALID_HANDLE_VALUE)
215 LOG_THROW( "Port not open" ); 221 LOG_THROW("Port not open");
216 S_CLOSE(_hSerial); 222 S_CLOSE(_hSerial);
217 223
218 _hSerial = INVALID_HANDLE_VALUE; 224 _hSerial = INVALID_HANDLE_VALUE;
219 _isOpen = false; 225 _isOpen = false;
220 LOG_TRACE("Device close successfull."); 226 LOG_TRACE("Device close successfull.");
221 } 227 }
222 228
223 /////////////////////////////////////////////////////////////////////////////// 229 ///////////////////////////////////////////////////////////////////////////////
224 230
225 unsigned char Serial::readByte() const 231 unsigned char Serial::readByte() const
226 { 232 {
227 if( !_isOpen ) 233 if (!_isOpen)
228 LOG_THROW( "Port not open" ); 234 LOG_THROW("Port not open");
229 235
230 unsigned char byte = 0; 236 unsigned char byte = 0;
231 S_LEN len = 0; 237 S_LEN len = 0;
232 S_READ(_hSerial, &byte, 1, len); 238 S_READ(_hSerial, &byte, 1, len);
233 if( len != 1 ) 239 if (len != 1)
234 LOG_THROW_E(ReadTimeout, "< timeout" ); 240 LOG_THROW_E(ReadTimeout, "< timeout");
235 241
236 if( isprint(byte) ) 242 if (isprint(byte))
237 LOG_DEBUG("< " << QString::asprintf("%02x '%c'", byte, byte)); 243 LOG_DEBUG("< " << QString::asprintf("%02x '%c'", byte, byte));
238 else 244 else
239 LOG_DEBUG("< " << QString::asprintf("%02x", byte) ); 245 LOG_DEBUG("< " << QString::asprintf("%02x", byte));
240 246
241 return byte; 247 return byte;
242 } 248 }
243 249
244 void Serial::writeByte(unsigned char byte) const 250 void Serial::writeByte(unsigned char byte) const
245 { 251 {
246 if( !_isOpen ) 252 if (!_isOpen)
247 LOG_THROW( "Port not open" ); 253 LOG_THROW("Port not open");
248 254
249 if( isprint(byte) ) 255 if (isprint(byte))
250 LOG_DEBUG("> " << QString::asprintf("%02x '%c'", byte, byte) ); 256 LOG_DEBUG("> " << QString::asprintf("%02x '%c'", byte, byte));
251 else 257 else
252 LOG_DEBUG("> " << QString::asprintf("%02x", byte) ); 258 LOG_DEBUG("> " << QString::asprintf("%02x", byte));
253 259
254 S_LEN len = 0; 260 S_LEN len = 0;
255 S_WRITE(_hSerial, &byte, 1, len); 261 S_WRITE(_hSerial, &byte, 1, len);
256 if( len != 1 ) 262 if (len != 1)
257 // LOG_THROW_E(WriteTimeout, "> timeout"); 263 // LOG_THROW_E(WriteTimeout, "> timeout");
258 LOG_THROW("> timeout"); 264 LOG_THROW("> timeout");
259 } 265 }
260 266
261 /////////////////////////////////////////////////////////////////////////////// 267 ///////////////////////////////////////////////////////////////////////////////
262 268
263 unsigned short Serial::readShort() const 269 unsigned short Serial::readShort() const
269 275
270 void Serial::writeShort(unsigned short word) const 276 void Serial::writeShort(unsigned short word) const
271 { 277 {
272 unsigned char lo = word & 0xFF; 278 unsigned char lo = word & 0xFF;
273 unsigned char hi = word >> 8; 279 unsigned char hi = word >> 8;
274 writeByte(lo); writeByte(hi); 280 writeByte(lo);
281 writeByte(hi);
275 } 282 }
276 283
277 /////////////////////////////////////////////////////////////////////////////// 284 ///////////////////////////////////////////////////////////////////////////////
278 285
279 void Serial::writeInt24(unsigned int int24) const 286 void Serial::writeInt24(unsigned int int24) const
280 { 287 {
281 unsigned char lo = int24 & 0xFF; 288 unsigned char lo = int24 & 0xFF;
282 unsigned char hi = (int24 >> 8) & 0xFF; 289 unsigned char hi = (int24 >> 8) & 0xFF;
283 unsigned char up = (int24 >> 16) & 0xFF; 290 unsigned char up = (int24 >> 16) & 0xFF;
284 writeByte(lo); writeByte(hi); writeByte(up); 291 writeByte(lo);
292 writeByte(hi);
293 writeByte(up);
285 } 294 }
286 295
287 unsigned int Serial::readInt24() const 296 unsigned int Serial::readInt24() const
288 { 297 {
289 unsigned char lo = readByte(); 298 unsigned char lo = readByte();
292 return up << 16 | hi << 8 | lo; 301 return up << 16 | hi << 8 | lo;
293 } 302 }
294 303
295 /////////////////////////////////////////////////////////////////////////////// 304 ///////////////////////////////////////////////////////////////////////////////
296 305
297 unsigned int Serial::readBlock(unsigned char* ptr, unsigned int size) const 306 unsigned int Serial::readBlock(unsigned char *ptr, unsigned int size) const
298 { 307 {
299 if( !_isOpen ) 308 if (!_isOpen)
300 LOG_THROW( "Port not open" ); 309 LOG_THROW("Port not open");
301 310
302 unsigned int bytes = 0; 311 unsigned int bytes = 0;
303 312
304 bool timeout = false; 313 bool timeout = false;
305 while( size > 0 ) 314 while (size > 0) {
306 {
307 // Allow up to 1.0sec for each 4K block. 315 // Allow up to 1.0sec for each 4K block.
308 S_LEN todo = (size > 4096) ? 4096 : size; 316 S_LEN todo = (size > 4096) ? 4096 : size;
309 S_LEN done = 0; 317 S_LEN done = 0;
310 S_READ(_hSerial, ptr+bytes, todo, done); 318 S_READ(_hSerial, ptr + bytes, todo, done);
311 319
312 if( done == 0 ) { 320 if (done == 0) {
313 timeout = true; 321 timeout = true;
314 break; 322 break;
315 } 323 }
316 324
317 size -= done; 325 size -= done;
318 bytes += (unsigned int)done; 326 bytes += (unsigned int) done;
319 } 327 }
320 328
321 if( Log::minLevel <= Log::LEVEL_DEBUG ) 329 if (Log::minLevel <= Log::LEVEL_DEBUG) {
322 {
323 const int DUMP_LINE = 16; 330 const int DUMP_LINE = 16;
324 const int DUMP_MAX = 3*DUMP_LINE; 331 const int DUMP_MAX = 3 * DUMP_LINE;
325 const unsigned int length = (bytes < DUMP_MAX) ? bytes : DUMP_MAX; 332 const unsigned int length = (bytes < DUMP_MAX) ? bytes : DUMP_MAX;
326 for(unsigned int i=0; i<length; i += DUMP_LINE) 333 for (unsigned int i = 0; i < length; i += DUMP_LINE) {
327 { 334 LogAction logger(Log::LEVEL_DEBUG, __FILE__, __LINE__, "readBlock()");
328 LogAction logger(Log::LEVEL_DEBUG, __FILE__ ,__LINE__, "readBlock()");
329 logger << "< "; 335 logger << "< ";
330 for(unsigned int j=i; j<bytes && j<(i+DUMP_LINE); ++j) 336 for (unsigned int j = i; j < bytes && j < (i + DUMP_LINE); ++j)
331 logger << QString::asprintf("%02x ", ptr[j]); 337 logger << QString::asprintf("%02x ", ptr[j]);
332 for(unsigned int j=i; j<bytes && j<(i+DUMP_LINE); ++j) 338 for (unsigned int j = i; j < bytes && j < (i + DUMP_LINE); ++j)
333 logger << (isprint( ptr[j] ) 339 logger << (isprint(ptr[j]) ? ptr[j] : (unsigned char) '.');
334 ? ptr[j]
335 : (unsigned char)'.');
336 } 340 }
337 if( length < bytes ) 341 if (length < bytes)
338 LOG_DEBUG("< ... " << (bytes-length) << " more bytes."); 342 LOG_DEBUG("< ... " << (bytes - length) << " more bytes.");
339 } 343 }
340 344
341 if( timeout ) 345 if (timeout)
342 LOG_THROW_E(ReadTimeout, "< block timeout (missing " << size << " bytes)"); 346 LOG_THROW_E(ReadTimeout, "< block timeout (missing " << size << " bytes)");
343 347
344 return bytes; 348 return bytes;
345 } 349 }
346 350
347 /////////////////////////////////////////////////////////////////////////////// 351 ///////////////////////////////////////////////////////////////////////////////
348 352
349 void Serial::writeBlock(const unsigned char* ptr, unsigned int size) const 353 void Serial::writeBlock(const unsigned char *ptr, unsigned int size) const
350 { 354 {
351 if( !_isOpen ) 355 if (!_isOpen)
352 LOG_THROW( "Port not open" ); 356 LOG_THROW("Port not open");
353 357
354 if( Log::minLevel <= Log::LEVEL_DEBUG ) 358 if (Log::minLevel <= Log::LEVEL_DEBUG) {
355 {
356 const int DUMP_LINE = 16; 359 const int DUMP_LINE = 16;
357 const int DUMP_MAX = 3*DUMP_LINE; 360 const int DUMP_MAX = 3 * DUMP_LINE;
358 const unsigned int length = (size < DUMP_MAX) ? size : DUMP_MAX; 361 const unsigned int length = (size < DUMP_MAX) ? size : DUMP_MAX;
359 for(unsigned int i=0; i<length; i += DUMP_LINE) 362 for (unsigned int i = 0; i < length; i += DUMP_LINE) {
360 { 363 LogAction logger(Log::LEVEL_DEBUG, __FILE__, __LINE__, "writeBlock()");
361 LogAction logger(Log::LEVEL_DEBUG, __FILE__ ,__LINE__, "writeBlock()");
362 logger << "> "; 364 logger << "> ";
363 for(unsigned int j=i; j<size && j<(i+DUMP_LINE); ++j) 365 for (unsigned int j = i; j < size && j < (i + DUMP_LINE); ++j)
364 logger << QString::asprintf("%02x ", ptr[j]); 366 logger << QString::asprintf("%02x ", ptr[j]);
365 for(unsigned int j=i; j<size && j<(i+DUMP_LINE); ++j) 367 for (unsigned int j = i; j < size && j < (i + DUMP_LINE); ++j)
366 logger << (isprint( ptr[j] ) 368 logger << (isprint(ptr[j]) ? ptr[j] : (unsigned char) '.');
367 ? ptr[j]
368 : (unsigned char)'.');
369 } 369 }
370 if( length < size ) 370 if (length < size)
371 LOG_DEBUG("> ... " << (size-length) << " more bytes."); 371 LOG_DEBUG("> ... " << (size - length) << " more bytes.");
372 } 372 }
373 373
374 while( size > 0 ) 374 while (size > 0) {
375 {
376 // Allow up to 1.0sec for each 4K block. 375 // Allow up to 1.0sec for each 4K block.
377 S_LEN chunck = (size > 4096) ? 4096 : size; 376 S_LEN chunck = (size > 4096) ? 4096 : size;
378 S_LEN len = 0; 377 S_LEN len = 0;
379 S_WRITE(_hSerial, ptr, chunck, len); 378 S_WRITE(_hSerial, ptr, chunck, len);
380 379
381 if( len == 0 ) 380 if (len == 0)
382 LOG_THROW_E(WriteTimeout, "> block timeout"); 381 LOG_THROW_E(WriteTimeout, "> block timeout");
383 382
384 size -= len; 383 size -= len;
385 ptr += len; 384 ptr += len;
386 } 385 }
387 386
388 // Auto-fluh on each write. 387 // Auto-fluh on each write.
389 flush(); 388 flush();
390 } 389 }
391 390
392 /////////////////////////////////////////////////////////////////////////////// 391 ///////////////////////////////////////////////////////////////////////////////
393 392
394 void Serial::purge() 393 void Serial::purge()
395 { 394 {
396 if( !_isOpen ) 395 if (!_isOpen)
397 LOG_THROW( "Port not open" ); 396 LOG_THROW("Port not open");
398 397
399 // Empty incomming buffer 398 // Empty incomming buffer
400 S_PURGE(_hSerial); 399 S_PURGE(_hSerial);
401 400
402 LOG_TRACE("Device purged."); 401 LOG_TRACE("Device purged.");
404 403
405 /////////////////////////////////////////////////////////////////////////////// 404 ///////////////////////////////////////////////////////////////////////////////
406 405
407 void Serial::flush() const 406 void Serial::flush() const
408 { 407 {
409 if( !_isOpen ) 408 if (!_isOpen)
410 LOG_THROW( "Port not open" ); 409 LOG_THROW("Port not open");
411 410
412 S_FLUSH(_hSerial); 411 S_FLUSH(_hSerial);
413 } 412 }
414 413
415 /////////////////////////////////////////////////////////////////////////////// 414 ///////////////////////////////////////////////////////////////////////////////
417 void Serial::sleep(int msec) const 416 void Serial::sleep(int msec) const
418 { 417 {
419 #ifdef WIN32 418 #ifdef WIN32
420 Sleep(msec); 419 Sleep(msec);
421 #else 420 #else
422 usleep(msec*1000); 421 usleep(msec * 1000);
423 #endif 422 #endif
424 } 423 }