The OSC: 16MHz crystal xMega192D3

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

Up until now, the internal RC osc has been plenty accurate. In fact, the xMega's 1% calibrated internal RC osc is probably plenty accurate, but I wanted to use a crystal.

I THINK I have it running now on the 16MHz crystal. That is, I set #define F_CPU 32000000UL and _delay_ms(500) seems to be about 1/2 a second. Actually, this seems a little silly

So, do I have this right?

	OSC.XOSCCTRL=OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;
	OSC.CTRL|=OSC_XOSCEN_bm;
	uint8_t n=(CLK.PSCTRL & (~(CLK_PSADIV_gm | CLK_PSBCDIV1_bm | CLK_PSBCDIV0_bm))) | CLK_PSADIV_1_gc | CLK_PSBCDIV_1_1_gc;
	CCP=CCP_IOREG_gc;
	CLK.PSCTRL=n;

	// Wait for the external oscillator to stabilize
	while ((OSC.STATUS & OSC_XOSCRDY_bm)==0);

	// Select system clock source: External Osc. or Clock
	n=(CLK.CTRL & (~CLK_SCLKSEL_gm)) | CLK_SCLKSEL_XOSC_gc;
	CCP=CCP_IOREG_gc;
	CLK.CTRL=n;

internal 32kHz, PLL
	OSC.CTRL&= ~(OSC_RC2MEN_bm | OSC_RC32MEN_bm | OSC_RC32KEN_bm | OSC_PLLEN_bm);

Code lifted right here from the Freaks.

I think I can run the thing slowly, at like 2MHz most of the time to conserve power, then switch to 32MHz when I want to update the TFT display. Well, maybe not, as that would defeat the purpose of using a crystal, that is, keeping multiple devices in sync over a period of time.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

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

It looks like you are running directly from the external crystal with all prescalers set to 1:1. That would be 16MHz total.

To run at a higher frequency than the clock source you need to use the PLL to multiply by 2 in this case (PLL multiplicand times system clock prescalers should be equal to two).

So after you enabled the external crystal you should configure the PLL to use the crystal as source, multiply by two and then use the PLL as system clock source. Something like this

    // Use external 16MHz crystal for 32MHz clk_cpu
    // 12-16 MHz XTAL - 16K CLK Start Up
    OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;

    // Enable external oscillator
    OSC.CTRL |= OSC_XOSCEN_bm;
    // Wait until XOSC is ready
    while (!(OSC.STATUS & OSC_XOSCRDY_bm))
        ;

    // Prescaler A: 1:1, B, 1:1, C: 1:1 (all default). Unlock first.
    CCP = CCP_IOREG_gc;
    CLK.PSCTRL = CLK_PSADIV_1_gc | CLK_PSBCDIV_1_1_gc;

    // XOSC src for PLL, 2x.
    OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (OSC_PLLFAC_gm & 2);
    // Enable PLL
    OSC.CTRL |= OSC_PLLEN_bm;
    // Wait until PLL ready
    while (!(OSC.STATUS & OSC_PLLRDY_bm))
        ; 
    // PLL as system clock, unlock CLK.CTRL first
    CCP = CCP_IOREG_gc;
    CLK.CTRL = CLK_SCLKSEL_gm & CLK_SCLKSEL_PLL_gc;

    // Disable unused oscillators
    OSC.CTRL &= ~(OSC_RC2MEN_bm | OSC_RC32MEN_bm | OSC_RC32KEN_bm);

You can look at the system clock on, for example, PD7 with

    // Output system clock on PD7
    PORTD.DIRSET = PIN7_bm;
    PORTCFG.CLKEVOUT = PORTCFG_CLKOUT_PD7_gc;
=======================================================================
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I see, my notion of a 1Hz beat is a little off.

Many bits to get right, but I was pleased my crystal oscillated when I first tried it.

If you don't know my whole story, keep your mouth shut.

If you know my whole story, you're an accomplice. Keep your mouth shut. 

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

Quote:
but I was pleased my crystal oscillated when I first tried it.

Be careful. Unlike the Megas and Tinies where one can select a non-functional clock sourse, (e.g. ext Xtal when there isn't one), the Xmega always powers up on the internal Clock, and won't switch to an invalid clock source. If you select a clock that isn't valid the micro keeps running without switching the clock.

Just because it is running doesn't necessarily mean it is running on the clock you think you selected.

JC

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

Ahhh, MSP430 style.

That has its upside and downside. Up, you will never be able to "brick" one due to bad oscillator fuse settings. Maybe there are other things one can do to brick one, but not that.

Down, it may not be running at the frequency you think it is. During familiarization, it would be very useful to have a pin toggled at a rate that depends on the CPU clock that can be used to verify the clock frequency (scope, flashing LED, etc).

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

Quote:

it would be very useful to have a pin toggled at a rate that depends on the CPU clock that can be used to verify the clock frequency (scope, flashing LED, etc).

I assume Xmega have a CKOUT pin like modern mega do?

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

Quote:
Down, it may not be running at the frequency you think it is
But if the oscillator ready-flag is set then the oscillator is working (at least for the moment). You can enable XOSC Failure Detection and get an ISR called if there is a clock failure and the clock system is changed back to the reset state.

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

clawson wrote:
I assume Xmega have a CKOUT pin like modern mega do?
Yes, they have several. See my first post in this thread for an example of how to activate one of them.