XMega32a4u - use 2MHz internal oscillator & PLL to generate 8MHz clock

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

Hi, we are trying to run the XMEGa32A4u with an internal 8MHz clock.

 

Here is the code below. This does not run for some reason. We would put the AVR ICE on to test, but there is no timing or stopwatch so it is hard to see how that would help. Any help would be much appreciated. Thanks

 

#define RCOSC2M 0
#define RCOSC2MA 1

void set_8MHz_osc(void)
{
i_union cal;

    CPU.CCP=0xD8;    // Enable the clock source
    OSC.XOSCCTRL = 0x67; // enable 14MHz, 32kHz low power

    CPU.CCP=0xD8;   // Enable the clock source
    OSC.CTRL = OSC_PLLEN_bm | OSC_RC2MEN_bm; // PLLEN and RC2MEN
    while ((OSC.STATUS & (OSC_PLLEN_bm | OSC_RC2MEN_bm))!=(OSC_PLLEN_bm | OSC_RC2MEN_bm)) {} // wait for it to become stable

    CPU.CCP=0xD8;    // Enable the clock source
    OSC.PLLCTRL = 4; // 2MHzx4
    while ((OSC.STATUS & (OSC_PLLEN_bm | OSC_RC2MEN_bm))!=(OSC_PLLEN_bm | OSC_RC2MEN_bm)) {} // wait for it to become stable

    CPU.CCP=0xD8;
    CLK.CTRL = 0x04; // PLL is clock source now
    while ((OSC.STATUS & (OSC_PLLEN_bm | OSC_RC2MEN_bm))!=(OSC_PLLEN_bm | OSC_RC2MEN_bm)) {} // wait for it to become stable

    DFLLRC2M.CTRL = 1;

   	cal.b[0] = ReadSignatureByte(RCOSC2M);
	cal.b[1] = ReadSignatureByte(RCOSC2MA);
	/*
	* If a device has an uncalibrated value in the
	* production signature row (early sample part), load a
	* sane default calibration value.
	*/
	if (cal.u == 0xFFFF) {
		cal.u = 0x2340;
	}
//	osc_user_calibration(OSC_ID_RC2MHZ,cal);
    DFLLRC2M.CALA=cal.b[1];
	DFLLRC2M.CALB=cal.b[0];
}

 

Electronic System Design
http://www.esdn.com.au

Last Edited: Thu. Aug 17, 2017 - 12:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is what I have for the Xmega32E5 for 4MHz, I guess it should work for 8MHz if the last line is changed to divide by 2

 

// Set clock to 4 MHz
	OSC_PLLCTRL = 8;			// PLL mult. factor ( 2MHz x8 ) and set clock source to PLL
	OSC_CTRL = (1<<OSC_PLLEN_bp);		// Enable PLL

	while (!(OSC_STATUS & (1<<OSC_PLLRDY_bp)));

	CPU_CCP = CCP_IOREG_gc;			// Unlock sequence to access CLK_CTRL
	CLK_CTRL = CLK_SCLKSEL_PLL_gc;		// Select PLL as system clock 
	
	CPU_CCP=CCP_IOREG_gc;			// Unlock sequence to access CLK_CTRL
	CLK_PSCTRL = ( 1<<CLK_PSADIV1_bp |  1<<CLK_PSADIV0_bp);	//Divide by 4

 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

 

I've read that there is a minimum frequency for the PLL.  8 MHz may be too low.  I don't see anything in my manual but there are a few posts on avrfreaks.  Apparently some chips will do the 8MHz thing and others will fail.

 

You could try 16 MHz and then divide by 2.  The 32 MHz rc osc. divided by 4 could work.  I've read it takes less power than the PLL, important if it's battery powered.

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

You could try 16 MHz and then divide by 2

Which is what I said above??  wink

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

You shouldn't post 5 minutes before I do.  Bad forum etiquette.  wink  Actually I saw another post of yours on the subject.  Rather than give you credit, I thought I would try to look smart.  Didn't work.

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

