Shop OBEX P1 Docs P2 Docs Learn Events
Anybody aware of high accuracy (0.7 % or less) serial full duplex driver? - Page 3 — Parallax Forums

Anybody aware of high accuracy (0.7 % or less) serial full duplex driver?

13»

Comments

  • lonesocklonesock Posts: 917
    edited 2012-08-27 14:31
    OK, next release.
    • Cleaned up the SetBaud function a bit.
    • Documented the few remaining return values.
    • Got the TX carry-clock working (e.g. if the period should be 201 clocks, the half-period delays will alternate between 100 and 101 while sending).

    Jonathan

    EDIT: removed attachment...the one 4 posts down is better
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-08-27 19:32
    Hi Jonathan, here are a couple of preliminary scans. Each was taken with the transmitter only, repeatedly sending an ascii null at 57600. Not much of a test, I know. But the first is using 10MHz with the crystal, to compare with the second, RCfast. In this I made no setBaud adjustment for the actual RCfast frequency. The sigma isn't bad, though, just 0.015, but your algorithm timing is great, because the crystal came in with sigma identically zero.

    The real test comes from banging on it on the receive side. Any particular test you want?

    By the way, I found that it locks up if the receive pin sees a BREAK condition or if the pin is floating when the object is initialized.

    xtal1 5MHz PLLx2:
    10pll_57200.png


    RCfast:
    RCfast_57200.png
    640 x 480 - 14K
    640 x 480 - 14K
  • lonesocklonesock Posts: 917
    edited 2012-08-27 20:32
    Thanks, Tracy!

    No specific tests in mind (though some testing at 460_800 would be nice), I just want to squish any bugs before a formal release. Thanks for the heads up on the break condition...I will try to track that down tomorrow for yet another release.

    Thanks!
    Jonathan
  • pedwardpedward Posts: 1,642
    edited 2012-08-27 23:09
    Ariba wrote: »
    It should be possible to use the video generator to transmit a byte, this would make a very precise bit timing with no jitters.
    And you get more processing time for the receive task in the same cog.

    Andy

    You don't need the video generator, just the counter. You put your bit pattern in the counter high bits, then every N clock cycles you simply shl the counter and it appears on the designated pin. You can queue up to 3 bytes this way. In fact, this would be the way to redesign FDS to have enough cycles in the read loop to get very accurate timing all around.

    EDIT: Zombie thread!

    Another idea, use the other counter in free run capture mode. If you are time slicing the receiver and the transmitter, you look at phsX value of the counter to see if there is a bit transition that's happened since the last look. Each look corresponds to something like this:
    cmp phsb, (some value greater than 1/2 bit period but less than 1 full period) wc
    mov phsb, #0
    shl input, #1
    muxnc input, #1
    

    The idea is that you run it really fast and loose. The sample period you run the loop should be close to the bit period. This way you use the counter to vote the bit value high or low and you don't need to detect the edges. Of course the downside is that you can't get more than 1 transmitter and 1 receiver per COG, but you could possibly sample at very high speeds. I think you could get between 1-3Mbps full duplex. You could compensate for jitter and drift by subtracting or adding to phsX so it works out over time, this would also help with phase delay. If the remote device sends the start bit and you have some phase offset error, just add or subtract that into the phase accumulator of the counter.
  • lonesocklonesock Posts: 917
    edited 2012-08-28 09:12
    Here's the latest release:
    • Larger default RX buffer (you can set it, of course)
    • Added a non-blocking transmit buffer (TxBufNoWait)
    • Testing code uses that non-blocking send to stress the RX *while transmitting*
    • Tightened up some code, and refactored to avoid the lock-up mentioned by Tracy
    • Added more comments to the PASM

    @Tracy: I could not duplicate the lock-up on BREAK, but I did find some code that could be responsible. Did the lock-up only happen on RCFAST at 57_600?

    @pedward: I use a counter to align the RX code with the start bit (if we are closer than 1/4 bit width to the front of the start bit, then I wait another 1/2 bit, guaranteeing we will always be at least 1/4 bit period away from the transition). But using it to actually decide the bit value actually takes one instruction more. The simple way does a TEST then RCR. Using the counter needs a CMP, RCR, then MOV to reset the PHSx register. So other than strengthening the start-bit alignment, I opted to simply use the TEST command.

    Jonathan
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-08-28 11:15
    Jonathan,
    I'm attaching the simple spin program I was using to sample the tx output to p0 and input from p1. All is well if p1 is high. But if I bring it low, the serial output stops.

    -- okay! just tried it with your latest release. Whatever you did, the problem is fixed.

    Here are statistics at 460800 baud (clkfreq=80MHz). Again this is without any activity into the receiver.
    460800.png



    In order to scope out the receive timing in relation to bit edges, I'd need to insert a pin toggle in your receive routine. Could a pin toggle fit in right next to the test instruction?
    [FONT=courier new][SIZE=1]              ' read in 8 bits
    :get_bit      jmpret    lockstep_ret, tx_jump
                  test      maskRX, ina wc
                  rcr       data_in, #1 
                  jmpret    lockstep_ret, tx_jump              
                  djnz      bits_in, #:get_bit
    [/SIZE][/FONT]
    
    640 x 480 - 15K
  • lonesocklonesock Posts: 917
    edited 2012-08-28 12:10
    Thanks, Tracy...that's good news!

    Yep, there is time for a single instruction right after the TEST on line 309.

    Jonathan
  • lonesocklonesock Posts: 917
    edited 2012-08-29 13:45
    By the way, I expect one clock's worth of jitter for a single bit on the RX timing in the following circumstance:
    • The bit period is an odd number of clocks.
    • The cog started transmitting a byte in the middle of receiving a byte.
    This is because of the carry-clock operation. I only had room to shoe-horn it into the transmit code...the receive code is (or at least should be) robust enough to handle the bit period being 170 (at a minimum) clocks instead of 171. If TX isn't running, though, the actual bit period will be an even number. If TX is actively sending out a byte and the period P is an odd number, then it will toggle the 1/2 bit period between P/2 and P/2+1.

    This is one of those features that I like in principle, but it probably doesn't matter, and if I can't figure out a way to get it working all the time I may just dump it. Thoughts / opinions?

    Jonathan
  • lonesocklonesock Posts: 917
    edited 2012-09-01 18:19
    Here's an update:
    • removed the carry-clock code (simpler, not really much less accurate)
    • Added string to integer helper functions (AToI, HToI)
    Jonathan
Sign In or Register to comment.