Kévin Redon | 69b92d9 | 2019-01-24 16:39:20 +0100 | [diff] [blame] | 1 | |
| 2 | /** |
| 3 | * \file |
| 4 | * |
| 5 | * \brief SAM Oscillators Controller. |
| 6 | * |
| 7 | * Copyright (c) 2016-2018 Microchip Technology Inc. and its subsidiaries. |
| 8 | * |
| 9 | * \asf_license_start |
| 10 | * |
| 11 | * \page License |
| 12 | * |
| 13 | * Subject to your compliance with these terms, you may use Microchip |
| 14 | * software and any derivatives exclusively with Microchip products. |
| 15 | * It is your responsibility to comply with third party license terms applicable |
| 16 | * to your use of third party software (including open source software) that |
| 17 | * may accompany Microchip software. |
| 18 | * |
| 19 | * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, |
| 20 | * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, |
| 21 | * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, |
| 22 | * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE |
| 23 | * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL |
| 24 | * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE |
| 25 | * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE |
| 26 | * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT |
| 27 | * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY |
| 28 | * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, |
| 29 | * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. |
| 30 | * |
| 31 | * \asf_license_stop |
| 32 | * |
| 33 | */ |
| 34 | |
| 35 | #include <hpl_init.h> |
| 36 | #include <hpl_oscctrl_config.h> |
| 37 | #include <hpl_gclk_config.h> |
| 38 | |
| 39 | /** |
| 40 | * \brief Initialize clock sources |
| 41 | */ |
| 42 | void _oscctrl_init_sources(void) |
| 43 | { |
| 44 | void *hw = (void *)OSCCTRL; |
| 45 | |
| 46 | #if CONF_XOSC0_CONFIG == 1 |
| 47 | hri_oscctrl_write_XOSCCTRL_reg( |
| 48 | hw, |
| 49 | 0, |
| 50 | OSCCTRL_XOSCCTRL_CFDPRESC(CONF_XOSC0_CFDPRESC) | OSCCTRL_XOSCCTRL_STARTUP(CONF_XOSC0_STARTUP) |
| 51 | | (CONF_XOSC0_SWBEN << OSCCTRL_XOSCCTRL_SWBEN_Pos) | (CONF_XOSC0_CFDEN << OSCCTRL_XOSCCTRL_CFDEN_Pos) |
| 52 | | (0 << OSCCTRL_XOSCCTRL_ENALC_Pos) | OSCCTRL_XOSCCTRL_IMULT(CONF_XOSC0_IMULT) |
| 53 | | OSCCTRL_XOSCCTRL_IPTAT(CONF_XOSC0_IPTAT) | (CONF_XOSC0_LOWBUFGAIN << OSCCTRL_XOSCCTRL_LOWBUFGAIN_Pos) |
| 54 | | (0 << OSCCTRL_XOSCCTRL_ONDEMAND_Pos) | (CONF_XOSC0_RUNSTDBY << OSCCTRL_XOSCCTRL_RUNSTDBY_Pos) |
| 55 | | (CONF_XOSC0_XTALEN << OSCCTRL_XOSCCTRL_XTALEN_Pos) | (CONF_XOSC0_ENABLE << OSCCTRL_XOSCCTRL_ENABLE_Pos)); |
| 56 | #endif |
| 57 | |
| 58 | #if CONF_XOSC0_CONFIG == 1 |
| 59 | #if CONF_XOSC0_ENABLE == 1 |
| 60 | while (!hri_oscctrl_get_STATUS_XOSCRDY0_bit(hw)) |
| 61 | ; |
| 62 | #endif |
| 63 | #if CONF_XOSC0_ENALC == 1 |
| 64 | hri_oscctrl_set_XOSCCTRL_ENALC_bit(hw, 0); |
| 65 | #endif |
| 66 | #if CONF_XOSC0_ONDEMAND == 1 |
| 67 | hri_oscctrl_set_XOSCCTRL_ONDEMAND_bit(hw, 0); |
| 68 | #endif |
| 69 | #endif |
| 70 | |
| 71 | #if CONF_XOSC1_CONFIG == 1 |
| 72 | hri_oscctrl_write_XOSCCTRL_reg( |
| 73 | hw, |
| 74 | 1, |
| 75 | OSCCTRL_XOSCCTRL_CFDPRESC(CONF_XOSC1_CFDPRESC) | OSCCTRL_XOSCCTRL_STARTUP(CONF_XOSC1_STARTUP) |
| 76 | | (CONF_XOSC1_SWBEN << OSCCTRL_XOSCCTRL_SWBEN_Pos) | (CONF_XOSC1_CFDEN << OSCCTRL_XOSCCTRL_CFDEN_Pos) |
| 77 | | (0 << OSCCTRL_XOSCCTRL_ENALC_Pos) | OSCCTRL_XOSCCTRL_IMULT(CONF_XOSC1_IMULT) |
| 78 | | OSCCTRL_XOSCCTRL_IPTAT(CONF_XOSC1_IPTAT) | (CONF_XOSC1_LOWBUFGAIN << OSCCTRL_XOSCCTRL_LOWBUFGAIN_Pos) |
| 79 | | (0 << OSCCTRL_XOSCCTRL_ONDEMAND_Pos) | (CONF_XOSC1_RUNSTDBY << OSCCTRL_XOSCCTRL_RUNSTDBY_Pos) |
| 80 | | (CONF_XOSC1_XTALEN << OSCCTRL_XOSCCTRL_XTALEN_Pos) | (CONF_XOSC1_ENABLE << OSCCTRL_XOSCCTRL_ENABLE_Pos)); |
| 81 | #endif |
| 82 | |
| 83 | #if CONF_XOSC1_CONFIG == 1 |
| 84 | #if CONF_XOSC1_ENABLE == 1 |
| 85 | while (!hri_oscctrl_get_STATUS_XOSCRDY1_bit(hw)) |
| 86 | ; |
| 87 | #endif |
| 88 | #if CONF_XOSC1_ENALC == 1 |
| 89 | hri_oscctrl_set_XOSCCTRL_ENALC_bit(hw, 1); |
| 90 | #endif |
| 91 | #if CONF_XOSC1_ONDEMAND == 1 |
| 92 | hri_oscctrl_set_XOSCCTRL_ONDEMAND_bit(hw, 1); |
| 93 | #endif |
| 94 | #endif |
| 95 | |
| 96 | (void)hw; |
| 97 | } |
| 98 | |
| 99 | void _oscctrl_init_referenced_generators(void) |
| 100 | { |
| 101 | void *hw = (void *)OSCCTRL; |
| 102 | |
| 103 | #if CONF_DFLL_CONFIG == 1 |
| 104 | hri_gclk_write_GENCTRL_SRC_bf(GCLK, 0, GCLK_GENCTRL_SRC_OSCULP32K); |
| 105 | while (hri_gclk_get_SYNCBUSY_GENCTRL0_bit(GCLK)) |
| 106 | ; |
| 107 | uint8_t tmp; |
| 108 | hri_oscctrl_write_DFLLCTRLA_reg(hw, 0); |
| 109 | #if CONF_DFLL_USBCRM != 1 && CONF_DFLL_MODE != 0 |
| 110 | hri_gclk_write_PCHCTRL_reg( |
| 111 | GCLK, OSCCTRL_GCLK_ID_DFLL48, (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(CONF_DFLL_GCLK)); |
| 112 | #endif |
| 113 | |
| 114 | hri_oscctrl_write_DFLLMUL_reg(hw, |
| 115 | OSCCTRL_DFLLMUL_CSTEP(CONF_DFLL_CSTEP) | OSCCTRL_DFLLMUL_FSTEP(CONF_DFLL_FSTEP) |
| 116 | | OSCCTRL_DFLLMUL_MUL(CONF_DFLL_MUL)); |
| 117 | while (hri_oscctrl_get_DFLLSYNC_DFLLMUL_bit(hw)) |
| 118 | ; |
| 119 | |
| 120 | hri_oscctrl_write_DFLLCTRLB_reg(hw, 0); |
| 121 | while (hri_oscctrl_get_DFLLSYNC_DFLLCTRLB_bit(hw)) |
| 122 | ; |
| 123 | |
| 124 | tmp = (CONF_DFLL_RUNSTDBY << OSCCTRL_DFLLCTRLA_RUNSTDBY_Pos) | OSCCTRL_DFLLCTRLA_ENABLE; |
| 125 | hri_oscctrl_write_DFLLCTRLA_reg(hw, tmp); |
| 126 | while (hri_oscctrl_get_DFLLSYNC_ENABLE_bit(hw)) |
| 127 | ; |
| 128 | |
| 129 | #if CONF_DFLL_OVERWRITE_CALIBRATION == 1 |
| 130 | hri_oscctrl_write_DFLLVAL_reg(hw, OSCCTRL_DFLLVAL_COARSE(CONF_DFLL_COARSE) | OSCCTRL_DFLLVAL_FINE(CONF_DFLL_FINE)); |
| 131 | #endif |
| 132 | hri_oscctrl_write_DFLLVAL_reg(hw, hri_oscctrl_read_DFLLVAL_reg(hw)); |
| 133 | while (hri_oscctrl_get_DFLLSYNC_DFLLVAL_bit(hw)) |
| 134 | ; |
| 135 | |
| 136 | tmp = (CONF_DFLL_WAITLOCK << OSCCTRL_DFLLCTRLB_WAITLOCK_Pos) | (CONF_DFLL_BPLCKC << OSCCTRL_DFLLCTRLB_BPLCKC_Pos) |
| 137 | | (CONF_DFLL_QLDIS << OSCCTRL_DFLLCTRLB_QLDIS_Pos) | (CONF_DFLL_CCDIS << OSCCTRL_DFLLCTRLB_CCDIS_Pos) |
| 138 | | (CONF_DFLL_USBCRM << OSCCTRL_DFLLCTRLB_USBCRM_Pos) | (CONF_DFLL_LLAW << OSCCTRL_DFLLCTRLB_LLAW_Pos) |
| 139 | | (CONF_DFLL_STABLE << OSCCTRL_DFLLCTRLB_STABLE_Pos) | (CONF_DFLL_MODE << OSCCTRL_DFLLCTRLB_MODE_Pos) | 0; |
| 140 | hri_oscctrl_write_DFLLCTRLB_reg(hw, tmp); |
| 141 | while (hri_oscctrl_get_DFLLSYNC_DFLLCTRLB_bit(hw)) |
| 142 | ; |
| 143 | #endif |
| 144 | |
| 145 | #if CONF_FDPLL0_CONFIG == 1 |
| 146 | #if CONF_FDPLL0_REFCLK == 0 |
| 147 | hri_gclk_write_PCHCTRL_reg( |
| 148 | GCLK, OSCCTRL_GCLK_ID_FDPLL0, (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(CONF_FDPLL0_GCLK)); |
| 149 | #endif |
| 150 | hri_oscctrl_write_DPLLRATIO_reg( |
| 151 | hw, 0, OSCCTRL_DPLLRATIO_LDRFRAC(CONF_FDPLL0_LDRFRAC) | OSCCTRL_DPLLRATIO_LDR(CONF_FDPLL0_LDR)); |
| 152 | hri_oscctrl_write_DPLLCTRLB_reg( |
| 153 | hw, |
| 154 | 0, |
| 155 | OSCCTRL_DPLLCTRLB_DIV(CONF_FDPLL0_DIV) | (CONF_FDPLL0_DCOEN << OSCCTRL_DPLLCTRLB_DCOEN_Pos) |
| 156 | | OSCCTRL_DPLLCTRLB_DCOFILTER(CONF_FDPLL0_DCOFILTER) |
| 157 | | (CONF_FDPLL0_LBYPASS << OSCCTRL_DPLLCTRLB_LBYPASS_Pos) | OSCCTRL_DPLLCTRLB_LTIME(CONF_FDPLL0_LTIME) |
| 158 | | OSCCTRL_DPLLCTRLB_REFCLK(CONF_FDPLL0_REFCLK) | (CONF_FDPLL0_WUF << OSCCTRL_DPLLCTRLB_WUF_Pos) |
| 159 | | OSCCTRL_DPLLCTRLB_FILTER(CONF_FDPLL0_FILTER)); |
| 160 | hri_oscctrl_write_DPLLCTRLA_reg(hw, |
| 161 | 0, |
| 162 | (CONF_FDPLL0_RUNSTDBY << OSCCTRL_DPLLCTRLA_RUNSTDBY_Pos) |
| 163 | | (CONF_FDPLL0_ENABLE << OSCCTRL_DPLLCTRLA_ENABLE_Pos)); |
| 164 | #endif |
| 165 | |
| 166 | #if CONF_FDPLL1_CONFIG == 1 |
| 167 | #if CONF_FDPLL1_REFCLK == 0 |
| 168 | hri_gclk_write_PCHCTRL_reg( |
| 169 | GCLK, OSCCTRL_GCLK_ID_FDPLL1, (1 << GCLK_PCHCTRL_CHEN_Pos) | GCLK_PCHCTRL_GEN(CONF_FDPLL1_GCLK)); |
| 170 | #endif |
| 171 | hri_oscctrl_write_DPLLRATIO_reg( |
| 172 | hw, 1, OSCCTRL_DPLLRATIO_LDRFRAC(CONF_FDPLL1_LDRFRAC) | OSCCTRL_DPLLRATIO_LDR(CONF_FDPLL1_LDR)); |
| 173 | hri_oscctrl_write_DPLLCTRLB_reg( |
| 174 | hw, |
| 175 | 1, |
| 176 | OSCCTRL_DPLLCTRLB_DIV(CONF_FDPLL1_DIV) | (CONF_FDPLL1_DCOEN << OSCCTRL_DPLLCTRLB_DCOEN_Pos) |
| 177 | | OSCCTRL_DPLLCTRLB_DCOFILTER(CONF_FDPLL1_DCOFILTER) |
| 178 | | (CONF_FDPLL1_LBYPASS << OSCCTRL_DPLLCTRLB_LBYPASS_Pos) | OSCCTRL_DPLLCTRLB_LTIME(CONF_FDPLL1_LTIME) |
| 179 | | OSCCTRL_DPLLCTRLB_REFCLK(CONF_FDPLL1_REFCLK) | (CONF_FDPLL1_WUF << OSCCTRL_DPLLCTRLB_WUF_Pos) |
| 180 | | OSCCTRL_DPLLCTRLB_FILTER(CONF_FDPLL1_FILTER)); |
| 181 | hri_oscctrl_write_DPLLCTRLA_reg(hw, |
| 182 | 1, |
| 183 | (CONF_FDPLL1_RUNSTDBY << OSCCTRL_DPLLCTRLA_RUNSTDBY_Pos) |
| 184 | | (CONF_FDPLL1_ENABLE << OSCCTRL_DPLLCTRLA_ENABLE_Pos)); |
| 185 | #endif |
| 186 | |
| 187 | #if CONF_DFLL_CONFIG == 1 |
| 188 | if (hri_oscctrl_get_DFLLCTRLB_MODE_bit(hw)) { |
| 189 | hri_oscctrl_status_reg_t status_mask = OSCCTRL_STATUS_DFLLRDY | OSCCTRL_STATUS_DFLLLCKC; |
| 190 | |
| 191 | while (hri_oscctrl_get_STATUS_reg(hw, status_mask) != status_mask) |
| 192 | ; |
| 193 | } else { |
| 194 | while (!hri_oscctrl_get_STATUS_DFLLRDY_bit(hw)) |
| 195 | ; |
| 196 | } |
| 197 | #if CONF_DFLL_ONDEMAND == 1 |
| 198 | hri_oscctrl_set_DFLLCTRLA_ONDEMAND_bit(hw); |
| 199 | #endif |
| 200 | #endif |
| 201 | |
| 202 | #if CONF_FDPLL0_CONFIG == 1 |
| 203 | #if CONF_FDPLL0_ENABLE == 1 |
| 204 | while (!(hri_oscctrl_get_DPLLSTATUS_LOCK_bit(hw, 0) || hri_oscctrl_get_DPLLSTATUS_CLKRDY_bit(hw, 0))) |
| 205 | ; |
| 206 | #endif |
| 207 | #if CONF_FDPLL0_ONDEMAND == 1 |
| 208 | hri_oscctrl_set_DPLLCTRLA_ONDEMAND_bit(hw, 0); |
| 209 | #endif |
| 210 | #endif |
| 211 | |
| 212 | #if CONF_FDPLL1_CONFIG == 1 |
| 213 | #if CONF_FDPLL1_ENABLE == 1 |
| 214 | while (!(hri_oscctrl_get_DPLLSTATUS_LOCK_bit(hw, 1) || hri_oscctrl_get_DPLLSTATUS_CLKRDY_bit(hw, 1))) |
| 215 | ; |
| 216 | #endif |
| 217 | #if CONF_FDPLL1_ONDEMAND == 1 |
| 218 | hri_oscctrl_set_DPLLCTRLA_ONDEMAND_bit(hw, 1); |
| 219 | #endif |
| 220 | #endif |
| 221 | |
| 222 | #if CONF_DFLL_CONFIG == 1 |
| 223 | while (hri_gclk_read_SYNCBUSY_reg(GCLK)) |
| 224 | ; |
| 225 | hri_gclk_write_GENCTRL_SRC_bf(GCLK, 0, CONF_GCLK_GEN_0_SOURCE); |
| 226 | while (hri_gclk_get_SYNCBUSY_GENCTRL0_bit(GCLK)) |
| 227 | ; |
| 228 | #endif |
| 229 | (void)hw; |
| 230 | } |