How to write to a group of pins in PASM2?
jrullan
Posts: 168
in Propeller 2
I need to write to 8 sequential pins at the same time by moving a byte of data to them.
If I start @ pin 0, its easy enough:
But if I want to start at an arbitrary pin by specifying a pinfield it seems there is no single instruction that can do this.
I came up with this 9-instructions approach but I wonder if there is a correct way of doing this or a more efficient way:
Can this be done in less than 9 operations?
If I start @ pin 0, its easy enough:
MOV OUTA, data
But if I want to start at an arbitrary pin by specifying a pinfield it seems there is no single instruction that can do this.
I came up with this 9-instructions approach but I wonder if there is a correct way of doing this or a more efficient way:
CON _clkfreq = 160_000_000 VAR long stack[40] long pinfield PUB main() pinfield := 16 addpins 7 COGINIT(COGEXEC_NEW,@go,@pinfield) DAT ORG 0 go RDLONG pin_f, PTRA DIRH pin_f 'Set pins to outputs MOV base, pin_f 'Get base of pinfield AND base, #$3F '9 operations to move the data byte into an arbitrary position in OUTA MOV shifted, OUTA 'Get current value of OUTA MOV mask, #$FF 'Create a mask for 8 bits SHL mask, base 'Align mask with base pin position NOT mask 'Invert the mask AND shifted, mask 'Get everything but our pins MOV newval, data 'Get the data to send to the pins SHL newval, base 'Shift the new data to base pin position OR shifted, newval 'Combine data with the rest of the pins data AND OUTA, shifted 'Finally push the new value to OUTA data long 21 pin_f long 0 base long 0 mask long 0 shifted long 0 newval long 0
Can this be done in less than 9 operations?
Comments
Thanks @Tubular, honestly I would love to learn how to use the streamer. The benefits of it could out weight the arbitraryness of the requirements but I've tried to read the available documentation and I haven't been able to put it all together in my head. There seems to be several moving parts which I haven't identified so far.
Thanks @JonnyMac, it didn't occur to me to see the under the hood approach of other instructions. Seems like the "right way" approach to do what I want. But.. there are a few things to unpack and understand from that snippet:
Isn't .reg a symbol pointing to the muxq operation? It seems like bitc is hacking the encoding of muxq to modify its destination address (if that's true it's a pretty neat trick!) That seems to overcome the problem of limiting the arbitraryness to either within OUTA or within OUTB.
It still cost 9 operations but it is more versatile than my code. Wow so much to learn!
As always, thank you all, such a great community of like minded people!!
YES! I can confirm, finally understood the snippet, it in fact modifies the bit #9 of the MUXQ instruction using the carry from the ROR on the pinfield. If base pin is >= 32 the carry == 1 so it changes OUTA address from $1FC to $1FD (which is the address of OUTB) effectively selecting between the two with the carry. WOW!
THIS IS THE WAY!