PDA

View Full Version : ASM Help, Causes Full Prop Lockup, or Doesn't do anything



TJHJ
04-02-2009, 03:42 AM
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, 04:21 AM
For one, you're missing the "#" in jmp #PulseDelay. I haven't looked beyond that, though.

-Phil

MagIO2
04-02-2009, 04: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, 05: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

TJHJ
04-02-2009, 05:29 AM
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

TJHJ
04-02-2009, 05:41 AM
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, 05:47 AM
TJHZ,

You didn't read my rebuttal to MagIO2. Change your waits back to what they were.

-Phil

TJHJ
04-02-2009, 05:50 AM
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, 06: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

TJHJ
04-02-2009, 07:58 AM
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[&#173;2&#093;~ 'Set pin 2 to input
dira[&#173;3&#093;~ 'Set pin 3 to input
repeat
term.out(0) 'Clear terminal screen
term.dec(TimeDelay) 'Print current timeing delay value
if ina[&#173;2&#093; == 0 'if pin 2 is low, increase timeing value
TimeDelay++
elseif ina[&#173;3&#093; == 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, 08: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

TJHJ
04-02-2009, 09:38 AM
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