/// <summary> /// Closes and destroys the com port. /// </summary> protected void Destroy() { // Cancel I/O, kill receiver & close port. if(this.portOpen) { this.port.Cancel(); if(this.rxThread != null) { this.rxThread.Abort(); this.rxThread = null; } this.port.Close(); this.portOpen = false; } // Reinit resources. this.dcb = null; this.port = null; this.stats = null; this.props = null; this.tmout = null; this.rxOvr = null; this.txOvr = null; this.escape = null; this.writeEvent = null; this.recvrEvent = null; return; }
/// <summary> /// Create & opens the com port and configures it with the required settings. /// </summary> /// <param name="cfg">Reference to port user config.</param> /// <returns>True if port opened successfully.</returns> protected bool Create(SerialCnfg cfg) { // If port already open, return. if(portOpen) { this.CommError("Com Port Already Open."); return false; } // Init members. this.fault = ""; this.rxThread = null; this.writeEvent = new ManualResetEvent(false); this.recvrEvent = new ManualResetEvent(false); // Copy config to DCB. this.dcb = new Win32DCB(cfg); // Create handle to comm port. this.port = new Win32Com(); if((this.portOpen = this.port.Open(cfg.PortName, true)) == false) { this.CommError(this.port.Fault); return false; } this.portName = cfg.PortName; // Instantiate support classes. this.stats = new Win32Status(); this.tmout = new Win32Tmout(); this.props = new Win32Props(); this.escape = new Win32Escape(port.Handle); // Set read/write timeouts. this.tmout.WriteConstant = cfg.TxTmoConst; this.tmout.WriteMultiplier = cfg.TxTmoMulti; if(this.tmout.Set(this.port.Handle) == false) { this.Destroy(); this.CommError(this.tmout.Fault); return false; } // Overide OS default queue sizes. if((cfg.RxQueLen != 0) || (cfg.TxQueLen != 0)) { if(this.props.Set(this.port.Handle, (uint)cfg.RxQueLen, (uint)cfg.TxQueLen) == false) { this.Destroy(); this.CommError(this.props.Fault); return false; } } // Get the current properties. if(this.props.Get(this.port.Handle) == false) { this.Destroy(); this.CommError(this.props.Fault); return false; } // Set flow control limits. this.dcb.Limits(cfg, this.props.RxCurSize); // Update the port settings. if(this.dcb.Set(this.port.Handle) == false) { this.Destroy(); this.CommError(this.dcb.Fault); return false; } // XON/OFF extended functionality. this.escape.XOFFavailable = true; // RTS extended functionality. if(cfg.RtsControl == PinState.Disable) this.escape.RTS = false; else if(cfg.RtsControl == PinState.Enable) this.escape.RTS = true; else if(cfg.RtsControl == PinState.Handshake) this.escape.RTSavailable = false; // DTR extended functionality. if(cfg.DtrControl == PinState.Disable) this.escape.DTR = false; else if(cfg.DtrControl == PinState.Enable) this.escape.DTR = true; else if(cfg.DtrControl == PinState.Toggle) this.escape.DTR = false; else if(cfg.DtrControl == PinState.Handshake) this.escape.DTRavailable = false; // Create TX overlap memory pointer. this.txOvr = new Win32Ovrlap(this.port.Handle, this.writeEvent.Handle); // Set the receiver mode. this.immediate = cfg.ReceiveMode; // Start the receiver thread. this.rxThread = new Thread(new ThreadStart(ReceiveThread)); this.rxThread.Name = "COMReceiver"; this.rxThread.Priority = ThreadPriority.AboveNormal; this.rxThread.Start(); // Wait for receive thread to start. this.recvrEvent.WaitOne(500, false); // Port opened OK. return true; }