Updated to latest 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 case CPU_MULTIPLIER_2:
106 SCB_PLLCTRL = (SCB_PLLCTRL_MULT_2 | (1 << SCB_PLLCTRL_DIV_BIT));
107 break;
108 case CPU_MULTIPLIER_3:
109 SCB_PLLCTRL = (SCB_PLLCTRL_MULT_3 | (1 << SCB_PLLCTRL_DIV_BIT));
110 break;
111 case CPU_MULTIPLIER_4:
112 SCB_PLLCTRL = (SCB_PLLCTRL_MULT_4 | (1 << SCB_PLLCTRL_DIV_BIT));
113 break;
114 case CPU_MULTIPLIER_5:
115 SCB_PLLCTRL = (SCB_PLLCTRL_MULT_5 | (1 << SCB_PLLCTRL_DIV_BIT));
116 break;
117 case CPU_MULTIPLIER_6:
118 SCB_PLLCTRL = (SCB_PLLCTRL_MULT_6 | (1 << SCB_PLLCTRL_DIV_BIT));
119 break;
120 case CPU_MULTIPLIER_1:
121 default:
122 SCB_PLLCTRL = (SCB_PLLCTRL_MULT_1 | (1 << SCB_PLLCTRL_DIV_BIT));
123 break;
124 }
125
126 // Enable system PLL
127 SCB_PDRUNCFG &= ~(SCB_PDRUNCFG_SYSPLL_MASK);
128
129 // Wait for PLL to lock
130 while (!(SCB_PLLSTAT & SCB_PLLSTAT_LOCK));
131
132 // Setup main clock (use PLL output)
133 SCB_MAINCLKSEL = SCB_MAINCLKSEL_SOURCE_SYSPLLCLKOUT;
134 SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE; // Update clock source
135 SCB_MAINCLKUEN = SCB_MAINCLKUEN_DISABLE; // Toggle update register once
136 SCB_MAINCLKUEN = SCB_MAINCLKUEN_UPDATE;
137
138 // Wait until the clock is updated
139 while (!(SCB_MAINCLKUEN & SCB_MAINCLKUEN_UPDATE));
140
141 // Disable USB clock by default (enabled in USB code)
142 SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPAD_PD); // Power-down USB PHY
143 SCB_PDRUNCFG |= (SCB_PDSLEEPCFG_USBPLL_PD); // Power-down USB PLL
144
145 // Set system AHB clock
146 SCB_SYSAHBCLKDIV = SCB_SYSAHBCLKDIV_DIV1;
147
148 // Enabled IOCON clock for I/O related peripherals
149 SCB_SYSAHBCLKCTRL |= SCB_SYSAHBCLKCTRL_IOCON;
150 }
151
152 /**************************************************************************/
153 /*!
154 @brief Initialises the CPU, setting up the PLL, etc.
155 */
156 /**************************************************************************/
157 void cpuInit (void)
158 {
159 gpioInit();
160
161 // Set all GPIO pins to input by default
162 GPIO_GPIO0DIR &= ~(GPIO_IO_ALL);
163 GPIO_GPIO1DIR &= ~(GPIO_IO_ALL);
164 GPIO_GPIO2DIR &= ~(GPIO_IO_ALL);
165 GPIO_GPIO3DIR &= ~(GPIO_IO_ALL);
166
167 // Setup PLL (etc.)
168 cpuPllSetup(CPU_MULTIPLIER_6);
169 }
170
171 /**************************************************************************/
172 /*!
173 @brief Resets the device using the AIRCR register
174 */
175 /**************************************************************************/
176 void cpuReset (void)
177 {
178 // Reset device
179 SCB_AIRCR = SCB_AIRCR_VECTKEY_VALUE | SCB_AIRCR_SYSRESETREQ; // 0x05FA0004
180
181 // Ensure completion of memory access
182 // DSB acts as a special data synchronization memory barrier. Instructions
183 // that come after the DSB, in program order, do not execute until the DSB
184 // instruction completes. The DSB instruction completes when all explicit
185 // memory accesses before it complete.
186 __asm volatile("DSB");
187
188 // Wait for reset
189 while(1);
190 }
This page took 0.059842 seconds and 5 git commands to generate.