summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-04-09 17:27:13 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-04-09 17:27:13 -0600
commit537b5d71a46815412445398bd65195cb94d9434c (patch)
tree4ee43a0f5e49f7be6bf091f8062f04ff8799d96d
parent807be52e319e99af4d26c2da634bf7076de11a93 (diff)
downloadpx4-nuttx-537b5d71a46815412445398bd65195cb94d9434c.tar.gz
px4-nuttx-537b5d71a46815412445398bd65195cb94d9434c.tar.bz2
px4-nuttx-537b5d71a46815412445398bd65195cb94d9434c.zip
Fixes to the LM4F clock configuration. Errors in register handling caused everything to run at half speed
-rw-r--r--nuttx/ChangeLog4
-rw-r--r--nuttx/arch/arm/src/lm/chip/lm4f_syscontrol.h3
-rw-r--r--nuttx/arch/arm/src/lm/lm_syscontrol.c65
-rw-r--r--nuttx/configs/lm4f120-launchpad/include/board.h26
4 files changed, 72 insertions, 26 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 85bd58725..750cee557 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -4532,3 +4532,7 @@
leaving the interrupts in a strange state (2013-4-7).
* arch/arm/src/lpc17_lcd.c: Rommel Marcelo go the LPC1788
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).
diff --git a/nuttx/arch/arm/src/lm/chip/lm4f_syscontrol.h b/nuttx/arch/arm/src/lm/chip/lm4f_syscontrol.h
index e0701c11e..cc7659f29 100644
--- a/nuttx/arch/arm/src/lm/chip/lm4f_syscontrol.h
+++ b/nuttx/arch/arm/src/lm/chip/lm4f_syscontrol.h
@@ -475,7 +475,8 @@
#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_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 */
/* Main Oscillator Control */
diff --git a/nuttx/arch/arm/src/lm/lm_syscontrol.c b/nuttx/arch/arm/src/lm/lm_syscontrol.c
index 3c4c31a7b..b4210c44a 100644
--- a/nuttx/arch/arm/src/lm/lm_syscontrol.c
+++ b/nuttx/arch/arm/src/lm/lm_syscontrol.c
@@ -57,26 +57,29 @@
****************************************************************************/
#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
-# 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
-#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 SLOW_OSCDELAY (4*1024)
-#define PLLLOCK_DELAY (32*1024)
+#define FAST_OSCDELAY (512*1024)
+#define SLOW_OSCDELAY (4*1024)
+#define PLLLOCK_DELAY (32*1024)
/****************************************************************************
* Private Data
@@ -253,16 +256,25 @@ void lm_clockconfig(uint32_t newrcc, uint32_t newrcc2)
putreg32(SYSCON_MISC_PLLLMIS, LM_SYSCON_MISC);
- /* Write the new RCC/RCC2 values. Order depends upon whether RCC2 or RCC
- * is currently enabled.
+ /* Write the new RCC/RCC2 values.
+ *
+ * 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(rcc, LM_SYSCON_RCC);
}
- else
+ else
+#endif
{
putreg32(rcc, LM_SYSCON_RCC);
putreg32(rcc2, LM_SYSCON_RCC2);
@@ -294,9 +306,18 @@ void lm_clockconfig(uint32_t newrcc, uint32_t newrcc2)
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);
+#ifdef LM4F
+ rcc = getreg32(LM_SYSCON_RCC);
+#endif
putreg32(rcc2, LM_SYSCON_RCC2);
/* Wait for the system divider to be effective */
diff --git a/nuttx/configs/lm4f120-launchpad/include/board.h b/nuttx/configs/lm4f120-launchpad/include/board.h
index 2a88506a6..0bdc3fc89 100644
--- a/nuttx/configs/lm4f120-launchpad/include/board.h
+++ b/nuttx/configs/lm4f120-launchpad/include/board.h
@@ -77,16 +77,36 @@
* - 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 not powered down
* - 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 ******************************************************************/
/* The LM4F120 LaunchPad has a single RGB LED. There is only one visible LED which