Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sun May 14 23:18:57 2017 +0000
Revision:
18:6a4db94011d3
Publishing again

Who changed what in which revision?

UserRevisionLine numberNew 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