View Full Version : Full-Duplex Serial handshaking

04-23-2008, 10:27 AM
I need to add a handshaking command to the FDS object to signal to the sending serial device to stop sending because the Prop's buffer is full.

I have not decided whether I will be using hardware (CTS) or software (x-on/x-off) handshaking.

Could someone point out where I can add a test in FDS to determine the position of the receive buffer pointer in relation to the buffer size?

I want to either send an x-off command (or set an output pin to low) when the buffer is full and send an x-on command (or output pin high) when the buffer is say 80% empty.

Mike Green
04-23-2008, 10:51 AM
I'd strongly suggest increasing the buffer size in any event. It can be any power of 2. The code uses a bit mask to cause the buffer index to "wrap-around" and the bit mask is chosen to match the declared buffer size.

Right after the "receive" label and its jmpret instruction in the assembly code would be the place to put a test for the space left in the buffer and to clear or set CTS based on that. This would be executed between characters when the routine is waiting for a start bit.

04-23-2008, 11:57 AM
I was hoping that you were going to suggest a point within the spin code section as I am a little rusty with assembly code.

I have increased the buffer size to 512 bytes but the serial data comes in quicker than it is processed.

Could you provide some sample code to toggle an output pin to high when the buffer is 50% full and toggle low when full.


04-23-2008, 06:11 PM
You'll probably want to trigger the X-Off / CTS before buffer full http://forums.parallax.com/images/smilies/wink.gif

At what percentage the signal should be sent really depends on how fast the buffer gets filled, but starting with 75% might be good.


www.norfolkhelicopterclub.co.uk (http://www.norfolkhelicopterclub.co.uk)
You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)
BTW: I type as I'm thinking, so please don't take any offense at my writing style http://forums.parallax.com/images/smilies/smile.gif

Mike Green
04-23-2008, 09:13 PM
The code to turn CTS off has to be in the assembly language section since that's what is filling the buffer and incrementing the pointer. You theoretically could put the code to turn CTS on either in the assembly language or in the Spin routine that empties the buffer (rxcheck), but it's easier to just turn CTS on when it's not off and that way only one cog is trying to control CTS.

Here's a rough outline of what you might need. You might want it to be more complicated, like to add some hysteresis where you turn off CTS when the buffer becomes 3/4 full, but only turn on CTS when the buffer is 1/2 empty for example. If you want to use x-off / x-on, it becomes more complicated. You would like to "insert" the x-on / x-off ahead of the transmit buffer contents, so you'd need to have a flag for each that the transmit routine would check before fetching a byte from the buffer, "fetch" the x-on / x-off, and reset the flag.

rdlong t1,PAR ' Get receive input pointer
mov t2,par ' Get receive output pointer
add t2,#4
rdlong t2,t2
sub t2,t1 wz ' Check if equal
if_z jmp #bufferEmpty
and t2,#bufferMask ' Mask off since there's wraparound
cmp t2,#threshold wc ' Compare to threshold
if_c jmp #notYetFull
or outa,ctsMask ' Set CTS
jmp #continue
andn outa,ctsMask ' Clear CTS
' That's all

04-24-2008, 10:49 AM
Thanks for the example and the advice.

Just one question: What should "bufferMask" be set to ?

Mike Green
04-24-2008, 10:52 AM
bufferMask is set depending on the size of the buffer. The default is 16 bytes, so bufferMask should be $0F. If the buffer size is changed to 64 bytes, bufferMask should be $3F (and the $0F masks in the rest of the code should be changed to $3F as well).

Have a look at the FullDuplexSerial object in BoeBotBasic (from the Object Exchange). It already has been modified for variable size buffers with all the constant masks changed to named constants.

04-24-2008, 11:58 AM
Thanks Mike. I had an "educated" feeling that the mask should represent the size of the buffer.

I have already successfully increased the buffer to 512 bytes but I will take a look at the object you mentioned.