7e03bf6ef358b4950d50db10ff72e00d18039b40
[bertos.git] / bertos / cpu / arm / hw / init_lpc2.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \author Francesco Sacchi <batt@develer.com>
34  *
35  * \brief LPC2378 CRT.
36  */\r
37 #include <cpu/irq.h>\r
38 \r
39 #include <io/lpc23xx.h>\r
40 \r
41 #if CPU_FREQ != 72000000UL
42         /* Avoid errors on nightly test */
43         #if !defined(ARCH_NIGHTTEST) || !(ARCH & ARCH_NIGHTTEST)
44                 #warning Clock registers set for 72MHz operation, revise following code if you want a different clock.
45         #endif
46 #endif
47
48 /*
49  * With a 12MHz cristal, master clock is:
50  * (((2 * 12 * (PLL_MUL_VAL + 1)) / (PLL_DIV_VAL + 1)) / (LPC2_CPUCLOCK_DIV + 1))= 72MHz
51  */
52 #define PLL_MUL_VAL  11
53 #define PLL_DIV_VAL  0
54 #define LPC2_CPUCLOCK_DIV 3
55 \r
56 \r
57 /* PLL feed sequence */\r
58 #define PLL_FEED_SEQ() ATOMIC(PLLFEED = 0xAA; PLLFEED = 0x55;)\r
59 \r
60 static void configurePll(void)\r
61 {\r
62         /* Disconnect and disable the PLL, if already active */\r
63         if (PLLSTAT & (1 << 25))\r
64         {\r
65                 /* Disconnect PLL, but leave it enabled */\r
66                 PLLCON = 0x01;\r
67                 PLL_FEED_SEQ();\r
68                 /* Disable PLL */\r
69                 PLLCON = 0;\r
70                 PLL_FEED_SEQ();\r
71         }\r
72 \r
73         /* Enable the main oscillator and wait for it to be stable */\r
74         SCS |= (1 << 5);\r
75     while (!(SCS & (1 << 6))) ;\r
76 \r
77         /* Select the main oscillator as the PLL clock source */\r
78         CLKSRCSEL = 0x01;\r
79 \r
80         /* Set up PLL mul and div */\r
81         PLLCFG = PLL_MUL_VAL | (PLL_DIV_VAL << 16);\r
82         PLL_FEED_SEQ();\r
83         \r
84         /* Enable PLL, disconnected */\r
85         PLLCON = 0x01;\r
86         PLL_FEED_SEQ();\r
87 \r
88         /* Set clock divider */\r
89         CCLKCFG = LPC2_CPUCLOCK_DIV;\r
90 \r
91         /* Wait for the PLL to lock */\r
92         while (!(PLLSTAT & (1 << 26))) ;\r
93     \r
94         /* Enable and connect the PLL */\r
95     PLLCON = 0x03;\r
96         PLL_FEED_SEQ();\r
97 }\r
98 \r
99 void __init1(void);\r
100 \r
101 void __init1(void)\r
102 {\r
103         /* Map irq vectors to internal flash */\r
104         MEMMAP = 0x01;\r
105         /* Configure PLL, switch from IRC to Main OSC */\r
106         configurePll();\r
107 \r
108         /* Set memory accelerator module flash timings */\r
109 #if CPU_FREQ < 20000000UL\r
110         MAMTIM = 1;\r
111 #elif CPU_FREQ < 40000000UL\r
112         MAMTIM = 2;\r
113 #elif CPU_FREQ < 60000000UL\r
114         MAMTIM = 3;\r
115 #else\r
116         MAMTIM = 4;\r
117 #endif\r
118         \r
119         /* Memory accelerator module fully enabled */\r
120         MAMCR = 0x02;\r
121 }\r