Shop OBEX P1 Docs P2 Docs Learn Events
passing single arguments from spin to PASM — Parallax Forums

passing single arguments from spin to PASM

clcorbinclcorbin Posts: 14
edited 2009-01-25 08:13 in Propeller 1
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

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-01-25 05:11
    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".
  • clcorbinclcorbin Posts: 14
    edited 2009-01-25 06:12
    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 SchwabeBeau Schwabe Posts: 6,568
    edited 2009-01-25 08:13
    clcorbin,

    Your program is working exactly the way you are telling it to. 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

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 1/25/2009 8:29:13 AM GMT
Sign In or Register to comment.