]> rtime.felk.cvut.cz Git - sysless.git/commitdiff
LPC178x: Update system setup from available NXP examples.
authorPavel Pisa <pisa@cmp.felk.cvut.cz>
Thu, 20 Dec 2012 23:20:34 +0000 (00:20 +0100)
committerPavel Pisa <pisa@cmp.felk.cvut.cz>
Thu, 20 Dec 2012 23:20:34 +0000 (00:20 +0100)
Signed-off-by: Pavel Pisa <pisa@cmp.felk.cvut.cz>
arch/arm/mach-lpc178x/libs/hal/hal_machperiph.c
arch/arm/mach-lpc178x/libs/hal/hal_machperiph.h

index 5710f3cdc6ff4bb13bd1730417a77425a06260e2..17bd712ba8ab51975a92f75f32dafd78b416166f 100644 (file)
 #define CHECK_RSVD(val, mask)                     (val & mask)
 
 /* Clock Configuration -------------------------------------------------------*/
-#if (CHECK_RSVD((SCS_Val),       ~0x00000030))
+#if (CHECK_RSVD((SCS_Val),       ~0x0000003F))
    #error "SCS: Invalid values of reserved bits!"
 #endif
 
-#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2))
+#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 1))
    #error "CLKSRCSEL: Value out of range!"
 #endif
 
-#if (CHECK_RSVD((PLL0CFG_Val),   ~0x00FF7FFF))
+#if (CHECK_RSVD((PLL0CFG_Val),   ~0x0000007F))
    #error "PLL0CFG: Invalid values of reserved bits!"
 #endif
 
    #error "PLL1CFG: Invalid values of reserved bits!"
 #endif
 
-#if ((CCLKCFG_Val != 0) && (((CCLKCFG_Val - 1) % 2)))
-   #error "CCLKCFG: CCLKSEL field does not contain only odd values or 0!"
+#if (CHECK_RSVD((CCLKSEL_Val),   ~0x0000011F))
+   #error "CCLKSEL: Invalid values of reserved bits!"
 #endif
 
-#if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F))
-   #error "USBCLKCFG: Invalid values of reserved bits!"
+#if (CHECK_RSVD((USBCLKSEL_Val), ~0x0000031F))
+   #error "USBCLKSEL: Invalid values of reserved bits!"
 #endif
 
-#if (CHECK_RSVD((PCLKSEL0_Val),   0x000C0C00))
-   #error "PCLKSEL0: Invalid values of reserved bits!"
+#if (CHECK_RSVD((EMCCLKSEL_Val), ~0x00000001))
+   #error "EMCCLKSEL: Invalid values of reserved bits!"
 #endif
 
-#if (CHECK_RSVD((PCLKSEL1_Val),   0x03000300))
-   #error "PCLKSEL1: Invalid values of reserved bits!"
+#if (CHECK_RSVD((PCLKSEL_Val), ~0x0000001F))
+   #error "PCLKSEL: Invalid values of reserved bits!"
 #endif
 
-#if (CHECK_RSVD((PCONP_Val),      0x10100821))
+#if (CHECK_RSVD((PCONP_Val), ~0xFFFEFFFF))
    #error "PCONP: Invalid values of reserved bits!"
 #endif
 
+#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF))
+   #error "CLKOUTCFG: Invalid values of reserved bits!"
+#endif
+
 /* Flash Accelerator Configuration -------------------------------------------*/
