MCUinit.c: Wait until PLL is locked...

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MCUinit.c: Wait until PLL is locked...

1,626 Views
dougpaulsen
Contributor IV

Greetings: 

 

We have a MCF51AC256AC based project which is exhibiting a disconcerting tendency to fail to achieve PLL lock.

 

This is a Codewarrior 6.3 project and uses the Device Initialization feature to create a MCUinit.c file.  When starting up, MCU_init() executes but has a tendency to not a execute beyond the while(!MCGSC_LOCK) at the end of this code snippet:

  /*  System clock initialization */

  if (*(unsigned char*far)65470 != 255) { /* Test if the device trim value is stored on the specified address */

    MCGTRM = *(unsigned char*far)65470; /* Initialize MCGTRM register from a non volatile memory */

    MCGSC = *(unsigned char*far)1022;  /* Initialize MCGSC register from a non volatile memory */

  }

  /* MCGC2: BDIV=0,RANGE=1,HGO=1,LP=0,EREFS=1,ERCLKEN=1,EREFSTEN=0 */

  MCGC2 = 54;                          /* Set MCGC2 register */

  /* MCGC3: DIV32=1 */

  MCGC3 |= (unsigned char)16;                     

  /* MCGC1: CLKS=2,RDIV=2,IREFS=0,IRCLKEN=0,IREFSTEN=0 */

  MCGC1 = 144;                         /* Set MCGC1 register */

  /* MCGC3: LOLIE=0,PLLS=0,CME=0,DIV32=1,VDIV=8 */

  MCGC3 = 24;                          /* Set MCGC3 register */

  /* MCGC4: DMX32=0,DRST_DRS=0 */

  MCGC4 = 0;                           /* Set MCGC4 register */

  while(!MCGSC_OSCINIT) {              /* Wait until external reference is stable */

   SRS = 0;                            /* Reset watchdog counter */

  }

  while(MCGSC_IREFST) {                /* Wait until external reference is selected */

   SRS = 0;                            /* Reset watchdog counter */

  }

  while((MCGSC & 12) != 8) {           /* Wait until external clock is selected as a bus clock reference */

   SRS = 0;                            /* Reset watchdog counter */

  }

  /* MCGC2: BDIV=0,RANGE=1,HGO=1,LP=1,EREFS=1,ERCLKEN=1,EREFSTEN=0 */

  MCGC2 = 62;                          /* Set MCGC2 register */

  /* MCGC1: CLKS=2,RDIV=3,IREFS=0,IRCLKEN=0,IREFSTEN=0 */

  MCGC1 = 152;                         /* Set MCGC1 register */

  /* MCGC3: LOLIE=0,PLLS=0,CME=0,DIV32=0,VDIV=8 */

  MCGC3 = 8;                           /* Set MCGC3 register */

  /* MCGC3: LOLIE=0,PLLS=1,CME=0,DIV32=0,VDIV=8 */

  MCGC3 = 72;                          /* Set MCGC3 register */

  while(!MCGSC_PLLST) {                /* Wait until PLL is selected */

   SRS = 0;                            /* Reset watchdog counter */

  }

  /* MCGC2: LP=0 */

  MCGC2 &= (unsigned char)~8;                    

  while(!MCGSC_LOCK) {                 /* Wait until PLL is locked */

   SRS = 0;                            /* Reset watchdog counter */

  }

 

To decode the above, the project is defined with an external 9.8304 MHz CPU clock.  PLL mode PEE is selected with a reference clock divider auto selecting to 8 and the PLL multiplier factor auto selecting to 32.  This yields a 39.3216 MHz PLL output clock frequency and ultimately a 19.660 MHz internal bus frequency.  Why so fast?  Well, this yields a critical 4.9 MHz PWM output which in turn clocks a peripheral chip.

 

I have observed the occasional "while(!MCGSC_LOCK)" wait during development, which I had (hopefully) attributed to prototype hardware and/or BDM debugger interaction.  Most distressingly, the PLL lock wait continues to appear now the project is in its free standing phase running on production hardware.

 

Any ideas why PLL lock seems to be difficult to achieve?  This project a next generation based on a HCS08 project where the identical setup has been used without issue.  Of course this is different hardware.

In the course of power consumption testing, we did find the power consumption of the MCF51AC256 goes way, way up when running in PLL mode (a point not identified in the documentation, so beware!).  Are there other drawbacks to PLL mode use in this chip?

 

Thanks for any thoughts or suggestions,

Doug

Labels (1)
Tags (5)
0 Kudos
1 Reply

862 Views
TomE
Specialist II

Nothing obviously wrong. You're dividing the 9.8304MHz by 8 to get "between 1 and 2 MHz" like the Data Sheet says. You're below the maximum PLL frequency.

I'd suggest you search this forum for "MCGSC_LOCK" and see if any of the 25 or so matches helps at all. You may find other examples of initialisation code to compare with yours.

Type "MCGSC_LOCK" into Google and look at every other example of initialisation code you can find, to see if anyone is doing anything different in terms of register setting or sequencing. Ones like this:

http://www.68hc08.net/modules/newbb/viewtopic.php?topic_id=1321

You might try to "wander" through the MCG Mode State Diagram a bit more to see if it affects anything. You can only get to PEE from PBE, but visiting FBE or BPLE might have an effect.

Can you try locking to different (lower) frequencies and see if that is more reliable? Characterising the problem (like "works below /20, fails above /44, intermittent between) might help with the diagnosis. You might be able to get a lock on a lower MGC-PLL[VDIV] value like the default of "1", and then increment it up to your final value. That might maintain lock between the increasing frequency steps better then jumping from "/1" to "/32" in one go. That might even work as a permanent solution.

> we did find the power consumption of the MCF51AC256 goes way, way up when running in PLL mode (a point not identified in the documentation, so beware!)

Do you have numbers? How many milliamps is it drawing?

The Data Sheet '2.6 Supply Current Characteristics" section only details FEI, FBE, WAIT and STOP mode currents. You should try measuring the current with the PLL enabled and disabled while running in a non PEE mode to see what the PLL hardware takes.

You should also extrapolate for 20MHz from the "Figure 9. Typical Run IDD vs. System Clock Freq. for FEI and FBE Modes" diagram which would predict something near 20mA. CPU power is normally linear with frequency. If you need to reduce the power in your application, make sure you "WAIT" the CPU when there's nothing to do and it can wait for a peripheral or timer interrupt. From the Data Sheet, WAIT at 16MHz should drop from 15mA to 5mA. You don't want it wasting electrons running full speed in a polling loop waiting for something to happen.


Tom

0 Kudos