1
2 /**
3 * \file
4 *
5 * \brief SAM Oscillators Controller.
6 *
7 * Copyright (C) 2015 - 2016 Atmel Corporation. All rights reserved.
8 *
9 * \asf_license_start
10 *
11 * \page License
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright notice,
17 * this list of conditions and the following disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above copyright notice,
20 * this list of conditions and the following disclaimer in the documentation
21 * and/or other materials provided with the distribution.
22 *
23 * 3. The name of Atmel may not be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * 4. This software may only be redistributed and used in connection with an
27 * Atmel microcontroller product.
28 *
29 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
30 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
32 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
33 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 *
41 * \asf_license_stop
42 *
43 */
44 #include <compiler.h>
45 #include <hpl_init.h>
46 #include <hpl_oscctrl_config.h>
47
48 /**
49 * \brief Initialize clock sources
50 */
_oscctrl_init_sources(void)51 void _oscctrl_init_sources(void)
52 {
53 void *hw = (void *)OSCCTRL;
54
55 #if CONF_XOSC_CONFIG == 1
56 hri_oscctrl_write_XOSCCTRL_reg(hw,
57 OSCCTRL_XOSCCTRL_STARTUP(CONF_XOSC_STARTUP)
58 | (CONF_XOSC_AMPGC << OSCCTRL_XOSCCTRL_AMPGC_Pos)
59 | OSCCTRL_XOSCCTRL_GAIN(CONF_XOSC_GAIN)
60 | (CONF_XOSC_ONDEMAND << OSCCTRL_XOSCCTRL_ONDEMAND_Pos)
61 | (CONF_XOSC_RUNSTDBY << OSCCTRL_XOSCCTRL_RUNSTDBY_Pos)
62 | (CONF_XOSC_XTALEN << OSCCTRL_XOSCCTRL_XTALEN_Pos)
63 | (CONF_XOSC_ENABLE << OSCCTRL_XOSCCTRL_ENABLE_Pos));
64
65 #endif
66
67 #if CONF_OSC16M_CONFIG == 1
68 hri_oscctrl_write_OSC16MCTRL_reg(hw,
69 (CONF_OSC16M_ONDEMAND << OSCCTRL_OSC16MCTRL_ONDEMAND_Pos)
70 | (CONF_OSC16M_RUNSTDBY << OSCCTRL_OSC16MCTRL_RUNSTDBY_Pos)
71 | (CONF_OSC16M_ENABLE << OSCCTRL_OSC16MCTRL_ENABLE_Pos)
72 | OSCCTRL_OSC16MCTRL_FSEL(CONF_OSC16M_FSEL));
73 #endif
74
75 #if CONF_XOSC_CONFIG == 1
76 #if CONF_XOSC_ENABLE == 1
77 while (!hri_oscctrl_get_STATUS_XOSCRDY_bit(hw))
78 ;
79 #endif
80 #if CONF_XOSC_ONDEMAND == 1
81 hri_oscctrl_set_XOSCCTRL_ONDEMAND_bit(hw);
82 #endif
83 #endif
84
85 #if CONF_OSC16M_CONFIG == 1
86 #if CONF_OSC16M_ENABLE == 1
87 while (!hri_oscctrl_get_STATUS_OSC16MRDY_bit(hw))
88 ;
89 #endif
90 #if CONF_OSC16M_ONDEMAND == 1
91 hri_oscctrl_set_OSC16MCTRL_ONDEMAND_bit(hw);
92 #endif
93 #endif
94 (void)hw;
95 }
96
_oscctrl_init_referenced_generators(void)97 void _oscctrl_init_referenced_generators(void)
98 {
99 void * hw = (void *)OSCCTRL;
100 hri_oscctrl_dfllctrl_reg_t tmp;
101
102 #if CONF_DFLL_CONFIG == 1
103 #if CONF_DFLL_OVERWRITE_CALIBRATION == 0
104 #define NVM_DFLL_COARSE_POS 26
105 #define NVM_DFLL_COARSE_SIZE 6
106 uint32_t coarse;
107 coarse = *((uint32_t *)(NVMCTRL_OTP5)) >> NVM_DFLL_COARSE_POS;
108 #endif
109 #if CONF_DFLL_USBCRM != 1 && CONF_DFLL_MODE != 0
110 hri_gclk_write_PCHCTRL_reg(GCLK, 0, (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(CONF_DFLL_GCLK));
111 #endif
112 hri_oscctrl_write_DFLLCTRL_reg(hw, OSCCTRL_DFLLCTRL_ENABLE);
113 while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw))
114 ;
115 hri_oscctrl_write_DFLLMUL_reg(hw,
116 OSCCTRL_DFLLMUL_CSTEP(CONF_DFLL_CSTEP) | OSCCTRL_DFLLMUL_FSTEP(CONF_DFLL_FSTEP)
117 | OSCCTRL_DFLLMUL_MUL(CONF_DFLL_MUL));
118 while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw))
119 ;
120
121 #if CONF_DFLL_OVERWRITE_CALIBRATION == 0
122 /* FINE is set to fixed value, which defined by DFLL48M Characteristics */
123 hri_oscctrl_write_DFLLVAL_reg(hw, OSCCTRL_DFLLVAL_COARSE(coarse) | OSCCTRL_DFLLVAL_FINE(512));
124 #else
125 hri_oscctrl_write_DFLLVAL_reg(hw, OSCCTRL_DFLLVAL_COARSE(CONF_DFLL_COARSE) | OSCCTRL_DFLLVAL_FINE(CONF_DFLL_FINE));
126 #endif
127
128 tmp = (CONF_DFLL_WAITLOCK << OSCCTRL_DFLLCTRL_WAITLOCK_Pos) | (CONF_DFLL_BPLCKC << OSCCTRL_DFLLCTRL_BPLCKC_Pos)
129 | (CONF_DFLL_QLDIS << OSCCTRL_DFLLCTRL_QLDIS_Pos) | (CONF_DFLL_CCDIS << OSCCTRL_DFLLCTRL_CCDIS_Pos)
130 | (CONF_DFLL_RUNSTDBY << OSCCTRL_DFLLCTRL_RUNSTDBY_Pos) | (CONF_DFLL_USBCRM << OSCCTRL_DFLLCTRL_USBCRM_Pos)
131 | (CONF_DFLL_LLAW << OSCCTRL_DFLLCTRL_LLAW_Pos) | (CONF_DFLL_STABLE << OSCCTRL_DFLLCTRL_STABLE_Pos)
132 | (CONF_DFLL_MODE << OSCCTRL_DFLLCTRL_MODE_Pos) | (CONF_DFLL_ENABLE << OSCCTRL_DFLLCTRL_ENABLE_Pos);
133 hri_oscctrl_write_DFLLCTRL_reg(hw, tmp);
134
135 #endif
136
137 #if CONF_DPLL_CONFIG == 1
138 #if CONF_DPLL_REFCLK == 2
139 hri_gclk_write_PCHCTRL_reg(GCLK, 1, (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(CONF_DPLL_GCLK));
140 #endif
141 hri_oscctrl_write_DPLLRATIO_reg(
142 hw, OSCCTRL_DPLLRATIO_LDRFRAC(CONF_DPLL_LDRFRAC) | OSCCTRL_DPLLRATIO_LDR(CONF_DPLL_LDR));
143 hri_oscctrl_write_DPLLCTRLB_reg(hw,
144 OSCCTRL_DPLLCTRLB_DIV(CONF_DPLL_DIV)
145 | (CONF_DPLL_LBYPASS << OSCCTRL_DPLLCTRLB_LBYPASS_Pos)
146 | OSCCTRL_DPLLCTRLB_LTIME(CONF_DPLL_LTIME)
147 | OSCCTRL_DPLLCTRLB_REFCLK(CONF_DPLL_REFCLK)
148 | (CONF_DPLL_WUF << OSCCTRL_DPLLCTRLB_WUF_Pos)
149 | (CONF_DPLL_LPEN << OSCCTRL_DPLLCTRLB_LPEN_Pos)
150 | OSCCTRL_DPLLCTRLB_FILTER(CONF_DPLL_FILTER));
151 hri_oscctrl_write_DPLLPRESC_reg(hw, OSCCTRL_DPLLPRESC_PRESC(CONF_DPLL_PRESC));
152 hri_oscctrl_write_DPLLCTRLA_reg(hw,
153 (0 << OSCCTRL_DPLLCTRLA_ONDEMAND_Pos)
154 | (CONF_DPLL_RUNSTDBY << OSCCTRL_DPLLCTRLA_RUNSTDBY_Pos)
155 | (CONF_DPLL_ENABLE << OSCCTRL_DPLLCTRLA_ENABLE_Pos));
156 #endif
157
158 #if CONF_DFLL_CONFIG == 1
159 if (hri_oscctrl_get_DFLLCTRL_MODE_bit(hw)) {
160 hri_oscctrl_status_reg_t status_mask = OSCCTRL_STATUS_DFLLRDY | OSCCTRL_STATUS_DFLLLCKC;
161
162 while (hri_oscctrl_get_STATUS_reg(hw, status_mask) != status_mask)
163 ;
164 } else {
165 while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw))
166 ;
167 }
168 #if CONF_DFLL_ONDEMAND == 1
169 hri_oscctrl_set_DFLLCTRL_ONDEMAND_bit(hw);
170 #endif
171 #endif
172
173 #if CONF_DPLL_CONFIG == 1
174 #if CONF_DPLL_ENABLE == 1
175 while (!(hri_oscctrl_get_DPLLSTATUS_LOCK_bit(hw) || hri_oscctrl_get_DPLLSTATUS_CLKRDY_bit(hw)))
176 ;
177 #endif
178 #if CONF_DPLL_ONDEMAND == 1
179 hri_oscctrl_set_DPLLCTRLA_ONDEMAND_bit(hw);
180 #endif
181 #endif
182
183 #if CONF_DFLL_CONFIG == 1
184 while (hri_gclk_read_SYNCBUSY_reg(GCLK))
185 ;
186 #endif
187 (void)hw, (void)tmp;
188 }
189