Re: non-standard baud rates with Prolific 2303 USB-serial

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux