mbed library sources

Fork of mbed-src by mbed official

Revision:
256:76fd9a263045
Parent:
47:02833c62d054
Child:
294:78f9587bb26d
--- a/targets/cmsis/TARGET_NXP/TARGET_LPC43XX/system_LPC43xx.c	Fri Jul 11 10:00:08 2014 +0100
+++ b/targets/cmsis/TARGET_NXP/TARGET_LPC43XX/system_LPC43xx.c	Tue Jul 15 07:45:08 2014 +0100
@@ -35,8 +35,11 @@
 #define COUNT_OF(a) (sizeof(a)/sizeof(a[0]))
 
 /* Clock variables */
-//uint32_t SystemCoreClock = CRYSTAL_MAIN_FREQ_IN;		/*!< System Clock Frequency (Core Clock)*/
-uint32_t SystemCoreClock = 204000000;
+#if (CLOCK_SETUP)
+uint32_t SystemCoreClock = MAX_CLOCK_FREQ;
+#else
+uint32_t SystemCoreClock = CRYSTAL_MAIN_FREQ_IN;
+#endif
 
 #if !defined(CORE_M0)
 /* SCU pin definitions for pin muxing */
@@ -45,32 +48,80 @@
     uint16_t mode;      /* SCU pin mode and function */
 } PINMUX_GRP_T;
 
+/* Pins to initialize before clocks are configured */
+static const PINMUX_GRP_T pre_clock_mux[] = {
+    /* SPIFI pins */
+    {SCU_REG(0x3, 3), (SCU_PINIO_FAST | 0x3)},  /* P3_3 SPIFI CLK */
+    {SCU_REG(0x3, 4), (SCU_PINIO_FAST | 0x3)},  /* P3_4 SPIFI D3  */
+    {SCU_REG(0x3, 5), (SCU_PINIO_FAST | 0x3)},  /* P3_5 SPIFI D2  */
+    {SCU_REG(0x3, 6), (SCU_PINIO_FAST | 0x3)},  /* P3_6 SPIFI D1  */
+    {SCU_REG(0x3, 7), (SCU_PINIO_FAST | 0x3)},  /* P3_7 SPIFI D0  */
+    {SCU_REG(0x3, 8), (SCU_PINIO_FAST | 0x3)}   /* P3_8 SPIFI CS/SSEL */
+};
+
+/* Pins to initialize after clocks are configured */
+static const PINMUX_GRP_T post_clock_mux[] = {
+    /* Boot pins */
+    {SCU_REG(0x1, 1), (SCU_PINIO_FAST | 0x0)},  /* P1_1  BOOT0 */
+    {SCU_REG(0x1, 2), (SCU_PINIO_FAST | 0x0)},  /* P1_2  BOOT1 */
+    {SCU_REG(0x2, 8), (SCU_PINIO_FAST | 0x0)},  /* P2_8  BOOT2 */
+    {SCU_REG(0x2, 9), (SCU_PINIO_FAST | 0x0)},  /* P2_9  BOOT3 */
+    /* Micromint Bambino 200/210 */
+    {SCU_REG(0x6, 11), (SCU_PINIO_FAST | 0x0)}, /* P6_11 LED1 */
+    {SCU_REG(0x2, 5), (SCU_PINIO_FAST | 0x0)},  /* P2_5  LED2 */
+    {SCU_REG(0x2, 7), (SCU_PINIO_FAST | 0x0)},  /* P2_7  BTN1 */
+    /* Micromint Bambino 210 */
+    {SCU_REG(0x6, 1), (SCU_PINIO_FAST | 0x0)},  /* P6_1  LED3 */
+    {SCU_REG(0x6, 2), (SCU_PINIO_FAST | 0x0)},  /* P6_2  LED4 */
+};
+
+#if (CLOCK_SETUP)
+/* Structure for initial base clock states */
+struct CLK_BASE_STATES {
+    CGU_BASE_CLK_T clk; /* Base clock */
+    CGU_CLKIN_T clkin;  /* Base clock source */
+    uint8_t powerdn;    /* Set to 1 if base clock is initially powered down */
+};
+
+/* Initial base clock states are mostly on */
+static const struct CLK_BASE_STATES clock_states[] = {
+    {CLK_BASE_SAFE, CLKIN_IRC, 0},
+    {CLK_BASE_APB1, CLKIN_MAINPLL, 0},
+    {CLK_BASE_APB3, CLKIN_MAINPLL, 0},
+    {CLK_BASE_USB0, CLKIN_USBPLL, 1},
+    {CLK_BASE_PERIPH, CLKIN_MAINPLL, 0},
+    {CLK_BASE_SPI, CLKIN_MAINPLL, 0},
+    {CLK_BASE_PHY_TX, CLKIN_ENET_TX, 0},
+#if defined(USE_RMII)
+    {CLK_BASE_PHY_RX, CLKIN_ENET_TX, 0},
+#else
+    {CLK_BASE_PHY_RX, CLKIN_ENET_RX, 0},
+#endif
+    {CLK_BASE_SDIO, CLKIN_MAINPLL, 0},
+    {CLK_BASE_SSP0, CLKIN_MAINPLL, 0},
+    {CLK_BASE_SSP1, CLKIN_MAINPLL, 0},
+    {CLK_BASE_UART0, CLKIN_MAINPLL, 0},
+    {CLK_BASE_UART1, CLKIN_MAINPLL, 0},
+    {CLK_BASE_UART2, CLKIN_MAINPLL, 0},
+    {CLK_BASE_UART3, CLKIN_MAINPLL, 0},
+    {CLK_BASE_OUT, CLKINPUT_PD, 0},
+    {CLK_BASE_APLL, CLKINPUT_PD, 0},
+    {CLK_BASE_CGU_OUT0, CLKINPUT_PD, 0},
+    {CLK_BASE_CGU_OUT1, CLKINPUT_PD, 0},
+
+    /* Clocks derived from dividers */
+    {CLK_BASE_LCD, CLKIN_IDIVC, 0},
+    {CLK_BASE_USB1, CLKIN_IDIVD, 1}
+};
+#endif /* defined(CLOCK_SETUP) */
+
 /* Local functions */
-static void SystemCoreClockUpdate(void);
+static uint32_t SystemGetMainPLLHz(void);
 static void SystemSetupClock(void);
 static void SystemSetupPins(const PINMUX_GRP_T *mux, uint32_t n);
 static void SystemSetupMemory(void);
 static void WaitUs(uint32_t us);
 
-/* Pins to initialize before clocks are configured */
-static const PINMUX_GRP_T pre_clock_mux[] = {
-    /* SPIFI pins */
-    {SCU_REG(0x3, 3), (SCU_PINIO_FAST | 0x3)},  // P3_3 SPIFI CLK
-    {SCU_REG(0x3, 4), (SCU_PINIO_FAST | 0x3)},  // P3_4 SPIFI D3
-    {SCU_REG(0x3, 5), (SCU_PINIO_FAST | 0x3)},  // P3_5 SPIFI D2
-    {SCU_REG(0x3, 6), (SCU_PINIO_FAST | 0x3)},  // P3_6 SPIFI D1
-    {SCU_REG(0x3, 7), (SCU_PINIO_FAST | 0x3)},  // P3_7 SPIFI D0
-    {SCU_REG(0x3, 8), (SCU_PINIO_FAST | 0x3)}   // P3_8 SPIFI CS/SSEL
-};
-
-/* Pins to initialize after clocks are configured */
-static const PINMUX_GRP_T post_clock_mux[] = {
-    /* Boot pins */
-    {SCU_REG(0x1, 1), (SCU_PINIO_FAST | 0x0)},  // P1_1  BOOT0
-    {SCU_REG(0x1, 2), (SCU_PINIO_FAST | 0x0)},  // P1_2  BOOT1
-    {SCU_REG(0x2, 8), (SCU_PINIO_FAST | 0x0)},  // P2_8  BOOT2
-    {SCU_REG(0x2, 9), (SCU_PINIO_FAST | 0x0)}   // P2_9  BOOT3
-};
 #endif /* !defined(CORE_M0) */
 
 /*
@@ -79,33 +130,34 @@
 void SystemInit(void)
 {
 #if !defined(CORE_M0)
-    unsigned int *pSCB_VTOR = (unsigned int *) 0xE000ED08;
 
+    /* Initialize vector table in flash */
 #if defined(__ARMCC_VERSION)
     extern void *__Vectors;
 
