Incorrect Audio PLL Behavior - **FIXED**

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

Incorrect Audio PLL Behavior - **FIXED**

604 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ehughes on Tue Apr 29 04:50:34 MST 2014
I am seeing goofy behavior from the Audio PLL in the LPC4357.

The frac value in the user manual & generated by the pll_dialog tool produce incorrect values.  I first started with NP_DIV & fractional values from page 189,, Rev 1.8 of UM10503.

I am using the Keil MCB4357 Board Library with a 12MHz input clock.  I first tried to get a 12.288Mhz output clock.

Here is the code that sets up the Audio PLL:

//*************************************************************
    audioPLLSetup.ctrl =   (1<<11) //Enable Autoblock
            | (1<<4)  //PLL Clock Enable
 | (1<<12); //Enable Fractional Divider

audioPLLSetup.ndiv = ((3)<<0)   //Pdec
  | ((1)<<12);  //Ndec

audioPLLSetup.frac = 0x1a1cac;


Chip_Clock_SetupPLL(CLKIN_CRYSTAL, CGU_AUDIO_PLL, &audioPLLSetup); 
Chip_Clock_EnablePLL(CGU_AUDIO_PLL);

//*************************************************************

also, in the CLK_BASE_STATES structure, I route the audio PLL output to CGUOUT0

{CLK_BASE_CGU_OUT0, CLKIN_AUDIOPLL, true, false},


This configuration returns a frequency of 15.63Mhz!

So,  I double checked the CGU settings in the debugger and also checked the values again what the PLL_Dialog tool produces.

I tried a could other values for audioPLLSetup.frac and could see the frequency move.   The is a linear relationship between the fracvalue and what I get on the CGUOUT0 pin.

frac value    Measured Frequency
0x1a1cac<<1   31.25MHz
0x1a1cac      15.72MHz
0x1a1cac>>1   7.813MHz

3 other observations:

1.  The Lock bit in the STAT register never goes active (it appears that the signal is stable and is not hunting around).

2.  even though I set the PLLFRACT_REQ in the CTRL register, it appears to always read back as zero in the debugger.

3.)   If I use normal MDEC mode,  the output frequency is at around 60Mhz!   This uses the setting from the PLL dialog tool.

Any pointers?    I can manually find my setpoint by trial and error but I would really like to understand what is happening.
Labels (1)
0 Kudos
1 Reply

413 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ehughes on Sun Aug 23 13:39:06 MST 2015
I wanted to post an update to this issue.      For the longest time I have been using the "hand tuned" PLL value but very uncomfortable with it.   There were some units that came from assembly with wierd issues that were tracked down to the PLL not initializing correctly.    Below is the code that works.

Notes:

1.)   The PLL must be disabled before setting the 1st values.
2.)   After setting it up, it was necessary, to enable disable and re-enable.
3.)  After #2,   I woudl have a look that checks the lock bit and will chip disabling and reenabling the lock bit.     I honestly don't think the lock bit works correctly as the PLL still outputs a correct value (verified with a frequency counter) when the lock bit isn't set
4.)  If the PLL setup is done on the board library, I noticed it would take 3 to 5 retires to get a lock.  If the routine is done a few milliseconds after reset,  it takes fewer resets to get a lock (i.e. but it after main).

void InitAudioPLL()
{
uint8_t LockRetries = 0;

    CGU_USBAUDIO_PLL_SETUP_T audioPLLSetup;

Chip_Clock_DisablePLL(CGU_AUDIO_PLL);

audioPLLSetup.ctrl =   (0x06<<24) //Crystal OSC as input to Audio PLL
| (1<<11) //Enable Autoblock
     | (1<<4) //PLL Clock Enable
| (1<<12); //Enable Fractional Divider

audioPLLSetup.ndiv = ((3)<<0)  //Pdec
   | ((1)<<12);  //Ndec

    audioPLLSetup.fract = 0x1a1cac;

//audioPLLSetup.fract = 1342168; //hand tuned weird value

Chip_Clock_SetupPLL(CLKIN_CRYSTAL, CGU_AUDIO_PLL, &audioPLLSetup); // FIXME

Delay_mS(50);

Chip_Clock_EnablePLL(CGU_AUDIO_PLL);

Delay_mS(50);

while(      LockRetries<5
&& ((Chip_Clock_GetPLLStatus(CGU_AUDIO_PLL) & 0x01) == 0)
)
{
Chip_Clock_DisablePLL(CGU_AUDIO_PLL);

Delay_mS(50);

Chip_Clock_EnablePLL(CGU_AUDIO_PLL);

Delay_mS(50);

if(Chip_Clock_GetPLLStatus(CGU_AUDIO_PLL) &0x01)
{
break;
}
else
{
LockRetries++;
}
}

if(LockRetries >= 5)
{
//Debug Here
}

}