From 60f615024d1fe3912dddf1aef457423e7737912d Mon Sep 17 00:00:00 2001 From: Mahesh Mahadevan Date: Thu, 24 Oct 2019 12:51:02 -0500 Subject: [PATCH] MIMXRT1050: Update the low power driver to SDK 2.6 Signed-off-by: Mahesh Mahadevan --- .../TARGET_MIMXRT1050/TARGET_EVK/lpm.c | 1011 +++++++---------- .../TARGET_MIMXRT1050/TARGET_EVK/lpm.h | 188 ++- .../TARGET_MIMXRT1050/TARGET_EVK/specific.c | 609 ++++++++++ .../TARGET_MIMXRT1050/TARGET_EVK/specific.h | 49 + 4 files changed, 1153 insertions(+), 704 deletions(-) create mode 100644 targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/specific.c create mode 100644 targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/specific.h diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.c index 35d2d4ede9..74e2bcc859 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.c @@ -1,626 +1,467 @@ /* - * The Clear BSD License * Copyright 2017 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted (subject to the limitations in the disclaimer below) 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. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * 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 "lpm.h" #include "fsl_gpc.h" #include "fsl_dcdc.h" #include "fsl_gpt.h" -#include "fsl_lpuart.h" -#include "fsl_iomuxc.h" #include "fsl_clock_config.h" -#include "serial_api.h" #include "mbed_critical.h" #include "cmsis.h" +#include "specific.h" /******************************************************************************* * Definitions ******************************************************************************/ #define LPM_GPC_IMR_NUM (sizeof(GPC->IMR) / sizeof(GPC->IMR[0])) -typedef struct _lpm_clock_context -{ - uint32_t armDiv; - uint32_t ahbDiv; - uint32_t ipgDiv; - uint32_t perDiv; - uint32_t perSel; - uint32_t periphSel; - uint32_t preperiphSel; - uint32_t pfd480; - uint32_t pfd528; - uint32_t pllArm_loopdiv; - uint32_t pllArm; - uint32_t pllSys; - uint32_t pllUsb1; - uint32_t pllUsb2; - uint32_t pllAudio; - uint32_t pllVideo; - uint32_t pllEnet; - uint32_t is_valid; -} lpm_clock_context_t; - /******************************************************************************* * Variables ******************************************************************************/ -static lpm_clock_context_t s_clockContext; -static uint32_t s_DllBackupValue = 0; +uint32_t g_savedPrimask; +GPT_Type *vPortGetGptBase(void); +IRQn_Type vPortGetGptIrqn(void); /******************************************************************************* * Code ******************************************************************************/ - -void BOARD_SetLPClockGate(void) +void EnableRegularLDO(void) { - CCM->CCGR0 = 0x0F4000C5U; - CCM->CCGR1 = 0x541C0000U; - CCM->CCGR2 = 0x00150010U; - CCM->CCGR3 = 0x50040130U; - CCM->CCGR4 = 0x00005514U; - CCM->CCGR5 = 0x51001105U; - CCM->CCGR6 = 0x005405C0U; + /* Enable Regular LDO 2P5 and 1P1 */ + PMU->REG_2P5_SET = PMU_REG_2P5_ENABLE_LINREG_MASK; + PMU->REG_1P1_SET = PMU_REG_1P1_ENABLE_LINREG_MASK; } -void BOARD_ResetLPClockGate(void) +void DisableRegularLDO(void) { - CCM->CCGR0 = 0xFFFFFFFFU; - CCM->CCGR1 = 0xFFFFFFFFU; - CCM->CCGR2 = 0xFFFFFFFFU; - CCM->CCGR3 = 0xFFFFFFFFU; - CCM->CCGR4 = 0xFFFFFFFFU; - CCM->CCGR5 = 0xFFFFFFFFU; - CCM->CCGR6 = 0xFFFFFFFFU; + /* Disable Regular LDO 2P5 and 1P1 */ + PMU->REG_2P5_CLR = PMU_REG_2P5_ENABLE_LINREG_MASK; + PMU->REG_1P1_CLR = PMU_REG_1P1_ENABLE_LINREG_MASK; } -void LPM_SwitchToRcOSC(void) +void EnableWeakLDO(void) { - /* Switch to RC-OSC */ - XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK; - /* Turn off XTAL-OSC */ - CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power down */ + /* Enable Weak LDO 2P5 and 1P1 */ + PMU->REG_2P5_SET = PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; + PMU->REG_1P1_SET = PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; - /* Wait CCM operation finishes */ - CLOCK_CCM_HANDSHAKE_WAIT(); - /* Take some delay */ - LPM_DELAY(40); + SDK_DelayAtLeastUs(40); } -void LPM_SwitchToXtalOSC(void) +void DisableWeakLDO(void) { - /* Restore XTAL-OSC and enable detector */ - CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power up */ - while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0) - { - } - CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; /* detect freq */ - while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0) - { - } - CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; - - /* Switch to XTAL-OSC */ - XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_CLR_OSC_SEL_MASK; - /* Turn off XTAL-OSC detector */ - CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; - - /* Wait CCM operation finishes */ - CLOCK_CCM_HANDSHAKE_WAIT(); - /* Take some delay */ - LPM_DELAY(40); + /* Disable Weak LDO 2P5 and 1P1 */ + PMU->REG_2P5_CLR = PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; + PMU->REG_1P1_CLR = PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; } -void LPM_SwitchBandgap(void) +void BandgapOn(void) { - /* Switch bandgap */ - PMU->MISC0_SET = 0x00000004; - XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK; - PMU->MISC0_SET = CCM_ANALOG_MISC0_REFTOP_PWD_MASK; - - /* Wait CCM operation finishes */ - CLOCK_CCM_HANDSHAKE_WAIT(); - /* Take some delay */ - LPM_DELAY(40); -} - -void LPM_RestoreBandgap(void) -{ - /* Restore bandgap */ /* Turn on regular bandgap and wait for stable */ - PMU->MISC0_CLR = CCM_ANALOG_MISC0_REFTOP_PWD_MASK; + PMU->MISC0_CLR = PMU_MISC0_REFTOP_PWD_MASK; while ((PMU->MISC0 & PMU_MISC0_REFTOP_VBGUP_MASK) == 0) { } /* Low power band gap disable */ XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK; - PMU->MISC0_CLR = 0x00000004; +} +void BandgapOff(void) +{ + XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_LPBG_SEL_MASK; + PMU->MISC0_SET = PMU_MISC0_REFTOP_PWD_MASK; +} + +/*! + * @brief Set CCM MUX node to certain value. + * + * @param mux Which mux node to set, see \ref clock_mux_t. + * @param value Clock mux value to set, different mux has different value range. + */ +void CLOCK_SET_MUX(clock_mux_t mux, uint32_t value) +{ + uint32_t busyShift; + + busyShift = CCM_TUPLE_BUSY_SHIFT(mux); + CCM_TUPLE_REG(CCM, mux) = (CCM_TUPLE_REG(CCM, mux) & (~CCM_TUPLE_MASK(mux))) | + (((uint32_t)((value) << CCM_TUPLE_SHIFT(mux))) & CCM_TUPLE_MASK(mux)); + + //assert(busyShift <= CCM_NO_BUSY_WAIT); + + /* Clock switch need Handshake? */ + if (CCM_NO_BUSY_WAIT != busyShift) + { + /* Wait until CCM internal handshake finish. */ + while (CCM->CDHIPR & (1U << busyShift)) + { + } + } +} + +/*! + * @brief Set CCM DIV node to certain value. + * + * @param divider Which div node to set, see \ref clock_div_t. + * @param value Clock div value to set, different divider has different value range. + */ +void CLOCK_SET_DIV(clock_div_t divider, uint32_t value) +{ + uint32_t busyShift; + + busyShift = CCM_TUPLE_BUSY_SHIFT(divider); + CCM_TUPLE_REG(CCM, divider) = (CCM_TUPLE_REG(CCM, divider) & (~CCM_TUPLE_MASK(divider))) | + (((uint32_t)((value) << CCM_TUPLE_SHIFT(divider))) & CCM_TUPLE_MASK(divider)); + + //assert(busyShift <= CCM_NO_BUSY_WAIT); + + /* Clock switch need Handshake? */ + if (CCM_NO_BUSY_WAIT != busyShift) + { + /* Wait until CCM internal handshake finish. */ + while (CCM->CDHIPR & (1U << busyShift)) + { + } + } +} + +void ClockSelectXtalOsc(void) +{ + /* Enable XTAL 24MHz clock source. */ + CLOCK_InitExternalClk(0); /* Wait CCM operation finishes */ CLOCK_CCM_HANDSHAKE_WAIT(); /* Take some delay */ - LPM_DELAY(40); + SDK_DelayAtLeastUs(40); + /* Switch clock source to external OSC. */ + CLOCK_SwitchOsc(kCLOCK_XtalOsc); + /* Turn off XTAL-OSC detector */ + CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; + /* Power Down internal RC. */ + CLOCK_DeinitRcOsc24M(); } -void LPM_EnableWakeupSource(uint32_t irq) +void ClockSelectRcOsc(void) { - GPC_EnableIRQ(GPC, irq); -} - -void LPM_DisableWakeupSource(uint32_t irq) -{ - GPC_DisableIRQ(GPC, irq); -} - -/* - * ERR007265: CCM: When improper low-power sequence is used, - * the SoC enters low power mode before the ARM core executes WFI. - * - * Software workaround: - * 1) Software should trigger IRQ #41 (GPR_IRQ) to be always pending - * by setting IOMUX_GPR1_GINT. - * 2) Software should then unmask IRQ #41 in GPC before setting CCM - * Low-Power mode. - * 3) Software should mask IRQ #41 right after CCM Low-Power mode - * is set (set bits 0-1 of CCM_CLPCR). - */ -static void LPM_SetClockMode(clock_mode_t mode, uint32_t clpcr) -{ - switch (mode) - { - case kCLOCK_ModeRun: - CCM->CLPCR = clpcr; - break; - default: - LPM_EnableWakeupSource(GPR_IRQ_IRQn); - CCM->CLPCR = clpcr; - LPM_DisableWakeupSource(GPR_IRQ_IRQn); - break; - } -} - -void LPM_SwitchFlexspiClock(clock_mode_t powermode) -{ - while (!((FLEXSPI->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) - { - ; - } - FLEXSPI->MCR0 |= FLEXSPI_MCR0_MDIS_MASK; - /* Disable clock gate of flexspi. */ - CCM->CCGR6 &= (~CCM_CCGR6_CG5_MASK); - - /* Periph_clk output will be used as SEMC clock root */ - CLOCK_SET_MUX(kCLOCK_SemcMux, 0x0); - /* Set post divider for SEMC clock as 0. */ - CLOCK_SET_DIV(kCLOCK_SemcDiv, 0x0); - + /* Enable internal RC. */ + XTALOSC24M->LOWPWR_CTRL |= XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK; /* Wait CCM operation finishes */ - while (CCM->CDHIPR != 0) - { - } - - /* Semc_clk_root_pre will be used as flexspi clock. */ - CLOCK_SET_MUX(kCLOCK_FlexspiMux, 0x0); - /* Set divider for flexspi clock root 0. */ - CLOCK_SET_DIV(kCLOCK_FlexspiDiv, 0x0); - - /* Enable clock gate of flexspi. */ - CCM->CCGR6 |= (CCM_CCGR6_CG5_MASK); - - if (kCLOCK_ModeStop == powermode) { - FLEXSPI->DLLCR[0] = FLEXSPI_DLLCR_OVRDEN(1) | FLEXSPI_DLLCR_OVRDVAL(19); - } else { - FLEXSPI->DLLCR[0] = 0x79; - } - FLEXSPI->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; - FLEXSPI->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK; - - while (FLEXSPI->MCR0 & FLEXSPI_MCR0_SWRESET_MASK) { - } - - while (!((FLEXSPI->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) { - } - + CLOCK_CCM_HANDSHAKE_WAIT(); /* Take some delay */ - LPM_DELAY(40); + SDK_DelayAtLeastUs(4000); + /* Switch clock source to internal RC. */ + XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK; + /* Disable XTAL 24MHz clock source. */ + CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; } -void LPM_RestoreFlexspiClock(void) +void LPM_SetRunModeConfig(void) { - while (!((FLEXSPI->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) - { - ; - } - FLEXSPI->MCR0 |= FLEXSPI_MCR0_MDIS_MASK; - /* Disable clock gate of flexspi. */ - CCM->CCGR6 &= (~CCM_CCGR6_CG5_MASK); - - /* PLL3 PFD0 will be used as flexspi clock. */ - CLOCK_SET_MUX(kCLOCK_FlexspiMux, 0x3); - /* Set divider for flexspi clock root 0. */ - CLOCK_SET_DIV(kCLOCK_FlexspiDiv, 0x0); - - /* Enable clock gate of flexspi. */ - CCM->CCGR6 |= (CCM_CCGR6_CG5_MASK); - - /* PLL2 PFD2 output will be used as SEMC clock root */ - CLOCK_SET_MUX(kCLOCK_SemcMux, 0x1); - /* Set post divider for SEMC clock as 1. */ - CLOCK_SET_DIV(kCLOCK_SemcDiv, 0x1); - - /* Wait CCM operation finishes */ - while (CCM->CDHIPR != 0) - { - } - - FLEXSPI->DLLCR[0] = s_DllBackupValue; - FLEXSPI->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; - FLEXSPI->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK; - while (FLEXSPI->MCR0 & FLEXSPI_MCR0_SWRESET_MASK) - { - } - while (!((FLEXSPI->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) - { - ; - } - /* Take some delay */ - LPM_DELAY(40); + CCM->CLPCR &= ~(CCM_CLPCR_LPM_MASK | CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK); } -void LPM_DisablePLLs(clock_mode_t powermode) +void LPM_SetWaitModeConfig(void) { - s_clockContext.pfd480 = CCM_ANALOG->PFD_480; - s_clockContext.pfd528 = CCM_ANALOG->PFD_528; - s_clockContext.pllSys = CCM_ANALOG->PLL_SYS; - s_clockContext.pllUsb1 = CCM_ANALOG->PLL_USB1; - s_clockContext.pllUsb2 = CCM_ANALOG->PLL_USB2; - s_clockContext.pllAudio = CCM_ANALOG->PLL_AUDIO; - s_clockContext.pllVideo = CCM_ANALOG->PLL_VIDEO; - s_clockContext.pllEnet = CCM_ANALOG->PLL_ENET; - s_clockContext.pllArm_loopdiv = - (CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT; - s_clockContext.pllArm = CCM_ANALOG->PLL_ARM; - s_clockContext.periphSel = CLOCK_GetMux(kCLOCK_PeriphMux); - s_clockContext.ipgDiv = CLOCK_GetDiv(kCLOCK_IpgDiv); - s_clockContext.ahbDiv = CLOCK_GetDiv(kCLOCK_AhbDiv); - s_clockContext.perSel = CLOCK_GetMux(kCLOCK_PerclkMux); - s_clockContext.perDiv = CLOCK_GetDiv(kCLOCK_PerclkDiv); - s_clockContext.preperiphSel = CLOCK_GetMux(kCLOCK_PrePeriphMux); - s_clockContext.armDiv = CLOCK_GetDiv(kCLOCK_ArmDiv); - s_clockContext.is_valid = 1; + uint32_t clpcr; - /* Power off USB2 PLL */ - CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_BYPASS_MASK; - CCM_ANALOG->PLL_USB2_CLR = CCM_ANALOG_PLL_USB2_POWER_MASK; - /* Power off AUDIO PLL */ - CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; - CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK; - /* Power off VIDEO PLL */ - CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; - CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK; - /* Power off ENET PLL */ - CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_BYPASS_MASK; - CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK; - - if (kCLOCK_ModeWait == powermode) { - CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); - CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); - CLOCK_SetMux(kCLOCK_PeriphMux, 1); - CLOCK_SetDiv(kCLOCK_IpgDiv, 0); - CLOCK_SetDiv(kCLOCK_AhbDiv, 0); - - /*ARM PLL as clksource*/ - /* 24 * 88 / 2 / 8 = 132MHz */ - CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK; - CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_BYPASS_MASK; - CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK; - CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_DIV_SELECT(88); - CLOCK_SetDiv(kCLOCK_ArmDiv, 7); - CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_BYPASS_MASK; - - /*Select ARM_PLL for pre_periph_clock */ - CLOCK_SetMux(kCLOCK_PrePeriphMux, 3); - CLOCK_SetMux(kCLOCK_PeriphMux, 0); - - /* SET AHB, IPG to 33MHz */ - CLOCK_SetDiv(kCLOCK_IpgDiv, 0); - CLOCK_SetDiv(kCLOCK_AhbDiv, 3); - - /*Set PERCLK to 33MHz*/ - //CLOCK_SetMux(kCLOCK_PerclkMux, 0); - //CLOCK_SetDiv(kCLOCK_PerclkDiv, 0); - } else { - CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); - CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); - CLOCK_SetMux(kCLOCK_PeriphMux, 1); - CLOCK_SetDiv(kCLOCK_IpgDiv, 0); - CLOCK_SetDiv(kCLOCK_AhbDiv, 0); - - /*ARM PLL as clksource*/ - CCM_ANALOG->PLL_ARM |= CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_BYPASS_MASK; - /* Power off ARM PLL */ - CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK; - - /*Select ARM_PLL for pre_periph_clock */ - CLOCK_SetDiv(kCLOCK_ArmDiv, 0x0); - CLOCK_SetMux(kCLOCK_PrePeriphMux, 0x3); - CLOCK_SetMux(kCLOCK_PeriphMux, 0x0); - - /* SET AHB, IPG to 12MHz */ - CLOCK_SetDiv(kCLOCK_IpgDiv, 0); - CLOCK_SetDiv(kCLOCK_AhbDiv, 1); - - /*Set PERCLK to 12Mhz*/ - //CLOCK_SetMux(kCLOCK_PerclkMux, 0x0); - //CLOCK_SetDiv(kCLOCK_PerclkDiv, 0x0); - } - - core_util_critical_section_enter(); - LPM_SwitchFlexspiClock(powermode); - core_util_critical_section_exit(); - - CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd0); - CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd1); - CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd2); - CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd3); - - /* Power off USB1 PLL */ - CCM_ANALOG->PLL_USB1_SET = CCM_ANALOG_PLL_USB1_BYPASS_MASK; - CCM_ANALOG->PLL_USB1_CLR = CCM_ANALOG_PLL_USB1_POWER_MASK; - - CLOCK_DeinitSysPfd(kCLOCK_Pfd0); - CLOCK_DeinitSysPfd(kCLOCK_Pfd1); - CLOCK_DeinitSysPfd(kCLOCK_Pfd2); - CLOCK_DeinitSysPfd(kCLOCK_Pfd3); - - /* When need to close PLL, we need to use bypass clock first and then power it down. */ - /* Power off SYS PLL */ - CCM_ANALOG->PLL_SYS_SET = CCM_ANALOG_PLL_SYS_BYPASS_MASK; - CCM_ANALOG->PLL_SYS_SET = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK; + /* + * ERR007265: CCM: When improper low-power sequence is used, + * the SoC enters low power mode before the ARM core executes WFI. + * + * Software workaround: + * 1) Software should trigger IRQ #41 (GPR_IRQ) to be always pending + * by setting IOMUXC_GPR_GPR1_GINT. + * 2) Software should then unmask IRQ #41 in GPC before setting CCM + * Low-Power mode. + * 3) Software should mask IRQ #41 right after CCM Low-Power mode + * is set (set bits 0-1 of CCM_CLPCR). + */ + GPC_EnableIRQ(GPC, GPR_IRQ_IRQn); + clpcr = CCM->CLPCR & (~(CCM_CLPCR_LPM_MASK | CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK)); + CCM->CLPCR = clpcr | CCM_CLPCR_LPM(kCLOCK_ModeWait) | CCM_CLPCR_MASK_SCU_IDLE_MASK | CCM_CLPCR_MASK_L2CC_IDLE_MASK | + CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK | CCM_CLPCR_STBY_COUNT_MASK | CCM_CLPCR_BYPASS_LPM_HS0_MASK | + CCM_CLPCR_BYPASS_LPM_HS1_MASK; + GPC_DisableIRQ(GPC, GPR_IRQ_IRQn); } -void LPM_RestorePLLs(void) +void LPM_SetStopModeConfig(void) { - if (s_clockContext.is_valid) - { - /* Bypass PLL first */ - CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK)) | - CCM_ANALOG_PLL_USB1_BYPASS_MASK; + uint32_t clpcr; - CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK)) | - CCM_ANALOG_PLL_USB1_ENABLE_MASK | CCM_ANALOG_PLL_USB1_POWER_MASK | - CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; - - while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0) - { - } - - /* Disable Bypass */ - CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_BYPASS_MASK; - - /* Restore USB1 PLL PFD */ - CCM_ANALOG->PFD_480 = s_clockContext.pfd480; - CCM_ANALOG->PFD_480_CLR = CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK; - - /* Disable Usb1 PLL output for USBPHY1. */ - CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; - - /* When need to enable PLL, we need to use bypass clock first and then switch pll back. */ - /* Power on SYS PLL and wait for locked */ - CCM_ANALOG->PLL_SYS_SET = CCM_ANALOG_PLL_SYS_BYPASS_MASK; - CCM_ANALOG->PLL_SYS_CLR = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK; - CCM_ANALOG->PLL_SYS = s_clockContext.pllSys; - - while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0) - { - } - - /* Restore SYS PLL PFD */ - CCM_ANALOG->PFD_528 = s_clockContext.pfd528; - CCM_ANALOG->PFD_528_CLR = CCM_ANALOG_PFD_528_PFD2_CLKGATE_MASK; - - core_util_critical_section_enter(); - LPM_RestoreFlexspiClock(); - core_util_critical_section_exit(); - } else { - return; - } - - CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0); - CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0); - CLOCK_SetMux(kCLOCK_PeriphMux, 1); - CLOCK_SetDiv(kCLOCK_IpgDiv, 0x3); - CLOCK_SetDiv(kCLOCK_AhbDiv, 0x0); - - /* ARM PLL as clksource*/ - CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK; - CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_BYPASS_MASK; - - CLOCK_SetDiv(kCLOCK_ArmDiv, s_clockContext.armDiv); - CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK; - CCM_ANALOG->PLL_ARM_SET = CCM_ANALOG_PLL_ARM_DIV_SELECT(s_clockContext.pllArm_loopdiv); - if ((s_clockContext.pllArm & CCM_ANALOG_PLL_ARM_BYPASS_MASK) == 0) - { - while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0) - { - } - } - if ((s_clockContext.pllArm & CCM_ANALOG_PLL_ARM_BYPASS_MASK) == 0) - { - CCM_ANALOG->PLL_ARM_CLR = CCM_ANALOG_PLL_ARM_BYPASS_MASK; - } - - /* Restore AHB and IPG div */ - CCM->CBCDR = (CCM->CBCDR & ~(CCM_CBCDR_AHB_PODF_MASK | CCM_CBCDR_IPG_PODF_MASK | CCM_CBCDR_PERIPH_CLK_SEL_MASK)) | - CCM_CBCDR_AHB_PODF(s_clockContext.ahbDiv) | CCM_CBCDR_IPG_PODF(s_clockContext.ipgDiv) | - CCM_CBCDR_PERIPH_CLK_SEL(s_clockContext.periphSel); - - /* Restore Periphral clock */ - CCM->CSCMR1 = (CCM->CSCMR1 & ~CCM_CSCMR1_PERCLK_PODF_MASK) | CCM_CSCMR1_PERCLK_PODF(s_clockContext.perDiv) | - CCM_CSCMR1_PERCLK_CLK_SEL(s_clockContext.perSel); - - /* Switch clocks back */ - CCM->CBCMR = - (CCM->CBCMR & ~CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) | CCM_CBCMR_PRE_PERIPH_CLK_SEL(s_clockContext.preperiphSel); - - /* Wait CCM operation finishes */ - while (CCM->CDHIPR != 0) - { - } - - /* Restore USB2 PLL */ - CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_BYPASS_MASK; - CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_POWER_MASK; - CCM_ANALOG->PLL_USB2 = s_clockContext.pllUsb2; - if ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_POWER_MASK) != 0) - { - while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0) - { - } - } - - /* Restore AUDIO PLL */ - CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; - CCM_ANALOG->PLL_AUDIO_CLR = CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK; - CCM_ANALOG->PLL_AUDIO = s_clockContext.pllAudio; - if ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK) == 0) - { - while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0) - { - } - } - - /* Restore VIDEO PLL */ - CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; - CCM_ANALOG->PLL_VIDEO_CLR = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK; - CCM_ANALOG->PLL_VIDEO = s_clockContext.pllVideo; - if ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK) == 0) - { - while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0) - { - } - } - - /* Restore ENET PLL */ - CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_BYPASS_MASK; - CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK; - CCM_ANALOG->PLL_ENET = s_clockContext.pllEnet; - if ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_POWERDOWN_MASK) == 0) - { - while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0) - { - } - } - - s_clockContext.is_valid = 0; + /* + * ERR007265: CCM: When improper low-power sequence is used, + * the SoC enters low power mode before the ARM core executes WFI. + * + * Software workaround: + * 1) Software should trigger IRQ #41 (GPR_IRQ) to be always pending + * by setting IOMUXC_GPR_GPR1_GINT. + * 2) Software should then unmask IRQ #41 in GPC before setting CCM + * Low-Power mode. + * 3) Software should mask IRQ #41 right after CCM Low-Power mode + * is set (set bits 0-1 of CCM_CLPCR). + */ + GPC_EnableIRQ(GPC, GPR_IRQ_IRQn); + clpcr = CCM->CLPCR & (~(CCM_CLPCR_LPM_MASK | CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK)); + CCM->CLPCR = clpcr | CCM_CLPCR_LPM(kCLOCK_ModeStop) | CCM_CLPCR_MASK_L2CC_IDLE_MASK | CCM_CLPCR_MASK_SCU_IDLE_MASK | + CCM_CLPCR_VSTBY_MASK | CCM_CLPCR_STBY_COUNT_MASK | CCM_CLPCR_SBYOS_MASK | + CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK | CCM_CLPCR_BYPASS_LPM_HS0_MASK | CCM_CLPCR_BYPASS_LPM_HS1_MASK; + GPC_DisableIRQ(GPC, GPR_IRQ_IRQn); } -static void LPM_SystemIdle(clock_mode_t powermode) +void LPM_OverDriveRun(void) { + /* CCM Mode */ + DCDC_BootIntoCCM(DCDC); + /* Connect internal the load resistor */ + DCDC->REG1 |= DCDC_REG1_REG_RLOAD_SW_MASK; + /* Adjust SOC voltage to 1.275V */ + DCDC_AdjustTargetVoltage(DCDC, 0x13, 0x1); + + /* Disable FET ODRIVE */ + PMU->REG_CORE_CLR = PMU_REG_CORE_FET_ODRIVE_MASK; + /* Connect vdd_high_in and connect vdd_snvs_in */ + PMU->MISC0_CLR = PMU_MISC0_DISCON_HIGH_SNVS_MASK; + + BandgapOn(); + EnableRegularLDO(); + DisableWeakLDO(); + + ClockSetToOverDriveRun(); + SetRestoreClockGate(); +} + +void LPM_FullSpeedRun(void) +{ + /* CCM Mode */ + DCDC_BootIntoCCM(DCDC); + /* Connect internal the load resistor */ + DCDC->REG1 |= DCDC_REG1_REG_RLOAD_SW_MASK; + /* Adjust SOC voltage to 1.275V */ + DCDC_AdjustTargetVoltage(DCDC, 0x13, 0x1); + + /* Disable FET ODRIVE */ + PMU->REG_CORE_CLR = PMU_REG_CORE_FET_ODRIVE_MASK; + /* Connect vdd_high_in and connect vdd_snvs_in */ + PMU->MISC0_CLR = PMU_MISC0_DISCON_HIGH_SNVS_MASK; + + BandgapOn(); + EnableRegularLDO(); + DisableWeakLDO(); + + ClockSetToFullSpeedRun(); + + /* Adjust SOC voltage to 1.15V */ + DCDC_AdjustTargetVoltage(DCDC, 0xe, 0x1); +} + +void LPM_LowSpeedRun(void) +{ + /* CCM Mode */ + DCDC_BootIntoCCM(DCDC); + /* Connect internal the load resistor */ + DCDC->REG1 |= DCDC_REG1_REG_RLOAD_SW_MASK; + /* Adjust SOC voltage to 1.275V */ + DCDC_AdjustTargetVoltage(DCDC, 0x13, 0x1); + + /* Disable FET ODRIVE */ + PMU->REG_CORE_CLR = PMU_REG_CORE_FET_ODRIVE_MASK; + /* Connect vdd_high_in and connect vdd_snvs_in */ + PMU->MISC0_CLR = PMU_MISC0_DISCON_HIGH_SNVS_MASK; + + BandgapOn(); + EnableRegularLDO(); + DisableWeakLDO(); + + ClockSetToLowSpeedRun(); + + /* Adjust SOC voltage to 1.15V */ + DCDC_AdjustTargetVoltage(DCDC, 0xe, 0x1); +} + +void LPM_LowPowerRun(void) +{ + ClockSetToLowPowerRun(); + + /* Power down USBPHY */ + PowerDownUSBPHY(); + + /* Adjust SOC voltage to 0.95V */ + DCDC_AdjustTargetVoltage(DCDC, 0x6, 0x1); + /* DCM Mode */ + DCDC_BootIntoDCM(DCDC); + /* Disconnect internal the load resistor */ + DCDC->REG1 &= ~DCDC_REG1_REG_RLOAD_SW_MASK; + /* Power Down output range comparator */ + DCDC->REG0 |= DCDC_REG0_PWD_CMP_OFFSET_MASK; + + /* Enable FET ODRIVE */ + PMU->REG_CORE_SET = PMU_REG_CORE_FET_ODRIVE_MASK; + /* Connect vdd_high_in and connect vdd_snvs_in */ + PMU->MISC0_CLR = PMU_MISC0_DISCON_HIGH_SNVS_MASK; + + EnableWeakLDO(); + DisableRegularLDO(); + BandgapOff(); +} + +void LPM_EnterSystemIdle(void) +{ + LPM_SetWaitModeConfig(); + SetLowPowerClockGate(); + + ClockSetToSystemIdle(); + + /* Power down USBPHY */ + PowerDownUSBPHY(); + + /* DCDC to 1.15V */ + DCDC_AdjustTargetVoltage(DCDC, 0xe, 0x1); + /* DCM Mode */ + DCDC_BootIntoDCM(DCDC); + /* Disconnect internal the load resistor */ + DCDC->REG1 &= ~DCDC_REG1_REG_RLOAD_SW_MASK; + /* Power Down output range comparator */ + DCDC->REG0 |= DCDC_REG0_PWD_CMP_OFFSET_MASK; + + /* Enable FET ODRIVE */ + PMU->REG_CORE_SET = PMU_REG_CORE_FET_ODRIVE_MASK; + /* Connect vdd_high_in and connect vdd_snvs_in */ + PMU->MISC0_CLR = PMU_MISC0_DISCON_HIGH_SNVS_MASK; + + EnableRegularLDO(); + DisableWeakLDO(); + BandgapOn(); + + PeripheralEnterDozeMode(); +} + +void LPM_ExitSystemIdle(void) +{ + PeripheralExitDozeMode(); + LPM_SetRunModeConfig(); +} + +void LPM_EnterLowPowerIdle(void) +{ + LPM_SetWaitModeConfig(); + SetLowPowerClockGate(); + + ClockSetToLowPowerIdle(); + + /* Power down USBPHY */ + PowerDownUSBPHY(); + + /* Adjust SOC voltage to 0.95V */ + DCDC_AdjustTargetVoltage(DCDC, 0x6, 0x1); + /* DCM Mode */ + DCDC_BootIntoDCM(DCDC); + /* Disconnect internal the load resistor */ + DCDC->REG1 &= ~DCDC_REG1_REG_RLOAD_SW_MASK; + /* Power Down output range comparator */ + DCDC->REG0 |= DCDC_REG0_PWD_CMP_OFFSET_MASK; + + /* Enable FET ODRIVE */ + PMU->REG_CORE_SET = PMU_REG_CORE_FET_ODRIVE_MASK; + /* Connect vdd_high_in and connect vdd_snvs_in */ + PMU->MISC0_CLR = PMU_MISC0_DISCON_HIGH_SNVS_MASK; + + EnableWeakLDO(); + DisableRegularLDO(); + BandgapOff(); + + PeripheralEnterDozeMode(); +} + +void LPM_ExitLowPowerIdle(void) +{ + PeripheralExitDozeMode(); + LPM_SetRunModeConfig(); +} + +void LPM_EnterSuspend(void) +{ + uint32_t i; + uint32_t gpcIMR[LPM_GPC_IMR_NUM]; + + LPM_SetStopModeConfig(); + SetLowPowerClockGate(); + + /* Disconnect internal the load resistor */ + DCDC->REG1 &= ~DCDC_REG1_REG_RLOAD_SW_MASK; + + /* Turn off FlexRAM0 */ + GPC->CNTR |= GPC_CNTR_PDRAM0_PGE_MASK; + /* Turn off FlexRAM1 */ + PGC->MEGA_CTRL |= PGC_MEGA_CTRL_PCR_MASK; + + /* Clean and disable data cache to make sure context is saved into RAM */ + SCB_CleanDCache(); + SCB_DisableDCache(); + + /* Adjust LP voltage to 0.925V */ + DCDC_AdjustTargetVoltage(DCDC, 0x13, 0x1); /* Switch DCDC to use DCDC internal OSC */ DCDC_SetClockSource(DCDC, kDCDC_ClockInternalOsc); /* Power down USBPHY */ - USBPHY1->CTRL = 0xFFFFFFFF; - USBPHY2->CTRL = 0xFFFFFFFF; + PowerDownUSBPHY(); - LPM_DisablePLLs(powermode); + /* Power down CPU when requested */ + PGC->CPU_CTRL = PGC_CPU_CTRL_PCR_MASK; - /* Enable weak 2P5 and turn off regular 2P5 */ - PMU->REG_2P5 &= ~PMU_REG_2P5_ENABLE_LINREG_MASK; - PMU->REG_2P5 |= PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; - - /* Enable weak 1P1 and turn off regular 1P1 */ - PMU->REG_1P1 &= ~PMU_REG_1P1_ENABLE_LINREG_MASK; - PMU->REG_1P1 |= PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; - - core_util_critical_section_enter(); - LPM_SwitchToRcOSC(); - core_util_critical_section_exit(); - - /* Lower OSC current by 37.5% */ - CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_I_MASK; /* Enable FET ODRIVE */ PMU->REG_CORE_SET = PMU_REG_CORE_FET_ODRIVE_MASK; - /* Disconnect vdd_high_in and connect vdd_snvs_in */ - CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_DISCON_HIGH_SNVS_MASK; + /* Connect vdd_high_in and connect vdd_snvs_in */ + PMU->MISC0_CLR = PMU_MISC0_DISCON_HIGH_SNVS_MASK; + /* STOP_MODE config, turn off all analog except RTC in stop mode */ + PMU->MISC0_CLR = PMU_MISC0_STOP_MODE_CONFIG_MASK; - DCDC_AdjustTargetVoltage(DCDC, 0x6, 0x1); + /* Mask all GPC interrupts before enabling the RBC counters to + * avoid the counter starting too early if an interupt is already + * pending. + */ + for (i = 0; i < LPM_GPC_IMR_NUM; i++) + { + gpcIMR[i] = GPC->IMR[i]; + GPC->IMR[i] = 0xFFFFFFFFU; + } - core_util_critical_section_enter(); - LPM_SwitchBandgap(); - core_util_critical_section_exit(); + /* + * ERR006223: CCM: Failure to resuem from wait/stop mode with power gating + * Configure REG_BYPASS_COUNTER to 2 + * Enable the RBC bypass counter here to hold off the interrupts. RBC counter + * needs to be no less than 2. + */ + CCM->CCR = (CCM->CCR & ~CCM_CCR_REG_BYPASS_COUNT_MASK) | CCM_CCR_REG_BYPASS_COUNT(2); + CCM->CCR |= (CCM_CCR_OSCNT(0xAF) | CCM_CCR_COSC_EN_MASK | CCM_CCR_RBC_EN_MASK); - /* RBC = 0; Enable COSC, OSC COUNT = 0xAF */ - CCM->CCR = (CCM_CCR_COSC_EN_MASK | CCM_CCR_OSCNT(0xAF)); + /* Now delay for a short while (3usec) at this point + * so a short loop should be enough. This delay is required to ensure that + * the RBC counter can start counting in case an interrupt is already pending + * or in case an interrupt arrives just as ARM is about to assert DSM_request. + */ + SDK_DelayAtLeastUs(3); + + /* Recover all the GPC interrupts. */ + for (i = 0; i < LPM_GPC_IMR_NUM; i++) + { + GPC->IMR[i] = gpcIMR[i]; + } + + PeripheralEnterStopMode(); } -void LPM_SystemRestoreIdle(void) +void LPM_EnterSNVS(void) { - DCDC_AdjustTargetVoltage(DCDC, 0x12, 0x1); - - /* Switch DCDC to use DCDC internal OSC */ - DCDC_SetClockSource(DCDC, kDCDC_ClockExternalOsc); - - /* Disconnect vdd_snvs_in and connect vdd_high_in */ - CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_DISCON_HIGH_SNVS_MASK; - /* Increase OSC current to normal */ - CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_I_MASK; - - core_util_critical_section_enter(); - LPM_SwitchToXtalOSC(); - LPM_RestoreBandgap(); - core_util_critical_section_exit(); - - /* Disable FET ODRIVE */ - PMU->REG_CORE_CLR = PMU_REG_CORE_FET_ODRIVE_MASK; - - /* Enable regular 2P5 and wait for stable */ - PMU->REG_2P5_SET = PMU_REG_2P5_ENABLE_LINREG_MASK; - while ((PMU->REG_2P5 & PMU_REG_2P5_OK_VDD2P5_MASK) == 0) + SNVS->LPCR |= SNVS_LPCR_TOP_MASK; + while (1) /* Shutdown */ { } - /* Turn off weak 2P5 */ - PMU->REG_2P5_CLR = PMU_REG_2P5_ENABLE_WEAK_LINREG_MASK; - - /* Enable regular 1P1 and wait for stable */ - PMU->REG_1P1_SET = PMU_REG_1P1_ENABLE_LINREG_MASK; - while ((PMU->REG_1P1 & PMU_REG_1P1_OK_VDD1P1_MASK) == 0) - { - } - /* Turn off weak 1P1 */ - PMU->REG_1P1_CLR = PMU_REG_1P1_ENABLE_WEAK_LINREG_MASK; - - LPM_RestorePLLs(); } bool LPM_Init(void) @@ -640,7 +481,7 @@ bool LPM_Init(void) XTALOSC24M_OSC_CONFIG0_ENABLE_MASK; XTALOSC24M->OSC_CONFIG1 = XTALOSC24M_OSC_CONFIG1_COUNT_RC_CUR(0x40) | XTALOSC24M_OSC_CONFIG1_COUNT_RC_TRG(0x2DC); /* Take some delay */ - LPM_DELAY(40); + SDK_DelayAtLeastUs(4000); /* Add some hysteresis */ tmp_reg = XTALOSC24M->OSC_CONFIG0; tmp_reg &= ~(XTALOSC24M_OSC_CONFIG0_HYST_PLUS_MASK | XTALOSC24M_OSC_CONFIG0_HYST_MINUS_MASK); @@ -655,13 +496,12 @@ bool LPM_Init(void) tmp_reg = XTALOSC24M->OSC_CONFIG1; XTALOSC24M->OSC_CONFIG1 = tmp_reg; - s_DllBackupValue = FLEXSPI->DLLCR[0]; - /* ERR007265 */ IOMUXC_GPR->GPR1 |= IOMUXC_GPR_GPR1_GINT_MASK; /* Initialize GPC to mask all IRQs */ - for (i = 0; i < LPM_GPC_IMR_NUM; i++) { + for (i = 0; i < LPM_GPC_IMR_NUM; i++) + { GPC->IMR[i] = 0xFFFFFFFFU; } @@ -674,80 +514,39 @@ void LPM_Deinit(void) IOMUXC_GPR->GPR1 &= ~IOMUXC_GPR_GPR1_GINT_MASK; } +void LPM_EnableWakeupSource(uint32_t irq) +{ + GPC_EnableIRQ(GPC, irq); +} + +void LPM_DisableWakeupSource(uint32_t irq) +{ + GPC_DisableIRQ(GPC, irq); +} + +GPT_Type *vPortGetGptBase(void) +{ + return GPT2; +} + +IRQn_Type vPortGetGptIrqn(void) +{ + return GPT2_IRQn; +} + void vPortPRE_SLEEP_PROCESSING(clock_mode_t powermode) { - uint32_t clpcr; + LPM_EnableWakeupSource(vPortGetGptIrqn()); - clpcr = CCM->CLPCR & (~(CCM_CLPCR_LPM_MASK | CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK)); - - switch (powermode) - { - case kCLOCK_ModeWait: -#if 0 - LPM_EnableWakeupSource(PIT_IRQn); - - LPM_SetClockMode(kCLOCK_ModeWait, clpcr | CCM_CLPCR_LPM(kCLOCK_ModeWait) | - CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK | CCM_CLPCR_STBY_COUNT_MASK | 0x1C | - 0x08280000); - IOMUXC_GPR->GPR8 = 0xaaaaaaaa; - IOMUXC_GPR->GPR12 = 0x0000000a; -#endif - break; - case kCLOCK_ModeStop: - LPM_EnableWakeupSource(GPT2_IRQn); - - LPM_SetClockMode(kCLOCK_ModeWait, clpcr | CCM_CLPCR_LPM(kCLOCK_ModeWait) | - CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK | CCM_CLPCR_STBY_COUNT_MASK | 0x1C | - 0x08280000); - BOARD_SetLPClockGate(); - LPM_SystemIdle(powermode); - IOMUXC_GPR->GPR8 = 0xaaaaaaaa; - IOMUXC_GPR->GPR12 = 0x0000000a; - break; - default: - assert(false); - break; - } + LPM_EnterLowPowerIdle(); } void vPortPOST_SLEEP_PROCESSING(clock_mode_t powermode) { - uint32_t clpcr; + LPM_ExitLowPowerIdle(); - clpcr = CCM->CLPCR & (~(CCM_CLPCR_LPM_MASK | CCM_CLPCR_ARM_CLK_DIS_ON_LPM_MASK)); + LPM_OverDriveRun(); - switch (powermode) - { - case kCLOCK_ModeWait: -#if 0 - - IOMUXC_GPR->GPR8 = 0x00000000; - IOMUXC_GPR->GPR12 = 0x00000000; - LPM_SetClockMode(kCLOCK_ModeRun, clpcr); - - LPM_DisableWakeupSource(PIT_IRQn); -#endif - - break; - case kCLOCK_ModeStop: - __NOP(); - __NOP(); - __NOP(); - __NOP(); - IOMUXC_GPR->GPR8 = 0x00000000; - IOMUXC_GPR->GPR12 = 0x00000000; - /* Interrupt occurs before system idle */ - LPM_SystemRestoreIdle(); - BOARD_ResetLPClockGate(); - - LPM_SetClockMode(kCLOCK_ModeRun, clpcr); - - LPM_DisableWakeupSource(GPT2_IRQn); - - break; - default: - assert(false); - break; - } + LPM_DisableWakeupSource(vPortGetGptIrqn()); } diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.h index c1b9a78744..ea20400cee 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/lpm.h @@ -1,127 +1,100 @@ /* - * The Clear BSD License * Copyright 2017 NXP * All rights reserved. * * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted (subject to the limitations in the disclaimer below) 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. - * - * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. - * 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 _LPM_H_ #define _LPM_H_ #include "fsl_clock.h" +#include /******************************************************************************* * Definitions ******************************************************************************/ extern void vPortGPTIsr(void); +extern uint32_t g_savedPrimask; #define vPortGptIsr GPT1_IRQHandler -#define CLOCK_SET_MUX(mux, value) \ - \ -do \ - { \ - CCM_TUPLE_REG(CCM, mux) = (CCM_TUPLE_REG(CCM, mux) & (~CCM_TUPLE_MASK(mux))) | \ - (((uint32_t)((value) << CCM_TUPLE_SHIFT(mux))) & CCM_TUPLE_MASK(mux)); \ - while (CCM->CDHIPR != 0) \ - { \ - } \ - \ -} \ - while (0) - -#define CLOCK_SET_DIV(divider, value) \ - \ -do \ - { \ - CCM_TUPLE_REG(CCM, divider) = (CCM_TUPLE_REG(CCM, divider) & (~CCM_TUPLE_MASK(divider))) | \ - (((uint32_t)((value) << CCM_TUPLE_SHIFT(divider))) & CCM_TUPLE_MASK(divider)); \ - while (CCM->CDHIPR != 0) \ - { \ - } \ - \ -} \ - while (0) - #define CLOCK_CCM_HANDSHAKE_WAIT() \ - \ -do \ + \ + do \ { \ while (CCM->CDHIPR != 0) \ { \ } \ - \ -} \ - while (0) + \ + } while (0) -#define LPM_DELAY(value) \ - \ -do \ - { \ - for (uint32_t i = 0; i < 5 * value; i++) \ - { \ - __NOP(); \ - } \ - \ -} \ - while (0) - -#define ROM_CODE_ENTRY_ADDR (0x200000U) - -/*! @name Time sensitive region */ -/* @{ */ #if defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1) -#if (defined(__ICCARM__)) -#define AT_QUICKACCESS_SECTION_CODE(func) __ramfunc func -#elif(defined(__ARMCC_VERSION)) -#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("RamFunction"))) func -#elif defined(__MCUXPRESSO) -#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section(".ramfunc.$SRAM_ITC"))) func -#elif(defined(__GNUC__)) -#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("RamFunction"))) func +#define LPM_EnterCritical() \ + \ + do \ + { \ + g_savedPrimask = DisableGlobalIRQ(); \ + SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; \ + \ + } while (0) + +#define LPM_ExitCritical() \ + \ + do \ + { \ + EnableGlobalIRQ(g_savedPrimask); \ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; \ + \ + } while (0) + #else -#error Toolchain not supported. -#endif /* defined(__ICCARM__) */ -#else -#if (defined(__ICCARM__)) -#define AT_QUICKACCESS_SECTION_CODE(func) func -#elif(defined(__ARMCC_VERSION)) -#define AT_QUICKACCESS_SECTION_CODE(func) func -#elif(defined(__MCUXPRESSO)) -#define AT_QUICKACCESS_SECTION_CODE(func) func -#elif(defined(__GNUC__)) -#define AT_QUICKACCESS_SECTION_CODE(func) func -#else -#error Toolchain not supported. +#define LPM_EnterCritical() +#define LPM_ExitCritical() #endif -#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */ + +/* Power mode definition of low power management. + * Waken up duration Off > Dsm > Idle > Wait > Run. + */ +typedef enum _lpm_power_mode +{ + LPM_PowerModeOverRun = 0, /* Over RUN mode, CPU won't stop running */ + + LPM_PowerModeFullRun, /* Full RUN mode, CPU won't stop running */ + + LPM_PowerModeLowSpeedRun, + + LPM_PowerModeLowPowerRun, + + LPM_PowerModeRunEnd = LPM_PowerModeLowPowerRun, + /* In system wait mode, cpu clock is gated. + * All peripheral can remain active, clock gating decided by CCGR setting. + * DRAM enters auto-refresh mode when there is no access. + */ + LPM_PowerModeSysIdle, /* System WAIT mode, also system low speed idle */ + + /* In low power idle mode, all PLL/PFD is off, cpu power is off. + * Analog modules running in low power mode. + * All high-speed peripherals are power gated + * Low speed peripherals can remain running at low frequency + * DRAM in self-refresh. + */ + LPM_PowerModeLPIdle, /* Low Power Idle mode */ + + /* In deep sleep mode, all PLL/PFD is off, XTAL is off, cpu power is off. + * All clocks are shut off except 32K RTC clock + * All high-speed peripherals are power gated + * Low speed peripherals are clock gated + * DRAM in self-refresh. + * If RTOS is used, systick will be disabled in DSM + */ + LPM_PowerModeSuspend, /* Deep Sleep mode, suspend. */ + + LPM_PowerModeSNVS, /* Power off mode, or shutdown mode */ + + LPM_PowerModeEnd = LPM_PowerModeSNVS +} lpm_power_mode_t; /******************************************************************************* * API @@ -131,8 +104,8 @@ do \ extern "C" { #endif /* __cplusplus*/ -AT_QUICKACCESS_SECTION_CODE(void LPM_SwitchFlexspiClock(clock_mode_t powermode)); -AT_QUICKACCESS_SECTION_CODE(void LPM_RestoreFlexspiClock(void)); +AT_QUICKACCESS_SECTION_CODE(void CLOCK_SET_MUX(clock_mux_t mux, uint32_t value)); +AT_QUICKACCESS_SECTION_CODE(void CLOCK_SET_DIV(clock_div_t divider, uint32_t value)); /* Initialize the Low Power Management */ bool LPM_Init(void); @@ -146,6 +119,25 @@ void LPM_EnableWakeupSource(uint32_t irq); /* Disable wakeup source in low power mode */ void LPM_DisableWakeupSource(uint32_t irq); +void ClockSelectXtalOsc(void); +void ClockSelectRcOsc(void); +void LPM_EnableWakeupSource(uint32_t irq); +void LPM_DisableWakeupSource(uint32_t irq); +void LPM_PreEnterWaitMode(void); +void LPM_PostExitWaitMode(void); +void LPM_PreEnterStopMode(void); +void LPM_PostExitStopMode(void); +void LPM_OverDriveRun(void); +void LPM_FullSpeedRun(void); +void LPM_LowSpeedRun(void); +void LPM_LowPowerRun(void); +void LPM_EnterSystemIdle(void); +void LPM_ExitSystemIdle(void); +void LPM_EnterLowPowerIdle(void); +void LPM_ExitLowPowerIdle(void); +void LPM_EnterSuspend(void); +void LPM_EnterSNVS(void); + #if defined(__cplusplus) } #endif /* __cplusplus*/ diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/specific.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/specific.c new file mode 100644 index 0000000000..270565c3c4 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/specific.c @@ -0,0 +1,609 @@ +/* + * Copyright 2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "specific.h" +#include "fsl_common.h" +#include "fsl_clock.h" +#include "lpm.h" +#include "fsl_iomuxc.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +const clock_arm_pll_config_t armPllConfig_PowerMode = { + .loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */ + .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ +}; +const clock_sys_pll_config_t sysPllConfig_PowerMode = { + .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */ + .numerator = 0, /* 30 bit numerator of fractional loop divider */ + .denominator = 1, /* 30 bit denominator of fractional loop divider */ + .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ +}; +const clock_usb_pll_config_t usb1PllConfig_PowerMode = { + .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */ + .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */ +}; + +AT_QUICKACCESS_SECTION_CODE(void SwitchSystemClocks(lpm_power_mode_t power_mode)); + +#define NUMBER_OF_CCM_GATE_REGS 7 +static uint32_t clock_gate_values[NUMBER_OF_CCM_GATE_REGS]; + +void SwitchSystemClocks(lpm_power_mode_t power_mode) +{ +#if (defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) + while (!((FLEXSPI_INST->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI_INST->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) + { + } + FLEXSPI_INST->MCR0 |= FLEXSPI_MCR0_MDIS_MASK; + + /* Disable clock gate of flexspi. */ + CCM->CCGR6 &= (~CCM_CCGR6_CG5_MASK); +#endif + switch (power_mode) + { + case LPM_PowerModeOverRun: + CLOCK_SET_DIV(kCLOCK_SemcDiv, 3); // SEMC CLK should not exceed 166MHz + CLOCK_SET_DIV(kCLOCK_FlexspiDiv, 0); // FLEXSPI in DDR mode + CLOCK_SET_MUX(kCLOCK_FlexspiMux, 3); // FLEXSPI mux to PLL3 PFD0 + /* CORE CLK to 600MHz, AHB, IPG to 150MHz, PERCLK to 75MHz */ + //CLOCK_SET_DIV(kCLOCK_PerclkDiv, 1); + CLOCK_SET_DIV(kCLOCK_IpgDiv, 3); + CLOCK_SET_DIV(kCLOCK_AhbDiv, 0); + //CLOCK_SET_MUX(kCLOCK_PerclkMux, 0); // PERCLK mux to IPG CLK + CLOCK_SET_MUX(kCLOCK_PrePeriphMux, 3); // PRE_PERIPH_CLK mux to ARM PLL + CLOCK_SET_MUX(kCLOCK_PeriphMux, 0); // PERIPH_CLK mux to PRE_PERIPH_CLK + break; + case LPM_PowerModeFullRun: + CLOCK_SET_DIV(kCLOCK_SemcDiv, 3); // SEMC CLK should not exceed 166MHz + CLOCK_SET_DIV(kCLOCK_FlexspiDiv, 0); // FLEXSPI in DDR mode + CLOCK_SET_MUX(kCLOCK_FlexspiMux, 3); // FLEXSPI mux to PLL3 PFD0 + /* CORE CLK to 528MHz, AHB, IPG to 132MHz, PERCLK to 66MHz */ + CLOCK_SET_DIV(kCLOCK_PerclkDiv, 1); + CLOCK_SET_DIV(kCLOCK_IpgDiv, 3); + CLOCK_SET_DIV(kCLOCK_AhbDiv, 0); + CLOCK_SET_MUX(kCLOCK_PerclkMux, 0); // PERCLK mux to IPG CLK + CLOCK_SET_MUX(kCLOCK_PrePeriphMux, 0); // PRE_PERIPH_CLK mux to SYS PLL + CLOCK_SET_MUX(kCLOCK_PeriphMux, 0); // PERIPH_CLK mux to PRE_PERIPH_CLK + break; + case LPM_PowerModeLowSpeedRun: + case LPM_PowerModeSysIdle: + CLOCK_SET_DIV(kCLOCK_SemcDiv, 3); // SEMC CLK should not exceed 166MHz + CLOCK_SET_DIV(kCLOCK_FlexspiDiv, 1); // FLEXSPI in DDR mode + CLOCK_SET_MUX(kCLOCK_FlexspiMux, 2); // FLEXSPI mux to PLL2 PFD2 + /* CORE CLK to 132MHz and AHB, IPG, PERCLK to 33MHz */ + CLOCK_SET_DIV(kCLOCK_PerclkDiv, 0); + CLOCK_SET_DIV(kCLOCK_IpgDiv, 3); + CLOCK_SET_DIV(kCLOCK_AhbDiv, 3); + CLOCK_SET_MUX(kCLOCK_PerclkMux, 0); // PERCLK mux to IPG CLK + CLOCK_SET_MUX(kCLOCK_PrePeriphMux, 0); // Switch PRE_PERIPH_CLK to SYS PLL + CLOCK_SET_MUX(kCLOCK_PeriphMux, 0); // Switch PERIPH_CLK to PRE_PERIPH_CLK + break; + case LPM_PowerModeLowPowerRun: + case LPM_PowerModeLPIdle: + CLOCK_SET_DIV(kCLOCK_PeriphClk2Div, 0); + CLOCK_SET_MUX(kCLOCK_PeriphClk2Mux, 1); // PERIPH_CLK2 mux to OSC + CLOCK_SET_MUX(kCLOCK_PeriphMux, 1); // PERIPH_CLK mux to PERIPH_CLK2 + CLOCK_SET_DIV(kCLOCK_SemcDiv, 0); + CLOCK_SET_MUX(kCLOCK_SemcMux, 0); // SEMC mux to PERIPH_CLK + CLOCK_SET_DIV(kCLOCK_FlexspiDiv, 0); // FLEXSPI in DDR mode + CLOCK_SET_MUX(kCLOCK_FlexspiMux, 0); // FLEXSPI mux to semc_clk_root_pre + /* CORE CLK to 24MHz and AHB, IPG, PERCLK to 12MHz */ + //CLOCK_SET_DIV(kCLOCK_PerclkDiv, 0); + CLOCK_SET_DIV(kCLOCK_IpgDiv, 1); + CLOCK_SET_DIV(kCLOCK_AhbDiv, 0); + //CLOCK_SET_MUX(kCLOCK_PerclkMux, 0); // PERCLK mux to IPG CLK + break; + default: + break; + } + +#if (defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1)) + /* Enable clock gate of flexspi. */ + CCM->CCGR6 |= (CCM_CCGR6_CG5_MASK); + + if ((LPM_PowerModeLowPowerRun == power_mode) || (LPM_PowerModeLPIdle == power_mode)) + { + FLEXSPI_INST->DLLCR[0] = FLEXSPI_DLLCR_OVRDEN(1) | FLEXSPI_DLLCR_OVRDVAL(19); + } + else + { + FLEXSPI_INST->DLLCR[0] = FLEXSPI_DLLCR_DLLEN(1) | FLEXSPI_DLLCR_SLVDLYTARGET(15); + } + + FLEXSPI_INST->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; + FLEXSPI_INST->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK; + while (FLEXSPI_INST->MCR0 & FLEXSPI_MCR0_SWRESET_MASK) + { + } + while (!((FLEXSPI_INST->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (FLEXSPI_INST->STS0 & FLEXSPI_STS0_SEQIDLE_MASK))) + { + } +#endif +} + +void ClockSetToOverDriveRun(void) +{ + // CORE CLK mux to 24M before reconfigure PLLs + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeLowPowerRun); + LPM_ExitCritical(); + ClockSelectXtalOsc(); + + /* Init ARM PLL */ + CLOCK_SetDiv(kCLOCK_ArmDiv, 1); + CLOCK_InitArmPll(&armPllConfig_PowerMode); + + /* Init SYS PLL*/ + CLOCK_InitSysPll(&sysPllConfig_PowerMode); + /* Init System pfd0. */ + CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); + /* Init System pfd1. */ + CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); + /* Init System pfd2. */ + CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); + /* Init System pfd3. */ + CLOCK_InitSysPfd(kCLOCK_Pfd3, 16); + + /* Init USB1 PLL. */ + CLOCK_InitUsb1Pll(&usb1PllConfig_PowerMode); + /* Init Usb1 pfd0. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33); + /* Init Usb1 pfd1. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); + /* Init Usb1 pfd2. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); + /* Init Usb1 pfd3. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19); + /* Disable Usb1 PLL output for USBPHY1. */ + CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; + + /* Init USB2 PLL*/ + CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_BYPASS_MASK; + CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_ENABLE_MASK; + CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_POWER_MASK; + while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0) + { + } + CCM_ANALOG->PLL_USB2_CLR = CCM_ANALOG_PLL_USB2_BYPASS_MASK; + + /* Init AUDIO PLL */ + CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; + CCM_ANALOG->PLL_AUDIO_CLR = CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK; + CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; + while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0) + { + } + CCM_ANALOG->PLL_AUDIO_CLR = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; + + /* Init VIDEO PLL */ + CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; + CCM_ANALOG->PLL_VIDEO_CLR = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK; + CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_ENABLE_MASK; + while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0) + { + } + CCM_ANALOG->PLL_VIDEO_CLR = CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; + + /* Init ENET PLL */ + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_BYPASS_MASK; + CCM_ANALOG->PLL_ENET_CLR = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK; + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_ENABLE_MASK; + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; + while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0) + { + } + CCM_ANALOG->PLL_ENET_CLR = CCM_ANALOG_PLL_ENET_BYPASS_MASK; + + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeOverRun); + LPM_ExitCritical(); +} + +void ClockSetToFullSpeedRun(void) +{ + // CORE CLK mux to 24M before reconfigure PLLs + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeLowPowerRun); + LPM_ExitCritical(); + ClockSelectXtalOsc(); + + /* Init ARM PLL */ + CLOCK_SetDiv(kCLOCK_ArmDiv, 1); + CLOCK_InitArmPll(&armPllConfig_PowerMode); + + /* Init SYS PLL. */ + CLOCK_InitSysPll(&sysPllConfig_PowerMode); + /* Init System pfd0. */ + CLOCK_InitSysPfd(kCLOCK_Pfd0, 27); + /* Init System pfd1. */ + CLOCK_InitSysPfd(kCLOCK_Pfd1, 16); + /* Init System pfd2. */ + CLOCK_InitSysPfd(kCLOCK_Pfd2, 24); + /* Init System pfd3. */ + CLOCK_InitSysPfd(kCLOCK_Pfd3, 16); + + /* Init USB1 PLL. */ + CLOCK_InitUsb1Pll(&usb1PllConfig_PowerMode); + /* Init Usb1 pfd0. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33); + /* Init Usb1 pfd1. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16); + /* Init Usb1 pfd2. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17); + /* Init Usb1 pfd3. */ + CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19); + /* Disable Usb1 PLL output for USBPHY1. */ + CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; + + /* Init USB2 PLL*/ + CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_BYPASS_MASK; + CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_ENABLE_MASK; + CCM_ANALOG->PLL_USB2_SET = CCM_ANALOG_PLL_USB2_POWER_MASK; + while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0) + { + } + CCM_ANALOG->PLL_USB2_CLR = CCM_ANALOG_PLL_USB2_BYPASS_MASK; + + /* Init AUDIO PLL */ + CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; + CCM_ANALOG->PLL_AUDIO_CLR = CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK; + CCM_ANALOG->PLL_AUDIO_SET = CCM_ANALOG_PLL_AUDIO_ENABLE_MASK; + while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0) + { + } + CCM_ANALOG->PLL_AUDIO_CLR = CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; + + /* Init VIDEO PLL */ + CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; + CCM_ANALOG->PLL_VIDEO_CLR = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK; + CCM_ANALOG->PLL_VIDEO_SET = CCM_ANALOG_PLL_VIDEO_ENABLE_MASK; + while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0) + { + } + CCM_ANALOG->PLL_VIDEO_CLR = CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; + + /* Init ENET PLL */ + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_BYPASS_MASK; + CCM_ANALOG->PLL_ENET_CLR = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK; + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_ENABLE_MASK; + CCM_ANALOG->PLL_ENET_SET = CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; + while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0) + { + } + CCM_ANALOG->PLL_ENET_CLR = CCM_ANALOG_PLL_ENET_BYPASS_MASK; + + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeFullRun); + LPM_ExitCritical(); +} + +void ClockSetToLowSpeedRun(void) +{ + // CORE CLK mux to 24M before reconfigure PLLs + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeLowPowerRun); + LPM_ExitCritical(); + ClockSelectXtalOsc(); + + /* Deinit ARM PLL */ + CLOCK_DeinitArmPll(); + + /* Init SYS PLL */ + CLOCK_InitSysPll(&sysPllConfig_PowerMode); + + /* Deinit SYS PLL PFD 0 1 3 */ + CLOCK_DeinitSysPfd(kCLOCK_Pfd0); + CLOCK_DeinitSysPfd(kCLOCK_Pfd1); + /* Init System pfd2. */ + CLOCK_InitSysPfd(kCLOCK_Pfd2, 18); + CLOCK_DeinitSysPfd(kCLOCK_Pfd3); + + /* Deinit USB1 PLL */ + CLOCK_DeinitUsb1Pll(); + + /* Deinit USB1 PLL PFD 0 1 2 3 */ + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd0); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd1); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd2); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd3); + + /* Deinit USB2 PLL */ + CLOCK_DeinitUsb2Pll(); + + /* Deinit AUDIO PLL */ + CLOCK_DeinitAudioPll(); + + /* Deinit VIDEO PLL */ + CLOCK_DeinitVideoPll(); + + /* Deinit ENET PLL */ + CLOCK_DeinitEnetPll(); + + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeLowSpeedRun); + LPM_ExitCritical(); +} + +void ClockSetToLowPowerRun(void) +{ + // CORE CLK mux to 24M before reconfigure PLLs + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeLowPowerRun); + LPM_ExitCritical(); + ClockSelectRcOsc(); + + /* Deinit ARM PLL */ + CLOCK_DeinitArmPll(); + + /* Deinit SYS PLL */ + CLOCK_DeinitSysPll(); + + /* Deinit SYS PLL PFD 0 1 2 3 */ + CLOCK_DeinitSysPfd(kCLOCK_Pfd0); + CLOCK_DeinitSysPfd(kCLOCK_Pfd1); + CLOCK_DeinitSysPfd(kCLOCK_Pfd2); + CLOCK_DeinitSysPfd(kCLOCK_Pfd3); + + /* Power Down USB1 PLL */ + CCM_ANALOG->PLL_USB1_SET = CCM_ANALOG_PLL_USB1_BYPASS_MASK; + CCM_ANALOG->PLL_USB1_CLR = CCM_ANALOG_PLL_USB1_POWER_MASK; + CCM_ANALOG->PLL_USB1_CLR = CCM_ANALOG_PLL_USB1_ENABLE_MASK; + + /* Deinit USB1 PLL PFD 0 1 2 3 */ + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd0); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd1); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd2); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd3); + + /* Deinit USB2 PLL */ + CLOCK_DeinitUsb2Pll(); + + /* Deinit AUDIO PLL */ + CLOCK_DeinitAudioPll(); + + /* Deinit VIDEO PLL */ + CLOCK_DeinitVideoPll(); + + /* Deinit ENET PLL */ + CLOCK_DeinitEnetPll(); +} + +void ClockSetToSystemIdle(void) +{ + // CORE CLK mux to 24M before reconfigure PLLs + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeLowPowerRun); + LPM_ExitCritical(); + ClockSelectXtalOsc(); + + /* Deinit ARM PLL */ + CLOCK_DeinitArmPll(); + + /* Init SYS PLL */ + CLOCK_InitSysPll(&sysPllConfig_PowerMode); + + /* Deinit SYS PLL PFD 0 1 3 */ + CLOCK_DeinitSysPfd(kCLOCK_Pfd0); + CLOCK_DeinitSysPfd(kCLOCK_Pfd1); + /* Init System pfd2. */ + CLOCK_InitSysPfd(kCLOCK_Pfd2, 18); + CLOCK_DeinitSysPfd(kCLOCK_Pfd3); + + /* Deinit USB1 PLL */ + CLOCK_DeinitUsb1Pll(); + + /* Deinit USB1 PLL PFD 0 1 2 3 */ + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd0); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd1); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd2); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd3); + + /* Deinit USB2 PLL */ + CLOCK_DeinitUsb2Pll(); + + /* Deinit AUDIO PLL */ + CLOCK_DeinitAudioPll(); + + /* Deinit VIDEO PLL */ + CLOCK_DeinitVideoPll(); + + /* Deinit ENET PLL */ + CLOCK_DeinitEnetPll(); + + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeSysIdle); + LPM_ExitCritical(); +} + +void ClockSetToLowPowerIdle(void) +{ + // CORE CLK mux to 24M before reconfigure PLLs + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeLowPowerRun); + LPM_ExitCritical(); + ClockSelectRcOsc(); + + /* Deinit ARM PLL */ + CLOCK_DeinitArmPll(); + + /* Deinit SYS PLL */ + CLOCK_DeinitSysPll(); + + /* Deinit SYS PLL PFD 0 1 2 3 */ + CLOCK_DeinitSysPfd(kCLOCK_Pfd0); + CLOCK_DeinitSysPfd(kCLOCK_Pfd1); + CLOCK_DeinitSysPfd(kCLOCK_Pfd2); + CLOCK_DeinitSysPfd(kCLOCK_Pfd3); + + /* Deinit USB1 PLL */ + CLOCK_DeinitUsb1Pll(); + + /* Deinit USB1 PLL PFD 0 1 2 3 */ + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd0); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd1); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd2); + CLOCK_DeinitUsb1Pfd(kCLOCK_Pfd3); + + /* Deinit USB2 PLL */ + CLOCK_DeinitUsb2Pll(); + + /* Deinit AUDIO PLL */ + CLOCK_DeinitAudioPll(); + + /* Deinit VIDEO PLL */ + CLOCK_DeinitVideoPll(); + + /* Deinit ENET PLL */ + CLOCK_DeinitEnetPll(); + + LPM_EnterCritical(); + SwitchSystemClocks(LPM_PowerModeLPIdle); + LPM_ExitCritical(); +} + +void SetLowPowerClockGate(void) +{ + /* Save of the clock gate registers */ + clock_gate_values[0] = CCM->CCGR0; + clock_gate_values[1] = CCM->CCGR1; + clock_gate_values[2] = CCM->CCGR2; + clock_gate_values[3] = CCM->CCGR3; + clock_gate_values[4] = CCM->CCGR4; + clock_gate_values[5] = CCM->CCGR5; + clock_gate_values[6] = CCM->CCGR6; + + /* Set low power gate values */ + CCM->CCGR0 = CCM_CCGR0_CG0(1) | CCM_CCGR0_CG1(1) | CCM_CCGR0_CG3(3) | CCM_CCGR0_CG11(1) | CCM_CCGR0_CG12(1); + CCM->CCGR1 = CCM_CCGR1_CG9(3) | CCM_CCGR1_CG10(1) | CCM_CCGR1_CG13(1) | CCM_CCGR1_CG14(1) | CCM_CCGR1_CG15(1); + CCM->CCGR2 = CCM_CCGR2_CG2(1) | CCM_CCGR2_CG8(1) | CCM_CCGR2_CG9(1) | CCM_CCGR2_CG10(1); + CCM->CCGR3 = CCM_CCGR3_CG2(1) | CCM_CCGR3_CG4(1) | CCM_CCGR3_CG9(1) | CCM_CCGR3_CG14(3) | CCM_CCGR3_CG15(1); + CCM->CCGR4 = + CCM_CCGR4_CG1(1) | CCM_CCGR4_CG2(1) | CCM_CCGR4_CG4(1) | CCM_CCGR4_CG5(1) | CCM_CCGR4_CG6(1) | CCM_CCGR4_CG7(1); + CCM->CCGR5 = CCM_CCGR5_CG0(1) | CCM_CCGR5_CG1(1) | CCM_CCGR5_CG4(1) | CCM_CCGR5_CG6(1) | CCM_CCGR5_CG12(1) | + CCM_CCGR5_CG14(1) | CCM_CCGR5_CG15(1); + /* We can enable DCDC when need to config it and close it after configuration */ + CCM->CCGR6 = CCM_CCGR6_CG3(1) | CCM_CCGR6_CG4(1) | CCM_CCGR6_CG5(1) | CCM_CCGR6_CG9(1) | CCM_CCGR6_CG10(1) | + CCM_CCGR6_CG11(1); +} + +void SetRestoreClockGate(void) +{ + CCM->CCGR0 = clock_gate_values[0]; + CCM->CCGR1 = clock_gate_values[1]; + CCM->CCGR2 = clock_gate_values[2]; + CCM->CCGR3 = clock_gate_values[3]; + CCM->CCGR4 = clock_gate_values[4]; + CCM->CCGR5 = clock_gate_values[5]; + CCM->CCGR6 = clock_gate_values[6]; +} + +void PowerDownUSBPHY(void) +{ + USBPHY1->CTRL = 0xFFFFFFFF; + USBPHY2->CTRL = 0xFFFFFFFF; +} + +void ConfigUartRxPinToGpio(void) +{ + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_GPIO1_IO13, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_GPIO1_IO13, + IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | IOMUXC_SW_PAD_CTL_PAD_PUS(2) | IOMUXC_SW_PAD_CTL_PAD_PUE_MASK); +} + +void ReConfigUartRxPin(void) +{ + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, 0); + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B0_13_LPUART1_RX, IOMUXC_SW_PAD_CTL_PAD_SPEED(2)); +} + +#define GPR4_STOP_REQ_BITS \ + (IOMUXC_GPR_GPR4_ENET_STOP_REQ_MASK | IOMUXC_GPR_GPR4_SAI1_STOP_REQ_MASK | IOMUXC_GPR_GPR4_SAI2_STOP_REQ_MASK | \ + IOMUXC_GPR_GPR4_SAI3_STOP_REQ_MASK | IOMUXC_GPR_GPR4_SEMC_STOP_REQ_MASK | IOMUXC_GPR_GPR4_PIT_STOP_REQ_MASK | \ + IOMUXC_GPR_GPR4_FLEXIO1_STOP_REQ_MASK | IOMUXC_GPR_GPR4_FLEXIO2_STOP_REQ_MASK) + +#define GPR4_STOP_ACK_BITS \ + (IOMUXC_GPR_GPR4_ENET_STOP_ACK_MASK | IOMUXC_GPR_GPR4_SAI1_STOP_ACK_MASK | IOMUXC_GPR_GPR4_SAI2_STOP_ACK_MASK | \ + IOMUXC_GPR_GPR4_SAI3_STOP_ACK_MASK | IOMUXC_GPR_GPR4_SEMC_STOP_ACK_MASK | IOMUXC_GPR_GPR4_PIT_STOP_ACK_MASK | \ + IOMUXC_GPR_GPR4_FLEXIO1_STOP_ACK_MASK | IOMUXC_GPR_GPR4_FLEXIO2_STOP_ACK_MASK) + +#define GPR7_STOP_REQ_BITS \ + (IOMUXC_GPR_GPR7_LPI2C1_STOP_REQ_MASK | IOMUXC_GPR_GPR7_LPI2C2_STOP_REQ_MASK | \ + IOMUXC_GPR_GPR7_LPI2C3_STOP_REQ_MASK | IOMUXC_GPR_GPR7_LPI2C4_STOP_REQ_MASK | \ + IOMUXC_GPR_GPR7_LPSPI1_STOP_REQ_MASK | IOMUXC_GPR_GPR7_LPSPI2_STOP_REQ_MASK | \ + IOMUXC_GPR_GPR7_LPSPI3_STOP_REQ_MASK | IOMUXC_GPR_GPR7_LPSPI4_STOP_REQ_MASK | \ + IOMUXC_GPR_GPR7_LPUART1_STOP_REQ_MASK | IOMUXC_GPR_GPR7_LPUART2_STOP_REQ_MASK | \ + IOMUXC_GPR_GPR7_LPUART3_STOP_REQ_MASK | IOMUXC_GPR_GPR7_LPUART4_STOP_REQ_MASK | \ + IOMUXC_GPR_GPR7_LPUART5_STOP_REQ_MASK | IOMUXC_GPR_GPR7_LPUART6_STOP_REQ_MASK | \ + IOMUXC_GPR_GPR7_LPUART7_STOP_REQ_MASK | IOMUXC_GPR_GPR7_LPUART8_STOP_REQ_MASK) + +#define GPR7_STOP_ACK_BITS \ + (IOMUXC_GPR_GPR7_LPI2C1_STOP_ACK_MASK | IOMUXC_GPR_GPR7_LPI2C2_STOP_ACK_MASK | \ + IOMUXC_GPR_GPR7_LPI2C3_STOP_ACK_MASK | IOMUXC_GPR_GPR7_LPI2C4_STOP_ACK_MASK | \ + IOMUXC_GPR_GPR7_LPSPI1_STOP_ACK_MASK | IOMUXC_GPR_GPR7_LPSPI2_STOP_ACK_MASK | \ + IOMUXC_GPR_GPR7_LPSPI3_STOP_ACK_MASK | IOMUXC_GPR_GPR7_LPSPI4_STOP_ACK_MASK | \ + IOMUXC_GPR_GPR7_LPUART1_STOP_ACK_MASK | IOMUXC_GPR_GPR7_LPUART2_STOP_ACK_MASK | \ + IOMUXC_GPR_GPR7_LPUART3_STOP_ACK_MASK | IOMUXC_GPR_GPR7_LPUART4_STOP_ACK_MASK | \ + IOMUXC_GPR_GPR7_LPUART5_STOP_ACK_MASK | IOMUXC_GPR_GPR7_LPUART6_STOP_ACK_MASK | \ + IOMUXC_GPR_GPR7_LPUART7_STOP_ACK_MASK | IOMUXC_GPR_GPR7_LPUART8_STOP_ACK_MASK) + +#define GPR8_DOZE_BITS \ + (IOMUXC_GPR_GPR8_LPI2C1_IPG_DOZE_MASK | IOMUXC_GPR_GPR8_LPI2C2_IPG_DOZE_MASK | \ + IOMUXC_GPR_GPR8_LPI2C3_IPG_DOZE_MASK | IOMUXC_GPR_GPR8_LPI2C4_IPG_DOZE_MASK | \ + IOMUXC_GPR_GPR8_LPSPI1_IPG_DOZE_MASK | IOMUXC_GPR_GPR8_LPSPI2_IPG_DOZE_MASK | \ + IOMUXC_GPR_GPR8_LPSPI3_IPG_DOZE_MASK | IOMUXC_GPR_GPR8_LPSPI4_IPG_DOZE_MASK | \ + IOMUXC_GPR_GPR8_LPUART1_IPG_DOZE_MASK | IOMUXC_GPR_GPR8_LPUART2_IPG_DOZE_MASK | \ + IOMUXC_GPR_GPR8_LPUART3_IPG_DOZE_MASK | IOMUXC_GPR_GPR8_LPUART4_IPG_DOZE_MASK | \ + IOMUXC_GPR_GPR8_LPUART5_IPG_DOZE_MASK | IOMUXC_GPR_GPR8_LPUART6_IPG_DOZE_MASK | \ + IOMUXC_GPR_GPR8_LPUART7_IPG_DOZE_MASK | IOMUXC_GPR_GPR8_LPUART8_IPG_DOZE_MASK) + +#define GPR8_STOP_MODE_BITS \ + (IOMUXC_GPR_GPR8_LPI2C1_IPG_STOP_MODE_MASK | IOMUXC_GPR_GPR8_LPI2C2_IPG_STOP_MODE_MASK | \ + IOMUXC_GPR_GPR8_LPI2C3_IPG_STOP_MODE_MASK | IOMUXC_GPR_GPR8_LPI2C4_IPG_STOP_MODE_MASK | \ + IOMUXC_GPR_GPR8_LPSPI1_IPG_STOP_MODE_MASK | IOMUXC_GPR_GPR8_LPSPI2_IPG_STOP_MODE_MASK | \ + IOMUXC_GPR_GPR8_LPSPI3_IPG_STOP_MODE_MASK | IOMUXC_GPR_GPR8_LPSPI4_IPG_STOP_MODE_MASK | \ + IOMUXC_GPR_GPR8_LPUART2_IPG_STOP_MODE_MASK | IOMUXC_GPR_GPR8_LPUART3_IPG_STOP_MODE_MASK | \ + IOMUXC_GPR_GPR8_LPUART4_IPG_STOP_MODE_MASK | IOMUXC_GPR_GPR8_LPUART5_IPG_STOP_MODE_MASK | \ + IOMUXC_GPR_GPR8_LPUART6_IPG_STOP_MODE_MASK | IOMUXC_GPR_GPR8_LPUART7_IPG_STOP_MODE_MASK | \ + IOMUXC_GPR_GPR8_LPUART8_IPG_STOP_MODE_MASK) + +#define GPR12_DOZE_BITS (IOMUXC_GPR_GPR12_FLEXIO1_IPG_DOZE_MASK | IOMUXC_GPR_GPR12_FLEXIO2_IPG_DOZE_MASK) + +#define GPR12_STOP_MODE_BITS (IOMUXC_GPR_GPR12_FLEXIO1_IPG_STOP_MODE_MASK | IOMUXC_GPR_GPR12_FLEXIO2_IPG_STOP_MODE_MASK) + +void PeripheralEnterDozeMode(void) +{ + IOMUXC_GPR->GPR8 = GPR8_DOZE_BITS; + IOMUXC_GPR->GPR12 = GPR12_DOZE_BITS; +} + +void PeripheralExitDozeMode(void) +{ + IOMUXC_GPR->GPR8 = 0x00000000; + IOMUXC_GPR->GPR12 = 0x00000000; +} + +void PeripheralEnterStopMode(void) +{ + IOMUXC_GPR->GPR4 = IOMUXC_GPR_GPR4_ENET_STOP_REQ_MASK; + while ((IOMUXC_GPR->GPR4 & IOMUXC_GPR_GPR4_ENET_STOP_ACK_MASK) != IOMUXC_GPR_GPR4_ENET_STOP_ACK_MASK) + { + } + IOMUXC_GPR->GPR4 = GPR4_STOP_REQ_BITS; + IOMUXC_GPR->GPR7 = GPR7_STOP_REQ_BITS; + IOMUXC_GPR->GPR8 = GPR8_DOZE_BITS | GPR8_STOP_MODE_BITS; + IOMUXC_GPR->GPR12 = GPR12_DOZE_BITS | GPR12_STOP_MODE_BITS; + while ((IOMUXC_GPR->GPR4 & GPR4_STOP_ACK_BITS) != GPR4_STOP_ACK_BITS) + { + } + while ((IOMUXC_GPR->GPR7 & GPR7_STOP_ACK_BITS) != GPR7_STOP_ACK_BITS) + { + } +} + diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/specific.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/specific.h new file mode 100644 index 0000000000..cc384b4fa4 --- /dev/null +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1050/TARGET_EVK/specific.h @@ -0,0 +1,49 @@ +/* + * Copyright 2018-2019 NXP + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _SPECIFIC_H_ +#define _SPECIFIC_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define FLEXSPI_INST FLEXSPI +#define HAS_WAKEUP_PIN (1) + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +void ClockSetToOverDriveRun(void); +void ClockSetToFullSpeedRun(void); +void ClockSetToLowSpeedRun(void); +void ClockSetToLowPowerRun(void); +void ClockSetToSystemIdle(void); +void ClockSetToLowPowerIdle(void); + +void SetLowPowerClockGate(void); +void SetRestoreClockGate(void); +void PowerDownUSBPHY(void); +void ConfigUartRxPinToGpio(void); +void ReConfigUartRxPin(void); +void PeripheralEnterDozeMode(void); +void PeripheralExitDozeMode(void); +void PeripheralEnterStopMode(void); +void APP_PrintRunFrequency(int32_t run_freq_only); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _SPECIFIC_H_ */