Shop OBEX P1 Docs P2 Docs Learn Events
[resolved][puzzle] pass-through — Parallax Forums

[resolved][puzzle] pass-through

kuronekokuroneko Posts: 3,623
edited 2010-11-10 22:06 in Propeller 1
A serial port (tx/rx) is connected to the prop at pins A/B, another one at (different) pins C/D. Route traffic from the first port through the prop to the second and vice versa with the minimum amount of software possible to keep the connection alive.

Comments

  • Linus AkessonLinus Akesson Posts: 22
    edited 2010-11-10 05:54
    The first solution that springs to mind involves two cogs and two spare I/O pins. Each cog needs four registers of code to set things up, and can then go on to do other things.

    Is this the solution you had in mind, or is there a better way?
  • kuronekokuroneko Posts: 3,623
    edited 2010-11-10 05:56
    Is this the solution you had in mind, or is there a better way?

    We are on the same page.
  • Linus AkessonLinus Akesson Posts: 22
    edited 2010-11-10 07:01
    Come to think of it, I actually need six registers per cog, worst case. I forgot about setting up DIRA.

    By the way, if we're free to choose A/B/C/D ourselves, the puzzle can be solved with no more than three registers on a single cog. But then the cog can't do anything else.
  • kwinnkwinn Posts: 8,697
    edited 2010-11-10 07:31
    A single cog and very simple pasm program is all you need.

    Read data on port 1 rx pin
    Write data to port 2 tx pin
    Read data on port 2 rx pin
    Write data to port 1 tx pin

    If you select the pins carefully a read, shift, write, and jump instruction are all that is needed.

    Sorry, forgot to include an "and" between the shift and write instruction to remove unwanted bits.
  • ericballericball Posts: 774
    edited 2010-11-10 07:53
    With the proper port arrangement it's 6 longs total:
    { port 1 rx pin = N
    port 1 tx pin = N+x
    port 2 tx pin = N+16
    port 2 rx pin = N+16+x
    }
    	MOV	DIRA, outmask
    loop	MOV	outmask, INA
    	ROL	outmask, #16
    	MOV	OUTA, outmask
    	JMP	#loop
    outmask	LONG	|<(N+x)+|<(N+16)
    
  • Tracy AllenTracy Allen Posts: 6,666
    edited 2010-11-10 08:22
    How about the ol' POSDET inverters:
    ctra := (%01001 << 26) + (pA << 9) + pD
    ctrb := (%01001 << 26) + (pC << 9) + pB
    {pA and pC are prop tx outputs, pB and pD are prop rx inputs}
    
  • jazzedjazzed Posts: 11,803
    edited 2010-11-10 08:59
    How about the ol' POSDET inverters:
    ctra := (%01001 << 26) + (pA << 9) + pD
    ctrb := (%01001 << 26) + (pC << 9) + pB
    {pA and pC are prop tx outputs, pB and pD are prop rx inputs}
    
    Very nice :) At a glance this seems like a reasonable solution.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-11-10 10:39
    The feedback is always negative, though. You would need a external inverters to restore the polarity. ('Too bad there isn't a mode with positive feedback. It would make Schmitt triggers easier! :) )

    -Phil
  • jazzedjazzed Posts: 11,803
    edited 2010-11-10 14:04
    The feedback is always negative, though. You would need a external inverters to restore the polarity. ('Too bad there isn't a mode with positive feedback. It would make Schmitt triggers easier! :) )

    -Phil
    Oh rats :)
  • kuronekokuroneko Posts: 3,623
    edited 2010-11-10 15:22
    jazzed wrote: »
    Oh rats :)

    Don't be so negative! You can simply chain two cogs which sorts out polarity issues and we are back to a zero-footprint connection.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2010-11-10 18:09
    But doing the reinversion internally does use up two more pins. Does that count toward the "footprint"?

    (Kuroneko, somehow I get the feeling there's a much more elegant solution that you're about to spring on us! :) )

    -Phil
  • kuronekokuroneko Posts: 3,623
    edited 2010-11-10 18:14
    ericball wrote: »
    With the proper port arrangement it's 6 longs total:
    {
    port 1 rx pin = N
    port 1 tx pin = N+x
    port 2 tx pin = M
    port 2 rx pin = M+x
    M > N
    }
    	MOV	DIRA, outmask
    loop	MOV	outmask, INA
    	ROL	outmask, #M-N
    	MOV	OUTA, outmask
    	JMP	#loop
    outmask	LONG	|<(N+[COLOR="Red"]?[/COLOR])+|<(M)
    

    Can you give an example arrangement? The way the pins are assigned ATM and to have it work requires a stronger restriction than M>N.
  • ericballericball Posts: 774
    edited 2010-11-10 18:17
    Hi kuroneko,

    Hmmm... thinking about it, you are correct. M = N + 16. I'll update my post.

    So to pass through the standard P30/P31 serial port (P30 - Serial Tx to host, P31 - Serial Rx from host ) then P15 would be serial Tx and P14 would be serial Rx.
  • kuronekokuroneko Posts: 3,623
    edited 2010-11-10 18:23
    But doing the reinversion internally does use up two more pins. Does that count toward the "footprint"?

    Emphasis was on software overhead which is zero for this counter approach. Unfortunately it uses 2 extra pins and 2 cogs (but covers any assignment and the cogs are only borrowed). Next best thing would be the 3 instruction version suggested by Linus although it's limited to specific assignments.

    As for a more elegant solution, erm, not ATM. But it's on my list of irritating limitations so maybe I come up with something at some point.
  • Tracy AllenTracy Allen Posts: 6,666
    edited 2010-11-10 19:07
    I do happen to have a PCB where the one device comes in true (prop plug) and the other device is inverted (an embedded modem), due to the way the level shifters are arranged. So the single pair of cog counters works fine with that. It's a freebie when it works.

    I see now this is what Linus was proposing too, in pasm, 6 instructions to set dira, dirb, outa, outb, ctra, and ctrb. And the same in another cog plus the two helper pins if you need the second inversion. Dirs and outs really only need to be done once and are probably going to be absorbed in some other code. So it really comes down to the 2 ctrx, or 4 ctrx + 2 helper pins.

    Out of curiosity I tried a dedicated cog spin version that comes down to this snippet,
    repeat
         outa[pA] := ina[pD]
         outa[pC] := ina[pB]
    
    Which with 80MHz clock was able to keep up at 9600 baud, but with noticeable jitter on the edges. That can be a bit faster if the pins alternate in a way that allows shift & mask.
  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2010-11-10 19:11
    I normally just poll these pins and pass them through in this manner but bear in mind that although this sample code dedicates a cog you are still able to implement a call to this bit of code within say a normal uart cog as long as the polling rate is fast enough to update the pins which doesn't really have to be all that fast. I find that there are usually at least one of the cogs that can be patched for such operations if there aren't any spare.

    This is only a functional solution and not the "elegant" solution you were asking for. But squeeze tight enough and elegant solutions just seem to pop out.
    ' connect an serial port to a second port in simple virtual wire mode 
    '
    patch_init
            or      dira,txd1
            or      dira,txd2
    patching
            test    rxd1,ina wc
            muxc  outa,txd2
            test    rxd2,ina wc
            muxc  outa,txd1
            jmp    #patching
    
    rxd1  long  |<rxdpin1
    txd1  long  |<txdpin1
    rxd2  long  |<rxdpin2
    txd2  long  |<txdpin2
    
  • Linus AkessonLinus Akesson Posts: 22
    edited 2010-11-10 22:06
    Ok, here are my proposals, as hinted at the beginning of the thread. Two cogs, two spare pins, six registers per cog:
    mov DIRA, =1 << A | 1 << D
    mov CTRA, =%01001 << 26 | A << 9 | C
    mov CTRB, =%01001 << 26 | D << 9 | B
    

    The above code inverts the polarity, so to get a pass-through effect you need to daisy-chain two cogs.

    My second proposal is a single cog and three registers, but only if we can pick the pin numbers ourselves. This is how it could be done if A = 23, B = 1, C = 0, D = 24:
            movi DIRA, #3
    loop    movi OUTA, INA
            jmp #loop
    
Sign In or Register to comment.