diff --git a/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.cpp b/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.cpp index 9ac086d771..8be325b0dc 100644 --- a/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.cpp +++ b/features/nanostack/targets/TARGET_NXP/TARGET_KW41Z/NanostackRfPhyKw41z.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "mbed_power_mgmt.h" #include "common_functions.h" #include "platform/arm_hal_interrupt.h" #include "platform/arm_hal_phy.h" @@ -87,8 +88,9 @@ static uint8_t MAC64_addr[8]; static xcvrState_t mPhySeqState; static uint8_t rf_mac_handle; -volatile uint8_t rf_ed_value = 0; -static bool rf_ack_pending_state = false; +static volatile uint8_t rf_ed_value = 0; +static volatile bool rf_ack_pending_state = false; +static volatile bool sleep_blocked = false; static NanostackRfPhyKw41z *rf = NULL; @@ -155,6 +157,11 @@ static int8_t rf_device_register(void) static void rf_device_unregister(void) { arm_net_phy_unregister(rf_radio_driver_id); + + if (sleep_blocked) { + sleep_manager_unlock_deep_sleep(); + sleep_blocked = false; + } } /* @@ -209,16 +216,29 @@ static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_ /*Reset PHY driver and set to idle*/ case PHY_INTERFACE_RESET: rf_abort(); + if (sleep_blocked) { + sleep_manager_unlock_deep_sleep(); + sleep_blocked = false; + } break; /*Disable PHY Interface driver*/ case PHY_INTERFACE_DOWN: rf_abort(); + if (sleep_blocked) { + sleep_manager_unlock_deep_sleep(); + sleep_blocked = false; + } break; /*Enable PHY Interface driver*/ case PHY_INTERFACE_UP: if (PhyPlmeSetCurrentChannelRequest(rf_channel, 0)) { return 1; } + if (!sleep_blocked) { + /* Disable enter to deep sleep when transfer active */ + sleep_manager_lock_deep_sleep(); + sleep_blocked = true; + } rf_receive(); break; /*Enable wireless interface ED scan mode*/ @@ -226,6 +246,11 @@ static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_ if (PhyPlmeSetCurrentChannelRequest(rf_channel, 0)) { return 1; } + if (!sleep_blocked) { + /* Disable enter to deep sleep when transfer active */ + sleep_manager_lock_deep_sleep(); + sleep_blocked = true; + } rf_abort(); rf_mac_ed_state_enable(); break; @@ -234,6 +259,11 @@ static int8_t rf_interface_state_control(phy_interface_state_e new_state, uint8_ if (PhyPlmeSetCurrentChannelRequest(rf_channel, 0)) { return 1; } + if (!sleep_blocked) { + /* Disable enter to deep sleep when transfer active */ + sleep_manager_lock_deep_sleep(); + sleep_blocked = true; + } rf_receive(); break; } diff --git a/features/netsocket/emac-drivers/TARGET_Freescale_EMAC/kinetis_emac.cpp b/features/netsocket/emac-drivers/TARGET_Freescale_EMAC/kinetis_emac.cpp index e0ad4cc1d3..857d8e95f4 100644 --- a/features/netsocket/emac-drivers/TARGET_Freescale_EMAC/kinetis_emac.cpp +++ b/features/netsocket/emac-drivers/TARGET_Freescale_EMAC/kinetis_emac.cpp @@ -46,6 +46,7 @@ #include "kinetis_emac_config.h" #include "kinetis_emac.h" +#include "mbed_power_mgmt.h" enet_handle_t g_handle; // TX Buffer descriptors @@ -496,6 +497,9 @@ bool Kinetis_EMAC::power_up() return false; } + // Can't enter deep sleep as long as Ethernet is active + sleep_manager_lock_deep_sleep(); + /* Worker thread */ thread = create_new_thread("Kinetis_EMAC_thread", &Kinetis_EMAC::thread_function, this, THREAD_STACKSIZE, THREAD_PRIORITY, &thread_cb); @@ -580,7 +584,8 @@ void Kinetis_EMAC::set_all_multicast(bool all) void Kinetis_EMAC::power_down() { - /* No-op at this stage */ + // Ethernet went down, can enter deep sleep + sleep_manager_unlock_deep_sleep(); } void Kinetis_EMAC::set_memory_manager(EMACMemoryManager &mem_mngr) diff --git a/features/netsocket/emac-drivers/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.cpp b/features/netsocket/emac-drivers/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.cpp index ffab0e1b5d..d777bb0f42 100644 --- a/features/netsocket/emac-drivers/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.cpp +++ b/features/netsocket/emac-drivers/TARGET_NXP_EMAC/TARGET_IMX/imx_emac.cpp @@ -46,6 +46,7 @@ #include "imx_emac_config.h" #include "imx_emac.h" +#include "mbed_power_mgmt.h" enet_handle_t g_handle; // RX packet buffer pointers @@ -500,6 +501,9 @@ bool Kinetis_EMAC::power_up() return false; } + // Can't enter deep sleep as long as Ethernet is active + sleep_manager_lock_deep_sleep(); + /* Worker thread */ thread = create_new_thread("Kinetis_EMAC_thread", &Kinetis_EMAC::thread_function, this, THREAD_STACKSIZE, THREAD_PRIORITY, &thread_cb); @@ -584,7 +588,8 @@ void Kinetis_EMAC::set_all_multicast(bool all) void Kinetis_EMAC::power_down() { - /* No-op at this stage */ + // Ethernet went down, can enter deep sleep + sleep_manager_unlock_deep_sleep(); } void Kinetis_EMAC::set_memory_manager(EMACMemoryManager &mem_mngr) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_smc.c index dacf193476..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_smc.c @@ -1,94 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * All rights reserved. * - * 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" -#include "fsl_flash.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ void SMC_PreEnterStopModes(void) { - flash_prefetch_speculation_status_t speculationStatus = - { - kFLASH_prefetchSpeculationOptionDisable, /* Disable instruction speculation.*/ - kFLASH_prefetchSpeculationOptionDisable, /* Disable data speculation.*/ - }; - - __disable_irq(); + g_savedPrimask = DisableGlobalIRQ(); __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); } +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ 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(); + EnableGlobalIRQ(g_savedPrimask); __ISB(); } +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -96,13 +170,19 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ @@ -114,22 +194,29 @@ status_t SMC_SetPowerModeWait(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -137,12 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -152,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -172,18 +263,24 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { /* configure VLPW mode */ @@ -196,14 +293,20 @@ status_t SMC_SetPowerModeVlpw(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -211,12 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -227,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -267,12 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -284,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -296,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -319,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -332,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -383,12 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_smc.h index 168ce83501..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * All rights reserved. * - * 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,15 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.3. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 3)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -64,18 +41,14 @@ typedef enum _smc_power_mode_protection #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -85,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -107,7 +80,7 @@ typedef enum _smc_power_state typedef enum _smc_run_mode { kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ @@ -119,7 +92,7 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ @@ -148,7 +121,7 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; @@ -324,11 +297,7 @@ void SMC_PostExitStopModes(void); * * This function should be called before entering WAIT/VLPW modes. */ -static inline void SMC_PreEnterWaitModes(void) -{ - __disable_irq(); - __ISB(); -} +void SMC_PreEnterWaitModes(void); /*! * @brief Recovers after wake up from stop modes. @@ -336,11 +305,7 @@ static inline void SMC_PreEnterWaitModes(void) * This function should be called after wake up from WAIT/VLPW modes. * It is used with @ref SMC_PreEnterWaitModes. */ -static inline void SMC_PostExitWaitModes(void) -{ - __enable_irq(); - __ISB(); -} +void SMC_PostExitWaitModes(void); /*! * @brief Configures the system to RUN power mode. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/serial_api.c index c8f38964c0..ff3fa9256c 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/serial_api.c @@ -340,4 +340,14 @@ const PinMap *serial_rts_pinmap() return PinMap_UART_RTS; } +void serial_wait_tx_complete(uint32_t uart_index) +{ + UART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kUART_TransmissionCompleteFlag & UART_GetStatusFlags((UART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/drivers/fsl_smc.c index 5c86e3366b..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/drivers/fsl_smc.c @@ -1,94 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" -#include "fsl_flash.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ void SMC_PreEnterStopModes(void) { - flash_prefetch_speculation_status_t speculationStatus = - { - kFLASH_prefetchSpeculationOptionDisable, /* Disable instruction speculation.*/ - kFLASH_prefetchSpeculationOptionDisable, /* Disable data speculation.*/ - }; - - __disable_irq(); + g_savedPrimask = DisableGlobalIRQ(); __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); } +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ 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(); + EnableGlobalIRQ(g_savedPrimask); __ISB(); } +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -96,13 +170,19 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ @@ -114,22 +194,29 @@ status_t SMC_SetPowerModeWait(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -137,12 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -152,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -172,18 +263,24 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { /* configure VLPW mode */ @@ -196,14 +293,20 @@ status_t SMC_SetPowerModeVlpw(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -211,12 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -227,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -267,12 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -284,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -296,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -319,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -332,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -383,12 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/drivers/fsl_smc.h index b901468e70..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,15 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.3. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 3)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -64,18 +41,14 @@ typedef enum _smc_power_mode_protection #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -85,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -107,7 +80,7 @@ typedef enum _smc_power_state typedef enum _smc_run_mode { kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ @@ -119,7 +92,7 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ @@ -148,7 +121,7 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; @@ -324,11 +297,7 @@ void SMC_PostExitStopModes(void); * * This function should be called before entering WAIT/VLPW modes. */ -static inline void SMC_PreEnterWaitModes(void) -{ - __disable_irq(); - __ISB(); -} +void SMC_PreEnterWaitModes(void); /*! * @brief Recovers after wake up from stop modes. @@ -336,11 +305,7 @@ static inline void SMC_PreEnterWaitModes(void) * This function should be called after wake up from WAIT/VLPW modes. * It is used with @ref SMC_PreEnterWaitModes. */ -static inline void SMC_PostExitWaitModes(void) -{ - __enable_irq(); - __ISB(); -} +void SMC_PostExitWaitModes(void); /*! * @brief Configures the system to RUN power mode. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/serial_api.c index 8f6332296c..eab2c000bb 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/serial_api.c @@ -332,4 +332,14 @@ const PinMap *serial_rts_pinmap() return PinMap_UART_RTS; } +void serial_wait_tx_complete(uint32_t uart_index) +{ + LPUART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kLPUART_TransmissionCompleteFlag & LPUART_GetStatusFlags((LPUART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/drivers/fsl_smc.c index 0018cf7dce..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/drivers/fsl_smc.c @@ -1,60 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -62,38 +170,53 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); __WFI(); + __ISB(); return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -101,10 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -114,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -134,42 +263,50 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { - /* Power mode transaction to VLPW can only happen in VLPR mode */ - if (kSMC_PowerStateVlpr != SMC_GetPowerModeState(base)) - { - return kStatus_Fail; - } - /* configure VLPW mode */ /* Set the SLEEPDEEP bit to enable deep sleep mode */ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); __WFI(); + __ISB(); return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -177,10 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -191,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -231,10 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -246,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -258,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -281,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -294,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -345,10 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/drivers/fsl_smc.h index 5149f87e34..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,16 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.1. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -54,29 +30,25 @@ typedef enum _smc_power_mode_protection { #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */ #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-Power Mode. */ + kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-power Mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High Speed Run mode. */ + kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode. */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -86,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -107,10 +79,10 @@ typedef enum _smc_power_state */ typedef enum _smc_run_mode { - kSMC_RunNormal = 0U, /*!< normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-Low-Power RUN mode. */ + kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_Hsrun = 3U /*!< High Speed Run mode (HSRUN). */ + kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ } smc_run_mode_t; @@ -120,12 +92,12 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-Low-Power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_StopLls = 3U, /*!< Low-Leakage Stop mode. */ + kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #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) - kSMC_StopVlls = 4U /*!< Very-Low-Leakage Stop mode. */ + kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */ #endif } smc_stop_mode_t; @@ -149,13 +121,13 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; /*! - * @brief SMC configuration status + * @brief SMC configuration status. */ enum _smc_status { @@ -190,7 +162,7 @@ typedef struct _smc_param #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) /*! - * @brief SMC Low-Leakage Stop power mode config + * @brief SMC Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_lls_config { @@ -205,7 +177,7 @@ typedef struct _smc_power_mode_lls_config #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief SMC Very Low-Leakage Stop power mode config + * @brief SMC Very Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_vlls_config { @@ -242,10 +214,10 @@ extern "C" { * @brief Gets the SMC version ID. * * This function gets the SMC version ID, including major version number, - * minor version number and feature specification number. + * minor version number, and feature specification number. * * @param base SMC peripheral base address. - * @param versionId Pointer to version ID structure. + * @param versionId Pointer to the version ID structure. */ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) { @@ -257,10 +229,10 @@ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) /*! * @brief Gets the SMC parameter. * - * This function gets the SMC parameter, including the enabled power mdoes. + * This function gets the SMC parameter including the enabled power mdoes. * * @param base SMC peripheral base address. - * @param param Pointer to SMC param structure. + * @param param Pointer to the SMC param structure. */ void SMC_GetParam(SMC_Type *base, smc_param_t *param); #endif @@ -274,7 +246,7 @@ void SMC_GetParam(SMC_Type *base, smc_param_t *param); * system level initialization stage. See the reference manual for details. * This register can only write once after the power reset. * - * The allowed modes are passed as bit map, for example, to allow LLS and VLLS, + * The allowed modes are passed as bit map. For example, to allow LLS and VLLS, * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps). * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll). * @@ -289,13 +261,13 @@ static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedMod /*! * @brief Gets the current power mode status. * - * This function returns the current power mode stat. Once application - * switches the power mode, it should always check the stat to check whether it - * runs into the specified mode or not. An application should check + * This function returns the current power mode status. After the application + * switches the power mode, it should always check the status to check whether it + * runs into the specified mode or not. The application should check * this mode before switching to a different mode. The system requires that * only certain modes can switch to other specific modes. See the * reference manual for details and the smc_power_state_t for information about - * the power stat. + * the power status. * * @param base SMC peripheral base address. * @return Current power mode status. @@ -306,7 +278,37 @@ static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base) } /*! - * @brief Configure the system to RUN power mode. + * @brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with @ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void); + +/*! + * @brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with @ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void); + +/*! + * @brief Configures the system to RUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -315,7 +317,7 @@ status_t SMC_SetPowerModeRun(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) /*! - * @brief Configure the system to HSRUN power mode. + * @brief Configures the system to HSRUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -324,7 +326,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ /*! - * @brief Configure the system to WAIT power mode. + * @brief Configures the system to WAIT power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -332,7 +334,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); status_t SMC_SetPowerModeWait(SMC_Type *base); /*! - * @brief Configure the system to Stop power mode. + * @brief Configures the system to Stop power mode. * * @param base SMC peripheral base address. * @param option Partial Stop mode option. @@ -342,7 +344,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode. @@ -351,7 +353,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode); #else /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -360,7 +362,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_LPWUI */ /*! - * @brief Configure the system to VLPW power mode. + * @brief Configures the system to VLPW power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -368,7 +370,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); status_t SMC_SetPowerModeVlpw(SMC_Type *base); /*! - * @brief Configure the system to VLPS power mode. + * @brief Configures the system to VLPS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -379,7 +381,7 @@ status_t SMC_SetPowerModeVlps(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)) /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @param config The LLS power mode configuration structure @@ -388,7 +390,7 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base); status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config); #else /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -399,7 +401,7 @@ status_t SMC_SetPowerModeLls(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief Configure the system to VLLS power mode. + * @brief Configures the system to VLLS power mode. * * @param base SMC peripheral base address. * @param config The VLLS power mode configuration structure. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/serial_api.c index 8500a29d9e..6eb9daa682 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL27Z/serial_api.c @@ -288,4 +288,14 @@ const PinMap *serial_rts_pinmap() return PinMap_UART_RTS; } +void serial_wait_tx_complete(uint32_t uart_index) +{ + LPUART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kLPUART_TransmissionCompleteFlag & LPUART_GetStatusFlags((LPUART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/drivers/fsl_smc.c index 0018cf7dce..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/drivers/fsl_smc.c @@ -1,60 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -62,38 +170,53 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); __WFI(); + __ISB(); return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -101,10 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -114,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -134,42 +263,50 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { - /* Power mode transaction to VLPW can only happen in VLPR mode */ - if (kSMC_PowerStateVlpr != SMC_GetPowerModeState(base)) - { - return kStatus_Fail; - } - /* configure VLPW mode */ /* Set the SLEEPDEEP bit to enable deep sleep mode */ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); __WFI(); + __ISB(); return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -177,10 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -191,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -231,10 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -246,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -258,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -281,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -294,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -345,10 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/drivers/fsl_smc.h index 5149f87e34..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,16 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.1. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -54,29 +30,25 @@ typedef enum _smc_power_mode_protection { #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */ #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-Power Mode. */ + kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-power Mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High Speed Run mode. */ + kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode. */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -86,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -107,10 +79,10 @@ typedef enum _smc_power_state */ typedef enum _smc_run_mode { - kSMC_RunNormal = 0U, /*!< normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-Low-Power RUN mode. */ + kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_Hsrun = 3U /*!< High Speed Run mode (HSRUN). */ + kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ } smc_run_mode_t; @@ -120,12 +92,12 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-Low-Power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_StopLls = 3U, /*!< Low-Leakage Stop mode. */ + kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #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) - kSMC_StopVlls = 4U /*!< Very-Low-Leakage Stop mode. */ + kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */ #endif } smc_stop_mode_t; @@ -149,13 +121,13 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; /*! - * @brief SMC configuration status + * @brief SMC configuration status. */ enum _smc_status { @@ -190,7 +162,7 @@ typedef struct _smc_param #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) /*! - * @brief SMC Low-Leakage Stop power mode config + * @brief SMC Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_lls_config { @@ -205,7 +177,7 @@ typedef struct _smc_power_mode_lls_config #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief SMC Very Low-Leakage Stop power mode config + * @brief SMC Very Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_vlls_config { @@ -242,10 +214,10 @@ extern "C" { * @brief Gets the SMC version ID. * * This function gets the SMC version ID, including major version number, - * minor version number and feature specification number. + * minor version number, and feature specification number. * * @param base SMC peripheral base address. - * @param versionId Pointer to version ID structure. + * @param versionId Pointer to the version ID structure. */ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) { @@ -257,10 +229,10 @@ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) /*! * @brief Gets the SMC parameter. * - * This function gets the SMC parameter, including the enabled power mdoes. + * This function gets the SMC parameter including the enabled power mdoes. * * @param base SMC peripheral base address. - * @param param Pointer to SMC param structure. + * @param param Pointer to the SMC param structure. */ void SMC_GetParam(SMC_Type *base, smc_param_t *param); #endif @@ -274,7 +246,7 @@ void SMC_GetParam(SMC_Type *base, smc_param_t *param); * system level initialization stage. See the reference manual for details. * This register can only write once after the power reset. * - * The allowed modes are passed as bit map, for example, to allow LLS and VLLS, + * The allowed modes are passed as bit map. For example, to allow LLS and VLLS, * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps). * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll). * @@ -289,13 +261,13 @@ static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedMod /*! * @brief Gets the current power mode status. * - * This function returns the current power mode stat. Once application - * switches the power mode, it should always check the stat to check whether it - * runs into the specified mode or not. An application should check + * This function returns the current power mode status. After the application + * switches the power mode, it should always check the status to check whether it + * runs into the specified mode or not. The application should check * this mode before switching to a different mode. The system requires that * only certain modes can switch to other specific modes. See the * reference manual for details and the smc_power_state_t for information about - * the power stat. + * the power status. * * @param base SMC peripheral base address. * @return Current power mode status. @@ -306,7 +278,37 @@ static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base) } /*! - * @brief Configure the system to RUN power mode. + * @brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with @ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void); + +/*! + * @brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with @ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void); + +/*! + * @brief Configures the system to RUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -315,7 +317,7 @@ status_t SMC_SetPowerModeRun(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) /*! - * @brief Configure the system to HSRUN power mode. + * @brief Configures the system to HSRUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -324,7 +326,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ /*! - * @brief Configure the system to WAIT power mode. + * @brief Configures the system to WAIT power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -332,7 +334,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); status_t SMC_SetPowerModeWait(SMC_Type *base); /*! - * @brief Configure the system to Stop power mode. + * @brief Configures the system to Stop power mode. * * @param base SMC peripheral base address. * @param option Partial Stop mode option. @@ -342,7 +344,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode. @@ -351,7 +353,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode); #else /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -360,7 +362,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_LPWUI */ /*! - * @brief Configure the system to VLPW power mode. + * @brief Configures the system to VLPW power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -368,7 +370,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); status_t SMC_SetPowerModeVlpw(SMC_Type *base); /*! - * @brief Configure the system to VLPS power mode. + * @brief Configures the system to VLPS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -379,7 +381,7 @@ status_t SMC_SetPowerModeVlps(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)) /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @param config The LLS power mode configuration structure @@ -388,7 +390,7 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base); status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config); #else /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -399,7 +401,7 @@ status_t SMC_SetPowerModeLls(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief Configure the system to VLLS power mode. + * @brief Configures the system to VLLS power mode. * * @param base SMC peripheral base address. * @param config The VLLS power mode configuration structure. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/serial_api.c index 3deee1e332..bdd325dd8f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/serial_api.c @@ -300,4 +300,14 @@ const PinMap *serial_rts_pinmap() return PinMap_UART_RTS; } +void serial_wait_tx_complete(uint32_t uart_index) +{ + LPUART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kLPUART_TransmissionCompleteFlag & LPUART_GetStatusFlags((LPUART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_smc.c index 45382fdffe..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_smc.c @@ -1,60 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -62,13 +170,19 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ @@ -80,22 +194,29 @@ status_t SMC_SetPowerModeWait(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -103,12 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -118,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -138,18 +263,24 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { /* configure VLPW mode */ @@ -162,14 +293,20 @@ status_t SMC_SetPowerModeVlpw(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -177,12 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -193,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -233,12 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -250,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -262,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -285,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -298,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -349,12 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_smc.h index 4148734a2a..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,15 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.2. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -53,29 +30,25 @@ typedef enum _smc_power_mode_protection { #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */ #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-Power Mode. */ + kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-power Mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High Speed Run mode. */ + kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode. */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -85,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -106,10 +79,10 @@ typedef enum _smc_power_state */ typedef enum _smc_run_mode { - kSMC_RunNormal = 0U, /*!< normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-Low-Power RUN mode. */ + kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_Hsrun = 3U /*!< High Speed Run mode (HSRUN). */ + kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ } smc_run_mode_t; @@ -119,12 +92,12 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-Low-Power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_StopLls = 3U, /*!< Low-Leakage Stop mode. */ + kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #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) - kSMC_StopVlls = 4U /*!< Very-Low-Leakage Stop mode. */ + kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */ #endif } smc_stop_mode_t; @@ -148,13 +121,13 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; /*! - * @brief SMC configuration status + * @brief SMC configuration status. */ enum _smc_status { @@ -189,7 +162,7 @@ typedef struct _smc_param #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) /*! - * @brief SMC Low-Leakage Stop power mode config + * @brief SMC Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_lls_config { @@ -204,7 +177,7 @@ typedef struct _smc_power_mode_lls_config #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief SMC Very Low-Leakage Stop power mode config + * @brief SMC Very Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_vlls_config { @@ -241,10 +214,10 @@ extern "C" { * @brief Gets the SMC version ID. * * This function gets the SMC version ID, including major version number, - * minor version number and feature specification number. + * minor version number, and feature specification number. * * @param base SMC peripheral base address. - * @param versionId Pointer to version ID structure. + * @param versionId Pointer to the version ID structure. */ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) { @@ -256,10 +229,10 @@ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) /*! * @brief Gets the SMC parameter. * - * This function gets the SMC parameter, including the enabled power mdoes. + * This function gets the SMC parameter including the enabled power mdoes. * * @param base SMC peripheral base address. - * @param param Pointer to SMC param structure. + * @param param Pointer to the SMC param structure. */ void SMC_GetParam(SMC_Type *base, smc_param_t *param); #endif @@ -273,7 +246,7 @@ void SMC_GetParam(SMC_Type *base, smc_param_t *param); * system level initialization stage. See the reference manual for details. * This register can only write once after the power reset. * - * The allowed modes are passed as bit map, for example, to allow LLS and VLLS, + * The allowed modes are passed as bit map. For example, to allow LLS and VLLS, * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps). * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll). * @@ -288,13 +261,13 @@ static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedMod /*! * @brief Gets the current power mode status. * - * This function returns the current power mode stat. Once application - * switches the power mode, it should always check the stat to check whether it - * runs into the specified mode or not. An application should check + * This function returns the current power mode status. After the application + * switches the power mode, it should always check the status to check whether it + * runs into the specified mode or not. The application should check * this mode before switching to a different mode. The system requires that * only certain modes can switch to other specific modes. See the * reference manual for details and the smc_power_state_t for information about - * the power stat. + * the power status. * * @param base SMC peripheral base address. * @return Current power mode status. @@ -305,7 +278,37 @@ static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base) } /*! - * @brief Configure the system to RUN power mode. + * @brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with @ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void); + +/*! + * @brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with @ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void); + +/*! + * @brief Configures the system to RUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -314,7 +317,7 @@ status_t SMC_SetPowerModeRun(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) /*! - * @brief Configure the system to HSRUN power mode. + * @brief Configures the system to HSRUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -323,7 +326,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ /*! - * @brief Configure the system to WAIT power mode. + * @brief Configures the system to WAIT power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -331,7 +334,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); status_t SMC_SetPowerModeWait(SMC_Type *base); /*! - * @brief Configure the system to Stop power mode. + * @brief Configures the system to Stop power mode. * * @param base SMC peripheral base address. * @param option Partial Stop mode option. @@ -341,7 +344,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode. @@ -350,7 +353,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode); #else /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -359,7 +362,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_LPWUI */ /*! - * @brief Configure the system to VLPW power mode. + * @brief Configures the system to VLPW power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -367,7 +370,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); status_t SMC_SetPowerModeVlpw(SMC_Type *base); /*! - * @brief Configure the system to VLPS power mode. + * @brief Configures the system to VLPS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -378,7 +381,7 @@ status_t SMC_SetPowerModeVlps(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)) /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @param config The LLS power mode configuration structure @@ -387,7 +390,7 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base); status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config); #else /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -398,7 +401,7 @@ status_t SMC_SetPowerModeLls(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief Configure the system to VLLS power mode. + * @brief Configures the system to VLLS power mode. * * @param base SMC peripheral base address. * @param config The VLLS power mode configuration structure. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/serial_api.c index dd4a672fbd..d87ed1cc53 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL82Z/serial_api.c @@ -328,4 +328,14 @@ const PinMap *serial_rts_pinmap() return PinMap_UART_RTS; } +void serial_wait_tx_complete(uint32_t uart_index) +{ + LPUART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kLPUART_TransmissionCompleteFlag & LPUART_GetStatusFlags((LPUART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_smc.c index 45382fdffe..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_smc.c @@ -1,60 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -62,13 +170,19 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ @@ -80,22 +194,29 @@ status_t SMC_SetPowerModeWait(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -103,12 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -118,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -138,18 +263,24 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { /* configure VLPW mode */ @@ -162,14 +293,20 @@ status_t SMC_SetPowerModeVlpw(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -177,12 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -193,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -233,12 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -250,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -262,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -285,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -298,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -349,12 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_smc.h index 4148734a2a..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,15 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.2. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -53,29 +30,25 @@ typedef enum _smc_power_mode_protection { #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */ #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-Power Mode. */ + kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-power Mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High Speed Run mode. */ + kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode. */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -85,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -106,10 +79,10 @@ typedef enum _smc_power_state */ typedef enum _smc_run_mode { - kSMC_RunNormal = 0U, /*!< normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-Low-Power RUN mode. */ + kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_Hsrun = 3U /*!< High Speed Run mode (HSRUN). */ + kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ } smc_run_mode_t; @@ -119,12 +92,12 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-Low-Power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_StopLls = 3U, /*!< Low-Leakage Stop mode. */ + kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #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) - kSMC_StopVlls = 4U /*!< Very-Low-Leakage Stop mode. */ + kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */ #endif } smc_stop_mode_t; @@ -148,13 +121,13 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; /*! - * @brief SMC configuration status + * @brief SMC configuration status. */ enum _smc_status { @@ -189,7 +162,7 @@ typedef struct _smc_param #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) /*! - * @brief SMC Low-Leakage Stop power mode config + * @brief SMC Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_lls_config { @@ -204,7 +177,7 @@ typedef struct _smc_power_mode_lls_config #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief SMC Very Low-Leakage Stop power mode config + * @brief SMC Very Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_vlls_config { @@ -241,10 +214,10 @@ extern "C" { * @brief Gets the SMC version ID. * * This function gets the SMC version ID, including major version number, - * minor version number and feature specification number. + * minor version number, and feature specification number. * * @param base SMC peripheral base address. - * @param versionId Pointer to version ID structure. + * @param versionId Pointer to the version ID structure. */ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) { @@ -256,10 +229,10 @@ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) /*! * @brief Gets the SMC parameter. * - * This function gets the SMC parameter, including the enabled power mdoes. + * This function gets the SMC parameter including the enabled power mdoes. * * @param base SMC peripheral base address. - * @param param Pointer to SMC param structure. + * @param param Pointer to the SMC param structure. */ void SMC_GetParam(SMC_Type *base, smc_param_t *param); #endif @@ -273,7 +246,7 @@ void SMC_GetParam(SMC_Type *base, smc_param_t *param); * system level initialization stage. See the reference manual for details. * This register can only write once after the power reset. * - * The allowed modes are passed as bit map, for example, to allow LLS and VLLS, + * The allowed modes are passed as bit map. For example, to allow LLS and VLLS, * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps). * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll). * @@ -288,13 +261,13 @@ static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedMod /*! * @brief Gets the current power mode status. * - * This function returns the current power mode stat. Once application - * switches the power mode, it should always check the stat to check whether it - * runs into the specified mode or not. An application should check + * This function returns the current power mode status. After the application + * switches the power mode, it should always check the status to check whether it + * runs into the specified mode or not. The application should check * this mode before switching to a different mode. The system requires that * only certain modes can switch to other specific modes. See the * reference manual for details and the smc_power_state_t for information about - * the power stat. + * the power status. * * @param base SMC peripheral base address. * @return Current power mode status. @@ -305,7 +278,37 @@ static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base) } /*! - * @brief Configure the system to RUN power mode. + * @brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with @ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void); + +/*! + * @brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with @ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void); + +/*! + * @brief Configures the system to RUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -314,7 +317,7 @@ status_t SMC_SetPowerModeRun(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) /*! - * @brief Configure the system to HSRUN power mode. + * @brief Configures the system to HSRUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -323,7 +326,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ /*! - * @brief Configure the system to WAIT power mode. + * @brief Configures the system to WAIT power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -331,7 +334,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); status_t SMC_SetPowerModeWait(SMC_Type *base); /*! - * @brief Configure the system to Stop power mode. + * @brief Configures the system to Stop power mode. * * @param base SMC peripheral base address. * @param option Partial Stop mode option. @@ -341,7 +344,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode. @@ -350,7 +353,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode); #else /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -359,7 +362,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_LPWUI */ /*! - * @brief Configure the system to VLPW power mode. + * @brief Configures the system to VLPW power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -367,7 +370,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); status_t SMC_SetPowerModeVlpw(SMC_Type *base); /*! - * @brief Configure the system to VLPS power mode. + * @brief Configures the system to VLPS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -378,7 +381,7 @@ status_t SMC_SetPowerModeVlps(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)) /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @param config The LLS power mode configuration structure @@ -387,7 +390,7 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base); status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config); #else /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -398,7 +401,7 @@ status_t SMC_SetPowerModeLls(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief Configure the system to VLLS power mode. + * @brief Configures the system to VLLS power mode. * * @param base SMC peripheral base address. * @param config The VLLS power mode configuration structure. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/serial_api.c index c890abb224..7d916d2cc6 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW24D/serial_api.c @@ -327,4 +327,14 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi #endif +void serial_wait_tx_complete(uint32_t uart_index) +{ + UART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kUART_TransmissionCompleteFlag & UART_GetStatusFlags((UART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_smc.c index 45382fdffe..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_smc.c @@ -1,60 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -62,13 +170,19 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ @@ -80,22 +194,29 @@ status_t SMC_SetPowerModeWait(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -103,12 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -118,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -138,18 +263,24 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { /* configure VLPW mode */ @@ -162,14 +293,20 @@ status_t SMC_SetPowerModeVlpw(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -177,12 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -193,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -233,12 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -250,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -262,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -285,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -298,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -349,12 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_smc.h index 4148734a2a..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,15 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.2. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -53,29 +30,25 @@ typedef enum _smc_power_mode_protection { #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */ #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-Power Mode. */ + kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-power Mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High Speed Run mode. */ + kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode. */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -85,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -106,10 +79,10 @@ typedef enum _smc_power_state */ typedef enum _smc_run_mode { - kSMC_RunNormal = 0U, /*!< normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-Low-Power RUN mode. */ + kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_Hsrun = 3U /*!< High Speed Run mode (HSRUN). */ + kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ } smc_run_mode_t; @@ -119,12 +92,12 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-Low-Power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_StopLls = 3U, /*!< Low-Leakage Stop mode. */ + kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #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) - kSMC_StopVlls = 4U /*!< Very-Low-Leakage Stop mode. */ + kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */ #endif } smc_stop_mode_t; @@ -148,13 +121,13 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; /*! - * @brief SMC configuration status + * @brief SMC configuration status. */ enum _smc_status { @@ -189,7 +162,7 @@ typedef struct _smc_param #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) /*! - * @brief SMC Low-Leakage Stop power mode config + * @brief SMC Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_lls_config { @@ -204,7 +177,7 @@ typedef struct _smc_power_mode_lls_config #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief SMC Very Low-Leakage Stop power mode config + * @brief SMC Very Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_vlls_config { @@ -241,10 +214,10 @@ extern "C" { * @brief Gets the SMC version ID. * * This function gets the SMC version ID, including major version number, - * minor version number and feature specification number. + * minor version number, and feature specification number. * * @param base SMC peripheral base address. - * @param versionId Pointer to version ID structure. + * @param versionId Pointer to the version ID structure. */ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) { @@ -256,10 +229,10 @@ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) /*! * @brief Gets the SMC parameter. * - * This function gets the SMC parameter, including the enabled power mdoes. + * This function gets the SMC parameter including the enabled power mdoes. * * @param base SMC peripheral base address. - * @param param Pointer to SMC param structure. + * @param param Pointer to the SMC param structure. */ void SMC_GetParam(SMC_Type *base, smc_param_t *param); #endif @@ -273,7 +246,7 @@ void SMC_GetParam(SMC_Type *base, smc_param_t *param); * system level initialization stage. See the reference manual for details. * This register can only write once after the power reset. * - * The allowed modes are passed as bit map, for example, to allow LLS and VLLS, + * The allowed modes are passed as bit map. For example, to allow LLS and VLLS, * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps). * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll). * @@ -288,13 +261,13 @@ static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedMod /*! * @brief Gets the current power mode status. * - * This function returns the current power mode stat. Once application - * switches the power mode, it should always check the stat to check whether it - * runs into the specified mode or not. An application should check + * This function returns the current power mode status. After the application + * switches the power mode, it should always check the status to check whether it + * runs into the specified mode or not. The application should check * this mode before switching to a different mode. The system requires that * only certain modes can switch to other specific modes. See the * reference manual for details and the smc_power_state_t for information about - * the power stat. + * the power status. * * @param base SMC peripheral base address. * @return Current power mode status. @@ -305,7 +278,37 @@ static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base) } /*! - * @brief Configure the system to RUN power mode. + * @brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with @ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void); + +/*! + * @brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with @ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void); + +/*! + * @brief Configures the system to RUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -314,7 +317,7 @@ status_t SMC_SetPowerModeRun(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) /*! - * @brief Configure the system to HSRUN power mode. + * @brief Configures the system to HSRUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -323,7 +326,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ /*! - * @brief Configure the system to WAIT power mode. + * @brief Configures the system to WAIT power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -331,7 +334,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); status_t SMC_SetPowerModeWait(SMC_Type *base); /*! - * @brief Configure the system to Stop power mode. + * @brief Configures the system to Stop power mode. * * @param base SMC peripheral base address. * @param option Partial Stop mode option. @@ -341,7 +344,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode. @@ -350,7 +353,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode); #else /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -359,7 +362,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_LPWUI */ /*! - * @brief Configure the system to VLPW power mode. + * @brief Configures the system to VLPW power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -367,7 +370,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); status_t SMC_SetPowerModeVlpw(SMC_Type *base); /*! - * @brief Configure the system to VLPS power mode. + * @brief Configures the system to VLPS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -378,7 +381,7 @@ status_t SMC_SetPowerModeVlps(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)) /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @param config The LLS power mode configuration structure @@ -387,7 +390,7 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base); status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config); #else /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -398,7 +401,7 @@ status_t SMC_SetPowerModeLls(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief Configure the system to VLLS power mode. + * @brief Configures the system to VLLS power mode. * * @param base SMC peripheral base address. * @param config The VLLS power mode configuration structure. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/serial_api.c index 7d5131768e..99e9da8537 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/serial_api.c @@ -282,4 +282,14 @@ const PinMap *serial_rts_pinmap() return PinMap_UART_RTS; } +void serial_wait_tx_complete(uint32_t uart_index) +{ + LPUART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kLPUART_TransmissionCompleteFlag & LPUART_GetStatusFlags((LPUART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.c index 0018cf7dce..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.c @@ -1,60 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -62,38 +170,53 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); __WFI(); + __ISB(); return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -101,10 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -114,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -134,42 +263,50 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { - /* Power mode transaction to VLPW can only happen in VLPR mode */ - if (kSMC_PowerStateVlpr != SMC_GetPowerModeState(base)) - { - return kStatus_Fail; - } - /* configure VLPW mode */ /* Set the SLEEPDEEP bit to enable deep sleep mode */ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); __WFI(); + __ISB(); return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -177,10 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -191,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -231,10 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -246,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -258,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -281,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -294,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -345,10 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __WFI(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.h index 5149f87e34..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,16 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.1. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -54,29 +30,25 @@ typedef enum _smc_power_mode_protection { #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeVlls = SMC_PMPROT_AVLLS_MASK, /*!< Allow Very-low-leakage Stop Mode. */ #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-Leakage Stop Mode. */ + kSMC_AllowPowerModeLls = SMC_PMPROT_ALLS_MASK, /*!< Allow Low-leakage Stop Mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-Power Mode. */ + kSMC_AllowPowerModeVlp = SMC_PMPROT_AVLP_MASK, /*!< Allow Very-Low-power Mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High Speed Run mode. */ + kSMC_AllowPowerModeHsrun = SMC_PMPROT_AHSRUN_MASK, /*!< Allow High-speed Run mode. */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -86,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -107,10 +79,10 @@ typedef enum _smc_power_state */ typedef enum _smc_run_mode { - kSMC_RunNormal = 0U, /*!< normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-Low-Power RUN mode. */ + kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - kSMC_Hsrun = 3U /*!< High Speed Run mode (HSRUN). */ + kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ } smc_run_mode_t; @@ -120,12 +92,12 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-Low-Power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - kSMC_StopLls = 3U, /*!< Low-Leakage Stop mode. */ + kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #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) - kSMC_StopVlls = 4U /*!< Very-Low-Leakage Stop mode. */ + kSMC_StopVlls = 4U /*!< Very-low-leakage Stop mode. */ #endif } smc_stop_mode_t; @@ -149,13 +121,13 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; /*! - * @brief SMC configuration status + * @brief SMC configuration status. */ enum _smc_status { @@ -190,7 +162,7 @@ typedef struct _smc_param #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) /*! - * @brief SMC Low-Leakage Stop power mode config + * @brief SMC Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_lls_config { @@ -205,7 +177,7 @@ typedef struct _smc_power_mode_lls_config #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief SMC Very Low-Leakage Stop power mode config + * @brief SMC Very Low-Leakage Stop power mode configuration. */ typedef struct _smc_power_mode_vlls_config { @@ -242,10 +214,10 @@ extern "C" { * @brief Gets the SMC version ID. * * This function gets the SMC version ID, including major version number, - * minor version number and feature specification number. + * minor version number, and feature specification number. * * @param base SMC peripheral base address. - * @param versionId Pointer to version ID structure. + * @param versionId Pointer to the version ID structure. */ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) { @@ -257,10 +229,10 @@ static inline void SMC_GetVersionId(SMC_Type *base, smc_version_id_t *versionId) /*! * @brief Gets the SMC parameter. * - * This function gets the SMC parameter, including the enabled power mdoes. + * This function gets the SMC parameter including the enabled power mdoes. * * @param base SMC peripheral base address. - * @param param Pointer to SMC param structure. + * @param param Pointer to the SMC param structure. */ void SMC_GetParam(SMC_Type *base, smc_param_t *param); #endif @@ -274,7 +246,7 @@ void SMC_GetParam(SMC_Type *base, smc_param_t *param); * system level initialization stage. See the reference manual for details. * This register can only write once after the power reset. * - * The allowed modes are passed as bit map, for example, to allow LLS and VLLS, + * The allowed modes are passed as bit map. For example, to allow LLS and VLLS, * use SMC_SetPowerModeProtection(kSMC_AllowPowerModeVlls | kSMC_AllowPowerModeVlps). * To allow all modes, use SMC_SetPowerModeProtection(kSMC_AllowPowerModeAll). * @@ -289,13 +261,13 @@ static inline void SMC_SetPowerModeProtection(SMC_Type *base, uint8_t allowedMod /*! * @brief Gets the current power mode status. * - * This function returns the current power mode stat. Once application - * switches the power mode, it should always check the stat to check whether it - * runs into the specified mode or not. An application should check + * This function returns the current power mode status. After the application + * switches the power mode, it should always check the status to check whether it + * runs into the specified mode or not. The application should check * this mode before switching to a different mode. The system requires that * only certain modes can switch to other specific modes. See the * reference manual for details and the smc_power_state_t for information about - * the power stat. + * the power status. * * @param base SMC peripheral base address. * @return Current power mode status. @@ -306,7 +278,37 @@ static inline smc_power_state_t SMC_GetPowerModeState(SMC_Type *base) } /*! - * @brief Configure the system to RUN power mode. + * @brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ +void SMC_PreEnterStopModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with @ref SMC_PreEnterStopModes. + */ +void SMC_PostExitStopModes(void); + +/*! + * @brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void); + +/*! + * @brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with @ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void); + +/*! + * @brief Configures the system to RUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -315,7 +317,7 @@ status_t SMC_SetPowerModeRun(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) /*! - * @brief Configure the system to HSRUN power mode. + * @brief Configures the system to HSRUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -324,7 +326,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ /*! - * @brief Configure the system to WAIT power mode. + * @brief Configures the system to WAIT power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -332,7 +334,7 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base); status_t SMC_SetPowerModeWait(SMC_Type *base); /*! - * @brief Configure the system to Stop power mode. + * @brief Configures the system to Stop power mode. * * @param base SMC peripheral base address. * @param option Partial Stop mode option. @@ -342,7 +344,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); #if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @param wakeupMode Enter Normal Run mode if true, else stay in VLPR mode. @@ -351,7 +353,7 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option); status_t SMC_SetPowerModeVlpr(SMC_Type *base, bool wakeupMode); #else /*! - * @brief Configure the system to VLPR power mode. + * @brief Configures the system to VLPR power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -360,7 +362,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); #endif /* FSL_FEATURE_SMC_HAS_LPWUI */ /*! - * @brief Configure the system to VLPW power mode. + * @brief Configures the system to VLPW power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -368,7 +370,7 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base); status_t SMC_SetPowerModeVlpw(SMC_Type *base); /*! - * @brief Configure the system to VLPS power mode. + * @brief Configures the system to VLPS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -379,7 +381,7 @@ status_t SMC_SetPowerModeVlps(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)) /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @param config The LLS power mode configuration structure @@ -388,7 +390,7 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base); status_t SMC_SetPowerModeLls(SMC_Type *base, const smc_power_mode_lls_config_t *config); #else /*! - * @brief Configure the system to LLS power mode. + * @brief Configures the system to LLS power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -399,7 +401,7 @@ status_t SMC_SetPowerModeLls(SMC_Type *base); #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) /*! - * @brief Configure the system to VLLS power mode. + * @brief Configures the system to VLLS power mode. * * @param base SMC peripheral base address. * @param config The VLLS power mode configuration structure. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/serial_api.c index e38f48a41d..6f15814c92 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K22F/serial_api.c @@ -302,4 +302,14 @@ const PinMap *serial_rts_pinmap() return PinMap_UART_RTS; } +void serial_wait_tx_complete(uint32_t uart_index) +{ + UART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kUART_TransmissionCompleteFlag & UART_GetStatusFlags((UART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/drivers/fsl_smc.c index dacf193476..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/drivers/fsl_smc.c @@ -1,94 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * All rights reserved. * - * 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" -#include "fsl_flash.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ void SMC_PreEnterStopModes(void) { - flash_prefetch_speculation_status_t speculationStatus = - { - kFLASH_prefetchSpeculationOptionDisable, /* Disable instruction speculation.*/ - kFLASH_prefetchSpeculationOptionDisable, /* Disable data speculation.*/ - }; - - __disable_irq(); + g_savedPrimask = DisableGlobalIRQ(); __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); } +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ 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(); + EnableGlobalIRQ(g_savedPrimask); __ISB(); } +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -96,13 +170,19 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ @@ -114,22 +194,29 @@ status_t SMC_SetPowerModeWait(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -137,12 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -152,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -172,18 +263,24 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { /* configure VLPW mode */ @@ -196,14 +293,20 @@ status_t SMC_SetPowerModeVlpw(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -211,12 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -227,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -267,12 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -284,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -296,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -319,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -332,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -383,12 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/drivers/fsl_smc.h index 168ce83501..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP + * All rights reserved. * - * 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,15 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.3. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 3)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -64,18 +41,14 @@ typedef enum _smc_power_mode_protection #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -85,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -107,7 +80,7 @@ typedef enum _smc_power_state typedef enum _smc_run_mode { kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ @@ -119,7 +92,7 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ @@ -148,7 +121,7 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; @@ -324,11 +297,7 @@ void SMC_PostExitStopModes(void); * * This function should be called before entering WAIT/VLPW modes. */ -static inline void SMC_PreEnterWaitModes(void) -{ - __disable_irq(); - __ISB(); -} +void SMC_PreEnterWaitModes(void); /*! * @brief Recovers after wake up from stop modes. @@ -336,11 +305,7 @@ static inline void SMC_PreEnterWaitModes(void) * This function should be called after wake up from WAIT/VLPW modes. * It is used with @ref SMC_PreEnterWaitModes. */ -static inline void SMC_PostExitWaitModes(void) -{ - __enable_irq(); - __ISB(); -} +void SMC_PostExitWaitModes(void); /*! * @brief Configures the system to RUN power mode. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/serial_api.c index af826c10b1..eb85c220d5 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K24F/serial_api.c @@ -723,4 +723,14 @@ void serial_rx_abort_asynch(serial_t *obj) } } +void serial_wait_tx_complete(uint32_t uart_index) +{ + UART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kUART_TransmissionCompleteFlag & UART_GetStatusFlags((UART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_smc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_smc.c index 5c86e3366b..b3998d0370 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_smc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_smc.c @@ -1,94 +1,168 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_smc.h" -#include "fsl_flash.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.smc" +#endif + +typedef void (*smc_stop_ram_func_t)(void); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void); + +/******************************************************************************* + * Variables + ******************************************************************************/ +static uint32_t g_savedPrimask; + +/* + * The ram function code is: + * + * uint32_t i; + * for (i=0; i<0x8; i++) + * { + * __NOP(); + * } + * __DSB(); + * __WFI(); + * __ISB(); + * + * When entring the stop modes, the flash prefetch might be interrupted, thus + * the prefetched code or data might be broken. To make sure the flash is idle + * when entring the stop modes, the code is moved to ram. And delay for a while + * before WFI to make sure previous flash prefetch is finished. + * + * Only need to do like this when code is in flash, if code is in rom or ram, + * this is not necessary. + */ +static uint16_t s_stopRamFuncArray[] = { + 0x2000, /* MOVS R0, #0 */ + 0x2808, /* CMP R0, #8 */ + 0xD202, /* BCS.N */ + 0xBF00, /* NOP */ + 0x1C40, /* ADDS R0, R0, #1 */ + 0xE7FA, /* B.N */ + 0xF3BF, 0x8F4F, /* DSB */ + 0xBF30, /* WFI */ + 0xF3BF, 0x8F6F, /* ISB */ + 0x4770, /* BX LR */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ +static void SMC_EnterStopRamFunc(void) +{ + uint32_t ramFuncEntry = ((uint32_t)(s_stopRamFuncArray)) + 1U; + smc_stop_ram_func_t stopRamFunc = (smc_stop_ram_func_t)ramFuncEntry; + stopRamFunc(); +} #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) +/*! + * brief Gets the SMC parameter. + * + * This function gets the SMC parameter including the enabled power mdoes. + * + * param base SMC peripheral base address. + * param param Pointer to the SMC param structure. + */ void SMC_GetParam(SMC_Type *base, smc_param_t *param) { - uint32_t reg = base->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->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 */ +/*! + * brief Prepares to enter stop modes. + * + * This function should be called before entering STOP/VLPS/LLS/VLLS modes. + */ void SMC_PreEnterStopModes(void) { - flash_prefetch_speculation_status_t speculationStatus = - { - kFLASH_prefetchSpeculationOptionDisable, /* Disable instruction speculation.*/ - kFLASH_prefetchSpeculationOptionDisable, /* Disable data speculation.*/ - }; - - __disable_irq(); + g_savedPrimask = DisableGlobalIRQ(); __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); } +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from STOP/VLPS/LLS/VLLS modes. + * It is used with ref SMC_PreEnterStopModes. + */ 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(); + EnableGlobalIRQ(g_savedPrimask); __ISB(); } +/*! + * brief Prepares to enter wait modes. + * + * This function should be called before entering WAIT/VLPW modes. + */ +void SMC_PreEnterWaitModes(void) +{ + g_savedPrimask = DisableGlobalIRQ(); + __ISB(); +} + +/*! + * brief Recovers after wake up from stop modes. + * + * This function should be called after wake up from WAIT/VLPW modes. + * It is used with ref SMC_PreEnterWaitModes. + */ +void SMC_PostExitWaitModes(void) +{ + EnableGlobalIRQ(g_savedPrimask); + __ISB(); +} + +/*! + * brief Configures the system to RUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)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) +/*! + * brief Configures the system to HSRUN power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeHsrun(SMC_Type *base) { uint8_t reg; @@ -96,13 +170,19 @@ status_t SMC_SetPowerModeHsrun(SMC_Type *base) reg = base->PMCTRL; /* configure High Speed RUN mode */ reg &= ~SMC_PMCTRL_RUNM_MASK; - reg |= (kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); + reg |= ((uint8_t)kSMC_Hsrun << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ +/*! + * brief Configures the system to WAIT power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ @@ -114,22 +194,29 @@ status_t SMC_SetPowerModeWait(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to Stop power mode. + * + * param base SMC peripheral base address. + * param option Partial Stop mode option. + * return SMC configuration error code. + */ 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 */ + /* configure the Partial Stop mode in Normal Stop mode */ reg = base->STOPCTRL; - reg &= ~SMC_STOPCTRL_PSTOPO_MASK; - reg |= ((uint32_t)option << SMC_STOPCTRL_PSTOPO_SHIFT); + reg &= ~(uint8_t)SMC_STOPCTRL_PSTOPO_MASK; + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopNormal << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode (stop mode) */ @@ -137,12 +224,10 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter Stop mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -152,12 +237,18 @@ status_t SMC_SetPowerModeStop(SMC_Type *base, smc_partial_stop_option_t option) } } +/*! + * brief Configures the system to VLPR power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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; @@ -172,18 +263,24 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base else { /* remains in VLP mode on an interrupt */ - reg &= ~SMC_PMCTRL_LPWUI_MASK; + reg &= ~(uint8_t)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); + reg &= ~(uint8_t)SMC_PMCTRL_RUNM_MASK; + reg |= ((uint8_t)kSMC_RunVlpr << SMC_PMCTRL_RUNM_SHIFT); base->PMCTRL = reg; return kStatus_Success; } +/*! + * brief Configures the system to VLPW power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlpw(SMC_Type *base) { /* configure VLPW mode */ @@ -196,14 +293,20 @@ status_t SMC_SetPowerModeVlpw(SMC_Type *base) return kStatus_Success; } +/*! + * brief Configures the system to VLPS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)kSMC_StopVlps << SMC_PMCTRL_STOPM_SHIFT); base->PMCTRL = reg; /* Set the SLEEPDEEP bit to enable deep sleep mode */ @@ -211,12 +314,10 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter VLPS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -227,27 +328,33 @@ status_t SMC_SetPowerModeVlps(SMC_Type *base) } #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) +/*! + * brief Configures the system to LLS power mode. + * + * param base SMC peripheral base address. + * return SMC configuration error code. + */ 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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_LLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ @@ -267,12 +374,10 @@ status_t SMC_SetPowerModeLls(SMC_Type *base /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } @@ -284,6 +389,13 @@ status_t SMC_SetPowerModeLls(SMC_Type *base #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) +/*! + * brief Configures the system to VLLS power mode. + * + * param base SMC peripheral base address. + * param config The VLLS power mode configuration structure. + * return SMC configuration error code. + */ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t *config) { uint8_t reg; @@ -296,12 +408,12 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #endif { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enablePorDetectInVlls0) + if (true == 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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_PORPO_MASK; #endif } else @@ -319,7 +431,7 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t else if (config->subMode == kSMC_StopSub2) { /* configure whether the Por Detect work in Vlls0 mode */ - if (config->enableRam2InVlls2) + if (true == config->enableRam2InVlls2) { #if (defined(FSL_FEATURE_SMC_USE_VLLSCTRL_REG) && FSL_FEATURE_SMC_USE_VLLSCTRL_REG) base->VLLSCTRL |= SMC_VLLSCTRL_RAM2PO_MASK; @@ -332,37 +444,38 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t #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; + base->STOPCTRL &= ~(uint8_t)SMC_STOPCTRL_RAM2PO_MASK; #endif } } else { + /* Add this to fix MISRA C2012 rule15.7 issue: Empty else without comment. */ } #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); + reg &= ~(uint8_t)SMC_PMCTRL_STOPM_MASK; + reg |= ((uint8_t)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); + reg |= ((uint8_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); + reg &= ~(uint8_t)SMC_STOPCTRL_LLSM_MASK; + reg |= ((uint8_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); + reg |= ((uint8_t)config->subMode << SMC_STOPCTRL_VLLSM_SHIFT); base->STOPCTRL = reg; #endif /* FSL_FEATURE_SMC_HAS_LLS_SUBMODE */ #endif @@ -383,12 +496,10 @@ status_t SMC_SetPowerModeVlls(SMC_Type *base, const smc_power_mode_vlls_config_t /* read back to make sure the configuration valid before enter stop mode */ (void)base->PMCTRL; - __DSB(); - __WFI(); - __ISB(); + SMC_EnterStopRamFunc(); /* check whether the power mode enter LLS mode succeed */ - if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) + if (0U != (base->PMCTRL & SMC_PMCTRL_STOPA_MASK)) { return kStatus_SMC_StopAbort; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_smc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_smc.h index b901468e70..e5c318e1a1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_smc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/drivers/fsl_smc.h @@ -1,31 +1,9 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * All rights reserved. * - * 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 Freescale Semiconductor, Inc. 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. + * SPDX-License-Identifier: BSD-3-Clause */ #ifndef _FSL_SMC_H_ @@ -36,15 +14,14 @@ /*! @addtogroup smc */ /*! @{ */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief SMC driver version 2.0.3. */ -#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 3)) +/*! @brief SMC driver version 2.0.5. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 5)) /*@}*/ /*! @@ -64,18 +41,14 @@ typedef enum _smc_power_mode_protection #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ kSMC_AllowPowerModeAll = (0U #if (defined(FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_VERY_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_AVLLS_MASK + | SMC_PMPROT_AVLLS_MASK #endif #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) - | - SMC_PMPROT_ALLS_MASK + | SMC_PMPROT_ALLS_MASK #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ - | - SMC_PMPROT_AVLP_MASK + | SMC_PMPROT_AVLP_MASK #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) - | - kSMC_AllowPowerModeHsrun + | kSMC_AllowPowerModeHsrun #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ ) /*!< Allow all power mode. */ } smc_power_mode_protection_t; @@ -85,7 +58,7 @@ typedef enum _smc_power_mode_protection */ typedef enum _smc_power_state { - kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ + kSMC_PowerStateRun = 0x01U << 0U, /*!< 0000_0001 - Current power mode is RUN */ kSMC_PowerStateStop = 0x01U << 1U, /*!< 0000_0010 - Current power mode is STOP */ kSMC_PowerStateVlpr = 0x01U << 2U, /*!< 0000_0100 - Current power mode is VLPR */ kSMC_PowerStateVlpw = 0x01U << 3U, /*!< 0000_1000 - Current power mode is VLPW */ @@ -107,7 +80,7 @@ typedef enum _smc_power_state typedef enum _smc_run_mode { kSMC_RunNormal = 0U, /*!< Normal RUN mode. */ - kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ + kSMC_RunVlpr = 2U, /*!< Very-low-power RUN mode. */ #if (defined(FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) && FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE) kSMC_Hsrun = 3U /*!< High-speed Run mode (HSRUN). */ #endif /* FSL_FEATURE_SMC_HAS_HIGH_SPEED_RUN_MODE */ @@ -119,7 +92,7 @@ typedef enum _smc_run_mode typedef enum _smc_stop_mode { kSMC_StopNormal = 0U, /*!< Normal STOP mode. */ - kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ + kSMC_StopVlps = 2U, /*!< Very-low-power STOP mode. */ #if (defined(FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) && FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE) kSMC_StopLls = 3U, /*!< Low-leakage Stop mode. */ #endif /* FSL_FEATURE_SMC_HAS_LOW_LEAKAGE_STOP_MODE */ @@ -148,7 +121,7 @@ typedef enum _smc_stop_submode */ typedef enum _smc_partial_stop_mode { - kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ + kSMC_PartialStop = 0U, /*!< STOP - Normal Stop mode*/ kSMC_PartialStop1 = 1U, /*!< Partial Stop with both system and bus clocks disabled*/ kSMC_PartialStop2 = 2U, /*!< Partial Stop with system clock disabled and bus clock enabled*/ } smc_partial_stop_option_t; @@ -324,11 +297,7 @@ void SMC_PostExitStopModes(void); * * This function should be called before entering WAIT/VLPW modes. */ -static inline void SMC_PreEnterWaitModes(void) -{ - __disable_irq(); - __ISB(); -} +void SMC_PreEnterWaitModes(void); /*! * @brief Recovers after wake up from stop modes. @@ -336,11 +305,7 @@ static inline void SMC_PreEnterWaitModes(void) * This function should be called after wake up from WAIT/VLPW modes. * It is used with @ref SMC_PreEnterWaitModes. */ -static inline void SMC_PostExitWaitModes(void) -{ - __enable_irq(); - __ISB(); -} +void SMC_PostExitWaitModes(void); /*! * @brief Configures the system to RUN power mode. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/serial_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/serial_api.c index bdfb73b2ac..2e2552f551 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/serial_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/serial_api.c @@ -24,6 +24,7 @@ #include #include "cmsis.h" +#include "mbed_power_mgmt.h" #include "pinmap.h" #include "fsl_uart.h" #include "peripheral_clock_defines.h" @@ -543,6 +544,9 @@ int serial_tx_asynch(serial_t *obj, const void *tx, size_t tx_length, uint8_t tx /* Start the transfer */ serial_send_asynch(obj); + /* Can't enter deep sleep as long as UART transmit is active */ + sleep_manager_lock_deep_sleep(); + return 0; } @@ -608,6 +612,9 @@ void serial_rx_asynch(serial_t *obj, void *rx, size_t rx_length, uint8_t rx_widt /* Start the transfer */ serial_receive_asynch(obj); + + /* Can't enter deep sleep as long as UART transfer is active */ + sleep_manager_lock_deep_sleep(); } uint8_t serial_tx_active(serial_t *obj) @@ -640,11 +647,15 @@ int serial_irq_handler_asynch(serial_t *obj) if ((obj->serial.txstate != kUART_TxIdle) && (obj->serial.uart_dma_handle.txState == kUART_TxIdle)) { obj->serial.txstate = kUART_TxIdle; status |= SERIAL_EVENT_TX_COMPLETE; + /* Transmit is complete, re-enable entry to deep sleep mode */ + sleep_manager_unlock_deep_sleep(); } if ((obj->serial.rxstate != kUART_RxIdle) && (obj->serial.uart_dma_handle.rxState == kUART_RxIdle)) { obj->serial.rxstate = kUART_RxIdle; status |= SERIAL_EVENT_RX_COMPLETE; + /* Receive is complete, re-enable entry to deep sleep mode */ + sleep_manager_unlock_deep_sleep(); } /* Release the dma channels if they were opportunistically allocated */ @@ -661,11 +672,15 @@ int serial_irq_handler_asynch(serial_t *obj) if ((obj->serial.txstate != kUART_TxIdle) && (obj->serial.uart_transfer_handle.txState == kUART_TxIdle)) { obj->serial.txstate = kUART_TxIdle; status |= SERIAL_EVENT_TX_COMPLETE; + /* Transmit is complete, re-enable entry to deep sleep mode */ + sleep_manager_unlock_deep_sleep(); } if ((obj->serial.rxstate != kUART_RxIdle) && (obj->serial.uart_transfer_handle.rxState == kUART_RxIdle)) { obj->serial.rxstate = kUART_RxIdle; status |= SERIAL_EVENT_RX_COMPLETE; + /* Receive is complete, re-enable entry to deep sleep mode */ + sleep_manager_unlock_deep_sleep(); } } #if 0 @@ -697,6 +712,11 @@ int serial_irq_handler_asynch(serial_t *obj) void serial_tx_abort_asynch(serial_t *obj) { + // If we're not currently transferring, then there's nothing to do here + if (serial_tx_active(obj) == 0) { + return; + } + if (obj->serial.uartDmaRx.dmaUsageState == DMA_USAGE_ALLOCATED || obj->serial.uartDmaRx.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) { UART_TransferAbortSendEDMA(uart_addrs[obj->serial.index], &obj->serial.uart_dma_handle); /* Release the dma channels if they were opportunistically allocated */ @@ -711,10 +731,20 @@ void serial_tx_abort_asynch(serial_t *obj) } else { UART_TransferAbortSend(uart_addrs[obj->serial.index], &obj->serial.uart_transfer_handle); } + + obj->serial.txstate = kUART_TxIdle; + + /* Re-enable entry to deep sleep mode */ + sleep_manager_unlock_deep_sleep(); } void serial_rx_abort_asynch(serial_t *obj) { + // If we're not currently transferring, then there's nothing to do here + if (serial_rx_active(obj) == 0) { + return; + } + if (obj->serial.uartDmaRx.dmaUsageState == DMA_USAGE_ALLOCATED || obj->serial.uartDmaRx.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) { UART_TransferAbortReceiveEDMA(uart_addrs[obj->serial.index], &obj->serial.uart_dma_handle); /* Release the dma channels if they were opportunistically allocated */ @@ -729,6 +759,21 @@ void serial_rx_abort_asynch(serial_t *obj) } else { UART_TransferAbortReceive(uart_addrs[obj->serial.index], &obj->serial.uart_transfer_handle); } + + obj->serial.rxstate = kUART_RxIdle; + + /* Re-enable entry to deep sleep mode */ + sleep_manager_unlock_deep_sleep(); +} + +void serial_wait_tx_complete(uint32_t uart_index) +{ + UART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kUART_TransmissionCompleteFlag & UART_GetStatusFlags((UART_Type *)base))) + { + } } #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/spi_api.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/spi_api.c index 26a8396a6f..01c2965bac 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/spi_api.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/spi_api.c @@ -23,6 +23,7 @@ #include "cmsis.h" #include "pinmap.h" #include "mbed_error.h" +#include "mbed_power_mgmt.h" #include "fsl_dspi.h" #include "peripheral_clock_defines.h" #include "dma_reqs.h" @@ -369,6 +370,9 @@ void spi_master_transfer(spi_t *obj, const void *tx, size_t tx_length, void *rx, /* Start the transfer */ if (spi_master_transfer_asynch(obj) != kStatus_Success) { obj->spi.status = kDSPI_Idle; + } else { + // Can't enter deep sleep as long as SPI transfer is active + sleep_manager_lock_deep_sleep(); } } @@ -428,12 +432,18 @@ uint32_t spi_irq_handler_asynch(spi_t *obj) } obj->spi.status = kDSPI_Idle; + // SPI transfer done, can enter deep sleep + sleep_manager_unlock_deep_sleep(); + return SPI_EVENT_COMPLETE; } } else { /* Interrupt implementation */ obj->spi.status = kDSPI_Idle; + // SPI transfer done, can enter deep sleep + sleep_manager_unlock_deep_sleep(); + return SPI_EVENT_COMPLETE; } } @@ -462,6 +472,9 @@ void spi_abort_asynch(spi_t *obj) } obj->spi.status = kDSPI_Idle; + + // SPI transfer done, can enter deep sleep + sleep_manager_unlock_deep_sleep(); } uint8_t spi_active(spi_t *obj) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/sleep.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/sleep.c index c9d9ae05b3..1cada1a601 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/sleep.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/api/sleep.c @@ -17,6 +17,11 @@ #include "cmsis.h" #include "fsl_smc.h" #include "fsl_clock_config.h" +#include "pinmap.h" +#include "fsl_port.h" +#include "PeripheralPins.h" + +extern void serial_wait_tx_complete(uint32_t uart_index); void hal_sleep(void) { @@ -25,50 +30,35 @@ void hal_sleep(void) SMC_SetPowerModeWait(SMC); } -static void PreEnterStopModes(void) -{ - flash_prefetch_speculation_status_t speculationStatus = - { - kFLASH_prefetchSpeculationOptionDisable, /* Disable instruction speculation.*/ - kFLASH_prefetchSpeculationOptionDisable, /* Disable data speculation.*/ - }; - - __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); -} - -static void PostExitStopModes(void) -{ - flash_prefetch_speculation_status_t speculationStatus = - { - kFLASH_prefetchSpeculationOptionEnable, /* Enable instruction speculation.*/ - kFLASH_prefetchSpeculationOptionEnable, /* Enable data speculation.*/ - }; - - FLASH_PflashSetPrefetchSpeculation(&speculationStatus); - - __ISB(); -} - void hal_deepsleep(void) { + uint32_t pin_func; #if (defined(FSL_FEATURE_SOC_MCG_COUNT) && FSL_FEATURE_SOC_MCG_COUNT) #if (defined(FSL_FEATURE_MCG_HAS_PLL) && FSL_FEATURE_MCG_HAS_PLL) - mcg_mode_t mode = CLOCK_GetMode(); + smc_power_state_t original_power_state; + + original_power_state = SMC_GetPowerModeState(SMC); #endif // FSL_FEATURE_MCG_HAS_PLL #endif // FSL_FEATURE_SOC_MCG_COUNT SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); - PreEnterStopModes(); + /* Wait till debug UART is done transmitting */ + serial_wait_tx_complete(STDIO_UART); + + /* + * Set pin for current leakage. + * Debug console RX pin: Set to pinmux to disable. + * Debug console TX pin: Don't need to change. + */ + pin_function(STDIO_UART_RX, (int)kPORT_PinDisabledOrAnalog); + + SMC_PreEnterStopModes(); SMC_SetPowerModeVlps(SMC); - PostExitStopModes(); + SMC_PostExitStopModes(); + + pin_func = pinmap_find_function(STDIO_UART_RX, PinMap_UART_RX); + pin_function(STDIO_UART_RX, pin_func); #if (defined(FSL_FEATURE_SOC_MCG_COUNT) && FSL_FEATURE_SOC_MCG_COUNT) #if (defined(FSL_FEATURE_MCG_HAS_PLL) && FSL_FEATURE_MCG_HAS_PLL) @@ -76,8 +66,12 @@ void hal_deepsleep(void) * If enter stop modes when MCG in PEE mode, then after wakeup, the MCG is in PBE mode, * need to enter PEE mode manually. */ - if (mode == kMCG_ModePEE) { - BOARD_BootClockRUN(); + if (original_power_state == kSMC_PowerStateRun) { + /* Wait for PLL lock. */ + while (!(kMCG_Pll0LockFlag & CLOCK_GetStatusFlags())) + { + } + CLOCK_SetPeeMode(); } #endif // FSL_FEATURE_MCG_HAS_PLL #endif // FSL_FEATURE_SOC_MCG_COUNT diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/serial_api.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/serial_api.c index c7f40cffaf..b68cccbe25 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/serial_api.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/serial_api.c @@ -316,4 +316,14 @@ const PinMap *serial_rts_pinmap() return PinMap_UART_RTS; } +void serial_wait_tx_complete(uint32_t uart_index) +{ + LPUART_Type *base = uart_addrs[uart_index]; + + /* Wait till data is flushed out of transmit buffer */ + while (!(kLPUART_TransmissionCompleteFlag & LPUART_GetStatusFlags((LPUART_Type *)base))) + { + } +} + #endif diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/sleep.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/sleep.c index 59f01d78a4..bf4d011b87 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/sleep.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/sleep.c @@ -19,6 +19,7 @@ extern void vPortPRE_SLEEP_PROCESSING(clock_mode_t powermode); extern void vPortPOST_SLEEP_PROCESSING(clock_mode_t powermode); +extern void serial_wait_tx_complete(uint32_t uart_index); void hal_sleep(void) @@ -36,6 +37,9 @@ void hal_deepsleep(void) { vPortPRE_SLEEP_PROCESSING(kCLOCK_ModeStop); + /* Wait till debug UART is done transmitting */ + serial_wait_tx_complete(STDIO_UART); + __DSB(); __WFI(); __ISB(); diff --git a/targets/targets.json b/targets/targets.json index 45df01d9fe..3a5c9df6da 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -1220,7 +1220,7 @@ ], "is_disk_virtual": true, "public": false, - "macros": ["CPU_MK22FN512VLH12", "FSL_RTOS_MBED"], + "macros": ["CPU_MK22FN512VLH12", "FSL_RTOS_MBED", "MBED_TICKLESS"], "inherits": ["Target"], "detect_code": ["0231"], "device_has": [ @@ -1321,7 +1321,7 @@ "core": "Cortex-M0+", "supported_toolchains": ["GCC_ARM", "ARM", "IAR"], "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "FRDM"], - "macros": ["CPU_MKL82Z128VLK7", "FSL_RTOS_MBED"], + "macros": ["CPU_MKL82Z128VLK7", "FSL_RTOS_MBED", "MBED_TICKLESS"], "is_disk_virtual": true, "inherits": ["Target"], "detect_code": ["0218"], @@ -1363,7 +1363,7 @@ "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "FRDM"], "is_disk_virtual": true, - "macros": ["CPU_MKW24D512VHA5", "FSL_RTOS_MBED"], + "macros": ["CPU_MKW24D512VHA5", "FSL_RTOS_MBED", "MBED_TICKLESS"], "inherits": ["Target"], "detect_code": ["0250"], "device_has": [ @@ -1401,7 +1401,7 @@ "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "FRDM", "FRAMEWORK_5_3_3", "NXP"], "is_disk_virtual": true, - "macros": ["CPU_MKW41Z512VHT4", "FSL_RTOS_MBED"], + "macros": ["CPU_MKW41Z512VHT4", "FSL_RTOS_MBED", "MBED_TICKLESS"], "inherits": ["Target"], "detect_code": ["0201"], "device_has": [ @@ -1497,7 +1497,8 @@ "PSA" ], "is_disk_virtual": true, - "macros": ["CPU_MK64FN1M0VMD12", "FSL_RTOS_MBED", "MBED_SPLIT_HEAP"], + + "macros": ["CPU_MK64FN1M0VMD12", "FSL_RTOS_MBED", "MBED_SPLIT_HEAP", "MBED_TICKLESS"], "inherits": ["Target"], "detect_code": ["0240"], "device_has": [ @@ -1652,7 +1653,7 @@ "MCU_K64F" ], "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], - "macros": ["CPU_MK64FN1M0VMD12", "FSL_RTOS_MBED", "TARGET_K64F"], + "macros": ["CPU_MK64FN1M0VMD12", "FSL_RTOS_MBED", "TARGET_K64F", "MBED_TICKLESS"], "is_disk_virtual": true, "default_toolchain": "ARM", "detect_code": ["0214"], @@ -1789,7 +1790,7 @@ "PSA" ], "is_disk_virtual": true, - "macros": ["CPU_MK66FN2M0VMD18", "FSL_RTOS_MBED", "MBED_SPLIT_HEAP"], + "macros": ["CPU_MK66FN2M0VMD18", "FSL_RTOS_MBED", "MBED_SPLIT_HEAP", "MBED_TICKLESS"], "inherits": ["Target"], "detect_code": ["0311"], "device_has": [ @@ -1829,7 +1830,7 @@ "supported_toolchains": ["ARM", "GCC_ARM", "IAR"], "extra_labels": ["Freescale", "MCUXpresso_MCUS", "KSDK2_MCUS", "FRDM"], "is_disk_virtual": true, - "macros": ["CPU_MK82FN256VDC15", "FSL_RTOS_MBED"], + "macros": ["CPU_MK82FN256VDC15", "FSL_RTOS_MBED", "MBED_TICKLESS"], "inherits": ["Target"], "detect_code": ["0217"], "device_has": [ @@ -1941,7 +1942,8 @@ "XIP_BOOT_HEADER_DCD_ENABLE=1", "SKIP_SYSCLK_INIT", "FSL_FEATURE_PHYKSZ8081_USE_RMII50M_MODE", - "MBED_MPU_CUSTOM" + "MBED_MPU_CUSTOM", + "MBED_TICKLESS" ], "inherits": ["Target"], "detect_code": ["0227"],