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!