measuring external pulse width and time intervals - what is the best resolution?
I do not yet have a Propeller system, I'm trying to find out if it is useful for my purposes. I read the data sheet but I have not yet understood enough to be able to answer my question below.
I want to be able to make high-resolution pulse width and time interval measurements. That is, say I have two signals, each connected to an input pin. Let's say there is a rising edge on pin A and about 10 microseconds later, there is a rising edge on pin B. Using the propeller chip and one or more cogs (?) what is the best resolution with which I can measure the time interval between the edges on pin A and B? Do I get the resolution of the system clock at 80 MHz (=> 12.5 nsec) or is it something slower due to some hub-synchronization requirements? Does the cog timer have direct hardware edge-capture, or do I need to poll the pin state in software, meaning I have at least a few clock cycles of uncertainty?
I want to be able to make high-resolution pulse width and time interval measurements. That is, say I have two signals, each connected to an input pin. Let's say there is a rising edge on pin A and about 10 microseconds later, there is a rising edge on pin B. Using the propeller chip and one or more cogs (?) what is the best resolution with which I can measure the time interval between the edges on pin A and B? Do I get the resolution of the system clock at 80 MHz (=> 12.5 nsec) or is it something slower due to some hub-synchronization requirements? Does the cog timer have direct hardware edge-capture, or do I need to poll the pin state in software, meaning I have at least a few clock cycles of uncertainty?

