1 #include <system_def.h>
3 #include <hal_machperiph.h>
9 /*----------------------------------------------------------------------------
10 Check the register settings
11 *----------------------------------------------------------------------------*/
12 #define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
13 #define CHECK_RSVD(val, mask) (val & mask)
15 /* Clock Configuration -------------------------------------------------------*/
16 #if (CHECK_RSVD((SYSOSCCTRL_Val), ~0x00000003))
17 #error "SYSOSCCTRL: Invalid values of reserved bits!"
20 #if (CHECK_RSVD((WDTOSCCTRL_Val), ~0x000001FF))
21 #error "WDTOSCCTRL: Invalid values of reserved bits!"
24 #if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 2))
25 #error "SYSPLLCLKSEL: Value out of range!"
28 #if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000001FF))
29 #error "SYSPLLCTRL: Invalid values of reserved bits!"
32 #if (CHECK_RSVD((MAINCLKSEL_Val), ~0x00000003))
33 #error "MAINCLKSEL: Invalid values of reserved bits!"
36 #if (CHECK_RANGE((USBPLLCLKSEL_Val), 0, 1))
37 #error "USBPLLCLKSEL: Value out of range!"
40 #if (CHECK_RSVD((USBPLLCTRL_Val), ~0x000001FF))
41 #error "USBPLLCTRL: Invalid values of reserved bits!"
44 #if (CHECK_RSVD((USBPLLUEN_Val), ~0x00000001))
45 #error "USBPLLUEN: Invalid values of reserved bits!"
48 #if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
49 #error "SYSAHBCLKDIV: Value out of range!"
52 #if (CHECK_RSVD((AHBCLKCTRL_Val), ~0x0001FFFF))
53 #error "AHBCLKCTRL: Invalid values of reserved bits!"
56 #if (CHECK_RSVD((SYSMEMREMAP_Val), ~0x00000003))
57 #error "SYSMEMREMAP: Invalid values of reserved bits!"
61 /*----------------------------------------------------------------------------
62 Clock Variable definitions
63 *----------------------------------------------------------------------------*/
64 unsigned int system_frequency = __SYSTEM_CLOCK; /*!< System Clock Frequency (Core Clock) */
66 /*----------------------------------------------------------------------------
68 *----------------------------------------------------------------------------*/
69 void system_core_clock_update (void) /* Get Core Clock Frequency */
73 /* Determine clock frequency according to clock register values */
74 switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
75 case 0: wdt_osc = 400000; break;
76 case 1: wdt_osc = 500000; break;
77 case 2: wdt_osc = 800000; break;
78 case 3: wdt_osc = 1100000; break;
79 case 4: wdt_osc = 1400000; break;
80 case 5: wdt_osc = 1600000; break;
81 case 6: wdt_osc = 1800000; break;
82 case 7: wdt_osc = 2000000; break;
83 case 8: wdt_osc = 2200000; break;
84 case 9: wdt_osc = 2400000; break;
85 case 10: wdt_osc = 2600000; break;
86 case 11: wdt_osc = 2700000; break;
87 case 12: wdt_osc = 2900000; break;
88 case 13: wdt_osc = 3100000; break;
89 case 14: wdt_osc = 3200000; break;
90 case 15: wdt_osc = 3400000; break;
92 wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
94 switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
95 case 0: /* Internal RC oscillator */
96 system_frequency = __IRC_OSC_CLK;
98 case 1: /* Input Clock to System PLL */
99 switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
100 case 0: /* Internal RC oscillator */
101 system_frequency = __IRC_OSC_CLK;
103 case 1: /* System oscillator */
104 system_frequency = __SYS_OSC_CLK;
106 case 2: /* WDT Oscillator */
107 system_frequency = wdt_osc;
109 case 3: /* Reserved */
110 system_frequency = 0;
114 case 2: /* WDT Oscillator */
115 system_frequency = wdt_osc;
117 case 3: /* System PLL Clock Out */
118 switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
119 case 0: /* Internal RC oscillator */
120 if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
121 system_frequency = __IRC_OSC_CLK;
123 system_frequency = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
126 case 1: /* System oscillator */
127 if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
128 system_frequency = __SYS_OSC_CLK;
130 system_frequency = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
133 case 2: /* WDT Oscillator */
134 if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
135 system_frequency = wdt_osc;
137 system_frequency = wdt_osc * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
140 case 3: /* Reserved */
141 system_frequency = 0;
147 system_frequency /= LPC_SYSCON->SYSAHBCLKDIV;
151 void system_clock_init(void)
153 #if (CLOCK_SETUP) /* Clock Setup */
154 #if (SYSCLK_SETUP) /* System Clock Setup */
156 #if (SYSOSC_SETUP) /* System Oscillator Setup */
159 LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_SYSOSC_PD; /* Power-up System Osc */
160 LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
161 for (i = 0; i < 200; i++) __NOP();
162 #endif /* SYSOSC_SETUP */
164 #if (SYSPLL_SETUP) /* System PLL Setup */
165 LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */
166 LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */
167 LPC_SYSCON->SYSPLLCLKUEN = 0x00; /* Toggle Update Register */
168 LPC_SYSCON->SYSPLLCLKUEN = 0x01;
169 while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */
170 LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
171 LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_SYSPLL_PD; /* Power-up SYSPLL */
172 while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */
174 LPC_SYSCON->PDRUNCFG |= PDRUNCFG_SYSPLL_PD; /* if PLL is not used, power-down PLL */
175 #endif /* SYSPLL_SETUP */
177 LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; /* Select Clock */
178 LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
179 LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */
180 LPC_SYSCON->MAINCLKUEN = 0x01;
181 while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */
183 #endif /* SYSCLK_SETUP */
185 #if (USBCLK_SETUP) /* USB Clock Setup */
186 LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_USBPAD_PD; /* Power-up USB PHY */
188 #if (USBPLL_SETUP) /* USB PLL Setup */
189 LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_USBPLL_PD; /* Power-up USB PLL */
190 LPC_SYSCON->USBPLLCLKSEL = USBPLLCLKSEL_Val; /* Select PLL Input */
191 LPC_SYSCON->USBPLLCLKUEN = 0x01; /* Update Clock Source */
192 LPC_SYSCON->USBPLLCLKUEN = 0x00; /* Toggle Update Register */
193 LPC_SYSCON->USBPLLCLKUEN = 0x01;
194 while (!(LPC_SYSCON->USBPLLCLKUEN & 0x01)); /* Wait Until Updated */
195 LPC_SYSCON->USBPLLCTRL = USBPLLCTRL_Val;
196 while (!(LPC_SYSCON->USBPLLSTAT & 0x01)); /* Wait Until PLL Locked */
197 LPC_SYSCON->USBCLKSEL = 0x00; /* Select USB PLL */
198 #else /* USBPLL_SETUP */
199 LPC_SYSCON->USBCLKSEL = 0x01; /* Select Main Clock */
200 #endif /* USBPLL_SETUP */
202 #else /* USBCLK_SETUP */
203 LPC_SYSCON->PDRUNCFG |= PDRUNCFG_USBPAD_PD; /* Power-down USB PHY */
204 LPC_SYSCON->PDRUNCFG |= PDRUNCFG_USBPLL_PD; /* Power-down USB PLL */
205 #endif /* USBCLK_SETUP */
207 LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val;
208 #endif /* CLOCK_SETUP */
210 LPC_SYSCON->SYSAHBCLKCTRL = AHBCLKCTRL_Val;
211 LPC_SYSCON->PDRUNCFG |= PDRUNCFG_WDTOSC_PD; /* Power down WDT, if it will be used, it should be enabled egain*/
214 //TODO: check WDT settings
215 void lpc_watchdog_feed()
220 LPC_WDT->FEED = 0xAA;
221 LPC_WDT->FEED = 0x55;
222 restore_flags(flags);
225 void lpc_watchdog_init(int on,int timeout_ms)
228 LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val;
229 LPC_SYSCON->WDTCLKDIV = 1; //preddelic musi byt >0 (0 je disable, 1= deleni 1 atd.)
230 LPC_SYSCON->PDRUNCFG &= ~PDRUNCFG_WDTOSC_PD; // Power-up WDT Clock (kdyby byl nahodou vyputy, vychozi je ale zapnuto)
231 LPC_SYSCON->SYSAHBCLKCTRL |= SAHBCCTRL_WDT; // je nutne povolit hodiny WDT v SYSAHBCLKCTRL
233 LPC_SYSCON->WDTCLKSEL = 2; //zdroj hodin bude WDT oscilator
234 LPC_SYSCON->WDTCLKUEN = 1;
235 LPC_SYSCON->WDTCLKUEN = 0;
236 LPC_SYSCON->WDTCLKUEN = 1;
237 while(!(LPC_SYSCON->WDTCLKUEN & 1));//prechozi 4 radky jsou nutne, aby se zmenil zdroj hodin
238 LPC_WDT->TC = (((__WDT_OSC_CLK) / 1000) * (timeout_ms / 4));
239 //LPC_WDT->TC = 1000;//(__WDT_OSC_CLK/4)*(1000/timeout_ms);
240 LPC_WDT->MOD = 0x03; /* Enable watchdog timer and reset */
243 void power_down_unused_periph(void)
245 if ((LPC_SYSCON->MAINCLKSEL > 0) && (LPC_SYSCON->WDTCLKSEL > 0) && ((LPC_SYSCON->SYSPLLCLKSEL > 0) || (LPC_SYSCON->PDAWAKECFG & PDRUNCFG_SYSPLL_PD)))
246 LPC_SYSCON->PDRUNCFG |= PDRUNCFG_IRCOUT_PD | PDRUNCFG_IRC_PD; /* if IRC is not used, power-down IRC */
248 //vypnu nepotrebne periferie, pokud je budu potrebovat, zapnou se v initu dane periferie
249 LPC_SYSCON->PDRUNCFG |= PDRUNCFG_ADC_PD; /* power-down ADC */