Sending Multiple Parms to an assembler language cog
Jeffrey Kane
Posts: 48
Hello,
This has probably been answered a million times, but I can't find multiple parms, besides arrays
How do I send multiple parms to an assembler program running on a cog, I can send one fine but I have more that I want to send
There is my code, so currently I can pass tHigh, but I also would like to send tCycle and Pin.
what i would like is cognew(@Frequency @tHigh,@tCycle,@Pin), but whatever works is fine by me.
as a side note, Is there a way to avoid the mov 's in the loop, they take up 8 cycles I would like to avoid.
CON
'Set up the clock mode
' _clkmode = xtal1 + pll16x
' _xinfreq = 5_000_000 '5 MHz clock * 16x PLL = 80 MHz system clock speed
_clkmode = xtal1 + pll16x 'Set up the system clock mode with 16x PLL
_xinfreq = 5_000_000 ' '5 MHz clock * 16x PLL = 80 MHz system clock speed or '6.25 MHz clock * 16x PLL = 100 MHz system clock
VAR
Long tHigh,tCycle,Pin
PUB Main {lauch cog to create Frequency cycles}
tHigh := 10
tCycle :=10000
Pin := 0
start(@tHigh)
PUB start(ptr)
cognew(@Frequency, @tHigh)
DAT
ORG 0 'Begin at Cog Ram addr 0
Frequency mov temp, par
rdlong _tHigh, temp
mov dira, dira_mode
:loop
mov tH,_tHigh
mov tC,_tCycle
xor outa, _Pin 'toggle pin 37
:waitlow djnz tC,#:waitlow 'wait 500us
xor outa, _Pin 'toggle pin 37
:waithigh djnz tH,#:waithigh 'wait 1 us
jmp #:loop
_Pin long |< 0
_tHigh long 5
_tCycle long 10000
temp long 0
tC res 1
tH res 1
dira_mode long %00000000_00000000_00000000_11111111
This has probably been answered a million times, but I can't find multiple parms, besides arrays
How do I send multiple parms to an assembler program running on a cog, I can send one fine but I have more that I want to send
There is my code, so currently I can pass tHigh, but I also would like to send tCycle and Pin.
what i would like is cognew(@Frequency @tHigh,@tCycle,@Pin), but whatever works is fine by me.
as a side note, Is there a way to avoid the mov 's in the loop, they take up 8 cycles I would like to avoid.
CON
'Set up the clock mode
' _clkmode = xtal1 + pll16x
' _xinfreq = 5_000_000 '5 MHz clock * 16x PLL = 80 MHz system clock speed
_clkmode = xtal1 + pll16x 'Set up the system clock mode with 16x PLL
_xinfreq = 5_000_000 ' '5 MHz clock * 16x PLL = 80 MHz system clock speed or '6.25 MHz clock * 16x PLL = 100 MHz system clock
VAR
Long tHigh,tCycle,Pin
PUB Main {lauch cog to create Frequency cycles}
tHigh := 10
tCycle :=10000
Pin := 0
start(@tHigh)
PUB start(ptr)
cognew(@Frequency, @tHigh)
DAT
ORG 0 'Begin at Cog Ram addr 0
Frequency mov temp, par
rdlong _tHigh, temp
mov dira, dira_mode
:loop
mov tH,_tHigh
mov tC,_tCycle
xor outa, _Pin 'toggle pin 37
:waitlow djnz tC,#:waitlow 'wait 500us
xor outa, _Pin 'toggle pin 37
:waithigh djnz tH,#:waithigh 'wait 1 us
jmp #:loop
_Pin long |< 0
_tHigh long 5
_tCycle long 10000
temp long 0
tC res 1
tH res 1
dira_mode long %00000000_00000000_00000000_11111111
Comments
rdlong _tHigh, temp
add temp,#4
rdlong _tCycle, temp
Never loop to create a pause but use waitcnt, it also gives the bonus of being a interval timer instead of pause.
As with your code the total cycle will be longer than 501us due to overhead.
Just to add to Tony's post, the VAR section will rearrange variables if the aren't the same time.
It will group all the longs together followed by the words followed by the bytes.
As long as you're not switching between variable types, the order will remain as Tony says. You'll also want to keep in mind the address passed with par needs to be long aligned.
rdlong _tHigh,temp
add temp,#4
rdlong _tCycle, temp
my var statement is:
VAR
Long tHigh,tCycle,Pin
so add temp,#4 would reference Pin?
also, regarding waitcnt, they seem to be different between spin and pasm,
waitcnt in assembler takes two parms, target and delta, when it is executed, it counts up to target, then adds delta and moves on, which is slightly different than the spin version, which just delays and can take a single parm,
I used waitcnt first but found it difficult to control, mostly when using multiple waitcnt's in a loop
for example
:loop
1) waitcnt(time,delta_a) 'delay 1 milliseconds
2) toggle 0 pin
3) waitcnt(time,delta_b) 'delay 5 milliseconds
4) toggle 1 pin
5) waitcnt(time,delta_c) 'delay 10 milliseconds
6) toggle 2 pin
jmp #:loop
so in pasm, waitcnt would compare cnt to time until it matches,then add delta_a to time and continue to the next instruction. so time is now changed to time = current cnt + delta+a, so the next statement 3, waitcnt would use the new time to wait for cnt to get to it, (only if you did not pass it with instruction 2, then add delta_b and then the same thing would happen on statement 5. time (which is time + delta_a + delta_b) would be waited by cnt and then incremented by delta_c
then you would go to the loop jmp, which would use time + delta_a + delta _b + delta_c as the new time to wait for,but odds are that the loop will cause the counter to pass before the next interation of the loop, and this would make thing go backward (or seem to on a scope)
I probably got this wrong, because it seems that you have to keep time ahead of cnt by using deltas that must be at least the sum of the entire loop (in cycles of instructions)
so it seems that it is important to capture the initial time from cnt very close to the loop and then add a delta to it, the initial delta should be the first delta used in the loop, because if you don't and are using very small changes, you might miss the time because cnt passed it already.
regards
Jeff
>so add temp,#4 would reference Pin?
No, hub is in bytes so it would reference to following long after the long PAR points to.
Add #4 again to temp to get the third long.
with waitcnt, learn how to use it as a pause first, a simple trick cnt on the left side is just like any other ram cog (as it's a shadow register)
mov cnt,_delay
add cnt,cnt
waitcnt cnt,#0
waitcnt works as designed, yes understanding how it works is helpful.
regards
Jeff
Perhaps he has a split personality Sorry I could not resist.