need help with asm effect flags and shared variables
laser-vector
Posts: 118
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:
Notice 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