Timer / Clock accuracy not what expected

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi

Xmega = 64A3U-AU

I am trying to get an accurate 1ms from a counter.
I am using an external watch crystal 32.768khz @ 20ppm .
The watch crystal is used to calibrate the main 32Mhz oscillator which is in turn used
to increment a counter with its PER set to 32000 - 1
When outputting the 32Mhz to a pin I can see that the auto calibration is working but not well enough.
It seems to hover at about 32.0300Mhz.
I am using the overflow to generate an event which is incrementing a 32 bit counter. It appears to go out
by as much as a second in about 20 minutes. I have tested this on 4 separate PCB's and all have the same problem,

Perhaps someone can see something I am doing wrong in the code below?

Thanks


	CLKSYS_XOSC_Config( 0, false, OSC_XOSCSEL_32KHz_gc ); 
	CLKSYS_Enable(OSC_XOSCEN_bm);//enable external watch crystal
	CLKSYS_Enable( OSC_RC32MEN_bm);
	CLKSYS_Prescalers_Config( CLK_PSADIV_1_gc, CLK_PSBCDIV_1_1_gc );//sys clock = 32Mhz
	while ( CLKSYS_IsReady( OSC_RC32MRDY_bm ) == 0 );
	CLKSYS_Main_ClockSource_Select( CLK_SCLKSEL_RC32M_gc );
	CLKSYS_Disable(OSC_RC2MEN_bm);//disable 2mhz osc
	...
	...
	...
	CLKSYS_AutoCalibration_Enable( OSC_RC32MCREF0_bm, true );
	...
	...
	...
	//enable a standard 16bit type1 counter
	TCD1.CTRLA = ( TCD1.CTRLA & ~TC1_CLKSEL_gm ) | TC_CLKSEL_DIV1_gc;//TCD1 set to be clocked by 32Mhz system clock
	TCD1.PER = 32000 - 1;//set over flow to happen every 1ms
	TCD1.INTCTRLA =  TC_OVFINTLVL_LO_gc;//set interrupt on for overflow

//--------------------------------------

void CLKSYS_AutoCalibration_Enable( uint8_t clkSource, bool extReference )
{
	OSC.DFLLCTRL = ( OSC.DFLLCTRL & ~clkSource ) | ( extReference ? clkSource : 0 );
	if (clkSource == OSC_RC2MCREF_bm) 
	{
		DFLLRC2M.CTRL |= DFLL_ENABLE_bm;
	} 
	else if (clkSource | OSC_RC32MCREF_gm) 
	{
		DFLLRC32M.CTRL |= DFLL_ENABLE_bm;
	}
}

//--------------------------------------
	
void CLKSYS_XOSC_Config( OSC_FRQRANGE_t freqRange,bool lowPower32kHz,OSC_XOSCSEL_t xoscModeSelection )
{
	OSC.XOSCCTRL = (uint8_t) freqRange |( lowPower32kHz ? OSC_X32KLPM_bm : 0 ) | xoscModeSelection;
}

//--------------------------------------



#define CLKSYS_Enable( _oscSel ) ( OSC.CTRL |= (_oscSel) )  //macro enables the selected oscillator.
#define CLKSYS_IsReady( _oscSel ) ( OSC.STATUS & (_oscSel) )  //macro checks if selected oscillator is ready.
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As far as I know, you are only 'calibrating' the 32MHz RC as a one-off event. i.e. setting the 'best' value to run at 'nearest' 32MHz.

So I would not expect long term 20ppm accuracy.
You can just clock a Timer from the 32kHz watch crystal. e.g. like you use the TOSC pins on a Mega.

I would need to study the clock options of the Xmega. You 'might' be able to PLL the 32kHz crystal. However the CodeVision Wizard says no.

So if you want an accurate RTC, use the watch crystal to clock a Timer.
If you want a 'pretty accurate' RTC, use a regular HF crystal (30ppm) and generate your MCU clock via the PLL.

I MAY HAVE THIS ALL WRONG.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, I think that you are actually doing the right thing. But is the 32.03 MHz clock stable?

Have you checked the accuracy of the 32.768 kHz clock?

Also, maybe you should make sure that the contents of the DFLL32M COMP value is really 0x7A12. In case that doesn't help, you could try increasing the COMP value to 0x7A2F, and see what happens.

Br, E

EDIT: Try decreasing the COMP value to 0x79F4. Sorry.

You're absolutely right. This member is stupid. Please help.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are waiting for the 32 MHz internal oscillator to stabilize before using it. That is good. But you do not wait for the 32 kHz crystal to stabilize before you enable DFLL. That is a requirement on the newer AU parts.

I made the same mistake when I ported some code from a 128D3 to a 128A3U. The D3 happily accepted that I enabled DFLL before the oscillator was stable. It just didn't correct the 32 MHz until the 32 kHz was stable. Using the same code on the A3U and it didn't start correcting the 32 MHz at all.
Just wait for the 32 kHz to stabilize, and then start DFLL.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

