[resolved][puzzle] pass-through
kuroneko
Posts: 3,623
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
Is this the solution you had in mind, or is there a better way?
We are on the same page.
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.
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.
-Phil
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.
(Kuroneko, somehow I get the feeling there's a much more elegant solution that you're about to spring on us! )
-Phil
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.
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.
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.
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, 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.
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.
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: