Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed MAX14720 MAX30205 USBDevice
SerialPortTester.cs
00001 // Copyright 2010-2014 Zach Saw 00002 // 00003 // Licensed under the Apache License, Version 2.0 (the "License"); 00004 // you may not use this file except in compliance with the License. 00005 // You may obtain a copy of the License at 00006 // 00007 // http://www.apache.org/licenses/LICENSE-2.0 00008 // 00009 // Unless required by applicable law or agreed to in writing, software 00010 // distributed under the License is distributed on an "AS IS" BASIS, 00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 // See the License for the specific language governing permissions and 00013 // limitations under the License. 00014 00015 using System; 00016 using System.IO; 00017 using System.IO.Ports; 00018 using System.Runtime.InteropServices; 00019 using System.Text; 00020 using Microsoft.Win32.SafeHandles; 00021 00022 namespace SerialPortTester 00023 { 00024 public class SerialPortFixer : IDisposable 00025 { 00026 public static void Execute(string portName) 00027 { 00028 using (new SerialPortFixer(portName)) 00029 { 00030 } 00031 } 00032 #region IDisposable Members 00033 00034 public void Dispose() 00035 { 00036 if (m_Handle != null) 00037 { 00038 m_Handle.Close(); 00039 m_Handle = null; 00040 } 00041 } 00042 00043 #endregion 00044 00045 #region Implementation 00046 00047 private const int DcbFlagAbortOnError = 14; 00048 private const int CommStateRetries = 10; 00049 private SafeFileHandle m_Handle; 00050 00051 private SerialPortFixer(string portName) 00052 { 00053 const int dwFlagsAndAttributes = 0x40000000; 00054 const int dwAccess = unchecked((int) 0xC0000000); 00055 00056 if ((portName == null) || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase)) 00057 { 00058 throw new ArgumentException("Invalid Serial Port", "portName"); 00059 } 00060 SafeFileHandle hFile = CreateFile(@"\\.\" + portName, dwAccess, 0, IntPtr.Zero, 3, dwFlagsAndAttributes, 00061 IntPtr.Zero); 00062 if (hFile.IsInvalid) 00063 { 00064 WinIoError(); 00065 } 00066 try 00067 { 00068 int fileType = GetFileType(hFile); 00069 if ((fileType != 2) && (fileType != 0)) 00070 { 00071 throw new ArgumentException("Invalid Serial Port", "portName"); 00072 } 00073 m_Handle = hFile; 00074 InitializeDcb(); 00075 } 00076 catch 00077 { 00078 hFile.Close(); 00079 m_Handle = null; 00080 throw; 00081 } 00082 } 00083 00084 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 00085 private static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId, 00086 StringBuilder lpBuffer, int nSize, IntPtr arguments); 00087 00088 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 00089 private static extern bool GetCommState(SafeFileHandle hFile, ref Dcb lpDcb); 00090 00091 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 00092 private static extern bool SetCommState(SafeFileHandle hFile, ref Dcb lpDcb); 00093 00094 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 00095 private static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref Comstat lpStat); 00096 00097 [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 00098 private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, 00099 IntPtr securityAttrs, int dwCreationDisposition, 00100 int dwFlagsAndAttributes, IntPtr hTemplateFile); 00101 00102 [DllImport("kernel32.dll", SetLastError = true)] 00103 private static extern int GetFileType(SafeFileHandle hFile); 00104 00105 private void InitializeDcb() 00106 { 00107 Dcb dcb = new Dcb(); 00108 GetCommStateNative(ref dcb); 00109 dcb.Flags &= ~(1u << DcbFlagAbortOnError); 00110 SetCommStateNative(ref dcb); 00111 } 00112 00113 private static string GetMessage(int errorCode) 00114 { 00115 StringBuilder lpBuffer = new StringBuilder(0x200); 00116 if ( 00117 FormatMessage(0x3200, new HandleRef(null, IntPtr.Zero), errorCode, 0, lpBuffer, lpBuffer.Capacity, 00118 IntPtr.Zero) != 0) 00119 { 00120 return lpBuffer.ToString(); 00121 } 00122 return "Unknown Error"; 00123 } 00124 00125 private static int MakeHrFromErrorCode(int errorCode) 00126 { 00127 return (int) (0x80070000 | (uint) errorCode); 00128 } 00129 00130 private static void WinIoError() 00131 { 00132 int errorCode = Marshal.GetLastWin32Error(); 00133 throw new IOException(GetMessage(errorCode), MakeHrFromErrorCode(errorCode)); 00134 } 00135 00136 private void GetCommStateNative(ref Dcb lpDcb) 00137 { 00138 int commErrors = 0; 00139 Comstat comStat = new Comstat(); 00140 00141 for (int i = 0; i < CommStateRetries; i++) 00142 { 00143 if (!ClearCommError(m_Handle, ref commErrors, ref comStat)) 00144 { 00145 WinIoError(); 00146 } 00147 if (GetCommState(m_Handle, ref lpDcb)) 00148 { 00149 break; 00150 } 00151 if (i == CommStateRetries - 1) 00152 { 00153 WinIoError(); 00154 } 00155 } 00156 } 00157 00158 private void SetCommStateNative(ref Dcb lpDcb) 00159 { 00160 int commErrors = 0; 00161 Comstat comStat = new Comstat(); 00162 00163 for (int i = 0; i < CommStateRetries; i++) 00164 { 00165 if (!ClearCommError(m_Handle, ref commErrors, ref comStat)) 00166 { 00167 WinIoError(); 00168 } 00169 if (SetCommState(m_Handle, ref lpDcb)) 00170 { 00171 break; 00172 } 00173 if (i == CommStateRetries - 1) 00174 { 00175 WinIoError(); 00176 } 00177 } 00178 } 00179 00180 #region Nested type: COMSTAT 00181 00182 [StructLayout(LayoutKind.Sequential)] 00183 private struct Comstat 00184 { 00185 public readonly uint Flags; 00186 public readonly uint cbInQue; 00187 public readonly uint cbOutQue; 00188 } 00189 00190 #endregion 00191 00192 #region Nested type: DCB 00193 00194 [StructLayout(LayoutKind.Sequential)] 00195 private struct Dcb 00196 { 00197 public readonly uint DCBlength; 00198 public readonly uint BaudRate; 00199 public uint Flags; 00200 public readonly ushort wReserved; 00201 public readonly ushort XonLim; 00202 public readonly ushort XoffLim; 00203 public readonly byte ByteSize; 00204 public readonly byte Parity; 00205 public readonly byte StopBits; 00206 public readonly byte XonChar; 00207 public readonly byte XoffChar; 00208 public readonly byte ErrorChar; 00209 public readonly byte EofChar; 00210 public readonly byte EvtChar; 00211 public readonly ushort wReserved1; 00212 } 00213 00214 #endregion 00215 00216 #endregion 00217 } 00218 00219 internal class Program 00220 { 00221 private static void Main(string[] args) 00222 { 00223 SerialPortFixer.Execute("COM1"); 00224 using (SerialPort port = new SerialPort("COM1")) 00225 { 00226 port.Write("test"); 00227 } 00228 } 00229 } 00230 }
Generated on Thu Jul 28 2022 18:07:15 by
1.7.2