From d76fc473a5e3be9f6291837d3621a12119d89e30 Mon Sep 17 00:00:00 2001 From: Ricardo Coelho Date: Tue, 8 Nov 2022 18:04:00 -0300 Subject: [PATCH] Databit, stopbit and paraty implemented; Fix CH340 initialization; --- .../Resources/Resource.Designer.cs | 2 +- .../driver/Ch34xSerialDriver.cs | 119 +++++++++++++----- 2 files changed, 92 insertions(+), 29 deletions(-) diff --git a/UsbSerialForAndroid/Resources/Resource.Designer.cs b/UsbSerialForAndroid/Resources/Resource.Designer.cs index 2a3f32a..c278fef 100644 --- a/UsbSerialForAndroid/Resources/Resource.Designer.cs +++ b/UsbSerialForAndroid/Resources/Resource.Designer.cs @@ -14,7 +14,7 @@ namespace Hoho.Android.UsbSerial { - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "12.2.0.155")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "13.0.0.73")] public partial class Resource { diff --git a/UsbSerialForAndroid/driver/Ch34xSerialDriver.cs b/UsbSerialForAndroid/driver/Ch34xSerialDriver.cs index 7871687..05c47ed 100644 --- a/UsbSerialForAndroid/driver/Ch34xSerialDriver.cs +++ b/UsbSerialForAndroid/driver/Ch34xSerialDriver.cs @@ -19,12 +19,13 @@ using Android.Views; using Android.Widget; using Android.Util; +using Java.Util; namespace Hoho.Android.UsbSerial.Driver { public class Ch34xSerialDriver : UsbSerialDriver { - private readonly string TAG = typeof (ProlificSerialDriver).Name; + private readonly string TAG = typeof(ProlificSerialDriver).Name; public Ch34xSerialDriver(UsbDevice device) { @@ -38,6 +39,20 @@ public class Ch340SerialPort : CommonUsbSerialPort private int DEFAULT_BAUD_RATE = 9600; + private const int SCL_DTR = 0x20; + private const int SCL_RTS = 0x40; + private const int LCR_ENABLE_RX = 0x80; + private const int LCR_ENABLE_TX = 0x40; + private const int LCR_STOP_BITS_2 = 0x04; + private const int LCR_CS8 = 0x03; + private const int LCR_CS7 = 0x02; + private const int LCR_CS6 = 0x01; + private const int LCR_CS5 = 0x00; + + private const int LCR_MARK_SPACE = 0x20; + private const int LCR_PAR_EVEN = 0x10; + private const int LCR_ENABLE_PAR = 0x08; + private Boolean dtr = false; private Boolean rts = false; @@ -85,9 +100,9 @@ public override void Open(UsbDeviceConnection connection) for (int i = 0; i < dataIface.EndpointCount; i++) { UsbEndpoint ep = dataIface.GetEndpoint(i); - if (ep.Type == (UsbAddressing) UsbSupport.UsbEndpointXferBulk) + if (ep.Type == (UsbAddressing)UsbSupport.UsbEndpointXferBulk) { - if (ep.Direction == (UsbAddressing) UsbSupport.UsbDirIn) + if (ep.Direction == (UsbAddressing)UsbSupport.UsbDirIn) { mReadEndpoint = ep; } @@ -202,8 +217,8 @@ public override int Write(byte[] src, int timeoutMillis) private int ControlOut(int request, int value, int index) { - int REQTYPE_HOST_TO_DEVICE = 0x41; - return mConnection.ControlTransfer((UsbAddressing) REQTYPE_HOST_TO_DEVICE, request, + int REQTYPE_HOST_TO_DEVICE = UsbConstants.UsbTypeVendor | UsbSupport.UsbDirOut; + return mConnection.ControlTransfer((UsbAddressing)REQTYPE_HOST_TO_DEVICE, request, value, index, null, 0, USB_TIMEOUT_MILLIS); } @@ -211,7 +226,7 @@ private int ControlOut(int request, int value, int index) private int ControlIn(int request, int value, int index, byte[] buffer) { int REQTYPE_HOST_TO_DEVICE = UsbConstants.UsbTypeVendor | UsbSupport.UsbDirIn; - return mConnection.ControlTransfer((UsbAddressing) REQTYPE_HOST_TO_DEVICE, request, + return mConnection.ControlTransfer((UsbAddressing)REQTYPE_HOST_TO_DEVICE, request, value, index, buffer, buffer.Length, USB_TIMEOUT_MILLIS); } @@ -245,17 +260,17 @@ private void CheckState(String msg, int request, int value, int[] expected) } } - private void WriteHandshakeByte() + private void SetControlLines() { - if (ControlOut(0xa4, ~((dtr ? 1 << 5 : 0) | (rts ? 1 << 6 : 0)), 0) < 0) + if (ControlOut(0xa4, ~((dtr ? SCL_DTR : 0) | (rts ? SCL_RTS : 0)), 0) < 0) { - throw new IOException("Failed to set handshake byte"); + throw new IOException("Failed to set control lines"); } } private void Initialize() { - CheckState("init #1", 0x5f, 0, new int[] {-1 /* 0x27, 0x30 */, 0x00}); + CheckState("init #1", 0x5f, 0, new int[] { -1 /* 0x27, 0x30 */, 0x00 }); if (ControlOut(0xa1, 0, 0) < 0) { @@ -264,14 +279,14 @@ private void Initialize() SetBaudRate(DEFAULT_BAUD_RATE); - CheckState("init #4", 0x95, 0x2518, new int[] {-1 /* 0x56, c3*/, 0x00}); + CheckState("init #4", 0x95, 0x2518, new int[] { -1 /* 0x56, c3*/, 0x00 }); if (ControlOut(0x9a, 0x2518, 0x0050) < 0) { throw new IOException("init failed! #5"); } - CheckState("init #6", 0x95, 0x0706, new int[] {0xff, 0xee}); + CheckState("init #6", 0x95, 0x0706, new int[] { -1 /*0xf?*/, -1 /*0xec,0xee*/}); if (ControlOut(0xa1, 0x501f, 0xd90a) < 0) { @@ -280,9 +295,9 @@ private void Initialize() SetBaudRate(DEFAULT_BAUD_RATE); - WriteHandshakeByte(); + SetControlLines(); - CheckState("init #10", 0x95, 0x0706, new int[] {-1 /* 0x9f, 0xff*/, 0xee}); + CheckState("init #10", 0x95, 0x0706, new int[] { -1 /* 0x9f, 0xff*/, 0xee }); } private void SetBaudRate(int baudRate) @@ -294,16 +309,16 @@ private void SetBaudRate(int baudRate) 0x6403, 0x000a, 115200, 0xcc03, 0x0008 }; - for (int i = 0; i < baud.Length/3; i++) + for (int i = 0; i < baud.Length / 3; i++) { - if (baud[i*3] == baudRate) + if (baud[i * 3] == baudRate) { - int ret = ControlOut(0x9a, 0x1312, baud[i*3 + 1]); + int ret = ControlOut(0x9a, 0x1312, baud[i * 3 + 1]); if (ret < 0) { throw new IOException("Error setting baud rate. #1"); } - ret = ControlOut(0x9a, 0x0f2c, baud[i*3 + 2]); + ret = ControlOut(0x9a, 0x0f2c, baud[i * 3 + 2]); if (ret < 0) { throw new IOException("Error setting baud rate. #1"); @@ -321,7 +336,41 @@ public override void SetParameters(int baudRate, int dataBits, StopBits stopBits { SetBaudRate(baudRate); - // TODO databit, stopbit and paraty set not implemented + int lcr = LCR_ENABLE_RX | LCR_ENABLE_TX; + + lcr |= dataBits switch + { + DATABITS_5 => LCR_CS5, + DATABITS_6 => LCR_CS6, + DATABITS_7 => LCR_CS7, + DATABITS_8 => LCR_CS8, + _ => throw new Java.Lang.IllegalArgumentException("Invalid data bits: " + dataBits), + }; + + + lcr |= (int)parity switch + { + PARITY_NONE => lcr, + PARITY_ODD => LCR_ENABLE_PAR, + PARITY_EVEN => LCR_ENABLE_PAR | LCR_PAR_EVEN, + PARITY_MARK => LCR_ENABLE_PAR | LCR_MARK_SPACE, + PARITY_SPACE => LCR_ENABLE_PAR | LCR_MARK_SPACE | LCR_PAR_EVEN, + _ => throw new Java.Lang.IllegalArgumentException("Invalid parity: " + parity), + }; + + lcr |= (int)stopBits switch + { + STOPBITS_1 => lcr, + STOPBITS_1_5 => throw new Java.Lang.UnsupportedOperationException("Unsupported stop bits: 1.5"), + STOPBITS_2 => LCR_STOP_BITS_2, + _ => throw new Java.Lang.IllegalArgumentException("Invalid stop bits: " + stopBits) + }; + + int ret = ControlOut(0x9a, 0x2518, lcr); + if (ret < 0) + { + throw new IOException("Error setting control byte"); + } } public override bool GetCD() @@ -347,7 +396,7 @@ public override bool GetDTR() public override void SetDTR(bool value) { dtr = value; - WriteHandshakeByte(); + SetControlLines(); } public override bool GetRI() @@ -363,18 +412,32 @@ public override bool GetRTS() public override void SetRTS(bool value) { rts = value; - WriteHandshakeByte(); + SetControlLines(); } - public override bool PurgeHwBuffers(bool flushReadBuffers, bool flushWriteBuffers) + /*public EnumSet getControlLines() { - return true; - } - } - public static Dictionary GetSupportedDevices() + int status = getStatus(); + EnumSet set = EnumSet.noneOf(ControlLine.class); + if(rts) set.add(ControlLine.RTS); + if((status & GCL_CTS) == 0) set.add(ControlLine.CTS); + if(dtr) set.add(ControlLine.DTR); + if((status & GCL_DSR) == 0) set.add(ControlLine.DSR); + if((status & GCL_CD) == 0) set.add(ControlLine.CD); + if((status & GCL_RI) == 0) set.add(ControlLine.RI); + return set; + }*/ + + public override bool PurgeHwBuffers(bool flushReadBuffers, bool flushWriteBuffers) { - return new Dictionary + return true; + } + } + + public static Dictionary GetSupportedDevices() + { + return new Dictionary { { UsbId.VENDOR_QINHENG, new int[] @@ -383,6 +446,6 @@ public static Dictionary GetSupportedDevices() } } }; - } } +} } \ No newline at end of file