need help with asm effect flags and shared variables
Hi
i have two asm blocks that share a variable and a spin routine that can set that variable to some value for control.
when the variable is 0 both asm loops are supposed to do nothing.
when it is set to 2 the "watchForHome" loop waits until there is some value in the PHSA register and then sets the variable to 1.
when the variable is 1 the "asmPID" loop should set "encoderPosition" equal to 0 and then set the shared variable back to 0.
what i am seeing though is the variable "homeFlagReset" starts equal to 0, when i type the command 'h' i see it change to 2.
when i rotate the shaft to the home flag i see it change to 0 then 1 and back again regardless if im still blocking the home flag or not and its just stuck in an endless loop. (eg output: 0,1,1,1,0,1,1,1,0,1,1,1,0......).
if i dont launch the "watchForHome" cog and just set "homeFlagReset" equal to 1 instead of 2 the "encoderPosition" variable is set to 0 and the "homeFlagReset" variable is reset to 0 successfully and all returns to normal.
im pretty new to assembly, i was hoping someone might be able to help me figure out what im doing wrong??
thanks!!
i have two asm blocks that share a variable and a spin routine that can set that variable to some value for control.
when the variable is 0 both asm loops are supposed to do nothing.
when it is set to 2 the "watchForHome" loop waits until there is some value in the PHSA register and then sets the variable to 1.
when the variable is 1 the "asmPID" loop should set "encoderPosition" equal to 0 and then set the shared variable back to 0.
what i am seeing though is the variable "homeFlagReset" starts equal to 0, when i type the command 'h' i see it change to 2.
when i rotate the shaft to the home flag i see it change to 0 then 1 and back again regardless if im still blocking the home flag or not and its just stuck in an endless loop. (eg output: 0,1,1,1,0,1,1,1,0,1,1,1,0......).
if i dont launch the "watchForHome" cog and just set "homeFlagReset" equal to 1 instead of 2 the "encoderPosition" variable is set to 0 and the "homeFlagReset" variable is reset to 0 successfully and all returns to normal.
im pretty new to assembly, i was hoping someone might be able to help me figure out what im doing wrong??
thanks!!
VAR
long speedTarget, homeFlagReset 'do not rearange
PUB main
cognew(@watchForHome, @homeFlagReset)
cogNumber := cognew(@initialization[0], @speedTarget[0])
...
repeat
if ser.RxCheck
inByte := ser.rx
if inByte == 13 'carriage return
case commandBuffer[0]
"h" :
homeFlagReset := 2
posTarget := -1000
other :
ser.str(string("?") )
ser.tx(13)
...
DAT
'Watch counter for home/limit signal
org 0
watchForHome
mov ctra, ctraval
mov frqa, #1
:loop mov addr, par 'homeFlagReset
rdlong tmp, addr
mov resetPhs, tmp
cmp resetPhs, #2 wz 'command 2 waits for reset
if_z cmp numOne, phsa wc 'if phsa is greater than 1
if_c mov phsa, #0 'reset phsa
if_c mov setHome, #1 'command 1 sets the reset
if_c wrlong setHome, addr 'write the value to the shared variable
jmp #:loop 'loop for next cycle
ctraval LONG %01100 << 26 + 19
resetPhs LONG 0
myPhs LONG 0
numBuff LONG 0
numOne long 1
tmp res
addr res
dat
initialization
blah blah...
...
...
org 0
asmPID
mov addrPID, par 'get the shared variable's address
add addrPID, #4 'we want the second long (eg. "homeFlagReset" )
rdlong tmpPID, addrPID 'get its value
cmp tmpPID, #1 wz 'if it equals 1 then reset position
if_z mov encoderPosition, #0 'resetting position
if_z wrlong encoderPosition, addrPID 'writing value
jmp #asmPID

Comments
If the initialization consists of long/word/byte data required by the PASM code above it, it must not come after the res section. Rather, the res has to come last, just before the next org.
-Phil
i went ahead and changed those to longs.
what really made a difference was changing the way the conditionals evaluated the flags and clearing phsa whenever the homing command isnt equal to 2. now its working but i still have much to learn
Why is asmPid recalculating the pointer to homeFlagReset every time through the loop? You could at least store the calculated pointer somewhere, it'll save you two instructions (and, probably more importantly, two longs of cogram!). I try to avoid par - it's nothing but a headacheful of pointers and a waste of unnecessary code that only gets run once. Instead try:
VAR long x PUB main xptr := @x cognew(@entry, 0) repeat x:= 1 repeat while x waitcnt(clkfreq + cnt) DAT org 0 entry rdlong t1, xptr wz tjz t1, #entry 'do stuff wrlong zero, xptr 'tell the spin cog we're done jmp #entry xptr long 0-0 zero long 0 t1 res 0Notice that xptr gets written before the cog gets loaded, so the correct pointer to x gets loaded into the cog along with the rest of the code. You would have homeResetFlagPtr instead. And yes, it is more efficient to pre-load every single hub pointer into what will be cogram after the cognew, no matter how many variables there are, because it will always take more than 1 long to calculate the address but it only takes 1 long to store it. Obviously, you should still calculate the pointer for array offsets and such.
Is there any reason to use par over this method? I've never seen any, even in cases when I've started multiple cogs from the same pasm (just put a little delay after the cognew or don't start a new cog for a while or wait on a flag that gets cleared by the newly started cog before starting the next cog or something).
electrodude