This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

EK-TM4C1294XL: PLL initialization/configuration steps

Part Number: EK-TM4C1294XL
Other Parts Discussed in Thread: TM4C1294NCPDT

Hello,

Seeking clarification about configuring the PLL using MOSC (external 25MHz xtal) to drive the SysClk, and having some doubts about the steps in the datasheet.

In the June 18, 2014 rev. of the TM4C1294NCPDT datasheet, Section 5.3 (pg. 246) PLL configuration, step 4 says to set the OSCSRC field to 0x3 = MOSC in the RSCLKCFG register, but it doesn't say anything about setting the PLLSRC field to MOSC, which seems important for configuring the PLL.  In the TivaWare implementation of SysCtlClockFreqSet(), it sets both OSCSRC and PLLSRC to 0x3 = MOSC, but then it reverts OSCSRC back to use the PIOSC before exiting.  First and second questions are:

Is step 4 correct or should it be saying to set the PLLSRC field to 0x3 instead?  Is there any reason to set both OSCSRC and PLLSRC to MOSC during configuration if your only intention is to enable the PLL to drive SysClk?

The datasheet also doesn't mention about setting the OSCRNG bit in the MOSCTL.  I'm not sure if this is required when using the PLL or OSC (PLL bypassed) or both, but the SysCtlClockFreqSet implementation does set it.  Third question:

Should the OSCRNG be set when using the PLL (frequencies > 10MHz)?

A more trivial quandary is whether steps 7 (write to MEMTIM0) and 8 (wait for PLLSTAT) must be executed in that order.  It seems that MEMTIM0 could be set after the PLL locks, but before MEMTIMU is set (to enable the new EPROM & Flash timings).  So, last question:

Is there some reason to write to MEMTIM0 before the PLL status changes to locked?

I've been able to configure the PLL to drive the SysClk successfully to 120MHz using the code below, leaving OSCSRC = 0x0 PIOSC, and so far everything seems to work OK.  I broke it down into three main steps.  Any feedback/corrections here are appreciated.

