ATXMEGA selecting internal clock source

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

Just started using ATXMEGA A1 128 and I am trying to turn on the internal 32MHZ clock. Runs with default 2MHZ fine, but when I try...

OSC.CTRL = 0b00000001; // 32 mhz internal

The processor does not kick in to 32MHZ. Is there another step that has to be done? Thanks

I tried the CCP = 0xD8 before the OSC.CTRL with no luck.

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

Here's a function I use to set up (and calibrate) the clocks on the ATxmega128A1 - produced using CodeVision and compiles on AVR Studio:

(You can remove the code for the 2MHz internal and external oscillators if you plan on just using the 32MHz clock)

Good luck!

// Define CPU clock frequency (if not already defined)
#ifndef F_CPU
	// Enable/Disable internal oscillators
	//#define F_CPU 2000000
	#define F_CPU 32000000
	// Enable/Disable external 14.7456 MHz oscillator
	//#define F_CPU 14745600
#endif

void system_clocks_init(void);
// System Clocks initialization
void system_clocks_init(void)
{
	unsigned char n,s;
	// Save interrupts enabled/disabled state
	s=SREG;
	// Disable interrupts
	asm("cli");

	#if F_CPU==14745600
	// External 14745.600 kHz oscillator initialization
	OSC.XOSCCTRL=OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;
	// Enable the external oscillator
	OSC.CTRL|=OSC_XOSCEN_bm;

	// System clock prescaler A division factor: 1
	// System clock prescalers B & C division factors: B:1, C:1
	// ClkPer4: 14745.600 kHz
	// ClkPer2: 14745.600 kHz
	// ClkPer:  14745.600 kHz
	// ClkCPU:  14745.600 kHz
	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 the system clock source: External Osc. or Clock
	n=(CLK.CTRL & (~CLK_SCLKSEL_gm)) | CLK_SCLKSEL_XOSC_gc;
	CCP=CCP_IOREG_gc;
	CLK.CTRL=n;

	// Disable the unused oscillators: 2 MHz, 32 MHz, internal 32 kHz, PLL
	OSC.CTRL&= ~(OSC_RC2MEN_bm | OSC_RC32MEN_bm | OSC_RC32KEN_bm | OSC_PLLEN_bm);

	// Peripheral Clock output: Disabled
	PORTCFG.CLKEVOUT=(PORTCFG.CLKEVOUT & (~PORTCFG_CLKOUT_gm)) | PORTCFG_CLKOUT_OFF_gc;

	#elif F_CPU==32000000
	// Internal 32 kHz RC oscillator initialization
	// Enable the internal 32 kHz RC oscillator
	OSC.CTRL|=OSC_RC32KEN_bm;
	// Wait for the internal 32 kHz RC oscillator to stabilize
	while ((OSC.STATUS & OSC_RC32KRDY_bm)==0);

	// Internal 32 MHz RC oscillator initialization
	// Enable the internal 32 MHz RC oscillator
	OSC.CTRL|=OSC_RC32MEN_bm;

	// System clock prescaler A division factor: 1
	// System clock prescalers B & C division factors: B:1, C:1
	// ClkPer4: 32000.000 kHz
	// ClkPer2: 32000.000 kHz
	// ClkPer:  32000.000 kHz
	// ClkCPU:  32000.000 kHz
	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;

	// Internal 32 MHz RC osc. calibration reference clock source: 32.768 kHz Internal Osc.
	OSC.DFLLCTRL&= ~(OSC_RC32MCREF_bm | OSC_RC2MCREF_bm);
	// Enable the autocalibration of the internal 32 MHz RC oscillator
	DFLLRC32M.CTRL|=DFLL_ENABLE_bm;

	// Wait for the internal 32 MHz RC oscillator to stabilize
	while ((OSC.STATUS & OSC_RC32MRDY_bm)==0);

	// Select the system clock source: 32 MHz Internal RC Osc.
	n=(CLK.CTRL & (~CLK_SCLKSEL_gm)) | CLK_SCLKSEL_RC32M_gc;
	CCP=CCP_IOREG_gc;
	CLK.CTRL=n;

	// Disable the unused oscillators: 2 MHz, external clock/crystal oscillator, PLL
	OSC.CTRL&= ~(OSC_RC2MEN_bm | OSC_XOSCEN_bm | OSC_PLLEN_bm);

	// Peripheral Clock output: Disabled
	PORTCFG.CLKEVOUT=(PORTCFG.CLKEVOUT & (~PORTCFG_CLKOUT_gm)) | PORTCFG_CLKOUT_OFF_gc;
	
	#elif F_CPU==2000000
	// Internal 32 kHz RC oscillator initialization
	// Enable the internal 32 kHz RC oscillator
	OSC.CTRL|=OSC_RC32KEN_bm;
	// Wait for the internal 32 kHz RC oscillator to stabilize
	while ((OSC.STATUS & OSC_RC32KRDY_bm)==0);

	// Internal 2 MHz RC oscillator initialization
	// Enable the internal 2 MHz RC oscillator
	OSC.CTRL|=OSC_RC2MEN_bm;

	// System clock prescaler A division factor: 1
	// System clock prescalers B & C division factors: B:1, C:1
	// ClkPer4: 2000.000 kHz
	// ClkPer2: 2000.000 kHz
	// ClkPer:  2000.000 kHz
	// ClkCPU:  2000.000 kHz
	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;

	// Internal 2 MHz RC osc. calibration reference clock source: 32.768 kHz Internal Osc.
	OSC.DFLLCTRL&= ~(OSC_RC32MCREF_bm | OSC_RC2MCREF_bm);
	// Enable the autocalibration of the internal 2 MHz RC oscillator
	DFLLRC2M.CTRL|=DFLL_ENABLE_bm;

	// Wait for the internal 2 MHz RC oscillator to stabilize
	while ((OSC.STATUS & OSC_RC2MRDY_bm)==0);

	// Select the system clock source: 2 MHz Internal RC Osc.
	n=(CLK.CTRL & (~CLK_SCLKSEL_gm)) | CLK_SCLKSEL_RC2M_gc;
	CCP=CCP_IOREG_gc;
	CLK.CTRL=n;

	// Disable the unused oscillators: 32 MHz, external clock/crystal oscillator, PLL
	OSC.CTRL&= ~(OSC_RC32MEN_bm | OSC_XOSCEN_bm | OSC_PLLEN_bm);

	// Peripheral Clock output: Disabled
	PORTCFG.CLKEVOUT=(PORTCFG.CLKEVOUT & (~PORTCFG_CLKOUT_gm)) | PORTCFG_CLKOUT_OFF_gc;
	#endif

	// Restore interrupts enabled/disabled state
	SREG=s;
} // system_clocks_init()
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After Reset,you can simply use:

OSC.CTRL|=OSC_RC32MEN_bm;
while (!(OSC.STATUS & OSC_RC32MRDY_bm));
CCP=CCP_IOREG_gc;
CLK.CTRL=CLK_SCLKSEL_RC32M_gc;
// If you want to disable RC2M
OSC.CTRL&=(~OSC_RC2MEN_bm);

Ozhan KD
Knowledge is POWER

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

Careful with the DFLL. Like many things it is broken on the 128A1. The errata section in the datasheet list a workaround.

Stealing Proteus doesn't make you an engineer.

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

Did anyone find a solution to this? I am using the atxmegaA3 256 and 128 with code similar to that proposed above by electronic.designer. when I started using studio 5 i can no longer select the 32mhz clock. suggestions? I am currently downloading studio 5 v2.

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

Don't waste time with AS5 if you are trying to do real work. Stick with AS4 until they finish AS5.

(I'll move this thread to the Xmega forum).

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

Welcome to the forum.

My code is similar to the above, just a different language:

Clockopt5:
   'Set up the Xmega Clock. Works.
   'Run at 32 MHz from the Internal 32 MHz Osc.
   'Xmega runs on Int 2MHz Osc on Startup.
   'This turns on the Int 32 MHz Osc, awaits it being ready, and switches to it.
   'Don't forget the Configuration Change Register Protection Trigger before
   'changing the uC's Clock Source.
   'First turn ON the 32 MHz Int Osc:
   'They wait until the Int 32 MHz Osc is ready to be used.
   Osc_ctrl = 2                                             'Int 32 MHz Osc ON
   Rvbit = 0                                                'Clear flag
   While Rvbit = 0
      'Read the Int 32 MHz Osc Status
      Regdata = Osc_status                                  'Status of all Int Osc Sources
      Rvbit = Regdata.1                                     'Int 32 MHz Osc Status, 1 = Ready
   Wend
   Cpu_ccp = 216                                            'Config Change Protection
   Clk_ctrl = 1                                             'Use Int 32 MHz Osc
   Return

JC

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

ok, thanks for the comments, back to as4