Comments
You can get system clock resolution with the usual off by one cycle uncertainty wrt when the edge/transition is sampled. While edge-capture is available in h/w it only applies to edge counting modes which isn't useful for your scenario. You may want to look at LOGIC counter modes like A != B. While both your inputs are low nothing happens. Then A has a low/high transition which enables the counter (A !=
That said, while counters can do lots of things without s/w support there are certain things they can't do without help. It'd be a good idea to get the requirements sorted beforehand. And feel free to ask more (specific) questions when you get there.
Yeap - the cog can capture a change of state of any pin. no clock cycles missing here !
The only problem of the propeller is that it can cause addiction, than all the others 517 hobbies that you have will have to wait for implementations with the prop chip. !
It's an stunting piece of infinite solutions !
have fun !
Amaral
They work with system clock resolution.
Here are possible code snippets in Assembly: Andy
Sadly, the Prop 1 does not have external capture, but it does have the WAIT opcodes mentioned above, and they are 'auto-stretching' opcodes, that will add as many SysCLKS as needed - so yes, they do resolve to 12.5ns.
There IS a fish-hook in this, however, in that the WAIT opcodes are LEVEL based, and not TRUE edge based.
So in your example, Provided PinB is low for the whole time from PinA rise, to the needed Pin B rise, Two WaitUntilHI will work.
If Pin B can ever be Hi at the Pin A trigger, then Two WaitUntilHI will fail, as the PinB one will fire instantly.
You can add a third line to emulate edge
Wait Until Pin A Low << safety, ensures next line is waiting.
Wait Until Pin A Hi
Capture StartTime
Wait Until Pin B Low << usually immediate, but safely allows B to be high at A rise.
Wait Until Pin B Hi
Capture EndTime
This has a minimum resolvable time A-B, and the safe step also needs that B is low for some of the time.
A true hardware capture would not have these 'level handshake' issues, and could capture down to coincident timing (0ns)
If you can add a D-FF, and sample two pins, then you can get closer to true EDGE based.
This is one chip you have to play with to really get to know and love.
Pick up a QuickStart board at Radio Shack.
' sigin is the pin number of the input 1-pulse-per-second signal waitpeq(0, |< sigin, 0) ' wait for sigin pin to be low waitpeq(|< sigin, |< sigin, 0) ' wait for sigin pin to be high t1 := cnt repeat waitpeq(0, |< sigin, 0) ' wait for sigin pin to be low waitpeq(|< sigin, |< sigin, 0) ' wait for sigin pin to be high t2 := cnt ' capture system clock at rising edge delta := (t2-t1) - 100_000_000 ' difference from 1 sec in 10nsec units serial.Dec(delta) ' print timing value on serial output PrintNewLine t1 := t2And below is a sample of the output. Apparently my PPS signal is about 14.5 microseconds too long relative to the Prop clock, which is ok, but my concern is that I thought I would have 10 ns resolution. It looks like I've got a granularity of 16 clock cycles. Does this have something to do with waiting for main memory, and the hub access mechanism? Can I get edge to edge timing with true 10 ns granularity in any way? Do I need to use assembly? [EDIT: just found that Spin code is always executed out of hub ram, so that explains the 16 cycle granularity.]
{{ Object file: JPB-Timing1.spin Version: 0.1 Date: August 26 2012 Author: John Beale Company: bealecorner.com Licensing: public domain Purpose: measure difference in timing between sucessive input pulses which are nominally 1 second apart. No output when delay unchanged. 10 ns resolution Pin 27: input 1PPS signal Pin 28: Prop serial TX line Pin 29: Prop serial RX line }} CON _clkmode = xtal1 + pll16x 'Set up the clock mode _xinfreq = 6_250_000 '6.25 MHz clock * 16x PLL = 100 MHz system clock speed VAR LONG time1 ' hub ram location of delta-T timing result LONG oldtime LONG diftime LONG sec ' elapsed time in seconds OBJ serial : "FullDuplexSerial" PUB jpbMain dira[27] := %0 ' make PortA bit 27 input serial.Start(29, 28, %0000, 230_400) ' serial I/O launches into new cog serial.Str(STRING("JPB Timing 1 -- Aug. 26 2012")) serial.Tx($0D) ' newline: ASCII 13 = carriage return oldtime := 0 ' initialize history sec := 0 COGNEW(@pinWatch, @time1) ' launch assy timing routine REPEAT waitcnt(cnt + clkfreq) ' wait one second sec := sec + 1 if (time1 <> oldtime) ' has the time value changed? diftime := time1 - 100_000_000 serial.Dec(sec) serial.Str(STRING(",")) serial.Dec(diftime) ' print timing value on serial output serial.Tx($0D) ' newline: ASCII 13 = carriage return oldtime := time1 ' ===================================================================== DAT ORG 0 pinWatch waitpne pinA,pinA ' wait for input pin to be low waitpeq pinA,pinA ' rising edge #1 mov tstart,cnt ' capture system clock as 'start' time :loop waitpne pinA,pinA ' wait for input pin to be low waitpeq pinA,pinA ' rising edge #2 mov tend,cnt ' capture system timer as 'end' time mov temp,tend ' copy into temporary variable sub temp,tstart ' subtract start time from end time WRLONG temp, PAR ' write result to hub ram loc. set in PARAMETER mov tstart,tend ' copy 'end' clock into start clock value JMP #:loop ' ...and do it all again pinA LONG $01<<27 ' portA pin to monitor for input signal tstart LONG 0 ' clock time at start of pulse: Tstart tend LONG 0 ' clock time at end of pulse: Tend temp LONG 0 ' temporary var for difference (Tend - Tstart) ' =========================================================sample output:
[FONT=courier new][SIZE=1]CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' 80 MHz clkfreq MYPIN = 0 OBJ debug : "fullduplexserial" PUB countHighLow | hightime debug.start(31,30,0,9600) waitcnt(clkfreq/10+cnt) ctra := %01000 << 26 + MYPIN ' POSDET ctrb := %01100 << 26 + MYPIN ' NEGDET frqa := 1 frqb := 1 waitpeq(|< MYPIN, |< MYPIN, 0) ' sync to input waitpeq(0, |< MYPIN, 0) phsa := 0 ' ready for POSDET phase waitpne(|< MYPIN, |< MYPIN, 0) repeat phsb := 0 ' pin is high, POSDET phsa advancing, phsb not waitpeq(0 , |< MYPIN, 0) ' pin goes low, phsa stops, phsb starts hightime := phsa ' capture the time pin was high phsa := 0 ' pin is low, NEGDET phsb advancing, phsa not waitpeq(|< MYPIN, |< MYPIN, 0) ' pin goes high, phsb stops, phsa starts debug.dec((phsb + hightime)*10/8) ' total is high plus low times debug.tx(13) ' note conversion to [/SIZE][/FONT][FONT=courier new][SIZE=1]units of ns*10[/SIZE][/FONT]eBay has real, non-GPS dependant atomic clocks in a board-mount package for under $100.
http://www.ebay.com/sch/i.html?_nkw=atomic+standard&_sacat=0&_odkw=atomic+electronic&LH_BIN=. _lncat=0&_sac=1&_osacat=0