-    *pSCB_VTOR = (unsigned int) &__Vectors;
+    SCB->VTOR = (unsigned int) &__Vectors;
 #elif defined(__IAR_SYSTEMS_ICC__)
     extern void *__vector_table;
 
-    *pSCB_VTOR = (unsigned int) &__vector_table;
+    SCB->VTOR = (unsigned int) &__vector_table;
 #elif defined(TOOLCHAIN_GCC_ARM)
     extern void *__isr_vector;
 
-    *pSCB_VTOR = (unsigned int) &__isr_vector;
+    SCB->VTOR = (unsigned int) &__isr_vector;
 #else /* defined(__GNUC__) and others */
     extern void *g_pfnVectors;
 
-    *pSCB_VTOR = (unsigned int) &g_pfnVectors;
+    SCB->VTOR = (unsigned int) &g_pfnVectors;
 #endif
 
+#if !defined(TOOLCHAIN_GCC)
 #if defined(__FPU_PRESENT) && __FPU_PRESENT == 1
     /* Initialize floating point */
     fpuInit();
 #endif
+#endif
 
     SystemSetupPins(pre_clock_mux, COUNT_OF(pre_clock_mux)); /* Configure pins */
-
     SystemSetupClock();   /* Configure processor and peripheral clocks */
     SystemSetupPins(post_clock_mux, COUNT_OF(post_clock_mux)); /* Configure pins */
     SystemSetupMemory();  /* Configure external memory */
