예제 #1
0
 internal static extern bool SetCommState(IntPtr hFile, [In] ref Dcb lpDCB);
예제 #2
0
        public static IntPtr OpenPort(int portNum, RS232Config config)
        {
            // Validate inputs
            if (portNum < 0 || portNum > 255)
            {
                throw new ArgumentException("Invalid port number (valid range is [0, 255]).", nameof(portNum));
            }

            if (!config.IsValid(out var msg))
            {
                throw new ArgumentException(msg, nameof(config));
            }

            // Open the port
            var fileName = "\\\\.\\COM" + portNum;
            var hPort    = RS232PInvoke.CreateFileA(
                fileName,                               // File name for com port
                FileAccess.ReadWrite,                   // Read/Write access for (rx/tx)
                FileShare.None,                         // no share
                IntPtr.Zero,                            // no security
                FileMode.Open,                          // open existing
                FileAttributes.Normal,                  // normal file
                IntPtr.Zero);                           // no template file

            if (hPort.ToInt32() == -1)
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }

            // Configure the port
            var dcb = new Dcb
            {
                BaudRate = (uint)config.BaudRate,
                ByteSize = (byte)config.DataBits,
                Parity   = config.Parity,
                StopBits = config.StopBits,
            };

            if (!RS232PInvoke.SetCommState(hPort, ref dcb))
            {
                RS232PInvoke.CloseHandle(hPort);
                throw new Exception("Could not configure COM port settings.");
            }

            // Configure the port time-outs
            var timeouts = new COMMTIMEOUTS
            {
                // Read operations return immediately
                ReadIntervalTimeout        = 0xFFFF_FFFF, // MAXDWORD
                ReadTotalTimeoutMultiplier = 0,
                ReadTotalTimeoutConstant   = 0,

                // Timeouts not used for write operations
                WriteTotalTimeoutMultiplier = 0,
                WriteTotalTimeoutConstant   = 0,
            };

            if (!RS232PInvoke.SetCommTimeouts(hPort, ref timeouts))
            {
                RS232PInvoke.CloseHandle(hPort);
                throw new Exception("Could not configure COM port timeouts.");
            }

            // Return port handle for caller
            return(hPort);
        }