AVR32DD20 Cascaded TCBs = 32bit timer but CAPT pulses are intermittently missed and CCMP counts seems wrong #441
-
I'm seeing a raft of strange phenomena that I'd appreciate comment on. I am trying to cascade TCB0 and TCB1 into a 32 bit frequency counter. I'm driving the AVR32DD20 from a 10 MHz external clock (very stable) into My understanding is that at the moment when the CAPT event happens (the pulse rising on 'PA2'), the CNT values from TCB0 and TCB1 will be simultaneously (or as near as) written to their respective CCMP registers (which I know are 16 bit word registers and I could be reading them wrongly). To notify the CPU that the CCMP registers need to be read (ie the 1Hz pulse has been detected) I set a TCB CAPT interrupt, where I copy values from TCB CCMP registers into variables and flag to main loop, where I shift up the MSBs, combine and print them. Code will be below as a reply to this initial message. Phenomenon 1 - count is significantly different to 10 million.These are typical printouts
The 1 Hz pulse generator is way off. The source of that is a 10 MHz oscillator with better than 1PPM stability, so I'm more suspicious of the pulse generator than the input clock at the moment. But something is off here. Phenomenon 2 - missed CAPT events/pulsesNotice how every now and then the count rises to approximately double the normal ~10 million? It appears to be random, no regular spacing. It also sometimes grows to 3 - 6 times the ~10 million value. I have watched a scope trigger continuously while it happens and I don't believe the scope has missed any pulses. The 1 Hz pulses are only 100 nanoseconds wide, so maybe they're too short to be noticed? But that doesn't seem to be consistent with the fact that the "double" count after they are missed appears to have a couple more counts that twice the ~10 million counts.... Phenomenon 3 - missed CAPT events lead to more than double CCMP count values?It seems like if you accept the 20131066 are missed CAPT events (and the serial print certainly pauses, as if the timer is continuing to count, even if the scope shows the pulse arrived), 2 x 10065532 is 20131064. And even if this is all 0-indexed, we are still off by a couple of counts. But the description of the Section 24.3.3.1.4 Input Capture Frequency Measurement Mode indicates that we should see an instantaneous transfer of CNT to CCMP and restart, so where would additional counts come from if the CAPT event had been missed? Any ideas what is going on here or what to test? |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments 5 replies
-
|
Beta Was this translation helpful? Give feedback.
-
It just feels like a rollover, dont it. I havent used the tcb timer in that much depth, so... Can the timer be configured to generate a rollover interrupt with the isr toggling a hardware pin for scope viewing? is there any coincidence with the anomaly? How does your hardware setup work without the counters cascaded, ie just 16 bits? Same but different? If i understand what you are doing, the counter values are the time drift (or phase error) of the 1pps in relation to your 10mhz clock. Those two clocks must be pretty accurate as i see no drift in dt. Have you tried stressing it with two clocks that are drifting apart to see if something breaks? Sometimes something that is broken is easier to fix than almost running... Sounds like another fun project! |
Beta Was this translation helpful? Give feedback.
-
I think I have a partial answer for Phenomenon 1. The count is almost 0xFFFF too high. So if I adjust the counter by 0x10000, it lands much closer to 10 million. But I don't understand why. My 0-indexed maths must be off so we'll leave it there for now. Only 2 more phenomena to solve! |
Beta Was this translation helpful? Give feedback.
-
most gps module has a 1pps output with a fairly extreme long term accuracy, but with mixed short term precision. Whether there's one in your junkbox or fedex from your favorite toystore, that might be a quick and easy way to have a second very accurate clock to beat against your 10mhz osc. |
Beta Was this translation helpful? Give feedback.
-
In section 16.2.1 of the dd20 datasheet is this quote: An event signal from an asynchronous source will be synchronized by the Event System before being routed to the Im unclear how the 'is async' decision in Figure 16-1 is made or what your pclock is, but maybe that nagging thought you had about the 100nS pulse being too short was justified? |
Beta Was this translation helpful? Give feedback.
-
So I have found the problem with the second two phenomena. The short pulse (90 ns pulse width from a supposed 100 ns source) means that as the two very stable clock process past each other (ie gradual phase shift) they can get into a phase where the pulse edge is detected by the TCB0 input but the event doesn't last long enough to be treated as a CAPT signal. Interesting. So I tried using the CCL to lengthen the pulses, taking inspiration from the logic library latch without sequencer example:
and the events need to be updated too:
This results in a 6.5ms pulse on the output (not included above but you can do this to monitor on
Here's the output now. Where you can see the occasional 10000003 count, those are areas where the CAPT would most likely have been missed and the "double" count would have been reached. The fact that it sometimes counts 3x, 4x and upto 6x the nominal 10 million count fits with the hypothesis that the relative clock phase is changing slowly because the two clocks are so stable.
|
Beta Was this translation helpful? Give feedback.
-
perhaps feed the 1pps to the portpin via a schottky diode and enable that pins pulldown (or pullup depending pps polarity)? If you have to add a small cap, so be it. |
Beta Was this translation helpful? Give feedback.
-
I think they obliquely warn you about that in the datasheet, and in any
case I'm pretty sure they specify that the signal must meet the nyquist
criteria to be reliably detected and reacted to correctly.... ( I know
there are other place s where they mention an interrupt that will do
not-nothing but not everything if the pulse is shorter than the nyquist
criteria.
You notice that you're reading numbers 2-3 clocks high - I wonder if thats
a sync delay
…On Wed, Jun 7, 2023 at 6:56 AM SimonMerrett ***@***.***> wrote:
So I have found the problem with the second two phenomena. The short pulse
(90 ns pulse width from a supposed 100 ns source) means that as the two
very stable clock process past each other (ie gradual phase shift) they can
get into a phase where the pulse edge is detected by the TCB0 input but the
event doesn't last long enough to be treated as a CAPT signal. Interesting.
So I tried using the CCL to lengthen the pulses, taking inspiration from
the logic library latch without sequencer example:
void CCL0_init(void)
{
/*
3-input truth table:
|IN2|IN1|IN0| Y |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 |
| 0 | 1 | 0 | 1 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 0 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 0 |
| 1 | 1 | 1 | 1 |
*/
Logic0.enable = true; // Enable logic block 1
Logic0.input0 = in::feedback; // Use own feedback as input 0
Logic0.input1 = in::event_a; // TCB0 OVF as input 1 (RESET)
Logic0.input2 = in::event_b; // PA2 level as input 2 (SET)
Logic0.output = out::disable; // disable logic block 0 output pin
Logic0.truth = 0x8E; // Set truth table - SR latch behaviour
// Initialize logic block 1
Logic0.init();
// Set interrupt (supports RISING, FALLING and CHANGE)
Logic0.attachInterrupt(logic0_ISR, RISING);
// Start the AVR logic hardware
Logic::start();
}
and the events need to be updated too:
void init_eventsys(void)
{
/* Set up generators */
EVSYS.CHANNEL0 = EVSYS_CHANNEL0_TCB0_OVF_gc; // set up channel 0 generator to be TCB0 overflow
EVSYS.CHANNEL1 = EVSYS_CHANNEL1_PORTA_PIN2_gc; // set up channel 1 generator to be PA2 logic level
EVSYS.CHANNEL2 = EVSYS_CHANNEL2_CCL_LUT0_gc; // set up channel 2 generator to be LUT0 output
/* Set up users */
EVSYS.USERTCB1COUNT = EVSYS_USER_CHANNEL0_gc; // TCB1 counts TCB0 0xFFFF TOP overflows
EVSYS.USERTCB0CAPT = EVSYS_USER_CHANNEL2_gc; // TCB0 transfers COUNT to CCMP on PA2 logic HIGH and resets
EVSYS.USERTCB1CAPT = EVSYS_USER_CHANNEL2_gc; // TCB1 transfers COUNT to CCMP on PA2 logic HIGH and resets
EVSYS.USERCCLLUT0A = EVSYS_USER_CHANNEL1_gc; // LUT0 takes PA2 pulse as input
EVSYS.USERCCLLUT0B = EVSYS_USER_CHANNEL0_gc; // LUT0 takes TCB0 OVF as input
}
This results in a 6.5ms pulse on the output (not included above but you
can do this to monitor on PC2
EVSYS.USEREVSYSEVOUTC = EVSYS_USER_CHANNEL2_gc; // route the TCB0 overflow event to PC2
PORTMUX.EVSYSROUTEA |= PORTMUX_EVOUTC_bm; // Output on PC2
PORTC.DIRSET |= PIN2_bm; // EVOUTC on PC2
Here's the output now. Where you can see the occasional 10000003 count,
those are areas where the CAPT would most likely have been missed and the
"double" count would have been reached. The fact that it sometimes counts
3x, 4x and upto 6x the nominal 10 million count fits with the hypothesis
that the relative clock phase is changing slowly because the two clocks are
so stable.
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000002
10000003
10000002
10000002
10000002
10000002
10000002
10000003
10000002
—
Reply to this email directly, view it on GitHub
<#441 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABTXEW62AYWARBHDQFHA6ITXKBM53ANCNFSM6AAAAAAY4S4LFY>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
--
____________
Spence Konde
Azzy’S Electronics
New products! Check them out at tindie.com/stores/DrAzzy
GitHub: github.com/SpenceKonde
ATTinyCore <https://github.com/SpenceKonde/ATTinyCore>: Arduino support for
all pre-2016 tinyAVR with >2k flash!
megaTinyCore <https://github.com/SpenceKonde/megaTinyCore>: Arduino support
for all post-2016 tinyAVR parts!
DxCore <https://github.com/SpenceKonde/DxCore>: Arduino support for the AVR
Dx-series parts, the latest and greatest from Microchip!
Contact: ***@***.***
|
Beta Was this translation helpful? Give feedback.
So I have found the problem with the second two phenomena. The short pulse (90 ns pulse width from a supposed 100 ns source) means that as the two very stable clock process past each other (ie gradual phase shift) they can get into a phase where the pulse edge is detected by the TCB0 input but the event doesn't last long enough to be treated as a CAPT signal. Interesting.
So I tried using the CCL to lengthen the pulses, taking inspiration from the logic library latch without sequencer example: