P2 Input Capture questions?
Capt. Quirk
Posts: 872
in Propeller 2
Chip's terminology is not the same as other suppliers, so that can make smart pins harder to follow.
I have not purchased a P2 yet, but after trying to read the data sheet,
I am not certain the P2 provides an easy way to perform Input Capture.
A simple tachometer that is capable of recording the time period of one
revolution and converts that to rpm is at the core of all my potential
P2 projects.
A simple example is my ignition test stand spinning at the low speed of
2307 rpm. The period is 26ms, and because it is set up with a hall sensor
25ms is high, and 1ms is low.
Normally I count from falling edge to falling edge (26ms @2307rpm).
So many of the P2 pin states talk about accumulating clock cycles within
a hi or low state, or events within a period.
Pin State %10_000 looks promising, but there is no mention of falling
edges.
Is there an easy way to perform input capture?
Can input capture be done with an interrupt?
On some micro-controllers DMA seems to be helpful. Is a Streamer
helpful for input capture on the P2?
Can the clock speed be reduced to 1mhz on the input capture pin?
Thanks
Bill M.

Comments
I suppose you could have two adjacent pins on the same signal, one monitoring high duration, and one monitoring low duration. Combine the counts to get the input capture. Kinda clunky, though.
VAR long time ' continually updated with period as measured in P2 system clocks PUB timecog() | time1, time2, time3 time1 := getct() repeat asm modcz %1111, %1111 wcz ' setpat ##$1000000, ##$0000000 ' bit mask set to your pin (this example is for pin56) ' waitpat setpat ##$1000000, ##$1000000 ' for pin 56 waitpat getct time3 mov time2, time3 sub time2, time1 mov time1, time3 endasm time := time2High and low periods are added together then divided into a scaled system clock value.
con xtal = 20_000_000 dv = 20 mlt = 100 sys_clk = xtal / dv * mlt clk = 1 << 24 | (dv-1) << 18 | (mlt-1) << 8 us = sys_clk / 1_000_000 baud = 115_200 cpb = (sys_clk / baud) << 16 | 7 tx_pin = 62 #24 ref highx lowx hz = 100 dat org 'setup system clock hubset ##clk | %1111_01_00 waitx ##20_000_000/100 hubset ##clk | %1111_01_11 'setup async transmitter wrpin #%1_11110_0,#tx_pin wxpin ##cpb,#tx_pin dirh #tx_pin 'setup cog for reference pulses loc ptra,#@ref_signal coginit #16,ptra 'setup smartpin to measure high period of ref pin wrpin ##%0111_0000_000_0000000000000_00_10001_0,#highx dirh #highx 'setup smartpin to measure low period of ref pin (inverted input) wrpin ##%1110_0000_000_0000000000000_00_10001_0,#lowx dirh #lowx main waitx ##sys_clk / 2 rdpin high,#highx 'get period value rdpin low,#lowx 'get period value mov pa,high call #dec 'show high period mov char,#" " call #tx_char mov pa,low call #dec 'show low period call #newline qmul ##sys_clk,#10 'calc rom getqx pa add high,low qdiv pa,high getqx pa qmul pa,#6 getqx pa call #dec call #newline call #newline jmp #main dec mov pb,##1_000_000_000 mov digits,#10 .loop qdiv pa,pb getqx char getqy pa add char,#"0" call #tx_char qdiv pb,#10 getqx pb djnz digits,#.loop ret newline mov char,#13 tx_char rdpin ina,#62 wc if_c jmp #tx_char wypin char,#62 ret char long 0 digits long 0 high long 0 low long 0 dat orgh $400 org ref_signal rep @zzz,#0 waitx ##(25_000*us)-6 drvl #ref waitx ##(1_000 * us)-6 drvh #ref zzzTest output show high perio of 25mS and low period of 1mS.
Calculated RPM is ~2304.
Yes, if you wanted to set up an event, the HW pin abilities mean you would usually use the pin HW
Interesting question. I think the streamer is timed-only, and cannot trigger from a smart pin capture.
No. Time units are all in SysCLKS, but they capture 32b, so you just shift the unwanted bits away.
on P2 if we take 100MHz, one period of 26ms is 2600000
Possible period-capture modes would be :
%MMMMM:
a) %10011 = for X periods, count time
b) %10101 = for periods in X+ clocks, count time
c) %10111 = for periods in X+ clocks, count periods
a) mode measures over a defined number of whole periods, which can be X=1, or 10, or anything that gives a sensible read rate.
b) & c) mode gives an (appx) known read rate, and auto-scales, and auto-stretches too.
Usually you pair synchronized 2 pins one in each of b) and c) as you need to know how many whole periods were in that window.
(see the reciprocal counter examples).
This gives you a very wide dynamic range.
mode %10101 = P_COUNTER_TICKS
should work to measure the periode ticks with smartpins.
Here is a Spin2 example that works for me. You can read the current periode ticks anytime from the smartpin.
'' Periode time test P40=fout and P39=fin are connected together CON _clkfreq = 160_000_000 PUB testIt() | fout, fin pinstart(39, P_PERIODS_TICKS, 1, 0) '1 periode, posedge to posedge fout := 100 'start with 100 Hz pinstart(40, P_NCO_FREQ +P_OE, 1, 0) 'NCO output repeat wypin(40, fout frac clkfreq) 'update NCO freq fout += 10 'raise freq slowly waitms(500) fin := clkfreq / rdpin(39) + 1 'read periode and calc freq debug(udec(fin)," Hz")if you set the mode for P39 with: P_PERIODS_TICKS + P_FILT1_AB, then the input gets filtered with a 600ns filter time, that is: glitches on the posedges will not be counted for 600ns. The input filters can also be configured, but there are 4 default filter settings.
Andy
qmul ##sys_clk,#60 'calc rom getqx pa getqy pb add high,low setq pb qdiv pa,high getqx paTweaked ref to 25.007mS high period and got this result
Circuitsoft for your input!
Hopefully in the near future, I can respond with intelligent
questions.
Bill M.