Example #1
0
        internal void Init(string devicePath)
        {
            IntPtr handle = NativeMethods.CreateFileFromDevice(devicePath,
                                                               NativeMethods.EFileAccess.Read | NativeMethods.EFileAccess.Write,
                                                               NativeMethods.EFileShare.None);

            if (handle == (IntPtr)(-1))
            {
                int hr = Marshal.GetHRForLastWin32Error();
                throw DeviceException.CreateIOException(Device, "Unable to open serial device (" + devicePath + ").", hr);
            }

            var timeouts = new NativeMethods.COMMTIMEOUTS();

            timeouts.ReadIntervalTimeout        = uint.MaxValue;
            timeouts.ReadTotalTimeoutConstant   = uint.MaxValue - 1; // CP210x fails if this is set to uint.MaxValue.
            timeouts.ReadTotalTimeoutMultiplier = uint.MaxValue;
            if (!NativeMethods.SetCommTimeouts(handle, out timeouts))
            {
                int hr = Marshal.GetHRForLastWin32Error();
                NativeMethods.CloseHandle(handle);
                throw DeviceException.CreateIOException(Device, "Unable to set serial timeouts.", hr);
            }

            _handle = handle;
            HandleInitAndOpen();
        }
Example #2
0
        /// <summary>
        /// Opens a new serial port connection.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">Port is already open.</exception>
        /// <exception cref="System.IO.IOException">The port is in an invalid state. -or- An attempt to set the state of the underlying port failed.</exception>
        /// <exception cref="System.UnauthorizedAccessException">Access is denied to the port.</exception>
        public void Open()
        {
            if (this.IsOpen)
            {
                throw new InvalidOperationException("Port is already open.");
            }

            if (IsRunningOnMono == false)
            {
                var portName = (this.PortName.StartsWith(@"\\?\", StringComparison.Ordinal) ? "" : @"\\?\") + this.PortName;
                this.Handle = NativeMethods.CreateFileW(
                    portName,
                    NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE,
                    0, //exclusive access
                    IntPtr.Zero,
                    NativeMethods.OPEN_EXISTING,
                    0,
                    IntPtr.Zero
                    );

                if (this.IsOpen == false)
                {
                    throw new IOException("The port is in an invalid state.");
                }

                var config = new NativeMethods.COMMCONFIG();
                config.dwSize                = Marshal.SizeOf(config);
                config.wVersion              = 1;
                config.wReserved             = 0;
                config.dcb                   = new NativeMethods.DCB();
                config.dcb.DCBlength         = Marshal.SizeOf(config.dcb);
                config.dcb.BaudRate          = this.BaudRate;
                config.dcb.fBinary           = 1;
                config.dcb.fParity           = 0;
                config.dcb.fOutxCtsFlow      = 0;
                config.dcb.fOutxDsrFlow      = 0;
                config.dcb.fDtrControl       = NativeMethods.DTR_CONTROL_ENABLE;
                config.dcb.fDsrSensitivity   = 0;
                config.dcb.fTXContinueOnXoff = 0;
                config.dcb.fOutX             = 0;
                config.dcb.fInX              = 0;
                config.dcb.fErrorChar        = 0;
                config.dcb.fNull             = 0;
                config.dcb.fRtsControl       = NativeMethods.RTS_CONTROL_ENABLE;
                config.dcb.fAbortOnError     = 0;
                config.dcb.fDummy2           = 0;
                config.dcb.wReserved         = 0;
                config.dcb.XonLim            = 0;
                config.dcb.XoffLim           = 0;
                config.dcb.ByteSize          = (byte)this.DataBits;
                switch (this.Parity)
                {
                case Parity.None: config.dcb.Parity = NativeMethods.NOPARITY; break;

                case Parity.Odd: config.dcb.Parity = NativeMethods.ODDPARITY; break;

                case Parity.Even: config.dcb.Parity = NativeMethods.EVENPARITY; break;

                case Parity.Mark: config.dcb.Parity = NativeMethods.MARKPARITY; break;

                case Parity.Space: config.dcb.Parity = NativeMethods.SPACEPARITY; break;

                default: throw new IOException("An attempt to set the state of the underlying port failed (invalid parity).");
                }
                switch (this.StopBits)
                {
                case StopBits.One: config.dcb.StopBits = NativeMethods.ONESTOPBIT; break;

                case StopBits.OnePointFive: config.dcb.StopBits = NativeMethods.ONE5STOPBITS; break;

                case StopBits.Two: config.dcb.StopBits = NativeMethods.TWOSTOPBITS; break;

                default: throw new IOException("An attempt to set the state of the underlying port failed (invalid stop bit count).");
                }
                config.dcb.XonChar       = 0x11;
                config.dcb.XoffChar      = 0x13;
                config.dcb.ErrorChar     = 0x3F;
                config.dcb.EofChar       = 0;
                config.dcb.EvtChar       = 0;
                config.dcb.wReserved1    = 0;
                config.dwProviderSubType = NativeMethods.PST_RS232;
                config.dwProviderOffset  = 0;
                config.dwProviderSize    = 0;
                config.wcProviderData    = null;
                var resultConfigSet = NativeMethods.SetCommConfig(this.Handle, ref config, config.dwSize);
                if (resultConfigSet != true)
                {
                    throw new IOException("An attempt to set the state of the underlying port failed.", new Win32Exception());
                }

                var commTimeouts = new NativeMethods.COMMTIMEOUTS();
                commTimeouts.ReadIntervalTimeout         = NativeMethods.MAXDWORD;
                commTimeouts.ReadTotalTimeoutMultiplier  = (this.ReadTimeout == 0) ? 0 : -1;
                commTimeouts.ReadTotalTimeoutConstant    = (this.ReadTimeout != InfiniteTimeout) ? this.ReadTimeout : -2;
                commTimeouts.WriteTotalTimeoutMultiplier = 0;
                commTimeouts.WriteTotalTimeoutConstant   = (this.ReadTimeout != InfiniteTimeout) ? this.WriteTimeout : 0;
                var resultTimeouts = NativeMethods.SetCommTimeouts(this.Handle, ref commTimeouts);
                if (resultTimeouts != true)
                {
                    throw new IOException("An attempt to set the state of the underlying port failed.", new Win32Exception());
                }
            }
            else
            {
                var portName = (this.PortName.StartsWith(@"\\?\", StringComparison.Ordinal) ? this.PortName.Remove(0, 4).Trim() : this.PortName.Trim());
                this.FrameworkSerialPort              = new SerialPort(portName, this.BaudRate, this.Parity, this.DataBits, this.StopBits);
                this.FrameworkSerialPort.ReadTimeout  = this.ReadTimeout;
                this.FrameworkSerialPort.WriteTimeout = this.WriteTimeout;
                this.FrameworkSerialPort.DtrEnable    = true;
                this.FrameworkSerialPort.RtsEnable    = true;
                this.FrameworkSerialPort.Open();
            }

            this.Purge();
        }