6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 15, 2024 3:29 am

All times are UTC




Post new topic Reply to topic  [ 15 posts ] 
Author Message
 Post subject: NXP "INDUSTRIAL" UARTs
PostPosted: Tue Jul 05, 2016 8:37 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8487
Location: Midwestern USA
Elsewhere on the forum, someone had expressed dismay with the ongoing transmit bug in the WDC 65C51 UART and said that he was going to use something else. Ergo I thought I'd post the driver code that I developed several years ago for the Philips/NXP "industrial" UARTs that have FIFOs. The attached code is for the 65C816 and was done in the Kowalski assembler, using macros to synthesize the '816 instructions. It will need some work before it will assemble, but you shouldn't have any trouble resolving assembler dependencies.

By the way, the "industrial" moniker comes from the fact that these UARTs have been widely used in TIA-232/422/485 factory networks to communicate with machines. Reliability and performance are major concerns in such electrically hostile environments, things that Philips addressed long ago in their line of UARTs. My experience with Philips UARTs date back some 25 years, and I have long recommended they be used in place of the 65C51 or 6850, both of which represent the state of the art of the 1970s. :D

The 26C92 and 28L92 that I have used in my POC units are part of a family of UARTs that come in single, dual, quadruple and octal channel models. For our purposes, the following single, dual and quad units are best used (see attached data sheets):

  • 28L91 — single channel UART with 16-deep receive and transmit FIFOs, in a PLCC-44 package. Use with a MAX-232 transceiver to implement TIA-232 with hardware handshaking. I recommend this device in place of the 16550, the latter which is a bit of a pain to program.

  • 26C92 — dual channel UART with 8-deep receive and transmit FIFOs, in a PLCC-44 package. Use with a MAX-238 transceiver to implement TIA-232 with hardware handshaking.

  • 28L92 — dual channel UART with 16-deep receive and transmit FIFOs, in a PLCC-44 package. Use with a MAX-238 transceiver to implement TIA-232 with hardware handshaking.

  • 28C94 — quadruple channel UART with 8-deep receive and transmit FIFOs, in a PLCC-52 package. Use with a MAX-248 transceiver to implement TIA-232 with hardware handshaking.

The 28C94 may be characterized as two 26C92s in a single package. There is also a 28L194 quad channel device that is more-or-less two 28L92 units in one package, as well as an eight channel unit, the 28L198, which is sort of two 28L194 units in a single package. I have not used the 28L194 or 28L198, or investigated their suitability for a 65xx system.

All of these UARTs are capable of a maximum of 921 Kbps CBAT simultaneously on all channels, assuming the host system has enough performance to process the interrupts. In addition to their serial capabilities, the 28L91, 26C92 and 28L92 have a 16 bit counter/timer that can be used for a variety of timing purposes, such as generating a jiffy IRQ. The 28C94 has two such counter/timers. Also present are some programmable I/O pins that can be used for various things.

A 3.6864 MHz clock is used by these UARTs to drive the baud rate generator(s) and perform internal sequencing. Hence these UARTs run asynchronously relative to the 65xx Ø2 clock, which has some hardware interfacing implications. Use of the 65C816's VDA/VPA address qualifying outputs is mandatory with these devices to avoid errors when certain registers are accessed.

The attached driver code includes a file named ASSEMBLE_DRIVER.asm, which can be loaded into the Kowalski assembler/simulator and assembled once some (obvious) dependencies are resolved. Pay particular attention to the following line of code in that file:

Code:
.include "include\hardware\nxp\28l92.asm"

The above INCLUDE statement indicates which UART is being used. Info files for the 26C92, 28L92 and 28C94 are available.

As this is not a trivial piece of software, you will need to study it in some detail in order to successfully adapt it to your system. For example, there are stubs in the interrupt handlers that will need to be resolved before successful assembly can occur. Also, I have not created a setup table for the 28C94, which is noted in source comments (it's something that can be created from the existing dual channel table).

If you have any questions on this driver, please post them here and I'll try to give you some help.
——————————————————————————————————————————————————————
Attachment:
File comment: NXP 28L91 Single Channel UART
uart_single_28L91.pdf [268.4 KiB]
Downloaded 200 times
Attachment:
File comment: NXP 28L92 Dual Channel UART (DUART)
uart_dual_28L92.pdf [336.96 KiB]
Downloaded 220 times
Attachment:
File comment: NXP 28C94 Quadruple Channel UART (QUART)
uart_quad_28C94.pdf [231.41 KiB]
Downloaded 177 times
Attachment:
File comment: NXP UART 65C816 Drivers
nxp_uart.zip [34.68 KiB]
Downloaded 210 times

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 06, 2016 1:30 pm 
Offline

Joined: Wed Oct 23, 2013 8:52 pm
Posts: 17
Thank you for posting this topic, I have tried to find SC28L91s. My local stockist only has the '92s and no longer stock the '91s. Looking through the datasheet it appears that both parts have the same pinout but the RxDB, and TxDB pins have been removed on the '91. I have pulled a design together based on the '92.

I'm just wondering if there is anyway to create a piggy back board that plugs into the 6551 28pin socket so I can get rid of them once and for all!!


Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 06, 2016 4:05 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8487
Location: Midwestern USA
malcnorth wrote:
Thank you for posting this topic, I have tried to find SC28L91s. My local stockist only has the '92s and no longer stock the '91s.

Mouser Electronics stocks the 28L91 in TSOP. Dunno if that's a viable source for you.

Quote:
I'm just wondering if there is anyway to create a piggy back board that plugs into the 6551 28pin socket so I can get rid of them once and for all!!

I don't see why not, although the piggyback board would have to have some logic on it to generate /RD, /WD, the inverted reset, etc. The attached circuit generates /RD and /WD, fully qualified by Ø2. You can run your reset line through an unused section of U5 to generate the active high reset needed by the 28L9x.

Attachment:
File comment: Read/Write Signal Generation w/Ø2 Qualification
read_write_qualify.gif
read_write_qualify.gif [ 32.21 KiB | Viewed 4745 times ]

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Last edited by BigDumbDinosaur on Fri Jul 08, 2016 5:57 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 06, 2016 5:47 pm 
Offline

Joined: Wed Oct 23, 2013 8:52 pm
Posts: 17
As it turned out I could only get parts in PQFP or TSSOP, so i have ordered everything from mouser, i went for the duart as I can re-use it when I get past the debug on this board. Ordered some proto PCBs as well so should be able to build in about a weeks time. I'll keep you posted, in the meantime I will look at the piggy back board.


Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 06, 2016 6:08 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8487
Location: Midwestern USA
malcnorth wrote:
As it turned out I could only get parts in PQFP or TSSOP, so i have ordered everything from mouser, i went for the duart as I can re-use it when I get past the debug on this board.

When I designed POC I never considered the single channel UART, as there was no PCB real estate savings to be had and I was sure I could find a use for the second channel. I subsequently set up channel B to provide a data link to my UNIX (now Linux) software development box, transferring data via Motorola S-records.

POC V2 will use the 28C94 and a MAX248, continuing with channel A as the console and channel B acting as the data link to my development machine. I will have two uncommitted channels available for other functions, such as driving a serial printer—I have an old Oki 520 with a serial interface. Something else I may toy with is rigging up a TIA-485 data link between two or more POCs, just to see if I can make it work. Such a link could be run at 96 KB/second, which while not at 10Base-T speed, would be plenty fast.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 06, 2016 11:20 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1385
malcnorth wrote:
Thank you for posting this topic, I have tried to find SC28L91s. My local stockist only has the '92s and no longer stock the '91s. Looking through the datasheet it appears that both parts have the same pinout but the RxDB, and TxDB pins have been removed on the '91. I have pulled a design together based on the '92.

I'm just wondering if there is anyway to create a piggy back board that plugs into the 6551 28pin socket so I can get rid of them once and for all!!


Well, not exactly. The 6551 only has two address lines, the NXP devices requires 3 or more depending on the specific device. While you could re-purpose the Xtal lines for additional address lines (and put the NXP clock onboard), it's not a drop-in replacement as a plug-in board. Beyond that no real issue.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 13, 2016 3:48 pm 
Offline

Joined: Thu Jun 04, 2015 3:43 pm
Posts: 42
Nitpicking this post in the WDC 65C51 thread.

BigDumbDinosaur wrote:
At least in the case of the NXP UARTs, non-standard baud rates can be configured in software by using the counter/timer as the clock source for the baud rate generator. For example, the 26C92 DUART can be made to run at speeds up to 920 Kbps by having the internal baud rate generator slaved to C/T underflows. To achieve 920 Kbps, the C/T is programmed to free-run at its shortest periodic rate, which is X1 ÷ 4, where X1 is the 3.6864 MHz clock source. The result is that the baud rate generator sees a 921.6 KHz time base.


In my reading of the datasheet, the timer output is used to create the 16x clock for the baud rate generator; the result of feeding it with a 921600 Hz clock would be a data rate of 57600 bits per second. (Edit: I mixed up the terms here, the baud rate generator is a different block; I should have said it's the 16x clock that goes into the transmitters and receivers.)

I had the same initial excitement about programming baudrates using the timer, but what you seem to end up with - at least with the C92 - is at low divisors either coarse adjustments (base/2, base/3, etc) that duplicate standard baud rates, oddball in-between baud rates, or at larger divisors, very slow rates. Do the later chips let you generate the x1 clock too?

But on the other hand you can use a second externally generated clock to drive the transmitter/receiver circuits, and that looks more useful to get nonstandard baud rates. (That's how old MIDI interfaces for the Mac used to work, they'd generate a 1 MHz or 500 kHz clock that was fed into the serial port circuitry to get the 500k/16 = 31250 bps data rate.)


Last edited by magetoo on Thu Jul 14, 2016 4:55 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Wed Jul 13, 2016 5:31 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8487
Location: Midwestern USA
magetoo wrote:
Nitpicking this post in the WDC 65C51 thread...In my reading of the datasheet, the timer output is used to create the 16x clock for the baud rate generator; the result of feeding it with a 921600 Hz clock would be a data rate of 57600 bits per second.

Take a look at CSRA[3:0], CSRA[7:4], etc., described on page 18 of the 26C92 data sheet, to see how to run at 921.6 Kbps.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 14, 2016 4:52 am 
Offline

Joined: Thu Jun 04, 2015 3:43 pm
Posts: 42
BigDumbDinosaur wrote:
Take a look at CSRA[3:0], CSRA[7:4], etc., described on page 18 of the 26C92 data sheet, to see how to run at 921.6 Kbps.


I've read the datasheet too, and I see a different picture.

Page 2, "DESCRIPTION":
Quote:
[Each] receiver and transmitter can select its operating speed as one of 27 fixed baud rates, a 16X clock derived from a programmable counter/timer, or an external 1X or 16X clock

Page 8, "BRG"
Quote:
The clock outputs from the BRG are at 16X the actual baud rate. The counter/timer can be used as a timer to produce a 16X clock for any other baud rate by counting down the crystal clock or an external clock.

Page 8, "Baud Rate Generation with the C/T"
Quote:
When the timer is selected as baud rates for receiver or transmitter via the Clock Select register their output will be configured as a 16x clock. Therefore one needs to program the timer to generate a clock 16 times faster than the data rate.

And when we take a look at the CSRA/CSRB registers on page 18:
Quote:
CSRA7:4 - Channel A Receiver Clock Select
The receiver clock is always a 16X clock except for CSRA[7:4]=1111. (meaning an external 1X clock is used)
CSRA3:0 - Channel A Transmitter Clock Select
The transmitter clock is always a 16X clock except for CSRA[3:0]=1111.


So what is this 16X clock that keeps being mentioned?

RS-232 is an asynchronous signalling standard. This means that there is no clock common to transmitter and receiver, and when someone sends you a sequence of bits you have to figure out where the transitions are yourself. The way this is done is by sampling the incoming signal many times per nominal bit time and using several data points to decide whether you are seeing a one or a zero. Sampling only once per bit time *can not work* when running asynchronously - you could never be sure if you were safely sampling in the middle of bits, or sampling near the edges, and since transmitter and receiver clocks might skew, the edges could move in such a way that you sample the same bit twice or miss some bits entirely.

So that's why we have an internal clock that is a multiple of the baud rate. Why 16? I'm not an expert, but sampling the signal levels 16 times per bit seems to be a theme common to all UARTs I have seen; so without going on another research binge I'd say there is a standard (RS-232?) that specifies sampling at 16 times the nominal baud rate, and that this is baked in deep into the silicon. (but see below)

If you read datasheets for UARTs this factor of sixteen shows up again and again; maximum baud rates tend to be the externally provided clock divided by 16, with possibly a pre-divider in front. All the standard baud rates are a "baud rate crystal frequency" divided by small integer values, divided by 16. The stop bit length for the C92 is specified in increments of 1/16 of a bit time. And so on.


There's also the what-if argument. The maximum "regular" baud rate mentioned in the datasheet is 230400 baud. This is the nominal clock frequency of 3.6864 MHz divided by 16. If it were possible to go higher using the timer, don't you think that functionality would be included in the regular baud rate generator and the resulting higher data rate bragged about on page one? (Other manufacturers, like Maxim, do exactly this with their 8X and 4X modes.)


So for the 'C92 and clones/descendants, it seems that the only way to reach 921600 bps is by bypassing most of the internal clocking circuitry and feeding the transmitters/receivers directly with a faster 16X clock signal - which the silicon does let you do. This clock can go up to 16 MHz, which gives the 16MHz/16 = 1Mbit maximum data rate that is listed in the data sheet.

The other way to go faster is by using a crystal with a different frequency. The highest data rate that is possible without clocking transmitters/receivers directly would then be 500kbit/sec, since the X1 main clock input is limited to 8 MHz.


What about those 1X modes then? I don't know. 1X sampling won't work in asynchronous communication. The only explanation that makes sense is that they are there for synchronous operation, when transmitter and receiver are fed by the same clock. It also makes sense for a synchronous communication option to be tied to the external clocking option. (I believe some of the later NXP UARTs can output a 16X or 1X clock on their GPIO pins - presumably so that one end could generate the clocks that the other end uses.)


This post took over two hours to write. Should have left it at "no, you're wrong".


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 14, 2016 9:31 am 
Online
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8541
Location: Southern California
I'm in no position to comment about the 26C92; but I'll comment on possibly forgoing a much higher input clock rate:
magetoo wrote:
So what is this 16X clock that keeps being mentioned?

RS-232 is an asynchronous signalling standard. This means that there is no clock common to transmitter and receiver, and when someone sends you a sequence of bits you have to figure out where the transitions are yourself. The way this is done is by sampling the incoming signal many times per nominal bit time and using several data points to decide whether you are seeing a one or a zero. Sampling only once per bit time *can not work* when running asynchronously - you could never be sure if you were safely sampling in the middle of bits, or sampling near the edges, and since transmitter and receiver clocks might skew, the edges could move in such a way that you sample the same bit twice or miss some bits entirely.

So that's why we have an internal clock that is a multiple of the baud rate. Why 16? I'm not an expert, but sampling the signal levels 16 times per bit seems to be a theme common to all UARTs I have seen; so without going on another research binge I'd say there is a standard (RS-232?) that specifies sampling at 16 times the nominal baud rate, and that this is baked in deep into the silicon.

If you could start the receiver clock at the perfect time and only wanted to sample once per bit, you could start the clock when you sense the valid leading edge of the start bit, then start sampling half a cycle later (we're already accounting for slew rate), and every cycle after that, until you receive the stop bit. Although it's not the best, a 1X clock would work. But since you can't start a crystal oscillator that way, and won't find crystals at say 230,400Hz or 921,600Hz anyway, you start with a higher crystal frequency, and start a counter when the start bit's valid leading edge is detected, and then you can get time resolution that's 1/8 the time of half bit, which is quite adequate. I understand many UARTs sample many times in each bit period and "take a vote," in order to minimize the effects of noise.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 14, 2016 10:44 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10977
Location: England
(I think the early simpler UARTs, like the 6850 found in Acorn's Beeb, offer 64x, 16x and 1x clock inputs. For the first two, that means they oversample the input, can get a timing reference from the falling edge of the start bit, and for subsequent bits they aim to sample near the middle of the bit. It's possible they even take a majority vote on the three middle samples - I'm sure I've seen that done. But indeed, at 1x mode, the datasheet is clear that the clock needs to be synchronous with the incoming data.
http://www.classiccmp.org/dunfield/r/6850.pdf
)


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 14, 2016 11:44 am 
Offline

Joined: Mon Aug 05, 2013 10:43 pm
Posts: 258
Location: Southampton, UK
My limited experience of UARTs:

MC6850: A nice simple UART. Nice and compact, 24 pin DIP. Trivial to program. 1, 16 or 64 clock divider. On my micro I clocked the CPU at the 3.68Mhz and divided down by 64 in the UART to give a 57600 serial console rate. These are easy to obtain through ebay costing only a couple of quid each and IMO make a great "starter UART". Though of course they are NMOS, with no baud rate generator, FIFO etc. But they are still worth looking at for a first time SBCer.

XR88C681: This is a DUART available in DIP28, DIP40 or PLCC44. I think these parts, and the NXP ones BDD talks about, are derived from the MC68681, which was Motorola's DUART in the 68K companion IC family? (If someone has some kind of "family tree of UARTs" I'd love to see it). Anyway, these are harder to obtain, especially the "sawn off" 28 pin DIP version. 2/4 FIFO, with a timer. Max rate is apparently 1Mbit/s though the most I cranked mine too was 1152000. I'm sure NXP have a very similar part, though I'm not sure if they are/were made in DIP.

SC16C654: A QUART in PLCC68. I'm not sure how these fit into the models BDD mentions. But this one has a 64byte FIFO, and has the dual bus mode support (MC68K vs Intel). I use 68 mode in my board, even if I do have to monkey around with the CS line to assert it later to mimic the 68000 bus. It means the interrupt lines are shared which was necessary with my interrupt routing arrangement. Annoyingly it lacks a timer, but it does have that nice deep FIFO and it's rated to 5Mbit/s, though again I've only used it at 115200. I mainly chose this QUART because I got a job lot at a good price on eBay.

Of course all of those were picked without concern for wether the part was current or not.

UARTs are fun! I've not yet found one that I didn't like or was difficult to program, though as you get into the more complex ones I have found a number of subtle behaviours that exist because the vendor wants to retain backward compatibility (the register "API") with earlier models and make the next iteration a drop in replacement. This is a tad irritating; the "new" functionality is often hidden behind other registers etc. And the NXP datasheets are really much to terse for my tastes.

_________________
8 bit fun and games: https://www.aslak.net/


Top
 Profile  
Reply with quote  
PostPosted: Thu Jul 14, 2016 5:45 pm 
Offline

Joined: Thu Jun 04, 2015 3:43 pm
Posts: 42
GARTHWILSON wrote:
If you could start the receiver clock at the perfect time and only wanted to sample once per bit, you could start the clock when you sense the valid leading edge of the start bit, then start sampling half a cycle later (we're already accounting for slew rate), and every cycle after that, until you receive the stop bit. Although it's not the best, a 1X clock would work.


Good point, that is the more important reason to have the 16X clock and I was mixing up two unrelated things earlier.

Detecting the start bit and taking a majority vote of multiple samples both use faster clocks, but majority sampling is not really needed. When the receiver has synchronized and is shifting in bits, it samples at the same point for each bit (or takes multiple samples around the same point for each bit), and there just isn't enough time within one received word for that point to drift by much when the words are short.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jul 15, 2016 12:29 am 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 589
Location: Michigan, USA
Aslak3 wrote:
My limited experience of UARTs:

MC6850: A nice simple UART. Nice and compact, 24 pin DIP. Trivial to program. 1, 16 or 64 clock divider. On my micro I clocked the CPU at the 3.68Mhz and divided down by 64 in the UART to give a 57600 serial console rate. These are easy to obtain through ebay costing only a couple of quid each and IMO make a great "starter UART". Though of course they are NMOS, with no baud rate generator, FIFO etc. But they are still worth looking at for a first time SBCer.

May I mention the Hitachi CMOS HD6350 versions of the NMOS MC6850/EF6850 series as an alternative? They're perfect for the (classic I/O) 1-MHz and 2-MHz 'starter', 'trainer', 'retro', or 'replica' systems I build. You can get NOS (New Old Stock) HD63B50P parts for 66 cents each (quantity 5, including shipping) from Chinese vendors and my simple inexpensive PIC 'ClockGen' can generate any x16 baud rate clock for 2400-bps up to the 1-mbps limit (the NMOS 6850 series top out at 500-kbps).

Have fun, guys. Cheerful regards, Mike


Attachments:
HD6350-HD6850 ACIA Datasheet.pdf [543.24 KiB]
Downloaded 172 times
Top
 Profile  
Reply with quote  
 Post subject: NXP "INDUSTRIAL" UARTs
PostPosted: Mon Jul 18, 2016 6:12 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8487
Location: Midwestern USA
Here are some reference materials I had stashed away in a dusty corner of one of my servers.
Attachment:
File comment: Serial Interface Quick Reference
serial_qik_ref.pdf [86.77 KiB]
Downloaded 186 times
Attachment:
File comment: Serial Interface White Paper
whitepaper_rs232_rs485.pdf [69.96 KiB]
Downloaded 191 times
Attachment:
File comment: Extended Data Rates on Philips UARTs
extended_data_rates.pdf [34 KiB]
Downloaded 178 times
Attachment:
File comment: TIA-485 Automatic Turnaround
auto485_turnaround.pdf [38.31 KiB]
Downloaded 200 times

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 14 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: