-
Notifications
You must be signed in to change notification settings - Fork 2k
/
cpu.c
173 lines (146 loc) · 4.11 KB
/
cpu.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
* Copyright (C) 2015-2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_efm32
* @{
*
* @file
* @brief Implementation of the CPU initialization
*
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
* @author Bas Stottelaar <basstottelaar@gmail.com>
*
* @}
*/
#include "cpu.h"
#include "periph_conf.h"
#include "periph/init.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_emu.h"
/**
* @brief Default settings for CMU initialization.
*/
#ifndef CMU_HFXOINIT
#define CMU_HFXOINIT CMU_HFXOINIT_DEFAULT
#endif
#ifndef CMU_LFXOINIT
#define CMU_LFXOINIT CMU_LFXOINIT_DEFAULT
#endif
/**
* @brief Default settings for EMU initialization
*/
#ifndef EMU_DCDCINIT
#define EMU_DCDCINIT EMU_DCDCINIT_DEFAULT
#endif
#ifndef EMU_EM23INIT
#define EMU_EM23INIT EMU_EM23INIT_DEFAULT
#endif
#ifndef EMU_EM4INIT
#define EMU_EM4INIT EMU_EM4INIT_DEFAULT
#endif
#ifdef _SILICON_LABS_32B_SERIES_1
/**
* @brief Initialize integrated DC-DC regulator
*/
static void dcdc_init(void)
{
EMU_DCDCInit_TypeDef init_dcdc = EMU_DCDCINIT;
EMU_DCDCInit(&init_dcdc);
}
#endif
/**
* @brief Configure clock sources and the CPU frequency
*
* On a EFM32 CPU, there are two options for selecting the main clock
* source, using an external clock source (HFXO), or using the internal RC
* oscillator (HFRCO, enabled by default).
*
* The clocks for the LFA, LFB, LFE and HFPER are also configured.
*
* When selecting the HFXO, the HFRCO is disabled. The same applies for the
* LFA, LFB and LFE branch, in case the LFXO is selected.
*/
static void clk_init(void)
{
/* initialize HFXO with board-specific parameters before switching */
if (CLOCK_HF == cmuSelect_HFXO) {
CMU_HFXOInit_TypeDef init_hfxo = CMU_HFXOINIT;
CMU_HFXOInit(&init_hfxo);
}
/* set (and enable) the HF clock source */
CMU_ClockSelectSet(cmuClock_HF, CLOCK_HF);
CMU_ClockDivSet(cmuClock_CORE, CLOCK_CORE_DIV);
/* disable the HFRCO if external crystal is used */
if (CLOCK_HF == cmuSelect_HFXO) {
CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
}
/* initialize LFXO with board-specific parameters before switching */
if (CLOCK_LFA == cmuSelect_LFXO || CLOCK_LFB == cmuSelect_LFXO ||
#ifdef _SILICON_LABS_32B_SERIES_1
CLOCK_LFE == cmuSelect_LFXO)
#else
false)
#endif
{
CMU_LFXOInit_TypeDef init_lfxo = CMU_LFXOINIT;
CMU_LFXOInit(&init_lfxo);
}
/* set (and enable) the LFA clock source */
CMU_ClockSelectSet(cmuClock_LFA, CLOCK_LFA);
/* set (and enable) the LFB clock source */
CMU_ClockSelectSet(cmuClock_LFB, CLOCK_LFB);
#ifdef _SILICON_LABS_32B_SERIES_1
/* set (and enable) the LFE clock source */
CMU_ClockSelectSet(cmuClock_LFE, CLOCK_LFE);
#endif
/* disable the LFRCO if external crystal is used */
if (CLOCK_LFA == cmuSelect_LFXO && CLOCK_LFB == cmuSelect_LFXO &&
#ifdef _SILICON_LABS_32B_SERIES_1
CLOCK_LFE == cmuSelect_LFXO)
#else
true)
#endif
{
CMU_OscillatorEnable(cmuOsc_LFRCO, false, false);
}
}
/**
* @brief Initialize sleep modes
*
* The EFM32 has several energy saving modes (EM0 - EM4), of which deeper
* modes save more energy.s
*/
static void pm_init(void)
{
/* initialize EM2 and EM3 */
EMU_EM23Init_TypeDef init_em23 = EMU_EM23INIT;
EMU_EM23Init(&init_em23);
#ifdef _SILICON_LABS_32B_SERIES_1
/* initialize EM4 */
EMU_EM4Init_TypeDef init_em4 = EMU_EM4INIT;
EMU_EM4Init(&init_em4);
#endif
}
void cpu_init(void)
{
/* apply errata that may be applicable (see em_chip.h) */
CHIP_Init();
/* initialize the Cortex-M core */
cortexm_init();
#ifdef _SILICON_LABS_32B_SERIES_1
/* initialize dc-dc */
dcdc_init();
#endif
/* initialize clock sources and generic clocks */
clk_init();
/* initialize power management interface */
pm_init();
/* trigger static peripheral initialization */
periph_init();
}