Fahrplan: Finale Version.
[hackover2013-badge-firmware.git] / core / cpu / cpu.c
1 /**************************************************************************/
2 /*!
3 @file cpu.c
4 @author K. Townsend (microBuilder.eu)
5 @date 22 March 2010
6 @version 0.10
7
8 @section DESCRIPTION
9
10 Initialises the CPU and any core clocks. By default, the core clock
11 is set to run at 72MHz. In order to reduce power consumption all pins
12 are set to GPIO and input by cpuInit.
13
14 @section EXAMPLE
15 @code
16 #include "lpc134x.h"
17 #include "core/cpu/cpu.h"
18
19 int main (void)
20 {
21 // Initialise the CPU and setup the PLL
22 cpuInit();
23
24 while(1)
25 {
26 }
27 }
28 @endcode
29
30 @section LICENSE
31
32 Software License Agreement (BSD License)
33
34 Copyright (c) 2010, microBuilder SARL
35 All rights reserved.
36
37 Redistribution and use in source and binary forms, with or without
38 modification, are permitted provided that the following conditions are met:
39 1. Redistributions of source code must retain the above copyright
40 notice, this list of conditions and the following disclaimer.
41 2. Redistributions in binary form must reproduce the above copyright
42 notice, this list of conditions and the following disclaimer in the
43 documentation and/or other materials provided with the distribution.
44 3. Neither the name of the copyright holders nor the
45 names of its contributors may be used to endorse or promote products
46 derived from this software without specific prior written permission.
47
48 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
49 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
52 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
56 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
57 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 */
59 /**************************************************************************/
60
61 #include "cpu.h"
62 #include "core/gpio/gpio.h"
63
64 /**************************************************************************/
65 /*!
66 @brief Configures the main clock/PLL
67
68 The speed at which the MCU operates is set here using the SCB_PLLCTRL
69 register, and the SCB_PLLCLKSEL register can be used to select which
70 oscillator to use to generate the system clocks (the internal 12MHz
71 oscillator or an external crystal).
72
73 @param[in] multiplier
74 The PLL multiplier
75
76 */
77 /**************************************************************************/
78 void cpuPllSetup (cpuMultiplier_t multiplier)
79 {
80 uint32_t i;
81
82 // Power up system oscillator
83 SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_SYSOSC_MASK);
84
85 // Setup the crystal input (bypass disabled, 1-20MHz crystal)
86 SCB_SYSOSCCTRL = (SCB_SYSOSCCTRL_BYPASS_DISABLED | SCB_SYSOSCCTRL_FREQRANGE_1TO20MHZ);
87
88 for (i = 0; i < 200; i++)
89 {
90 __asm volatile ("NOP");
91 }
92
93 // Configure PLL
94 SCB_PLLCLKSEL = SCB_CLKSEL_SOURCE_MAINOSC; // Select external crystal as PLL clock source
95 SCB_PLLCLKUEN = SCB_PLLCLKUEN_UPDATE; // Update clock source
96 SCB_PLLCLKUEN = SCB_PLLCLKUEN_DISABLE; // Toggle update register once
97 SCB_PLLCLKUEN = SCB_PLLCLKUEN_UPDATE; // Update clock source again
98
99 // Wait until the clock is updated
100 while (!(SCB_PLLCLKUEN & SCB_PLLCLKUEN_UPDATE));
101
102 // Set clock speed
103 switch (multiplier)
104 {
105 // Fclkout = M * Fclkin = FCCO / (2 * P)
106 // FCCO should be in the range of 156-320MHz
107 // (see Table 58 of the LPC1343 usermanual for examples)
108 case CPU_MULTIPLIER_2:
109 // Fclkout = 24.0MHz
110 // FCCO = 2 * 4 * 24 = 192MHz
111 SCB_PLLCTRL = (SCB_PLLCTRL_MSEL_2 | SCB_PLLCTRL_PSEL_4);
112 break;
113 case CPU_MULTIPLIER_3:
114 // Fclkout = 36.0MHz
115 // FCCO = 2 * 4 * 36 = 288MHz
116 SCB_PLLCTRL = (SCB_PLLCTRL_MSEL_3 | SCB_PLLCTRL_PSEL_4);
117 break;
118 case CPU_MULTIPLIER_4:
119 // Fclkout = 48.0MHz
120 // FCCO = 2 * 2 * 48 = 192MHz
121 SCB_PLLCTRL = (SCB_PLLCTRL_MSEL_4 | SCB_PLLCTRL_PSEL_2);
122 break;
123 case CPU_MULTIPLIER_5:
124 // Fclkout = 60.0MHz
125 // FCCO = 2 * 2 * 60 = 240MHz
126 SCB_PLLCTRL = (SCB_PLLCTRL_MSEL_5 | SCB_PLLCTRL_PSEL_2);
127 break;
128 case CPU_MULTIPLIER_6:
129 // Fclkout = 72.0MHz
130 // FCCO = 2 * 2 * 72 = 288MHz
131 SCB_PLLCTRL = (SCB_PLLCTRL_MSEL_6 | SCB_PLLCTRL_PSEL_2);
132 break;
133 case CPU_MULTIPLIER_1:
134 default:
135 // Fclkout = 12.0MHz
136 // FCCO = 2 * 8 * 12 = 192MHz
137 SCB_PLLCTRL = (SCB_PLLCTRL_MSEL_1 | SCB_PLLCTRL_PSEL_8);
138 break;
139 }
140
141 // Enable system PLL
142 SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_SYSPLL_MASK);
143
144 // Wait for PLL to lock
145 while (!(SCB_PLLSTAT & SCB_PLLSTAT_LOCK));
146
147 // Setup main clock (use PLL output)
148 SCB_MAINCLKSEL = SCB_MAINCLKSEL_SOURCE_SYSPLLCLKOUT;
149 SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; // Update clock source
150 SCB_MAINCLKUEN = SCB_MAINCLKUEN_DISABLE; // Toggle update register once
151 SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE;
152
153 // Wait until the clock is updated
154 while (!(SCB_MAINCLKUEN & SCB_MAINCLKUEN_UPDATE));
155
156 // Disable USB clock by default (enabled in USB code)
157 SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPAD_PD); // Power-down USB PHY
158 SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPLL_PD); // Power-down USB PLL
159
160 // Set system AHB clock
161 SCB_SYSAHBCLKDIV = SCB_SYSAHBCLKDIV_DIV1;
162
163 // Enabled IOCON clock for I/O related peripherals
164 SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_IOCON;
165 }
166
167 /**************************************************************************/
168 /*!
169 @brief Initialises the CPU, setting up the PLL, etc.
170 */
171 /**************************************************************************/
172 void cpuInit (void)
173 {
174 gpioInit();
175
176 // Set all GPIO pins to input by default
177 GPIO_GPIO0DIR &= ~(GPIO_IO_ALL);
178 GPIO_GPIO1DIR &= ~(GPIO_IO_ALL);
179 GPIO_GPIO2DIR &= ~(GPIO_IO_ALL);
180 GPIO_GPIO3DIR &= ~(GPIO_IO_ALL);
181
182 // Setup PLL (etc.)
183 cpuPllSetup(CPU_MULTIPLIER_6);
184 }
185
186 /**************************************************************************/
187 /*!
188 @brief Resets the device using the AIRCR register
189 */
190 /**************************************************************************/
191 void cpuReset (void)
192 {
193 // Reset device
194 SCB_AIRCR = SCB_AIRCR_VECTKEY_VALUE | SCB_AIRCR_SYSRESETREQ; // 0x05FA0004
195
196 // Ensure completion of memory access
197 // DSB acts as a special data synchronization memory barrier. Instructions
198 // that come after the DSB, in program order, do not execute until the DSB
199 // instruction completes. The DSB instruction completes when all explicit
200 // memory accesses before it complete.
201 __asm volatile("DSB");
202
203 // Wait for reset
204 while(1);
205 }
This page took 0.05484 seconds and 5 git commands to generate.