//         After power-on reset (POR) the CPU will be using the precision internal
//         oscillator (PIOSC) which runs at 16MHz.  There are three main steps to 
//         initializing/using the PLL:
//            1) Enable the main oscillator (MOSC).
//            2) Configure and enable the PLL.
//            3) Reconfigure SysClk to use the PLL as its source.
//         Each main step has one or more substeps involving direct register access. 
//
void PLL_Init120MHz(void)
{	
	//
	// STEP 1:  Enable the MOSC
	//
	
	// Apply sub-steps 1-3 together to preserve the current MOSCCTL bit values.
	uint32_t mosc = SYSCTL_MOSCCTL_R;
	
	// 1) Power up the MOSC (main oscillator) by clearing the "no crystal" bit.
	// The crystal on the EK-TM4C1294XL board is 25MHz and connected to OSC0 and OSC1.
	mosc &= ~SYSCTL_MOSCCTL_NOXTAL;
	
	// 2) Enable power to the main oscillator by clearing the power down bit.
	mosc &= ~SYSCTL_MOSCCTL_PWRDN;
	
	// 3) Specify high oscillator range (>= 10 MHz).
	// This substep is performed by SysCtlClockFreqSet, which says is to "Increase
	// the drive strength for MOSC of 10MHz and above".  It is not used by Valvano
        // or mentioned in the data sheet configuration.
	mosc |= SYSCTL_MOSCCTL_OSCRNG;
	
	// 3) Set and wait until sufficient time has passed for the MOSC to reach the expected 25MHz frequency
	// of the crystal.  The resulting MOSCCTL value will be 0x10.
	SYSCTL_MOSCCTL_R = mosc;
	
	//This is checking the power up masked interrupt status bit.  
	while((SYSCTL_RIS_R & SYSCTL_RIS_MOSCPUPRIS) == 0) {}
	
	//
        // STEP 2:  Configure and enable the PLL
        //
		
	// 5) Clear and set the PLL input clock source to be the MOSC.
	// It appears that this substep is not mentioned in the data sheet due to a typo (?) which says
        // to set the OSCSRC field instead.  SysCtlClockFreqSet and Valvano both set PLLSRC, 
        // but then they also set OSCSRC as well. SysCtlClockFreqSet restores OSCSRC after
        // enabling the PLL, but Valvano does not.  It seems unnecessary to ever set OSCSRC given
        // that the PLL will not be bypassed (?).  There is no explanation in the datasheet as to why
        // OSCCRC must be configured to use MOSC temporarily while the PLL is being configured, so
        // skipping it here.
	SYSCTL_RSCLKCFG_R  = (SYSCTL_RSCLKCFG_R & ~SYSCTL_RSCLKCFG_PLLSRC_M) | SYSCTL_RSCLKCFG_PLLSRC_MOSC;
						
	// Steps 6-8 are described in the data sheet tables (pgs. 237-238)
	// fin = fxtal / ((Q+1)(N+1))	
	// MDIV = MINT + (MFRAC / 1024)
	// fvco = fin * MDIV
	// SysClk = fvco / (PSYSDIV + 1)
	
	// 6) For fxtal= 25MHz, set Q = 0, N = 4 => fin = 25MHz/((0+1)(4+1)) = 5MHz
	SYSCTL_PLLFREQ1_R = 0x4;

        // 7) Set MFRAC = 0		
	SYSCTL_PLLFREQ0_R &= ~SYSCTL_PLLFREQ0_MFRAC_M;
		
	// 8) Set MINT = 96 = 0x60 => fvco = (5MHz * 96) = 480MHz
	SYSCTL_PLLFREQ0_R = (SYSCTL_PLLFREQ0_R & ~SYSCTL_PLLFREQ0_MINT_M) | 0x60;
		
	// 9) Power up the PLL.  It will take some time to settle and lock the requested frequency.
	SYSCTL_PLLFREQ0_R |= SYSCTL_PLLFREQ0_PLLPWR;	

	// 10) Wait until the PLL is powered and locked.
	while ((SYSCTL_PLLSTAT_R & SYSCTL_PLLSTAT_LOCK) == 0) {}
	
        //
        // STEP 3:  Reconfigure SysClk to use the PLL.  
        //
		
        // 11) Set the timing parameters for the main Flash and EEPROM memories.
        // These settings will take effect once the MEMTIMU bit is set below.
	// Therefore, clear the relevant field bits making sure to leave the reserved bits unchanged.
	// For CPU frequency 100MHz < f <= 120MHz:
	//  EBCHT = FBCHT = 0x6
	//  EBCE = FBCE = 0
	//  FWS = EWS = 0x5;
	// Since the reserved bits 20 and 4 are showing 0x1, the resulting MEMTIM0 value should be:  0x01950195
	uint32_t memtim0 = SYSCTL_MEMTIM0_R;
	memtim0 &= ~(SYSCTL_MEMTIM0_EBCHT_M | SYSCTL_MEMTIM0_EBCE | SYSCTL_MEMTIM0_EWS_M | 
                                SYSCTL_MEMTIM0_FBCHT_M | SYSCTL_MEMTIM0_FBCE | SYSCTL_MEMTIM0_FWS_M);
	memtim0 |= (SYSCTL_MEMTIM0_EBCHT_3_5 | SYSCTL_MEMTIM0_FBCHT_3_5 | (0x5 << SYSCTL_MEMTIM0_EWS_S) |  0x5);
	SYSCTL_MEMTIM0_R = memtim0;
										 	
	// Apply steps 12-14 together.
	uint32_t rsclkcfg = SYSCTL_RSCLKCFG_R;
	
	// 12) Set the PLL System Clock divisor = 3 => SysClk = 480MHz / (1+3) = 120MHz.
	rsclkcfg = (rsclkcfg & ~SYSCTL_RSCLKCFG_PSYSDIV_M) | 0x3;		
		
	// 13) Use PLL as the system clock source
	rsclkcfg |= SYSCTL_RSCLKCFG_USEPLL;
		
	// 14) Apply the MEMTIMU register value and upate the memory timings set in MEMTIM0.
	rsclkcfg |= SYSCTL_RSCLKCFG_MEMTIMU;		
		
	SYSCTL_RSCLKCFG_R = rsclkcfg;
			
}

