Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-dev by
targets/TARGET_Atmel/TARGET_SAM_CortexM4/drivers/pmc/sleep.c@184:08ed48f1de7f, 2018-04-19 (annotated)
- Committer:
- AnnaBridge
- Date:
- Thu Apr 19 17:12:19 2018 +0100
- Revision:
- 184:08ed48f1de7f
- Parent:
- 160:d5399cc887bb
mbed-dev library. Release version 161
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> |
| AnnaBridge | 184:08ed48f1de7f | 48 | #include "mbed_power_mgmt.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 |
