d9982bcdc84fe0cc181ac390b99adbc024d44aff
[platform/upstream/connectedhomeip.git] / examples / platform / efr32 / efr32mg12 / BRD4163A / 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 "FreeRTOSConfig.h"
50 #include "bsp.h"
51 #include "init_mcu.h"
52
53 // Bit [19] in MODULEINFO is the HFXOCALVAL:
54 // 1=No factory cal, use default XO tunning value in FW
55 // 0=Factory Cal, use XO tunning value in DI
56 #define DEVINFO_MODULEINFO_HFXOCALVAL_MASK 0x00080000UL
57 // Calibration value for HFXO CTUNE is at DEVINFO Offset 0x08
58 #define DEVINFO_MODULEINFO_CRYSTALOSCCALVAL (*((uint16_t *) (uint32_t)(DEVINFO_BASE + 0x8UL)))
59 // [15:9] : (LFXOTUNING) Calibration for LFXO TUNING
60 // [8:0]  : (HFXOCTUNE) Calibration for HFXO CTUNE
61 #define DEVINFO_HFXOCTUNE_MASK 0x01FFUL
62
63 #define set_HFXO_CTUNE(val)                                                                                                        \
64     do                                                                                                                             \
65     {                                                                                                                              \
66         hfxoInit.ctuneSteadyState = (val);                                                                                         \
67     } while (0)
68
69 static void initMcu_clocks(void);
70 static void initHFXO(void);
71
72 void initMcu(void)
73 {
74     // ISR safe FreeRTOS API functions must *only* be called
75     // from interrupts that have been assigned a priority at or below
76     // configMAX_SYSCALL_INTERRUPT_PRIORITY.
77     // Here we init all IRQ prio to configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
78     // to make sure no IRQ use default priority of zero as that is the highest possible priority
79     for (IRQn_Type i = 0; i < EXT_IRQ_COUNT; i++)
80     {
81         NVIC_SetPriority(i, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
82     }
83     // Device errata
84     CHIP_Init();
85
86     // Set up DC-DC converter
87     EMU_DCDCInit_TypeDef dcdcInit = BSP_DCDC_INIT;
88 #if HAL_DCDC_BYPASS
89     dcdcInit.dcdcMode = emuDcdcMode_Bypass;
90 #endif
91     EMU_DCDCInit(&dcdcInit);
92
93     // Set up clocks
94     initMcu_clocks();
95
96     RTCC_Init_TypeDef rtccInit = RTCC_INIT_DEFAULT;
97     rtccInit.enable            = true;
98     rtccInit.debugRun          = false;
99     rtccInit.precntWrapOnCCV0  = false;
100     rtccInit.cntWrapOnCCV1     = false;
101     rtccInit.prescMode         = rtccCntTickPresc;
102     rtccInit.presc             = rtccCntPresc_1;
103     rtccInit.enaOSCFailDetect  = false;
104     rtccInit.cntMode           = rtccCntModeNormal;
105     RTCC_Init(&rtccInit);
106
107 #if defined(EMU_VSCALE_PRESENT)
108     // Set up EM0, EM1 energy mode configuration
109     EMU_EM01Init_TypeDef em01Init = EMU_EM01INIT_DEFAULT;
110     EMU_EM01Init(&em01Init);
111 #endif // EMU_VSCALE_PRESENT
112     // Set up EM2, EM3 energy mode configuration
113     EMU_EM23Init_TypeDef em23init = EMU_EM23INIT_DEFAULT;
114 #if defined(EMU_VSCALE_PRESENT)
115     em23init.vScaleEM23Voltage = emuVScaleEM23_LowPower;
116 #endif // EMU_VSCALE_PRESENT
117     EMU_EM23Init(&em23init);
118
119 #if defined(RMU_PRESENT)
120     // Set reset mode for sysreset back to DEFAULT (extended), this might have
121     // been changed by the bootloader to FULL reset.
122     RMU->CTRL = (RMU->CTRL & ~_RMU_CTRL_SYSRMODE_MASK) | RMU_CTRL_SYSRMODE_DEFAULT;
123 #endif
124 }
125
126 static void initMcu_clocks(void)
127 {
128     // Initialize HFXO
129     initHFXO();
130
131     // Set system HFXO frequency
132     SystemHFXOClockSet(BSP_CLK_HFXO_FREQ);
133
134     // Enable HFXO oscillator, and wait for it to be stable
135     CMU_OscillatorEnable(cmuOsc_HFXO, true, true);
136
137     // Enable HFXO Autostart only if EM2 voltage scaling is disabled.
138     // In 1.0 V mode the chip does not support frequencies > 21 MHz,
139     // this is why HFXO autostart is not supported in this case.
140 #if !defined(_EMU_CTRL_EM23VSCALE_MASK)
141     // Automatically start and select HFXO
142     CMU_HFXOAutostartEnable(0, true, true);
143 #else
144     CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
145 #endif //_EMU_CTRL_EM23VSCALE_MASK
146
147     // HFRCO not needed when using HFXO
148     CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
149
150     // Enabling HFBUSCLKLE clock for LE peripherals
151     CMU_ClockEnable(cmuClock_HFLE, true);
152
153     // Initialize LFXO
154     CMU_LFXOInit_TypeDef lfxoInit = BSP_CLK_LFXO_INIT;
155     lfxoInit.ctune                = BSP_CLK_LFXO_CTUNE;
156     CMU_LFXOInit(&lfxoInit);
157     // Set system LFXO frequency
158     SystemLFXOClockSet(BSP_CLK_LFXO_FREQ);
159
160     // Set LFXO if selected as LFCLK
161     CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
162     CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
163     CMU_ClockSelectSet(cmuClock_LFE, cmuSelect_LFXO);
164 }
165
166 static void initHFXO(void)
167 {
168     // Initialize HFXO
169     // Use BSP_CLK_HFXO_INIT as last result (4th)
170     CMU_HFXOInit_TypeDef hfxoInit = BSP_CLK_HFXO_INIT;
171     // if Factory Cal exists in DEVINFO then use it above all (1st)
172     if (0 == (DEVINFO->MODULEINFO & DEVINFO_MODULEINFO_HFXOCALVAL_MASK))
173     {
174 #if defined(_SILICON_LABS_32B_SERIES_1)
175         set_HFXO_CTUNE(DEVINFO_MODULEINFO_CRYSTALOSCCALVAL);
176 #elif defined(_SILICON_LABS_32B_SERIES_2)
177         set_HFXO_CTUNE(DEVINFO->MODXOCAL & _DEVINFO_MODXOCAL_HFXOCTUNEXIANA_MASK);
178 #endif
179     }
180     // if User page has CTUNE from studio use that in 2nd place
181 #if (MFG_CTUNE_EN == 1)
182     else if (MFG_CTUNE_VAL != 0xFFFF)
183     {
184         set_HFXO_CTUNE(MFG_CTUNE_VAL);
185     }
186 #endif
187     // 3rd option, get data from header defined for product/board
188 #if defined(BSP_CLK_HFXO_CTUNE) && BSP_CLK_HFXO_CTUNE >= 0
189     else
190     {
191         set_HFXO_CTUNE(BSP_CLK_HFXO_CTUNE);
192     }
193 #endif
194     CMU_HFXOInit(&hfxoInit);
195 }