Shop OBEX P1 Docs P2 Docs Learn Events
Passing variables from Spin Cog to PASM Cog and back — Parallax Forums

Passing variables from Spin Cog to PASM Cog and back

I have been trying to build a PASM loop that can pull and update variables that are also affected by a Spin loop. After looking at forum posts and library code, I have tried to understand how rdlong and ptra work by making a small file that just passes numbers around. wrlong works as I expect but if I try to act on the value I get from rdlong, it's as though there is a bit shift, byte, long, word issue happening.
Below is the test code I am experimenting with. I expect the wrlong is writing datFlagA and datFlagC but because nothing was done to them they are fine. I can also change varFlagD as expected forcing it to 5. The problem is if I add subtract etc from the variables in PASAM.
I have tried different variations of this and similar code I found. It's time to reach out because I am not making any progress. Please help me understand reading vars from different cogs into PASM.

The terminal Output is:

varFlagA := 111
varFlagB := 222
varFlagC := 1479
varFlagD := 5
@varFlagA := 9256
@varFlagB := 9260
@varFlagC := 9264
@varFlagD := 9268

The Spin code is:

var
long varFlagA
long varFlagB
long varFlagC
long varFlagD

pub main()
setup()
varFlagA := 111
varFlagB := 222
varFlagC := 333
varFlagD := 444
coginit(COGEXEC_NEW, @start_dat, @varFlagA)

term.str(string(13, 10))
term.str(string("varFlagA := "))
term.dec(varFlagA)
term.str(string(13, 10))
term.str(string("varFlagB := "))
term.dec(varFlagB)
term.str(string(13, 10))
term.str(string("varFlagC := "))
term.dec(varFlagC)
term.str(string(13, 10))
term.str(string("varFlagD := "))
term.dec(varFlagD)
term.str(string(13, 10))
term.str(string("@varFlagA := "))
term.dec(@varFlagA)
term.str(string(13, 10))
term.str(string("@varFlagB := "))
term.dec(@varFlagB)
term.str(string(13, 10))
term.str(string("@varFlagC := "))
term.dec(@varFlagC)
term.str(string(13, 10))
term.str(string("@varFlagD := "))
term.dec(@varFlagD)

The dat section is:

dat
org 0

start_dat setq #4-1
rdlong datFlagA,ptra
mov t1,#0
mov t2,#1
mov t3,#2
adds t1,datFlagB
adds t2,datFlagC
adds t3, #3
wrlong datFlagA,ptra[0]
wrlong t1,ptra[1]
wrlong t2,ptra[2]
wrlong t3,ptra[3]
jmp #start_dat

datFlagA res 1
datFlagB res 1
datFlagC res 1
datFlagD res 1
t1 res 1
t2 res 1
t3 res 1

Thanks

-Chud

Comments

  • JonnyMacJonnyMac Posts: 9,061

    Is is possible that you have a race condition? When dealing with multiple longs this can be tricky. I did a really simple program that uses a flag from the hub that tells the cog it's okay to read and operate on hub variables. Dirt simple, but maybe it will help. And, if you're using Windows, P2 debug in Spin and PASM really helps. This is what my program debug window looks like.

    This is the cog code that waits on a flag from the hub. After its work, the cog clears the flag.

    dat
    
                            org       0
    
    entry                   rdlong    pr0, ptra[0]          wz      ' read flag
            if_z            jmp       #entry                        ' wait until !0
    
                            debug("Flag detected")
    
                            rdlong    pr1, ptra[1]                  ' read value1 from hub
    
                            debug("Cog value1 = ", udec_(pr1))
    
                            shl       pr1, #1                       ' double it
                            wrlong    pr1, ptra[2]                  ' write back to value2
                            wrlong    #0, ptra[0]                   ' clear flag
                            jmp       #entry
    
  • AribaAriba Posts: 2,687

    Not sure what you have expected, but these is all correct,

    FlagA is not modified and shows the inital value
    To FlagB you add 0 (zero), so it shows also the initial value
    To FlagC 1 (one) is added on every PASM loop, the value it shows depends on the time between the cogstart and the read for displaying it.
    FlagD shows the value of 2+3 = 5

    If you don't repeat the PASM code, but make a
    jmp #$
    instead of jmp #start_dat
    FlagC will show 334, which is 333+1

    Andy

  • @JonnyMac said:
    Is is possible that you have a race condition? When dealing with multiple longs this can be tricky. I did a really simple program that uses a flag from the hub that tells the cog it's okay to read and operate on hub variables. Dirt simple, but maybe it will help. And, if you're using Windows, P2 debug in Spin and PASM really helps. This is what my program debug window looks like.

    Thank you this is quite helpful. I do plan on implementing locks to prevent / allow loops to access variables.

  • @Ariba said:
    Not sure what you have expected, but these is all correct,

    FlagA is not modified and shows the inital value
    To FlagB you add 0 (zero), so it shows also the initial value
    To FlagC 1 (one) is added on every PASM loop, the value it shows depends on the time between the cogstart and the read for displaying it.
    FlagD shows the value of 2+3 = 5

    If you don't repeat the PASM code, but make a
    jmp #$
    instead of jmp #start_dat
    FlagC will show 334, which is 333+1

    Andy

    Thanks for the help.
    I did not realize I built a useless counter.
    Using mov to swap the vars or turning off the loop shows the rdlong was working as intended.
    I laughed at myself for a bit four lines into your post.

  • Thank you this is quite helpful. I do plan on implementing locks to prevent / allow loops to access variables.

    One of the very easiest ways is to have the data source set a HUB long to a ready to read value, and I always just used 1, unless I was cramming state in there (unwise), or needed a specific data consumer to fetch the source data.

    When the data consumer is done, it resets the HUB long to 0.

    For single source, either single consumer or single member of a consumer group, this works great!

    The built in lock feature never quite seemed as simple and effective. Could be me.

Sign In or Register to comment.