Shop OBEX P1 Docs P2 Docs Learn Events
PASM options -- which is best way? — Parallax Forums

PASM options -- which is best way?

I have an application where the main cog is making a PASM cog go to sleep when it is not being used. I am using waitpeq in the PASM and having the main cog (running a C program) use a pin as a flag to turn the cog on and off. The first time the PASM runs I want the cog to run (not wait) and store the pin number / mask as a 32 bit value (into a variable "waitpin"). I've gotten it to work, but I keep on coming up with different options for the test for the first time through. I am limited in what I can do by the way the PASM code is set up.

The code I am using (at this time) is:
DAT		org

loop		add 	waitpin, #0	wz	‘’ waitpin is the 32 bit pin mask
	‘’ first time through “waitpin” is zero, subsequent times it is a pin mask non-zero
	if_nz	waitpeq waitpin, waitpin	‘’ sleep til other cog sets waitpin high

… 
do PASM stuff  (first time through jmp to #startup, initialize stuff, put pin value in waitpin)
…
do more PASM stuff

… jmp #loop

… 
waitpin 	long	0


Since "add" is unsigned, I shouldn't have any problem adding 0 and storing it back to waitpin
Reading the propeller manual, I see that I could also use "or" or "cmp" instead of "add" all with the wz flag.
"cmp" doesn't write back to waitpin, but the others do unless the nr flag is specified. In this case writing back to waitpin (either 0 or its original value) doesn't seem to be a problem.

Since I'm new to PASM, what would be the best option and why?

Thanks
Tom

Comments

  • Peter JakackiPeter Jakacki Posts: 10,193
    edited 2016-02-22 20:13
    So why don't you just:

    do PASM stuff

    waitpeq ' cog will shutdown until port = mask (or your variant as required)
    jmp #loop

  • Neither option will work because each cog involved has a private copy of waitpin. When you start up a cog, the 512 longs at the specified hub address get copied into the cog's memory, then executed. All PASM instructions refer to the copy in the cog's memory. To reference hub memory from a cog, you have to use the RDxxxx and WRxxxx instructions. The Spin interpreter (which runs in a cog) does this to access interpreted code and data in hub memory.

    I recommend that you look at the LOCKxxx instructions (and corresponding Spin statements) to signal among cogs. If a lock is set, the PASM cog can continue, otherwise it continues to check the lock. When it's finished its work, it can clear the lock. The Spin code requests a lock during initialization and clears it. When the Spin code wants the PASM cog to do its thing, it sets the lock and waits for the PASM cog to clear it when it's done.
  • Thanks for the info, but I probably wasn't clear in what I am doing.

    The reason I want to wait the cog is to reduce the power used for a battery powered application so having it check for a lock won't do that.

    When the main cog starts the PASM cog it passes a command variable through "par". The variable has 4 parameters packed into the 32 bit variable. One parameter is 3 bits containing the pin number that will be converted into the 32 bit pin mask and stored into waitpin. The first time through waitpin should be 0 since that is how it is declared in the assembly language program:
    "waitpin long 0".

    As I mentioned above the program as written does work. I tested it by adding some temporary code that turns off an LED just before the waitpeq instruction and turns it back on just after. The LED lights for a split second and turns off for 10 seconds which is what the main cog is calling for.

    I'm just trying to figure out the best way to do the test before the waitpeq.

    Thanks again
    Tom
  • Mike GreenMike Green Posts: 23,101
    edited 2016-02-22 21:34
    Why should "waitpin" be zero in the loop? The cog starts executing at location 0 where you'd normally put your initialization code. This should extract the I/O pin number from PAR and make a mask out of it in waitpin. You'd probably want to initialize "waitpin" to 1 anyway like this:
            org   0
    start   mov   temp,PAR   ' get parameters
    '       shr   temp,#xxx   ' use if pin# not least significant
    '       and   temp,#$1F   ' now assume pin# in bits 4-0
            shl   waitpin,temp   ' shift mask into place (only uses bits 4-0 for #shifts)
    
    loop    waitpeq waitpin,waitpin   ' wait for I/O pin to be high
    ' ....   do stuff
    ' ....   make sure the I/O pin is low before jumping back to loop
    ' ....   either set it low here (if appropriate) or wait for it to be low
    ' ....   if some other cog is setting it low
            jmp   #loop
    
    temp    long  0
    waitpin long  1
    
  • twm47099 wrote: »
    The code I am using (at this time) is:
    DAT		org
    
    loop		add 	waitpin, #0	wz	‘’ waitpin is the 32 bit pin mask
    	‘’ first time through “waitpin” is zero, subsequent times it is a pin mask non-zero
    	if_nz	waitpeq waitpin, waitpin	‘’ sleep til other cog sets waitpin high
    
    … 
    do PASM stuff  (first time through jmp to #startup, initialize stuff, put pin value in waitpin)
    …
    do more PASM stuff
    
    … jmp #loop
    
    … 
    waitpin 	long	0
    
    

    Since "add" is unsigned, I shouldn't have any problem adding 0 and storing it back to waitpin
    Reading the propeller manual, I see that I could also use "or" or "cmp" instead of "add" all with the wz flag.
    "cmp" doesn't write back to waitpin, but the others do unless the nr flag is specified. In this case writing back to waitpin (either 0 or its original value) doesn't seem to be a problem.

    Since I'm new to PASM, what would be the best option and why?

    cmp is probably the clearest to read, since you are in fact comparing the value to 0 and not trying to change it. But as you point out all of those options would work.
Sign In or Register to comment.