a5343fb696c99b298a0f9a9a8d53c47cd65e0c73
[platform/upstream/connectedhomeip.git] / examples / platform / efr32 / efr32mg12 / BRD4166A / init_mcu.c
1 /*
2  *
3  *    Copyright (c) 2020 Project CHIP Authors
4  *    All rights reserved.
5  *
6  *    Licensed under the Apache License, Version 2.0 (the "License");
7  *    you may not use this file except in compliance with the License.
8  *    You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing, software
13  *    distributed under the License is distributed on an "AS IS" BASIS,
14  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *    See the License for the specific language governing permissions and
16  *    limitations under the License.
17  */
18 /*******************************************************************************
19  * @file
20  * @brief init_mcu.c
21  *******************************************************************************
22  * # License
23  * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
24  *******************************************************************************
25  *
26  * The licensor of this software is Silicon Laboratories Inc. Your use of this
27  * software is governed by the terms of Silicon Labs Master Software License
28  * Agreement (MSLA) available at
29  * www.silabs.com/about-us/legal/master-software-license-agreement. This
30  * software is distributed to you in Source Code format and is governed by the
31  * sections of the MSLA applicable to Source Code.
32  *
33  ******************************************************************************/
34
35 #if defined(HAL_CONFIG)
36 #include "bsphalconfig.h"
37 #include "hal-config.h"
38 #else
39 #include "bspconfig.h"
40 #endif
41
42 #include "board_features.h"
43
44 #include "em_chip.h"
45 #include "em_cmu.h"
46 #include "em_emu.h"
47 #include "em_rtcc.h"
48
49 #include "bsp.h"
50
51 #include "FreeRTOSConfig.h"
52 #include "init_mcu.h"
53
54 // Bit [19] in MODULEINFO is the HFXOCALVAL:
55 // 1=No factory cal, use default XO tunning value in FW
56 // 0=Factory Cal, use XO tunning value in DI
57 #define DEVINFO_MODULEINFO_HFXOCALVAL_MASK 0x00080000UL
58 // Calibration value for HFXO CTUNE is at DEVINFO Offset 0x08
59 #define DEVINFO_MODULEINFO_CRYSTALOSCCALVAL (*((uint16_t *) (uint32_t)(DEVINFO_BASE + 0x8UL)))
60 // [15:9] : (LFXOTUNING) Calibration for LFXO TUNING
61 // [8:0]  : (HFXOCTUNE) Calibration for HFXO CTUNE
62 #define DEVINFO_HFXOCTUNE_MASK 0x01FFUL
63
64 #define set_HFXO_CTUNE(val)                                                                                                        \
65     do                                                                                                                             \
66     {                                                                                                                              \
67         hfxoInit.ctuneSteadyState = (val);                                                                                         \
68     } while (0)
69
70 static void initMcu_clocks(void);
71 static void initHFXO(void);
72
73 void initMcu(void)
74 {
75     // ISR safe FreeRTOS API functions must *only* be called
76     // from interrupts that have been assigned a priority at or below
77     // configMAX_SYSCALL_INTERRUPT_PRIORITY.
78     // Here we init all IRQ prio to configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
79     // to make sure no IRQ use default priority of zero as that is the highest possible priority
80     for (IRQn_Type i = 0; i < EXT_IRQ_COUNT; i++)
81     {
82         NVIC_SetPriority(i, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
83     }
84
85     // Device errata
86     CHIP_Init();
87
88     // Set up DC-DC converter
89     EMU_DCDCInit_TypeDef dcdcInit = BSP_DCDC_INIT;
90 #if HAL_DCDC_BYPASS
91     dcdcInit.dcdcMode = emuDcdcMode_Bypass;
92 #endif
93     EMU_DCDCInit(&dcdcInit);
94
95     // Set up clocks
96     initMcu_clocks();
97
98     RTCC_Init_TypeDef rtccInit = RTCC_INIT_DEFAULT;
99     rtccInit.enable            = true;
100     rtccInit.debugRun          = false;
101     rtccInit.precntWrapOnCCV0  = false;
102     rtccInit.cntWrapOnCCV1     = false;
103     rtccInit.prescMode         = rtccCntTickPresc;
104     rtccInit.presc             = rtccCntPresc_1;
105     rtccInit.enaOSCFailDetect  = false;
106     rtccInit.cntMode           = rtccCntModeNormal;
107     RTCC_Init(&rtccInit);
108
109 #if defined(EMU_VSCALE_PRESENT)
110     // Set up EM0, EM1 energy mode configuration
111     EMU_EM01Init_TypeDef em01Init = EMU_EM01INIT_DEFAULT;
112     EMU_EM01Init(&em01Init);
113 #endif // EMU_VSCALE_PRESENT
114     // Set up EM2, EM3 energy mode configuration
115     EMU_EM23Init_TypeDef em23init = EMU_EM23INIT_DEFAULT;
116 #if defined(EMU_VSCALE_PRESENT)
117     em23init.vScaleEM23Voltage = emuVScaleEM23_LowPower;
118 #endif // EMU_VSCALE_PRESENT
119     EMU_EM23Init(&em23init);
120
121 #if defined(RMU_PRESENT)
122     // Set reset mode for sysreset back to DEFAULT (extended), this might have
123     // been changed by the bootloader to FULL reset.
124     RMU->CTRL = (RMU->CTRL & ~_RMU_CTRL_SYSRMODE_MASK) | RMU_CTRL_SYSRMODE_DEFAULT;
125 #endif
126 }
127
128 static void initMcu_clocks(void)
129 {
130     // Initialize HFXO
131     initHFXO();
132
133     // Set system HFXO frequency
134     SystemHFXOClockSet(BSP_CLK_HFXO_FREQ);
135
136     // Enable HFXO oscillator, and wait for it to be stable
137     CMU_OscillatorEnable(cmuOsc_HFXO, true, true);
138
139     // Enable HFXO Autostart only if EM2 voltage scaling is disabled.
140     // In 1.0 V mode the chip does not support frequencies > 21 MHz,
141     // this is why HFXO autostart is not supported in this case.
142 #if !defined(_EMU_CTRL_EM23VSCALE_MASK)
143     // Automatically start and select HFXO
144     CMU_HFXOAutostartEnable(0, true, true);
145 #else
146     CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
147 #endif //_EMU_CTRL_EM23VSCALE_MASK
148
149     // HFRCO not needed when using HFXO
150     CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
151
152     // Enabling HFBUSCLKLE clock for LE peripherals
153     CMU_ClockEnable(cmuClock_HFLE, true);
154
155     // Initialize LFXO
156     CMU_LFXOInit_TypeDef lfxoInit = BSP_CLK_LFXO_INIT;
157     lfxoInit.ctune                = BSP_CLK_LFXO_CTUNE;
158     CMU_LFXOInit(&lfxoInit);
159     // Set system LFXO frequency
160     SystemLFXOClockSet(BSP_CLK_LFXO_FREQ);
161
162     // Set LFXO if selected as LFCLK
163     CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
164     CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
165     CMU_ClockSelectSet(cmuClock_LFE, cmuSelect_LFXO);
166     CMU_ClockEnable(cmuClock_GPIO, true);
167 }
168
169 static void initHFXO(void)
170 {
171     // Initialize HFXO
172     // Use BSP_CLK_HFXO_INIT as last result (4th)
173     CMU_HFXOInit_TypeDef hfxoInit = BSP_CLK_HFXO_INIT;
174     // if Factory Cal exists in DEVINFO then use it above all (1st)
175     if (0 == (DEVINFO->MODULEINFO & DEVINFO_MODULEINFO_HFXOCALVAL_MASK))
176     {
177 #if defined(_SILICON_LABS_32B_SERIES_1)
178         set_HFXO_CTUNE(DEVINFO_MODULEINFO_CRYSTALOSCCALVAL);
179 #elif defined(_SILICON_LABS_32B_SERIES_2)
180         set_HFXO_CTUNE(DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK);
181 #endif
182     }
183     // if User page has CTUNE from studio use that in 2nd place
184 #if (MFG_CTUNE_EN == 1)
185     else if (MFG_CTUNE_VAL != 0xFFFF)
186     {
187         set_HFXO_CTUNE(MFG_CTUNE_VAL);
188     }
189 #endif
190     // 3rd option, get data from header defined for product/board
191 #if defined(BSP_CLK_HFXO_CTUNE) && BSP_CLK_HFXO_CTUNE >= 0
192     else
193     {
194         set_HFXO_CTUNE(BSP_CLK_HFXO_CTUNE);
195     }
196 #endif
197     CMU_HFXOInit(&hfxoInit);
198
199     // Set system HFXO frequency
200     SystemHFXOClockSet(BSP_CLK_HFXO_FREQ);
201 }