Port-amiga archive

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

Re: Problems with IOblix serial ports



So you might try to add
 options  COM_16650
to your config file, to improve things (which should be included in the
GENERIC file, when it really helps). I'm not absolutely sure about this,
but from the com.c source it seems that most(all?) 16650 functions are
supported by the 16C654.

I've added this, but didn't see any changes. It was pointed out to me by a different brother that the 16C654 should be considered distinct:

"DON'T use the 16550 datasheet to determine the characteristics for the 16550 as applying to the 16654. The 550 is a National Semiconductor part and copied by dozens of companies. The 1665x is a Startec/Exar part, copied by only a few companies. It is a much newer part and probably faster."

In com.c it's mentioned that there are other features (such as automatic hardware flow control) on the StarTech versions and that the National Semiconductor part is handled differently in several respects as compared with the StarTech. I did notice that the GENERIC kernel shows:

com0 at iobl0 port 0x0108 ipl 6: ns16650a, working fifo
...

whereas the new kernel with COM_16650 shows:

com0 at iobl0 port 0x0108 ipl 6: st16650a, working fifo
...

There is a very interesting feature I found in the datasheet:

The ST16C654 has a built-in clock-divider function, which divides the
output baud rate either by 1 or by 4 (!). Sounds familiar? ;)
It is contolled by bit 7 of the MCR register, which seems unused in com(4),
as far as I could see.

After a reset this bit should be zero, which means divide by 1. But
something in your system (maybe com(4)?) sets it to 1, enabling divide by 4.

Setting MCR-bit7 could be correct, because when not dividing by 4 some
important baud rates are not available:

MCR     Bit7=1     Bit7=0
           50        200
          300       1200
          600       2400
         1200       4800
         2400       9600
         4800      19.2K
         9600      38.4k
        19.2k      76.8k
        38.4k     153.6k
        57.6k     230.4k
        115.2k    460.8k

So the error seems to be that com(4) doesn't take the 16654-specific
clock-divider into account, while calculating the clock for the baud
rate you have set. That could be fixed in comspeed().

A simple solution would be to reset the bit to zero, but then you won't
get 115200 neither, according to the table above.

Is MCR-bit7 per port, or is it set for the entire chip?

For a clean solution com(4) should be able to detect a 16654 first, but I
don't know how to do it. Are there any differences to detect? In the worst
case we have to create a new option, like COM_16654.

In the case of the IOblix, we could always assume 16654. Patrick or Mike - what do you recommend regarding detecting a 16654 as compared with a 16550?

Maybe you want to make some experiments first? Print/reset this bit at
various places? Test with a factor 4 in comspeed(). Then we could even
move this discussion to a MI list, like tech-kern or tech-misc?

Will do.

Patrick made these nice division tables. Perhaps someone can explain
how we're getting some of these baud rates from a 24 MHz oscillator?
Or is 9615 baud close enough to 9600 that it doesn't matter much?

That's a tolerance below 2%, not 25% as in your first table (or I
misunderstood something).

The percentages were the amount of remainder left.

The com(4) driver accepts tolerances up to 3% (COM_TOLERANCE). So this
should be safe.

Gotcha.

Thanks very much! I'll report back when I've done a few more tests.

John


Home | Main Index | Thread Index | Old Index