Chip,
In the latest DOCs, part of some modes has moved into Y, which means it is harder to create a single mode-define.
I notice what take most space in the WRPIN is the DAC fields, which are also not right-aligned.
Combined with my suggestion to have user control of CT.CLK, xNT.CLK sources plus config of Auto-Clear and Over-run replace features (ie that's 4 flags)
that reduces the modes overall, (but not by 4 bits)
What about moving DAC fields into Y reg, so most pin uses can be started with a single WRPIN (and optional is WXPIN,WYPIN), and moving those mode-bits from Y, into
WRPIN.
Same operations, just different mapping, and should allow easy mode-equates to be defined to cover all the modes currently there, plus the new variant ones the improved user-controls allow.
The new Microchip PIC32MK MC series, has 6 Quadrature channels, but they are smarter than just Quadrature
Summary says :
The QEI module consists of the following major features:
•Four input pins: two phase signals, an index pulse and a home pulse
•Programmable digital noise filters on inputs
•Quadrature decoder providing counter pulses and count direction
•Count direction status
•4x count resolution
•Index (INDX) pulse to reset the position counter
•General purpose 32-bit Timer/Counter mode
•Interrupts generated by QEI or counter events
•32-bit velocity counter
•32-bit position counter
•32-bit index pulse counter
•32-bit interval timer
•32-bit position Initialization/Capture register
•32-bit Compare Less Than and Greater Than registers
•External Up/Down Count mode
•External Gated Count mode
•External Gated Timer mode
•Interval Timer mode
So they have the External Up/Down Count mode, which has just been added to P2 Smart Pin cell, plus they have gated Count and Timer modes.
Each cell has 5 x 32b capture registers, 4 x 32b Counters and 2 x 32b compares.
They do have overflow flags.
The velocity counter clears-on-read, but relies on paced software readings to derive dT
The interval timer captures-&-clears on edge, so is suited for low speed velocity
The position counter, has no clear-on-read or capture.
The compare signals can drive a Pin directly.
In equivalent terms, I think a P2 smart pin cell has 2 counters, 1 compare and 1 capture, which means multiple pin cells are needed to replace one QEI module.
Certainly indicates user control of clear-on-capture is needed, as well as control of CLK.DIR.EN to pins.
Compare -> Pin in P2, may require an interrupt, but to have Compare in Quad & UD modes, I think xNT Ctr needs to be Up.Dn capable. Is xNT Up.Dn capable ?
In summary: I think the 'higher end' P2 pin modes (like Whole-Period capture) are smart enough, but the simpler lower-end ones around counting/timing, need some details improved.
----- %10010 = Time X A-input highs -----
GO.S = Ar ' Set on rising edge of A
GO.R = !DIR
CT.CLK = SC ' sysClock
CT.CE = GO ' starts on rising edge of A
CT.R = (NT == X) or !DIR ' reset the count
NT.CLK = SC
NT.CE = Ah ' increments while A is high
NT.R = (NT == X) or !DIR ' rinse and repeat when X reached
Z.D = CT ' implicit
Z.LE = (NT == X) ' capture CT before it resets
Z.R = !DIR
IN.S = (NT == X) ' event notify
IN.R = ACK or !DIR
I note one nice detail already - failing to ACK doesn't stall/block anything. Well, not the counter modes at least.
I think that is how it is currently designed, and something I've suggested is made a user-choice.
Sometimes you want to get the first-reading, and sometimes, you want to lose least information.
----- %10010 = Time X A-input highs -----
GO.S = Ar ' Set on rising edge of A
GO.R = !DIR
CT.CLK = SC ' sysClock
CT.CE = GO ' starts on rising edge of A
CT.R = (NT == X) or !DIR ' reset the count
NT.CLK = SC
NT.CE = Ah ' increments while A is high
NT.R = (NT == X) or !DIR ' rinse and repeat when X reached
Z.D = CT ' implicit
Z.LE = (NT == X) ' capture CT before it resets
Z.R = !DIR
That does not look quite right ? if you are timing over X-cycles of A, then NT.CK=Ar ?
Chip,
I've noticed a timing curiosity with mode %10001 = Time A-input high states. The Z latch is not updated until about 6 sys-clocks after falling edge of A-input, and IN is not raised for another 2 sys-clocks.
I only noticed it because I'm bit-bashing the Smartpin's A-input so can measure by instructions executed. This is only my second mode investigated so I guess I'm going to find many more of these.
if you are timing over X-cycles of A, then NT.CK=Ar ?
Checked it pretty carefully. NT accumulates A high time in sys-clocks. A large value in X can trigger Z latch in a single A pulse if A is high for longer than X in sys-clocks.
That said, I am getting some inconsistencies with the precise threshold for a single A pulse length. Will look at that harder tomorrow.
Checked it pretty carefully. NT accumulates A high time in sys-clocks. A large value in X can trigger Z latch in a single A pulse if A is high for longer than X in sys-clocks.
That said, I am getting some inconsistencies with the precise threshold for a single A pulse length. Will look at that harder tomorrow.
hmm... Then we seem to have a case where the hardware does not match the words ?
The DOCs say this "%10010 = Time X A-input highs Time is measured until X highs are accumulated.
X[31:0] establishes how many highs are to be accumulated.
Time is measured in clock cycles until X highs are accumulated from the input."
Chip's description can be understood as per my measure. That was the reason why I targeted that particular mode first - To make sure I understood the description given.
To compare X to a number of A pulses, mode %10011 = For X periods, count time or %10100 = For X periods, count states would work nicely. Z returns accumulated total (period) time of all pulses or accumulated high (duty) time of all pulses, respectively. So that's covered as well. (But untested ...)
Chip's description can be understood as per my measure. ....
Checked it pretty carefully. NT accumulates A high time in sys-clocks. A large value in X can trigger Z latch in a single A pulse if A is high for longer than X in sys-clocks.
If a large X triggers in a single wider A, that fails "until X highs"
OK, let's ignore the "until X highs" words for now, and consider how the equations you have, could actually work in real usage cases.
With the ability to exit early, anytime Ah, it has lost the whole cycles capture detail, and that renders it unusable for high precision work.
What whole entity capture gives you, is a higher level of precision simple gating does not.
A mode that exits based on gated-time threshold, as your tests seems to show, is partly like a monostable mode I have suggested, only that monostable mode re-sets on every A cycle.
... be interesting to see how the closely related other 2 Whole-Entity modes actually test, and if they have similar loss-of-whole encapsulation (which I'd call a bug )
I have no idea what use this mode has but the description does fit. Although a fuller description would be welcome also.
I agree a better description is needed.
My understanding was these modes paired
%10001 = Time A-input high states
%10010 = Time X A-input highs
ie the first one is a one-shot gated timer, suited to lower pulse rates, and the second version would be used on higher pulse rates, to average gate signal width over many cycles.
However, your reports leave me unsure how anyone could practically use this mode ?
Other modes where the wording needs to improve are
%10011 = For X periods, count time
%10100 = For X periods, count states
First of those is clearly dT over multiple X whole periods, so that is ok.
The second one however, I'm unclear how that can ever give an answer that is not simply =X, or maybe 2X. States are locked into edges, and edges are locked into periods ?
Unless 'X periods' counts just one pin, and 'states' collects both pins, but the words do not suggest that ?
I tested all those modes and they seemed to work correctly. They don't do any fancy stuff, though, regarding capturing and holding, say, an initial sample. They just keep running, taking measurements.
I tested all those modes and they seemed to work correctly. They don't do any fancy stuff, though, regarding capturing and holding, say, an initial sample. They just keep running, taking measurements.
The problem is, the DOC's make it very hard to extract what 'correctly' means, exactly.
In the one under discussion, I've taken "until X highs" to mean what it says, that X occurrences of High are counted, ie the xNT counter increments for each High.
The derived equations and tests seem to indicate those words should be more like "until the total time spent Hi, across one or many Hi's, equals X ", here xNT increments by SysCLK and is gated (clock enabled) by Ah.
An example of how each mode could be put to practical use, would also help.
JMG,
We're only in prototype testing and refining phase. Things are still in flux. Perfecting the readability of documentation comes later.
I'll do my best to confirm the exact functional details with the FPGA and then we can discuss any functional design changes we'd like. But fleshing out the documentation will still come later.
I've been trying a lot of combinations to isolate the inconsistencies with mode %10010 = Time X A-input highs but only got more puzzled as a result.
It almost matches if viewed as accumulator running at half sys-clock rate but not even that explains all. To be consistent it seems to also require an individual pulse length to be that long too. Of course, a single pulse is how I was doing the earlier tests and got good results.
I've been trying a lot of combinations to isolate the inconsistencies with mode %10010 = Time X A-input highs but only got more puzzled as a result.
Trying to reverse engineer and test is always going to be an exercise in frustration ..
idea: If Chip is busy with Spin2, maybe he can publish the Counter parts of Pins verilog ?
This makes your testing easier, and someone can even run Verilog test cases which can help DOCs later.
My above findings for mode %10010 is holding true in all cases I've tried now. Accumulator is resetting on every A-low and it's also only counting at half rate of sysclock.
I'm pretty confident that wasn't the intended behaviour.
My above findings for mode %10010 is holding true in all cases I've tried now. Accumulator is resetting on every A-low and it's also only counting at half rate of sysclock.
I'm pretty confident that wasn't the intended behaviour.
I tried this out and it looks to me like it's working right.
I think the problem is in the terse description.
What this mode does is count clocks until X highs are registered. "Highs" are just clock cycles where the A-input is high, They are not high pulses. As soon as X highs are counted, the time it took to count them up is moved into Z and the IN signal is raised, then a new count begins. This is kind of like a duty-cycle input, of sorts.
Remember that as soon as the goal of X highs is reached, a new count begins. If you hold the pin high, it will just keep issuing measurements that are the same as X.
Here is a test program I wrote that measures the time for 32 highs. If you change the 59 to 60, you will get the 2nd measurement (=32) instead of the 1st measurement (=35):
Oh, yeah, I did forget that detail in the mess of learning PASM/PNut at the same time. I had been incorrectly looking for the first repeats that had consistent reading. It's funny in a way because my very first tests gave good results because I was only testing a single pulse. It went pear shaped when I tried to get repeats ... Thanks for having a look Chip. I'll go over my testing again ...
I tried this out and it looks to me like it's working right.
I think the problem is in the terse description.
What this mode does is count clocks until X highs are registered. "Highs" are just clock cycles where the A-input is high, They are not high pulses. As soon as X highs are counted, the time it took to count them up is moved into Z and the IN signal is raised, then a new count begins. This is kind of like a duty-cycle input, of sorts.
Remember that as soon as the goal of X highs is reached, a new count begins. If you hold the pin high, it will just keep issuing measurements that are the same as X.
So this is part Gated Timer, only with X-threshold added, and part monostable, only without re-trigger.
Can you give some use examples for this mode ?
It seems the longer you wait, the more chance almost any input conditions have of meeting (> X summed total high times) ? Because it is not whole A-inputs, the reported time-required will always be > x, but by some elastic amount that does not give much information about A signal ?
Actually, it's even stranger ... as your example has a longer wait, reporting a lower value.
I can see practical uses for a Monostable action, which is very close to what you describe, only adding 'A-low clears the count'.
Result is it only triggers when any single pulse high width exceeds X
Naming notes comment : If you are using X in smart pins as a threshold, using WAITX then gets quite confusing to read.
Seem either the Smart Pin threshold register needs to change from X, or WAITX needs to be called WaitT or similar ?
I've been calling xNT as the buried counter, (to show it belongs to X, but can be N or Time derived) so maybe rename the Smart pin reg to N or NT ?
Here is a test program I wrote that measures the time for 32 highs. If you change the 59 to 60, you will get the 2nd measurement (=32) instead of the 1st measurement (=35):
Studying that, why is it 35 instead of 34 ? Is there one more clock delay in OUTH than in DIRH ? Makes sense if there is a Pin FF, but the DOCs should specify the two delays,
one is an Opcode delay, and the other is the Delay-to-Pin.
Also, there seems no mechanism to let users know you overflowed, and have captured the second measurement ?
That's right about the different delays between out and dir. This mode is meant to run continuously, periodically reporting results. It's really a duty type of input.
This mode is meant to run continuously, periodically reporting results. It's really a duty type of input.
I'm still unclear on an exact use of this mode ?
If you want to trigger on some duty threshold, like a monostable, you need to reset the Gated Timer when A is Low.
If you want to measure Duty of A, you need to Gate Timer on Ah and capture on Af.
That simplest design works OK up to some modest frequency, but at higher frequencies, and with sources that use many-cycle dither, adding some cycles count to that makes sense.
It maybe that both can be via one mode, where X=1 can capture one pulse, and X>1 captures over many. (but not how this mode works currently)
I think these modes cover that use ? ( used where some sample count is better than a minimum timebase)
%10011 = For X periods, count time
%10100 = For X periods, count states
If you want highest precision true duty cycle capture, you need two pin cells, one to report actual period(s), and the other to report actual tH(s)
Or, you could alternate rapidly one Pin-cell between Period and tH measurements, and accept some loss of precision to source jitter/drift.
I'm somewhat guessing that is what "For X periods, count states" is trying/meaning to say - that it sums tH, via Gated Timer, over X whole periods ?
I'm somewhat guessing that is what "For X periods, count states" is trying/meaning to say - that it sums tH, via Gated Timer, over X whole periods ?
Yes, that is one of the two modes that make up your "reciprocal counter" idea. One counts time for X periods, while the other measures high states during those periods, but not before or after. Using those two modes together can give you very accurate period/frequency, plus duty cycle.
Comments
In the latest DOCs, part of some modes has moved into Y, which means it is harder to create a single mode-define.
I notice what take most space in the WRPIN is the DAC fields, which are also not right-aligned.
Combined with my suggestion to have user control of CT.CLK, xNT.CLK sources plus config of Auto-Clear and Over-run replace features (ie that's 4 flags)
that reduces the modes overall, (but not by 4 bits)
What about moving DAC fields into Y reg, so most pin uses can be started with a single WRPIN (and optional is WXPIN,WYPIN), and moving those mode-bits from Y, into
WRPIN.
Same operations, just different mapping, and should allow easy mode-equates to be defined to cover all the modes currently there, plus the new variant ones the improved user-controls allow.
Summary says :
The QEI module consists of the following major features:
•Four input pins: two phase signals, an index pulse and a home pulse
•Programmable digital noise filters on inputs
•Quadrature decoder providing counter pulses and count direction
•Count direction status
•4x count resolution
•Index (INDX) pulse to reset the position counter
•General purpose 32-bit Timer/Counter mode
•Interrupts generated by QEI or counter events
•32-bit velocity counter
•32-bit position counter
•32-bit index pulse counter
•32-bit interval timer
•32-bit position Initialization/Capture register
•32-bit Compare Less Than and Greater Than registers
•External Up/Down Count mode
•External Gated Count mode
•External Gated Timer mode
•Interval Timer mode
So they have the External Up/Down Count mode, which has just been added to P2 Smart Pin cell, plus they have gated Count and Timer modes.
Each cell has 5 x 32b capture registers, 4 x 32b Counters and 2 x 32b compares.
They do have overflow flags.
The velocity counter clears-on-read, but relies on paced software readings to derive dT
The interval timer captures-&-clears on edge, so is suited for low speed velocity
The position counter, has no clear-on-read or capture.
The compare signals can drive a Pin directly.
Supported modes are
11 = SysCLK/N=CLK, QEB = CLK.EN Gated Timer mode
10 = QEA=CLK, QEB = CLK.EN Gated Counter Mode
01 = QEA=CLK, QEB= DIRN Up.Dn Counter mode
00 = QEA,QEB as standard Quadrature Encoder Interface Count mode (x4 mode)
In equivalent terms, I think a P2 smart pin cell has 2 counters, 1 compare and 1 capture, which means multiple pin cells are needed to replace one QEI module.
Certainly indicates user control of clear-on-capture is needed, as well as control of CLK.DIR.EN to pins.
Compare -> Pin in P2, may require an interrupt, but to have Compare in Quad & UD modes, I think xNT Ctr needs to be Up.Dn capable. Is xNT Up.Dn capable ?
In summary: I think the 'higher end' P2 pin modes (like Whole-Period capture) are smart enough, but the simpler lower-end ones around counting/timing, need some details improved.
I've started testing the Smartpin modes to check the detailed operation ...
I note one nice detail already - failing to ACK doesn't stall/block anything. Well, not the counter modes at least.
Sometimes you want to get the first-reading, and sometimes, you want to lose least information.
That does not look quite right ? if you are timing over X-cycles of A, then NT.CK=Ar ?
I've noticed a timing curiosity with mode %10001 = Time A-input high states. The Z latch is not updated until about 6 sys-clocks after falling edge of A-input, and IN is not raised for another 2 sys-clocks.
I only noticed it because I'm bit-bashing the Smartpin's A-input so can measure by instructions executed. This is only my second mode investigated so I guess I'm going to find many more of these.
Checked it pretty carefully. NT accumulates A high time in sys-clocks. A large value in X can trigger Z latch in a single A pulse if A is high for longer than X in sys-clocks.
That said, I am getting some inconsistencies with the precise threshold for a single A pulse length. Will look at that harder tomorrow.
hmm... Then we seem to have a case where the hardware does not match the words ?
The DOCs say this
"%10010 = Time X A-input highs Time is measured until X highs are accumulated.
X[31:0] establishes how many highs are to be accumulated.
Time is measured in clock cycles until X highs are accumulated from the input."
Is part of that due to the input noise filters ? It should be a balanced delay, so is the capture width what you expected ?
To compare X to a number of A pulses, mode %10011 = For X periods, count time or %10100 = For X periods, count states would work nicely. Z returns accumulated total (period) time of all pulses or accumulated high (duty) time of all pulses, respectively. So that's covered as well. (But untested ...)
If a large X triggers in a single wider A, that fails "until X highs"
OK, let's ignore the "until X highs" words for now, and consider how the equations you have, could actually work in real usage cases.
With the ability to exit early, anytime Ah, it has lost the whole cycles capture detail, and that renders it unusable for high precision work.
What whole entity capture gives you, is a higher level of precision simple gating does not.
A mode that exits based on gated-time threshold, as your tests seems to show, is partly like a monostable mode I have suggested, only that monostable mode re-sets on every A cycle.
... be interesting to see how the closely related other 2 Whole-Entity modes actually test, and if they have similar loss-of-whole encapsulation (which I'd call a bug )
I have no idea what use this mode has but the description does fit. Although a fuller description would be welcome also.
My understanding was these modes paired
%10001 = Time A-input high states
%10010 = Time X A-input highs
ie the first one is a one-shot gated timer, suited to lower pulse rates, and the second version would be used on higher pulse rates, to average gate signal width over many cycles.
However, your reports leave me unsure how anyone could practically use this mode ?
Other modes where the wording needs to improve are
%10011 = For X periods, count time
%10100 = For X periods, count states
First of those is clearly dT over multiple X whole periods, so that is ok.
The second one however, I'm unclear how that can ever give an answer that is not simply =X, or maybe 2X. States are locked into edges, and edges are locked into periods ?
Unless 'X periods' counts just one pin, and 'states' collects both pins, but the words do not suggest that ?
%10011 pairs with %10100 and does what you are asking for. I already stated that. I'll do some testing to verify ...
The problem is, the DOC's make it very hard to extract what 'correctly' means, exactly.
In the one under discussion, I've taken "until X highs" to mean what it says, that X occurrences of High are counted, ie the xNT counter increments for each High.
The derived equations and tests seem to indicate those words should be more like "until the total time spent Hi, across one or many Hi's, equals X ", here xNT increments by SysCLK and is gated (clock enabled) by Ah.
An example of how each mode could be put to practical use, would also help.
We're only in prototype testing and refining phase. Things are still in flux. Perfecting the readability of documentation comes later.
I'll do my best to confirm the exact functional details with the FPGA and then we can discuss any functional design changes we'd like. But fleshing out the documentation will still come later.
It almost matches if viewed as accumulator running at half sys-clock rate but not even that explains all. To be consistent it seems to also require an individual pulse length to be that long too. Of course, a single pulse is how I was doing the earlier tests and got good results.
Chip, mode %10010 seems to be broken.
Trying to reverse engineer and test is always going to be an exercise in frustration ..
idea: If Chip is busy with Spin2, maybe he can publish the Counter parts of Pins verilog ?
This makes your testing easier, and someone can even run Verilog test cases which can help DOCs later.
My above findings for mode %10010 is holding true in all cases I've tried now. Accumulator is resetting on every A-low and it's also only counting at half rate of sysclock.
I'm pretty confident that wasn't the intended behaviour.
Can you try a lower SysCLK ?
I tried this out and it looks to me like it's working right.
I think the problem is in the terse description.
What this mode does is count clocks until X highs are registered. "Highs" are just clock cycles where the A-input is high, They are not high pulses. As soon as X highs are counted, the time it took to count them up is moved into Z and the IN signal is raised, then a new count begins. This is kind of like a duty-cycle input, of sorts.
Remember that as soon as the goal of X highs is reached, a new count begins. If you hold the pin high, it will just keep issuing measurements that are the same as X.
Here is a test program I wrote that measures the time for 32 highs. If you change the 59 to 60, you will get the 2nd measurement (=32) instead of the 1st measurement (=35):
Can you give some use examples for this mode ?
It seems the longer you wait, the more chance almost any input conditions have of meeting (> X summed total high times) ? Because it is not whole A-inputs, the reported time-required will always be > x, but by some elastic amount that does not give much information about A signal ?
Actually, it's even stranger ... as your example has a longer wait, reporting a lower value.
I can see practical uses for a Monostable action, which is very close to what you describe, only adding 'A-low clears the count'.
Result is it only triggers when any single pulse high width exceeds X
Naming notes comment : If you are using X in smart pins as a threshold, using WAITX then gets quite confusing to read.
Seem either the Smart Pin threshold register needs to change from X, or WAITX needs to be called WaitT or similar ?
I've been calling xNT as the buried counter, (to show it belongs to X, but can be N or Time derived) so maybe rename the Smart pin reg to N or NT ?
Studying that, why is it 35 instead of 34 ? Is there one more clock delay in OUTH than in DIRH ? Makes sense if there is a Pin FF, but the DOCs should specify the two delays,
one is an Opcode delay, and the other is the Delay-to-Pin.
Also, there seems no mechanism to let users know you overflowed, and have captured the second measurement ?
If you want to trigger on some duty threshold, like a monostable, you need to reset the Gated Timer when A is Low.
If you want to measure Duty of A, you need to Gate Timer on Ah and capture on Af.
That simplest design works OK up to some modest frequency, but at higher frequencies, and with sources that use many-cycle dither, adding some cycles count to that makes sense.
It maybe that both can be via one mode, where X=1 can capture one pulse, and X>1 captures over many. (but not how this mode works currently)
I think these modes cover that use ? ( used where some sample count is better than a minimum timebase)
%10011 = For X periods, count time
%10100 = For X periods, count states
If you want highest precision true duty cycle capture, you need two pin cells, one to report actual period(s), and the other to report actual tH(s)
Or, you could alternate rapidly one Pin-cell between Period and tH measurements, and accept some loss of precision to source jitter/drift.
I'm somewhat guessing that is what "For X periods, count states" is trying/meaning to say - that it sums tH, via Gated Timer, over X whole periods ?
As for it's usefulness, unless Phil can think of a way to use it, I think I'd put it on the scrapheap alongside mode %10000.
Mode %10010 just tells you how long it took to register X highs.
Mode %10000 is used by the boot ROM for automatic baud detection. It works great there.
Yes, that is one of the two modes that make up your "reciprocal counter" idea. One counts time for X periods, while the other measures high states during those periods, but not before or after. Using those two modes together can give you very accurate period/frequency, plus duty cycle.