Multi cog and timing rising edge.
TxRx
Posts: 4
Hi.
I'm quite new to propeller and the SPIN language. What I am trying is to time two incomming signals on two different cogs, the timing frame is small and acuaracy is important. To test the code i tied the two input pins together and pulled the pins high, the code then writes down CNT when the pins go high, the priblem is that the CNT written down is different by 20-100 clock cycles. Any sugestions why this happends?
Code below:
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
OBJ
pst : "Parallax Serial Terminal"
VAR
byte Counter
long stack1[50], stack2[50]
PUB Main
cognew(trigger1(3), @stack1)
cognew(trigger2(4), @stack2)
PUB trigger1(PIN)| trigger
repeat
repeat until ina[PIN]
trigger := cnt
common2[0] := trigger
waitcnt(clkfreq * 5 + cnt) 'wait 5 sec before restart
PUB trigger2(PIN)| trigger
repeat
repeat until ina[PIN]
trigger := cnt
common2[1] := trigger'GetCNT(trigger)
waitcnt(clkfreq * 5 + cnt) ' 'wait 5 sec before restart
When i print the two variables back via serial line in one case i got
trigger1: 413511535
trigger2: 413511617
I tought that since the COG is independent and the input is tied tigether the values should be the same, what am I missing?
Any gurus out there that may enlighten me?
I'm quite new to propeller and the SPIN language. What I am trying is to time two incomming signals on two different cogs, the timing frame is small and acuaracy is important. To test the code i tied the two input pins together and pulled the pins high, the code then writes down CNT when the pins go high, the priblem is that the CNT written down is different by 20-100 clock cycles. Any sugestions why this happends?
Code below:
CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
OBJ
pst : "Parallax Serial Terminal"
VAR
byte Counter
long stack1[50], stack2[50]
PUB Main
cognew(trigger1(3), @stack1)
cognew(trigger2(4), @stack2)
PUB trigger1(PIN)| trigger
repeat
repeat until ina[PIN]
trigger := cnt
common2[0] := trigger
waitcnt(clkfreq * 5 + cnt) 'wait 5 sec before restart
PUB trigger2(PIN)| trigger
repeat
repeat until ina[PIN]
trigger := cnt
common2[1] := trigger'GetCNT(trigger)
waitcnt(clkfreq * 5 + cnt) ' 'wait 5 sec before restart
When i print the two variables back via serial line in one case i got
trigger1: 413511535
trigger2: 413511617
I tought that since the COG is independent and the input is tied tigether the values should be the same, what am I missing?
Any gurus out there that may enlighten me?
Comments
Btw, to post code you can use the [ code ] tags to preserve formatting.
The difference you see in your code is because of each COG having been started at different times. So, one COG is processing the ina when your signal comes, the other one is processing the repeat instruction.
If synchronize both COGs with a waitcnt the difference should be smaller.
And using waitpne/waitpeq should also show a smaller difference.
But smaller difference still includes some inaccuracy, because of the longer runtime of a spin instruction. So, it`s really best to use a counter as this has an accuracy with a difference of a clock cycle. Second best is PASM.
So the timing needs to be done with 3 inputs and anyone may be triggered before eachother.
I tried your pasm code and it looks nice(to mee it looks like greek, but I'm working on that part :P )
One question, why are you using different brackets on the two different storages?
So, my guess is that storage[ 0 ] is for the spin compiler like long[ @storage + 0 ], which means that there is a runtime addition which only wastes some cycles. You could also skip the [ 0 ] completely, but it makes the code more readable if you show that storage is an array. That's where { 0 } comes into the game, it does not change anything but the readability.
is there some code cost to actually writing storage[ 0 ], over storage{0} ?
WAITPxx can have a mask, so you can test 3 pins and WAITPNE until any of those 3 changes, then you can flip the mask to 2 pins, and wait for the stop ?
If you capture the pin-triplet at the same time as the CNT, you can work out later, which pin-states drove the events
To use 3 cogs for the inputs is ok in this case, I'm probably only going to end up using 5-6 cogs for this project.
In the code i also see that you are moving cnt to cnt, is one cnt pointing to local cog RAM? In that case where is that declared in the code?
Day to day I'm usually coding in C#/Java and this asm coding really makes my brain twitch
nice! I have not looked into this yet.
My solution so far is as follows:
Only problem with this solution is that i wold like to have a variable(appx 200ms) delay before jumping back to Loop. But this delay does not work..