Shop OBEX P1 Docs P2 Docs Learn Events
Full-Duplex Serial handshaking — Parallax Forums

Full-Duplex Serial handshaking

William50William50 Posts: 22
edited 2008-04-24 04:58 in Propeller 1
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.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-04-23 03:51
    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.
  • William50William50 Posts: 22
    edited 2008-04-23 04:57
    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.

    Tnx.
  • simonlsimonl Posts: 866
    edited 2008-04-23 11:11
    You'll probably want to trigger the X-Off / CTS before buffer full 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.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,

    Simon
    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 smile.gif
  • Mike GreenMike Green Posts: 23,101
    edited 2008-04-23 14:13
    William50,
    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
    bufferEmpty
    notYetFull
            andn outa,ctsMask  ' Clear CTS
    continue
    ' That's all
    
  • William50William50 Posts: 22
    edited 2008-04-24 03:49
    Thanks for the example and the advice.

    Just one question: What should "bufferMask" be set to ?
  • Mike GreenMike Green Posts: 23,101
    edited 2008-04-24 03:52
    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.
  • William50William50 Posts: 22
    edited 2008-04-24 04:58
    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.
Sign In or Register to comment.