Time between edges
Ltech
Posts: 385
in Propeller 1
I try to get the time between variable edges of a square wave.
The minimum time are 240us, the maximum 1_020us.
I only need to detect value 250us or 1_000us, it is "Biphase marque"
I try in spin
Is this to simple ?
I do not get the expected timings, compare to my scope
The minimum time are 240us, the maximum 1_020us.
I only need to detect value 250us or 1_000us, it is "Biphase marque"
I try in spin
ctra := %01110<<26 + pin 'ctra for neg edge detection
frqa := 1
ctrb := %01000<<26 + pin 'ctrb for pulstime high
frqb := 1
...
repeat i from 0 to 80 'main loop detection
phsa := phsb := 0 'clr edge and pulstime
repeat until (phsa OR phsb) 'wait for neg edge OR pos edge
pulses[i] := (phsb+phsa) ' I expect to get the time between edges => A can be 0; or b can be 0. So sum would be edge time
Is this to simple ?
I do not get the expected timings, compare to my scope

Comments
So, in your code, PHSA is always 0, and PHSB is almost same some small value each time.
If you don't need accuracy and quickness, below might work:
ctra := %01110<<26 + pin frqa := 1 ctrb := %01000<<26 + pin frqb := 1 ... repeat i from 0 to 80 phsa := phsb := 0 repeat until phsa 'wait for next edge pulses[i] := phsb ctra ^= |<28 ' toggle counter mode between neg edge detection and pos edge detection ctrb ^= |<28 ' toggle counter mode between pulsetime high and pulsetime lowAlso you can use WAITPxx command, instead of REPEAT UNITIL command:
ctrb := %01000<<26 + pin frqb := 1 ... WAITPEQ( 0, |<pin, 0 ) ' to assume ina[pin] to be low repeat i from 0 to 80 prevstat := ina & |<pin ' prevstat is LONG variable phsb := 0 WAITPNE( prevstat, |<pin, 0 ) 'wait for next edge pulses[i] := phsb ctrb ^= |<28 ' toggle counter mode between pulsetime high and pulsetime lowAnd also you can use system counter CNT to measure time, instead of cog-counters:
WAITPEQ( 0, |<pin, 0 ) ' to assume ina[pin] to be low repeat i from 0 to 80 prevstat := ina & |<pin ' prevstat is LONG variable prevcnt := CNT ' prevcnt is LONG variable WAITPNE( prevstat, |<pin, 0 ) 'wait for next edge pulses[i] := CNT - prevcnt(Sorry I did not test these yet but I'll later.)
It's best to use a constant for your pin mask. Spin already has some overhead and you don't want to add any more by creating a mask in place.
If you just want the next complete half cycle, regardless of phase, this works (I tested both methods with an oscillator running using CTRA).
Warning: If the pin doesn't change, these methods will block your program. What you could do is launch it into its own temporary cog which would allow your foreground code to timeout the measurement.
I don't have time today to test this part.
I wil test it tomorrow
Daniel
I got in a dedicated cog, detecting all the edges and toggle pin:
Repeat !outa[Pin_14_det] 'edge pulse for mask waitcnt(50*us +cnt) !outa[Pin_14_det] waitpne(pinstate, EDGE_MASK2, 0) ' look for edge do not match pinstate :=ina[Pin_0_in]'And other cog, analyzing @ 6/8 time, of the next pulse:
Repeat i from 0 to 80 waitpeq(EDGE_MASK, EDGE_MASK, 0) phsa := 0 !outa[Pin_15_edge] 'Just for scope monitoring waitcnt(380*us + cnt) !outa[Pin_15_edge] pulses[i] := (phsa/2)The result if I have 2 pulses, we got a 1, if we have 1 pulse we got 0
Proof of concept is working fine.
Now I go try in pasm