Skip to content

Commit

Permalink
add dedicated handling for Ch34x baud rate 921600
Browse files Browse the repository at this point in the history
  • Loading branch information
kai-morich committed Jul 28, 2021
1 parent 76f0260 commit 18e300e
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ private void doReadWrite(String reason) throws Exception {
doReadWrite(reason, -1);
}
private void doReadWrite(String reason, int readWait) throws Exception {
byte[] buf1 = new byte[]{ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
byte[] buf2 = new byte[]{ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26};
byte[] buf1 = new byte[]{ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x55, 0x55};
byte[] buf2 = new byte[]{ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x55, 0x55};
byte[] data;

telnet.write(buf1);
Expand Down Expand Up @@ -420,6 +420,36 @@ public void ftdiBaudRate() throws Exception {
}
}

@Test
public void Ch34xBaudRate() throws Exception {
Assume.assumeTrue("only for Ch34x", usb.serialDriver instanceof Ch34xSerialDriver);
usb.open();

int[] baudRates = {
115200, 230400, 256000, 307200, 460800, 921600, 1000000, 1228800
};
for (int baudRate : baudRates) {
telnet.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
usb.setParameters(baudRate, 8, 1, UsbSerialPort.PARITY_NONE);
doReadWrite(baudRate + "");
try {
usb.setParameters(baudRate + (1 << 29), 8, 1, UsbSerialPort.PARITY_NONE);
doReadWrite(baudRate + "+(1<<29)");

usb.setParameters(baudRate - 1, 8, 1, UsbSerialPort.PARITY_NONE);
doReadWrite(baudRate + "-1");

usb.setParameters(baudRate + 1, 8, 1, UsbSerialPort.PARITY_NONE);
doReadWrite(baudRate + "+1");
if (baudRate == 921600)
fail("error expected for " + baudRate + " baud");
} catch(AssertionError err) {
if (baudRate != 921600)
throw(err);
}
}
}

@Test
public void baudRate() throws Exception {
usb.open();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.util.Log;

import com.hoho.android.usbserial.BuildConfig;

import java.io.IOException;
import java.util.Collections;
Expand Down Expand Up @@ -191,29 +194,39 @@ private void initialize() throws IOException {


private void setBaudRate(int baudRate) throws IOException {
final long CH341_BAUDBASE_FACTOR = 1532620800;
final int CH341_BAUDBASE_DIVMAX = 3;

long factor = CH341_BAUDBASE_FACTOR / baudRate;
int divisor = CH341_BAUDBASE_DIVMAX;

while ((factor > 0xfff0) && divisor > 0) {
factor >>= 3;
divisor--;
}
long factor;
long divisor;

if (factor > 0xfff0) {
throw new UnsupportedOperationException("Unsupported baud rate: " + baudRate);
if (baudRate == 921600) {
divisor = 7;
factor = 0xf300;
} else {
final long BAUDBASE_FACTOR = 1532620800;
final int BAUDBASE_DIVMAX = 3;

if(BuildConfig.DEBUG && (baudRate & (3<<29)) == (1<<29))
baudRate &= ~(1<<29); // for testing purpose bypass dedicated baud rate handling
factor = BAUDBASE_FACTOR / baudRate;
divisor = BAUDBASE_DIVMAX;
while ((factor > 0xfff0) && divisor > 0) {
factor >>= 3;
divisor--;
}
if (factor > 0xfff0) {
throw new UnsupportedOperationException("Unsupported baud rate: " + baudRate);
}
factor = 0x10000 - factor;
}

factor = 0x10000 - factor;
divisor |= 0x0080; // else ch341a waits until buffer full
int ret = controlOut(0x9a, 0x1312, (int) ((factor & 0xff00) | divisor));
int val1 = (int) ((factor & 0xff00) | divisor);
int val2 = (int) (factor & 0xff);
Log.d(TAG, String.format("baud rate=%d, 0x1312=0x%04x, 0x0f2c=0x%04x", baudRate, val1, val2));
int ret = controlOut(0x9a, 0x1312, val1);
if (ret < 0) {
throw new IOException("Error setting baud rate: #1)");
}

ret = controlOut(0x9a, 0x0f2c, (int) (factor & 0xff));
ret = controlOut(0x9a, 0x0f2c, val2);
if (ret < 0) {
throw new IOException("Error setting baud rate: #2");
}
Expand Down

0 comments on commit 18e300e

Please sign in to comment.