1 /***************************************************************************//**
2  * @file
3  * @brief Device initialization for DPLL.
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2019 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 #include "sl_device_init_dpll.h"
31 #include "sl_device_init_dpll_config.h"
32 
33 #include "em_cmu.h"
34 
sl_device_init_dpll(void)35 sl_status_t sl_device_init_dpll(void)
36 {
37   CMU_DPLLInit_TypeDef dpll_init = {
38     .frequency = SL_DEVICE_INIT_DPLL_FREQ,
39     .n = SL_DEVICE_INIT_DPLL_N,
40     .m = SL_DEVICE_INIT_DPLL_M,
41     .refClk = SL_DEVICE_INIT_DPLL_REFCLK,
42     .edgeSel = SL_DEVICE_INIT_DPLL_EDGE,
43     .lockMode = SL_DEVICE_INIT_DPLL_LOCKMODE,
44     .autoRecover = SL_DEVICE_INIT_DPLL_AUTORECOVER,
45     .ditherEn = SL_DEVICE_INIT_DPLL_DITHER
46   };
47 
48   CMU_Select_TypeDef selected_sysclk = CMU_ClockSelectGet(cmuClock_SYSCLK);
49 
50   if (selected_sysclk == cmuSelect_HFRCODPLL) {
51     // From Reference Manual:
52     // The CMU should not be running from the HFRCO. If necessary, the CMU
53     // should switch to the FSRCO until after the DPLL has locked to avoid
54     // over-clocking due to overshoot.
55     CMU_CLOCK_SELECT_SET(SYSCLK, FSRCO);
56   }
57 
58 #if (_SILICON_LABS_32B_SERIES_2_CONFIG > 1)
59   CMU_ClockEnable(cmuClock_DPLL0, true);
60 #endif
61 
62   bool success = CMU_DPLLLock(&dpll_init);
63 
64   if (selected_sysclk == cmuSelect_HFRCODPLL) {
65     CMU_CLOCK_SELECT_SET(SYSCLK, HFRCODPLL);
66   }
67 
68   if (success) {
69     return SL_STATUS_OK;
70   } else {
71     return SL_STATUS_FAIL;
72   }
73 }
74