mik3y / usb-serial-for-android

Android USB host serial driver library for CDC, FTDI, Arduino and other devices.
MIT License
4.9k stars 1.59k forks source link

The baud rate of 921600 doesn't work. #377

Closed Voluntino closed 3 years ago

Voluntino commented 3 years ago

Hello, I modified the baud rate, but only the baud rate of 921600 doesn't work, and the other baud rates including 1500000 can work normally. What's the problem? My hardware is Ch34x. Thank you very much for your contribution!

Voluntino commented 3 years ago

I solved this problem by modifying the baud rate calculation.

kai-morich commented 3 years ago

How did you change it? Can you provide a patch?

Voluntino commented 3 years ago

I'm glad to share my thoughts with you. 

I wrote a brief account in the annex. Please remind me if you have any related improvements in the future.

------------------ 原始邮件 ------------------ 发件人: "mik3y/usb-serial-for-android" @.>; 发送时间: 2021年7月26日(星期一) 中午12:43 @.>; @.**@.>; 主题: Re: [mik3y/usb-serial-for-android] The baud rate of 921600 doesn't work. (#377)

How did you change it? Can you provide a patch?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

Voluntino commented 3 years ago

In Ch34xSerialDriver.setBaudRate

I think the calculation here may be wrong, but because I'm not good at hardware, I can't rule out the error in the calculation formula.

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

            if (factor > 0xfff0) {
                throw new UnsupportedOperationException("Unsupported baud rate: " + baudRate);
            }

            factor = 0x10000 - factor;
            divisor |= 0x0080; // else ch341a waits until buffer full
            int ret = controlOut(0x9a, 0x1312, (int) ((factor & 0xff00) | divisor));
            if (ret < 0) {
                throw new IOException("Error setting baud rate: #1)");
            }

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

Then I referred to this: UsbSerial/CH34xSerialDevice.java at master · felHR85/UsbSerial (github.com)

// Baud rates values
    private static final int CH34X_300_1312 = 0xd980;
    private static final int CH34X_300_0f2c = 0xeb;
    private static final int CH34X_600_1312 = 0x6481;
    private static final int CH34X_600_0f2c = 0x76;
    private static final int CH34X_1200_1312 = 0xb281;
    private static final int CH34X_1200_0f2c = 0x3b;
    private static final int CH34X_2400_1312 = 0xd981;
    private static final int CH34X_2400_0f2c = 0x1e;
    private static final int CH34X_4800_1312 = 0x6482;
    private static final int CH34X_4800_0f2c = 0x0f;
    private static final int CH34X_9600_1312 = 0xb282;
    private static final int CH34X_9600_0f2c = 0x08;
    private static final int CH34X_19200_1312 = 0xd982;
    private static final int CH34X_19200_0f2c_rest = 0x07;
    private static final int CH34X_38400_1312 = 0x6483;
    private static final int CH34X_57600_1312 = 0x9883;
    private static final int CH34X_115200_1312 = 0xcc83;
    private static final int CH34X_230400_1312 = 0xe683;
    private static final int CH34X_460800_1312 = 0xf383;
    private static final int CH34X_921600_1312 = 0xf387;
    private static final int CH34X_1228800_1312 = 0xfb03;
    private static final int CH34X_1228800_0f2c = 0x21;
    private static final int CH34X_2000000_1312 = 0xfd03;
    private static final int CH34X_2000000_0f2c = 0x02;
private void setBaudRate(int baudRate) throws IOException {
            if(baudRate <= 300)
            {
                int ret = setBaudRate(CH34X_300_1312, CH34X_300_0f2c); //300
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 300  && baudRate <= 600)
            {
                int ret = setBaudRate(CH34X_600_1312, CH34X_600_0f2c); //600
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");

            }else if(baudRate > 600 && baudRate <= 1200)
            {
                int ret = setBaudRate(CH34X_1200_1312, CH34X_1200_0f2c); //1200
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 1200 && baudRate <=2400)
            {
                int ret = setBaudRate(CH34X_2400_1312, CH34X_2400_0f2c); //2400
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 2400 && baudRate <= 4800)
            {
                int ret = setBaudRate(CH34X_4800_1312, CH34X_4800_0f2c); //4800
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 4800 && baudRate <= 9600)
            {
                int ret = setBaudRate(CH34X_9600_1312, CH34X_9600_0f2c); //9600
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 9600 && baudRate <= 19200)
            {
                int ret = setBaudRate(CH34X_19200_1312, CH34X_19200_0f2c_rest); //19200
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 19200 && baudRate <= 38400)
            {
                int ret = setBaudRate(CH34X_38400_1312, CH34X_19200_0f2c_rest); //38400
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 38400 && baudRate <= 57600)
            {
                int ret = setBaudRate(CH34X_57600_1312, CH34X_19200_0f2c_rest); //57600
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 57600 && baudRate <= 115200) //115200
            {
                int ret = setBaudRate(CH34X_115200_1312, CH34X_19200_0f2c_rest);
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 115200 && baudRate <= 230400) //230400
            {
                int ret = setBaudRate(CH34X_230400_1312, CH34X_19200_0f2c_rest);
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 230400 && baudRate <= 460800) //460800
            {
                int ret = setBaudRate(CH34X_460800_1312, CH34X_19200_0f2c_rest);
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }else if(baudRate > 460800 && baudRate <= 921600)
            {
                int ret = setBaudRate(CH34X_921600_1312, CH34X_19200_0f2c_rest);
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            } else if(baudRate > 921600 && baudRate <= 1228800)
            {
                int ret = setBaudRate(CH34X_1228800_1312, CH34X_1228800_0f2c);
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            } else if(baudRate > 1228800 && baudRate <= 2000000)
            {
                int ret = setBaudRate(CH34X_2000000_1312, CH34X_2000000_0f2c);
                if(ret == -1)
                    throw new IOException("SetBaudRate failed!");
            }
        }

The calculated value of each baud rate is listed, and the calculation is skipped. Finally, the equipment can work.

kai-morich commented 3 years ago

the if baudrate ... variant was previously used in this library and later replaced with the formula variant to support non-standard baudrates. I will try to figure out differences.

Voluntino commented 3 years ago

Thanks.

kai-morich commented 3 years ago

fixed with 18e300efa3ec5e5b78acaa326ad6e525c3e10abd

kai-morich commented 3 years ago

released with v3.4.2