]> rtime.felk.cvut.cz Git - lincan.git/blob - embedded/arch/arm/mach-lpc17xx/libs/hal/hal_machperiph.c
Contributed support for LCP17xx devices and PiKRON's LMC1 board.
[lincan.git] / embedded / arch / arm / mach-lpc17xx / libs / hal / hal_machperiph.c
1
2 #include <system_def.h>
3 #include <cpu_def.h>
4 #include <hal_machperiph.h>
5
6
7 /*----------------------------------------------------------------------------
8   Check the register settings
9  *----------------------------------------------------------------------------*/
10 #define CHECK_RANGE(val, min, max)                ((val < min) || (val > max))
11 #define CHECK_RSVD(val, mask)                     (val & mask)
12
13 /* Clock Configuration -------------------------------------------------------*/
14 #if (CHECK_RSVD((SCS_Val),       ~0x00000030))
15    #error "SCS: Invalid values of reserved bits!"
16 #endif
17
18 #if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2))
19    #error "CLKSRCSEL: Value out of range!"
20 #endif
21
22 #if (CHECK_RSVD((PLL0CFG_Val),   ~0x00FF7FFF))
23    #error "PLL0CFG: Invalid values of reserved bits!"
24 #endif
25
26 #if (CHECK_RSVD((PLL1CFG_Val),   ~0x0000007F))
27    #error "PLL1CFG: Invalid values of reserved bits!"
28 #endif
29
30 #if ((CCLKCFG_Val != 0) && (((CCLKCFG_Val - 1) % 2)))
31    #error "CCLKCFG: CCLKSEL field does not contain only odd values or 0!"
32 #endif
33
34 #if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F))
35    #error "USBCLKCFG: Invalid values of reserved bits!"
36 #endif
37
38 #if (CHECK_RSVD((PCLKSEL0_Val),   0x000C0C00))
39    #error "PCLKSEL0: Invalid values of reserved bits!"
40 #endif
41
42 #if (CHECK_RSVD((PCLKSEL1_Val),   0x03000300))
43    #error "PCLKSEL1: Invalid values of reserved bits!"
44 #endif
45
46 #if (CHECK_RSVD((PCONP_Val),      0x10100821))
47    #error "PCONP: Invalid values of reserved bits!"
48 #endif
49
50 /* Flash Accelerator Configuration -------------------------------------------*/
51 #if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F07F))
52    #error "FLASHCFG: Invalid values of reserved bits!"
53 #endif
54
55 /*----------------------------------------------------------------------------
56   Clock Variable definitions
57  *----------------------------------------------------------------------------*/
58 unsigned int system_frequency = IRC_OSC; /*!< System Clock Frequency (Core Clock)  */
59
60 void system_clock_init(void)
61 {
62 #if (CLOCK_SETUP)                       /* Clock Setup                        */
63   SC->SCS       = SCS_Val;
64   if (SCS_Val & (1 << 5)) {             /* If Main Oscillator is enabled      */
65     while ((SC->SCS & (1 << 6)) == 0);  /* Wait for Oscillator to be ready    */
66   }
67
68 #if (PLL0_SETUP)
69   SC->CLKSRCSEL = CLKSRCSEL_Val;        /* Select Clock Source for PLL0       */
70   SC->PLL0CFG   = PLL0CFG_Val;
71   SC->PLL0CON   = 0x01;                 /* PLL0 Enable                        */
72   SC->PLL0FEED  = 0xAA;
73   SC->PLL0FEED  = 0x55;
74   while (!(SC->PLL0STAT & (1 << 26)));  /* Wait for PLOCK0                    */
75   SC->CCLKCFG   = CCLKCFG_Val;          /* Setup Clock Divider                */
76
77   SC->PLL0CON   = 0x03;                 /* PLL0 Enable & Connect              */
78   SC->PLL0FEED  = 0xAA;
79   SC->PLL0FEED  = 0x55;
80 #endif
81
82 #if (PLL1_SETUP)
83   SC->PLL1CFG   = PLL1CFG_Val;
84   SC->PLL1CON   = 0x01;                 /* PLL1 Enable                        */
85   SC->PLL1FEED  = 0xAA;
86   SC->PLL1FEED  = 0x55;
87   while (!(SC->PLL1STAT & (1 << 10)));  /* Wait for PLOCK1                    */
88
89   SC->PLL1CON   = 0x03;                 /* PLL1 Enable & Connect              */
90   SC->PLL1FEED  = 0xAA;
91   SC->PLL1FEED  = 0x55;
92 #endif
93
94 #ifdef USBCLKCFG_Val
95 #if USBCLKCFG_Val != 0
96   SC->USBCLKCFG = USBCLKCFG_Val;
97 #endif
98 #endif
99
100 #endif
101
102   /* Determine clock frequency according to clock register values             */
103   if (((SC->PLL0STAT >> 24) & 3) == 3) {/* If PLL0 enabled and connected      */
104     switch (SC->CLKSRCSEL & 0x03) {
105       case 0:                           /* Internal RC oscillator => PLL0     */
106       case 3:                           /* Reserved, default to Internal RC   */
107         system_frequency = (IRC_OSC *
108                           (((2 * ((SC->PLL0STAT & 0x7FFF) + 1))) /
109                           (((SC->PLL0STAT >> 16) & 0xFF) + 1))   /
110                           ((SC->CCLKCFG & 0xFF)+ 1));
111         break;
112       case 1:                           /* Main oscillator => PLL0            */
113         system_frequency = (OSC_CLK *
114                           (((2 * ((SC->PLL0STAT & 0x7FFF) + 1))) /
115                           (((SC->PLL0STAT >> 16) & 0xFF) + 1))   /
116                           ((SC->CCLKCFG & 0xFF)+ 1));
117         break;
118       case 2:                           /* RTC oscillator => PLL0             */
119         system_frequency = (RTC_CLK *
120                           (((2 * ((SC->PLL0STAT & 0x7FFF) + 1))) /
121                           (((SC->PLL0STAT >> 16) & 0xFF) + 1))   /
122                           ((SC->CCLKCFG & 0xFF)+ 1));
123         break;
124     }
125   } else {
126     switch (SC->CLKSRCSEL & 0x03) {
127       case 0:                           /* Internal RC oscillator => PLL0     */
128       case 3:                           /* Reserved, default to Internal RC   */
129         system_frequency = IRC_OSC / ((SC->CCLKCFG & 0xFF)+ 1);
130         break;
131       case 1:                           /* Main oscillator => PLL0            */
132         system_frequency = OSC_CLK / ((SC->CCLKCFG & 0xFF)+ 1);
133         break;
134       case 2:                           /* RTC oscillator => PLL0             */
135         system_frequency = RTC_CLK / ((SC->CCLKCFG & 0xFF)+ 1);
136         break;
137     }
138   }
139
140 #if (FLASH_SETUP == 1)                  /* Flash Accelerator Setup            */
141   SC->FLASHCFG  = FLASHCFG_Val;
142 #endif
143 }
144
145 void lpc_watchdog_feed()
146 {
147   unsigned long flags;
148
149   save_and_cli(flags);
150   WDT->WDFEED = 0xAA;
151   WDT->WDFEED = 0x55;
152   restore_flags(flags);
153 }
154
155 void lpc_watchdog_init(int on,int timeout_ms)
156 {
157   if (!on) return;
158   WDT->WDCLKSEL = 1;
159   WDT->WDTC = (PCLK/4)/(1000/timeout_ms);
160   WDT->WDMOD = 0x03;                               /* Enable watchdog timer and reset */
161 }