Fixes to the LM4F clock configuration. Errors in register handling caused everything to run at half speed

This commit is contained in:
Gregory Nutt 2013-04-09 17:27:13 -06:00
parent 7a3cc22417
commit 1ad9b6c565
2 changed files with 45 additions and 23 deletions

View File

@ -475,7 +475,8 @@
#define SYSCON_RCC2_SYSDIV2_SHIFT 23 /* Bits 28-23: System Clock Divisor */ #define SYSCON_RCC2_SYSDIV2_SHIFT 23 /* Bits 28-23: System Clock Divisor */
#define SYSCON_RCC2_SYSDIV2_MASK (0x3f << SYSCON_RCC2_SYSDIV2_SHIFT) #define SYSCON_RCC2_SYSDIV2_MASK (0x3f << SYSCON_RCC2_SYSDIV2_SHIFT)
# define SYSCON_RCC2_SYSDIV(n) ((n-1) << SYSCON_RCC2_SYSDIV2_SHIFT) # define SYSCON_RCC2_SYSDIV(n) ((n-1) << SYSCON_RCC2_SYSDIV2_SHIFT)
#define SYSCON_RCC2_DIV400 (1 << 30) /* Bit 3-: Divide PLL as 400 MHz vs. 200 MHz */ # define SYSCON_RCC2_SYSDIV_DIV400(n) (((n-1) >> 1) << SYSCON_RCC2_SYSDIV2_SHIFT)
#define SYSCON_RCC2_DIV400 (1 << 30) /* Bit 30: Divide PLL as 400 MHz vs. 200 MHz */
#define SYSCON_RCC2_USERCC2 (1 << 31) /* Bit 31: Use RCC2 When set */ #define SYSCON_RCC2_USERCC2 (1 << 31) /* Bit 31: Use RCC2 When set */
/* Main Oscillator Control */ /* Main Oscillator Control */

View File

@ -58,21 +58,24 @@
#ifdef LM4F #ifdef LM4F
# define RCC_OSCMASK (SYSCON_RCC_MOSCDIS) # define RCC_OSCMASK (SYSCON_RCC_MOSCDIS)
#else # define RCC_XTALMASK (SYSCON_RCC_XTAL_MASK | SYSCON_RCC_OSCSRC_MASK | \
# define RCC_OSCMASK (SYSCON_RCC_IOSCDIS|SYSCON_RCC_MOSCDIS)
#endif
#define RCC_XTALMASK (SYSCON_RCC_XTAL_MASK|SYSCON_RCC_OSCSRC_MASK|\
SYSCON_RCC_PWRDN) SYSCON_RCC_PWRDN)
#define RCC2_XTALMASK (SYSCON_RCC2_USERCC2|SYSCON_RCC2_OSCSRC2_MASK|\ # define RCC2_XTALMASK (SYSCON_RCC2_OSCSRC2_MASK | SYSCON_RCC2_PWRDN2 | \
SYSCON_RCC2_PWRDN2) SYSCON_RCC2_SYSDIV2LSB | SYSCON_RCC2_SYSDIV2_MASK | \
#ifdef LM4F SYSCON_RCC2_DIV400 | SYSCON_RCC2_USERCC2)
# define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK|SYSCON_RCC_USESYSDIV|\ # define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK | SYSCON_RCC_USESYSDIV | \
SYSCON_RCC_MOSCDIS) SYSCON_RCC_MOSCDIS)
# define RCC2_DIVMASK (SYSCON_RCC2_SYSDIV2LSB | SYSCON_RCC2_SYSDIV2_MASK)
#else #else
# define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK|SYSCON_RCC_USESYSDIV|\ # define RCC_OSCMASK (SYSCON_RCC_IOSCDIS | SYSCON_RCC_MOSCDIS)
SYSCON_RCC_IOSCDIS|SYSCON_RCC_MOSCDIS) # define RCC_XTALMASK (SYSCON_RCC_XTAL_MASK | SYSCON_RCC_OSCSRC_MASK | \
SYSCON_RCC_PWRDN)
# define RCC2_XTALMASK (SYSCON_RCC2_OSCSRC2_MASK | SYSCON_RCC2_PWRDN2 | \
SYSCON_RCC2_SYSDIV2_MASK | SYSCON_RCC2_USERCC2)
# define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK | SYSCON_RCC_USESYSDIV | \
SYSCON_RCC_IOSCDIS | SYSCON_RCC_MOSCDIS)
# define RCC2_DIVMASK (SYSCON_RCC2_SYSDIV2_MASK)
#endif #endif
#define RCC2_DIVMASK (SYSCON_RCC2_SYSDIV2_MASK)
#define FAST_OSCDELAY (512*1024) #define FAST_OSCDELAY (512*1024)
#define SLOW_OSCDELAY (4*1024) #define SLOW_OSCDELAY (4*1024)
@ -253,16 +256,25 @@ void lm_clockconfig(uint32_t newrcc, uint32_t newrcc2)
putreg32(SYSCON_MISC_PLLLMIS, LM_SYSCON_MISC); putreg32(SYSCON_MISC_PLLLMIS, LM_SYSCON_MISC);
/* Write the new RCC/RCC2 values. Order depends upon whether RCC2 or RCC /* Write the new RCC/RCC2 values.
* is currently enabled. *
* Original LM3S Logic: Order depends upon whether RCC2 or RCC is
* currently enabled.
*
* LM4F120 Data Sheet: "Write the RCC register prior to writing the
* RCC2 register. If a subsequent write to the RCC register is required,
* include another register access after writing the RCC register and
* before writing the RCC2 register.
*/ */
if (rcc2 & SYSCON_RCC2_USERCC2) #ifndef LM4F
if ((rcc2 & SYSCON_RCC2_USERCC2) != 0)
{ {
putreg32(rcc2, LM_SYSCON_RCC2); putreg32(rcc2, LM_SYSCON_RCC2);
putreg32(rcc, LM_SYSCON_RCC); putreg32(rcc, LM_SYSCON_RCC);
} }
else else
#endif
{ {
putreg32(rcc, LM_SYSCON_RCC); putreg32(rcc, LM_SYSCON_RCC);
putreg32(rcc2, LM_SYSCON_RCC2); putreg32(rcc2, LM_SYSCON_RCC2);
@ -294,9 +306,18 @@ void lm_clockconfig(uint32_t newrcc, uint32_t newrcc2)
rcc2 &= ~SYSCON_RCC2_BYPASS2; rcc2 &= ~SYSCON_RCC2_BYPASS2;
} }
/* Now we can set the final RCC/RCC2 values */ /* Now we can set the final RCC/RCC2 values:
*
* LM4F120 Data Sheet: "Write the RCC register prior to writing the
* RCC2 register. If a subsequent write to the RCC register is required,
* include another register access after writing the RCC register and
* before writing the RCC2 register.
*/
putreg32(rcc, LM_SYSCON_RCC); putreg32(rcc, LM_SYSCON_RCC);
#ifdef LM4F
rcc = getreg32(LM_SYSCON_RCC);
#endif
putreg32(rcc2, LM_SYSCON_RCC2); putreg32(rcc2, LM_SYSCON_RCC2);
/* Wait for the system divider to be effective */ /* Wait for the system divider to be effective */