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
Diff: HspGuiSourceV301/GuiDLLs/SerialWrap/SerialPortTester.cs
- Revision:
- 20:6d2af70c92ab
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HspGuiSourceV301/GuiDLLs/SerialWrap/SerialPortTester.cs Tue Apr 06 06:41:40 2021 +0000
@@ -0,0 +1,230 @@
+// Copyright 2010-2014 Zach Saw
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+using System;
+using System.IO;
+using System.IO.Ports;
+using System.Runtime.InteropServices;
+using System.Text;
+using Microsoft.Win32.SafeHandles;
+
+namespace SerialPortTester
+{
+ public class SerialPortFixer : IDisposable
+ {
+ public static void Execute(string portName)
+ {
+ using (new SerialPortFixer(portName))
+ {
+ }
+ }
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ if (m_Handle != null)
+ {
+ m_Handle.Close();
+ m_Handle = null;
+ }
+ }
+
+ #endregion
+
+ #region Implementation
+
+ private const int DcbFlagAbortOnError = 14;
+ private const int CommStateRetries = 10;
+ private SafeFileHandle m_Handle;
+
+ private SerialPortFixer(string portName)
+ {
+ const int dwFlagsAndAttributes = 0x40000000;
+ const int dwAccess = unchecked((int) 0xC0000000);
+
+ if ((portName == null) || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase))
+ {
+ throw new ArgumentException("Invalid Serial Port", "portName");
+ }
+ SafeFileHandle hFile = CreateFile(@"\\.\" + portName, dwAccess, 0, IntPtr.Zero, 3, dwFlagsAndAttributes,
+ IntPtr.Zero);
+ if (hFile.IsInvalid)
+ {
+ WinIoError();
+ }
+ try
+ {
+ int fileType = GetFileType(hFile);
+ if ((fileType != 2) && (fileType != 0))
+ {
+ throw new ArgumentException("Invalid Serial Port", "portName");
+ }
+ m_Handle = hFile;
+ InitializeDcb();
+ }
+ catch
+ {
+ hFile.Close();
+ m_Handle = null;
+ throw;
+ }
+ }
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId,
+ StringBuilder lpBuffer, int nSize, IntPtr arguments);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern bool GetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern bool SetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref Comstat lpStat);
+
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode,
+ IntPtr securityAttrs, int dwCreationDisposition,
+ int dwFlagsAndAttributes, IntPtr hTemplateFile);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ private static extern int GetFileType(SafeFileHandle hFile);
+
+ private void InitializeDcb()
+ {
+ Dcb dcb = new Dcb();
+ GetCommStateNative(ref dcb);
+ dcb.Flags &= ~(1u << DcbFlagAbortOnError);
+ SetCommStateNative(ref dcb);
+ }
+
+ private static string GetMessage(int errorCode)
+ {
+ StringBuilder lpBuffer = new StringBuilder(0x200);
+ if (
+ FormatMessage(0x3200, new HandleRef(null, IntPtr.Zero), errorCode, 0, lpBuffer, lpBuffer.Capacity,
+ IntPtr.Zero) != 0)
+ {
+ return lpBuffer.ToString();
+ }
+ return "Unknown Error";
+ }
+
+ private static int MakeHrFromErrorCode(int errorCode)
+ {
+ return (int) (0x80070000 | (uint) errorCode);
+ }
+
+ private static void WinIoError()
+ {
+ int errorCode = Marshal.GetLastWin32Error();
+ throw new IOException(GetMessage(errorCode), MakeHrFromErrorCode(errorCode));
+ }
+
+ private void GetCommStateNative(ref Dcb lpDcb)
+ {
+ int commErrors = 0;
+ Comstat comStat = new Comstat();
+
+ for (int i = 0; i < CommStateRetries; i++)
+ {
+ if (!ClearCommError(m_Handle, ref commErrors, ref comStat))
+ {
+ WinIoError();
+ }
+ if (GetCommState(m_Handle, ref lpDcb))
+ {
+ break;
+ }
+ if (i == CommStateRetries - 1)
+ {
+ WinIoError();
+ }
+ }
+ }
+
+ private void SetCommStateNative(ref Dcb lpDcb)
+ {
+ int commErrors = 0;
+ Comstat comStat = new Comstat();
+
+ for (int i = 0; i < CommStateRetries; i++)
+ {
+ if (!ClearCommError(m_Handle, ref commErrors, ref comStat))
+ {
+ WinIoError();
+ }
+ if (SetCommState(m_Handle, ref lpDcb))
+ {
+ break;
+ }
+ if (i == CommStateRetries - 1)
+ {
+ WinIoError();
+ }
+ }
+ }
+
+ #region Nested type: COMSTAT
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct Comstat
+ {
+ public readonly uint Flags;
+ public readonly uint cbInQue;
+ public readonly uint cbOutQue;
+ }
+
+ #endregion
+
+ #region Nested type: DCB
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct Dcb
+ {
+ public readonly uint DCBlength;
+ public readonly uint BaudRate;
+ public uint Flags;
+ public readonly ushort wReserved;
+ public readonly ushort XonLim;
+ public readonly ushort XoffLim;
+ public readonly byte ByteSize;
+ public readonly byte Parity;
+ public readonly byte StopBits;
+ public readonly byte XonChar;
+ public readonly byte XoffChar;
+ public readonly byte ErrorChar;
+ public readonly byte EofChar;
+ public readonly byte EvtChar;
+ public readonly ushort wReserved1;
+ }
+
+ #endregion
+
+ #endregion
+ }
+
+ internal class Program
+ {
+ private static void Main(string[] args)
+ {
+ SerialPortFixer.Execute("COM1");
+ using (SerialPort port = new SerialPort("COM1"))
+ {
+ port.Write("test");
+ }
+ }
+ }
+}