-#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F07F))
-   #error "FLASHCFG: Invalid values of reserved bits!"
+#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F000))
+   #warning "FLASHCFG: Invalid values of reserved bits!"
+#endif
+
+/*----------------------------------------------------------------------------
+  DEFINES
+ *----------------------------------------------------------------------------*/
+/* pll_out_clk = F_cco / (2 × P)
+   F_cco = pll_in_clk × M × 2 × P */
+#define __M                   ((PLL0CFG_Val & 0x1F) + 1)
+#define __PLL0_CLK(__F_IN)    (__F_IN * __M)
+#define __CCLK_DIV            (CCLKSEL_Val & 0x1F)
+#define __PCLK_DIV                       (PCLKSEL_Val & 0x1F)
+#define __ECLK_DIV                       ((EMCCLKSEL_Val & 0x01) + 1)
+
+/* Determine core clock frequency according to settings */
+#if (CLOCK_SETUP)                       /* Clock Setup                        */
+
+  #if ((CLKSRCSEL_Val & 0x01) == 1) && ((SCS_Val & 0x20)== 0)
+   #error "Main Oscillator is selected as clock source but is not enabled!"
+  #endif
+
+  #if ((CCLKSEL_Val & 0x100) == 0x100) && (PLL0_SETUP == 0)
+   #error "Main PLL is selected as clock source but is not enabled!"
+  #endif
+
+  #if ((CCLKSEL_Val & 0x100) == 0)      /* cclk = sysclk */
+    #if ((CLKSRCSEL_Val & 0x01) == 0)   /* sysclk = irc_clk */
+        #define __CORE_CLK (IRC_OSC / __CCLK_DIV)
+               #define __PER_CLK  (IRC_OSC/  __PCLK_DIV)
+        #define __EMC_CLK  (IRC_OSC/  __ECLK_DIV)
+    #else                               /* sysclk = osc_clk */
+        #define __CORE_CLK (OSC_CLK / __CCLK_DIV)
+        #define __PER_CLK  (OSC_CLK/  __PCLK_DIV)
+        #define __EMC_CLK  (OSC_CLK/  __ECLK_DIV)
+    #endif
+  #else                                 /* cclk = pll_clk */
+    #if ((CLKSRCSEL_Val & 0x01) == 0)   /* sysclk = irc_clk */
+        #define __CORE_CLK (__PLL0_CLK(IRC_OSC) / __CCLK_DIV)
+        #define __PER_CLK  (__PLL0_CLK(IRC_OSC) / __PCLK_DIV)
+        #define __EMC_CLK  (__PLL0_CLK(IRC_OSC) / __ECLK_DIV)
+    #else                               /* sysclk = osc_clk */
+        #define __CORE_CLK (__PLL0_CLK(OSC_CLK) / __CCLK_DIV)
+        #define __PER_CLK  (__PLL0_CLK(OSC_CLK) / __PCLK_DIV)
+               #define __EMC_CLK  (__PLL0_CLK(OSC_CLK) / __ECLK_DIV)
+    #endif
+  #endif
+
+#else
+        #define __CORE_CLK (IRC_OSC)
+        #define __PER_CLK  (IRC_OSC)
+        #define __EMC_CLK  (IRC_OSC)
 #endif
 
 /*----------------------------------------------------------------------------
   Clock Variable definitions
  *----------------------------------------------------------------------------*/