Thanks!

  • Hello j spicer,

    j spicer said:
    Is step 4 correct or should it be saying to set the PLLSRC field to 0x3 instead?  Is there any reason to set both OSCSRC and PLLSRC to MOSC during configuration if your only intention is to enable the PLL to drive SysClk?

    The document does seem to miss a step regarding the PLLSRC requirements for driving the PLL from MOSC. If you look at Table 5-3, it clearly states PLLSRC needs to be set to 0x3 when driving the PLL from MOSC.

    j spicer said:

    The datasheet also doesn't mention about setting the OSCRNG bit in the MOSCTL.  I'm not sure if this is required when using the PLL or OSC (PLL bypassed) or both, but the SysCtlClockFreqSet implementation does set it.  Third question:

    Should the OSCRNG be set when using the PLL (frequencies > 10MHz)?

    The OSCRNG for MOSC is dependent on the external crystal used with the device. As low as 5MHz can be used, in which case the OSCRNG bit should not be set. When any crystal greater than 10MHz is used, then the OSCRNG bit should be set. I believe as the PLL operates with an input crystal as low as 5 MHz, this step was not mentioned as there are cases it doesn't apply, though it would have been good to note it as a system specific step.

    j spicer said:

    A more trivial quandary is whether steps 7 (write to MEMTIM0) and 8 (wait for PLLSTAT) must be executed in that order.  It seems that MEMTIM0 could be set after the PLL locks, but before MEMTIMU is set (to enable the new EPROM & Flash timings).  So, last question:

    Is there some reason to write to MEMTIM0 before the PLL status changes to locked?

    From what I am seeing, I think you can change that order without issue, but I did not write the code for SysCtlClockFreqSet so I can't say with 100% certainty.

    j spicer said:
    I've been able to configure the PLL to drive the SysClk successfully to 120MHz using the code below, leaving OSCSRC = 0x0 PIOSC, and so far everything seems to work OK.  I broke it down into three main steps.  Any feedback/corrections here are appreciated.

    I don't understand why you would go through the effort to remake a function that TivaWare already handles. In any case, it is not something we will review. The TivaWare implementation is well tested by hundreds of customers and so our efforts are towards supporting TivaWare APIs which are well tested and proven. This is stated in our Forum Guidelines, Point #4: e2e.ti.com/.../695568

  • Hello Ralph!

    The document does seem to miss a step regarding the PLLSRC requirements for driving the PLL from MOSC. If you look at Table 5-3, it clearly states PLLSRC needs to be set to 0x3 when driving the PLL from MOSC.

    Is it that the document misses a step or has a mistyped a step?  My second question was whether both OSCSCR and PLLSRC must be set, in which case there's a missed step concerning setting PLLSRC.  On the other hand, if OSCSRC does not need to be set while configuring the PLL, then it appears to be a typo only, and "OSCSCR" should be replaced with "PLLSRC".

    The OSCRNG for MOSC is dependent on the external crystal used with the device.

    Thanks!  It wasn't clear that the > 10 MHz frequency referred to the crystal, but that corroborates with what SysCtlClockFreqSet is checking before setting.

    From what I am seeing, I think you can change that order without issue...

    It seemed reasonable IMO as well.  Thanks for confirming, and understood this may not be 100%.

     

       

  • Hello J Spicer,

    Thanks for the follow-up question. The answer isn't exactly straightforward actually. Based on the intended device operation, the document 'misses a step' in terms of the PLLSRC setting.

    However, as you noted, the OSCSRC gets set to the PIOSC at the end of the SysCtlClockFreqSet, so it would seem like OSCSRC was just a typo, right? Well, the reason OSCSRC is set to PIOSC is actually due to an errata item, SYSCTL#23 which is documented here: www.ti.com/.../spmz850g.pdf

    As a result of SYSCTL#23, the setting for OSCSRC at the end of clock configuration is to set the OSCCLK to take PIOSC instead of MOSC. So the datasheet directive RE: OSCSRC wouldn't be an issue if the errata item did not exist.
  • Hello Ralph,

    I was thinking that it might be a typo because the steps in Section 5.3 (pg 246) are explicitly about configuring the PLL for SYSCLK after POR.  If the intention is to use the PLL, then why change OSCSRC at all?  It already defaults to PIOSC, and if you won't be using it, why change it?  I'm basing this also on the Clock Tree of Figure 5-5, in which SYSCLK appears to be driven exclusively by either OSCCLK or VCO, depending on the setting of USEPLL. 

    Errata #23 seems to be confirming the same:

    In TivaWare 2.1.2 or earlier, the SysCtlClockFreqSet sets the PLL source as MOSC when the API is called with the parameter SYSCTL_OSC_MAIN. It sets the OSCCLK as MOSC which is not required and may cause this issue.

    My interpretation of SysCtlClockFreqSet was that it is setting OSCSRC to MOSC as a fallback position, e.g. in case the PLL option wasn't chosen or it failed to lock  In that case, you'd end up with SysClk driven by the main oscillator via OSCCLK.  But then restoring to PIOSC at the end made no sense, until now.

    For me anyway, the key words from the Errata are "not required" for PLL, which is why I've left out setting OSCSRC in my revised steps, in spite of what Step 4 and SysCtlClockFreqSet say, because it just doesn't seem necessary.

  • Hello j spicer,

    I don't disagree with your train of thought, but unfortunately I was not around when the SysCtlClockFreqSet API was written or modified for the errata item, so I don't know exactly why that step was taken. It could well be have done because the DS never should have instructed as such.

    At this point of time, since the API is used with no issues for hundreds customers who have a wide array of use cases, systems, and operating environments, we are not going to investigate any modifications to SysCtlClockFreqSet and risk potential unforeseen issues arising. As the old saying goes, 'If it ain't broke, don't fix it'.
  • Hello Ralph,

    I don't think you should modify SysCtlClockFreqSet either, but you ought to at least put some investigation into why the datasheet says to set OSCSRC to MOSC in a section on initialization/configuration of the PLL. If that information is incorrect and the SysCtlClockFreqSet programmer followed it in the past (as others have and still will), it could be the reason why the function was broken and had to be issued the previous errata. In any case, it's disappointing not to get a definitive answer about OSCSRC <-MOSC here, but I do understand that this forum's focus is on the TivaWare API, and I appreciate your time and support. Thanks!

    Regards,
    jspicer