Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion UsbSerialForAndroid/Resources/Resource.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

119 changes: 91 additions & 28 deletions UsbSerialForAndroid/driver/Ch34xSerialDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -202,16 +217,16 @@ 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);
}


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);
}

Expand Down Expand Up @@ -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)
{
Expand All @@ -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)
{
Expand All @@ -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)
Expand All @@ -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");
Expand All @@ -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()
Expand All @@ -347,7 +396,7 @@ public override bool GetDTR()
public override void SetDTR(bool value)
{
dtr = value;
WriteHandshakeByte();
SetControlLines();
}

public override bool GetRI()
Expand All @@ -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<ControlLine> getControlLines()
{
return true;
}
}

public static Dictionary<int, int[]> GetSupportedDevices()
int status = getStatus();
EnumSet<ControlLine> 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<int, int[]>
return true;
}
}

public static Dictionary<int, int[]> GetSupportedDevices()
{
return new Dictionary<int, int[]>
{
{
UsbId.VENDOR_QINHENG, new int[]
Expand All @@ -383,6 +446,6 @@ public static Dictionary<int, int[]> GetSupportedDevices()
}
}
};
}
}
}
}