This is the latest working repository used in our demo video for the Maxim to display temperature readings on Bluetooth
hspguisourcev301/HspGuiSourceV301/GuiDLLs/SerialWrap/SerialPortTester.cs
- Committer:
- darienf
- Date:
- 2021-05-02
- Revision:
- 5:bc128a16232f
- Parent:
- 3:36de8b9e4b1a
File content as of revision 5:bc128a16232f:
// 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"); } } } }