t
Fork of mbed-dev by
targets/TARGET_Atmel/TARGET_SAM_CortexM4/drivers/pmc/sleep.c@160:d5399cc887bb, 2017-03-14 (annotated)
- Committer:
- <>
- Date:
- Tue Mar 14 16:40:56 2017 +0000
- Revision:
- 160:d5399cc887bb
- Parent:
- 149:156823d33999
This updates the lib to the mbed lib v138
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mbed_official | 107:414e9c822e99 | 1 | /** |
mbed_official | 107:414e9c822e99 | 2 | * \file |
mbed_official | 107:414e9c822e99 | 3 | * |
mbed_official | 107:414e9c822e99 | 4 | * \brief Sleep mode access |
mbed_official | 107:414e9c822e99 | 5 | * |
mbed_official | 107:414e9c822e99 | 6 | * Copyright (c) 2012-2015 Atmel Corporation. All rights reserved. |
mbed_official | 107:414e9c822e99 | 7 | * |
mbed_official | 107:414e9c822e99 | 8 | * \asf_license_start |
mbed_official | 107:414e9c822e99 | 9 | * |
mbed_official | 107:414e9c822e99 | 10 | * \page License |
mbed_official | 107:414e9c822e99 | 11 | * |
mbed_official | 107:414e9c822e99 | 12 | * Redistribution and use in source and binary forms, with or without |
mbed_official | 107:414e9c822e99 | 13 | * modification, are permitted provided that the following conditions are met: |
mbed_official | 107:414e9c822e99 | 14 | * |
mbed_official | 107:414e9c822e99 | 15 | * 1. Redistributions of source code must retain the above copyright notice, |
mbed_official | 107:414e9c822e99 | 16 | * this list of conditions and the following disclaimer. |
mbed_official | 107:414e9c822e99 | 17 | * |
mbed_official | 107:414e9c822e99 | 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
mbed_official | 107:414e9c822e99 | 19 | * this list of conditions and the following disclaimer in the documentation |
mbed_official | 107:414e9c822e99 | 20 | * and/or other materials provided with the distribution. |
mbed_official | 107:414e9c822e99 | 21 | * |
mbed_official | 107:414e9c822e99 | 22 | * 3. The name of Atmel may not be used to endorse or promote products derived |
mbed_official | 107:414e9c822e99 | 23 | * from this software without specific prior written permission. |
mbed_official | 107:414e9c822e99 | 24 | * |
mbed_official | 107:414e9c822e99 | 25 | * 4. This software may only be redistributed and used in connection with an |
mbed_official | 107:414e9c822e99 | 26 | * Atmel microcontroller product. |
mbed_official | 107:414e9c822e99 | 27 | * |
mbed_official | 107:414e9c822e99 | 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED |
mbed_official | 107:414e9c822e99 | 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
mbed_official | 107:414e9c822e99 | 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE |
mbed_official | 107:414e9c822e99 | 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR |
mbed_official | 107:414e9c822e99 | 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
mbed_official | 107:414e9c822e99 | 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
mbed_official | 107:414e9c822e99 | 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
mbed_official | 107:414e9c822e99 | 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
mbed_official | 107:414e9c822e99 | 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
mbed_official | 107:414e9c822e99 | 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
mbed_official | 107:414e9c822e99 | 38 | * POSSIBILITY OF SUCH DAMAGE. |
mbed_official | 107:414e9c822e99 | 39 | * |
mbed_official | 107:414e9c822e99 | 40 | * \asf_license_stop |
mbed_official | 107:414e9c822e99 | 41 | * |
mbed_official | 107:414e9c822e99 | 42 | */ |
mbed_official | 107:414e9c822e99 | 43 | /* |
mbed_official | 107:414e9c822e99 | 44 | * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> |
mbed_official | 107:414e9c822e99 | 45 | */ |
mbed_official | 107:414e9c822e99 | 46 | |
mbed_official | 107:414e9c822e99 | 47 | #include <compiler.h> |
<> | 160:d5399cc887bb | 48 | #include "mbed_sleep.h" |
mbed_official | 107:414e9c822e99 | 49 | |
mbed_official | 107:414e9c822e99 | 50 | /* SAM3 and SAM4 series */ |
mbed_official | 107:414e9c822e99 | 51 | #if (SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4E || SAM4N || SAM4C || \ |
mbed_official | 107:414e9c822e99 | 52 | SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAMS70 || SAME70) |
mbed_official | 107:414e9c822e99 | 53 | # include "pmc.h" |
mbed_official | 107:414e9c822e99 | 54 | # include "board.h" |
mbed_official | 107:414e9c822e99 | 55 | |
mbed_official | 107:414e9c822e99 | 56 | /* Checking board configuration of main clock xtal statup time */ |
mbed_official | 107:414e9c822e99 | 57 | #if !defined(BOARD_OSC_STARTUP_US) |
mbed_official | 107:414e9c822e99 | 58 | # warning The board main clock xtal statup time has not been defined. Using default settings. |
mbed_official | 107:414e9c822e99 | 59 | # define BOARD_OSC_STARTUP_US (15625UL) |
mbed_official | 107:414e9c822e99 | 60 | #endif |
mbed_official | 107:414e9c822e99 | 61 | |
mbed_official | 107:414e9c822e99 | 62 | #if !defined(EFC0) |
mbed_official | 107:414e9c822e99 | 63 | # define EFC0 EFC |
mbed_official | 107:414e9c822e99 | 64 | #endif |
mbed_official | 107:414e9c822e99 | 65 | |
mbed_official | 107:414e9c822e99 | 66 | /** |
mbed_official | 107:414e9c822e99 | 67 | * Save clock settings and shutdown PLLs |
mbed_official | 107:414e9c822e99 | 68 | */ |
mbed_official | 107:414e9c822e99 | 69 | __always_inline static void pmc_save_clock_settings( |
mbed_official | 107:414e9c822e99 | 70 | uint32_t *p_osc_setting, |
mbed_official | 107:414e9c822e99 | 71 | uint32_t *p_pll0_setting, |
mbed_official | 107:414e9c822e99 | 72 | uint32_t *p_pll1_setting, |
mbed_official | 107:414e9c822e99 | 73 | uint32_t *p_mck_setting, |
mbed_official | 107:414e9c822e99 | 74 | uint32_t *p_fmr_setting, |
mbed_official | 107:414e9c822e99 | 75 | #if defined(EFC1) |
mbed_official | 107:414e9c822e99 | 76 | uint32_t *p_fmr_setting1, |
mbed_official | 107:414e9c822e99 | 77 | #endif |
mbed_official | 107:414e9c822e99 | 78 | const bool disable_xtal) |
mbed_official | 107:414e9c822e99 | 79 | { |
mbed_official | 107:414e9c822e99 | 80 | uint32_t mor = PMC->CKGR_MOR; |
mbed_official | 107:414e9c822e99 | 81 | uint32_t mckr = PMC->PMC_MCKR; |
mbed_official | 107:414e9c822e99 | 82 | uint32_t fmr = EFC0->EEFC_FMR; |
mbed_official | 107:414e9c822e99 | 83 | # if defined(EFC1) |
mbed_official | 107:414e9c822e99 | 84 | uint32_t fmr1 = EFC1->EEFC_FMR; |
mbed_official | 107:414e9c822e99 | 85 | # endif |
mbed_official | 107:414e9c822e99 | 86 | |
mbed_official | 107:414e9c822e99 | 87 | if (p_osc_setting) { |
mbed_official | 107:414e9c822e99 | 88 | *p_osc_setting = mor; |
mbed_official | 107:414e9c822e99 | 89 | } |
mbed_official | 107:414e9c822e99 | 90 | if (p_pll0_setting) { |
mbed_official | 107:414e9c822e99 | 91 | *p_pll0_setting = PMC->CKGR_PLLAR; |
mbed_official | 107:414e9c822e99 | 92 | } |
mbed_official | 107:414e9c822e99 | 93 | if (p_pll1_setting) { |
mbed_official | 107:414e9c822e99 | 94 | #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) |
mbed_official | 107:414e9c822e99 | 95 | *p_pll1_setting = PMC->CKGR_PLLBR; |
mbed_official | 107:414e9c822e99 | 96 | #elif (SAM3U || SAM3XA) |
mbed_official | 107:414e9c822e99 | 97 | *p_pll1_setting = PMC->CKGR_UCKR; |
mbed_official | 107:414e9c822e99 | 98 | #else |
mbed_official | 107:414e9c822e99 | 99 | *p_pll1_setting = 0; |
mbed_official | 107:414e9c822e99 | 100 | #endif |
mbed_official | 107:414e9c822e99 | 101 | } |
mbed_official | 107:414e9c822e99 | 102 | if (p_mck_setting) { |
mbed_official | 107:414e9c822e99 | 103 | *p_mck_setting = mckr; |
mbed_official | 107:414e9c822e99 | 104 | } |
mbed_official | 107:414e9c822e99 | 105 | if (p_fmr_setting) { |
mbed_official | 107:414e9c822e99 | 106 | *p_fmr_setting = fmr; |
mbed_official | 107:414e9c822e99 | 107 | } |
mbed_official | 107:414e9c822e99 | 108 | #if defined(EFC1) |
mbed_official | 107:414e9c822e99 | 109 | if (p_fmr_setting1) { |
mbed_official | 107:414e9c822e99 | 110 | *p_fmr_setting1 = fmr1; |
mbed_official | 107:414e9c822e99 | 111 | } |
mbed_official | 107:414e9c822e99 | 112 | #endif |
mbed_official | 107:414e9c822e99 | 113 | |
mbed_official | 107:414e9c822e99 | 114 | /* Enable FAST RC */ |
mbed_official | 107:414e9c822e99 | 115 | PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor | CKGR_MOR_MOSCRCEN; |
mbed_official | 107:414e9c822e99 | 116 | /* if MCK source is PLL, switch to mainck */ |
mbed_official | 107:414e9c822e99 | 117 | if ((mckr & PMC_MCKR_CSS_Msk) > PMC_MCKR_CSS_MAIN_CLK) { |
mbed_official | 107:414e9c822e99 | 118 | /* MCK -> MAINCK */ |
mbed_official | 107:414e9c822e99 | 119 | mckr = (mckr & (~PMC_MCKR_CSS_Msk)) | PMC_MCKR_CSS_MAIN_CLK; |
mbed_official | 107:414e9c822e99 | 120 | PMC->PMC_MCKR = mckr; |
mbed_official | 107:414e9c822e99 | 121 | while(!(PMC->PMC_SR & PMC_SR_MCKRDY)); |
mbed_official | 107:414e9c822e99 | 122 | } |
mbed_official | 107:414e9c822e99 | 123 | /* MCK prescale -> 1 */ |
mbed_official | 107:414e9c822e99 | 124 | if (mckr & PMC_MCKR_PRES_Msk) { |
mbed_official | 107:414e9c822e99 | 125 | mckr = (mckr & (~PMC_MCKR_PRES_Msk)); |
mbed_official | 107:414e9c822e99 | 126 | PMC->PMC_MCKR = mckr; |
mbed_official | 107:414e9c822e99 | 127 | while(!(PMC->PMC_SR & PMC_SR_MCKRDY)); |
mbed_official | 107:414e9c822e99 | 128 | } |
mbed_official | 107:414e9c822e99 | 129 | /* Disable PLLs */ |
mbed_official | 107:414e9c822e99 | 130 | pmc_disable_pllack(); |
mbed_official | 107:414e9c822e99 | 131 | #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) |
mbed_official | 107:414e9c822e99 | 132 | pmc_disable_pllbck(); |
mbed_official | 107:414e9c822e99 | 133 | #elif (SAM3U || SAM3XA) |
mbed_official | 107:414e9c822e99 | 134 | pmc_disable_upll_clock(); |
mbed_official | 107:414e9c822e99 | 135 | #endif |
mbed_official | 107:414e9c822e99 | 136 | |
mbed_official | 107:414e9c822e99 | 137 | /* Prepare for entering WAIT mode */ |
mbed_official | 107:414e9c822e99 | 138 | /* Wait fast RC ready */ |
mbed_official | 107:414e9c822e99 | 139 | while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); |
mbed_official | 107:414e9c822e99 | 140 | |
mbed_official | 107:414e9c822e99 | 141 | /* Switch mainck to FAST RC */ |
mbed_official | 107:414e9c822e99 | 142 | #if SAMG |
mbed_official | 107:414e9c822e99 | 143 | /** |
mbed_official | 107:414e9c822e99 | 144 | * For the sleepwalking feature, we need an accurate RC clock. Only 24M and |
mbed_official | 107:414e9c822e99 | 145 | * 16M are trimmed in production. Here we select the 24M. |
mbed_official | 107:414e9c822e99 | 146 | * And so wait state need to be 1. |
mbed_official | 107:414e9c822e99 | 147 | */ |
mbed_official | 107:414e9c822e99 | 148 | EFC0->EEFC_FMR = (fmr & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(1); |
mbed_official | 107:414e9c822e99 | 149 | |
mbed_official | 107:414e9c822e99 | 150 | PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | CKGR_MOR_MOSCRCF_24_MHz | |
mbed_official | 107:414e9c822e99 | 151 | CKGR_MOR_KEY_PASSWD; |
mbed_official | 107:414e9c822e99 | 152 | #else |
mbed_official | 107:414e9c822e99 | 153 | PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | |
mbed_official | 107:414e9c822e99 | 154 | CKGR_MOR_KEY_PASSWD; |
mbed_official | 107:414e9c822e99 | 155 | #endif |
mbed_official | 107:414e9c822e99 | 156 | while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)); |
mbed_official | 107:414e9c822e99 | 157 | |
mbed_official | 107:414e9c822e99 | 158 | #if (!SAMG) |
mbed_official | 107:414e9c822e99 | 159 | /* FWS update */ |
mbed_official | 107:414e9c822e99 | 160 | EFC0->EEFC_FMR = fmr & (~EEFC_FMR_FWS_Msk); |
mbed_official | 107:414e9c822e99 | 161 | #if defined(EFC1) |
mbed_official | 107:414e9c822e99 | 162 | EFC1->EEFC_FMR = fmr1 & (~EEFC_FMR_FWS_Msk); |
mbed_official | 107:414e9c822e99 | 163 | #endif |
mbed_official | 107:414e9c822e99 | 164 | #endif |
mbed_official | 107:414e9c822e99 | 165 | |
mbed_official | 107:414e9c822e99 | 166 | /* Disable XTALs */ |
mbed_official | 107:414e9c822e99 | 167 | if (disable_xtal) { |
mbed_official | 107:414e9c822e99 | 168 | PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | |
mbed_official | 107:414e9c822e99 | 169 | CKGR_MOR_KEY_PASSWD; |
mbed_official | 107:414e9c822e99 | 170 | } |
mbed_official | 107:414e9c822e99 | 171 | } |
mbed_official | 107:414e9c822e99 | 172 | |
mbed_official | 107:414e9c822e99 | 173 | /** |
mbed_official | 107:414e9c822e99 | 174 | * Restore clock settings |
mbed_official | 107:414e9c822e99 | 175 | */ |
mbed_official | 107:414e9c822e99 | 176 | __always_inline static void pmc_restore_clock_setting( |
mbed_official | 107:414e9c822e99 | 177 | const uint32_t osc_setting, |
mbed_official | 107:414e9c822e99 | 178 | const uint32_t pll0_setting, |
mbed_official | 107:414e9c822e99 | 179 | const uint32_t pll1_setting, |
mbed_official | 107:414e9c822e99 | 180 | const uint32_t mck_setting, |
mbed_official | 107:414e9c822e99 | 181 | const uint32_t fmr_setting |
mbed_official | 107:414e9c822e99 | 182 | #if defined(EFC1) |
mbed_official | 107:414e9c822e99 | 183 | , const uint32_t fmr_setting1 |
mbed_official | 107:414e9c822e99 | 184 | #endif |
mbed_official | 107:414e9c822e99 | 185 | ) |
mbed_official | 107:414e9c822e99 | 186 | { |
mbed_official | 107:414e9c822e99 | 187 | uint32_t mckr; |
mbed_official | 107:414e9c822e99 | 188 | uint32_t pll_sr = 0; |
mbed_official | 107:414e9c822e99 | 189 | |
mbed_official | 107:414e9c822e99 | 190 | /* Switch mainck to external xtal */ |
mbed_official | 107:414e9c822e99 | 191 | if (CKGR_MOR_MOSCXTBY == (osc_setting & CKGR_MOR_MOSCXTBY)) { |
mbed_official | 107:414e9c822e99 | 192 | /* Bypass mode */ |
mbed_official | 107:414e9c822e99 | 193 | PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | |
mbed_official | 107:414e9c822e99 | 194 | CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY | |
mbed_official | 107:414e9c822e99 | 195 | CKGR_MOR_MOSCSEL; |
mbed_official | 107:414e9c822e99 | 196 | PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN & |
mbed_official | 107:414e9c822e99 | 197 | ~CKGR_MOR_MOSCRCF_Msk) |
mbed_official | 107:414e9c822e99 | 198 | | CKGR_MOR_KEY_PASSWD; |
mbed_official | 107:414e9c822e99 | 199 | } else if (CKGR_MOR_MOSCXTEN == (osc_setting & CKGR_MOR_MOSCXTEN)) { |
mbed_official | 107:414e9c822e99 | 200 | /* Enable External XTAL */ |
mbed_official | 107:414e9c822e99 | 201 | if (!(PMC->CKGR_MOR & CKGR_MOR_MOSCXTEN)) { |
mbed_official | 107:414e9c822e99 | 202 | PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) | |
mbed_official | 107:414e9c822e99 | 203 | CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN; |
mbed_official | 107:414e9c822e99 | 204 | /* Wait the Xtal to stabilize */ |
mbed_official | 107:414e9c822e99 | 205 | while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)); |
mbed_official | 107:414e9c822e99 | 206 | } |
mbed_official | 107:414e9c822e99 | 207 | /* Select External XTAL */ |
mbed_official | 107:414e9c822e99 | 208 | if (!(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL)) { |
mbed_official | 107:414e9c822e99 | 209 | PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL; |
mbed_official | 107:414e9c822e99 | 210 | while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)); |
mbed_official | 107:414e9c822e99 | 211 | } |
mbed_official | 107:414e9c822e99 | 212 | /* Disable Fast RC */ |
mbed_official | 107:414e9c822e99 | 213 | PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN & |
mbed_official | 107:414e9c822e99 | 214 | ~CKGR_MOR_MOSCRCF_Msk) |
mbed_official | 107:414e9c822e99 | 215 | | CKGR_MOR_KEY_PASSWD; |
mbed_official | 107:414e9c822e99 | 216 | } |
mbed_official | 107:414e9c822e99 | 217 | |
mbed_official | 107:414e9c822e99 | 218 | if (pll0_setting & CKGR_PLLAR_MULA_Msk) { |
mbed_official | 107:414e9c822e99 | 219 | #if (SAM4C || SAM4CM || SAMG || SAM4CP) |
mbed_official | 107:414e9c822e99 | 220 | PMC->CKGR_PLLAR = pll0_setting; |
mbed_official | 107:414e9c822e99 | 221 | #else |
mbed_official | 107:414e9c822e99 | 222 | PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | pll0_setting; |
mbed_official | 107:414e9c822e99 | 223 | #endif |
mbed_official | 107:414e9c822e99 | 224 | pll_sr |= PMC_SR_LOCKA; |
mbed_official | 107:414e9c822e99 | 225 | } |
mbed_official | 107:414e9c822e99 | 226 | #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) |
mbed_official | 107:414e9c822e99 | 227 | if (pll1_setting & CKGR_PLLBR_MULB_Msk) { |
mbed_official | 107:414e9c822e99 | 228 | PMC->CKGR_PLLBR = pll1_setting; |
mbed_official | 107:414e9c822e99 | 229 | pll_sr |= PMC_SR_LOCKB; |
mbed_official | 107:414e9c822e99 | 230 | } |
mbed_official | 107:414e9c822e99 | 231 | #elif (SAM3U || SAM3XA) |
mbed_official | 107:414e9c822e99 | 232 | if (pll1_setting & CKGR_UCKR_UPLLEN) { |
mbed_official | 107:414e9c822e99 | 233 | PMC->CKGR_UCKR = pll1_setting; |
mbed_official | 107:414e9c822e99 | 234 | pll_sr |= PMC_SR_LOCKU; |
mbed_official | 107:414e9c822e99 | 235 | } |
mbed_official | 107:414e9c822e99 | 236 | #else |
mbed_official | 107:414e9c822e99 | 237 | UNUSED(pll1_setting); |
mbed_official | 107:414e9c822e99 | 238 | #endif |
mbed_official | 107:414e9c822e99 | 239 | /* Wait MCK source ready */ |
mbed_official | 107:414e9c822e99 | 240 | switch(mck_setting & PMC_MCKR_CSS_Msk) { |
mbed_official | 107:414e9c822e99 | 241 | case PMC_MCKR_CSS_PLLA_CLK: |
mbed_official | 107:414e9c822e99 | 242 | while (!(PMC->PMC_SR & PMC_SR_LOCKA)); |
mbed_official | 107:414e9c822e99 | 243 | break; |
mbed_official | 107:414e9c822e99 | 244 | #if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) |
mbed_official | 107:414e9c822e99 | 245 | case PMC_MCKR_CSS_PLLB_CLK: |
mbed_official | 107:414e9c822e99 | 246 | while (!(PMC->PMC_SR & PMC_SR_LOCKB)); |
mbed_official | 107:414e9c822e99 | 247 | break; |
mbed_official | 107:414e9c822e99 | 248 | #elif (SAM3U || SAM3XA) |
mbed_official | 107:414e9c822e99 | 249 | case PMC_MCKR_CSS_UPLL_CLK: |
mbed_official | 107:414e9c822e99 | 250 | while (!(PMC->PMC_SR & PMC_SR_LOCKU)); |
mbed_official | 107:414e9c822e99 | 251 | break; |
mbed_official | 107:414e9c822e99 | 252 | #endif |
mbed_official | 107:414e9c822e99 | 253 | } |
mbed_official | 107:414e9c822e99 | 254 | |
mbed_official | 107:414e9c822e99 | 255 | /* Switch to faster clock */ |
mbed_official | 107:414e9c822e99 | 256 | mckr = PMC->PMC_MCKR; |
mbed_official | 107:414e9c822e99 | 257 | |
mbed_official | 107:414e9c822e99 | 258 | /* Set PRES */ |
mbed_official | 107:414e9c822e99 | 259 | PMC->PMC_MCKR = (mckr & ~PMC_MCKR_PRES_Msk) |
mbed_official | 107:414e9c822e99 | 260 | | (mck_setting & PMC_MCKR_PRES_Msk); |
mbed_official | 107:414e9c822e99 | 261 | while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); |
mbed_official | 107:414e9c822e99 | 262 | |
mbed_official | 107:414e9c822e99 | 263 | /* Restore flash wait states */ |
mbed_official | 107:414e9c822e99 | 264 | EFC0->EEFC_FMR = fmr_setting; |
mbed_official | 107:414e9c822e99 | 265 | #if defined(EFC1) |
mbed_official | 107:414e9c822e99 | 266 | EFC1->EEFC_FMR = fmr_setting1; |
mbed_official | 107:414e9c822e99 | 267 | #endif |
mbed_official | 107:414e9c822e99 | 268 | |
mbed_official | 107:414e9c822e99 | 269 | /* Set CSS and others */ |
mbed_official | 107:414e9c822e99 | 270 | PMC->PMC_MCKR = mck_setting; |
mbed_official | 107:414e9c822e99 | 271 | while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); |
mbed_official | 107:414e9c822e99 | 272 | |
mbed_official | 107:414e9c822e99 | 273 | /* Waiting all restored PLLs ready */ |
mbed_official | 107:414e9c822e99 | 274 | while (!(PMC->PMC_SR & pll_sr)); |
mbed_official | 107:414e9c822e99 | 275 | } |
mbed_official | 107:414e9c822e99 | 276 | |
mbed_official | 107:414e9c822e99 | 277 | /** If clocks are switched for some sleep mode */ |
mbed_official | 107:414e9c822e99 | 278 | static volatile bool b_is_sleep_clock_used = false; |
mbed_official | 107:414e9c822e99 | 279 | /** Callback invoked once when clocks are restored */ |
mbed_official | 107:414e9c822e99 | 280 | static pmc_callback_wakeup_clocks_restored_t callback_clocks_restored = NULL; |
mbed_official | 107:414e9c822e99 | 281 | |
mbed_official | 107:414e9c822e99 | 282 | void pmc_sleep(int sleep_mode) |
mbed_official | 107:414e9c822e99 | 283 | { |
mbed_official | 107:414e9c822e99 | 284 | switch (sleep_mode) { |
mbed_official | 107:414e9c822e99 | 285 | #if (!(SAMG51 || SAMG53 || SAMG54)) |
mbed_official | 107:414e9c822e99 | 286 | case SAM_PM_SMODE_SLEEP_WFI: |
mbed_official | 107:414e9c822e99 | 287 | case SAM_PM_SMODE_SLEEP_WFE: |
mbed_official | 107:414e9c822e99 | 288 | #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAMS70 || SAME70) |
mbed_official | 107:414e9c822e99 | 289 | SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP; |
mbed_official | 107:414e9c822e99 | 290 | cpu_irq_enable(); |
mbed_official | 107:414e9c822e99 | 291 | __WFI(); |
mbed_official | 107:414e9c822e99 | 292 | break; |
mbed_official | 107:414e9c822e99 | 293 | #else |
mbed_official | 107:414e9c822e99 | 294 | PMC->PMC_FSMR &= (uint32_t)~PMC_FSMR_LPM; |
mbed_official | 107:414e9c822e99 | 295 | SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP; |
mbed_official | 107:414e9c822e99 | 296 | cpu_irq_enable(); |
mbed_official | 107:414e9c822e99 | 297 | if (sleep_mode == SAM_PM_SMODE_SLEEP_WFI) |
mbed_official | 107:414e9c822e99 | 298 | __WFI(); |
mbed_official | 107:414e9c822e99 | 299 | else |
mbed_official | 107:414e9c822e99 | 300 | __WFE(); |
mbed_official | 107:414e9c822e99 | 301 | break; |
mbed_official | 107:414e9c822e99 | 302 | #endif |
mbed_official | 107:414e9c822e99 | 303 | #endif |
mbed_official | 107:414e9c822e99 | 304 | |
mbed_official | 107:414e9c822e99 | 305 | case SAM_PM_SMODE_WAIT_FAST: |
mbed_official | 107:414e9c822e99 | 306 | case SAM_PM_SMODE_WAIT: { |
mbed_official | 107:414e9c822e99 | 307 | uint32_t mor, pllr0, pllr1, mckr; |
mbed_official | 107:414e9c822e99 | 308 | uint32_t fmr; |
mbed_official | 107:414e9c822e99 | 309 | #if defined(EFC1) |
mbed_official | 107:414e9c822e99 | 310 | uint32_t fmr1; |
mbed_official | 107:414e9c822e99 | 311 | #endif |
mbed_official | 107:414e9c822e99 | 312 | #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAMS70 || SAME70) |
mbed_official | 107:414e9c822e99 | 313 | (sleep_mode == SAM_PM_SMODE_WAIT_FAST) ? |
mbed_official | 107:414e9c822e99 | 314 | pmc_set_flash_in_wait_mode(PMC_FSMR_FLPM_FLASH_STANDBY) : |
mbed_official | 107:414e9c822e99 | 315 | pmc_set_flash_in_wait_mode(PMC_FSMR_FLPM_FLASH_DEEP_POWERDOWN); |
mbed_official | 107:414e9c822e99 | 316 | #endif |
mbed_official | 107:414e9c822e99 | 317 | cpu_irq_disable(); |
mbed_official | 107:414e9c822e99 | 318 | b_is_sleep_clock_used = true; |
mbed_official | 107:414e9c822e99 | 319 | |
mbed_official | 107:414e9c822e99 | 320 | #if (SAM4C || SAM4CM || SAM4CP) |
mbed_official | 107:414e9c822e99 | 321 | /* Backup the sub-system 1 status and stop sub-system 1 */ |
mbed_official | 107:414e9c822e99 | 322 | uint32_t cpclk_backup = PMC->PMC_SCSR & |
mbed_official | 107:414e9c822e99 | 323 | (PMC_SCSR_CPCK | PMC_SCSR_CPBMCK); |
mbed_official | 107:414e9c822e99 | 324 | PMC->PMC_SCDR = cpclk_backup | PMC_SCDR_CPKEY_PASSWD; |
mbed_official | 107:414e9c822e99 | 325 | #endif |
mbed_official | 107:414e9c822e99 | 326 | pmc_save_clock_settings(&mor, &pllr0, &pllr1, &mckr, &fmr, |
mbed_official | 107:414e9c822e99 | 327 | #if defined(EFC1) |
mbed_official | 107:414e9c822e99 | 328 | &fmr1, |
mbed_official | 107:414e9c822e99 | 329 | #endif |
mbed_official | 107:414e9c822e99 | 330 | (sleep_mode == SAM_PM_SMODE_WAIT)); |
mbed_official | 107:414e9c822e99 | 331 | |
mbed_official | 107:414e9c822e99 | 332 | /* Enter wait mode */ |
mbed_official | 107:414e9c822e99 | 333 | cpu_irq_enable(); |
mbed_official | 107:414e9c822e99 | 334 | |
mbed_official | 107:414e9c822e99 | 335 | pmc_enable_waitmode(); |
mbed_official | 107:414e9c822e99 | 336 | |
mbed_official | 107:414e9c822e99 | 337 | cpu_irq_disable(); |
mbed_official | 107:414e9c822e99 | 338 | pmc_restore_clock_setting(mor, pllr0, pllr1, mckr, fmr |
mbed_official | 107:414e9c822e99 | 339 | #if defined(EFC1) |
mbed_official | 107:414e9c822e99 | 340 | , fmr1 |
mbed_official | 107:414e9c822e99 | 341 | #endif |
mbed_official | 107:414e9c822e99 | 342 | ); |
mbed_official | 107:414e9c822e99 | 343 | |
mbed_official | 107:414e9c822e99 | 344 | #if (SAM4C || SAM4CM || SAM4CP) |
mbed_official | 107:414e9c822e99 | 345 | /* Restore the sub-system 1 */ |
mbed_official | 107:414e9c822e99 | 346 | PMC->PMC_SCER = cpclk_backup | PMC_SCER_CPKEY_PASSWD; |
mbed_official | 107:414e9c822e99 | 347 | #endif |
mbed_official | 107:414e9c822e99 | 348 | b_is_sleep_clock_used = false; |
mbed_official | 107:414e9c822e99 | 349 | if (callback_clocks_restored) { |
mbed_official | 107:414e9c822e99 | 350 | callback_clocks_restored(); |
mbed_official | 107:414e9c822e99 | 351 | callback_clocks_restored = NULL; |
mbed_official | 107:414e9c822e99 | 352 | } |
mbed_official | 107:414e9c822e99 | 353 | cpu_irq_enable(); |
mbed_official | 107:414e9c822e99 | 354 | |
mbed_official | 107:414e9c822e99 | 355 | break; |
mbed_official | 107:414e9c822e99 | 356 | } |
mbed_official | 107:414e9c822e99 | 357 | #if (!(SAMG51 || SAMG53 || SAMG54)) |
mbed_official | 107:414e9c822e99 | 358 | case SAM_PM_SMODE_BACKUP: |
mbed_official | 107:414e9c822e99 | 359 | SCB->SCR |= SCR_SLEEPDEEP; |
mbed_official | 107:414e9c822e99 | 360 | #if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAMS70 || SAME70) |
mbed_official | 107:414e9c822e99 | 361 | SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF_STOP_VREG; |
mbed_official | 107:414e9c822e99 | 362 | cpu_irq_enable(); |
mbed_official | 107:414e9c822e99 | 363 | __WFI() ; |
mbed_official | 107:414e9c822e99 | 364 | #else |
mbed_official | 107:414e9c822e99 | 365 | cpu_irq_enable(); |
mbed_official | 107:414e9c822e99 | 366 | __WFE() ; |
mbed_official | 107:414e9c822e99 | 367 | #endif |
mbed_official | 107:414e9c822e99 | 368 | break; |
mbed_official | 107:414e9c822e99 | 369 | #endif |
mbed_official | 107:414e9c822e99 | 370 | } |
mbed_official | 107:414e9c822e99 | 371 | } |
mbed_official | 107:414e9c822e99 | 372 | |
mbed_official | 107:414e9c822e99 | 373 | bool pmc_is_wakeup_clocks_restored(void) |
mbed_official | 107:414e9c822e99 | 374 | { |
mbed_official | 107:414e9c822e99 | 375 | return !b_is_sleep_clock_used; |
mbed_official | 107:414e9c822e99 | 376 | } |
mbed_official | 107:414e9c822e99 | 377 | |
mbed_official | 107:414e9c822e99 | 378 | void pmc_wait_wakeup_clocks_restore( |
mbed_official | 107:414e9c822e99 | 379 | pmc_callback_wakeup_clocks_restored_t callback) |
mbed_official | 107:414e9c822e99 | 380 | { |
mbed_official | 107:414e9c822e99 | 381 | if (b_is_sleep_clock_used) { |
mbed_official | 107:414e9c822e99 | 382 | cpu_irq_disable(); |
mbed_official | 107:414e9c822e99 | 383 | callback_clocks_restored = callback; |
mbed_official | 107:414e9c822e99 | 384 | } else if (callback) { |
mbed_official | 107:414e9c822e99 | 385 | callback(); |
mbed_official | 107:414e9c822e99 | 386 | } |
mbed_official | 107:414e9c822e99 | 387 | } |
mbed_official | 107:414e9c822e99 | 388 | |
mbed_official | 107:414e9c822e99 | 389 | #endif |