Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(331)

Side by Side Diff: device/serial/serial_io_handler_win.cc

Issue 873903002: Set serial connection parameters immediately on connect. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add a comment explaing the "set" notation. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « device/serial/serial_io_handler_win.h ('k') | device/serial/serial_service_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <windows.h> 5 #include <windows.h>
6 6
7 #include "device/serial/serial_io_handler_win.h" 7 #include "device/serial/serial_io_handler_win.h"
8 8
9 namespace device { 9 namespace device {
10 10
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 write_context_->handler = this; 160 write_context_->handler = this;
161 memset(&write_context_->overlapped, 0, sizeof(write_context_->overlapped)); 161 memset(&write_context_->overlapped, 0, sizeof(write_context_->overlapped));
162 162
163 // A ReadIntervalTimeout of MAXDWORD will cause async reads to complete 163 // A ReadIntervalTimeout of MAXDWORD will cause async reads to complete
164 // immediately with any data that's available, even if there is none. 164 // immediately with any data that's available, even if there is none.
165 // This is OK because we never issue a read request until WaitCommEvent 165 // This is OK because we never issue a read request until WaitCommEvent
166 // signals that data is available. 166 // signals that data is available.
167 COMMTIMEOUTS timeouts = {0}; 167 COMMTIMEOUTS timeouts = {0};
168 timeouts.ReadIntervalTimeout = MAXDWORD; 168 timeouts.ReadIntervalTimeout = MAXDWORD;
169 if (!::SetCommTimeouts(file().GetPlatformFile(), &timeouts)) { 169 if (!::SetCommTimeouts(file().GetPlatformFile(), &timeouts)) {
170 VPLOG(1) << "Failed to set serial timeouts";
170 return false; 171 return false;
171 } 172 }
172 173
173 DCB config = {0}; 174 return true;
174 config.DCBlength = sizeof(config);
175 if (!GetCommState(file().GetPlatformFile(), &config)) {
176 return false;
177 }
178 // Setup some sane default state.
179 config.fBinary = TRUE;
180 config.fParity = FALSE;
181 config.fAbortOnError = TRUE;
182 config.fOutxCtsFlow = FALSE;
183 config.fOutxDsrFlow = FALSE;
184 config.fRtsControl = RTS_CONTROL_ENABLE;
185 config.fDtrControl = DTR_CONTROL_ENABLE;
186 config.fDsrSensitivity = FALSE;
187 config.fOutX = FALSE;
188 config.fInX = FALSE;
189 return SetCommState(file().GetPlatformFile(), &config) != 0;
190 } 175 }
191 176
192 void SerialIoHandlerWin::ReadImpl() { 177 void SerialIoHandlerWin::ReadImpl() {
193 DCHECK(CalledOnValidThread()); 178 DCHECK(CalledOnValidThread());
194 DCHECK(pending_read_buffer()); 179 DCHECK(pending_read_buffer());
195 DCHECK(file().IsValid()); 180 DCHECK(file().IsValid());
196 181
197 DWORD errors; 182 DWORD errors;
198 COMSTAT status; 183 COMSTAT status;
199 if (!ClearCommError(file().GetPlatformFile(), &errors, &status) || 184 if (!ClearCommError(file().GetPlatformFile(), &errors, &status) ||
200 errors != 0) { 185 errors != 0) {
201 QueueReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); 186 QueueReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR);
202 return; 187 return;
203 } 188 }
204 189
205 SetCommMask(file().GetPlatformFile(), EV_RXCHAR); 190 if (!SetCommMask(file().GetPlatformFile(), EV_RXCHAR)) {
191 VPLOG(1) << "Failed to set serial event flags";
192 }
206 193
207 event_mask_ = 0; 194 event_mask_ = 0;
208 BOOL ok = ::WaitCommEvent( 195 BOOL ok = ::WaitCommEvent(
209 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped); 196 file().GetPlatformFile(), &event_mask_, &comm_context_->overlapped);
210 if (!ok && GetLastError() != ERROR_IO_PENDING) { 197 if (!ok && GetLastError() != ERROR_IO_PENDING) {
198 VPLOG(1) << "Failed to receive serial event";
211 QueueReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR); 199 QueueReadCompleted(0, serial::RECEIVE_ERROR_SYSTEM_ERROR);
212 } 200 }
213 is_comm_pending_ = true; 201 is_comm_pending_ = true;
214 } 202 }
215 203
216 void SerialIoHandlerWin::WriteImpl() { 204 void SerialIoHandlerWin::WriteImpl() {
217 DCHECK(CalledOnValidThread()); 205 DCHECK(CalledOnValidThread());
218 DCHECK(pending_write_buffer()); 206 DCHECK(pending_write_buffer());
219 DCHECK(file().IsValid()); 207 DCHECK(file().IsValid());
220 208
(...skipping 12 matching lines...) Expand all
233 DCHECK(file().IsValid()); 221 DCHECK(file().IsValid());
234 ::CancelIo(file().GetPlatformFile()); 222 ::CancelIo(file().GetPlatformFile());
235 } 223 }
236 224
237 void SerialIoHandlerWin::CancelWriteImpl() { 225 void SerialIoHandlerWin::CancelWriteImpl() {
238 DCHECK(CalledOnValidThread()); 226 DCHECK(CalledOnValidThread());
239 DCHECK(file().IsValid()); 227 DCHECK(file().IsValid());
240 ::CancelIo(file().GetPlatformFile()); 228 ::CancelIo(file().GetPlatformFile());
241 } 229 }
242 230
231 bool SerialIoHandlerWin::ConfigurePortImpl() {
232 DCB config = {0};
233 config.DCBlength = sizeof(config);
234 if (!GetCommState(file().GetPlatformFile(), &config)) {
235 VPLOG(1) << "Failed to get serial port info";
236 return false;
237 }
238
239 // Set up some sane default options that are not configurable.
240 config.fBinary = TRUE;
241 config.fParity = FALSE;
242 config.fAbortOnError = TRUE;
243 config.fOutxDsrFlow = FALSE;
244 config.fDtrControl = DTR_CONTROL_ENABLE;
245 config.fDsrSensitivity = FALSE;
246 config.fOutX = FALSE;
247 config.fInX = FALSE;
248
249 DCHECK(options().bitrate);
250 config.BaudRate = BitrateToSpeedConstant(options().bitrate);
251
252 DCHECK(options().data_bits != serial::DATA_BITS_NONE);
253 config.ByteSize = DataBitsEnumToConstant(options().data_bits);
254
255 DCHECK(options().parity_bit != serial::PARITY_BIT_NONE);
256 config.Parity = ParityBitEnumToConstant(options().parity_bit);
257
258 DCHECK(options().stop_bits != serial::STOP_BITS_NONE);
259 config.StopBits = StopBitsEnumToConstant(options().stop_bits);
260
261 DCHECK(options().has_cts_flow_control);
262 if (options().cts_flow_control) {
263 config.fOutxCtsFlow = TRUE;
264 config.fRtsControl = RTS_CONTROL_HANDSHAKE;
265 } else {
266 config.fOutxCtsFlow = FALSE;
267 config.fRtsControl = RTS_CONTROL_ENABLE;
268 }
269
270 if (!SetCommState(file().GetPlatformFile(), &config)) {
271 VPLOG(1) << "Failed to set serial port info";
272 return false;
273 }
274 return true;
275 }
276
243 SerialIoHandlerWin::SerialIoHandlerWin( 277 SerialIoHandlerWin::SerialIoHandlerWin(
244 scoped_refptr<base::MessageLoopProxy> file_thread_message_loop, 278 scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
245 scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop) 279 scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop)
246 : SerialIoHandler(file_thread_message_loop, ui_thread_message_loop), 280 : SerialIoHandler(file_thread_message_loop, ui_thread_message_loop),
247 event_mask_(0), 281 event_mask_(0),
248 is_comm_pending_(false) { 282 is_comm_pending_(false) {
249 } 283 }
250 284
251 SerialIoHandlerWin::~SerialIoHandlerWin() { 285 SerialIoHandlerWin::~SerialIoHandlerWin() {
252 } 286 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 } else { 325 } else {
292 WriteCompleted(bytes_transferred, 326 WriteCompleted(bytes_transferred,
293 error == ERROR_SUCCESS ? serial::SEND_ERROR_NONE 327 error == ERROR_SUCCESS ? serial::SEND_ERROR_NONE
294 : serial::SEND_ERROR_SYSTEM_ERROR); 328 : serial::SEND_ERROR_SYSTEM_ERROR);
295 } 329 }
296 } else { 330 } else {
297 NOTREACHED() << "Invalid IOContext"; 331 NOTREACHED() << "Invalid IOContext";
298 } 332 }
299 } 333 }
300 334
301 bool SerialIoHandlerWin::ConfigurePort( 335 bool SerialIoHandlerWin::Flush() const {
302 const serial::ConnectionOptions& options) { 336 if (!PurgeComm(file().GetPlatformFile(), PURGE_RXCLEAR | PURGE_TXCLEAR)) {
303 DCB config = {0}; 337 VPLOG(1) << "Failed to flush serial port";
304 config.DCBlength = sizeof(config);
305 if (!GetCommState(file().GetPlatformFile(), &config)) {
306 return false; 338 return false;
307 } 339 }
308 if (options.bitrate) 340 return true;
309 config.BaudRate = BitrateToSpeedConstant(options.bitrate);
310 if (options.data_bits != serial::DATA_BITS_NONE)
311 config.ByteSize = DataBitsEnumToConstant(options.data_bits);
312 if (options.parity_bit != serial::PARITY_BIT_NONE)
313 config.Parity = ParityBitEnumToConstant(options.parity_bit);
314 if (options.stop_bits != serial::STOP_BITS_NONE)
315 config.StopBits = StopBitsEnumToConstant(options.stop_bits);
316 if (options.has_cts_flow_control) {
317 if (options.cts_flow_control) {
318 config.fOutxCtsFlow = TRUE;
319 config.fRtsControl = RTS_CONTROL_HANDSHAKE;
320 } else {
321 config.fOutxCtsFlow = FALSE;
322 config.fRtsControl = RTS_CONTROL_ENABLE;
323 }
324 }
325 return SetCommState(file().GetPlatformFile(), &config) != 0;
326 }
327
328 bool SerialIoHandlerWin::Flush() const {
329 return PurgeComm(file().GetPlatformFile(), PURGE_RXCLEAR | PURGE_TXCLEAR) !=
330 0;
331 } 341 }
332 342
333 serial::DeviceControlSignalsPtr SerialIoHandlerWin::GetControlSignals() const { 343 serial::DeviceControlSignalsPtr SerialIoHandlerWin::GetControlSignals() const {
334 DWORD status; 344 DWORD status;
335 if (!GetCommModemStatus(file().GetPlatformFile(), &status)) { 345 if (!GetCommModemStatus(file().GetPlatformFile(), &status)) {
346 VPLOG(1) << "Failed to get port control signals";
336 return serial::DeviceControlSignalsPtr(); 347 return serial::DeviceControlSignalsPtr();
337 } 348 }
338 349
339 serial::DeviceControlSignalsPtr signals(serial::DeviceControlSignals::New()); 350 serial::DeviceControlSignalsPtr signals(serial::DeviceControlSignals::New());
340 signals->dcd = (status & MS_RLSD_ON) != 0; 351 signals->dcd = (status & MS_RLSD_ON) != 0;
341 signals->cts = (status & MS_CTS_ON) != 0; 352 signals->cts = (status & MS_CTS_ON) != 0;
342 signals->dsr = (status & MS_DSR_ON) != 0; 353 signals->dsr = (status & MS_DSR_ON) != 0;
343 signals->ri = (status & MS_RING_ON) != 0; 354 signals->ri = (status & MS_RING_ON) != 0;
344 return signals.Pass(); 355 return signals.Pass();
345 } 356 }
346 357
347 bool SerialIoHandlerWin::SetControlSignals( 358 bool SerialIoHandlerWin::SetControlSignals(
348 const serial::HostControlSignals& signals) { 359 const serial::HostControlSignals& signals) {
349 if (signals.has_dtr) { 360 if (signals.has_dtr) {
350 if (!EscapeCommFunction(file().GetPlatformFile(), 361 if (!EscapeCommFunction(file().GetPlatformFile(),
351 signals.dtr ? SETDTR : CLRDTR)) { 362 signals.dtr ? SETDTR : CLRDTR)) {
363 VPLOG(1) << "Failed to configure DTR signal";
352 return false; 364 return false;
353 } 365 }
354 } 366 }
355 if (signals.has_rts) { 367 if (signals.has_rts) {
356 if (!EscapeCommFunction(file().GetPlatformFile(), 368 if (!EscapeCommFunction(file().GetPlatformFile(),
357 signals.rts ? SETRTS : CLRRTS)) { 369 signals.rts ? SETRTS : CLRRTS)) {
370 VPLOG(1) << "Failed to configure RTS signal";
358 return false; 371 return false;
359 } 372 }
360 } 373 }
361 return true; 374 return true;
362 } 375 }
363 376
364 serial::ConnectionInfoPtr SerialIoHandlerWin::GetPortInfo() const { 377 serial::ConnectionInfoPtr SerialIoHandlerWin::GetPortInfo() const {
365 DCB config = {0}; 378 DCB config = {0};
366 config.DCBlength = sizeof(config); 379 config.DCBlength = sizeof(config);
367 if (!GetCommState(file().GetPlatformFile(), &config)) { 380 if (!GetCommState(file().GetPlatformFile(), &config)) {
381 VPLOG(1) << "Failed to get serial port info";
368 return serial::ConnectionInfoPtr(); 382 return serial::ConnectionInfoPtr();
369 } 383 }
370 serial::ConnectionInfoPtr info(serial::ConnectionInfo::New()); 384 serial::ConnectionInfoPtr info(serial::ConnectionInfo::New());
371 info->bitrate = SpeedConstantToBitrate(config.BaudRate); 385 info->bitrate = SpeedConstantToBitrate(config.BaudRate);
372 info->data_bits = DataBitsConstantToEnum(config.ByteSize); 386 info->data_bits = DataBitsConstantToEnum(config.ByteSize);
373 info->parity_bit = ParityBitConstantToEnum(config.Parity); 387 info->parity_bit = ParityBitConstantToEnum(config.Parity);
374 info->stop_bits = StopBitsConstantToEnum(config.StopBits); 388 info->stop_bits = StopBitsConstantToEnum(config.StopBits);
375 info->cts_flow_control = config.fOutxCtsFlow != 0; 389 info->cts_flow_control = config.fOutxCtsFlow != 0;
376 return info.Pass(); 390 return info.Pass();
377 } 391 }
378 392
379 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) { 393 std::string SerialIoHandler::MaybeFixUpPortName(const std::string& port_name) {
380 // For COM numbers less than 9, CreateFile is called with a string such as 394 // For COM numbers less than 9, CreateFile is called with a string such as
381 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added. 395 // "COM1". For numbers greater than 9, a prefix of "\\\\.\\" must be added.
382 if (port_name.length() > std::string("COM9").length()) 396 if (port_name.length() > std::string("COM9").length())
383 return std::string("\\\\.\\").append(port_name); 397 return std::string("\\\\.\\").append(port_name);
384 398
385 return port_name; 399 return port_name;
386 } 400 }
387 401
388 } // namespace device 402 } // namespace device
OLDNEW
« no previous file with comments | « device/serial/serial_io_handler_win.h ('k') | device/serial/serial_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698