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