From 56e86c626df3dbf74c1021210636a7c5d92a49ce Mon Sep 17 00:00:00 2001 From: Dominik Sliwa Date: Tue, 30 Oct 2018 16:31:29 +0100 Subject: move to cmake Signed-off-by: Dominik Sliwa --- drivers/src/fsl_smc.c | 400 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 400 insertions(+) create mode 100644 drivers/src/fsl_smc.c (limited to 'drivers/src/fsl_smc.c') diff --git a/drivers/src/fsl_smc.c b/drivers/src/fsl_smc.c new file mode 100644 index 0000000..dacf193 --- /dev/null +++ b/drivers/src/fsl_smc.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_smc.h" +#include "fsl_flash.h" + +#if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +void SMC_GetParam(SMC_Type *base, smc_param_t *param) +{ + uint32_t reg = base->PARAM; + param->hsrunEnable = (bool)(reg & SMC_PARAM_EHSRUN_MASK); + param->llsEnable = (bool)(reg & SMC_PARAM_ELLS_MASK); + param->lls2Enable = (bool)(reg & SMC_PARAM_ELLS2_MASK); + param->vlls0Enable = (bool)(reg & SMC_PARAM_EVLLS0_MASK); +} +#endif /* FSL_FEATURE_SMC_HAS_PARAM */ + +void SMC_PreEnterStopModes(void) +{ + flash_prefetch_speculation_status_t speculationStatus = + { + kFLASH_prefetchSpeculationOptionDisable, /* Disable instruction speculation.*/ + kFLASH_prefetchSpeculationOptionDisable, /* Disable data speculation.*/ + }; + + __disable_irq(); + __ISB(); + + /* + * Before enter stop modes, the flash cache prefetch should be disabled. + * Otherwise the prefetch might be interrupted by stop, then the data and + * and instruction from flash are wrong. + */ + FLASH_PflashSetPrefetchSpeculation(&speculationStatus); +} + +void SMC_PostExitStopModes(void) +{ + flash_prefetch_speculation_status_t speculationStatus = + { + kFLASH_prefetchSpeculationOptionEnable, /* Enable instruction speculation.*/ + kFLASH_prefetchSpeculationOptionEnable, /* Enable data speculation.*/ + }; + + FLASH_PflashSetPrefetchSpeculation(&speculationStatus); + + __enable_irq(); + __ISB(); +} + +status_t SMC_SetPowerModeRun(SMC_Type *base) +{ + uint8_t reg; + + reg = base->PMCTRL; + /* configure Normal RUN mode */ + reg &= ~SMC_PMCTRL_RUNM_MASK; + reg |= (kSMC_RunNormal << SMC_PMCTRL_RUNM_SHIFT); + base->PMCTRL = reg; + + return kStatus_Success; +} + +#if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) +status_t SMC_SetPowerModeHsrun(SMC_Type *base) +{ + uint8_t reg; + + reg = base->PMCTRL; + /* configure High Speed RUN mode */ + reg &= ~SMC_PMCTRL_RUNM_MASK; + reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + base->PMCTRL = reg; + + return kStatus_Success; +} +#endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ + +status_t SMC_SetPowerModeWait(SMC_Type *base) +{ + /* configure Normal Wait mode */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); + __WFI(); + __ISB(); + + return kStatus_Success; +} + +status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) +{ + uint8_t reg; + +#if (defined(FSL_FEATURE_SMC_HAS_PSTOPO) && FSL_FEATURE_SMC_HAS_PSTOPO) + /* configure the Partial Stop mode in Noraml Stop mode */ + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + base->STOPCTRL = reg; +#endif + + /* configure Normal Stop mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + + /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __DSB(); + __WFI(); + __ISB(); + + /* check whether the power mode enter Stop mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} + +status_t SMC_SetPowerModeVlpr(SMC_Type *base +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + , + bool wakeupMode +#endif + ) +{ + uint8_t reg; + + reg = base->PMCTRL; +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + /* configure whether the system remains in VLP mode on an interrupt */ + if (wakeupMode) + { + /* exits to RUN mode on an interrupt */ + reg |= SMC_PMCTRL_LPWUI_MASK; + } + else + { + /* remains in VLP mode on an interrupt */ + reg &= ~SMC_PMCTRL_LPWUI_MASK; + } +#endif /* FSL_FEATURE_SMC_HAS_LPWUI */ + + /* configure VLPR mode */ + reg &= ~SMC_PMCTRL_RUNM_MASK; + reg |= (kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); + base->PMCTRL = reg; + + return kStatus_Success; +} + +status_t SMC_SetPowerModeVlpw(SMC_Type *base) +{ + /* configure VLPW mode */ + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); + __WFI(); + __ISB(); + + return kStatus_Success; +} + +status_t SMC_SetPowerModeVlps(SMC_Type *base) +{ + uint8_t reg; + + /* configure VLPS mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __DSB(); + __WFI(); + __ISB(); + + /* check whether the power mode enter VLPS mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} + +#if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +status_t SMC_SetPowerModeLls(SMC_Type *base +#if ((defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) || \ + (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO)) + , + const smc_power_mode_lls_config_t *config +#endif + ) +{ + uint8_t reg; + + /* configure to LLS mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopLls << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + +/* configure LLS sub-mode*/ +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); + base->STOPCTRL = reg; +#endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ + +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + if (config->enableLpoClock) + { + base->STOPCTRL &= ~SMC_STOPCTRL_LPOPO_MASK; + } + else + { + base->STOPCTRL |= SMC_STOPCTRL_LPOPO_MASK; + } +#endif /* FSL_FEATURE_SMC_HAS_LPOPO */ + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __DSB(); + __WFI(); + __ISB(); + + /* check whether the power mode enter LLS mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} +#endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ + +#if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) +status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) +{ + uint8_t reg; + +#if (defined(FSL_FEATURE_SMC_HAS_PORPO) && FSL_FEATURE_SMC_HAS_PORPO) +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) || \ + (defined(FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) && FSL_FEATURE_SMC_USE_STOPCTRL_VLLSM) || \ + (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + if (config->subMode == kSMC_StopSub0) +#endif + { + /* configure whether the Por Detect work in Vlls0 mode */ + if (config->enablePorDetectInVlls0) + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL &= ~SMC_VLLSCTRL_PORPO_MASK; +#else + base->STOPCTRL &= ~SMC_STOPCTRL_PORPO_MASK; +#endif + } + else + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL |= SMC_VLLSCTRL_PORPO_MASK; +#else + base->STOPCTRL |= SMC_STOPCTRL_PORPO_MASK; +#endif + } + } +#endif /* FSL_FEATURE_SMC_HAS_PORPO */ + +#if (defined(FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) && FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION) + else if (config->subMode == kSMC_StopSub2) + { + /* configure whether the Por Detect work in Vlls0 mode */ + if (config->enableRam2InVlls2) + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; +#else + base->STOPCTRL |= SMC_STOPCTRL_RAM2PO_MASK; +#endif + } + else + { +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + base->VLLSCTRL &= ~SMC_VLLSCTRL_RAM2PO_MASK; +#else + base->STOPCTRL &= ~SMC_STOPCTRL_RAM2PO_MASK; +#endif + } + } + else + { + } +#endif /* FSL_FEATURE_SMC_HAS_RAM2_POWER_OPTION */ + + /* configure to VLLS mode */ + reg = base->PMCTRL; + reg &= ~SMC_PMCTRL_STOPM_MASK; + reg |= (kSMC_StopVlls << SMC_PMCTRL_STOPM_SHIFT); + base->PMCTRL = reg; + +/* configure the VLLS sub-mode */ +#if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) + reg = base->VLLSCTRL; + reg &= ~SMC_VLLSCTRL_VLLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_VLLSCTRL_VLLSM_SHIFT); + base->VLLSCTRL = reg; +#else +#if (defined(FSL_FEATURE_SMC_HAS_LLS_SUBMODE) && FSL_FEATURE_SMC_HAS_LLS_SUBMODE) + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); + base->STOPCTRL = reg; +#else + reg = base->STOPCTRL; + reg &= ~SMC_STOPCTRL_VLLSM_MASK; + reg |= ((uint32_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); + base->STOPCTRL = reg; +#endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ +#endif + +#if (defined(FSL_FEATURE_SMC_HAS_LPOPO) && FSL_FEATURE_SMC_HAS_LPOPO) + if (config->enableLpoClock) + { + base->STOPCTRL &= ~SMC_STOPCTRL_LPOPO_MASK; + } + else + { + base->STOPCTRL |= SMC_STOPCTRL_LPOPO_MASK; + } +#endif /* FSL_FEATURE_SMC_HAS_LPOPO */ + + /* Set the SLEEPDEEP bit to enable deep sleep mode */ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* read back to make sure the configuration valid before enter stop mode */ + (void)base->PMCTRL; + __DSB(); + __WFI(); + __ISB(); + + /* check whether the power mode enter LLS mode succeed */ + if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + { + return kStatus_SMC_StopAbort; + } + else + { + return kStatus_Success; + } +} +#endif /* FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE */ -- cgit v1.2.3