Did not you notice that the data sheet specifies that the oscillation frequency should be 20 MHz or more?

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

Thanks John and Steve. It seems to work now. I think the problem was setting the PLL bits after the PLL was turned on. Below is the final code.

 

kabasan, can you point out which page in the data sheet says that the PLL should not be set to 8MHz? We did notice on p82/478 that it said PLL 20 - 128MHz output frequency but we can see no warnings otherwise. Thanks

void set_8MHz_osc(void)
{
i_union cal;

    CPU.CCP=CCP_IOREG_gc;    // 0xd8 Enable the clock source
    OSC.XOSCCTRL = 0x67; // enable 14MHz, 32kHz low power

     OSC.PLLCTRL = 0x4; // 2MHzx8=16Mhz
//   CPU.CCP=CCP_IOREG_gc;   // 0xd8 Enable the clock source
    OSC.CTRL = OSC_PLLEN_bm; // PLLEN and RC2MEN
    while ((OSC.STATUS & (OSC_PLLEN_bm ))!=(OSC_PLLEN_bm)) {} // wait for it to become stable

  //  CPU.CCP=CCP_IOREG_gc;    // 0xd8 Enable the clock source
   // while ((OSC.STATUS & OSC_PLLEN_bm)!=OSC_PLLEN_bm)  {} // wait for it to become stable

    CPU.CCP=CCP_IOREG_gc; //0xd8
    CLK.CTRL = CLK_SCLKSEL_PLL_gc; // PLL is clock source now
 //   while ((OSC.STATUS & (OSC_PLLEN_bm | OSC_RC2MEN_bm))!=(OSC_PLLEN_bm | OSC_RC2MEN_bm)) {} // wait for it to become stable

  //	CPU_CCP=CCP_IOREG_gc;			// Unlock sequence to access CLK_CTRL

 

Electronic System Design
http://www.esdn.com.au

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

If you are a project that ends on your own, it is free to ignore p107 of this document.

 

http://www.atmel.com/images/Atme...

 

 

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

By the way, are not you dissatisfied with RC32MHz divided by 4?

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

Great, thanks Kabasan. The reason to run using the 2MHz Oscillator and then X4 to get 8MHz is to reduce the current. We are using 32 boards each with its own XMega32A4U on it so a 5mA difference will become 160mA from the main power supply.

 

I will test running at 32MHz/4 and will use this if there is no increase in current. Thanks again for your help, and also to John and Steve.

Electronic System Design
http://www.esdn.com.au

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

You can either use RC2M and multiply by 4 with the PLL to get 8MHz

Or use RC32M and divide by 4 to get 8MHz

 

I think you will find the oscillators take a similar current.    It is the core running at 8MHz that takes most current.

So whichever clock method you use,  you still want to run for a short time and go to sleep whenever you can.

 

Likewise,  you only enable ports and peripherals as necessary.

If you are stopping and starting clocks frequently,  your app might be happier with 32MHz div4.

 

David.

Last Edited: Thu. Aug 17, 2017 - 08:35 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks David. I tried using the 32MHz oscilator using OSC.PLLCTRL = 0x81; but that did not work.

 

Multiplying the 2MHz x16 and then dividing by 4 showed that the current rose from 16.7 to 16.9mA, as you said not much difference. Thanks

Electronic System Design
http://www.esdn.com.au

Last Edited: Fri. Aug 18, 2017 - 02:22 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I tried using the 32MHz oscilator using OSC.PLLCTRL = 0x81; but that did not work.

 

Why use the PLL at all?  Select the RC32M as the clock source and divide that by four via the prescaler.

Greg Muth

Portland, OR, US

Xplained Boards mostly

Atmel Studio 7.0 on Windows 10

 

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

Good idea. That works. 16.7mA current drain again.

Electronic System Design
http://www.esdn.com.au