Spin running on P2!
David Betz
Posts: 14,516
Using the latest version of PropGCC for P2 and a slightly hacked version of Eric's spin2cpp translator, I got the following code running on my DE2-115:
VAR long val PUB main dirb := $ffffffff val := $55555555 repeat pinb := val val ^= $ffffffff waitcnt(getcnt + 30000000)I'm not sure though if this actually qualifies as having Spin working on P2 since it is just Spin translated to C++. :-)
Comments
I thought you could read PINx registers and expect them to be what you have driven them to as long as you waited long enough. I'm assuming the C++ code in your version would end up with the assigning and the xor'ing happening one after another and would optimize down to just the 2 instructions (mov, xor), with the loop stuff being after the wait, to jump back up? Am I missing something, or just wrong about pinb?
Roy
Rearranging the code as you suggested did not make it work. Maybe Chip will comment on how PINx works. I seem to remember him saying that a read-modify-write instruction will do what we expect but not two separate instructions. I don't think propgcc optimizes to a single read-modify-write instruction.
Have You tested use this instruction first?
Maybe.
I dont know how ports are on default mode ---> so this instruction can give You correct results if default are different that You wait
No problem..
We are here to help others understand P2 ----> so Yours ideas help me and vice-versa
Oh right, I was thinking along the wrong lines there. I think maybe it has to do with what slot the PINB register is accessed from (D or S). So you need PINB to be in the D slot to write out to the pins, but in the S slot to read the input state of the pins. (Or is it the reverse of that?
Can you share the C code produced (since I don't have access to spin2cpp at the moment), and the GAS/PASM output from propgcc?
Roy
Here is the generated code using -Os -mno-fcache.
I guess it's obvious what the problem is here. GCC doesn't generate a read-modify-write instruction with PINB in the destination field. I'm not sure if the optimizer could be improved to handle this case. Maybe Eric will know.
Chip:
OFFP D/#n - clears both the DIR bit and PIN bit for the PIN (input with output bit low)
GETP and GETNP do not affect the DIR bit. They only read the input, regardless of its DIR state. In other words,
if a PIN is outputting a low, but is externally being forced high, you will read the high state.
Thanks, I don't understand why that doesn't work? Can you share the GAS/PASM of the version that does work?
Sapieha: This is exactly what I though I remembered Chip saying a while back - that it read the IO pin and not the internal output latch. (And IIRC this is different to the P1).
Note that bits 5 and 6 of D/#n will determine which port gets selected. There was a time when my assembler would treat constants differently for PORT instructions, using bits 0 and 1, but I thought it would be troublesome, so I made it not shift the constant bits down, giving identical function for either a register or a constant (that is, bits 5 and 6 are used).
It is true that only a read-modify-write (or a write) to a PINx register will affect the output latches. A read-without-write will read the pins' input states, not the output latches. This is an unintended consequence of getting rid of discrete IN and OUT registers - it is not an issue in assembly, but it is in high-level languages.
That's right.
Ariba write in one of threads that. BUT You never commented it. It is correct?
(Ariba:) ? ? ?
If you use one of the pin output instructions (SETP, CLRP, NOTP ...) the direction is automatically set to output,
you don't need to set DIRx first.
So: Yes there is another way beside setting DIRx.
If you don't trust me then you can try it yourself with your DE0_NANO. That's how I found it out, it's not just phantasy.
A possible testcode: Andy
It's too late to change anything, at this point.
A high-level language may have to do read-modify-writes intended for OUT on a separate register which always gets copied to the PIN register.
The separate register approach is what I used in the first message of this topic. It works just fine. I have LEDs blinking on my DE2-115 board running the Spin code in that post.
If the DIRx bit is set you should anyway read the output states at the inputs. Otherwise you have a serious hardware problem (driving two outputs with opposite states against each other).
I only see a problem with "OpenDrain" outputs and PullUps which you preset to Low and then change only the DIRx bit. The Low of the output latch may be changed to High if you do a "Read PINx - Write PINX" sequence to modify another pin. But normally you will do OpenDrain pins with "CLRP pin" for Low and "OFFP pin" for High on the Prop 2.
If this is really a big problem then instead of separate INx and OUTx registers an easier solution my be a special "read output latch" instruction: RDOUTA r1
Andy
It si not that I don't trust You.
But for PDF I build i need INFO that are confirmed by Chip.
Ps.
Yours code now applied as example.
I don't know. It should work.
And it works when I run a similar code with the PNUT "IDE".
Andy
Thanks.
Now I can apply that to PDF as confirmed.