@@ -119,44 +171,125 @@
  */
 void SystemCoreClockUpdate(void)
 {
+    uint32_t reg, div, rate;
+
+    /* Get main PLL rate */
+    rate = SystemGetMainPLLHz();
+
+    /* Get clock divider */
+    reg = LPC_CCU1->CLKCCU[CLK_MX_MXCORE].CFG;
+    if (((reg >> 5) & 0x7) == 0) {
+        div = 1;
+    }
+    else {
+        div = 2;
+    }
+    rate = rate / div;
+
+    SystemCoreClock = rate;
+}
+
+/* Returns the frequency of the main PLL */
+uint32_t SystemGetMainPLLHz(void)
+{
+    uint32_t PLLReg = LPC_CGU->PLL1_CTRL;
+    uint32_t freq = CRYSTAL_MAIN_FREQ_IN;
+    uint32_t msel, nsel, psel, direct, fbsel;
+    uint32_t m, n, p;
+    const uint8_t ptab[] = {1, 2, 4, 8};
+
+    msel = (PLLReg >> 16) & 0xFF;
+    nsel = (PLLReg >> 12) & 0x3;
+    psel = (PLLReg >> 8) & 0x3;
+    direct = (PLLReg >> 7) & 0x1;
+    fbsel = (PLLReg >> 6) & 0x1;
+
+    m = msel + 1;
+    n = nsel + 1;
+    p = ptab[psel];
+
+    if (direct || fbsel) {
+        return m * (freq / n);
+    }
+
+    return (m / (2 * p)) * (freq / n);
 }
 
 #if !defined(CORE_M0)
 /*
  * SystemSetupClock() - Set processor and peripheral clocks
+ *
+ *    Clock       Frequency    Source
+ * CLK_BASE_MX     204 MHz    CLKIN_MAINPLL            (CLKIN_PLL1)
+ * CLK_BASE_SPIFI  102 MHz    CLKIN_IDIVE
+ * CLK_BASE_USB0   480 MHz    CLKIN_USBPLL  (Disabled) (CLKIN_PLL0USB)
+ * CLK_BASE_USB1    60 MHz    CLKIN_IDIVE   (Disabled)
+ *                 120 MHz    CLKIN_IDIVD   (Disabled)
+ *
+ *                  12 MHz    CLKIN_IDIVB
+ *                  12 MHz    CLKIN_IDIVC
+ *
  */
 void SystemSetupClock(void)
 {
 #if (CLOCK_SETUP)
-    /* Switch main clock to Internal RC (IRC) */
-    LPC_CGU->BASE_CLK[CLK_BASE_MX] = ((1 << 11) | (CLKIN_IRC << 24));
+    uint32_t i;
+
+    /* Switch main clock to Internal RC (IRC) while setting up PLL1 */
+    LPC_CGU->BASE_CLK[CLK_BASE_MX] = (1 << 11) | (CLKIN_IRC << 24);
 
     /* Enable the oscillator and wait 100 us */
     LPC_CGU->XTAL_OSC_CTRL = 0;
     WaitUs(100);
 
 #if (SPIFI_INIT)
-    /* Switch IDIVA clock to IRC and connect to SPIFI clock */
-    LPC_CGU->IDIV_CTRL[CLK_IDIV_A] =  ((1 << 11) | (CLKIN_IRC << 24));
-    LPC_CGU->BASE_CLK[CLK_BASE_SPIFI] =  ((1 << 11) | (CLKIN_IDIVA << 24));
+    /* Setup SPIFI control register and no-opcode mode */
+    LPC_SPIFI->CTRL = (0x100 << 0) | (1 << 16) | (1 << 29) | (1 << 30);
+    LPC_SPIFI->IDATA = 0xA5;
+    /* Switch IDIVE clock to IRC and connect to SPIFI clock */
+    LPC_CGU->IDIV_CTRL[CLK_IDIV_E] = ((1 << 11) | (CLKIN_IRC << 24));
+    LPC_CGU->BASE_CLK[CLK_BASE_SPIFI] = ((1 << 11) | (CLKIN_IDIVE << 24));
 #endif /* SPIFI_INIT */
 
-    /* Power down PLL1 */
-    LPC_CGU->PLL1_CTRL |= 1;
+    /* Configure PLL1 (MAINPLL) for main clock */
+    LPC_CGU->PLL1_CTRL |= 1; /* Power down PLL1 */
 
     /* Change PLL1 to 108 Mhz (msel=9, 12 MHz*9=108 MHz) */
-//    LPC_CGU->PLL1_CTRL = (DIRECT << 7) | (PSEL << 8) | (1 << 11) | (P(NSEL-1) << 12)  | ((MSEL-1) << 16) | (CLKIN_PLL1 << 24);
-    LPC_CGU->PLL1_CTRL = (1 << 7) | (0 << 8) | (1 << 11) | (0 << 12) | (8 << 16) | (CLKIN_PLL1 << 24);
+    LPC_CGU->PLL1_CTRL = (1 << 7) | (0 << 8) | (1 << 11) | (0 << 12) | (8 << 16)
+                         | (CLKIN_MAINPLL << 24);
     while (!(LPC_CGU->PLL1_STAT & 1)); /* Wait for PLL1 to lock */
     WaitUs(100);
 
     /* Change PLL1 to 204 Mhz (msel=17, 12 MHz*17=204 MHz) */
-    LPC_CGU->PLL1_CTRL = (1 << 7) | (0 << 8) | (1 << 11) | (0 << 12) | (16 << 16) | (CLKIN_PLL1 << 24);
+    LPC_CGU->PLL1_CTRL = (1 << 7) | (0 << 8) | (1 << 11) | (0 << 12) | (16 << 16)
+                         | (CLKIN_MAINPLL << 24);
     while (!(LPC_CGU->PLL1_STAT & 1)); /* Wait for PLL1 to lock */
 
-    /* Switch main clock to PLL1 */
-    LPC_CGU->BASE_CLK[CLK_BASE_MX] = ((1 << 11) | (CLKIN_PLL1 << 24));
-    SystemCoreClock = 204000000;
+    /* Connect main clock to PLL1 */
+    LPC_CGU->BASE_CLK[CLK_BASE_MX] = (1 << 11) | (CLKIN_MAINPLL << 24);
+
+    /* Set USB PLL dividers for 480 MHz (for USB0) */
+    LPC_CGU->PLL[CGU_USB_PLL].PLL_MDIV = 0x06167FFA;
+    LPC_CGU->PLL[CGU_USB_PLL].PLL_NP_DIV = 0x00302062;
+    LPC_CGU->PLL[CGU_USB_PLL].PLL_CTRL = 0x0000081D | (CLKIN_CRYSTAL << 24);
+
+    /* Set IDIVE clock to PLL1/2 = 102 MHz */
+    LPC_CGU->IDIV_CTRL[CLK_IDIV_E] = (1 << 2) | (1 << 11) | (CLKIN_MAINPLL << 24); /* PLL1/2 */
+
+    /* Set IDIVD clock to ((USBPLL/4) / 2) = 60 MHz (for USB1) */
+    LPC_CGU->IDIV_CTRL[CLK_IDIV_A] = (3 << 2) | (1 << 11) | (CLKIN_USBPLL << 24); /* USBPLL/4 */
+    LPC_CGU->IDIV_CTRL[CLK_IDIV_D] = (1 << 2) | (1 << 11) | (CLKIN_IDIVA << 24); /* IDIVA/2 */
+
+    /* Configure remaining integer dividers */
+    LPC_CGU->IDIV_CTRL[CLK_IDIV_B] = (0 << 2) | (1 << 11) | (CLKIN_IRC << 24); /* IRC */
+    LPC_CGU->IDIV_CTRL[CLK_IDIV_C] = (1 << 2) | (1 << 11) | (CLKIN_MAINPLL << 24); /* PLL1/2 */
+
+    /* Connect base clocks */
+    for (i = 0; i < COUNT_OF(clock_states); i++) {
+        LPC_CGU->BASE_CLK[clock_states[i].clk] =
+                         ( clock_states[i].powerdn << 0)
+                         | (1 << 11) | (clock_states[i].clkin << 24);
+    }
 #endif /* CLOCK_SETUP */
 }
 
