diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs b/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs
new file mode 100644
index 0000000..e24b6e4
--- /dev/null
+++ b/Nefarius.Peripherals.SerialPort/SerialPort.Properties.cs
@@ -0,0 +1,277 @@
+using Nefarius.Peripherals.SerialPort.Win32PInvoke;
+
+namespace Nefarius.Peripherals.SerialPort;
+
+public partial class SerialPort
+{
+ ///
+ /// If true, the port will automatically re-open on next send if it was previously closed due
+ /// to an error (default: false)
+ ///
+ public bool AutoReopen { get; set; }
+
+ ///
+ /// Baud Rate (default: 115200)
+ ///
+ /// Unsupported rates will throw "Bad settings".
+ public int BaudRate { get; set; } = 115200;
+
+ ///
+ /// If true, subsequent Send commands wait for completion of earlier ones enabling the results
+ /// to be checked. If false, errors, including timeouts, may not be detected, but performance
+ /// may be better.
+ ///
+ public bool CheckAllSends { get; set; } = true;
+
+ ///
+ /// Number of databits 1..8 (default: 8) unsupported values will throw "Bad settings"
+ ///
+ public int DataBits { get; set; } = 8;
+
+ ///
+ /// The parity checking scheme (default: none)
+ ///
+ public Parity Parity { get; set; } = Parity.None;
+
+ ///
+ /// If true, Xon and Xoff characters are sent to control the data flow from the remote station (default: false)
+ ///
+ public bool RxFlowX { get; set; }
+
+ ///
+ /// If true, received characters are ignored unless DSR is asserted by the remote station (default: false)
+ ///
+ public bool RxGateDsr { get; set; }
+
+ ///
+ /// The number of free bytes in the reception queue at which flow is disabled (default: 2048)
+ ///
+ public int RxHighWater { get; set; } = 2048;
+
+ ///
+ /// The number of bytes in the reception queue at which flow is re-enabled (default: 512)
+ ///
+ public int RxLowWater { get; set; } = 512;
+
+ ///
+ /// Requested size for receive queue (default: 0 = use operating system default)
+ ///
+ public int RxQueue { get; set; }
+
+ ///
+ /// Constant. Max time for Send in ms = (Multiplier * Characters) + Constant (default: 0)
+ ///
+ public int SendTimeoutConstant { get; set; }
+
+ ///
+ /// Multiplier. Max time for Send in ms = (Multiplier * Characters) + Constant
+ /// (default: 0 = No timeout)
+ ///
+ public int SendTimeoutMultiplier { get; set; }
+
+ ///
+ /// Number of stop bits (default: one)
+ ///
+ public StopBits StopBits { get; set; } = StopBits.One;
+
+ ///
+ /// If true, transmission is halted unless CTS is asserted by the remote station (default: false)
+ ///
+ public bool TxFlowCts { get; set; }
+
+ ///
+ /// If true, transmission is halted unless DSR is asserted by the remote station (default: false)
+ ///
+ public bool TxFlowDsr { get; set; }
+
+ ///
+ /// If true, transmission is halted when Xoff is received and restarted when Xon is received (default: false)
+ ///
+ public bool TxFlowX { get; set; }
+
+ ///
+ /// Requested size for transmit queue (default: 0 = use operating system default)
+ ///
+ public int TxQueue { get; set; }
+
+ ///
+ /// If false, transmission is suspended when this station has sent Xoff to the remote station (default: true)
+ /// Set false if the remote station treats any character as an Xon.
+ ///
+ public bool TxWhenRxXoff { get; set; } = true;
+
+ ///
+ /// Specidies the use to which the DTR output is put (default: none)
+ ///
+ public HsOutput UseDtr { get; set; } = HsOutput.None;
+
+ ///
+ /// Specifies the use to which the RTS output is put (default: none)
+ ///
+ public HsOutput UseRts { get; set; } = HsOutput.None;
+
+ ///
+ /// The character used to signal Xoff for X flow control (default: DC3)
+ ///
+ public ASCII XoffChar { get; set; } = ASCII.DC3;
+
+ ///
+ /// The character used to signal Xon for X flow control (default: DC1)
+ ///
+ public ASCII XonChar { get; set; } = ASCII.DC1;
+
+ ///
+ /// True if online.
+ ///
+ public bool Online => _online && CheckOnline();
+
+ ///
+ /// True if the RTS pin is controllable via the RTS property
+ ///
+ protected bool RtSavailable => _stateRts < 2;
+
+ ///
+ /// Set the state of the RTS modem control output
+ ///
+ protected bool Rts
+ {
+ set
+ {
+ if (_stateRts > 1) return;
+ CheckOnline();
+ if (value)
+ {
+ if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETRTS))
+ _stateRts = 1;
+ else
+ ThrowException("Unexpected Failure");
+ }
+ else
+ {
+ if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRRTS))
+ _stateRts = 1;
+ else
+ ThrowException("Unexpected Failure");
+ }
+ }
+ get => _stateRts == 1;
+ }
+
+ ///
+ /// True if the DTR pin is controllable via the DTR property
+ ///
+ protected bool DtrAvailable => _stateDtr < 2;
+
+ ///
+ /// The state of the DTR modem control output
+ ///
+ protected bool Dtr
+ {
+ set
+ {
+ if (_stateDtr > 1) return;
+ CheckOnline();
+ if (value)
+ {
+ if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETDTR))
+ _stateDtr = 1;
+ else
+ ThrowException("Unexpected Failure");
+ }
+ else
+ {
+ if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRDTR))
+ _stateDtr = 0;
+ else
+ ThrowException("Unexpected Failure");
+ }
+ }
+ get => _stateDtr == 1;
+ }
+
+ ///
+ /// Assert or remove a break condition from the transmission line
+ ///
+ protected bool Break
+ {
+ set
+ {
+ if (_stateBrk > 1) return;
+ CheckOnline();
+ if (value)
+ {
+ if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETBREAK))
+ _stateBrk = 0;
+ else
+ ThrowException("Unexpected Failure");
+ }
+ else
+ {
+ if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRBREAK))
+ _stateBrk = 0;
+ else
+ ThrowException("Unexpected Failure");
+ }
+ }
+ get => _stateBrk == 1;
+ }
+
+ ///
+ /// Port Name
+ ///
+ public string PortName { get; set; }
+
+ public Handshake Handshake
+ {
+ get => _handShake;
+ set
+ {
+ _handShake = value;
+ switch (_handShake)
+ {
+ case Handshake.None:
+ TxFlowCts = false;
+ TxFlowDsr = false;
+ TxFlowX = false;
+ RxFlowX = false;
+ UseRts = HsOutput.Online;
+ UseDtr = HsOutput.Online;
+ TxWhenRxXoff = true;
+ RxGateDsr = false;
+ break;
+ case Handshake.XonXoff:
+ TxFlowCts = false;
+ TxFlowDsr = false;
+ TxFlowX = true;
+ RxFlowX = true;
+ UseRts = HsOutput.Online;
+ UseDtr = HsOutput.Online;
+ TxWhenRxXoff = true;
+ RxGateDsr = false;
+ XonChar = ASCII.DC1;
+ XoffChar = ASCII.DC3;
+ break;
+ case Handshake.CtsRts:
+ TxFlowCts = true;
+ TxFlowDsr = false;
+ TxFlowX = false;
+ RxFlowX = false;
+ UseRts = HsOutput.Handshake;
+ UseDtr = HsOutput.Online;
+ TxWhenRxXoff = true;
+ RxGateDsr = false;
+ break;
+ case Handshake.DsrDtr:
+ TxFlowCts = false;
+ TxFlowDsr = true;
+ TxFlowX = false;
+ RxFlowX = false;
+ UseRts = HsOutput.Online;
+ UseDtr = HsOutput.Handshake;
+ TxWhenRxXoff = true;
+ RxGateDsr = false;
+ break;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Nefarius.Peripherals.SerialPort/SerialPort.cs b/Nefarius.Peripherals.SerialPort/SerialPort.cs
index cfddb9a..2e17be4 100644
--- a/Nefarius.Peripherals.SerialPort/SerialPort.cs
+++ b/Nefarius.Peripherals.SerialPort/SerialPort.cs
@@ -15,8 +15,41 @@ namespace Nefarius.Peripherals.SerialPort;
/// PInvokeSerialPort main class.
/// Borrowed from http://msdn.microsoft.com/en-us/magazine/cc301786.aspx ;)
///
-public class SerialPort : IDisposable
+public partial class SerialPort : IDisposable
{
+ private readonly ManualResetEvent _writeEvent = new(false);
+ private bool _auto;
+ private bool _checkSends = true;
+
+ private Handshake _handShake;
+ private SafeFileHandle _hPort;
+ private bool _online;
+ private NativeOverlapped _ptrUwo;
+ private Exception _rxException;
+ private bool _rxExceptionReported;
+ private Thread _rxThread;
+ private int _stateBrk = 2;
+ private int _stateDtr = 2;
+ private int _stateRts = 2;
+ private int _writeCount;
+
+ ///
+ /// Class constructor
+ ///
+ public SerialPort(string portName)
+ {
+ PortName = portName;
+ }
+
+ ///
+ ///
+ /// Class constructor
+ ///
+ public SerialPort(string portName, int baudRate) : this(portName)
+ {
+ BaudRate = baudRate;
+ }
+
///
///
/// For IDisposable
@@ -210,7 +243,7 @@ public class SerialPort : IDisposable
}
else
{
- if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.ERROR_IO_PENDING)
+ if (Marshal.GetLastWin32Error() != (int)WIN32_ERROR.ERROR_IO_PENDING)
ThrowException("Unexpected failure");
}
}
@@ -291,8 +324,7 @@ public class SerialPort : IDisposable
if (!Win32Com.GetCommModemStatus(_hPort.DangerousGetHandle(), out f)) ThrowException("Unexpected failure");
return new ModemStatus(f);
}
-
-
+
///
/// Get the status of the queues
///
@@ -506,317 +538,4 @@ public class SerialPort : IDisposable
ThrowException("Offline");
return false;
}
-
- #region Private fields
-
- private readonly ManualResetEvent _writeEvent = new(false);
- private bool _auto;
- private bool _checkSends = true;
-
- private Handshake _handShake;
- private SafeFileHandle _hPort;
- private bool _online;
- private NativeOverlapped _ptrUwo;
- private Exception _rxException;
- private bool _rxExceptionReported;
- private Thread _rxThread;
- private int _stateBrk = 2;
- private int _stateDtr = 2;
- private int _stateRts = 2;
- private int _writeCount;
-
- #endregion
-
- #region Public properties
-
- ///
- /// Class constructor
- ///
- public SerialPort(string portName)
- {
- PortName = portName;
- }
-
- ///
- ///
- /// Class constructor
- ///
- public SerialPort(string portName, int baudRate) : this(portName)
- {
- BaudRate = baudRate;
- }
-
- ///
- /// If true, the port will automatically re-open on next send if it was previously closed due
- /// to an error (default: false)
- ///
- public bool AutoReopen { get; set; }
-
- ///
- /// Baud Rate (default: 115200)
- ///
- /// Unsupported rates will throw "Bad settings".
- public int BaudRate { get; set; } = 115200;
-
- ///
- /// If true, subsequent Send commands wait for completion of earlier ones enabling the results
- /// to be checked. If false, errors, including timeouts, may not be detected, but performance
- /// may be better.
- ///
- public bool CheckAllSends { get; set; } = true;
-
- ///
- /// Number of databits 1..8 (default: 8) unsupported values will throw "Bad settings"
- ///
- public int DataBits { get; set; } = 8;
-
- ///
- /// The parity checking scheme (default: none)
- ///
- public Parity Parity { get; set; } = Parity.None;
-
- ///
- /// If true, Xon and Xoff characters are sent to control the data flow from the remote station (default: false)
- ///
- public bool RxFlowX { get; set; }
-
- ///
- /// If true, received characters are ignored unless DSR is asserted by the remote station (default: false)
- ///
- public bool RxGateDsr { get; set; }
-
- ///
- /// The number of free bytes in the reception queue at which flow is disabled (default: 2048)
- ///
- public int RxHighWater { get; set; } = 2048;
-
- ///
- /// The number of bytes in the reception queue at which flow is re-enabled (default: 512)
- ///
- public int RxLowWater { get; set; } = 512;
-
- ///
- /// Requested size for receive queue (default: 0 = use operating system default)
- ///
- public int RxQueue { get; set; }
-
- ///
- /// Constant. Max time for Send in ms = (Multiplier * Characters) + Constant (default: 0)
- ///
- public int SendTimeoutConstant { get; set; }
-
- ///
- /// Multiplier. Max time for Send in ms = (Multiplier * Characters) + Constant
- /// (default: 0 = No timeout)
- ///
- public int SendTimeoutMultiplier { get; set; }
-
- ///
- /// Number of stop bits (default: one)
- ///
- public StopBits StopBits { get; set; } = StopBits.One;
-
- ///
- /// If true, transmission is halted unless CTS is asserted by the remote station (default: false)
- ///
- public bool TxFlowCts { get; set; }
-
- ///
- /// If true, transmission is halted unless DSR is asserted by the remote station (default: false)
- ///
- public bool TxFlowDsr { get; set; }
-
- ///
- /// If true, transmission is halted when Xoff is received and restarted when Xon is received (default: false)
- ///
- public bool TxFlowX { get; set; }
-
- ///
- /// Requested size for transmit queue (default: 0 = use operating system default)
- ///
- public int TxQueue { get; set; }
-
- ///
- /// If false, transmission is suspended when this station has sent Xoff to the remote station (default: true)
- /// Set false if the remote station treats any character as an Xon.
- ///
- public bool TxWhenRxXoff { get; set; } = true;
-
- ///
- /// Specidies the use to which the DTR output is put (default: none)
- ///
- public HsOutput UseDtr { get; set; } = HsOutput.None;
-
- ///
- /// Specifies the use to which the RTS output is put (default: none)
- ///
- public HsOutput UseRts { get; set; } = HsOutput.None;
-
- ///
- /// The character used to signal Xoff for X flow control (default: DC3)
- ///
- public ASCII XoffChar { get; set; } = ASCII.DC3;
-
- ///
- /// The character used to signal Xon for X flow control (default: DC1)
- ///
- public ASCII XonChar { get; set; } = ASCII.DC1;
-
- ///
- /// True if online.
- ///
- public bool Online => _online && CheckOnline();
-
- ///
- /// True if the RTS pin is controllable via the RTS property
- ///
- protected bool RtSavailable => _stateRts < 2;
-
- ///
- /// Set the state of the RTS modem control output
- ///
- protected bool Rts
- {
- set
- {
- if (_stateRts > 1) return;
- CheckOnline();
- if (value)
- {
- if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETRTS))
- _stateRts = 1;
- else
- ThrowException("Unexpected Failure");
- }
- else
- {
- if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRRTS))
- _stateRts = 1;
- else
- ThrowException("Unexpected Failure");
- }
- }
- get => _stateRts == 1;
- }
-
- ///
- /// True if the DTR pin is controllable via the DTR property
- ///
- protected bool DtrAvailable => _stateDtr < 2;
-
- ///
- /// The state of the DTR modem control output
- ///
- protected bool Dtr
- {
- set
- {
- if (_stateDtr > 1) return;
- CheckOnline();
- if (value)
- {
- if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETDTR))
- _stateDtr = 1;
- else
- ThrowException("Unexpected Failure");
- }
- else
- {
- if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRDTR))
- _stateDtr = 0;
- else
- ThrowException("Unexpected Failure");
- }
- }
- get => _stateDtr == 1;
- }
-
- ///
- /// Assert or remove a break condition from the transmission line
- ///
- protected bool Break
- {
- set
- {
- if (_stateBrk > 1) return;
- CheckOnline();
- if (value)
- {
- if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.SETBREAK))
- _stateBrk = 0;
- else
- ThrowException("Unexpected Failure");
- }
- else
- {
- if (Win32Com.EscapeCommFunction(_hPort.DangerousGetHandle(), Win32Com.CLRBREAK))
- _stateBrk = 0;
- else
- ThrowException("Unexpected Failure");
- }
- }
- get => _stateBrk == 1;
- }
-
-
- ///
- /// Port Name
- ///
- public string PortName { get; set; }
-
- public Handshake Handshake
- {
- get => _handShake;
- set
- {
- _handShake = value;
- switch (_handShake)
- {
- case Handshake.None:
- TxFlowCts = false;
- TxFlowDsr = false;
- TxFlowX = false;
- RxFlowX = false;
- UseRts = HsOutput.Online;
- UseDtr = HsOutput.Online;
- TxWhenRxXoff = true;
- RxGateDsr = false;
- break;
- case Handshake.XonXoff:
- TxFlowCts = false;
- TxFlowDsr = false;
- TxFlowX = true;
- RxFlowX = true;
- UseRts = HsOutput.Online;
- UseDtr = HsOutput.Online;
- TxWhenRxXoff = true;
- RxGateDsr = false;
- XonChar = ASCII.DC1;
- XoffChar = ASCII.DC3;
- break;
- case Handshake.CtsRts:
- TxFlowCts = true;
- TxFlowDsr = false;
- TxFlowX = false;
- RxFlowX = false;
- UseRts = HsOutput.Handshake;
- UseDtr = HsOutput.Online;
- TxWhenRxXoff = true;
- RxGateDsr = false;
- break;
- case Handshake.DsrDtr:
- TxFlowCts = false;
- TxFlowDsr = true;
- TxFlowX = false;
- RxFlowX = false;
- UseRts = HsOutput.Online;
- UseDtr = HsOutput.Handshake;
- TxWhenRxXoff = true;
- RxGateDsr = false;
- break;
- }
- }
- }
-
- #endregion
}
\ No newline at end of file