On Sun, Feb 21, 2021 at 09:15:06PM -0500, Michael G. Katzmann wrote: > > So on more investigation and many hours of trial and error I have > determined the correct formua for the non-standard rates with this > Prolific 2303. > > There are four bytes used to send the baud rate. When not using the > 'standard' rates, the Linus driver sets byte 3 to 0x80 and bytes 1 and > 0 hold the divisor of the clock (12MHz * 32). > This divisor is encoded in a special way. The 'exponent' (log 4) and > the mantissa. This is calculated by dividing the divisor by 4 until it > is less than 512 (the number of times you can do this is the > exponent). e then goes in bits 1,2 and 3 of byte 1 with the MSBit of > the mantissa in bit 0 of byte 1. Byte 0 holds the lower 8 bits of the > mantissa. > > This does not work on the device I have USB PID/VID/REV is 0673 / > 2303/3.00. Instead...the calculation uses 1024 instead of 512 in the > method above and the exponent is in byte 1 bits 7,6&5 (the top 2 bits > of the mantissa are in bits 0 and 1). I tested this on all baud rates > that stty will allow that are not 'standard' and it works. (50, 110 > .... 3000000). > > The changed routine is below. I presume the original driver worked so > perhaps this device is a new variant with the same USB VID/PID. Nice work! Joe Abbott reported a similar issue (incidentally also when trying to use an ASR33) a few weeks ago and concluded that the Windows driver uses a different encoding: https://lore.kernel.org/r/CADuz4ONmN299aw460r4wXCEK5F1v9kt_cewCCrdg2hb5nJV9uQ@xxxxxxxxxxxxxx His device also had a bcdDevice of 0x0300 as yours (even if I believe his fell back to 9600 baud). Does your updated algorithm also result in 110 baud (8n1) being encoded as: a8 a6 01 80 00 02 07 And are you using some official Prolific Windows driver or something that came with the device? I tried asking Prolific about this but I'm still not sure whether these are official chips or counterfeit. 0x0300 is supposed to be a PL2303TA and Prolific claims that the current driver is working fine with these so we'd need to key off something more than just bcdDevice. Charles, here's another device that appears to use a different baudrate encoding. Does this mean it's not one of your devices or how can we detect when to use the alternate encoding? > static speed_t pl2303_encode_baud_rate_divisor(unsigned char buf[4], > speed_t baud) > { > unsigned int baseline, mantissa, exponent; > /* > * Apparently the formula is: > * baudrate = 12M * 32 / (mantissa * 4^exponent) > * where > * mantissa = buf[8:0] > * exponent = buf[11:9] > * > * Michael Katzmann: At least versions of the chip VID 0x067b PID 0x2303 bcdDevice 3.00 > * uses mantissa = buf[9:0] > * exponent = buf[15:13] > */ > baseline = 12000000 * 32; > mantissa = baseline / baud; > if (mantissa == 0) > mantissa = 1; /* Avoid dividing by zero if baud > 32*12M. */ > exponent = 0; > #undef ORIGINAL > #ifdef ORIGINAL > while (mantissa >= 512) { > if (exponent < 7) { > mantissa >>= 2; /* divide by 4 */ > exponent++; > } else { > /* Exponent is maxed. Trim mantissa and leave. */ > mantissa = 511; > break; > } > } > buf[3] = 0x80; > buf[2] = 0; > buf[1] = exponent << 1 | mantissa >> 8; > buf[0] = mantissa & 0xff; > #else > while (mantissa >= 1024) { > if (exponent < 7) { > mantissa >>= 2; /* divide by 4 */ > exponent++; > } else { > // This is an logical modification of the original code > // but I do not know if this an actual limitation > /* Exponent is maxed. Trim mantissa and leave. */ > mantissa = 1023 ; > break; > } > } > buf[3] = 0x80; > buf[2] = 0; > buf[1] = exponent << 5 | (mantissa >> 8); > buf[0] = mantissa & 0xff; > #endif > /* Calculate and return the exact baud rate. */ > baud = (baseline / mantissa) >> (exponent << 1); > > return baud; > } > > > On 2/21/21 10:37 AM, Michael G. Katzmann wrote: > > The Linux driver does not seem to produce sensible baud rated for > > other than the 'supported' rates. > > > > stty to 110 bd results in ~95,000 bd (that's not a typo but 95 > > thousand). Other rates like 200 also produce odd speeds although not > > in a logical manner. > > > > The data sheets don't describe the formula used for deriving the > > four bytes used to set the speed. > > > > I tried adding 110 to the supported rates but this did not produce > > the correct baud rate so I presume the Windows driver is using a > > formula different than the one in the Linux driver for 'non > > standard' baud rates. > > Johan