Extra bit time in FullDuplexSerial?
David Betz
Posts: 14,516
I was just looking through some code that I derived from the FullDuplexSerial driver and noticed the following:
or txdata,#$100 'or in a stop bit shl txdata,#2 or txdata,#1 'or in a idle line state and a start bit mov txbits,#11What's this about "idle line state"? Why is it necessary to add an extra bit time between two adjacent bytes during transmission? Shouldn't it be possible to send to bytes back to back?
Comments
This is how I do it, but it assumes the TX line is properly setup to begin with.
[Edit] Having thought about it for a minute, Chip probably did this because he couldn't add two stop bits without creating a constant (like I did) -- #$300 would be an illegal constant in PASM as it exceeds 511.
At low baud rates you're right: two stop bits is not required. But at faster baud rates with a software UART, the extra stop bit gives the processor time to handle what just came in (clean-up, buffer management, etc). FDS may be assuming that the other side is software too and is being kind.
It would not be very difficult to write a version of FDS that allowed one to set the number of stop bits. In most apps it's one or two (though I've seen more in a couple instances), and if one is okay, two will work. It seems to be the lowest [practical] common denominator.
Is there a way to set the carry flag with a single instruction?
Is there a way to clear the carry flag with a single instruction?
I'd like to write a function that use the state of the carry to indicate success or failure and it would be nice to be able to load up the value of C with a single instruction.
There's a thread where I discuss my attempt to add even parity to a serial driver. Tracy Allen kindly educated me about start bits and stop bits. There was mention of the two stop bits in this thread. I'm sure I could find it if you're interested in reading it.
Edit: Here's the link:
http://forums.parallax.com/showthread.php/155390-Adding-Even-Parity-to-One-Port-in-Tracy-Allen-s-4-Port-Serial-Object
I think there are ways to do what you want, but I'm not a PASM wizard yet either, just a guy who slogs it out trying to write simple code.
Phil Pilgrim once has a list of instruction tricks that would be helpful -- but they were lost during the forums migration. Perhaps he or on of the other PASM wizards will chime in. I'd like to know, too!
It can be a good idea to have a second stop bit as optional.(or even more choice, if that is easy to do )
You are right that at the byte-level, and with very fast receivers, there is no strict need, and it could be removed.
There is however a somewhat subtle system level use case where an extra idle bit helps, and that is with Baud skew on long packets.
If you receive 100 bytes, and echo on each one, you can get a TX overflow effect with slight baud differences.
(just 1% here is a full byte of creep)
Adding a second stop bit, allows the Baud to skew and ensures a slightly slower TX, can always pace continual RX.
If you push up the BAUD speed on FTDI/CP210x you will see they add extra stop bits, from the firmware not being able to keep up. They can add 1-2-3-4+ extra idle bit times.
The HS parts of FT232H/FT2232H are able to send higher speeds without added idles/stop bits..
+1
Thanks kuroneko.
-Phil
Keep in mind that 'standard baud rates' are no longer a constraint. (but keep them as a default/fallback)
Most modern USB-UART devices can accept any baud value, and deliver the nearest baud they support, which is mostly from a 12MHz virtual Baud Clock.
http://obex.parallax.com/object/246
If there a 2 COG version of this, that can go (a lot?) faster ? ie one COG for RX and One COG for TX
My dedicated fast serial receive routine works up to 3M baud with only one stop bit between characters so to make sure it can write the received data to the hub and be ready in time it prepares the hub write and index update while it is still receiving data so that all it has to do between characters is to write the data to the hub. btw, the TX part of this is a simple bit-bang without the need for buffering because at these high baud rates it's faster to bang out the bits rather than slow hub buffering and unbuffering.
I sometimes wish that asynch data would always have a start bit (0) followed by a mark (1) and then the data, so that start bits and timing could always be confirmed, that is detect the start bit and/or measure its width, then synchronize on the leading edge of the sync pulse. Then UARTs could automatically adapt their baud rates on the fly. All for the sake of 1 bit we are stuck with fixed baud rates and timing mismatches.
Is that 3.00Mbd with what Crystal / System Clock ? What margin is there for other clocks ?
Suppose a design used a USB related Clock, the two candidates could be
(16*48M/10)/3M = 25.6 - a simply alternating 25/26 would be ~0.4% off ?
(16*48M/8)/3M = 32
or a Std Xtal gives
(16*5M)/3M = 26.6666 => /27/27/26 repeating
I've tested this on a standard 80MHz Prop and checked the this with a scope as well. I know the timing would be off a little but it seems to work fine because I used it at this baudrate for quite some time early in the Tachyon development. 2M baud does not have this timing error at 80Mhz but my newer boards are designed to run from a 6MHz oscillator at 96MHz so there is no timing error at this frequency. btw, my start bit timing is pre-calculated to half a bit time less 4 cycles to compensate for latencies at higher speeds and I always check the stop bit for framing error as part of break detection.
Does it have enough headroom to run 3M at 25.5 cycles per bit average (vs 26 2/3 at 80Mhz )
If it uses an unrolled loop, it may be possible to support fractional baud ideas to get more Xtal choice tolerance.
Check my sig for the Dropbox links where you will find the serial receive right at the end of the Tachyon2.4.spin source or look in the "trouble with serial code" thread where I pasted this code in. It is more than just unrolled, it is interwoven and writes immediate fields to reconstruct the data so that saves a right justification operation as well.
Cheers,
Peter (pjv)
The 1/3 tick error can be centrally positioned, to be -1.5 tick at start and +1.5 tick at Stop bit.
I think there is room to gain another 15% bit timing margin, if you swap the Startbit code to immediately after Stop/save (removes one JMP, and inserts it in a less critical place).
With some low cost Micros having 1.5% Oscillator tolerance, every bit of margin helps.
Of course, if the Micro also provides the 4.8MHz or 6Mhz CLK, then there is no relative drift to allow for.