PDA

View Full Version : passing single arguments from spin to PASM



clcorbin
01-25-2009, 12:56 PM
I am just getting back into "playing" with assembly on my propeller board. I took an assembly class in college (engineering major, but I took a lot of programming electives) 18 years or so ago. That was on a PDP-11... About a decade ago, I bought a few books and learned SOME PC assembly, more as a hobby and to better understand the PC than anything.

Anyway, I have been starting out small: toggle an output to turn an LED on and off. That worked perfectly, so I decided to expand this simple exercise to the next level and have it flip TWO LEDs on and off. That should be pretty simple, right?

Just duplicating the code and editing the new output pin would have gotten it running, but I decided to be "smart" and add a parameter so I could use the cognew call on the same pasm code and pass it the output pin number to get code reuse and test the waters with passing arguments.

As I had no idea how to deal with arguments in PASM, I hit the manual... And came up blank. The Assembly 101 pdf seemed like a great start (and it was), but I still didn't find my example. A review of assorted PASM examples (along with searching the forums) DID find a couple of references to passing multiple arguments using the fun joy that is self modifying code.

That was a bit over my head for a begining learning exercise!

So, in my digging around, I did not find any simple way to pass a single argument to a PASM function. Either I DID see the correct example and simply didn't understand what t was (entirely possible!), I didn't find the correct example to review or there is no example of this.

Can I talk someone into showing how to do something that SHOULD be simple? Or perhaps point me to a few good examples that I can study and learn from?

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Clint

Mike Green
01-25-2009, 01:11 PM
You need to give an example of what you'd like to do. There are all sorts of ways to pass parameters from Spin to assembler. There are some examples in the "sticky threads" at the top of the message thread list like in "Propeller Programming Tutorials" and the Propeller Education Kit tutorials.

The easiest was is to pass the address of a variable as the 2nd parameter to COGNEW like "COGNEW(@entry,@variable)". The address of the variable will appear in the PAR register in the cog where it can be used with RDxxxx and WRxxxx like "RDLONG temp,PAR" to get the long value stored in "variable" or "WRLONG temp,PAR" to change the value to whatever is in "temp".

clcorbin
01-25-2009, 02:12 PM
Mike,

Thanks for the small kick to the tail. That definitely helped, but it still is not operating like I would expect. Here is the current code, based on the LED example in Assembly 101:




CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000

VAR
long _Pin

PUB Main
{Launch cog to toggle P16 endlessly}

_Pin := 16
cognew(@Toggle, %00000000000000000000000000000001) ' Launch new cog
waitcnt(1000 + cnt)

_Pin := 18
cognew(@Toggle, @_Pin) ' Launch new cog
waitcnt(1000 + cnt)

_Pin := 20
cognew(@Toggle, @_Pin) ' Launch new cog

DAT
ORG 0 'Begin at Cog RAM addr 0
Toggle rdlong Pin, PAR 'Get the Pin number from the Parameter register
mov LED, #1 'Configure pin
shl LED, Pin 'Set the pin mask so only LED's pin is toggled
{Set the outputs}
or dira, LED 'Set Pin to output
{Setup the intial clock and delays}
mov Time, cnt 'Calculate delay time
add Time, #$f 'Set intial delay here
{Start the main loop}
:loop waitcnt Time, Delay 'Wait
xor outa, LED 'Toggle Pin
jmp #:loop 'Loop endlessly

Delay long 600 'Clock cycles to delay

Time res 1 'System Counter workspace
LED res 1 'LED Pin mask
Pin res 1 'Pin number




What I was TRYING to do was set a variable to a pin number, start the code and pass that variable to it, wait a bit (to allow the first cog to initialize and start running), update the pin number to the next pin then start another cog toggling that new pin, etc.

What I found happening was no matter how many calls I made to cognew, it always ended up only toggling the last pin number passed (in above example, pin 20). For testing, I passed it a binary number 1 (instead of the variable) and it DID toggle both pin 1 and pin 20.

I think my understanding of the way cognew is working is flawed. My (limited) understanding was that when I started the new cog, it copied the code passed to it by the address into it's own local COG memory, then ran off the local memory. That would allow me to start the cog, create a local res that held the pin mask, then change the value of the variable before I started the next cog flipping the next pin.

Obviously, that is an incorrect idea!

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Clint

Beau Schwabe
01-25-2009, 04:13 PM
clcorbin, (http://forums.parallax.com/member.php?u=52395)

Your program is working exactly the way you are telling it to. http://forums.parallax.com/images/smilies/smilewinkgrin.gif

Each time you call cognew you are referencing the same variable for the Pin number _Pin.· Consequently the last assignment for _Pin ends up being 20.· Remember·ALL·new instances of Toggle are looking at _Pin.· If you index each pin instance to a unique variable your program will work as you are expecting it to.· I have increased the waitcnt times so that you could physically see the led's toggle and stagger in their startups.


CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
VAR
long _Pin1,_Pin2,_Pin3
PUB Main
{Launch cog to toggle P16 endlessly}
_Pin1 := 16
cognew(@Toggle, @_Pin1) ' Launch new cog
waitcnt(10_000_000 + cnt)
_Pin2 := 18
cognew(@Toggle, @_Pin2) ' Launch new cog
waitcnt(10_000_000 + cnt)

_Pin3 := 20
cognew(@Toggle, @_Pin3) ' Launch new cog
DAT
ORG 0 'Begin at Cog RAM addr 0
Toggle rdlong Pin, PAR 'Get the Pin number from the Parameter register
mov LED, #1 'Configure pin
shl LED, Pin 'Set the pin mask so only LED's pin is toggled
{Set the outputs}
or dira, LED 'Set Pin to output
{Setup the intial clock and delays}
mov Time, cnt 'Calculate delay time
add Time, #$f 'Set intial delay here
{Start the main loop}
:loop waitcnt Time, Delay 'Wait
xor outa, LED 'Toggle Pin
jmp #:loop 'Loop endlessly
Delay long 20_000_000 'Clock cycles to delay
Time res 1 'System Counter workspace
LED res 1 'LED Pin mask
Pin res 1 'Pin number



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe (mailto:bschwabe@parallax.com)

IC Layout Engineer
Parallax, Inc.

Post Edited (Beau Schwabe (Parallax)) : 1/25/2009 8:29:13 AM GMT