Skip to content
Snippets Groups Projects
Commit f01b7e15 authored by Gregory Nutt's avatar Gregory Nutt
Browse files

Fixes to the LM4F clock configuration. Errors in register handling caused...

Fixes to the LM4F clock configuration.  Errors in register handling caused everything to run at half speed
parent f8675d96
No related branches found
No related tags found
No related merge requests found
...@@ -4532,3 +4532,7 @@ ...@@ -4532,3 +4532,7 @@
leaving the interrupts in a strange state (2013-4-7). leaving the interrupts in a strange state (2013-4-7).
* arch/arm/src/lpc17_lcd.c: Rommel Marcelo go the LPC1788 * arch/arm/src/lpc17_lcd.c: Rommel Marcelo go the LPC1788
framebuffer-based LCD working. Very nice! (2013-4-08). framebuffer-based LCD working. Very nice! (2013-4-08).
* arch/arm/src/lm/lm_clockconfig.c and configs/lm4f120-launchpad:
Fix handling of the RCC SYSDIV2 field whent the PLL output is
400MHz. Don't forget to set the USERCC2 bit in the register or
all is for naught (2013-4-09).
...@@ -475,7 +475,8 @@ ...@@ -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 */
......
...@@ -57,26 +57,29 @@ ...@@ -57,26 +57,29 @@
****************************************************************************/ ****************************************************************************/
#ifdef LM4F #ifdef LM4F
# define RCC_OSCMASK (SYSCON_RCC_MOSCDIS) # define RCC_OSCMASK (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_SYSDIV2LSB | SYSCON_RCC2_SYSDIV2_MASK | \
SYSCON_RCC2_DIV400 | SYSCON_RCC2_USERCC2)
# define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK | SYSCON_RCC_USESYSDIV | \
SYSCON_RCC_MOSCDIS)
# define RCC2_DIVMASK (SYSCON_RCC2_SYSDIV2LSB | SYSCON_RCC2_SYSDIV2_MASK)
#else #else
# define RCC_OSCMASK (SYSCON_RCC_IOSCDIS|SYSCON_RCC_MOSCDIS) # define RCC_OSCMASK (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 RCC_XTALMASK (SYSCON_RCC_XTAL_MASK|SYSCON_RCC_OSCSRC_MASK|\
SYSCON_RCC_PWRDN)
#define RCC2_XTALMASK (SYSCON_RCC2_USERCC2|SYSCON_RCC2_OSCSRC2_MASK|\
SYSCON_RCC2_PWRDN2)
#ifdef LM4F
# define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK|SYSCON_RCC_USESYSDIV|\
SYSCON_RCC_MOSCDIS)
#else
# define RCC_DIVMASK (SYSCON_RCC_SYSDIV_MASK|SYSCON_RCC_USESYSDIV|\
SYSCON_RCC_IOSCDIS|SYSCON_RCC_MOSCDIS)
#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)
#define PLLLOCK_DELAY (32*1024) #define PLLLOCK_DELAY (32*1024)
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
...@@ -253,16 +256,25 @@ void lm_clockconfig(uint32_t newrcc, uint32_t newrcc2) ...@@ -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) ...@@ -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 */
......
...@@ -77,16 +77,36 @@ ...@@ -77,16 +77,36 @@
* - No auto-clock gating reset * - No auto-clock gating reset
*/ */
#define LM_RCC_VALUE (SYSCON_RCC_OSCSRC | SYSCON_RCC_XTAL | SYSCON_RCC_USESYSDIV | SYSCON_RCC_SYSDIV(LM_SYSDIV)) #define LM_RCC_VALUE (SYSCON_RCC_OSCSRC | SYSCON_RCC_XTAL | \
SYSCON_RCC_USESYSDIV | SYSCON_RCC_SYSDIV(LM_SYSDIV))
/* RCC2 settings -- RCC2 not used. Other RCC2 settings /* RCC2 settings
* *
* - PLL and sys dividers not bypassed. * - PLL and sys dividers not bypassed.
* - PLL not powered down * - PLL not powered down
* - Not using RCC2 * - Not using RCC2
*
* When SYSCON_RCC2_DIV400 is not selected, SYSDIV2 is the divisor-1.
* When SYSCON_RCC2_DIV400 is selected, SYSDIV2 is the divisor-1)/2, plus
* the LSB:
*
* SYSDIV2 SYSDIV2LSB DIVISOR
* 0 N/A 2
* 1 0 3
* " 1 4
* 2 0 5
* " 1 6
* etc.
*/ */
#define LM_RCC2_VALUE (SYSCON_RCC2_OSCSRC | SYSCON_RCC2_SYSDIV(LM_SYSDIV) | SYSCON_RCC2_DIV400) #if (LM_SYSDIV & 1) == 0
# define LM_RCC2_VALUE (SYSCON_RCC2_OSCSRC | SYSCON_RCC2_SYSDIV2LSB | \
SYSCON_RCC2_SYSDIV_DIV400(LM_SYSDIV) | \
SYSCON_RCC2_DIV400 | SYSCON_RCC2_USERCC2)
#else
# define LM_RCC2_VALUE (SYSCON_RCC2_OSCSRC | SYSCON_RCC2_SYSDIV_DIV400(LM_SYSDIV) | \
SYSCON_RCC2_DIV400 | SYSCON_RCC2_USERCC2)
#endif
/* LED definitions ******************************************************************/ /* LED definitions ******************************************************************/
/* The LM4F120 LaunchPad has a single RGB LED. There is only one visible LED which /* The LM4F120 LaunchPad has a single RGB LED. There is only one visible LED which
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment