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
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.
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
Thank you this is quite helpful. I do plan on implementing locks to prevent / allow loops to access variables.
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.
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.