That is good. But you do not wait for the 32 kHz crystal to stabilize before you enable DFLL. ...

LOL--Is this like "Who will watch the watchmen?" http://en.wikipedia.org/wiki/Qui...

Making an assumption, "waiting for a clock to stabilize" would involve counting clock ticks during a period of another timing source. So the stable 32kHz is used to tune the DFLL.

What clock source does the 32kHz use to verify stability? :twisted:

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And, of course, a 30 ppm crystal can still drift 30 seconds in about 11 days.

 

"We trained hard... but it seemed that every time we were beginning to form up into a team, we would be reorganized. I was to learn later in life that we tend to meet any new situation by reorganizing. And a wonderful method it can be of creating the illusion of progress while producing confusion, inefficiency and demoralization." Petronius Arbiter, approx. 2000 years ago.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

And, of course, a 30 ppm crystal can still drift 30 seconds in about 11 days.


That's exactly my rule-of-thumb for a DS1305 RTC with a watch crystal, not further calibrated: A minute-a-month. (The last time I tested a batch, it came out as a classic bell curve with most close to nominal and the outliers close to a minute-a-month.)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HF crystals are perhaps 30 ppm when a watch crystal is 20 ppm.

They will all follow the bell curve. If you are lucky, you may get well within 10 ppm.

My recent wristwatch purchases have been bad news. One is about 10 seconds in a month. The other is about 270 seconds a month. Both are specified as 30 secs a month.
In the past, Casio watches have managed about 30 second a year. (3 secs/month)

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
But you do not wait for the 32 kHz crystal to stabilize before you enable DFLL.

I do, I could not find anything in the docs about how to wait for the external watch crystal to become stable. So I started it up and only switched on the auto calibration about 2 seconds afterwards. I forgot to mention that in my code snippets.
The clock frequency does drop from close to 33Mhz down to the 32.03Mhz
I measured the watch crystal on one of my boards and it was 32.788kHz which seems rather fast for a 20ppm crystal??
I originally had 12.pf capacitors on the crystal but it took about 2.5 seconds to start up so I removed them - could this be causing it to be a bit fast? The data sheet said between 6pf - 15pf

Quote:
And, of course, a 30 ppm crystal can still drift 30 seconds in about 11 days.

I am getting about 3 seconds in an hour :?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A tuning fork watch crystal has a very odd temperature coefficient. It is bell-shaped, opening downward. It is most positive near 25C and gets more negative as the temperature moves away from that in either direction.

For a wrist watch, attached to a human wrist, it stays pretty close to 25C. When you take the watch off every night, it tends to slow down, depending on how it is actually calibrated. I have read that watch makers set the error a bit positive (gain time) at 25C to compensate for the fact that most take their watches off at night, where it looses. If you set it right on at 25C, then it it would run slow over an extended time interval.

So, it depends a whole bunch on how the oscillator is calibrated. And, yes, you really DO need to calibrate.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sounds like you need a TCXO. You can get 10 PPM watch crystals too, might be worth a try.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The 16MHz epson crystal I've been using is rated at 10ppm. Have a project coming up that includes a time of day clock, to tell when to do something. 10ppm should be plenty accurate for that. I'll likely goof up the accuracy more than that

 

"We trained hard... but it seemed that every time we were beginning to form up into a team, we would be reorganized. I was to learn later in life that we tend to meet any new situation by reorganizing. And a wonderful method it can be of creating the illusion of progress while producing confusion, inefficiency and demoralization." Petronius Arbiter, approx. 2000 years ago.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

davidgrm wrote:
I do, I could not find anything in the docs about how to wait for the external watch crystal to become stable. So I started it up and only switched on the auto calibration about 2 seconds afterwards. I forgot to mention that in my code snippets.

Ahhh, ok. You should be good then.
I don't use ASF myself, but I guess that you can wait for the external oscillator to stabilize this way:

while ( CLKSYS_IsReady( OSC_XOSCRDY_bm ) == 0 );

Quote:
I originally had 12.pf capacitors on the crystal but it took about 2.5 seconds to start up so I removed them - could this be causing it to be a bit fast?

Indeed, that is most likely the cause. 32.768 kHz watch crystals are very slow to stabilize. They are so slow that I can't wait for it to start when I boot. I just run on the uncorrected internal 32 MHz to begin with. Then when the 32.768 kHz crystal is ready, I enable DFLL. This gives me a few problems with UART communication the first second after power up, but I can live with that.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I put the capacitors back but found that the watch crystals dont seem to be the exact frequency they should be. I guess RS components buys them from China like everyone else. Anyway I wrote a function to calibrate the Dfll comp registers by comparing the ms count with the one pulse per second from a gps module. The time keeping is much more accurate now. Thanks to all for the suggestions and help

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also note that even a 10ppm or better xtal can be off by a few percent, depending on mnf qc. The ppm of course only denotes the temp coefficient, not tolerance.