My first PASM
I am working on my first PASM program (first "machine language" program ever).
I am converting a rather trivial program over to PASM. It is a LED control program I use to not slow down the controller cog. I have the SPIN version, and my attempt at the the PASM. The PASM seems to work somewhat, but it starts a couple seconds later than it seems it should, the type 4 blink doesn't work at all, and it only seems to loop once. Please take a look and help me out.
SPIN:
PASM:
Edit: fixed mCode formatting issue
Post Edited (Bobb Fwed) : 2/2/2009 9:45:43 PM GMT
I am converting a rather trivial program over to PASM. It is a LED control program I use to not slow down the controller cog. I have the SPIN version, and my attempt at the the PASM. The PASM seems to work somewhat, but it starts a couple seconds later than it seems it should, the type 4 blink doesn't work at all, and it only seems to loop once. Please take a look and help me out.
SPIN:
VAR
byte cog, cogon
long ledstack[noparse][[/noparse]20]
long ledblink
PUB Main
LED(0, 1)
PUB LED (pin1, pin2)
stop
cogon := (cog := cognew(dance(pin1, pin2, @ledblink), @ledstack)) > 0
REPEAT
waitcnt(clkfreq + cnt)
blinktype(1)
waitcnt(clkfreq + cnt)
blinktype(2)
waitcnt(clkfreq + cnt)
blinktype(4)
waitcnt(clkfreq + cnt)
blinktype(3)
PUB stop
if cogon~
cogstop(cog)
PUB blinktype (type)
ledblink.byte[noparse][[/noparse] 3 ] := type ' shove to high byte
PUB dance (pin1, pin2, typeAddr) | lled, i
OUTA[noparse][[/noparse]pin1]~
OUTA[noparse][[/noparse]pin2]~
DIRA[noparse][[/noparse]pin1]~~
DIRA[noparse][[/noparse]pin2]~~
REPEAT ' repeat forever
REPEAT UNTIL (lled := byte[noparse][[/noparse]typeAddr]) ' repeat nothing until type is set
long[noparse][[/noparse]typeAddr] >>= 8
long[noparse][[/noparse]typeAddr] >>= 8
CASE lled
1: ' green
OUTA[noparse][[/noparse]pin1]~
OUTA[noparse][[/noparse]pin2]~~
2: ' yellow
OUTA[noparse][[/noparse]pin1]~~
OUTA[noparse][[/noparse]pin2]~
3: ' off
OUTA[noparse][[/noparse]pin1]~
OUTA[noparse][[/noparse]pin2]~
4: ' blink: to show "on" -- switches color
REPEAT 2
pause(250)
!OUTA[noparse][[/noparse]pin1]
!OUTA[noparse][[/noparse]pin2]
PUB pause (pause_ms)
waitcnt(((clkfreq / 1000 * pause_ms) #> 381) + cnt)
PASM:
CON
LED1_p = 0
LED2_p = 1
OBJ
VAR
byte cog, cogon
word high_wait, low_wait
long ledblink
PUB LED | i
stop
cogon := (cog := cognew(@dance, @ledblink)) > 0
REPEAT
waitcnt(clkfreq + cnt)
blinktype(1)
waitcnt(clkfreq + cnt)
blinktype(2)
waitcnt(clkfreq + cnt)
blinktype(4)
waitcnt(clkfreq + cnt)
blinktype(3)
PUB stop
if cogon~
cogstop(cog)
PUB blinktype (type)
ledblink.byte[noparse][[/noparse] 3 ] := type ' shove to high byte
DAT
ORG 0
dance
MOV DIRA, LED_p
MOV OUTA, #0
danceloop ' loop forever
:loop
RDBYTE ledtype, PAR WZ
RDLONG shft, PAR
SHR shft, #8
WRLONG shft, PAR
IF_NZ JMP #caseswitch
JMP #:loop
caseswitch ' same as switch/case
type1 ' LED green
CMP ledtype, #1 WZ
IF_NZ JMP #type2
MOV OUTA, GREEN
JMP #danceloop
type2 ' LED yellow
CMP ledtype, #2 WZ
IF_NZ JMP #type3
MOV OUTA, YELLOW
JMP #danceloop
type3 ' LED off
CMP ledtype, #3 WZ
IF_NZ JMP #type4
MOV OUTA, #0
JMP #danceloop
type4 ' blink color back and forth
CMP ledtype, #4 WZ
IF_NZ JMP #type5
MOV idx, #2
:loop
MOV OUTA, NOT OUTA
MOV waitlen, cnt
ADD waitlen, pausetime
WAITCNT waitlen, pausetime
DJNZ idx, #:loop
JMP #danceloop
type5
JMP #danceloop ' back to top
LED_p LONG |< LED1_p | |< LED2_p
YELLOW LONG |< LED1_p
GREEN LONG |< LED2_p
pausetime LONG 1_000_000
waitlen LONG 0
shft LONG 0
idx LONG 0
ledtype BYTE 0
FIT 496
Edit: fixed mCode formatting issue
Post Edited (Bobb Fwed) : 2/2/2009 9:45:43 PM GMT

Comments
REPEAT UNTIL (lled := byte[noparse][[/noparse]typeAddr]) ' repeat nothing until type is set long[noparse][[/noparse]typeAddr] >>= 8 long[noparse][[/noparse]typeAddr] >>= 8You're doing something similar in the PASM code and to me it just looks like trouble. You're watching a memory location to see if it becomes non-zero, but at the same time you're continually writing a zero into it. There's a very small window of time for the other cog to set the blink type. The window is even smaller for the PASM version.
When the controller cog calls blinktype(), it sets byte 3 to the value.
While the LED cog is waiting, it shifts that value toward byte 0. Once it is reached, it executes that value.
I realize that I should be locking those addresses during the operation, but I haven't had a problem yet with the SPIN version. The blink type commands can be sent as close as 1000 cycles from each other, and some of the blinktypes (not all are listed in the program) are as long as 60 seconds. So if the 60 second command gets called, at least one more command is queued while that is happening. In the final version, I'd like 4 more queued, but I'll have to get this working before I get to that.
REPEAT UNTIL (lled := byte[noparse][[/noparse]typeAddr]) ' repeat nothing until type is set long[noparse][[/noparse]typeAddr] >>= 8 ' shift bytes right toward byte 0, so at some point the above code will not failOK. New task, can someone explain explain how the lock tasks work? I assume I locknew and get an ID, but how do I tell it what information is locked? Then I use lockset. When I am not accessing the info I use LockClr?
work? What is the best way to toggle a set of pins (like !OUTA[noparse]/noparse does in SPIN)