@@ -165,7 +298,7 @@
  */
 void SystemSetupPins(const PINMUX_GRP_T *mux, uint32_t n)
 {
-    uint16_t i;
+    uint32_t i;
 
     for (i = 0; i < n; i++) {
         *(mux[i].reg) = mux[i].mode;
@@ -188,35 +321,36 @@
  */
 void fpuInit(void)
 {
-	// from ARM TRM manual:
-	//   ; CPACR is located at address 0xE000ED88
-	//   LDR.W R0, =0xE000ED88
-	//   ; Read CPACR
-	//   LDR R1, [R0]
-	//   ; Set bits 20-23 to enable CP10 and CP11 coprocessors
-	//   ORR R1, R1, #(0xF << 20)
-	//   ; Write back the modified value to the CPACR
-	//   STR R1, [R0]
+   /*
+    * from ARM TRM manual:
+    *   ; CPACR is located at address 0xE000ED88
+    *   LDR.W R0, =0xE000ED88
+    *   ; Read CPACR
+    *   LDR R1, [R0]
+    *   ; Set bits 20-23 to enable CP10 and CP11 coprocessors
+    *   ORR R1, R1, #(0xF << 20)
+    *   ; Write back the modified value to the CPACR
+    *   STR R1, [R0]
+    */
 
-	volatile uint32_t *regCpacr = (uint32_t *) LPC_CPACR;
-	volatile uint32_t *regMvfr0 = (uint32_t *) SCB_MVFR0;
-	volatile uint32_t *regMvfr1 = (uint32_t *) SCB_MVFR1;
-	volatile uint32_t Cpacr;
-	volatile uint32_t Mvfr0;
-	volatile uint32_t Mvfr1;
-	char vfpPresent = 0;
+    volatile uint32_t *regCpacr = (uint32_t *) LPC_CPACR;
+    volatile uint32_t *regMvfr0 = (uint32_t *) SCB_MVFR0;
+    volatile uint32_t *regMvfr1 = (uint32_t *) SCB_MVFR1;
+    volatile uint32_t Cpacr;
+    volatile uint32_t Mvfr0;
+    volatile uint32_t Mvfr1;
+    char vfpPresent = 0;
 
-	Mvfr0 = *regMvfr0;
-	Mvfr1 = *regMvfr1;
+    Mvfr0 = *regMvfr0;
+    Mvfr1 = *regMvfr1;
 
-	vfpPresent = ((SCB_MVFR0_RESET == Mvfr0) && (SCB_MVFR1_RESET == Mvfr1));
+    vfpPresent = ((SCB_MVFR0_RESET == Mvfr0) && (SCB_MVFR1_RESET == Mvfr1));
 
-	if (vfpPresent) {
-		Cpacr = *regCpacr;
-		Cpacr |= (0xF << 20);
-		*regCpacr = Cpacr;	// enable CP10 and CP11 for full access
-	}
-
+    if (vfpPresent) {
+        Cpacr = *regCpacr;
+        Cpacr |= (0xF << 20);
+        *regCpacr = Cpacr;  /* enable CP10 and CP11 for full access */
+    }
 }
 #endif /* defined(__FPU_PRESENT) && __FPU_PRESENT == 1 */