EmbeddedRelated.com
Forums

UART design considerations

Started by Keith M March 3, 2008
I've implemented a simple software-based UART on a 50-mhz Parallax
uC.  I'm operating it at a baud rate of 2mbps.  It talks to an FTDI
FT232BM chip (http://www.ftdichip.com/Products/FT232BM.htm) in a usb-
serial converter.  While I've done extensive testing of the transmit
portion of my code, I'm still working on and refining my RX code.

Most UART implementations use an over-sampling (I've seen it called
super-sampling or majority center sampling as well) method where the
UART samples each bit between 8 and 16 times, and then uses that to
determine the transmitted bit value.  My simple UART samples just
once.

My pseudocode looks like this:

(interrupts are off)

wait for transition high to low     'look for start bit
NOP delay x-cycles to middle of 1st bit

for 8-bits

sample the bit
NOP delay rest-of-bit-period

next
NOP delay to eat stop bit


What PRACTICAL problems could show up by not oversampling?  My cable
distances are about 3 inches.  The FTDI converter uses a 6mhz crystal,
and the uC uses a 50mhz Murata resonator.

By waiting for the transition, I'm in-effect sync'ing to the start
bit.  So how much could my clock, or the FTDI's clock) really drift in
8(or 10 if you included start/stop) bit-times?  Even if there is a
slight change in the transmitted bit-period, wouldn't it have to be a
huge error in the same direction, before I end up sampling in the
wrong place?

I'm not arguing the time-tested methods that UARTs use --- I just
don't understand them in context of today's hardware.

Note that this is a hobby project, not a commercial or space shuttle
application, so simplicity here is really the deciding factor for me.

Thanks

Keith
On Mon, 03 Mar 2008 19:38:21 -0800, Keith M wrote:

> I've implemented a simple software-based UART on a 50-mhz Parallax uC. > I'm operating it at a baud rate of 2mbps. It talks to an FTDI FT232BM > chip (http://www.ftdichip.com/Products/FT232BM.htm) in a usb- serial > converter. While I've done extensive testing of the transmit portion of > my code, I'm still working on and refining my RX code. > > Most UART implementations use an over-sampling (I've seen it called > super-sampling or majority center sampling as well) method where the > UART samples each bit between 8 and 16 times, and then uses that to > determine the transmitted bit value. My simple UART samples just once. > > My pseudocode looks like this: > > (interrupts are off) > > wait for transition high to low 'look for start bit NOP delay > x-cycles to middle of 1st bit > > for 8-bits > > sample the bit > NOP delay rest-of-bit-period > > next > NOP delay to eat stop bit > > > What PRACTICAL problems could show up by not oversampling? My cable > distances are about 3 inches. The FTDI converter uses a 6mhz crystal, > and the uC uses a 50mhz Murata resonator. > > By waiting for the transition, I'm in-effect sync'ing to the start bit. > So how much could my clock, or the FTDI's clock) really drift in 8(or 10 > if you included start/stop) bit-times? Even if there is a slight change > in the transmitted bit-period, wouldn't it have to be a huge error in > the same direction, before I end up sampling in the wrong place? > > I'm not arguing the time-tested methods that UARTs use --- I just don't > understand them in context of today's hardware. > > Note that this is a hobby project, not a commercial or space shuttle > application, so simplicity here is really the deciding factor for me. >
AFAIK the standard UART behavior is to sample the _three_ intervals in the middle of a bit, and use a majority vote to decide on a 0 or a 1. If your signal is clean enough it doesn't make any difference at all to sample once or thrice. I think it's really a leftover from 300 baud modems working over phone lines -- I don't think that there are many point-to-point transmission environments where the signal is much improved by the majority-three voting. Doing a majority-16, or better yet doing an integrate-and-dump would, indeed, help, but not a majority-three, IMHO. -- Tim Wescott Control systems and communications consulting http://www.wescottdesign.com Need to learn how to apply control theory in your embedded system? "Applied Control Theory for Embedded Systems" by Tim Wescott Elsevier/Newnes, http://www.wescottdesign.com/actfes/actfes.html
On Mar 3, 11:43 pm, Tim Wescott <t...@seemywebsite.com> wrote:
> If > your signal is clean enough it doesn't make any difference at all to > sample once or thrice.
Sure.
> I don't think that there are many point-to-point transmission > environments where the signal is much improved by the majority-three > voting. Doing a majority-16, or better yet doing an integrate-and-dump > would, indeed, help, but not a majority-three, IMHO.
Majority-three doesn't sound too hard to implement. Sampling any more than just a few times would probably not work. 16 * 2mbps = 32mhz. Doesn't leave much time for anything else. I don't have enough practical experience to know really what can go wrong. My application will checksum the received data, which will be sent in relatively small groups, and it will retransmit any failed groups. It will be transmitting at 2mbps w/ no flow control, but I'm not concerned. The uC will be dedicated to the task of receiving the data and storing it. I have serial memory, so I might just store it as its received in real-time bit-by-bit.
> Tim Wescott
Thanks for the conversation. Keith
On Mar 4, 2:31 pm, Keith M <kmo...@gmail.com> wrote:
> On Mar 3, 11:43 pm, Tim Wescott <t...@seemywebsite.com> wrote: > > > If > > your signal is clean enough it doesn't make any difference at all to > > sample once or thrice. > > Sure. > > > I don't think that there are many point-to-point transmission > > environments where the signal is much improved by the majority-three > > voting. Doing a majority-16, or better yet doing an integrate-and-dump > > would, indeed, help, but not a majority-three, IMHO. > > Majority-three doesn't sound too hard to implement. Sampling any more > than just a few times would probably not work. 16 * 2mbps = 32mhz. > Doesn't leave much time for anything else. > > I don't have enough practical experience to know really what can go > wrong. > > My application will checksum the received data, which will be sent in > relatively small groups, and it will retransmit any failed groups. It > will be transmitting at 2mbps w/ no flow control, but I'm not > concerned. The uC will be dedicated to the task of receiving the data > and storing it. I have serial memory, so I might just store it as its > received in real-time bit-by-bit. > > > Tim Wescott > > Thanks for the conversation. > > Keith
I have never seen a UART that samples a bit more than once. The reason for the 8x or 16x clock is to detect the edge of the start bit with enough accuracy to then time out to the middle of the bit. Although you would not expect much drift in 10 bit times, the application of the standard UART does not always require a crystal and so it is tolerant of about 2% variation on each end. To get that level of tolerance, you need to start pretty much in the middle of the bit time. Then in 10 bits you won't be outside of the last bit. So how much resolution do you get when you "wait" for the start bit transition? What is the time of the loop? Try testing it by waiting for the start bit and then toggling an output bit. In fact, you can replace the "sample the bit" with "toggle output" to see how consistently you find the middle of the bit. A scope won't lie. BTW, by resonator, do you mean one of those ceramic things? My understanding is that they can vary a lot with temperature and from part to part. So you might actually miss the tolerance you need to make this work correctly. But some people use the term "resonator" to mean a crystal which would be much more accurate. I don't think you will see very much noise, just timing issues. Rick
On Wed, 5 Mar 2008 12:28:22 -0800 (PST), rickman <gnuarm@gmail.com>
wrote:

>I have never seen a UART that samples a bit more than once. The >reason for the 8x or 16x clock is to detect the edge of the start bit >with enough accuracy to then time out to the middle of the bit.
The AVRs, at least, also pull multiple samples at the expected center of the start bit after edge detection, and then also at the computed center of each data bit. For example, see page 148 of the data sheet <http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf> [Note for folks on a slow link, this is a 4.5 MB file.] -- Rich Webb Norfolk, VA

"rickman" <gnuarm@gmail.com> skrev i meddelandet
news:2c8f87cb-412b-4b9b-8c61-46bb7f6f453b@x30g2000hsd.googlegroups.com...
> On Mar 4, 2:31 pm, Keith M <kmo...@gmail.com> wrote: >> On Mar 3, 11:43 pm, Tim Wescott <t...@seemywebsite.com> wrote: >> >> > If >> > your signal is clean enough it doesn't make any difference at all to >> > sample once or thrice. >> >> Sure. >> >> > I don't think that there are many point-to-point transmission >> > environments where the signal is much improved by the majority-three >> > voting. Doing a majority-16, or better yet doing an integrate-and-dump >> > would, indeed, help, but not a majority-three, IMHO. >> >> Majority-three doesn't sound too hard to implement. Sampling any more >> than just a few times would probably not work. 16 * 2mbps = 32mhz. >> Doesn't leave much time for anything else. >> >> I don't have enough practical experience to know really what can go >> wrong. >> >> My application will checksum the received data, which will be sent in >> relatively small groups, and it will retransmit any failed groups. It >> will be transmitting at 2mbps w/ no flow control, but I'm not >> concerned. The uC will be dedicated to the task of receiving the data >> and storing it. I have serial memory, so I might just store it as its >> received in real-time bit-by-bit. >> >> > Tim Wescott >> >> Thanks for the conversation. >> >> Keith > > I have never seen a UART that samples a bit more than once. The > reason for the 8x or 16x clock is to detect the edge of the start bit > with enough accuracy to then time out to the middle of the bit.
You use the three sample majority voter mentioned before to get rid of noise in most UARTs AFAIK. Some advanced UARTs detect edges which are a little off, and will add/substract a sample from that bit to adapt to the incoming speed. Instead of sampling, you could only detect the time when there is an edge on RXD and then make decision from that info.
> Although you would not expect much drift in 10 bit times, the > application of the standard UART does not always require a crystal and > so it is tolerant of about 2% variation on each end. To get that > level of tolerance, you need to start pretty much in the middle of the > bit time. Then in 10 bits you won't be outside of the last bit. > > So how much resolution do you get when you "wait" for the start bit > transition? What is the time of the loop? Try testing it by waiting > for the start bit and then toggling an output bit. In fact, you can > replace the "sample the bit" with "toggle output" to see how > consistently you find the middle of the bit. A scope won't lie. > > BTW, by resonator, do you mean one of those ceramic things? My > understanding is that they can vary a lot with temperature and from > part to part. So you might actually miss the tolerance you need to > make this work correctly. But some people use the term "resonator" to > mean a crystal which would be much more accurate. > > I don't think you will see very much noise, just timing issues. > > Rick
-- Best Regards, Ulf Samuelsson This is intended to be my personal opinion which may, or may not be shared by my employer Atmel Nordic AB
Keith M wrote:

> On Mar 3, 11:43 pm, Tim Wescott <t...@seemywebsite.com> wrote: > > If > > your signal is clean enough it doesn't make any difference at all to > > sample once or thrice. > > Sure. > > > I don't think that there are many point-to-point transmission > > environments where the signal is much improved by the majority-three > > voting. Doing a majority-16, or better yet doing an integrate-and-dump > > would, indeed, help, but not a majority-three, IMHO. > > Majority-three doesn't sound too hard to implement. Sampling any more > than just a few times would probably not work. 16 * 2mbps = 32mhz. > Doesn't leave much time for anything else.
The 80C51 UARTS have always used x3 mid samples, and the AVRs followed that lead. It is quite common for simplest SW uarts to just fire T=1.5 bit times on start edge and then every bit time (ie not bother with any over sample) Don't forget to start the search for START bit edge, in the MIDDLE of the stop bit. A more thorough design will have false start detection (ie over sample the start bit), to make sure a spike does not fire a Byte RX The new Atmel ATxmega data, has a good uart section, and it also covers a x16 and x8 modes, and the required clock precisions needed. Makes good reference. -jg
On Mar 5, 3:28 pm, rickman <gnu...@gmail.com> wrote:

> I have never seen a UART that samples a bit more than once.
http://datasheets.maxim-ic.com/en/ds/MAX3100.pdf From PDF page 7, "An internal clock samples data at 16 times the data rate. The start bit can occur as much as one clock cycle before it is detected, as indicated by the shaded portion. The state of the start bit is defined as the majority of the 7th, 8th, and 9th sample of the internal 16x baud clock. Subsequent bits are also majority sampled." I must not be reading this right. Or is this just the exception?
> So how much resolution do you get when you "wait" for the start bit > transition? What is the time of the loop?
Great question. I hoping to get into the down and dirty with this. I'm at 50mhz, so my instruction execution cycle is 20ns. My bit period is 500ns for 2mbps baud rate. And remember this is _not_ RS232, so forget about inverting stuff. waitforstartbit: SNB receivepin (if receivepin is LOW, skip the next instruction) JMP waitforstartbit The execution time would be 2 cycles (2*20=40ns) if receivepin was low at the top of the code, or 4 cycles (4*20=80ns) if it had loop back. I _think_ this gives me a jitter of 40ns, the difference. Does this sound right? Even if I am slightly early or slightly late, this problem won't continue to slip (given a fixed transmit bit period), I'd just end up consistently sampling slightly off center on each bit. IE, its just a problem getting started, not a continuing problem.
> Try testing it by waiting > for the start bit and then toggling an output bit. In fact, you can > replace the "sample the bit" with "toggle output" to see how > consistently you find the middle of the bit. A scope won't lie.
Great idea.
> BTW, by resonator, do you mean one of those ceramic things?
I think so. CSTLS50M0X51-B0 http://www.murata.com/catalog/p16e.pdf Just so everyone knows, this uart code of mine actually functions as is, so I'd hope there aren't any MAJOR issues with it. I am in the process of doing a code review and want to stress test it. I'm looking to see if there are major design flaws in my code, since I've never written a UART before....
> Rick
Thanks! Keith
On Mar 5, 4:33 pm, Rich Webb <bbew...@mapson.nozirev.ten> wrote:

> The AVRs, at least, also pull multiple samples at the expected center > of the start bit after edge detection, and then also at the computed > center of each data bit. For example, see page 148 of the data sheet > <http://www.atmel.com/dyn/resources/prod_documents/doc2486.pdf> > [Note for folks on a slow link, this is a 4.5 MB file.]
Thanks for the link, Rich. That picture/description looks exactly like how Maxim is doing it with the MAX3100 UART. I posted the datasheet in another reply. That atmega link spells out exactly how they do their majority ruling, which is good, if end up implementing it.
> Rich Webb Norfolk, VA
Keith
On Mar 6, 2:27 am, "Ulf Samuelsson" <u...@a-t-m-e-l.com> wrote:

> You use the three sample majority voter mentioned before to get rid of noise > in most UARTs AFAIK. > Some advanced UARTs detect edges which are a little off, and will > add/substract a sample from that bit to adapt to the incoming speed.
Once again, I saw Maxim doing that. That's pretty neat, pretty advanced, and pretty unlikely I'm gonna touch it with a 10-ft assembly pole. :)
> Instead of sampling, you could only detect the time when there is an > edge on RXD and then make decision from that info.
Yeah, so you are saying to do edge detection to find the start bit, and then, what, just use delays as I'm doing now between the bits, and sample each bit? I don't really know what that gains me. Since I don't plan on using interrupts for this(for simplicity's sake, other stuff going on in the ISR, even though interrupts are disabled), I still have to check the edge detect register for a value. And that checking would be subject to the same "SNB/JMP" jitter I mentioned in an earlier reply. There are other issues, like my uC not supporting edge detection on my current port, etc.
> Best Regards, > Ulf Samuelsson > This is intended to be my personal opinion which may, > or may not be shared by my employer Atmel Nordic AB
Thanks Keith