1 /* 2 * Copyright (c) 2016, Freescale Semiconductor, Inc. 3 * Copyright 2016-2019 NXP 4 * All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 #include "fsl_msmc.h" 10 11 /* Component ID definition, used by tools. */ 12 #ifndef FSL_COMPONENT_ID 13 #define FSL_COMPONENT_ID "platform.drivers.msmc" 14 #endif 15 16 /*! 17 * brief Configure the system to RUN power mode. 18 * 19 * param base SMC peripheral base address. 20 * return SMC configuration error code. 21 */ SMC_SetPowerModeRun(SMC_Type * base)22status_t SMC_SetPowerModeRun(SMC_Type *base) 23 { 24 uint32_t reg; 25 26 reg = base->PMCTRL; 27 /* configure Normal RUN mode */ 28 reg &= ~SMC_PMCTRL_RUNM_MASK; 29 reg |= ((uint32_t)kSMC_RunNormal << SMC_PMCTRL_RUNM_SHIFT); 30 base->PMCTRL = reg; 31 32 return kStatus_Success; 33 } 34 35 /*! 36 * brief Configure the system to HSRUN power mode. 37 * 38 * param base SMC peripheral base address. 39 * return SMC configuration error code. 40 */ SMC_SetPowerModeHsrun(SMC_Type * base)41status_t SMC_SetPowerModeHsrun(SMC_Type *base) 42 { 43 uint32_t reg; 44 45 reg = base->PMCTRL; 46 /* configure High Speed RUN mode */ 47 reg &= ~SMC_PMCTRL_RUNM_MASK; 48 reg |= ((uint32_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); 49 base->PMCTRL = reg; 50 51 return kStatus_Success; 52 } 53 54 /*! 55 * brief Configure the system to WAIT power mode. 56 * 57 * param base SMC peripheral base address. 58 * return SMC configuration error code. 59 */ SMC_SetPowerModeWait(SMC_Type * base)60status_t SMC_SetPowerModeWait(SMC_Type *base) 61 { 62 /* configure Normal Wait mode */ 63 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; 64 __DSB(); 65 __WFI(); 66 __ISB(); 67 68 return kStatus_Success; 69 } 70 71 /*! 72 * brief Configure the system to Stop power mode. 73 * 74 * param base SMC peripheral base address. 75 * param option Partial Stop mode option. 76 * return SMC configuration error code. 77 */ SMC_SetPowerModeStop(SMC_Type * base,smc_partial_stop_option_t option)78status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) 79 { 80 status_t status; 81 uint32_t reg; 82 83 /* configure the Partial Stop mode in Normal Stop mode */ 84 reg = base->PMCTRL; 85 reg &= ~(SMC_PMCTRL_PSTOPO_MASK | SMC_PMCTRL_STOPM_MASK); 86 reg |= ((uint32_t)option << SMC_PMCTRL_PSTOPO_SHIFT) | ((uint32_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); 87 base->PMCTRL = reg; 88 89 /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ 90 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 91 92 /* read back to make sure the configuration valid before entering stop mode */ 93 (void)base->PMCTRL; 94 __DSB(); 95 __WFI(); 96 __ISB(); 97 98 #if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) 99 /* check whether the power mode enter Stop mode succeed */ 100 if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) 101 { 102 status = kStatus_SMC_StopAbort; 103 } 104 else 105 { 106 status = kStatus_Success; 107 } 108 #else 109 status = kStatus_Success; 110 #endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */ 111 112 return status; 113 } 114 115 /*! 116 * brief Configure the system to VLPR power mode. 117 * 118 * param base SMC peripheral base address. 119 * return SMC configuration error code. 120 */ SMC_SetPowerModeVlpr(SMC_Type * base)121status_t SMC_SetPowerModeVlpr(SMC_Type *base) 122 { 123 uint32_t reg; 124 125 reg = base->PMCTRL; 126 /* configure VLPR mode */ 127 reg &= ~SMC_PMCTRL_RUNM_MASK; 128 reg |= ((uint32_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); 129 base->PMCTRL = reg; 130 131 return kStatus_Success; 132 } 133 134 /*! 135 * brief Configure the system to VLPW power mode. 136 * 137 * param base SMC peripheral base address. 138 * return SMC configuration error code. 139 */ SMC_SetPowerModeVlpw(SMC_Type * base)140status_t SMC_SetPowerModeVlpw(SMC_Type *base) 141 { 142 /* configure VLPW mode */ 143 /* Clear the SLEEPDEEP bit to disable deep sleep mode */ 144 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; 145 __DSB(); 146 __WFI(); 147 __ISB(); 148 149 return kStatus_Success; 150 } 151 152 /*! 153 * brief Configure the system to VLPS power mode. 154 * 155 * param base SMC peripheral base address. 156 * return SMC configuration error code. 157 */ SMC_SetPowerModeVlps(SMC_Type * base)158status_t SMC_SetPowerModeVlps(SMC_Type *base) 159 { 160 uint32_t reg; 161 status_t status; 162 163 /* configure VLPS mode */ 164 reg = base->PMCTRL; 165 reg &= ~SMC_PMCTRL_STOPM_MASK; 166 reg |= ((uint32_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); 167 base->PMCTRL = reg; 168 169 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 170 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 171 172 /* read back to make sure the configuration valid before enter stop mode */ 173 (void)base->PMCTRL; 174 __DSB(); 175 __WFI(); 176 __ISB(); 177 178 #if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) 179 /* check whether the power mode enter Stop mode succeed */ 180 if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) 181 { 182 status = kStatus_SMC_StopAbort; 183 } 184 else 185 { 186 status = kStatus_Success; 187 } 188 #else 189 status = kStatus_Success; 190 #endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */ 191 192 return status; 193 } 194 195 /*! 196 * brief Configure the system to LLS power mode. 197 * 198 * param base SMC peripheral base address. 199 * return SMC configuration error code. 200 */ SMC_SetPowerModeLls(SMC_Type * base)201status_t SMC_SetPowerModeLls(SMC_Type *base) 202 { 203 uint32_t reg; 204 status_t status; 205 206 /* configure to LLS mode */ 207 reg = base->PMCTRL; 208 reg &= ~SMC_PMCTRL_STOPM_MASK; 209 reg |= ((uint32_t)kSMC_StopLls << SMC_PMCTRL_STOPM_SHIFT); 210 base->PMCTRL = reg; 211 212 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 213 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 214 215 /* read back to make sure the configuration valid before entering stop mode */ 216 (void)base->PMCTRL; 217 __DSB(); 218 __WFI(); 219 __ISB(); 220 221 #if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) 222 /* check whether the power mode enter Stop mode succeed */ 223 if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) 224 { 225 status = kStatus_SMC_StopAbort; 226 } 227 else 228 { 229 status = kStatus_Success; 230 } 231 #else 232 status = kStatus_Success; 233 #endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */ 234 235 return status; 236 } 237 238 #if (defined(FSL_FEATURE_SMC_HAS_SUB_STOP_MODE) && FSL_FEATURE_SMC_HAS_SUB_STOP_MODE) 239 240 #if (defined(FSL_FEATURE_SMC_HAS_STOP_SUBMODE0) && FSL_FEATURE_SMC_HAS_STOP_SUBMODE0) 241 /*! 242 * brief Configure the system to VLLS0 power mode. 243 * 244 * param base SMC peripheral base address. 245 * return SMC configuration error code. 246 */ SMC_SetPowerModeVlls0(SMC_Type * base)247status_t SMC_SetPowerModeVlls0(SMC_Type *base) 248 { 249 uint32_t reg; 250 251 /* configure to VLLS mode */ 252 reg = base->PMCTRL; 253 reg &= ~SMC_PMCTRL_STOPM_MASK; 254 reg |= ((uint32_t)kSMC_StopVlls0 << SMC_PMCTRL_STOPM_SHIFT); 255 base->PMCTRL = reg; 256 257 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 258 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 259 260 /* read back to make sure the configuration valid before enter stop mode */ 261 (void)base->PMCTRL; 262 __DSB(); 263 __WFI(); 264 __ISB(); 265 266 return kStatus_Success; 267 } 268 #endif /* FSL_FEATURE_SMC_HAS_STOP_SUBMODE0 */ 269 270 #if (defined(FSL_FEATURE_SMC_HAS_STOP_SUBMODE2) && FSL_FEATURE_SMC_HAS_STOP_SUBMODE2) 271 /*! 272 * brief Configure the system to VLLS2 power mode. 273 * 274 * param base SMC peripheral base address. 275 * return SMC configuration error code. 276 */ SMC_SetPowerModeVlls2(SMC_Type * base)277status_t SMC_SetPowerModeVlls2(SMC_Type *base) 278 { 279 uint32_t reg; 280 281 /* configure to VLLS mode */ 282 reg = base->PMCTRL; 283 reg &= ~SMC_PMCTRL_STOPM_MASK; 284 reg |= ((uint32_t)kSMC_StopVlls2 << SMC_PMCTRL_STOPM_SHIFT); 285 base->PMCTRL = reg; 286 287 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 288 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 289 290 /* read back to make sure the configuration valid before enter stop mode */ 291 (void)base->PMCTRL; 292 __DSB(); 293 __WFI(); 294 __ISB(); 295 296 return kStatus_Success; 297 } 298 #endif /* FSL_FEATURE_SMC_HAS_STOP_SUBMODE0 */ 299 300 #else /* FSL_FEATURE_SMC_HAS_SUB_STOP_MODE */ 301 /*! 302 * brief Configure the system to VLLS power mode. 303 * 304 * param base SMC peripheral base address. 305 * return SMC configuration error code. 306 */ SMC_SetPowerModeVlls(SMC_Type * base)307status_t SMC_SetPowerModeVlls(SMC_Type *base) 308 { 309 uint32_t reg; 310 status_t status; 311 312 /* configure to VLLS mode */ 313 reg = base->PMCTRL; 314 reg &= ~SMC_PMCTRL_STOPM_MASK; 315 reg |= ((uint32_t)kSMC_StopVlls << SMC_PMCTRL_STOPM_SHIFT); 316 base->PMCTRL = reg; 317 318 /* Set the SLEEPDEEP bit to enable deep sleep mode */ 319 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 320 321 /* read back to make sure the configuration valid before enter stop mode */ 322 (void)base->PMCTRL; 323 __DSB(); 324 __WFI(); 325 __ISB(); 326 327 #if (defined(FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) && FSL_FEATURE_SMC_HAS_PMCTRL_STOPA) 328 /* check whether the power mode enter Stop mode succeed */ 329 if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) 330 { 331 status = kStatus_SMC_StopAbort; 332 } 333 else 334 { 335 status = kStatus_Success; 336 } 337 #else 338 status = kStatus_Success; 339 #endif /* FSL_FEATURE_SMC_HAS_PMCTRL_STOPA */ 340 341 return status; 342 } 343 #endif /* FSL_FEATURE_SMC_HAS_SUB_STOP_MODE */ 344 345 /*! 346 * brief Configures the reset pin filter. 347 * 348 * This function sets the reset pin filter including the enablement/disablement and filter width. 349 * 350 * param base SMC peripheral base address. 351 * param config Pointer to the configuration structure. 352 */ SMC_ConfigureResetPinFilter(SMC_Type * base,const smc_reset_pin_filter_config_t * config)353void SMC_ConfigureResetPinFilter(SMC_Type *base, const smc_reset_pin_filter_config_t *config) 354 { 355 assert(NULL != config); 356 357 uint32_t reg; 358 359 reg = SMC_RPC_FILTCFG(config->slowClockFilterCount) | SMC_RPC_FILTEN(config->enableFilter); 360 #if (defined(FSL_FEATURE_SMC_HAS_RPC_LPOFEN) && FSL_FEATURE_SMC_HAS_RPC_LPOFEN) 361 if (config->enableLpoFilter) 362 { 363 reg |= SMC_RPC_LPOFEN_MASK; 364 } 365 #endif /* FSL_FEATURE_SMC_HAS_RPC_LPOFEN */ 366 367 base->RPC = reg; 368 } 369