1 /**************************************************************************/
4 @author K. Townsend (microBuilder.eu)
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.
17 #include "core/cpu/cpu.h"
21 // Initialise the CPU and setup the PLL
32 Software License Agreement (BSD License)
34 Copyright (c) 2010, microBuilder SARL
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.
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.
59 /**************************************************************************/
62 #include "core/gpio/gpio.h"
64 /**************************************************************************/
66 @brief Configures the main clock/PLL
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).
77 /**************************************************************************/
78 void cpuPllSetup (cpuMultiplier_t multiplier
)
82 // Power up system oscillator
83 SCB_PDRUNCFG
&= ~(SCB_PDRUNCFG_SYSOSC_MASK
);
85 // Setup the crystal input (bypass disabled, 1-20MHz crystal)
86 SCB_SYSOSCCTRL
= (SCB_SYSOSCCTRL_BYPASS_DISABLED
| SCB_SYSOSCCTRL_FREQRANGE_1TO20MHZ
);
88 for (i
= 0; i
< 200; i
++)
90 __asm
volatile ("NOP");
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
99 // Wait until the clock is updated
100 while (!(SCB_PLLCLKUEN
& SCB_PLLCLKUEN_UPDATE
));
105 case CPU_MULTIPLIER_2
:
106 SCB_PLLCTRL
= (SCB_PLLCTRL_MULT_2
| (1 << SCB_PLLCTRL_DIV_BIT
));
108 case CPU_MULTIPLIER_3
:
109 SCB_PLLCTRL
= (SCB_PLLCTRL_MULT_3
| (1 << SCB_PLLCTRL_DIV_BIT
));
111 case CPU_MULTIPLIER_4
:
112 SCB_PLLCTRL
= (SCB_PLLCTRL_MULT_4
| (1 << SCB_PLLCTRL_DIV_BIT
));
114 case CPU_MULTIPLIER_5
:
115 SCB_PLLCTRL
= (SCB_PLLCTRL_MULT_5
| (1 << SCB_PLLCTRL_DIV_BIT
));
117 case CPU_MULTIPLIER_6
:
118 SCB_PLLCTRL
= (SCB_PLLCTRL_MULT_6
| (1 << SCB_PLLCTRL_DIV_BIT
));
120 case CPU_MULTIPLIER_1
:
122 SCB_PLLCTRL
= (SCB_PLLCTRL_MULT_1
| (1 << SCB_PLLCTRL_DIV_BIT
));
127 SCB_PDRUNCFG
&= ~(SCB_PDRUNCFG_SYSPLL_MASK
);
129 // Wait for PLL to lock
130 while (!(SCB_PLLSTAT
& SCB_PLLSTAT_LOCK
));
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
;
138 // Wait until the clock is updated
139 while (!(SCB_MAINCLKUEN
& SCB_MAINCLKUEN_UPDATE
));
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
145 // Set system AHB clock
146 SCB_SYSAHBCLKDIV
= SCB_SYSAHBCLKDIV_DIV1
;
148 // Enabled IOCON clock for I/O related peripherals
149 SCB_SYSAHBCLKCTRL
|= SCB_SYSAHBCLKCTRL_IOCON
;
152 /**************************************************************************/
154 @brief Initialises the CPU, setting up the PLL, etc.
156 /**************************************************************************/
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
);
168 cpuPllSetup(CPU_MULTIPLIER_6
);
171 /**************************************************************************/
173 @brief Resets the device using the AIRCR register
175 /**************************************************************************/
179 SCB_AIRCR
= SCB_AIRCR_VECTKEY_VALUE
| SCB_AIRCR_SYSRESETREQ
; // 0x05FA0004
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");