View Full Version : ASM Help, Causes Full Prop Lockup, or Doesn't do anything
Hi all thanks for taking the time to read this and or help.
Simply I am trying to create a pulse based off the falling edge of an incoming pulse that occurs a variable amount of time from the incoming pulse and lasts for 2 milliseconds.
So my test program is a simple cog start then start the terminal with two buttons that allows me to change the delay value. I judge if the prop is working by terminal output, and if the program is effective with a two channel scope.
I am feeding the prop a pulse signal 50% high @ 120khz from a function generator.
Here is what I have
Con
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
PinIn = 0
PinOut = 1
MS2 = (80_000_000/1_000) * 2 'A 2 Milisecond Delay
obj
Term : "serial_terminal"
Var
Long TimeDelay
Pub Run
TimeDelay := 1000 'Set a base value
cognew(PulseDelayStart, @TimeDelay) 'Start a new cog w/ the asm program
term.start 'Start the terminal
dira~ 'Set pin 2 to input
dira~ 'Set pin 3 to input
repeat
term.out(0) 'Clear terminal screen
term.dec(TimeDelay) 'Print current timeing delay value
if ina == 0 'if pin 2 is low, increase timeing value
TimeDelay++
elseif ina == 0 'if pin 3 is low decrease timeing value but limit minium to 16
TimeDelay := (TimeDelay- 1) #> 16 'To prevent cog lockup
waitcnt(clkfreq /20 + cnt) 'Wait 1/20 of a second
Dat
org
PulseDelayStart xor DIRA, InMask ' Set crank to input
or DIRA, OutMask 'Set coil to output
xor OUTA, OutMask 'Set the output pin to low
PulseDelay waitpeq InMask, InMask 'Wait for the Pin to be high
waitpne InMask, InMask 'Wait for the pin to be low TDC
rdlong _nextWait, par 'Get the newest timeing value
add _nextWait, cnt 'Add current counter value to it
waitcnt _nextWait, _MS2 'Wait the timeing amount and add 2 ms delay
or OUTA, OutMask 'Turn on the coil out pin
waitcnt _nextWait, #0 'Wait 2 ms , 0 Delta for next wait _nextWait
xor OUTA, OutMask 'Turn off coil pin.
jmp PulseDelay 'Jump back up to start
_nextWait res 1 'Reserve 1 long for the wait command
_ms2 long ms2 'Constant 2 milisecond pulse, num of clk cycles
InMask long |< PinIn ' A mask for the input pin
OutMask long |< PinOut 'Output pin mask
If I call my cognew with PulseDelayStart I get nothing, the terminal does not run at all, it appears the whole prop is locked up.
If I call the cognew with PulseStart the terminal runs and the value changes up and down, but the program does not work, which makes sense as the Outpin pin is not an output.
So any ideas suggestions?
Thank you TJ
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I owe everyone here a bunch, So thanks again for answering my dumb questions.
Projects. RG500 ECU system. PropCopter. Prop CanSat. Prop Paste Gun.
Suzuki RG500 in a RGV 250 frame.
Bimota V-Due (Running on the fuel injection system)
Aprilia RS250
Phil Pilgrim (PhiPi)
04-02-2009, 03:21 AM
For one, you're missing the "#" in jmp #PulseDelay. I haven't looked beyond that, though.
-Phil
MagIO2
04-02-2009, 03:26 AM
1. Why do you use xor in the PulseDelayStart? With xor DIRA, InMask you toggle the InMask-bit of DIRA which will then be 1 as the DIRA is initialized as $0000_0000. So it's an output.
For setting bits you use the or, for clearing bits you should use the andn.
2. You should have the res behind the longs. I'm not sure if res will be resolved correctly by the spin compiler. The intention of res is to reserve a long which can be used by the symbol, but without wasting longs in HUB-RAM. So, that symbol is only available in the COG. I'd guess that this will overwrite your _ms2.
3. In the spin-part you should use ina and ina
4. Your timing will be more accurate if you store the cnt-value before you rdlong, as rdlong can take 7 to 22 cycles.
5. dira[2]~
··· dira[3]~
Just for clarification. It won't change anything in the functionalíty, as it dira is initialized as input.
·
6. waitpeq and waitpne should propably have the ina as source, otherwise the first one will be always true, the second one will be never true. That looks like an endless loop ;o)
Post Edited (MagIO2) : 4/1/2009 8:38:44 PM GMT
Phil Pilgrim (PhiPi)
04-02-2009, 04:19 AM
MagIO2 said...
waitpeq and waitpne should propably have the ina as source, otherwise the first one will be always true, the second one will be never true. That looks like an endless loop
Not so. In these intructions, the destination is ANDed with ina first, then compared with the source. So TJHJ's code for these two instructions is fine.
-Phil
Thanks all,
Phil
Thanks, I do pasm get good wait 2 months and forget everything.
MagIO2
For 1 and 5. It makes it more universal when I go to use it later, ensuring that the pin states are correct, just preferance. Is there a reason against this other than lost start up cycles?
Note on 1. Im out of pratice, thanks.
For 3. The fourms remove the·'[ 3·] or·'[ 4 ]. on me sometimes Havent figured out why yet.
For 6. I am winning the dumbass award. Thanks
For 2. Im not sure I get this one. If I do
_ms2 long ms2 res 1 'Obvious compiler error
but if I do
_ms2 res 1 ' I still have to place the ms2 number in a long, then read it from the hub, so isnt the net effect kind of the same?
I am not really understanding what you are telling me
OK current version, no sucess still.
Con
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
PinIn = 0
PinOut = 1
MS2 = (80_000_000/1_000) * 2 'A 2 Milisecond Delay
obj
Term : "serial_terminal"
Var
Long TimeDelay
Pub Run
TimeDelay := 1000 'Set a base value
cognew(PulseDelayStart, @TimeDelay) 'Start a new cog w/ the asm program
term.start 'Start the terminal
dira[2]~ 'Set pin 2 to input
dira[3]~ 'Set pin 3 to input
repeat
term.out(0) 'Clear terminal screen
term.dec(TimeDelay) 'Print current timeing delay value
if ina[2] == 0 'if pin 2 is low, increase timeing value
TimeDelay++
elseif ina[3] == 0 'if pin 3 is low decrease timeing value but limit minium to 16
TimeDelay := (TimeDelay- 1) #> 16 'To prevent cog lockup
waitcnt(clkfreq /20 + cnt) 'Wait 1/20 of a second
Dat
org
PulseDelayStart andn DIRA, InMask ' Set crank to input
or DIRA, OutMask 'Set coil to output
andn OUTA, OutMask 'Set the output pin to low
PulseDelay waitpeq INA, InMask 'Wait for the Pin to be high
waitpne INA, InMask 'Wait for the pin to be low TDC
mov _nextWait, CNT 'Get the current count before rdlong
rdlong _delay, par 'Get the newest timeing value
add _nextWait, _delay 'Add current counter value to it
waitcnt _nextWait, _MS2 'Wait the timeing amount and add 2 ms delay
or OUTA, OutMask 'Turn on the coil out pin
waitcnt _nextWait, #0 'Wait 2 ms , 0 Delta for next wait _nextWait
andn OUTA, OutMask 'Turn off coil pin.
jmp #PulseDelay 'Jump back up to start
_nextWait res 1 'Reserve 1 long for the wait command
_delay res 1 'The delay from the hub
_ms2 long ms2 'Constant 2 milisecond pulse, num of clk cycles
InMask long |< PinIn ' A mask for the input pin
OutMask long |< PinOut 'Output pin mask
Thoughts or ideas?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I owe everyone here a bunch, So thanks again for answering my dumb questions.
Projects. RG500 ECU system. PropCopter. Prop CanSat. Prop Paste Gun.
Suzuki RG500 in a RGV 250 frame.
Bimota V-Due (Running on the fuel injection system)
Aprilia RS250
I am reading a solid 2.348 on pin one running the above program. Never changing after the start. Chip Death? Provide any insights?
I tried this a test program. Is my asm that far out of pratice? The following should simpily turn on a pin. That is connected to an led
Con
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
LedPinNum = 4
Var
Long StartPoint
Pub Main
StartPoint := LedPinNum 'Set the pin number to be correct
dira[LedPinNum]~~ 'Test chip by turing on LED It comes on
outa[LedPinNum]~~
waitcnt(clkfreq+cnt) 'wait 1 second
outa[LedPinNum]~ 'Turn off led, start up asm cog
cognew(LightOn, @StartPoint)
repeat 'Forever repeat to keep chip running
waitcnt(clkfreq+cnt)
Dat
org
LightOn rdlong _PinNum, par 'Get the pin num from hub
mov _PinMask, #1 'Set mask to 1 to shift
shl _PinMask, _PinNum 'Move Left 1 to pin num
or DIRA,_PinMask 'Make pin an output
or OUTA,_PinMask 'turn on pin
jmpforever jmp #JmpForever 'Just keep reapeting so it never stops
_PinNum res 1
_PinMask res 1
Yet it seems to do nothing. Also note In the main program I tried the waitpeq and waitpne both ways, with waitpne ina, Inmask and waitpne Inmask, inmask. No change
Thanks again all
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I owe everyone here a bunch, So thanks again for answering my dumb questions.
Projects. RG500 ECU system. PropCopter. Prop CanSat. Prop Paste Gun.
Suzuki RG500 in a RGV 250 frame.
Bimota V-Due (Running on the fuel injection system)
Aprilia RS250
Post Edited (TJHJ) : 4/1/2009 9:50:56 PM GMT
Phil Pilgrim (PhiPi)
04-02-2009, 04:47 AM
TJHZ,
You didn't read my rebuttal to MagIO2. Change your waits back to what they were.
-Phil
Post tag, Phil your it. Sorry I was posting when you replied
waitpeq InMask, InMask 'Wait for the Pin to be high
waitpne InMask, InMask 'Wait for the pin to be low TDC
Is still causing me equivilent prop lock up.
Thanks for the help phil.
TJ
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I owe everyone here a bunch, So thanks again for answering my dumb questions.
Projects. RG500 ECU system. PropCopter. Prop CanSat. Prop Paste Gun.
Suzuki RG500 in a RGV 250 frame.
Bimota V-Due (Running on the fuel injection system)
Aprilia RS250
Phil Pilgrim (PhiPi)
04-02-2009, 05:03 AM
What MagIO2 meant about the reses is that they always need to come at the very end of your assembly code, after the longs, like this:
_ms2 long ms2 'Constant 2 milisecond pulse, num of clk cycles
InMask long |< PinIn ' A mask for the input pin
OutMask long |< PinOut 'Output pin mask
_nextWait res 1 'Reserve 1 long for the wait command
_delay res 1 'The delay from the hub
Also, if you run your program through my formatter (http://www.phipi.com/format), your bracketed numbers will display okay. Try using it and post a complete current version of your code.
-Phil
Current formatted code, thanks for clearing up the res thing phil, I was way over thinking that
Con
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
PinIn = 0
PinOut = 1
MS2 = (80_000_000/1_000) * 2 'A 2 Milisecond Delay
obj
Term : "serial_terminal"
Var
Long TimeDelay
Pub Run
TimeDelay := 1000 'Set a base value
cognew(PulseDelayStart, @TimeDelay) 'Start a new cog w/ the asm program
term.start 'Start the terminal
dira[­2]~ 'Set pin 2 to input
dira[­3]~ 'Set pin 3 to input
repeat
term.out(0) 'Clear terminal screen
term.dec(TimeDelay) 'Print current timeing delay value
if ina[­2] == 0 'if pin 2 is low, increase timeing value
TimeDelay++
elseif ina[­3] == 0 'if pin 3 is low decrease timeing value but limit minium to 16
TimeDelay := (TimeDelay- 1) #> 16 'To prevent cog lockup
waitcnt(clkfreq /20 + cnt) 'Wait 1/20 of a second
Dat
org
PulseDelayStart andn DIRA, InMask ' Set crank to input
or DIRA, OutMask 'Set coil to output
andn OUTA, OutMask 'Set the output pin to low
PulseDelay
waitpeq InMask, InMask 'Wait for the Pin to be high
waitpne InMask, InMask 'Wait for the pin to be low TDC
mov _nextWait, CNT 'Get the current count before rdlong
rdlong _delay, par 'Get the newest timeing value
add _nextWait, _delay 'Add current counter value to it
waitcnt _nextWait, _ms2 'Wait the timeing amount and add 2 ms delay
or OUTA, OutMask 'Turn on the coil out pin
waitcnt _nextWait, #0 'Wait 2 ms , 0 Delta for next wait _nextWait
andn OUTA, OutMask 'Turn off coil pin.
jmp #PulseDelay 'Jump back up to start
_ms2 long ms2 'Constant 2 milisecond pulse, num of clk cycles
InMask long |< PinIn ' A mask for the input pin
OutMask long |< PinOut 'Output pin mask
_nextWait res 1 'Reserve 1 long for the wait command
_delay res 1 'The delay from the hub
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I owe everyone here a bunch, So thanks again for answering my dumb questions.
Projects. RG500 ECU system. PropCopter. Prop CanSat. Prop Paste Gun.
Suzuki RG500 in a RGV 250 frame.
Bimota V-Due (Running on the fuel injection system)
Aprilia RS250
Post Edited (TJHJ) : 4/2/2009 12:04:48 AM GMT
Phil Pilgrim (PhiPi)
04-02-2009, 07:57 AM
Hmmm, I surprised the compiler didn't catch this one. (Actually, this would be legit if the long at PulseDelayStart contained the hub address of the new assembly cog.) The right way to start a new assembler cog is:
cognew(@PulseDelayStart, @TimeDelay) 'Start a new cog w/ the asm program
-Phil
Post Edited (Phil Pilgrim (PhiPi)) : 4/2/2009 1:15:14 AM GMT
THANK YOU SO MUCH.
Damn Its always the simple one, Ive spent so much time looking at the asm code. It works perfectly. Thank you so much for all of the help Phil and MagIO2
TJ
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
I owe everyone here a bunch, So thanks again for answering my dumb questions.
Projects. RG500 ECU system. PropCopter. Prop CanSat. Prop Paste Gun.
Suzuki RG500 in a RGV 250 frame.
Bimota V-Due (Running on the fuel injection system)
Aprilia RS250