-unsigned int system_frequency = IRC_OSC; /*!< System Clock Frequency (Core Clock)  */
+uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
+uint32_t PeripheralClock = __PER_CLK; /*!< Peripheral Clock Frequency (Pclk)  */
+uint32_t EMCClock               = __EMC_CLK; /*!< EMC Clock Frequency                            */
+uint32_t USBClock               = (48000000UL);                  /*!< USB Clock Frequency - this value will
+                                                                       be updated after call SystemCoreClockUpdate, should be 48MHz*/
+
+unsigned int system_frequency = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
+unsigned int peripheral_frequency = __PER_CLK;/*!< Peripheral Clock Frequency (Pclk)  */
+
+
+/*----------------------------------------------------------------------------
+  Clock functions
+ *----------------------------------------------------------------------------*/
+void system_clock_update_info(void)
+{
+  /* Determine clock frequency according to clock register values             */
+  if ((LPC_SC->CCLKSEL &0x100) == 0) {            /* cclk = sysclk    */
+    if ((LPC_SC->CLKSRCSEL & 0x01) == 0) {    /* sysclk = irc_clk */
+          SystemCoreClock = (IRC_OSC / (LPC_SC->CCLKSEL & 0x1F));
+          PeripheralClock = (IRC_OSC / (LPC_SC->PCLKSEL & 0x1F));
+          EMCClock        = (IRC_OSC / ((LPC_SC->EMCCLKSEL & 0x01)+1));
+    }
+    else {                                        /* sysclk = osc_clk */
+      if ((LPC_SC->SCS & 0x40) == 0) {
+          SystemCoreClock = 0;                      /* this should never happen! */
+          PeripheralClock = 0;
+          EMCClock        = 0;
+      }
+      else {
+          SystemCoreClock = (OSC_CLK / (LPC_SC->CCLKSEL & 0x1F));
+          PeripheralClock = (OSC_CLK / (LPC_SC->PCLKSEL & 0x1F));
+          EMCClock        = (OSC_CLK / ((LPC_SC->EMCCLKSEL & 0x01)+1));
+      }
+    }
+  }
+  else {                                          /* cclk = pll_clk */
+    if ((LPC_SC->PLL0STAT & 0x100) == 0) {        /* PLL0 not enabled */
+          SystemCoreClock = 0;                      /* this should never happen! */
+          PeripheralClock = 0;
+          EMCClock               = 0;
+    }
+    else {
+      if ((LPC_SC->CLKSRCSEL & 0x01) == 0) {    /* sysclk = irc_clk */
+          SystemCoreClock = (IRC_OSC * ((LPC_SC->PLL0STAT & 0x1F) + 1) / (LPC_SC->CCLKSEL & 0x1F));
+          PeripheralClock = (IRC_OSC * ((LPC_SC->PLL0STAT & 0x1F) + 1) / (LPC_SC->PCLKSEL & 0x1F));
+          EMCClock        = (IRC_OSC * ((LPC_SC->PLL0STAT & 0x1F) + 1) / ((LPC_SC->EMCCLKSEL & 0x01)+1));
+      }
+      else {                                        /* sysclk = osc_clk */
+        if ((LPC_SC->SCS & 0x40) == 0) {
+          SystemCoreClock = 0;                      /* this should never happen! */
+          PeripheralClock = 0;
+          EMCClock               = 0;
+        }
+        else {
+          SystemCoreClock = (OSC_CLK * ((LPC_SC->PLL0STAT & 0x1F) + 1) / (LPC_SC->CCLKSEL & 0x1F));
+          PeripheralClock = (OSC_CLK * ((LPC_SC->PLL0STAT & 0x1F) + 1) / (LPC_SC->PCLKSEL & 0x1F));
+          EMCClock        = (OSC_CLK * ((LPC_SC->PLL0STAT & 0x1F) + 1) / ((LPC_SC->EMCCLKSEL & 0x01)+1));
+        }
+      }
+    }
+  }
+  /* ---update USBClock------------------*/
+  if(LPC_SC->USBCLKSEL & (0x01<<8))//Use PLL0 as the input to the USB clock divider
+  {
+         switch (LPC_SC->USBCLKSEL & 0x1F)
+         {
+         case 0:
+                 USBClock = 0; //no clock will be provided to the USB subsystem
+                 break;
+         case 4:
+         case 6:
+                 if(LPC_SC->CLKSRCSEL & 0x01)  //pll_clk_in = main_osc
+                         USBClock = (OSC_CLK * ((LPC_SC->PLL0STAT & 0x1F) + 1) / (LPC_SC->USBCLKSEL & 0x1F));
+                 else //pll_clk_in = irc_clk
+                         USBClock = (IRC_OSC * ((LPC_SC->PLL0STAT & 0x1F) + 1) / (LPC_SC->USBCLKSEL & 0x1F));
+                 break;
+         default:
+                 USBClock = 0;  /* this should never happen! */
+         }
+  }
+  else if(LPC_SC->USBCLKSEL & (0x02<<8))//usb_input_clk = alt_pll (pll1)
+  {
+         if(LPC_SC->CLKSRCSEL & 0x01)  //pll1_clk_in = main_osc
+                       USBClock = (OSC_CLK * ((LPC_SC->PLL1STAT & 0x1F) + 1));
+         else //pll1_clk_in = irc_clk
+                       USBClock = (IRC_OSC * ((LPC_SC->PLL0STAT & 0x1F) + 1));
+  }
+  else
+         USBClock = 0; /* this should never happen! */
+
+  system_frequency = SystemCoreClock;
+  peripheral_frequency = PeripheralClock;
+}
+
+  /* Determine clock frequency according to clock register values             */
 
 void system_clock_init(void)
 {
 #if (CLOCK_SETUP)                       /* Clock Setup                        */
-  SC->SCS       = SCS_Val;
+  LPC_SC->SCS       = SCS_Val;
   if (SCS_Val & (1 << 5)) {             /* If Main Oscillator is enabled      */
-    while ((SC->SCS & (1 << 6)) == 0);  /* Wait for Oscillator to be ready    */
+    while ((LPC_SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready    */
   }
 
-#if (PLL0_SETUP)
-  SC->CLKSRCSEL = CLKSRCSEL_Val;        /* Select Clock Source for PLL0       */
-  SC->PLL0CFG   = PLL0CFG_Val;
-  SC->PLL0CON   = 0x01;                 /* PLL0 Enable                        */
-  SC->PLL0FEED  = 0xAA;
-  SC->PLL0FEED  = 0x55;
-  while (!(SC->PLL0STAT & (1 << 26)));  /* Wait for PLOCK0                    */
-  SC->CCLKCFG   = CCLKCFG_Val;          /* Setup Clock Divider                */
+  LPC_SC->CLKSRCSEL = CLKSRCSEL_Val;    /* Select Clock Source for sysclk/PLL0*/
 
-  SC->PLL0CON   = 0x03;                 /* PLL0 Enable & Connect              */
-  SC->PLL0FEED  = 0xAA;
-  SC->PLL0FEED  = 0x55;
+#if (PLL0_SETUP)
+  LPC_SC->PLL0CFG   = PLL0CFG_Val;
+  LPC_SC->PLL0CON   = 0x01;             /* PLL0 Enable                        */
+  LPC_SC->PLL0FEED  = 0xAA;
+  LPC_SC->PLL0FEED  = 0x55;
+  while (!(LPC_SC->PLL0STAT & (1<<10)));/* Wait for PLOCK0                    */
 #endif
 
 #if (PLL1_SETUP)
-  SC->PLL1CFG   = PLL1CFG_Val;
-  SC->PLL1CON   = 0x01;                 /* PLL1 Enable                        */
-  SC->PLL1FEED  = 0xAA;
-  SC->PLL1FEED  = 0x55;
-  while (!(SC->PLL1STAT & (1 << 10)));  /* Wait for PLOCK1                    */
-
-  SC->PLL1CON   = 0x03;                 /* PLL1 Enable & Connect              */
-  SC->PLL1FEED  = 0xAA;
-  SC->PLL1FEED  = 0x55;
-#endif
-
-#ifdef USBCLKCFG_Val
-#if USBCLKCFG_Val != 0
-  SC->USBCLKCFG = USBCLKCFG_Val;
-#endif
+  LPC_SC->PLL1CFG   = PLL1CFG_Val;
+  LPC_SC->PLL1CON   = 0x01;             /* PLL1 Enable                        */
+  LPC_SC->PLL1FEED  = 0xAA;
+  LPC_SC->PLL1FEED  = 0x55;
+  while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1                    */
 #endif
 
+  LPC_SC->CCLKSEL   = CCLKSEL_Val;      /* Setup Clock Divider                */
+  LPC_SC->USBCLKSEL = USBCLKSEL_Val;    /* Setup USB Clock Divider            */
+  LPC_SC->EMCCLKSEL = EMCCLKSEL_Val;    /* EMC Clock Selection                */
+  LPC_SC->PCLKSEL   = PCLKSEL_Val;      /* Peripheral Clock Selection         */
+  LPC_SC->PCONP     = PCONP_Val;        /* Power Control for Peripherals      */
+  LPC_SC->CLKOUTCFG = CLKOUTCFG_Val;    /* Clock Output Configuration         */
 #endif
 
-  /* Determine clock frequency according to clock register values             */
-  if (((SC->PLL0STAT >> 24) & 3) == 3) {/* If PLL0 enabled and connected      */
-    switch (SC->CLKSRCSEL & 0x03) {
-      case 0:                           /* Internal RC oscillator => PLL0     */
-      case 3:                           /* Reserved, default to Internal RC   */
-        system_frequency = (IRC_OSC *
-                          (((2 * ((SC->PLL0STAT & 0x7FFF) + 1))) /
-                          (((SC->PLL0STAT >> 16) & 0xFF) + 1))   /
-                          ((SC->CCLKCFG & 0xFF)+ 1));
-        break;
-      case 1:                           /* Main oscillator => PLL0            */
-        system_frequency = (OSC_CLK *
-                          (((2 * ((SC->PLL0STAT & 0x7FFF) + 1))) /
-                          (((SC->PLL0STAT >> 16) & 0xFF) + 1))   /
-                          ((SC->CCLKCFG & 0xFF)+ 1));
-        break;
-      case 2:                           /* RTC oscillator => PLL0             */
-        system_frequency = (RTC_CLK *
-                          (((2 * ((SC->PLL0STAT & 0x7FFF) + 1))) /
-                          (((SC->PLL0STAT >> 16) & 0xFF) + 1))   /
-                          ((SC->CCLKCFG & 0xFF)+ 1));
-        break;
-    }
-  } else {
-    switch (SC->CLKSRCSEL & 0x03) {
-      case 0:                           /* Internal RC oscillator => PLL0     */
-      case 3:                           /* Reserved, default to Internal RC   */
-        system_frequency = IRC_OSC / ((SC->CCLKCFG & 0xFF)+ 1);
-        break;
-      case 1:                           /* Main oscillator => PLL0            */
-        system_frequency = OSC_CLK / ((SC->CCLKCFG & 0xFF)+ 1);
-        break;
-      case 2:                           /* RTC oscillator => PLL0             */
-        system_frequency = RTC_CLK / ((SC->CCLKCFG & 0xFF)+ 1);
-        break;
-    }
-  }
-
 #if (FLASH_SETUP == 1)                  /* Flash Accelerator Setup            */
-  SC->FLASHCFG  = FLASHCFG_Val;
+  LPC_SC->FLASHCFG  = FLASHCFG_Val|0x03A;
 #endif
 }
 
@@ -147,15 +249,15 @@ void lpc_watchdog_feed()
   unsigned long flags;
 
   save_and_cli(flags);
-  WDT->WDFEED = 0xAA;
-  WDT->WDFEED = 0x55;
+  LPC_WDT->FEED = 0xAA;
+  LPC_WDT->FEED = 0x55;
   restore_flags(flags);
 }
 
 void lpc_watchdog_init(int on,int timeout_ms)
 {
   if (!on) return;
-  WDT->WDCLKSEL = 1;
-  WDT->WDTC = (PCLK/4)/(1000/timeout_ms);
-  WDT->WDMOD = 0x03;                              /* Enable watchdog timer and reset */
+  /*LPC_WDT->CLKSEL = 1;*/ /*FIXME*/
+  LPC_WDT->TC = (PCLK/4)/(1000/timeout_ms);
+  LPC_WDT->MOD = 0x03;                            /* Enable watchdog timer and reset */
 }
index aadc41d24bf4dbbbd3a577482e058e20c25a0d12..4514e43954feff4dd6cc55ff9057da5d12a9d2cb 100644 (file)
@@ -2,7 +2,8 @@
 #define _HAL_MACHPERIPH_H
 
 extern unsigned int system_frequency;
-#define PCLK ((system_frequency+2)/4)
+extern unsigned int peripheral_frequency;
+#define PCLK peripheral_frequency
 
 void system_clock_init(void);