How to measure frequency using smart pins ?
Bean
Posts: 8,129
In preparation for getting a P2 chip, my first project will be to very accurately measure the frequency of an input signal.
The input signal will be a square wave from 900Hz to 1100Hz measured for 1 second.
Looking at the smartpin docs, I assume I would use mode %10101 = For periods in X+ clock cycles, count time
But it appears this returns the total period, but how do I know how many cycles occurred within that total period ?
Basically I need to know how many cycles of the input occurred in how many clocks of the P2.
For example if the input was exactly 1000Hz, and the P2 is running at 200MHz and I sampled for 1 second,
I would expect to get the the values: 1000 and 200_000_000.
Do I need to use two smartpins ?
Any clarification would be appreciated.
Thanks, Bean
The input signal will be a square wave from 900Hz to 1100Hz measured for 1 second.
Looking at the smartpin docs, I assume I would use mode %10101 = For periods in X+ clock cycles, count time
But it appears this returns the total period, but how do I know how many cycles occurred within that total period ?
Basically I need to know how many cycles of the input occurred in how many clocks of the P2.
For example if the input was exactly 1000Hz, and the P2 is running at 200MHz and I sampled for 1 second,
I would expect to get the the values: 1000 and 200_000_000.
Do I need to use two smartpins ?
Any clarification would be appreciated.
Thanks, Bean
Comments
One cell captures cycles, the other captures time. This has a very wide dynamic range.
For a narrow known range, you might be able to use that X+ set fixed to 1000, and get a time result (sysclks) in 900 to 1100ms
An example is needed for that case too.
The problem I run into on the P1 is that if one of the inputs fails (doesn't change state), then the WAITPNE and WAITPEQ commands stop everything.
I think I remember hearing that the P2 has time-outs on these. Is that true ? That would help a lot.
Bean
I think the mode you want is %01110 (Count A-input positive edges), at least for the 1000 part. I don't understand why you'd use a smart pin to get back the 200_000_000 part.
Lots of choices for how:
- You could very precisely do that just with inline WAITSE1 and GETCT duo, respectively, looping for each interval until you've got enough data. There is plenty of time between pulse periods to make decisions and even emit progress for monitoring. Each new interval reading is referenced to first edge detection, so fully retained information extending out as long as you like. An extended version of this - https://forums.parallax.com/discussion/169129/increasing-the-resolution-of-pulse-timing
- Smartpins have multiple modes that can cover it. Many of them would be configured to report each pulse duration. Not really any different to the GETCT above. The ones of note would be:
%10010 AND !Y[2] = Time X A-input highs/rises/edges: This one you specify how many pulses you want to count and it'll tell you how long that took. I'm unsure but I guess using rise setting will start timing on first rise so will give back precise rise to rise measurement.
%10011 = For X periods, count time: Same as above (rise to rise setting) I think.
EDIT: I just read your follow-up about lost signal. Right, so the software solution won't be good enough. The smartpins should be good for this. They can be monitored and reset at will.
I also need "zero-dead-time", so there can't be any skipped cycles.
This is why the frequency is so low (1KHz), so there is time to get the values from multiple pins.
The way I do it with the P1 is to wait for an edge, then record CNT and the hardware counters count the cycles while I'm not looking.
The measurements might include an extra cycle or two, but that doesn't matter as long as none are missed.
Bean
EDIT: Ah, you mean you want no gaps in the measuring. Yep, easy-pees.
Here's a rough example:
The only restriction is you must be quick enough to read the current measurement before the next one arrives or it will be overwritten.
They will all start within ~1ms windows, and you have 0.9~1.1s before the next capture arrives on that same channel.
The 1-pin polling loop evanh coded above would change to be a test for any pin ready, then a store that pin 2-step.
Yes, for the measure whole cycles modes, they queue once armed, and wait for a valid before starting.
IIRC some also have a clear-on-capture ability, and for those, Chip added a smarter clear, so that if an edge was arriving on the same edge as clear, it instead loads with 1.
(that 0/1 choice should be clear of the -1 bug?)
That means it should be both gapless and have zero missing/added edges.
Seems Chip should send evanh & Bean P2 boards, so they can test the code snippets ?
It would be great to see these Smart Pin capture/count modes verified in silicon, up to the same MHz the code appears to run to
Is there any hardware overflow signal, to catch such an overwrite ? How do users know they have not missed a reading ?
By not being lazy farts. Code for real time operation and the problem goes away. The Prop is not a general computing platform where IRQ's commonly go to never-never-land.
Easy enough to say, but rather harder to prove to the management that you have a black-box that can 100% confirm no-missed-readings.
That's why other MCUs often/usually have such overflow flags. It's because customers expect & make use of them.
Take the example above, where someone has 60 channels ticking away..
Now imagine because the COG is mostly idling, and other COGs are busy, they add some maths and serial reporting code, then the boss wants faster reporting rates...
Things easily get incrementally more complex, but it passes all the bench tests.... and hey, we think we "Code for real time operation" so it will be fine ?
Addit: Looking at the above, you could emulate an overflow flag in software, with more complex polling, and 60 poll-count variables that check you did have at least one empty poll between same channel readings. Perhaps those 60 can pack into 60 booleans, as you only need a >0 test ?
You can still do your reports with realtime behaviour. You don't need any debug hand holding for that.
Here is actual output at the terminal (Using 20MHz sysclock): The leading spaces are because my integer print routine is fixed length.
This still sounds like mode %01110 (Count A-input positive edges). If you want to do it the P1 way, you could run it in continuous mode (interval=0). However, if you use a non-zero interval, then you don't have to bother with capturing CNT anymore (or correcting the captured counter value). You specify the precise number of clock cycles to count for (in this case 200_000_000). When the interval is reached, the counter value is stored (to Z) and the counting starts over again for the same interval. True zero-dead-time. As long as you pull the value from Z before the next interval expires, you have in infinite series of precisely-measured edge counts (and therefore frequency).
EDIT: Modes that can be configured for continuous accumulation won't reset Z count.
If I remember rightly, I even raised this point when we were working on polishing the smartpins.
Even without reset, in some modes you cannot quite simply 'carry on, in a corrective manner' - eg here, you would report twice the dT* for what you thought was 1000 cycles, but was actually 2000. If you are lucky, and a 2:1 range is not needed, you can use a value sanity check, but many systems have very wide dynamic ranges.
* I'm assuming the next capture simply replaces the last one.
I'm interested to see how a Reciprocal Counter works on real silicon, as there you need two pin-cells working in sync, to capture dT and dC.
I think Bean is chasing high precision here, so he is less interested in 'counting to 1000' than he is in timing exactly* how long 1000 cycles took,
and also wants to do that over many pins.
The P1 approach falls down, when you hope to do many pins. You run out of COGs or counters...
P2 in mode %10011 = For X periods, count time can manage 60 or more pins, all from a single COG, because the hardware does all the heavy lifting.
* eg 200MHz resolves to 5 micro-hertz in 1 second, and a P2 PLL locked to a ppb timebase can ensure these are genuine Hz
1000*5n*(200M+1) = 1000.000005
1000*5n*(200M-1) = 999.999995
There was no special hardware assigned for the job. The method was simple enough, check ISR interval against a generic timer chip. So it easily knew if, say, a hundred consecutive IRQ's had been missed.
Our current setup with the P1 measures 8 channels and we can specify either an exact number of cycles to measure, or a total time to measure. The advantage of the exact cycles is that you don't need to store the number of cycles. So there is only one number to worry about.
But some test require a certain gate time (+0 or +1 cycle). It totals until a rise time exceeds the limit, then returns cycles and clocks.
We currently use 4 propellers in a 1U chassis to measure 32 channels. It would be great if one P2 could do that (and with better resolution). 240MHz would give us three times the resolution we have with the P1. And a much larger buffer to store readings.
So if I follow evanh's code, you are only using one smart-pin cell ?
Bean
One P2 could easily manage 32 channels of the exact number of cycles to measure, as a single number consumes a single Smart Pin Cell.
Getting 32 channels of returns cycles and clocks is tighter, as you need pins to boot the P2, but you also need 64 Smart Pin Cells, for the dual-capture info.
Serial boot would use 2 pins, and there is a nearby-pin mapping ability in the smart pins, thus That can skip-over 2 UART pins ok, but if you want SPI and UART and 32 channels of pair-captures, some external MUX help looks to be needed.