Wed Mar 8 18:32:29 EST 2017
Extending timer capture values
Code looks like this:
CR TR CR TR
CR = capture interrupt is checked, and if there is a value it is
loaded. after this a new capture event can happen.
TR = current timer value is read.
The task is then to:
- extend the read capture value correctly
- update the extension counter on T rollover
The ambiguity is in the location of the actual capture event and the
rollover event in the grid imposed by CR and TR.
TR CR C TR CR TR, or
TR CR TR C CR TR
T0 T1 T2
It is straightforward to time extend C, if we assume we have an
extension counter E that represents the state of the extension after
the "nearest" rollover in the count.
if C is near the small end -> extend with E
large end -> extend with E - 1
The question is then, how to update E when a T rollover occurs?
It seems this cannot be done without causing a race. I can't say
exactly why, but I also can't answer the question about when to update
E such that it can be trusted when it is read to extend the C value
that is read at CR time.
My intution was to do the update "far away" from the point of use.
The solution I had was to use two extension counters, using the
assumption that a counter is not used for a very large margin around
the time when it gets updated, effectively "double buffering" it.
counter use update
M(id) Q2 Q3 Q4->Q1
W(rap) Q4 Q1 Q2->Q3
Then based on whether the captured count is in one of these regions,
the extension is easy to compute:
I currently beleive it can not be done by updating a single counter at
or near the rollover, because the order of the events is not known.
One possibility is to keep track of one extra bit in the extension to
disambiguate if the "nearest" rollover has been accounted for. This
likely is equivalent to keeping two counters, because they always stay
only one bit apart.
Essentially, that one bit encodes the information "does the current
extension account for the 'current' rollover or not?".
This bit is the high bit of the last read timer:
0 : rollover has occured
1 : rollover has not occured
But then this still needs an extra bit to take into account _whether
to look_ at that bit. And we wouldn't if we're in Q2,Q3, but we would
if we're in Q4,Q1.
So an aternative way:
- roll over the main counter in the straightforward way. this gives a
32-bit value that is "near" the capture event.
- based on whether the capture event was before or after the rollover,
extend it with the correct side.
"extending with the correct side" can be done simpler:
Given the notation above, we know that
- C =< CB =< T => C =< T
- The extension E:T can always be computed correctly
There are only two possibilities: (E-1):C or E:C
If E:C > T it must be (E-1):C
The condition that C happened at or before T is the property that
So the fundamental event ambiguity is:
TR R C TR vs
TR C R TR
I.e. did the rollover R happen before or after the capture event C.
The second TR will catch the rollover, but extension of C depends on
the orer of R and C.
The disambiguation works because in the second case (C <= R), E:C will
turn out to be past TR, which has to be wrong, so (E-1):C is the
correct extension in that case.
TC C TR R TC TR
TC TR C R TC TR
The C<->TR swap doesn't seem to matter in this case.
Summary: The problem was finding the right way to look at this.