diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/hardware_init_MK64F12.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/TARGET_K64F/hardware_init_MK64F12.c similarity index 100% rename from features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/hardware_init_MK64F12.c rename to features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/TARGET_K64F/hardware_init_MK64F12.c diff --git a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/hardware_init_MK66F18.c b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/TARGET_K66F/hardware_init_MK66F18.c similarity index 98% rename from features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/hardware_init_MK66F18.c rename to features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/TARGET_K66F/hardware_init_MK66F18.c index 6ff6dc2614..222a3173ee 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/hardware_init_MK66F18.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip-eth/arch/TARGET_Freescale/TARGET_K66F/hardware_init_MK66F18.c @@ -39,7 +39,7 @@ void k66f_init_eth_hardware(void) #ifndef FEATURE_UVISOR /* Disable MPU only when uVisor is not around. */ - MPU->CESR &= ~MPU_CESR_VLD_MASK; + SYSMPU->CESR &= ~SYSMPU_CESR_VLD_MASK; #endif/*FEATURE_UVISOR*/ /* Ungate the port clock */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_clock_config.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_clock_config.c old mode 100644 new mode 100755 index 93d47c7f50..d053db788a --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_clock_config.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_clock_config.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -28,154 +28,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "fsl_common.h" -#include "fsl_smc.h" -#include "fsl_clock_config.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -/*! @brief Clock configuration structure. */ -typedef struct _clock_config -{ - mcg_config_t mcgConfig; /*!< MCG configuration. */ - sim_clock_config_t simConfig; /*!< SIM configuration. */ - osc_config_t oscConfig; /*!< OSC configuration. */ - uint32_t coreClock; /*!< core clock frequency. */ -} clock_config_t; - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -extern uint32_t SystemCoreClock; - -/* Configuration for enter VLPR mode. Core clock = 4MHz. */ -const clock_config_t g_defaultClockConfigVlpr = { - .mcgConfig = - { - .mcgMode = kMCG_ModeBLPI, /* Work in BLPI mode. */ - .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */ - .ircs = kMCG_IrcFast, /* Select IRC4M. */ - .fcrdiv = 0U, /* FCRDIV is 0.*/ - - .frdiv = 0U, - .drs = kMCG_DrsLow, /* Low frequency range */ - .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ - .oscsel = kMCG_OscselOsc, /* Select OSC */ - - .pll0Config = - { - .enableMode = 0U, /* Don't enable PLL. */ - .prdiv = 0U, - .vdiv = 0U, - }, - .pllcs = kMCG_PllClkSelPll0, - }, - .simConfig = - { - .pllFllSel = 3U, /* PLLFLLSEL select IRC48MCLK. */ - .pllFllDiv = 0U, - .pllFllFrac = 0U, - .er32kSrc = 2U, /* ERCLK32K selection, use RTC. */ - .clkdiv1 = 0x00040000U, /* SIM_CLKDIV1. */ - }, - .oscConfig = {.freq = BOARD_XTAL0_CLK_HZ, - .capLoad = 0U, - .workMode = kOSC_ModeOscLowPower, - .oscerConfig = - { - .enableMode = kOSC_ErClkEnable, -#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) - .erclkDiv = 0U, -#endif - }}, - .coreClock = 4000000U, /* Core clock frequency */ -}; - -/* Configuration for enter RUN mode. Core clock = 120MHz. */ -const clock_config_t g_defaultClockConfigRun = { - .mcgConfig = - { - .mcgMode = kMCG_ModePEE, /* Work in PEE mode. */ - .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enable. */ - .ircs = kMCG_IrcSlow, /* Select IRC32k. */ - .fcrdiv = 0U, /* FCRDIV is 0. */ - - .frdiv = 4U, - .drs = kMCG_DrsLow, /* Low frequency range */ - .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ - .oscsel = kMCG_OscselOsc, /* Select OSC */ - - .pll0Config = - { - .enableMode = 0U, .prdiv = 0x00U, .vdiv = 0x04U, - }, - .pllcs = kMCG_PllClkSelPll0, - }, - .simConfig = - { - .pllFllSel = 1U, /* PLLFLLSEL select PLL. */ - .pllFllDiv = 0U, - .pllFllFrac = 0U, - .er32kSrc = 2U, /* ERCLK32K selection, use RTC. */ - .clkdiv1 = 0x01140000U, /* SIM_CLKDIV1. */ - }, - .oscConfig = {.freq = BOARD_XTAL0_CLK_HZ, - .capLoad = 0, - .workMode = kOSC_ModeOscLowPower, - .oscerConfig = - { - .enableMode = kOSC_ErClkEnable, -#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) - .erclkDiv = 0U, -#endif - }}, - .coreClock = 120000000U, /* Core clock frequency */ -}; - -/* Configuration for HSRUN mode. Core clock = 180MHz. */ -const clock_config_t g_defaultClockConfigHsrun = { - .mcgConfig = - { - .mcgMode = kMCG_ModePEE, /* Work in PEE mode. */ - .irclkEnableMode = kMCG_IrclkEnableInStop, /* MCGIRCLK enable. */ - .ircs = kMCG_IrcSlow, /* Select IRC32k.*/ - .fcrdiv = 0U, /* FCRDIV is 0. */ - - .frdiv = 4U, - .drs = kMCG_DrsLow, /* Low frequency range. */ - .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25%. */ - .oscsel = kMCG_OscselOsc, /* Select OSC. */ - - .pll0Config = - { - .enableMode = 0U, .prdiv = 0x00U, .vdiv = 0x0EU, - }, - .pllcs = kMCG_PllClkSelPll0, - }, - .simConfig = - { - .pllFllSel = 1U, /* PLLFLLSEL select PLL. */ - .er32kSrc = 2U, /* ERCLK32K selection, use RTC. */ - .clkdiv1 = 0x02260000U, /* SIM_CLKDIV1. */ - }, - .oscConfig = {.freq = BOARD_XTAL0_CLK_HZ, - .capLoad = 0, - .workMode = kOSC_ModeOscLowPower, - .oscerConfig = - { - .enableMode = kOSC_ErClkEnable, -#if (defined(FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) && FSL_FEATURE_OSC_HAS_EXT_REF_CLOCK_DIVIDER) - .erclkDiv = 0U, -#endif - }}, - .coreClock = 180000000U, /* Core clock frequency */ -}; - -/******************************************************************************* - * Code - ******************************************************************************/ /* * How to setup clock using clock driver functions: * @@ -204,62 +56,389 @@ const clock_config_t g_defaultClockConfigHsrun = { * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. */ -void BOARD_BootClockVLPR(void) +/* TEXT BELOW IS USED AS SETTING FOR THE CLOCKS TOOL ***************************** +!!ClocksProfile +product: Clocks v1.0 +processor: MK66FN2M0xxx18 +package_id: MK66FN2M0VMD18 +mcu_data: ksdk2_0 +processor_version: 1.0.1 +board: FRDM-K66F + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE CLOCKS TOOL **/ + +#include "fsl_smc.h" +#include "fsl_clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define MCG_PLL_DISABLE 0U /*!< MCGPLLCLK disabled */ +#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ +#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ +#define SIM_OSC32KSEL_RTC32KCLK_CLK 2U /*!< OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ +#define SIM_PLLFLLSEL_IRC48MCLK_CLK 3U /*!< PLLFLL select: IRC48MCLK clock */ +#define SIM_PLLFLLSEL_MCGPLLCLK_CLK 1U /*!< PLLFLL select: MCGPLLCLK clock */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + * Code + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_SetFllExtRefDiv + * Description : Configure FLL external reference divider (FRDIV). + * Param frdiv : The value to set FRDIV. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_SetFllExtRefDiv(uint8_t frdiv) { - CLOCK_SetSimSafeDivs(); + MCG->C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); +} - CLOCK_BootToBlpiMode(g_defaultClockConfigVlpr.mcgConfig.fcrdiv, g_defaultClockConfigVlpr.mcgConfig.ircs, - g_defaultClockConfigVlpr.mcgConfig.irclkEnableMode); +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/* TEXT BELOW IS USED AS SETTING FOR THE CLOCKS TOOL ***************************** +!!Configuration +name: BOARD_BootClockHSRUN +outputs: +- {id: Bus_clock.outFreq, value: 60 MHz} +- {id: Core_clock.outFreq, value: 180 MHz, locked: true, accuracy: '0.001'} +- {id: Flash_clock.outFreq, value: 180/7 MHz} +- {id: FlexBus_clock.outFreq, value: 60 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGFFCLK.outFreq, value: 375 kHz} +- {id: MCGIRCLK.outFreq, value: 32.768 kHz} +- {id: OSCERCLK.outFreq, value: 12 MHz} +- {id: OSCERCLK_UNDIV.outFreq, value: 12 MHz} +- {id: PLLFLLCLK.outFreq, value: 180 MHz} +- {id: System_clock.outFreq, value: 180 MHz} +settings: +- {id: MCGMode, value: PEE} +- {id: powerMode, value: HSRUN} +- {id: MCG.FCRDIV.scale, value: '1', locked: true} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IREFS.sel, value: MCG.FRDIV} +- {id: MCG.PLLS.sel, value: MCG.PLLCS} +- {id: MCG.VDIV.scale, value: '30'} +- {id: MCG_C1_IRCLKEN_CFG, value: Enabled} +- {id: MCG_C1_IREFSTEN_CFG, value: Enabled} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: OSC_CR_ERCLKEN_UNDIV_CFG, value: Enabled} +- {id: RTC_CR_CLKO_CFG, value: Disabled} +- {id: SIM.LPUARTSRCSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV2.scale, value: '3', locked: true} +- {id: SIM.OUTDIV3.scale, value: '3', locked: true} +- {id: SIM.OUTDIV4.scale, value: '7', locked: true} +- {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} +- {id: SIM.RMIICLKSEL.sel, value: SIM.ENET_1588_CLK_EXT} +- {id: SIM.SDHCSRCSEL.sel, value: OSC.OSCERCLK} +- {id: SIM.TPMSRCSEL.sel, value: SIM.PLLFLLDIV} +- {id: SIM.TRACECLKSEL.sel, value: SIM.TRACEDIV} +- {id: SIM.TRACEDIV.scale, value: '2'} +- {id: SIM.USBSRCSEL.sel, value: SIM.USBDIV} +- {id: USBPHY.DIV.scale, value: '40'} +- {id: USBPHY.PFD_CLK_SEL.sel, value: USBPHY.PFD_CLK_DIV2} +- {id: USBPHY.PFD_FRAC_DIV.scale, value: '24', locked: true} +sources: +- {id: OSC.OSC.outFreq, value: 12 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE CLOCKS TOOL **/ - CLOCK_SetSimConfig(&g_defaultClockConfigVlpr.simConfig); - - SystemCoreClock = g_defaultClockConfigVlpr.coreClock; - - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); - SMC_SetPowerModeVlpr(SMC); - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) +/******************************************************************************* + * Variables for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockHSRUN = { - } -} - -void BOARD_BootClockRUN(void) -{ - CLOCK_SetSimSafeDivs(); - - CLOCK_InitOsc0(&g_defaultClockConfigRun.oscConfig); - CLOCK_SetXtal0Freq(BOARD_XTAL0_CLK_HZ); - - CLOCK_BootToPeeMode(g_defaultClockConfigRun.mcgConfig.oscsel, kMCG_PllClkSelPll0, - &g_defaultClockConfigRun.mcgConfig.pll0Config); - - CLOCK_SetInternalRefClkConfig(g_defaultClockConfigRun.mcgConfig.irclkEnableMode, - g_defaultClockConfigRun.mcgConfig.ircs, g_defaultClockConfigRun.mcgConfig.fcrdiv); - - CLOCK_SetSimConfig(&g_defaultClockConfigRun.simConfig); - - SystemCoreClock = g_defaultClockConfigRun.coreClock; -} + .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ + .irclkEnableMode = kMCG_IrclkEnable | kMCG_IrclkEnableInStop,/* MCGIRCLK enabled as well as in STOP mode */ + .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */ + .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ + .vdiv = 0xeU, /* VCO divider: multiplied by 30 */ + }, + .pllcs = kMCG_PllClkSelPll0, /* PLL0 output clock is selected */ + }; +const sim_clock_config_t simConfig_BOARD_BootClockHSRUN = + { + .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ + .pllFllDiv = 0, /* PLLFLLSEL clock divider divisor: divided by 1 */ + .pllFllFrac = 0, /* PLLFLLSEL clock divider fraction: multiplied by 1 */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x2260000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /3, OUTDIV3: /3, OUTDIV4: /7 */ + }; +const osc_config_t oscConfig_BOARD_BootClockHSRUN = + { + .freq = 12000000U, /* Oscillator frequency: 12000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + .erclkDiv = 0, /* Divider for OSCERCLK: divided by 1 */ + } + }; +/******************************************************************************* + * Code for BOARD_BootClockHSRUN configuration + ******************************************************************************/ void BOARD_BootClockHSRUN(void) { + /* Set HSRUN power mode */ SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); SMC_SetPowerModeHsrun(SMC); while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) { } - + /* Set the system clock dividers in SIM to safe value. */ CLOCK_SetSimSafeDivs(); - - CLOCK_InitOsc0(&g_defaultClockConfigHsrun.oscConfig); - CLOCK_SetXtal0Freq(BOARD_XTAL0_CLK_HZ); - - CLOCK_BootToPeeMode(g_defaultClockConfigHsrun.mcgConfig.oscsel, kMCG_PllClkSelPll0, - &g_defaultClockConfigHsrun.mcgConfig.pll0Config); - - CLOCK_SetInternalRefClkConfig(g_defaultClockConfigHsrun.mcgConfig.irclkEnableMode, - g_defaultClockConfigHsrun.mcgConfig.ircs, g_defaultClockConfigHsrun.mcgConfig.fcrdiv); - - CLOCK_SetSimConfig(&g_defaultClockConfigHsrun.simConfig); - - SystemCoreClock = g_defaultClockConfigHsrun.coreClock; + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockHSRUN); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockHSRUN.freq); + /* Configure the Internal Reference clock (MCGIRCLK). */ + CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockHSRUN.irclkEnableMode, + mcgConfig_BOARD_BootClockHSRUN.ircs, + mcgConfig_BOARD_BootClockHSRUN.fcrdiv); + /* Configure FLL external reference divider (FRDIV). */ + CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockHSRUN.frdiv); + /* Set MCG to PEE mode. */ + CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockHSRUN.oscsel, + mcgConfig_BOARD_BootClockHSRUN.pllcs, + &mcgConfig_BOARD_BootClockHSRUN.pll0Config); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockHSRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK; } + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* TEXT BELOW IS USED AS SETTING FOR THE CLOCKS TOOL ***************************** +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Bus_clock.outFreq, value: 4 MHz} +- {id: Core_clock.outFreq, value: 4 MHz} +- {id: Flash_clock.outFreq, value: 800 kHz} +- {id: FlexBus_clock.outFreq, value: 4 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGIRCLK.outFreq, value: 4 MHz} +- {id: System_clock.outFreq, value: 4 MHz} +settings: +- {id: MCGMode, value: BLPI} +- {id: powerMode, value: VLPR} +- {id: MCG.CLKS.sel, value: MCG.IRCS} +- {id: MCG.FCRDIV.scale, value: '1', locked: true} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IRCS.sel, value: MCG.FCRDIV} +- {id: MCG_C1_IRCLKEN_CFG, value: Enabled} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: RTC_CR_CLKO_CFG, value: Disabled} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV3.scale, value: '1'} +- {id: SIM.OUTDIV4.scale, value: '5'} +- {id: SIM.PLLFLLSEL.sel, value: IRC48M.IRC48MCLK} +sources: +- {id: OSC.OSC.outFreq, value: 12 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE CLOCKS TOOL **/ + +/******************************************************************************* + * Variables for BOARD_BootClockVLPR configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockVLPR = + { + .mcgMode = kMCG_ModeBLPI, /* BLPI - Bypassed Low Power Internal */ + .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCG_IrcFast, /* Fast internal reference clock selected */ + .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ + .vdiv = 0x0U, /* VCO divider: multiplied by 16 */ + }, + .pllcs = kMCG_PllClkSelPll0, /* PLL0 output clock is selected */ + }; +const sim_clock_config_t simConfig_BOARD_BootClockVLPR = + { + .pllFllSel = SIM_PLLFLLSEL_IRC48MCLK_CLK, /* PLLFLL select: IRC48MCLK clock */ + .pllFllDiv = 0, /* PLLFLLSEL clock divider divisor: divided by 1 */ + .pllFllFrac = 0, /* PLLFLLSEL clock divider fraction: multiplied by 1 */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x40000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /1, OUTDIV3: /1, OUTDIV4: /5 */ + }; +const osc_config_t oscConfig_BOARD_BootClockVLPR = + { + .freq = 12000000U, /* Oscillator frequency: 12000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = + { + .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ + .erclkDiv = 0, /* Divider for OSCERCLK: divided by 1 */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockVLPR); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockVLPR.freq); + /* Set MCG to BLPI mode. */ + CLOCK_BootToBlpiMode(mcgConfig_BOARD_BootClockVLPR.fcrdiv, + mcgConfig_BOARD_BootClockVLPR.ircs, + mcgConfig_BOARD_BootClockVLPR.irclkEnableMode); + /* Select the MCG external reference clock. */ + CLOCK_SetExternalRefClkConfig(mcgConfig_BOARD_BootClockVLPR.oscsel); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); + /* Set VLPR power mode. */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); +#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) + SMC_SetPowerModeVlpr(SMC, false); +#else + SMC_SetPowerModeVlpr(SMC); +#endif + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) + { + } + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* TEXT BELOW IS USED AS SETTING FOR THE CLOCKS TOOL ***************************** +!!Configuration +name: BOARD_BootClockRUN +outputs: +- {id: Bus_clock.outFreq, value: 60 MHz} +- {id: Core_clock.outFreq, value: 120 MHz} +- {id: Flash_clock.outFreq, value: 24 MHz} +- {id: FlexBus_clock.outFreq, value: 60 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGFFCLK.outFreq, value: 375 kHz} +- {id: MCGIRCLK.outFreq, value: 32.768 kHz} +- {id: OSCERCLK.outFreq, value: 12 MHz} +- {id: OSCERCLK_UNDIV.outFreq, value: 12 MHz} +- {id: PLLFLLCLK.outFreq, value: 120 MHz} +- {id: System_clock.outFreq, value: 120 MHz} +settings: +- {id: MCGMode, value: PEE} +- {id: MCG.FCRDIV.scale, value: '1', locked: true} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IREFS.sel, value: MCG.FRDIV} +- {id: MCG.PLLS.sel, value: MCG.PLLCS} +- {id: MCG.PRDIV.scale, value: '1', locked: true} +- {id: MCG.VDIV.scale, value: '20', locked: true} +- {id: MCG_C1_IRCLKEN_CFG, value: Enabled} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: OSC_CR_ERCLKEN_UNDIV_CFG, value: Enabled} +- {id: RTC_CR_CLKO_CFG, value: Disabled} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV1.scale, value: '1', locked: true} +- {id: SIM.OUTDIV2.scale, value: '2'} +- {id: SIM.OUTDIV4.scale, value: '5'} +- {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} +sources: +- {id: OSC.OSC.outFreq, value: 12 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE CLOCKS TOOL **/ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockRUN = + { + .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ + .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */ + .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ + .vdiv = 0x4U, /* VCO divider: multiplied by 20 */ + }, + .pllcs = kMCG_PllClkSelPll0, /* PLL0 output clock is selected */ + }; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = + { + .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ + .pllFllDiv = 0, /* PLLFLLSEL clock divider divisor: divided by 1 */ + .pllFllFrac = 0, /* PLLFLLSEL clock divider fraction: multiplied by 1 */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x1140000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /2, OUTDIV4: /5 */ + }; +const osc_config_t oscConfig_BOARD_BootClockRUN = + { + .freq = 12000000U, /* Oscillator frequency: 12000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = + { + .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + .erclkDiv = 0, /* Divider for OSCERCLK: divided by 1 */ + } + }; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); + /* Configure the Internal Reference clock (MCGIRCLK). */ + CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockRUN.irclkEnableMode, + mcgConfig_BOARD_BootClockRUN.ircs, + mcgConfig_BOARD_BootClockRUN.fcrdiv); + /* Configure FLL external reference divider (FRDIV). */ + CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); + /* Set MCG to PEE mode. */ + CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel, + mcgConfig_BOARD_BootClockRUN.pllcs, + &mcgConfig_BOARD_BootClockRUN.pll0Config); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_clock_config.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_clock_config.h old mode 100644 new mode 100755 index 0a23dd9917..1086faaa83 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_clock_config.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_clock_config.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -27,28 +27,121 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + #ifndef _CLOCK_CONFIG_H_ #define _CLOCK_CONFIG_H_ -/******************************************************************************* - * DEFINITION - ******************************************************************************/ -#define BOARD_XTAL0_CLK_HZ 12000000U -#define BOARD_XTAL32K_CLK_HZ 32768U +#include "fsl_common.h" /******************************************************************************* - * API + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 12000000U /*!< Board xtal0 frequency in Hz */ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKHSRUN_CORE_CLOCK 180000000U /*!< Core clock frequency: 180000000Hz */ + +/*! @brief MCG set for BOARD_BootClockHSRUN configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockHSRUN; +/*! @brief SIM module set for BOARD_BootClockHSRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockHSRUN; +/*! @brief OSC set for BOARD_BootClockHSRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockHSRUN; + +/******************************************************************************* + * API for BOARD_BootClockHSRUN configuration ******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif /* __cplusplus*/ -void BOARD_BootClockVLPR(void); -void BOARD_BootClockRUN(void); +/*! + * @brief This function executes configuration of clocks. + * + */ void BOARD_BootClockHSRUN(void); #if defined(__cplusplus) } #endif /* __cplusplus*/ +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 4000000U /*!< Core clock frequency: 4000000Hz */ + +/*! @brief MCG set for BOARD_BootClockVLPR configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockVLPR; +/*! @brief SIM module set for BOARD_BootClockVLPR configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; +/*! @brief OSC set for BOARD_BootClockVLPR configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockVLPR; + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 120000000U /*!< Core clock frequency: 120000000Hz */ + +/*! @brief MCG set for BOARD_BootClockRUN configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + #endif /* _CLOCK_CONFIG_H_ */ + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.c index 961a97f339..a5bef533d5 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.c @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* 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. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "fsl_phy.h" @@ -53,8 +53,10 @@ extern uint32_t ENET_GetInstance(ENET_Type *base); * Variables ******************************************************************************/ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to enet clocks for each instance. */ extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT]; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Code @@ -64,14 +66,30 @@ status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz) { uint32_t bssReg; uint32_t counter = PHY_TIMEOUT_COUNT; + uint32_t idReg = 0; status_t result = kStatus_Success; uint32_t instance = ENET_GetInstance(base); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Set SMI first. */ CLOCK_EnableClock(s_enetClock[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ ENET_SetSMI(base, srcClock_Hz, false); + /* Initialization after PHY stars to work. */ + while ((idReg != PHY_CONTROL_ID1) && (counter != 0)) + { + PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg); + counter --; + } + + if (!counter) + { + return kStatus_Fail; + } + /* Reset PHY. */ + counter = PHY_TIMEOUT_COUNT; result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK); if (result == kStatus_Success) { diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.h index bf3167fa69..9353bea798 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/MK66F18.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/MK66F18.h index 516ce8501e..a2d8eec3b9 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/MK66F18.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/MK66F18.h @@ -9,17 +9,17 @@ ** Freescale C/C++ for Embedded ARM ** GNU C Compiler ** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler ** ** Reference manual: K66P144M180SF5RMV2, Rev. 1, Mar 2015 ** Version: rev. 3.0, 2015-03-25 -** Build: b151218 +** Build: b170112 ** ** Abstract: ** CMSIS Peripheral Access Layer for MK66F18 ** -** Copyright (c) 1997 - 2015 Freescale Semiconductor, Inc. -** All rights reserved. -** +** Copyright (c) 1997 - 2016 Freescale Semiconductor, Inc. +** Copyright 2016 - 2017 NXP ** Redistribution and use in source and binary forms, with or without modification, ** are permitted provided that the following conditions are met: ** @@ -30,7 +30,7 @@ ** 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 +** 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. ** @@ -45,8 +45,8 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -** http: www.freescale.com -** mail: support@freescale.com +** http: www.nxp.com +** mail: support@nxp.com ** ** Revisions: ** - rev. 1.0 (2013-09-02) @@ -5218,7 +5218,7 @@ typedef struct { /** Array initializer of DMA peripheral base pointers */ #define DMA_BASE_PTRS { DMA0 } /** Interrupt vectors for the DMA peripheral type */ -#define DMA_CHN_IRQS { DMA0_DMA16_IRQn, DMA1_DMA17_IRQn, DMA2_DMA18_IRQn, DMA3_DMA19_IRQn, DMA4_DMA20_IRQn, DMA5_DMA21_IRQn, DMA6_DMA22_IRQn, DMA7_DMA23_IRQn, DMA8_DMA24_IRQn, DMA9_DMA25_IRQn, DMA10_DMA26_IRQn, DMA11_DMA27_IRQn, DMA12_DMA28_IRQn, DMA13_DMA29_IRQn, DMA14_DMA30_IRQn, DMA15_DMA31_IRQn, DMA0_DMA16_IRQn, DMA1_DMA17_IRQn, DMA2_DMA18_IRQn, DMA3_DMA19_IRQn, DMA4_DMA20_IRQn, DMA5_DMA21_IRQn, DMA6_DMA22_IRQn, DMA7_DMA23_IRQn, DMA8_DMA24_IRQn, DMA9_DMA25_IRQn, DMA10_DMA26_IRQn, DMA11_DMA27_IRQn, DMA12_DMA28_IRQn, DMA13_DMA29_IRQn, DMA14_DMA30_IRQn, DMA15_DMA31_IRQn } +#define DMA_CHN_IRQS { { DMA0_DMA16_IRQn, DMA1_DMA17_IRQn, DMA2_DMA18_IRQn, DMA3_DMA19_IRQn, DMA4_DMA20_IRQn, DMA5_DMA21_IRQn, DMA6_DMA22_IRQn, DMA7_DMA23_IRQn, DMA8_DMA24_IRQn, DMA9_DMA25_IRQn, DMA10_DMA26_IRQn, DMA11_DMA27_IRQn, DMA12_DMA28_IRQn, DMA13_DMA29_IRQn, DMA14_DMA30_IRQn, DMA15_DMA31_IRQn, DMA0_DMA16_IRQn, DMA1_DMA17_IRQn, DMA2_DMA18_IRQn, DMA3_DMA19_IRQn, DMA4_DMA20_IRQn, DMA5_DMA21_IRQn, DMA6_DMA22_IRQn, DMA7_DMA23_IRQn, DMA8_DMA24_IRQn, DMA9_DMA25_IRQn, DMA10_DMA26_IRQn, DMA11_DMA27_IRQn, DMA12_DMA28_IRQn, DMA13_DMA29_IRQn, DMA14_DMA30_IRQn, DMA15_DMA31_IRQn } } #define DMA_ERROR_IRQS { DMA_Error_IRQn } /*! @@ -6182,6 +6182,9 @@ typedef struct { #define ENET_Receive_IRQS { ENET_Receive_IRQn } #define ENET_Error_IRQS { ENET_Error_IRQn } #define ENET_1588_Timer_IRQS { ENET_1588_Timer_IRQn } +/* ENET Buffer Descriptor and Buffer Address Alignment. */ +#define ENET_BUFF_ALIGNMENT (16U) + /*! * @} @@ -7731,30 +7734,30 @@ typedef struct { /* GPIO - Peripheral instance base addresses */ -/** Peripheral PTA base address */ -#define PTA_BASE (0x400FF000u) -/** Peripheral PTA base pointer */ -#define PTA ((GPIO_Type *)PTA_BASE) -/** Peripheral PTB base address */ -#define PTB_BASE (0x400FF040u) -/** Peripheral PTB base pointer */ -#define PTB ((GPIO_Type *)PTB_BASE) -/** Peripheral PTC base address */ -#define PTC_BASE (0x400FF080u) -/** Peripheral PTC base pointer */ -#define PTC ((GPIO_Type *)PTC_BASE) -/** Peripheral PTD base address */ -#define PTD_BASE (0x400FF0C0u) -/** Peripheral PTD base pointer */ -#define PTD ((GPIO_Type *)PTD_BASE) -/** Peripheral PTE base address */ -#define PTE_BASE (0x400FF100u) -/** Peripheral PTE base pointer */ -#define PTE ((GPIO_Type *)PTE_BASE) +/** Peripheral GPIOA base address */ +#define GPIOA_BASE (0x400FF000u) +/** Peripheral GPIOA base pointer */ +#define GPIOA ((GPIO_Type *)GPIOA_BASE) +/** Peripheral GPIOB base address */ +#define GPIOB_BASE (0x400FF040u) +/** Peripheral GPIOB base pointer */ +#define GPIOB ((GPIO_Type *)GPIOB_BASE) +/** Peripheral GPIOC base address */ +#define GPIOC_BASE (0x400FF080u) +/** Peripheral GPIOC base pointer */ +#define GPIOC ((GPIO_Type *)GPIOC_BASE) +/** Peripheral GPIOD base address */ +#define GPIOD_BASE (0x400FF0C0u) +/** Peripheral GPIOD base pointer */ +#define GPIOD ((GPIO_Type *)GPIOD_BASE) +/** Peripheral GPIOE base address */ +#define GPIOE_BASE (0x400FF100u) +/** Peripheral GPIOE base pointer */ +#define GPIOE ((GPIO_Type *)GPIOE_BASE) /** Array initializer of GPIO peripheral base addresses */ -#define GPIO_BASE_ADDRS { PTA_BASE, PTB_BASE, PTC_BASE, PTD_BASE, PTE_BASE } +#define GPIO_BASE_ADDRS { GPIOA_BASE, GPIOB_BASE, GPIOC_BASE, GPIOD_BASE, GPIOE_BASE } /** Array initializer of GPIO peripheral base pointers */ -#define GPIO_BASE_PTRS { PTA, PTB, PTC, PTD, PTE } +#define GPIO_BASE_PTRS { GPIOA, GPIOB, GPIOC, GPIOD, GPIOE } /*! * @} @@ -9827,252 +9830,6 @@ typedef struct { */ /* end of group MCM_Peripheral_Access_Layer */ -/* ---------------------------------------------------------------------------- - -- MPU Peripheral Access Layer - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup MPU_Peripheral_Access_Layer MPU Peripheral Access Layer - * @{ - */ - -/** MPU - Register Layout Typedef */ -typedef struct { - __IO uint32_t CESR; /**< Control/Error Status Register, offset: 0x0 */ - uint8_t RESERVED_0[12]; - struct { /* offset: 0x10, array step: 0x8 */ - __I uint32_t EAR; /**< Error Address Register, slave port n, array offset: 0x10, array step: 0x8 */ - __I uint32_t EDR; /**< Error Detail Register, slave port n, array offset: 0x14, array step: 0x8 */ - } SP[5]; - uint8_t RESERVED_1[968]; - __IO uint32_t WORD[12][4]; /**< Region Descriptor n, Word 0..Region Descriptor n, Word 3, array offset: 0x400, array step: index*0x10, index2*0x4 */ - uint8_t RESERVED_2[832]; - __IO uint32_t RGDAAC[12]; /**< Region Descriptor Alternate Access Control n, array offset: 0x800, array step: 0x4 */ -} MPU_Type; - -/* ---------------------------------------------------------------------------- - -- MPU Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup MPU_Register_Masks MPU Register Masks - * @{ - */ - -/*! @name CESR - Control/Error Status Register */ -#define MPU_CESR_VLD_MASK (0x1U) -#define MPU_CESR_VLD_SHIFT (0U) -#define MPU_CESR_VLD(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_VLD_SHIFT)) & MPU_CESR_VLD_MASK) -#define MPU_CESR_NRGD_MASK (0xF00U) -#define MPU_CESR_NRGD_SHIFT (8U) -#define MPU_CESR_NRGD(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_NRGD_SHIFT)) & MPU_CESR_NRGD_MASK) -#define MPU_CESR_NSP_MASK (0xF000U) -#define MPU_CESR_NSP_SHIFT (12U) -#define MPU_CESR_NSP(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_NSP_SHIFT)) & MPU_CESR_NSP_MASK) -#define MPU_CESR_HRL_MASK (0xF0000U) -#define MPU_CESR_HRL_SHIFT (16U) -#define MPU_CESR_HRL(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_HRL_SHIFT)) & MPU_CESR_HRL_MASK) -#define MPU_CESR_SPERR_MASK (0xF8000000U) -#define MPU_CESR_SPERR_SHIFT (27U) -#define MPU_CESR_SPERR(x) (((uint32_t)(((uint32_t)(x)) << MPU_CESR_SPERR_SHIFT)) & MPU_CESR_SPERR_MASK) - -/*! @name EAR - Error Address Register, slave port n */ -#define MPU_EAR_EADDR_MASK (0xFFFFFFFFU) -#define MPU_EAR_EADDR_SHIFT (0U) -#define MPU_EAR_EADDR(x) (((uint32_t)(((uint32_t)(x)) << MPU_EAR_EADDR_SHIFT)) & MPU_EAR_EADDR_MASK) - -/* The count of MPU_EAR */ -#define MPU_EAR_COUNT (5U) - -/*! @name EDR - Error Detail Register, slave port n */ -#define MPU_EDR_ERW_MASK (0x1U) -#define MPU_EDR_ERW_SHIFT (0U) -#define MPU_EDR_ERW(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_ERW_SHIFT)) & MPU_EDR_ERW_MASK) -#define MPU_EDR_EATTR_MASK (0xEU) -#define MPU_EDR_EATTR_SHIFT (1U) -#define MPU_EDR_EATTR(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_EATTR_SHIFT)) & MPU_EDR_EATTR_MASK) -#define MPU_EDR_EMN_MASK (0xF0U) -#define MPU_EDR_EMN_SHIFT (4U) -#define MPU_EDR_EMN(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_EMN_SHIFT)) & MPU_EDR_EMN_MASK) -#define MPU_EDR_EPID_MASK (0xFF00U) -#define MPU_EDR_EPID_SHIFT (8U) -#define MPU_EDR_EPID(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_EPID_SHIFT)) & MPU_EDR_EPID_MASK) -#define MPU_EDR_EACD_MASK (0xFFFF0000U) -#define MPU_EDR_EACD_SHIFT (16U) -#define MPU_EDR_EACD(x) (((uint32_t)(((uint32_t)(x)) << MPU_EDR_EACD_SHIFT)) & MPU_EDR_EACD_MASK) - -/* The count of MPU_EDR */ -#define MPU_EDR_COUNT (5U) - -/*! @name WORD - Region Descriptor n, Word 0..Region Descriptor n, Word 3 */ -#define MPU_WORD_VLD_MASK (0x1U) -#define MPU_WORD_VLD_SHIFT (0U) -#define MPU_WORD_VLD(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_VLD_SHIFT)) & MPU_WORD_VLD_MASK) -#define MPU_WORD_M0UM_MASK (0x7U) -#define MPU_WORD_M0UM_SHIFT (0U) -#define MPU_WORD_M0UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M0UM_SHIFT)) & MPU_WORD_M0UM_MASK) -#define MPU_WORD_M0SM_MASK (0x18U) -#define MPU_WORD_M0SM_SHIFT (3U) -#define MPU_WORD_M0SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M0SM_SHIFT)) & MPU_WORD_M0SM_MASK) -#define MPU_WORD_M0PE_MASK (0x20U) -#define MPU_WORD_M0PE_SHIFT (5U) -#define MPU_WORD_M0PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M0PE_SHIFT)) & MPU_WORD_M0PE_MASK) -#define MPU_WORD_ENDADDR_MASK (0xFFFFFFE0U) -#define MPU_WORD_ENDADDR_SHIFT (5U) -#define MPU_WORD_ENDADDR(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_ENDADDR_SHIFT)) & MPU_WORD_ENDADDR_MASK) -#define MPU_WORD_SRTADDR_MASK (0xFFFFFFE0U) -#define MPU_WORD_SRTADDR_SHIFT (5U) -#define MPU_WORD_SRTADDR(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_SRTADDR_SHIFT)) & MPU_WORD_SRTADDR_MASK) -#define MPU_WORD_M1UM_MASK (0x1C0U) -#define MPU_WORD_M1UM_SHIFT (6U) -#define MPU_WORD_M1UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M1UM_SHIFT)) & MPU_WORD_M1UM_MASK) -#define MPU_WORD_M1SM_MASK (0x600U) -#define MPU_WORD_M1SM_SHIFT (9U) -#define MPU_WORD_M1SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M1SM_SHIFT)) & MPU_WORD_M1SM_MASK) -#define MPU_WORD_M1PE_MASK (0x800U) -#define MPU_WORD_M1PE_SHIFT (11U) -#define MPU_WORD_M1PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M1PE_SHIFT)) & MPU_WORD_M1PE_MASK) -#define MPU_WORD_M2UM_MASK (0x7000U) -#define MPU_WORD_M2UM_SHIFT (12U) -#define MPU_WORD_M2UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M2UM_SHIFT)) & MPU_WORD_M2UM_MASK) -#define MPU_WORD_M2SM_MASK (0x18000U) -#define MPU_WORD_M2SM_SHIFT (15U) -#define MPU_WORD_M2SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M2SM_SHIFT)) & MPU_WORD_M2SM_MASK) -#define MPU_WORD_PIDMASK_MASK (0xFF0000U) -#define MPU_WORD_PIDMASK_SHIFT (16U) -#define MPU_WORD_PIDMASK(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_PIDMASK_SHIFT)) & MPU_WORD_PIDMASK_MASK) -#define MPU_WORD_M2PE_MASK (0x20000U) -#define MPU_WORD_M2PE_SHIFT (17U) -#define MPU_WORD_M2PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M2PE_SHIFT)) & MPU_WORD_M2PE_MASK) -#define MPU_WORD_M3UM_MASK (0x1C0000U) -#define MPU_WORD_M3UM_SHIFT (18U) -#define MPU_WORD_M3UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M3UM_SHIFT)) & MPU_WORD_M3UM_MASK) -#define MPU_WORD_M3SM_MASK (0x600000U) -#define MPU_WORD_M3SM_SHIFT (21U) -#define MPU_WORD_M3SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M3SM_SHIFT)) & MPU_WORD_M3SM_MASK) -#define MPU_WORD_M3PE_MASK (0x800000U) -#define MPU_WORD_M3PE_SHIFT (23U) -#define MPU_WORD_M3PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M3PE_SHIFT)) & MPU_WORD_M3PE_MASK) -#define MPU_WORD_PID_MASK (0xFF000000U) -#define MPU_WORD_PID_SHIFT (24U) -#define MPU_WORD_PID(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_PID_SHIFT)) & MPU_WORD_PID_MASK) -#define MPU_WORD_M4WE_MASK (0x1000000U) -#define MPU_WORD_M4WE_SHIFT (24U) -#define MPU_WORD_M4WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M4WE_SHIFT)) & MPU_WORD_M4WE_MASK) -#define MPU_WORD_M4RE_MASK (0x2000000U) -#define MPU_WORD_M4RE_SHIFT (25U) -#define MPU_WORD_M4RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M4RE_SHIFT)) & MPU_WORD_M4RE_MASK) -#define MPU_WORD_M5WE_MASK (0x4000000U) -#define MPU_WORD_M5WE_SHIFT (26U) -#define MPU_WORD_M5WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M5WE_SHIFT)) & MPU_WORD_M5WE_MASK) -#define MPU_WORD_M5RE_MASK (0x8000000U) -#define MPU_WORD_M5RE_SHIFT (27U) -#define MPU_WORD_M5RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M5RE_SHIFT)) & MPU_WORD_M5RE_MASK) -#define MPU_WORD_M6WE_MASK (0x10000000U) -#define MPU_WORD_M6WE_SHIFT (28U) -#define MPU_WORD_M6WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M6WE_SHIFT)) & MPU_WORD_M6WE_MASK) -#define MPU_WORD_M6RE_MASK (0x20000000U) -#define MPU_WORD_M6RE_SHIFT (29U) -#define MPU_WORD_M6RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M6RE_SHIFT)) & MPU_WORD_M6RE_MASK) -#define MPU_WORD_M7WE_MASK (0x40000000U) -#define MPU_WORD_M7WE_SHIFT (30U) -#define MPU_WORD_M7WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M7WE_SHIFT)) & MPU_WORD_M7WE_MASK) -#define MPU_WORD_M7RE_MASK (0x80000000U) -#define MPU_WORD_M7RE_SHIFT (31U) -#define MPU_WORD_M7RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_WORD_M7RE_SHIFT)) & MPU_WORD_M7RE_MASK) - -/* The count of MPU_WORD */ -#define MPU_WORD_COUNT (12U) - -/* The count of MPU_WORD */ -#define MPU_WORD_COUNT2 (4U) - -/*! @name RGDAAC - Region Descriptor Alternate Access Control n */ -#define MPU_RGDAAC_M0UM_MASK (0x7U) -#define MPU_RGDAAC_M0UM_SHIFT (0U) -#define MPU_RGDAAC_M0UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M0UM_SHIFT)) & MPU_RGDAAC_M0UM_MASK) -#define MPU_RGDAAC_M0SM_MASK (0x18U) -#define MPU_RGDAAC_M0SM_SHIFT (3U) -#define MPU_RGDAAC_M0SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M0SM_SHIFT)) & MPU_RGDAAC_M0SM_MASK) -#define MPU_RGDAAC_M0PE_MASK (0x20U) -#define MPU_RGDAAC_M0PE_SHIFT (5U) -#define MPU_RGDAAC_M0PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M0PE_SHIFT)) & MPU_RGDAAC_M0PE_MASK) -#define MPU_RGDAAC_M1UM_MASK (0x1C0U) -#define MPU_RGDAAC_M1UM_SHIFT (6U) -#define MPU_RGDAAC_M1UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M1UM_SHIFT)) & MPU_RGDAAC_M1UM_MASK) -#define MPU_RGDAAC_M1SM_MASK (0x600U) -#define MPU_RGDAAC_M1SM_SHIFT (9U) -#define MPU_RGDAAC_M1SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M1SM_SHIFT)) & MPU_RGDAAC_M1SM_MASK) -#define MPU_RGDAAC_M1PE_MASK (0x800U) -#define MPU_RGDAAC_M1PE_SHIFT (11U) -#define MPU_RGDAAC_M1PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M1PE_SHIFT)) & MPU_RGDAAC_M1PE_MASK) -#define MPU_RGDAAC_M2UM_MASK (0x7000U) -#define MPU_RGDAAC_M2UM_SHIFT (12U) -#define MPU_RGDAAC_M2UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M2UM_SHIFT)) & MPU_RGDAAC_M2UM_MASK) -#define MPU_RGDAAC_M2SM_MASK (0x18000U) -#define MPU_RGDAAC_M2SM_SHIFT (15U) -#define MPU_RGDAAC_M2SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M2SM_SHIFT)) & MPU_RGDAAC_M2SM_MASK) -#define MPU_RGDAAC_M2PE_MASK (0x20000U) -#define MPU_RGDAAC_M2PE_SHIFT (17U) -#define MPU_RGDAAC_M2PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M2PE_SHIFT)) & MPU_RGDAAC_M2PE_MASK) -#define MPU_RGDAAC_M3UM_MASK (0x1C0000U) -#define MPU_RGDAAC_M3UM_SHIFT (18U) -#define MPU_RGDAAC_M3UM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M3UM_SHIFT)) & MPU_RGDAAC_M3UM_MASK) -#define MPU_RGDAAC_M3SM_MASK (0x600000U) -#define MPU_RGDAAC_M3SM_SHIFT (21U) -#define MPU_RGDAAC_M3SM(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M3SM_SHIFT)) & MPU_RGDAAC_M3SM_MASK) -#define MPU_RGDAAC_M3PE_MASK (0x800000U) -#define MPU_RGDAAC_M3PE_SHIFT (23U) -#define MPU_RGDAAC_M3PE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M3PE_SHIFT)) & MPU_RGDAAC_M3PE_MASK) -#define MPU_RGDAAC_M4WE_MASK (0x1000000U) -#define MPU_RGDAAC_M4WE_SHIFT (24U) -#define MPU_RGDAAC_M4WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M4WE_SHIFT)) & MPU_RGDAAC_M4WE_MASK) -#define MPU_RGDAAC_M4RE_MASK (0x2000000U) -#define MPU_RGDAAC_M4RE_SHIFT (25U) -#define MPU_RGDAAC_M4RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M4RE_SHIFT)) & MPU_RGDAAC_M4RE_MASK) -#define MPU_RGDAAC_M5WE_MASK (0x4000000U) -#define MPU_RGDAAC_M5WE_SHIFT (26U) -#define MPU_RGDAAC_M5WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M5WE_SHIFT)) & MPU_RGDAAC_M5WE_MASK) -#define MPU_RGDAAC_M5RE_MASK (0x8000000U) -#define MPU_RGDAAC_M5RE_SHIFT (27U) -#define MPU_RGDAAC_M5RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M5RE_SHIFT)) & MPU_RGDAAC_M5RE_MASK) -#define MPU_RGDAAC_M6WE_MASK (0x10000000U) -#define MPU_RGDAAC_M6WE_SHIFT (28U) -#define MPU_RGDAAC_M6WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M6WE_SHIFT)) & MPU_RGDAAC_M6WE_MASK) -#define MPU_RGDAAC_M6RE_MASK (0x20000000U) -#define MPU_RGDAAC_M6RE_SHIFT (29U) -#define MPU_RGDAAC_M6RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M6RE_SHIFT)) & MPU_RGDAAC_M6RE_MASK) -#define MPU_RGDAAC_M7WE_MASK (0x40000000U) -#define MPU_RGDAAC_M7WE_SHIFT (30U) -#define MPU_RGDAAC_M7WE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M7WE_SHIFT)) & MPU_RGDAAC_M7WE_MASK) -#define MPU_RGDAAC_M7RE_MASK (0x80000000U) -#define MPU_RGDAAC_M7RE_SHIFT (31U) -#define MPU_RGDAAC_M7RE(x) (((uint32_t)(((uint32_t)(x)) << MPU_RGDAAC_M7RE_SHIFT)) & MPU_RGDAAC_M7RE_MASK) - -/* The count of MPU_RGDAAC */ -#define MPU_RGDAAC_COUNT (12U) - - -/*! - * @} - */ /* end of group MPU_Register_Masks */ - - -/* MPU - Peripheral instance base addresses */ -/** Peripheral MPU base address */ -#define MPU_BASE (0x4000D000u) -/** Peripheral MPU base pointer */ -#define MPU ((MPU_Type *)MPU_BASE) -/** Array initializer of MPU peripheral base addresses */ -#define MPU_BASE_ADDRS { MPU_BASE } -/** Array initializer of MPU peripheral base pointers */ -#define MPU_BASE_PTRS { MPU } - -/*! - * @} - */ /* end of group MPU_Peripheral_Access_Layer */ - - /* ---------------------------------------------------------------------------- -- NV Peripheral Access Layer ---------------------------------------------------------------------------- */ @@ -10590,7 +10347,7 @@ typedef struct { /** Array initializer of PIT peripheral base pointers */ #define PIT_BASE_PTRS { PIT } /** Interrupt vectors for the PIT peripheral type */ -#define PIT_IRQS { PIT0_IRQn, PIT1_IRQn, PIT2_IRQn, PIT3_IRQn } +#define PIT_IRQS { { PIT0_IRQn, PIT1_IRQn, PIT2_IRQn, PIT3_IRQn } } /*! * @} @@ -13236,6 +12993,252 @@ typedef struct { */ /* end of group SPI_Peripheral_Access_Layer */ +/* ---------------------------------------------------------------------------- + -- SYSMPU Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSMPU_Peripheral_Access_Layer SYSMPU Peripheral Access Layer + * @{ + */ + +/** SYSMPU - Register Layout Typedef */ +typedef struct { + __IO uint32_t CESR; /**< Control/Error Status Register, offset: 0x0 */ + uint8_t RESERVED_0[12]; + struct { /* offset: 0x10, array step: 0x8 */ + __I uint32_t EAR; /**< Error Address Register, slave port n, array offset: 0x10, array step: 0x8 */ + __I uint32_t EDR; /**< Error Detail Register, slave port n, array offset: 0x14, array step: 0x8 */ + } SP[5]; + uint8_t RESERVED_1[968]; + __IO uint32_t WORD[12][4]; /**< Region Descriptor n, Word 0..Region Descriptor n, Word 3, array offset: 0x400, array step: index*0x10, index2*0x4 */ + uint8_t RESERVED_2[832]; + __IO uint32_t RGDAAC[12]; /**< Region Descriptor Alternate Access Control n, array offset: 0x800, array step: 0x4 */ +} SYSMPU_Type; + +/* ---------------------------------------------------------------------------- + -- SYSMPU Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSMPU_Register_Masks SYSMPU Register Masks + * @{ + */ + +/*! @name CESR - Control/Error Status Register */ +#define SYSMPU_CESR_VLD_MASK (0x1U) +#define SYSMPU_CESR_VLD_SHIFT (0U) +#define SYSMPU_CESR_VLD(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_VLD_SHIFT)) & SYSMPU_CESR_VLD_MASK) +#define SYSMPU_CESR_NRGD_MASK (0xF00U) +#define SYSMPU_CESR_NRGD_SHIFT (8U) +#define SYSMPU_CESR_NRGD(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_NRGD_SHIFT)) & SYSMPU_CESR_NRGD_MASK) +#define SYSMPU_CESR_NSP_MASK (0xF000U) +#define SYSMPU_CESR_NSP_SHIFT (12U) +#define SYSMPU_CESR_NSP(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_NSP_SHIFT)) & SYSMPU_CESR_NSP_MASK) +#define SYSMPU_CESR_HRL_MASK (0xF0000U) +#define SYSMPU_CESR_HRL_SHIFT (16U) +#define SYSMPU_CESR_HRL(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_HRL_SHIFT)) & SYSMPU_CESR_HRL_MASK) +#define SYSMPU_CESR_SPERR_MASK (0xF8000000U) +#define SYSMPU_CESR_SPERR_SHIFT (27U) +#define SYSMPU_CESR_SPERR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_CESR_SPERR_SHIFT)) & SYSMPU_CESR_SPERR_MASK) + +/*! @name EAR - Error Address Register, slave port n */ +#define SYSMPU_EAR_EADDR_MASK (0xFFFFFFFFU) +#define SYSMPU_EAR_EADDR_SHIFT (0U) +#define SYSMPU_EAR_EADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EAR_EADDR_SHIFT)) & SYSMPU_EAR_EADDR_MASK) + +/* The count of SYSMPU_EAR */ +#define SYSMPU_EAR_COUNT (5U) + +/*! @name EDR - Error Detail Register, slave port n */ +#define SYSMPU_EDR_ERW_MASK (0x1U) +#define SYSMPU_EDR_ERW_SHIFT (0U) +#define SYSMPU_EDR_ERW(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_ERW_SHIFT)) & SYSMPU_EDR_ERW_MASK) +#define SYSMPU_EDR_EATTR_MASK (0xEU) +#define SYSMPU_EDR_EATTR_SHIFT (1U) +#define SYSMPU_EDR_EATTR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_EATTR_SHIFT)) & SYSMPU_EDR_EATTR_MASK) +#define SYSMPU_EDR_EMN_MASK (0xF0U) +#define SYSMPU_EDR_EMN_SHIFT (4U) +#define SYSMPU_EDR_EMN(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_EMN_SHIFT)) & SYSMPU_EDR_EMN_MASK) +#define SYSMPU_EDR_EPID_MASK (0xFF00U) +#define SYSMPU_EDR_EPID_SHIFT (8U) +#define SYSMPU_EDR_EPID(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_EPID_SHIFT)) & SYSMPU_EDR_EPID_MASK) +#define SYSMPU_EDR_EACD_MASK (0xFFFF0000U) +#define SYSMPU_EDR_EACD_SHIFT (16U) +#define SYSMPU_EDR_EACD(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_EDR_EACD_SHIFT)) & SYSMPU_EDR_EACD_MASK) + +/* The count of SYSMPU_EDR */ +#define SYSMPU_EDR_COUNT (5U) + +/*! @name WORD - Region Descriptor n, Word 0..Region Descriptor n, Word 3 */ +#define SYSMPU_WORD_VLD_MASK (0x1U) +#define SYSMPU_WORD_VLD_SHIFT (0U) +#define SYSMPU_WORD_VLD(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_VLD_SHIFT)) & SYSMPU_WORD_VLD_MASK) +#define SYSMPU_WORD_M0UM_MASK (0x7U) +#define SYSMPU_WORD_M0UM_SHIFT (0U) +#define SYSMPU_WORD_M0UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M0UM_SHIFT)) & SYSMPU_WORD_M0UM_MASK) +#define SYSMPU_WORD_M0SM_MASK (0x18U) +#define SYSMPU_WORD_M0SM_SHIFT (3U) +#define SYSMPU_WORD_M0SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M0SM_SHIFT)) & SYSMPU_WORD_M0SM_MASK) +#define SYSMPU_WORD_M0PE_MASK (0x20U) +#define SYSMPU_WORD_M0PE_SHIFT (5U) +#define SYSMPU_WORD_M0PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M0PE_SHIFT)) & SYSMPU_WORD_M0PE_MASK) +#define SYSMPU_WORD_ENDADDR_MASK (0xFFFFFFE0U) +#define SYSMPU_WORD_ENDADDR_SHIFT (5U) +#define SYSMPU_WORD_ENDADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_ENDADDR_SHIFT)) & SYSMPU_WORD_ENDADDR_MASK) +#define SYSMPU_WORD_SRTADDR_MASK (0xFFFFFFE0U) +#define SYSMPU_WORD_SRTADDR_SHIFT (5U) +#define SYSMPU_WORD_SRTADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_SRTADDR_SHIFT)) & SYSMPU_WORD_SRTADDR_MASK) +#define SYSMPU_WORD_M1UM_MASK (0x1C0U) +#define SYSMPU_WORD_M1UM_SHIFT (6U) +#define SYSMPU_WORD_M1UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M1UM_SHIFT)) & SYSMPU_WORD_M1UM_MASK) +#define SYSMPU_WORD_M1SM_MASK (0x600U) +#define SYSMPU_WORD_M1SM_SHIFT (9U) +#define SYSMPU_WORD_M1SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M1SM_SHIFT)) & SYSMPU_WORD_M1SM_MASK) +#define SYSMPU_WORD_M1PE_MASK (0x800U) +#define SYSMPU_WORD_M1PE_SHIFT (11U) +#define SYSMPU_WORD_M1PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M1PE_SHIFT)) & SYSMPU_WORD_M1PE_MASK) +#define SYSMPU_WORD_M2UM_MASK (0x7000U) +#define SYSMPU_WORD_M2UM_SHIFT (12U) +#define SYSMPU_WORD_M2UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M2UM_SHIFT)) & SYSMPU_WORD_M2UM_MASK) +#define SYSMPU_WORD_M2SM_MASK (0x18000U) +#define SYSMPU_WORD_M2SM_SHIFT (15U) +#define SYSMPU_WORD_M2SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M2SM_SHIFT)) & SYSMPU_WORD_M2SM_MASK) +#define SYSMPU_WORD_PIDMASK_MASK (0xFF0000U) +#define SYSMPU_WORD_PIDMASK_SHIFT (16U) +#define SYSMPU_WORD_PIDMASK(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_PIDMASK_SHIFT)) & SYSMPU_WORD_PIDMASK_MASK) +#define SYSMPU_WORD_M2PE_MASK (0x20000U) +#define SYSMPU_WORD_M2PE_SHIFT (17U) +#define SYSMPU_WORD_M2PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M2PE_SHIFT)) & SYSMPU_WORD_M2PE_MASK) +#define SYSMPU_WORD_M3UM_MASK (0x1C0000U) +#define SYSMPU_WORD_M3UM_SHIFT (18U) +#define SYSMPU_WORD_M3UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M3UM_SHIFT)) & SYSMPU_WORD_M3UM_MASK) +#define SYSMPU_WORD_M3SM_MASK (0x600000U) +#define SYSMPU_WORD_M3SM_SHIFT (21U) +#define SYSMPU_WORD_M3SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M3SM_SHIFT)) & SYSMPU_WORD_M3SM_MASK) +#define SYSMPU_WORD_M3PE_MASK (0x800000U) +#define SYSMPU_WORD_M3PE_SHIFT (23U) +#define SYSMPU_WORD_M3PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M3PE_SHIFT)) & SYSMPU_WORD_M3PE_MASK) +#define SYSMPU_WORD_PID_MASK (0xFF000000U) +#define SYSMPU_WORD_PID_SHIFT (24U) +#define SYSMPU_WORD_PID(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_PID_SHIFT)) & SYSMPU_WORD_PID_MASK) +#define SYSMPU_WORD_M4WE_MASK (0x1000000U) +#define SYSMPU_WORD_M4WE_SHIFT (24U) +#define SYSMPU_WORD_M4WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M4WE_SHIFT)) & SYSMPU_WORD_M4WE_MASK) +#define SYSMPU_WORD_M4RE_MASK (0x2000000U) +#define SYSMPU_WORD_M4RE_SHIFT (25U) +#define SYSMPU_WORD_M4RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M4RE_SHIFT)) & SYSMPU_WORD_M4RE_MASK) +#define SYSMPU_WORD_M5WE_MASK (0x4000000U) +#define SYSMPU_WORD_M5WE_SHIFT (26U) +#define SYSMPU_WORD_M5WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M5WE_SHIFT)) & SYSMPU_WORD_M5WE_MASK) +#define SYSMPU_WORD_M5RE_MASK (0x8000000U) +#define SYSMPU_WORD_M5RE_SHIFT (27U) +#define SYSMPU_WORD_M5RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M5RE_SHIFT)) & SYSMPU_WORD_M5RE_MASK) +#define SYSMPU_WORD_M6WE_MASK (0x10000000U) +#define SYSMPU_WORD_M6WE_SHIFT (28U) +#define SYSMPU_WORD_M6WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M6WE_SHIFT)) & SYSMPU_WORD_M6WE_MASK) +#define SYSMPU_WORD_M6RE_MASK (0x20000000U) +#define SYSMPU_WORD_M6RE_SHIFT (29U) +#define SYSMPU_WORD_M6RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M6RE_SHIFT)) & SYSMPU_WORD_M6RE_MASK) +#define SYSMPU_WORD_M7WE_MASK (0x40000000U) +#define SYSMPU_WORD_M7WE_SHIFT (30U) +#define SYSMPU_WORD_M7WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M7WE_SHIFT)) & SYSMPU_WORD_M7WE_MASK) +#define SYSMPU_WORD_M7RE_MASK (0x80000000U) +#define SYSMPU_WORD_M7RE_SHIFT (31U) +#define SYSMPU_WORD_M7RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_WORD_M7RE_SHIFT)) & SYSMPU_WORD_M7RE_MASK) + +/* The count of SYSMPU_WORD */ +#define SYSMPU_WORD_COUNT (12U) + +/* The count of SYSMPU_WORD */ +#define SYSMPU_WORD_COUNT2 (4U) + +/*! @name RGDAAC - Region Descriptor Alternate Access Control n */ +#define SYSMPU_RGDAAC_M0UM_MASK (0x7U) +#define SYSMPU_RGDAAC_M0UM_SHIFT (0U) +#define SYSMPU_RGDAAC_M0UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M0UM_SHIFT)) & SYSMPU_RGDAAC_M0UM_MASK) +#define SYSMPU_RGDAAC_M0SM_MASK (0x18U) +#define SYSMPU_RGDAAC_M0SM_SHIFT (3U) +#define SYSMPU_RGDAAC_M0SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M0SM_SHIFT)) & SYSMPU_RGDAAC_M0SM_MASK) +#define SYSMPU_RGDAAC_M0PE_MASK (0x20U) +#define SYSMPU_RGDAAC_M0PE_SHIFT (5U) +#define SYSMPU_RGDAAC_M0PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M0PE_SHIFT)) & SYSMPU_RGDAAC_M0PE_MASK) +#define SYSMPU_RGDAAC_M1UM_MASK (0x1C0U) +#define SYSMPU_RGDAAC_M1UM_SHIFT (6U) +#define SYSMPU_RGDAAC_M1UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M1UM_SHIFT)) & SYSMPU_RGDAAC_M1UM_MASK) +#define SYSMPU_RGDAAC_M1SM_MASK (0x600U) +#define SYSMPU_RGDAAC_M1SM_SHIFT (9U) +#define SYSMPU_RGDAAC_M1SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M1SM_SHIFT)) & SYSMPU_RGDAAC_M1SM_MASK) +#define SYSMPU_RGDAAC_M1PE_MASK (0x800U) +#define SYSMPU_RGDAAC_M1PE_SHIFT (11U) +#define SYSMPU_RGDAAC_M1PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M1PE_SHIFT)) & SYSMPU_RGDAAC_M1PE_MASK) +#define SYSMPU_RGDAAC_M2UM_MASK (0x7000U) +#define SYSMPU_RGDAAC_M2UM_SHIFT (12U) +#define SYSMPU_RGDAAC_M2UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M2UM_SHIFT)) & SYSMPU_RGDAAC_M2UM_MASK) +#define SYSMPU_RGDAAC_M2SM_MASK (0x18000U) +#define SYSMPU_RGDAAC_M2SM_SHIFT (15U) +#define SYSMPU_RGDAAC_M2SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M2SM_SHIFT)) & SYSMPU_RGDAAC_M2SM_MASK) +#define SYSMPU_RGDAAC_M2PE_MASK (0x20000U) +#define SYSMPU_RGDAAC_M2PE_SHIFT (17U) +#define SYSMPU_RGDAAC_M2PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M2PE_SHIFT)) & SYSMPU_RGDAAC_M2PE_MASK) +#define SYSMPU_RGDAAC_M3UM_MASK (0x1C0000U) +#define SYSMPU_RGDAAC_M3UM_SHIFT (18U) +#define SYSMPU_RGDAAC_M3UM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M3UM_SHIFT)) & SYSMPU_RGDAAC_M3UM_MASK) +#define SYSMPU_RGDAAC_M3SM_MASK (0x600000U) +#define SYSMPU_RGDAAC_M3SM_SHIFT (21U) +#define SYSMPU_RGDAAC_M3SM(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M3SM_SHIFT)) & SYSMPU_RGDAAC_M3SM_MASK) +#define SYSMPU_RGDAAC_M3PE_MASK (0x800000U) +#define SYSMPU_RGDAAC_M3PE_SHIFT (23U) +#define SYSMPU_RGDAAC_M3PE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M3PE_SHIFT)) & SYSMPU_RGDAAC_M3PE_MASK) +#define SYSMPU_RGDAAC_M4WE_MASK (0x1000000U) +#define SYSMPU_RGDAAC_M4WE_SHIFT (24U) +#define SYSMPU_RGDAAC_M4WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M4WE_SHIFT)) & SYSMPU_RGDAAC_M4WE_MASK) +#define SYSMPU_RGDAAC_M4RE_MASK (0x2000000U) +#define SYSMPU_RGDAAC_M4RE_SHIFT (25U) +#define SYSMPU_RGDAAC_M4RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M4RE_SHIFT)) & SYSMPU_RGDAAC_M4RE_MASK) +#define SYSMPU_RGDAAC_M5WE_MASK (0x4000000U) +#define SYSMPU_RGDAAC_M5WE_SHIFT (26U) +#define SYSMPU_RGDAAC_M5WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M5WE_SHIFT)) & SYSMPU_RGDAAC_M5WE_MASK) +#define SYSMPU_RGDAAC_M5RE_MASK (0x8000000U) +#define SYSMPU_RGDAAC_M5RE_SHIFT (27U) +#define SYSMPU_RGDAAC_M5RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M5RE_SHIFT)) & SYSMPU_RGDAAC_M5RE_MASK) +#define SYSMPU_RGDAAC_M6WE_MASK (0x10000000U) +#define SYSMPU_RGDAAC_M6WE_SHIFT (28U) +#define SYSMPU_RGDAAC_M6WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M6WE_SHIFT)) & SYSMPU_RGDAAC_M6WE_MASK) +#define SYSMPU_RGDAAC_M6RE_MASK (0x20000000U) +#define SYSMPU_RGDAAC_M6RE_SHIFT (29U) +#define SYSMPU_RGDAAC_M6RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M6RE_SHIFT)) & SYSMPU_RGDAAC_M6RE_MASK) +#define SYSMPU_RGDAAC_M7WE_MASK (0x40000000U) +#define SYSMPU_RGDAAC_M7WE_SHIFT (30U) +#define SYSMPU_RGDAAC_M7WE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M7WE_SHIFT)) & SYSMPU_RGDAAC_M7WE_MASK) +#define SYSMPU_RGDAAC_M7RE_MASK (0x80000000U) +#define SYSMPU_RGDAAC_M7RE_SHIFT (31U) +#define SYSMPU_RGDAAC_M7RE(x) (((uint32_t)(((uint32_t)(x)) << SYSMPU_RGDAAC_M7RE_SHIFT)) & SYSMPU_RGDAAC_M7RE_MASK) + +/* The count of SYSMPU_RGDAAC */ +#define SYSMPU_RGDAAC_COUNT (12U) + + +/*! + * @} + */ /* end of group SYSMPU_Register_Masks */ + + +/* SYSMPU - Peripheral instance base addresses */ +/** Peripheral SYSMPU base address */ +#define SYSMPU_BASE (0x4000D000u) +/** Peripheral SYSMPU base pointer */ +#define SYSMPU ((SYSMPU_Type *)SYSMPU_BASE) +/** Array initializer of SYSMPU peripheral base addresses */ +#define SYSMPU_BASE_ADDRS { SYSMPU_BASE } +/** Array initializer of SYSMPU peripheral base pointers */ +#define SYSMPU_BASE_PTRS { SYSMPU } + +/*! + * @} + */ /* end of group SYSMPU_Peripheral_Access_Layer */ + + /* ---------------------------------------------------------------------------- -- TPM Peripheral Access Layer ---------------------------------------------------------------------------- */ @@ -17249,6 +17252,43 @@ typedef struct { */ /* end of group Peripheral_access_layer */ +/* ---------------------------------------------------------------------------- + -- Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Bit_Field_Generic_Macros Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + * @{ + */ + +#if defined(__ARMCC_VERSION) + #if (__ARMCC_VERSION >= 6010050) + #pragma clang system_header + #endif +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma system_include +#endif + +/** + * @brief Mask and left-shift a bit field value for use in a register bit range. + * @param field Name of the register bit field. + * @param value Value of the bit field. + * @return Masked and shifted value. + */ +#define NXP_VAL2FLD(field, value) (((value) << (field ## _SHIFT)) & (field ## _MASK)) +/** + * @brief Mask and right-shift a register value to extract a bit field value. + * @param field Name of the register bit field. + * @param value Value of the register. + * @return Masked and shifted bit field value. + */ +#define NXP_FLD2VAL(field, value) (((value) & (field ## _MASK)) >> (field ## _SHIFT)) + +/*! + * @} + */ /* end of group Bit_Field_Generic_Macros */ + + /* ---------------------------------------------------------------------------- -- SDK Compatibility ---------------------------------------------------------------------------- */ @@ -17498,16 +17538,16 @@ typedef struct { #define DSPI2 SPI2 #define FLEXCAN0 CAN0 #define FLEXCAN1 CAN1 -#define GPIOA_BASE PTA_BASE -#define GPIOA PTA -#define GPIOB_BASE PTB_BASE -#define GPIOB PTB -#define GPIOC_BASE PTC_BASE -#define GPIOC PTC -#define GPIOD_BASE PTD_BASE -#define GPIOD PTD -#define GPIOE_BASE PTE_BASE -#define GPIOE PTE +#define PTA_BASE GPIOA_BASE +#define PTA GPIOA +#define PTB_BASE GPIOB_BASE +#define PTB GPIOB +#define PTC_BASE GPIOC_BASE +#define PTC GPIOC +#define PTD_BASE GPIOD_BASE +#define PTD GPIOD +#define PTE_BASE GPIOE_BASE +#define PTE GPIOE #define Watchdog_IRQn WDOG_EWM_IRQn #define Watchdog_IRQHandler WDOG_EWM_IRQHandler #define LPTimer_IRQn LPTMR0_IRQn diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/MK66F18_features.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/MK66F18_features.h index 07207f3a71..19bfac7013 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/MK66F18_features.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/MK66F18_features.h @@ -1,14 +1,13 @@ /* ** ################################################################### ** Version: rev. 2.9, 2015-06-08 -** Build: b151217 +** Build: b170228 ** ** Abstract: ** Chip specific module features. ** -** Copyright (c) 2015 Freescale Semiconductor, Inc. -** All rights reserved. -** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP ** Redistribution and use in source and binary forms, with or without modification, ** are permitted provided that the following conditions are met: ** @@ -19,7 +18,7 @@ ** 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 +** 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. ** @@ -34,8 +33,8 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -** http: www.freescale.com -** mail: support@freescale.com +** http: www.nxp.com +** mail: support@nxp.com ** ** Revisions: ** - rev. 1.0 (2013-09-02) @@ -212,8 +211,8 @@ #define FSL_FEATURE_SOC_MMAU_COUNT (0) /* @brief MMDVSQ availability on the SoC. */ #define FSL_FEATURE_SOC_MMDVSQ_COUNT (0) -/* @brief MPU availability on the SoC. */ -#define FSL_FEATURE_SOC_MPU_COUNT (1) +/* @brief SYSMPU availability on the SoC. */ +#define FSL_FEATURE_SOC_SYSMPU_COUNT (1) /* @brief MSCAN availability on the SoC. */ #define FSL_FEATURE_SOC_MSCAN_COUNT (0) /* @brief MSCM availability on the SoC. */ @@ -304,6 +303,8 @@ #define FSL_FEATURE_SOC_USB_COUNT (1) /* @brief USBDCD availability on the SoC. */ #define FSL_FEATURE_SOC_USBDCD_COUNT (1) +/* @brief USBHS availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHS_COUNT (1) /* @brief USBHSDCD availability on the SoC. */ #define FSL_FEATURE_SOC_USBHSDCD_COUNT (1) /* @brief USBPHY availability on the SoC. */ @@ -376,6 +377,8 @@ #define FSL_FEATURE_FLEXCAN_HAS_BUF31TO0M (0) /* @brief Number of interrupt vectors. */ #define FSL_FEATURE_FLEXCAN_INTERRUPT_COUNT (6) +/* @brief Is affected by errata with ID 5641 (Module does not transmit a message that is enabled to be transmitted at a specific moment during the arbitration process). */ +#define FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641 (0) /* CMP module features */ @@ -437,7 +440,7 @@ #define FSL_FEATURE_DMAMUX_MODULE_CHANNEL (32) /* @brief Total number of DMA channels on all modules. */ #define FSL_FEATURE_DMAMUX_DMAMUX_CHANNELS (FSL_FEATURE_SOC_DMAMUX_COUNT * 32) -/* @brief Has the periodic trigger capability for the triggered DMA channel 0 (register bit CHCFG0[TRIG]). */ +/* @brief Has the periodic trigger capability for the triggered DMA channel (register bit CHCFG0[TRIG]). */ #define FSL_FEATURE_DMAMUX_HAS_TRIG (1) /* ENET module features */ @@ -485,6 +488,10 @@ #define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (1) /* @brief Has flash cache control in MCM module. */ #define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (0) + /* @brief Has flash cache control in MSCM module. */ + #define FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS (0) + /* @brief Has prefetch speculation control in flash, such as kv5x. */ + #define FSL_FEATURE_FLASH_PREFETCH_SPECULATION_CONTROL_IN_FLASH (0) /* @brief P-Flash start address. */ #define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000) /* @brief P-Flash block count. */ @@ -499,6 +506,8 @@ #define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (16) /* @brief P-Flash block swap feature. */ #define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (1) + /* @brief P-Flash protection region count. */ + #define FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT (32) /* @brief Has FlexNVM memory. */ #define FSL_FEATURE_FLASH_HAS_FLEX_NVM (0) /* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */ @@ -551,6 +560,10 @@ #define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (1) /* @brief Has 0x49 Erase All Blocks Unsecure command. */ #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (0) + /* @brief Has 0x4A Read 1s All Execute-only Segments command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) + /* @brief Has 0x4B Erase All Execute-only Segments command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) /* @brief Has 0x80 Program Partition command. */ #define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (0) /* @brief Has 0x81 Set FlexRAM Function command. */ @@ -662,6 +675,10 @@ #define FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS (1) /* @brief Has flash cache control in MCM module. */ #define FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS (0) + /* @brief Has flash cache control in MSCM module. */ + #define FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS (0) + /* @brief Has prefetch speculation control in flash, such as kv5x. */ + #define FSL_FEATURE_FLASH_PREFETCH_SPECULATION_CONTROL_IN_FLASH (0) /* @brief P-Flash start address. */ #define FSL_FEATURE_FLASH_PFLASH_START_ADDRESS (0x00000000) /* @brief P-Flash block count. */ @@ -676,6 +693,8 @@ #define FSL_FEATURE_FLASH_PFLASH_BLOCK_DATA_PATH_WIDTH (16) /* @brief P-Flash block swap feature. */ #define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (1) + /* @brief P-Flash protection region count. */ + #define FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT (16) /* @brief Has FlexNVM memory. */ #define FSL_FEATURE_FLASH_HAS_FLEX_NVM (1) /* @brief FlexNVM start address. (Valid only if FlexNVM is available.) */ @@ -728,6 +747,10 @@ #define FSL_FEATURE_FLASH_HAS_SWAP_CONTROL_CMD (1) /* @brief Has 0x49 Erase All Blocks Unsecure command. */ #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD (0) + /* @brief Has 0x4A Read 1s All Execute-only Segments command. */ + #define FSL_FEATURE_FLASH_HAS_READ_1S_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) + /* @brief Has 0x4B Erase All Execute-only Segments command. */ + #define FSL_FEATURE_FLASH_HAS_ERASE_ALL_EXECUTE_ONLY_SEGMENTS_CMD (0) /* @brief Has 0x80 Program Partition command. */ #define FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD (1) /* @brief Has 0x81 Set FlexRAM Function command. */ @@ -830,6 +853,8 @@ ((x) == FTM3 ? (8) : (-1))))) /* @brief Has counter reset by the selected input capture event (register bits C0SC[ICRST], C1SC[ICRST], ...). */ #define FSL_FEATURE_FTM_HAS_COUNTER_RESET_BY_CAPTURE_EVENT (0) +/* @brief Has extended deadtime value. */ +#define FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE (0) /* @brief Enable pwm output for the module. */ #define FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT (0) /* @brief Has half-cycle reload for the module. */ @@ -839,6 +864,15 @@ /* @brief Has reload initialization trigger. */ #define FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER (0) +/* GPIO module features */ + +/* @brief Has fast (single cycle) access capability via a dedicated memory region. */ +#define FSL_FEATURE_GPIO_HAS_FAST_GPIO (0) +/* @brief Has port input disable register (PIDR). */ +#define FSL_FEATURE_GPIO_HAS_INPUT_DISABLE (0) +/* @brief Has dedicated interrupt vector. */ +#define FSL_FEATURE_GPIO_HAS_PORT_INTERRUPT_VECTOR (1) + /* I2C module features */ /* @brief Has System Management Bus support (registers SMB, A2, SLTL and SLTH). */ @@ -861,6 +895,8 @@ #define FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION (1) /* @brief Has double buffering support (register S2). */ #define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFERING (0) +/* @brief Has double buffer enable. */ +#define FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE (0) /* SAI module features */ @@ -899,12 +935,14 @@ #define FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE (8) /* @brief Number of digital filters. */ #define FSL_FEATURE_LLWU_HAS_PIN_FILTER (4) -/* @brief Has MF5 register. */ +/* @brief Has MF register. */ #define FSL_FEATURE_LLWU_HAS_MF (1) /* @brief Has PF register. */ #define FSL_FEATURE_LLWU_HAS_PF (1) /* @brief Has possibility to enable reset in low leakage power mode and enable digital filter for RESET pin (register LLWU_RST). */ #define FSL_FEATURE_LLWU_HAS_RESET_ENABLE (0) +/* @brief Has no internal module wakeup flag register. */ +#define FSL_FEATURE_LLWU_HAS_NO_INTERNAL_MODULE_WAKEUP_FLAG_REG (0) /* @brief Has external pin 0 connected to LLWU device. */ #define FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN0 (1) /* @brief Index of port of external pin. */ @@ -1126,14 +1164,24 @@ /* @brief Has process identifier support. */ #define FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE (0) +/* @brief L1 ICACHE line size in byte. */ +#define FSL_FEATURE_L1ICACHE_LINESIZE_BYTE (16) +/* @brief L1 DCACHE line size in byte. */ +#define FSL_FEATURE_L1DCACHE_LINESIZE_BYTE (16) /* LPTMR module features */ /* @brief Has shared interrupt handler with another LPTMR module. */ #define FSL_FEATURE_LPTMR_HAS_SHARED_IRQ_HANDLER (0) +/* @brief Whether LPTMR counter is 32 bits width. */ +#define FSL_FEATURE_LPTMR_CNR_WIDTH_IS_32B (0) +/* @brief Has timer DMA request enable (register bit CSR[TDRE]). */ +#define FSL_FEATURE_LPTMR_HAS_CSR_TDRE (0) /* LPUART module features */ +/* @brief LPUART0 and LPUART1 has shared interrupt vector. */ +#define FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1 (0) /* @brief Has receive FIFO overflow detection (bit field CFIFO[RXOFE]). */ #define FSL_FEATURE_LPUART_HAS_IRQ_EXTENDED_FUNCTIONS (0) /* @brief Has low power features (can be enabled in wait mode via register bit C1[DOZEEN] or CTRL[DOZEEN] if the registers are 32-bit wide). */ @@ -1150,8 +1198,10 @@ #define FSL_FEATURE_LPUART_HAS_IR_SUPPORT (1) /* @brief 2 bits long stop bit is available. */ #define FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT (1) -/* @brief Maximal data width without parity bit. */ +/* @brief If 10-bit mode is supported. */ #define FSL_FEATURE_LPUART_HAS_10BIT_DATA_SUPPORT (1) +/* @brief If 7-bit mode is supported. */ +#define FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT (0) /* @brief Baud rate fine adjustment is available. */ #define FSL_FEATURE_LPUART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (0) /* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */ @@ -1184,12 +1234,14 @@ #define FSL_FEATURE_LPUART_HAS_LOCAL_OPERATION_NETWORK_SUPPORT (0) /* @brief Has 32-bit registers (BAUD, STAT, CTRL, DATA, MATCH, MODIR) instead of 8-bit (BDH, BDL, C1, S1, D, etc.). */ #define FSL_FEATURE_LPUART_HAS_32BIT_REGISTERS (1) -/* @brief Lin break detect available (has bit BDH[LBKDIE]). */ -#define FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT (0) +/* @brief Lin break detect available (has bit BAUD[LBKDIE]). */ +#define FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT (1) /* @brief UART stops in Wait mode available (has bit C1[UARTSWAI]). */ #define FSL_FEATURE_LPUART_HAS_WAIT_MODE_OPERATION (0) /* @brief Has separate DMA RX and TX requests. */ #define FSL_FEATURE_LPUART_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1) +/* @brief Has separate RX and TX interrupts. */ +#define FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ (0) /* @brief Has LPAURT_PARAM. */ #define FSL_FEATURE_LPUART_HAS_PARAM (0) /* @brief Has LPUART_VERID. */ @@ -1239,7 +1291,7 @@ #define FSL_FEATURE_MCG_USE_PLLREFSEL (0) /* @brief TBD */ #define FSL_FEATURE_MCG_USE_SYSTEM_CLOCK (0) -/* @brief Has phase-locked loop (PLL) (register C5 and bits C6[VDIV], C6[PLLS], C6[LOLIE0], S[PLLST], S[LOCK0], S[LOLS]). */ +/* @brief Has phase-locked loop (PLL) (register C5 and bits C6[VDIV], C6[PLLS], C6[LOLIE0], S[PLLST], S[LOCK0], S[LOLS0]). */ #define FSL_FEATURE_MCG_HAS_PLL (1) /* @brief Has phase-locked loop (PLL) PRDIV (register C5[PRDIV]. */ #define FSL_FEATURE_MCG_HAS_PLL_PRDIV (1) @@ -1270,29 +1322,6 @@ /* @brief Reset clock mode is BLPI. */ #define FSL_FEATURE_MCG_RESET_IS_BLPI (0) -/* MPU module features */ - -/* @brief Specifies number of descriptors available. */ -#define FSL_FEATURE_MPU_DESCRIPTOR_COUNT (12) -/* @brief Has process identifier support. */ -#define FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER (1) -/* @brief Has master 0. */ -#define FSL_FEATURE_MPU_HAS_MASTER0 (1) -/* @brief Has master 1. */ -#define FSL_FEATURE_MPU_HAS_MASTER1 (1) -/* @brief Has master 2. */ -#define FSL_FEATURE_MPU_HAS_MASTER2 (1) -/* @brief Has master 3. */ -#define FSL_FEATURE_MPU_HAS_MASTER3 (1) -/* @brief Has master 4. */ -#define FSL_FEATURE_MPU_HAS_MASTER4 (1) -/* @brief Has master 5. */ -#define FSL_FEATURE_MPU_HAS_MASTER5 (1) -/* @brief Has master 6. */ -#define FSL_FEATURE_MPU_HAS_MASTER6 (1) -/* @brief Has master 7. */ -#define FSL_FEATURE_MPU_HAS_MASTER7 (0) - /* interrupt module features */ /* @brief Lowest interrupt request number. */ @@ -1390,20 +1419,13 @@ #define FSL_FEATURE_PORT_PCR_MUX_WIDTH (3) /* @brief Has dedicated interrupt vector. */ #define FSL_FEATURE_PORT_HAS_INTERRUPT_VECTOR (1) +/* @brief Has multiple pin IRQ configuration (register GICLR and GICHR). */ +#define FSL_FEATURE_PORT_HAS_MULTIPLE_IRQ_CONFIG (0) /* @brief Defines whether PCR[IRQC] bit-field has flag states. */ #define FSL_FEATURE_PORT_HAS_IRQC_FLAG (0) /* @brief Defines whether PCR[IRQC] bit-field has trigger states. */ #define FSL_FEATURE_PORT_HAS_IRQC_TRIGGER (0) -/* GPIO module features */ - -/* @brief Has fast (single cycle) access capability via a dedicated memory region. */ -#define FSL_FEATURE_GPIO_HAS_FAST_GPIO (0) -/* @brief Has port input disable register (PIDR). */ -#define FSL_FEATURE_GPIO_HAS_INPUT_DISABLE (0) -/* @brief Has dedicated interrupt vector. */ -#define FSL_FEATURE_GPIO_HAS_PORT_INTERRUPT_VECTOR (1) - /* RCM module features */ /* @brief Has Loss-of-Lock Reset support. */ @@ -1746,6 +1768,12 @@ #define FSL_FEATURE_SMC_HAS_PARAM (0) /* @brief Has SMC_VERID. */ #define FSL_FEATURE_SMC_HAS_VERID (0) +/* @brief Has stop abort flag (register bit PMCTRL[STOPA]). */ +#define FSL_FEATURE_SMC_HAS_PMCTRL_STOPA (1) +/* @brief Has tamper reset (register bit SRS[TAMPER]). */ +#define FSL_FEATURE_SMC_HAS_SRS_TAMPER (0) +/* @brief Has security violation reset (register bit SRS[SECVIO]). */ +#define FSL_FEATURE_SMC_HAS_SRS_SECVIO (0) /* DSPI module features */ @@ -1769,6 +1797,17 @@ /* @brief Has separate DMA RX and TX requests. */ #define FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(x) (1) +/* SYSMPU module features */ + +/* @brief Specifies number of descriptors available. */ +#define FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT (12) +/* @brief Has process identifier support. */ +#define FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER (1) +/* @brief Total number of MPU slave. */ +#define FSL_FEATURE_SYSMPU_SLAVE_COUNT (5) +/* @brief Total number of MPU master. */ +#define FSL_FEATURE_SYSMPU_MASTER_COUNT (7) + /* SysTick module features */ /* @brief Systick has external reference clock. */ @@ -1796,12 +1835,20 @@ #define FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER (1) /* @brief Has external trigger selection. */ #define FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION (1) -/* @brief Has TPM_COMBINE. */ +/* @brief Has TPM_COMBINE register. */ #define FSL_FEATURE_TPM_HAS_COMBINE (1) -/* @brief Has TPM_FILTER. */ +/* @brief Whether COMBINE register has effect. */ +#define FSL_FEATURE_TPM_COMBINE_HAS_EFFECTn(x) (1) +/* @brief Has TPM_POL. */ +#define FSL_FEATURE_TPM_HAS_POL (1) +/* @brief Has TPM_FILTER register. */ #define FSL_FEATURE_TPM_HAS_FILTER (1) -/* @brief Has TPM_QDCTRL. */ +/* @brief Whether FILTER register has effect. */ +#define FSL_FEATURE_TPM_FILTER_HAS_EFFECTn(x) (1) +/* @brief Has TPM_QDCTRL register. */ #define FSL_FEATURE_TPM_HAS_QDCTRL (1) +/* @brief Whether QDCTRL register has effect. */ +#define FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(x) (1) /* TSI module features */ @@ -1828,8 +1875,8 @@ #define FSL_FEATURE_UART_HAS_IR_SUPPORT (1) /* @brief 2 bits long stop bit is available. */ #define FSL_FEATURE_UART_HAS_STOP_BIT_CONFIG_SUPPORT (1) -/* @brief Maximal data width without parity bit. */ -#define FSL_FEATURE_UART_HAS_10BIT_DATA_SUPPORT (0) +/* @brief If 10-bit mode is supported. */ +#define FSL_FEATURE_UART_HAS_10BIT_DATA_SUPPORT (1) /* @brief Baud rate fine adjustment is available. */ #define FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT (1) /* @brief Baud rate oversampling is available (has bit fields C4[OSR], C5[BOTHEDGE], C5[RESYNCDIS] or BAUD[OSR], BAUD[BOTHEDGE], BAUD[RESYNCDIS] if the registers are 32-bit wide). */ @@ -1881,6 +1928,8 @@ /* USB module features */ +/* @brief KHCI module instance count */ +#define FSL_FEATURE_USB_KHCI_COUNT (1) /* @brief HOST mode enabled */ #define FSL_FEATURE_USB_KHCI_HOST_ENABLED (1) /* @brief OTG mode enabled */ @@ -1900,6 +1949,8 @@ /* USBHS module features */ +/* @brief EHCI module instance count */ +#define FSL_FEATURE_USBHS_EHCI_COUNT (1) /* @brief Number of endpoints supported */ #define FSL_FEATURE_USBHS_ENDPT_COUNT (8) @@ -1909,7 +1960,7 @@ #define FSL_FEATURE_VREF_HAS_CHOP_OSC (1) /* @brief Has second order curvature compensation (bit SC[ICOMPEN]) */ #define FSL_FEATURE_VREF_HAS_COMPENSATION (1) -/* @brief Describes the set of SC[MODE_LV] bitfield values */ +/* @brief If high/low buffer mode supported */ #define FSL_FEATURE_VREF_MODE_LV_TYPE (1) /* @brief Module has also low reference (registers VREFL/VREFH) */ #define FSL_FEATURE_VREF_HAS_LOW_REFERENCE (0) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/MK66FN2M0xxx18.sct b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/MK66FN2M0xxx18.sct index c19ce975ff..49d7a9ae4a 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/MK66FN2M0xxx18.sct +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/MK66FN2M0xxx18.sct @@ -7,14 +7,13 @@ ** Compiler: Keil ARM C/C++ Compiler ** Reference manual: K66P144M180SF5RMV2, Rev. 1, Mar 2015 ** Version: rev. 3.0, 2015-03-25 -** Build: b160406 +** Build: b170214 ** ** Abstract: ** Linker file for the Keil ARM C/C++ Compiler ** -** Copyright (c) 2016 Freescale Semiconductor, Inc. -** All rights reserved. -** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP ** Redistribution and use in source and binary forms, with or without modification, ** are permitted provided that the following conditions are met: ** @@ -25,7 +24,7 @@ ** 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 +** 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. ** @@ -40,8 +39,8 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -** http: www.freescale.com -** mail: support@freescale.com +** http: www.nxp.com +** mail: support@nxp.com ** ** ################################################################### */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/startup_MK66F18.S b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/startup_MK66F18.S index c7b44f7b24..3782b2f0a7 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/startup_MK66F18.S +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_ARM_STD/startup_MK66F18.S @@ -4,12 +4,11 @@ ; * MK66F18 ; * @version: 3.0 ; * @date: 2015-3-25 -; * @build: b151210 +; * @build: b170112 ; * --------------------------------------------------------------------------------------- ; * -; * Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. -; * All rights reserved. -; * +; * Copyright (c) 1997 - 2016, Freescale Semiconductor, Inc. +; * Copyright 2016 - 2017 NXP ; * Redistribution and use in source and binary forms, with or without modification, ; * are permitted provided that the following conditions are met: ; * @@ -20,7 +19,7 @@ ; * 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 +; * 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. ; * @@ -483,6 +482,8 @@ Reset_Handler PROC LDR R0, =0xE000ED08 LDR R1, =__Vectors STR R1, [R0] + LDR R2, [R1] + MSR MSP, R2 LDR R0, =SystemInit BLX R0 CPSIE i ; Unmask interrupts diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/MK66FN2M0xxx18.ld b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/MK66FN2M0xxx18.ld index 4145ee2c69..0287cf769d 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/MK66FN2M0xxx18.ld +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/MK66FN2M0xxx18.ld @@ -6,14 +6,13 @@ ** Compiler: GNU C Compiler ** Reference manual: K66P144M180SF5RMV2, Rev. 1, Mar 2015 ** Version: rev. 3.0, 2015-03-25 -** Build: b151217 +** Build: b170214 ** ** Abstract: ** Linker file for the GNU C Compiler ** -** Copyright (c) 2015 Freescale Semiconductor, Inc. -** All rights reserved. -** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP ** Redistribution and use in source and binary forms, with or without modification, ** are permitted provided that the following conditions are met: ** @@ -24,7 +23,7 @@ ** 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 +** 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. ** @@ -39,8 +38,8 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -** http: www.freescale.com -** mail: support@freescale.com +** http: www.nxp.com +** mail: support@nxp.com ** ** ################################################################### */ @@ -212,7 +211,6 @@ SECTIONS text_end = ORIGIN(m_text) + LENGTH(m_text); ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") - USB_RAM_GAP = DEFINED(__usb_ram_size__) ? __usb_ram_size__ : 0x800; /* Uninitialized data section */ .bss : { @@ -222,9 +220,6 @@ SECTIONS __bss_start__ = .; *(.bss) *(.bss*) - . = ALIGN(512); - USB_RAM_START = .; - . += USB_RAM_GAP; *(COMMON) . = ALIGN(4); __bss_end__ = .; @@ -248,17 +243,6 @@ SECTIONS . += STACK_SIZE; } > m_data_2 - m_usb_bdt USB_RAM_START (NOLOAD) : - { - *(m_usb_bdt) - USB_RAM_BDT_END = .; - } - - m_usb_global USB_RAM_BDT_END (NOLOAD) : - { - *(m_usb_global) - } - /* Initializes stack on the end of block */ __StackTop = ORIGIN(m_data_2) + LENGTH(m_data_2); __StackLimit = __StackTop - STACK_SIZE; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/startup_MK66F18.S b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/startup_MK66F18.S index 5a03e0326d..ceb9bbf6c3 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/startup_MK66F18.S +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_GCC_ARM/startup_MK66F18.S @@ -4,12 +4,11 @@ /* MK66F18 */ /* @version: 3.0 */ /* @date: 2015-3-25 */ -/* @build: b151210 */ +/* @build: b170112 */ /* ---------------------------------------------------------------------------------------*/ /* */ -/* Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. */ -/* All rights reserved. */ -/* */ +/* Copyright (c) 1997 - 2016, Freescale Semiconductor, Inc. */ +/* Copyright 2016 - 2017 NXP */ /* Redistribution and use in source and binary forms, with or without modification, */ /* are permitted provided that the following conditions are met: */ /* */ @@ -20,7 +19,7 @@ /* 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 */ +/* 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. */ /* */ @@ -328,6 +327,8 @@ Reset_Handler: ldr r0, =VTOR ldr r1, =__isr_vector str r1, [r0] + ldr r2, [r1] + msr msp, r2 #ifndef __NO_SYSTEM_INIT ldr r0,=SystemInit blx r0 diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/MK66FN2M0xxx18.icf b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/MK66FN2M0xxx18.icf index fe0daadc6a..6d7fb6135e 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/MK66FN2M0xxx18.icf +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/MK66FN2M0xxx18.icf @@ -6,14 +6,13 @@ ** Compiler: IAR ANSI C/C++ Compiler for ARM ** Reference manual: K66P144M180SF5RMV2, Rev. 1, Mar 2015 ** Version: rev. 3.0, 2015-03-25 -** Build: b151009 +** Build: b170214 ** ** Abstract: ** Linker file for the IAR ANSI C/C++ Compiler for ARM ** -** Copyright (c) 2015 Freescale Semiconductor, Inc. -** All rights reserved. -** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP ** Redistribution and use in source and binary forms, with or without modification, ** are permitted provided that the following conditions are met: ** @@ -24,7 +23,7 @@ ** 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 +** 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. ** @@ -39,8 +38,8 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -** http: www.freescale.com -** mail: support@freescale.com +** http: www.nxp.com +** mail: support@nxp.com ** ** ################################################################### */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/startup_MK66F18.S b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/startup_MK66F18.S index 4a5928de9f..47036fbd89 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/startup_MK66F18.S +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/TOOLCHAIN_IAR/startup_MK66F18.S @@ -4,12 +4,11 @@ ; MK66F18 ; @version: 3.0 ; @date: 2015-3-25 -; @build: b151210 +; @build: b170112 ; --------------------------------------------------------------------------------------- ; -; Copyright (c) 1997 - 2015 , Freescale Semiconductor, Inc. -; All rights reserved. -; +; Copyright (c) 1997 - 2016, Freescale Semiconductor, Inc. +; Copyright 2016 - 2017 NXP ; Redistribution and use in source and binary forms, with or without modification, ; are permitted provided that the following conditions are met: ; @@ -20,7 +19,7 @@ ; 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 +; 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. ; @@ -355,6 +354,8 @@ Reset_Handler LDR R0, =0xE000ED08 LDR R1, =__vector_table STR R1, [R0] + LDR R2, [R1] + MSR MSP, R2 LDR R0, =SystemInit BLX R0 CPSIE I ; Unmask interrupts diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/fsl_device_registers.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/fsl_device_registers.h index f7a122fcdb..9438c67fa1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/fsl_device_registers.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/fsl_device_registers.h @@ -1,7 +1,6 @@ /* - * Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc. - * All rights reserved. - * + * Copyright (c) 2014 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016 - 2017 NXP * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * @@ -12,7 +11,7 @@ * 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 + * 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. * @@ -26,6 +25,7 @@ * 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. + * */ #ifndef __FSL_DEVICE_REGISTERS_H__ @@ -36,7 +36,7 @@ * * The CPU macro should be declared in the project or makefile. */ -#if (defined(CPU_MK66FN2M0VLQ18) || defined(CPU_MK66FX1M0VLQ18) || defined(CPU_MK66FN2M0VMD18) || \ +#if (defined(CPU_MK66FN2M0VLQ18) || defined(CPU_MK66FN2M0VMD18) || defined(CPU_MK66FX1M0VLQ18) || \ defined(CPU_MK66FX1M0VMD18)) #define K66F18_SERIES diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/system_MK66F18.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/system_MK66F18.c index 04996c713f..a0a09bbc4d 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/system_MK66F18.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/system_MK66F18.c @@ -9,19 +9,19 @@ ** Freescale C/C++ for Embedded ARM ** GNU C Compiler ** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler ** ** Reference manual: K66P144M180SF5RMV2, Rev. 1, Mar 2015 ** Version: rev. 3.0, 2015-03-25 -** Build: b151216 +** Build: b170112 ** ** Abstract: ** Provides a system configuration function and a global variable that ** contains the system frequency. It configures the device and initializes ** the oscillator (PLL) that is part of the microcontroller device. ** -** Copyright (c) 2015 Freescale Semiconductor, Inc. -** All rights reserved. -** +** Copyright (c) 2016 Freescale Semiconductor, Inc. +** Copyright 2016 - 2017 NXP ** Redistribution and use in source and binary forms, with or without modification, ** are permitted provided that the following conditions are met: ** @@ -32,7 +32,7 @@ ** 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 +** 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. ** @@ -47,8 +47,8 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -** http: www.freescale.com -** mail: support@freescale.com +** http: www.nxp.com +** mail: support@nxp.com ** ** Revisions: ** - rev. 1.0 (2013-09-02) @@ -213,7 +213,6 @@ void SystemCoreClockUpdate (void) { Divider *= 0x04U; } else if ((USBPHY->ANACTRL & USBPHY_ANACTRL_PFD_CLK_SEL_MASK) == USBPHY_ANACTRL_PFD_CLK_SEL(2)) { Divider *= 0x02U; - } else { } MCGOUTClock = (uint32_t)(480000000 / Divider); MCGOUTClock *= 18; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/system_MK66F18.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/system_MK66F18.h index 3e8652e09a..3bbd4bf70d 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/system_MK66F18.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/device/system_MK66F18.h @@ -9,19 +9,19 @@ ** Freescale C/C++ for Embedded ARM ** GNU C Compiler ** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler ** ** Reference manual: K66P144M180SF5RMV2, Rev. 1, Mar 2015 ** Version: rev. 3.0, 2015-03-25 -** Build: b151216 +** Build: b170112 ** ** Abstract: ** Provides a system configuration function and a global variable that ** contains the system frequency. It configures the device and initializes ** the oscillator (PLL) that is part of the microcontroller device. ** -** Copyright (c) 2015 Freescale Semiconductor, Inc. -** All rights reserved. -** +** Copyright (c) 2016 Freescale Semiconductor, Inc. +** Copyright 2016 - 2017 NXP ** Redistribution and use in source and binary forms, with or without modification, ** are permitted provided that the following conditions are met: ** @@ -32,7 +32,7 @@ ** 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 +** 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. ** @@ -47,8 +47,8 @@ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ** -** http: www.freescale.com -** mail: support@freescale.com +** http: www.nxp.com +** mail: support@nxp.com ** ** Revisions: ** - rev. 1.0 (2013-09-02) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_adc16.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_adc16.c index 8f1aa77b2e..0af6a4443e 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_adc16.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_adc16.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -46,8 +46,10 @@ static uint32_t ADC16_GetInstance(ADC_Type *base); /*! @brief Pointers to ADC16 bases for each instance. */ static ADC_Type *const s_adc16Bases[] = ADC_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to ADC16 clocks for each instance. */ -const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS; +static const clock_ip_name_t s_adc16Clocks[] = ADC16_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Code @@ -57,7 +59,7 @@ static uint32_t ADC16_GetInstance(ADC_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_ADC16_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_adc16Bases); instance++) { if (s_adc16Bases[instance] == base) { @@ -65,7 +67,7 @@ static uint32_t ADC16_GetInstance(ADC_Type *base) } } - assert(instance < FSL_FEATURE_SOC_ADC16_COUNT); + assert(instance < ARRAY_SIZE(s_adc16Bases)); return instance; } @@ -76,8 +78,10 @@ void ADC16_Init(ADC_Type *base, const adc16_config_t *config) uint32_t tmp32; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the clock. */ CLOCK_EnableClock(s_adc16Clocks[ADC16_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* ADCx_CFG1. */ tmp32 = ADC_CFG1_ADICLK(config->clockSource) | ADC_CFG1_MODE(config->resolution); @@ -126,8 +130,10 @@ void ADC16_Init(ADC_Type *base, const adc16_config_t *config) void ADC16_Deinit(ADC_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable the clock. */ CLOCK_DisableClock(s_adc16Clocks[ADC16_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void ADC16_GetDefaultConfig(adc16_config_t *config) @@ -149,7 +155,7 @@ void ADC16_GetDefaultConfig(adc16_config_t *config) status_t ADC16_DoAutoCalibration(ADC_Type *base) { bool bHWTrigger = false; - uint32_t tmp32; + volatile uint32_t tmp32; /* 'volatile' here is for the dummy read of ADCx_R[0] register. */ status_t status = kStatus_Success; /* The calibration would be failed when in hardwar mode. @@ -171,6 +177,7 @@ status_t ADC16_DoAutoCalibration(ADC_Type *base) break; } } + tmp32 = base->R[0]; /* Dummy read to clear COCO caused by calibration. */ /* Restore the hardware trigger setting if it was enabled before. */ if (bHWTrigger) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_adc16.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_adc16.h index c6b5bc0d1a..ea62c55fee 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_adc16.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_adc16.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -38,7 +38,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -74,7 +73,7 @@ enum _adc16_status_flags * @brief Channel multiplexer mode for each channel. * * For some ADC16 channels, there are two pin selections in channel multiplexer. For example, ADC0_SE4a and ADC0_SE4b - * are the different channels but share the same channel number. + * are the different channels that share the same channel number. */ typedef enum _adc_channel_mux_mode { @@ -104,7 +103,7 @@ typedef enum _adc16_resolution kADC16_Resolution12or13Bit = 1U, /*!< Single End 12-bit or Differential Sample 13-bit. */ kADC16_Resolution10or11Bit = 2U, /*!< Single End 10-bit or Differential Sample 11-bit. */ - /* This group of enumeration is for public user. */ + /* This group of enumeration is for a public user. */ kADC16_ResolutionSE8Bit = kADC16_Resolution8or9Bit, /*!< Single End 8-bit. */ kADC16_ResolutionSE12Bit = kADC16_Resolution12or13Bit, /*!< Single End 12-bit. */ kADC16_ResolutionSE10Bit = kADC16_Resolution10or11Bit, /*!< Single End 10-bit. */ @@ -203,7 +202,7 @@ typedef enum _adc16_pga_gain #endif /* FSL_FEATURE_ADC16_HAS_PGA */ /*! - * @brief ADC16 converter configuration . + * @brief ADC16 converter configuration. */ typedef struct _adc16_config { @@ -219,7 +218,7 @@ typedef struct _adc16_config } adc16_config_t; /*! - * @brief ADC16 Hardware compare configuration. + * @brief ADC16 Hardware comparison configuration. */ typedef struct _adc16_hardware_compare_config { @@ -237,7 +236,7 @@ typedef struct _adc16_channel_config uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31. See channel connection information for each chip in Reference Manual document. */ - bool enableInterruptOnConversionCompleted; /*!< Generate a interrupt request once the conversion is completed. */ + bool enableInterruptOnConversionCompleted; /*!< Generate an interrupt request once the conversion is completed. */ #if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE bool enableDifferentialConversion; /*!< Using Differential sample mode. */ #endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */ @@ -296,9 +295,9 @@ void ADC16_Init(ADC_Type *base, const adc16_config_t *config); void ADC16_Deinit(ADC_Type *base); /*! - * @brief Gets an available pre-defined settings for converter's configuration. + * @brief Gets an available pre-defined settings for the converter's configuration. * - * This function initializes the converter configuration structure with an available settings. The default values are: + * This function initializes the converter configuration structure with available settings. The default values are as follows. * @code * config->referenceVoltageSource = kADC16_ReferenceVoltageSourceVref; * config->clockSource = kADC16_ClockSourceAsynchronousClock; @@ -310,7 +309,7 @@ void ADC16_Deinit(ADC_Type *base); * config->enableLowPower = false; * config->enableContinuousConversion = false; * @endcode - * @param config Pointer to configuration structure. + * @param config Pointer to the configuration structure. */ void ADC16_GetDefaultConfig(adc16_config_t *config); @@ -318,15 +317,15 @@ void ADC16_GetDefaultConfig(adc16_config_t *config); /*! * @brief Automates the hardware calibration. * - * This auto calibration helps to adjust the plus/minus side gain automatically on the converter's working situation. + * This auto calibration helps to adjust the plus/minus side gain automatically. * Execute the calibration before using the converter. Note that the hardware trigger should be used - * during calibration. + * during the calibration. * * @param base ADC16 peripheral base address. * * @return Execution status. * @retval kStatus_Success Calibration is done successfully. - * @retval kStatus_Fail Calibration is failed. + * @retval kStatus_Fail Calibration has failed. */ status_t ADC16_DoAutoCalibration(ADC_Type *base); #endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */ @@ -350,16 +349,16 @@ static inline void ADC16_SetOffsetValue(ADC_Type *base, int16_t value) /* @} */ /*! - * @name Advanced Feature + * @name Advanced Features * @{ */ #if defined(FSL_FEATURE_ADC16_HAS_DMA) && FSL_FEATURE_ADC16_HAS_DMA /*! - * @brief Enables generating the DMA trigger when conversion is completed. + * @brief Enables generating the DMA trigger when the conversion is complete. * * @param base ADC16 peripheral base address. - * @param enable Switcher of DMA feature. "true" means to enable, "false" means not. + * @param enable Switcher of the DMA feature. "true" means enabled, "false" means not enabled. */ static inline void ADC16_EnableDMA(ADC_Type *base, bool enable) { @@ -378,7 +377,7 @@ static inline void ADC16_EnableDMA(ADC_Type *base, bool enable) * @brief Enables the hardware trigger mode. * * @param base ADC16 peripheral base address. - * @param enable Switcher of hardware trigger feature. "true" means to enable, "false" means not. + * @param enable Switcher of the hardware trigger feature. "true" means enabled, "false" means not enabled. */ static inline void ADC16_EnableHardwareTrigger(ADC_Type *base, bool enable) { @@ -408,13 +407,12 @@ void ADC16_SetChannelMuxMode(ADC_Type *base, adc16_channel_mux_mode_t mode); /*! * @brief Configures the hardware compare mode. * - * The hardware compare mode provides a way to process the conversion result automatically by hardware. Only the result - * in - * compare range is available. To compare the range, see "adc16_hardware_compare_mode_t", or the reference - * manual document for more detailed information. + * The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the result + * in the compare range is available. To compare the range, see "adc16_hardware_compare_mode_t" or the appopriate reference + * manual for more information. * * @param base ADC16 peripheral base address. - * @param config Pointer to "adc16_hardware_compare_config_t" structure. Passing "NULL" is to disable the feature. + * @param config Pointer to the "adc16_hardware_compare_config_t" structure. Passing "NULL" disables the feature. */ void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare_config_t *config); @@ -422,21 +420,21 @@ void ADC16_SetHardwareCompareConfig(ADC_Type *base, const adc16_hardware_compare /*! * @brief Sets the hardware average mode. * - * Hardware average mode provides a way to process the conversion result automatically by hardware. The multiple - * conversion results are accumulated and averaged internally. This aids reading results. + * The hardware average mode provides a way to process the conversion result automatically by using hardware. The multiple + * conversion results are accumulated and averaged internally making them easier to read. * * @param base ADC16 peripheral base address. - * @param mode Setting hardware average mode. See "adc16_hardware_average_mode_t". + * @param mode Setting the hardware average mode. See "adc16_hardware_average_mode_t". */ void ADC16_SetHardwareAverage(ADC_Type *base, adc16_hardware_average_mode_t mode); #endif /* FSL_FEATURE_ADC16_HAS_HW_AVERAGE */ #if defined(FSL_FEATURE_ADC16_HAS_PGA) && FSL_FEATURE_ADC16_HAS_PGA /*! - * @brief Configures the PGA for converter's front end. + * @brief Configures the PGA for the converter's front end. * * @param base ADC16 peripheral base address. - * @param config Pointer to "adc16_pga_config_t" structure. Passing "NULL" is to disable the feature. + * @param config Pointer to the "adc16_pga_config_t" structure. Passing "NULL" disables the feature. */ void ADC16_SetPGAConfig(ADC_Type *base, const adc16_pga_config_t *config); #endif /* FSL_FEATURE_ADC16_HAS_PGA */ @@ -468,26 +466,26 @@ void ADC16_ClearStatusFlags(ADC_Type *base, uint32_t mask); /*! * @brief Configures the conversion channel. * - * This operation triggers the conversion if in software trigger mode. When in hardware trigger mode, this API + * This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API * configures the channel while the external trigger source helps to trigger the conversion. * * Note that the "Channel Group" has a detailed description. - * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC can have more than one - * group of status and control register, one for each conversion. The channel group parameter indicates which group of - * registers are used channel group 0 is for Group A registers and channel group 1 is for Group B registers. The + * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one + * group of status and control registers, one for each conversion. The channel group parameter indicates which group of + * registers are used, for example, channel group 0 is for Group A registers and channel group 1 is for Group B registers. The * channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of - * the channel groups is actively controlling ADC conversions. Channel group 0 is used for both software and hardware - * trigger modes of operation. Channel groups 1 and greater indicate potentially multiple channel group registers for - * use only in hardware trigger mode. See the chip configuration information in the MCU reference manual about the - * number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used - * for software trigger operation and therefore writes to these channel groups do not initiate a new conversion. - * Updating channel group 0 while a different channel group is actively controlling a conversion is allowed and + * the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and hardware + * trigger modes. Channel group 1 and greater indicates multiple channel group registers for + * use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual for the + * number of SC1n registers (channel groups) specific to this device. Channel group 1 or greater are not used + * for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion. + * Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and * vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a * conversion aborts the current conversion. * * @param base ADC16 peripheral base address. * @param channelGroup Channel group index. - * @param config Pointer to "adc16_channel_config_t" structure for conversion channel. + * @param config Pointer to the "adc16_channel_config_t" structure for the conversion channel. */ void ADC16_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc16_channel_config_t *config); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_clock.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_clock.c index bffbb4a312..d75d97ff4f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_clock.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_clock.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright (c) 2016 - 2017 , NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -12,7 +13,7 @@ * 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 + * o Neither the name of 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. * @@ -28,7 +29,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "fsl_common.h" #include "fsl_clock.h" /******************************************************************************* @@ -124,7 +124,6 @@ static uint32_t s_extPllFreq = 0U; /* External XTAL0 (OSC0) clock frequency. */ uint32_t g_xtal0Freq; - /* External XTAL32K clock frequency. */ uint32_t g_xtal32Freq; @@ -195,17 +194,36 @@ static uint32_t CLOCK_GetPll0RefFreq(void); */ static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq); +/******************************************************************************* + * Code + ******************************************************************************/ + +#ifndef MCG_USER_CONFIG_FLL_STABLE_DELAY_EN /*! * @brief Delay function to wait FLL stable. * * Delay function to wait FLL stable in FEI mode or FEE mode, should wait at least * 1ms. Every time changes FLL setting, should wait this time for FLL stable. */ -static void CLOCK_FllStableDelay(void); - -/******************************************************************************* - * Code - ******************************************************************************/ +void CLOCK_FllStableDelay(void) +{ + /* + Should wait at least 1ms. Because in these modes, the core clock is 100MHz + at most, so this function could obtain the 1ms delay. + */ + volatile uint32_t i = 30000U; + while (i--) + { + __NOP(); + } +} +#else /* With MCG_USER_CONFIG_FLL_STABLE_DELAY_EN defined. */ +/* Once user defines the MCG_USER_CONFIG_FLL_STABLE_DELAY_EN to use their own delay function, he has to + * create his own CLOCK_FllStableDelay() function in application code. Since the clock functions in this + * file would call the CLOCK_FllStableDelay() regardness how it is defined. + */ +extern void CLOCK_FllStableDelay(void); +#endif /* MCG_USER_CONFIG_FLL_STABLE_DELAY_EN */ static uint32_t CLOCK_GetMcgExtClkFreq(void) { @@ -342,19 +360,6 @@ static uint8_t CLOCK_GetOscRangeFromFreq(uint32_t freq) return range; } -static void CLOCK_FllStableDelay(void) -{ - /* - Should wait at least 1ms. Because in these modes, the core clock is 100MHz - at most, so this function could obtain the 1ms delay. - */ - volatile uint32_t i = 30000U; - while (i--) - { - __NOP(); - } -} - uint32_t CLOCK_GetOsc0ErClkUndivFreq(void) { if (OSC0->CR & OSC_CR_ERCLKEN_MASK) @@ -419,6 +424,9 @@ uint32_t CLOCK_GetPllFllSelClkFreq(void) case 1U: /* PLL. */ freq = CLOCK_GetPll0Freq(); break; + case 2U: /* USB1 PFD */ + freq = CLOCK_GetExtPllFreq(); + break; case 3U: /* MCG IRC48M. */ freq = MCG_INTERNAL_IRC_48M; break; @@ -572,8 +580,31 @@ bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq) } bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq) +{ + /* Source and freq are not used for USB HS. */ + src = src; + freq = freq; + + SIM->SCGC3 |= SIM_SCGC3_USBHS_MASK; + + SIM->USBPHYCTL = ((SIM->USBPHYCTL & ~(SIM_USBPHYCTL_USB3VOUTTRG_MASK)) | SIM_USBPHYCTL_USB3VOUTTRG(6U) /* 3.310V */ + | SIM_USBPHYCTL_USBVREGSEL_MASK); /* VREG_IN1 */ + + USBPHY->PLL_SIC |= USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* Enable USB clock output from USB PHY PLL */ + + return true; +} + +void CLOCK_DisableUsbhs0Clock(void) +{ + USBPHY->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_EN_USB_CLKS_MASK; /* Disable USB clock output from USB PHY PLL */ + SIM->SCGC3 &= ~SIM_SCGC3_USBHS_MASK; +} + +bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq) { volatile uint32_t i; + uint32_t phyPllDiv = 0U; /* * In order to bring up the internal 480MHz USB PLL clock, should make sure: @@ -584,12 +615,28 @@ bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq) assert(!(MCG->C2 & MCG_C2_IRCS_MASK)); assert(OSC0->CR & OSC_CR_ERCLKEN_MASK); + if (24000000U == freq) + { + phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(0U); + } + else if (16000000U == freq) + { + phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(1U); + } + else if (12000000U == freq) + { + phyPllDiv = USBPHY_PLL_SIC_PLL_DIV_SEL(2U); + } + else + { + return false; + } + /* Source and freq are not used for USB HS. */ src = src; - freq = freq; + SIM->SCGC3 |= SIM_SCGC3_USBHSPHY_MASK; SIM->SOPT2 |= SIM_SOPT2_USBREGEN_MASK; - SIM->SCGC3 |= (SIM_SCGC3_USBHS_MASK | SIM_SCGC3_USBHSPHY_MASK); i = 500000U; while (i--) @@ -597,12 +644,66 @@ bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq) __NOP(); } - SIM->USBPHYCTL = ((SIM->USBPHYCTL & ~(SIM_USBPHYCTL_USB3VOUTTRG_MASK)) | SIM_USBPHYCTL_USB3VOUTTRG(6U) /* 3.310V */ - | SIM_USBPHYCTL_USBVREGSEL_MASK); /* VREG_IN1 */ + USBPHY->TRIM_OVERRIDE_EN = 0x01U; /* Override the trim. */ + USBPHY->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */ + USBPHY->PLL_SIC |= USBPHY_PLL_SIC_PLL_POWER_MASK; /* power up PLL */ + USBPHY->PLL_SIC = (USBPHY->PLL_SIC & ~USBPHY_PLL_SIC_PLL_DIV_SEL_MASK) | phyPllDiv; + USBPHY->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_BYPASS_MASK; /* Clear bypass bit */ + USBPHY->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK; /* Clear to 0U to run clocks */ + + /* Wait for lock. */ + while (!(USBPHY->PLL_SIC & USBPHY_PLL_SIC_PLL_LOCK_MASK)) + { + } return true; } +void CLOCK_DisableUsbhs0PhyPllClock(void) +{ + USBPHY->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */ + USBPHY->PLL_SIC &= ~USBPHY_PLL_SIC_PLL_POWER_MASK; /* Power down PLL */ + SIM->SOPT2 &= ~SIM_SOPT2_USBREGEN_MASK; + SIM->SCGC3 &= ~SIM_SCGC3_USBHSPHY_MASK; +} + +void CLOCK_EnableUsbhs0PfdClock(uint8_t frac, clock_usb_pfd_src_t src) +{ + assert((frac <= 35U) && (frac >= 18U)); + uint32_t fracFreq = (480000U * 18U / frac) * 1000U; + + USBPHY->ANACTRL = (USBPHY->ANACTRL & ~(USBPHY_ANACTRL_PFD_FRAC_MASK | USBPHY_ANACTRL_PFD_CLK_SEL_MASK)) | + (USBPHY_ANACTRL_PFD_FRAC(frac) | USBPHY_ANACTRL_PFD_CLK_SEL(src)); + + USBPHY->ANACTRL &= ~USBPHY_ANACTRL_PFD_CLKGATE_MASK; + while (!(USBPHY->ANACTRL & USBPHY_ANACTRL_PFD_STABLE_MASK)) + { + } + + if (kCLOCK_UsbPfdSrcExt == src) + { + s_extPllFreq = g_xtal0Freq; + } + else if (kCLOCK_UsbPfdSrcFracDivBy4 == src) + { + s_extPllFreq = fracFreq / 4U; + } + else if (kCLOCK_UsbPfdSrcFracDivBy2 == src) + { + s_extPllFreq = fracFreq / 2U; + } + else + { + s_extPllFreq = fracFreq; + } +} + +void CLOCK_DisableUsbhs0PfdClock(void) +{ + USBPHY->ANACTRL |= USBPHY_ANACTRL_PFD_CLKGATE_MASK; + s_extPllFreq = 0U; +} + uint32_t CLOCK_GetOutClkFreq(void) { uint32_t mcgoutclk; @@ -705,6 +806,12 @@ uint32_t CLOCK_GetPll0Freq(void) mcgpll0clk = CLOCK_GetPll0RefFreq(); + /* + * Please call CLOCK_SetXtal0Freq base on board setting before using OSC0 clock. + * Please call CLOCK_SetXtal1Freq base on board setting before using OSC1 clock. + */ + assert(mcgpll0clk); + mcgpll0clk /= (FSL_FEATURE_MCG_PLL_PRDIV_BASE + MCG_C5_PRDIV0_VAL); mcgpll0clk *= (FSL_FEATURE_MCG_PLL_VDIV_BASE + MCG_C6_VDIV0_VAL); @@ -746,16 +853,6 @@ status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel) } MCG->C7 = (MCG->C7 & ~MCG_C7_OSCSEL_MASK) | MCG_C7_OSCSEL(oscsel); - if (kMCG_OscselOsc == oscsel) - { - if (MCG->C2 & MCG_C2_EREFS_MASK) - { - while (!(MCG->S & MCG_S_OSCINIT0_MASK)) - { - } - } - } - if (needDelay) { /* ERR009878 Delay at least 50 micro-seconds for external clock change valid. */ @@ -936,6 +1033,14 @@ void CLOCK_EnablePll0(mcg_pll_config_t const *config) } } +void CLOCK_SetPllClkSel(mcg_pll_clk_select_t pllcs) +{ + MCG->C11 = ((MCG->C11 & ~MCG_C11_PLLCS_MASK)) | MCG_C11_PLLCS(pllcs); + while (pllcs != MCG_S2_PLLCST_VAL) + { + } +} + void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode) { /* Clear the previous flag, MCG_SC[LOCS0]. */ @@ -1279,7 +1384,7 @@ mcg_mode_t CLOCK_GetMode(void) return mode; } -status_t CLOCK_SetFeiMode(mcg_drs_t drs, void (*fllStableDelay)(void)) +status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) { uint8_t mcg_c4; bool change_drs = false; @@ -1323,7 +1428,7 @@ status_t CLOCK_SetFeiMode(mcg_drs_t drs, void (*fllStableDelay)(void)) } /* In FEI mode, the MCG_C4[DMX32] is set to 0U. */ - MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DRST_DRS(drs)); + MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs)); /* Check MCG_S[CLKST] */ while (kMCG_ClkOutStatFll != MCG_S_CLKST_VAL) @@ -1372,6 +1477,17 @@ status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void | MCG_C1_FRDIV(frdiv) /* FRDIV */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ + /* If use external crystal as clock source, wait for it stable. */ + if (MCG_C7_OSCSEL(kMCG_OscselOsc) == (MCG->C7 & MCG_C7_OSCSEL_MASK)) + { + if (MCG->C2 & MCG_C2_EREFS_MASK) + { + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } + } + /* Wait and check status. */ while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL) { @@ -1406,7 +1522,7 @@ status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void return kStatus_Success; } -status_t CLOCK_SetFbiMode(mcg_drs_t drs, void (*fllStableDelay)(void)) +status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) { uint8_t mcg_c4; bool change_drs = false; @@ -1459,7 +1575,7 @@ status_t CLOCK_SetFbiMode(mcg_drs_t drs, void (*fllStableDelay)(void)) { } - MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DRST_DRS(drs)); + MCG->C4 = (mcg_c4 & ~(MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) | (MCG_C4_DMX32(dmx32) | MCG_C4_DRST_DRS(drs)); /* Wait for FLL stable time. */ if (fllStableDelay) @@ -1514,6 +1630,17 @@ status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void | MCG_C1_FRDIV(frdiv) /* FRDIV = frdiv */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ + /* If use external crystal as clock source, wait for it stable. */ + if (MCG_C7_OSCSEL(kMCG_OscselOsc) == (MCG->C7 & MCG_C7_OSCSEL_MASK)) + { + if (MCG->C2 & MCG_C2_EREFS_MASK) + { + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } + } + /* Wait for Reference clock Status bit to clear */ while (kMCG_FllSrcExternal != MCG_S_IREFST_VAL) { @@ -1574,6 +1701,12 @@ status_t CLOCK_SetBlpeMode(void) status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config) { + /* If external PLL is used, then the config could be NULL. */ + if (kMCG_PllClkSelExtPll != pllcs) + { + assert(config); + } + /* This function is designed to change MCG to PBE mode from PEE/BLPE/FBE, but with this workflow, the source mode could be all modes except PEI/PBI. @@ -1601,13 +1734,15 @@ status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *co CLOCK_EnablePll0(config); } + /* Change to PLL mode. */ + MCG->C6 |= MCG_C6_PLLS_MASK; + MCG->C11 = ((MCG->C11 & ~MCG_C11_PLLCS_MASK)) | MCG_C11_PLLCS(pllcs); while (pllcs != MCG_S2_PLLCST_VAL) { } - /* Change to PLL mode. */ - MCG->C6 |= MCG_C6_PLLS_MASK; + /* Wait for PLL mode changed. */ while (!(MCG->S & MCG_S_PLLST_MASK)) { } @@ -1682,9 +1817,9 @@ status_t CLOCK_InternalModeToFbiModeQuick(void) return kStatus_Success; } -status_t CLOCK_BootToFeiMode(mcg_drs_t drs, void (*fllStableDelay)(void)) +status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)) { - return CLOCK_SetFeiMode(drs, fllStableDelay); + return CLOCK_SetFeiMode(dmx32, drs, fllStableDelay); } status_t CLOCK_BootToFeeMode( @@ -1721,6 +1856,17 @@ status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel) ((MCG->C1 & ~(MCG_C1_CLKS_MASK | MCG_C1_IREFS_MASK)) | (MCG_C1_CLKS(kMCG_ClkOutSrcExternal) /* CLKS = 2 */ | MCG_C1_IREFS(kMCG_FllSrcExternal))); /* IREFS = 0 */ + /* If use external crystal as clock source, wait for it stable. */ + if (MCG_C7_OSCSEL(kMCG_OscselOsc) == (MCG->C7 & MCG_C7_OSCSEL_MASK)) + { + if (MCG->C2 & MCG_C2_EREFS_MASK) + { + while (!(MCG->S & MCG_S_OSCINIT0_MASK)) + { + } + } + } + /* Wait for MCG_S[CLKST] and MCG_S[IREFST]. */ while ((MCG->S & (MCG_S_IREFST_MASK | MCG_S_CLKST_MASK)) != (MCG_S_IREFST(kMCG_FllSrcExternal) | MCG_S_CLKST(kMCG_ClkOutStatExt))) @@ -1735,7 +1881,11 @@ status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel) status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config) { - assert(config); + /* If external PLL is used, then the config could be NULL. */ + if (kMCG_PllClkSelExtPll != pllcs) + { + assert(config); + } CLOCK_SetExternalRefClkConfig(oscsel); @@ -1793,7 +1943,7 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config) if (!(MCG->S & MCG_S_IRCST_MASK)) { CLOCK_ExternalModeToFbeModeQuick(); - CLOCK_SetFeiMode(config->drs, (void (*)(void))0); + CLOCK_SetFeiMode(config->dmx32, config->drs, (void (*)(void))0); } CLOCK_SetExternalRefClkConfig(config->oscsel); @@ -1805,7 +1955,7 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config) MCG->C2 &= ~MCG_C2_LP_MASK; /* Disable lowpower. */ { - CLOCK_SetFeiMode(config->drs, CLOCK_FllStableDelay); + CLOCK_SetFeiMode(config->dmx32, config->drs, CLOCK_FllStableDelay); } } @@ -1821,13 +1971,13 @@ status_t CLOCK_SetMcgConfig(const mcg_config_t *config) switch (next_mode) { case kMCG_ModeFEI: - status = CLOCK_SetFeiMode(config->drs, CLOCK_FllStableDelay); + status = CLOCK_SetFeiMode(config->dmx32, config->drs, CLOCK_FllStableDelay); break; case kMCG_ModeFEE: status = CLOCK_SetFeeMode(config->frdiv, config->dmx32, config->drs, CLOCK_FllStableDelay); break; case kMCG_ModeFBI: - status = CLOCK_SetFbiMode(config->drs, (void (*)(void))0); + status = CLOCK_SetFbiMode(config->dmx32, config->drs, (void (*)(void))0); break; case kMCG_ModeFBE: status = CLOCK_SetFbeMode(config->frdiv, config->dmx32, config->drs, (void (*)(void))0); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_clock.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_clock.h index d145692508..3f343f5cc9 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_clock.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_clock.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright (c) 2016 - 2017 , NXP * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -12,7 +13,7 @@ * 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 + * o Neither the name of 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. * @@ -31,45 +32,83 @@ #ifndef _FSL_CLOCK_H_ #define _FSL_CLOCK_H_ -#include "fsl_device_registers.h" -#include -#include -#include +#include "fsl_common.h" /*! @addtogroup clock */ /*! @{ */ +/*! @file */ + +/******************************************************************************* + * Configurations + ******************************************************************************/ + +/*! @brief Configures whether to check a parameter in a function. + * + * Some MCG settings must be changed with conditions, for example: + * 1. MCGIRCLK settings, such as the source, divider, and the trim value should not change when + * MCGIRCLK is used as a system clock source. + * 2. MCG_C7[OSCSEL] should not be changed when the external reference clock is used + * as a system clock source. For example, in FBE/BLPE/PBE modes. + * 3. The users should only switch between the supported clock modes. + * + * MCG functions check the parameter and MCG status before setting, if not allowed + * to change, the functions return error. The parameter checking increases code size, + * if code size is a critical requirement, change #MCG_CONFIG_CHECK_PARAM to 0 to + * disable parameter checking. + */ +#ifndef MCG_CONFIG_CHECK_PARAM +#define MCG_CONFIG_CHECK_PARAM 0U +#endif + +/*! @brief Configure whether driver controls clock + * + * When set to 0, peripheral drivers will enable clock in initialize function + * and disable clock in de-initialize function. When set to 1, peripheral + * driver will not control the clock, application could contol the clock out of + * the driver. + * + * @note All drivers share this feature switcher. If it is set to 1, application + * should handle clock enable and disable for all drivers. + */ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)) +#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0 +#endif + /******************************************************************************* * Definitions ******************************************************************************/ -/*! @brief Clock driver version. */ -#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */ +/*! @name Driver version */ +/*@{*/ +/*! @brief CLOCK driver version 2.2.2. */ +#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 2)) +/*@}*/ /*! @brief External XTAL0 (OSC0) clock frequency. * - * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz, when the clock is setup, use the - * function CLOCK_SetXtal0Freq to set the value in to clock driver. For example, - * if XTAL0 is 8MHz, + * The XTAL0/EXTAL0 (OSC0) clock frequency in Hz. When the clock is set up, use the + * function CLOCK_SetXtal0Freq to set the value in the clock driver. For example, + * if XTAL0 is 8 MHz: * @code - * CLOCK_InitOsc0(...); // Setup the OSC0 - * CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to clock driver. + * CLOCK_InitOsc0(...); // Set up the OSC0 + * CLOCK_SetXtal0Freq(80000000); // Set the XTAL0 value to the clock driver. * @endcode * - * This is important for the multicore platforms, only one core needs to setup - * OSC0 using CLOCK_InitOsc0, all other cores need to call CLOCK_SetXtal0Freq - * to get valid clock frequency. + * This is important for the multicore platforms where only one core needs to set up the + * OSC0 using the CLOCK_InitOsc0. All other cores need to call the CLOCK_SetXtal0Freq + * to get a valid clock frequency. */ extern uint32_t g_xtal0Freq; /*! @brief External XTAL32/EXTAL32/RTC_CLKIN clock frequency. * - * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz, when the clock is setup, use the - * function CLOCK_SetXtal32Freq to set the value in to clock driver. + * The XTAL32/EXTAL32/RTC_CLKIN clock frequency in Hz. When the clock is set up, use the + * function CLOCK_SetXtal32Freq to set the value in the clock driver. * - * This is important for the multicore platforms, only one core needs to setup - * the clock, all other cores need to call CLOCK_SetXtal32Freq - * to get valid clock frequency. + * This is important for the multicore platforms where only one core needs to set up + * the clock. All other cores need to call the CLOCK_SetXtal32Freq + * to get a valid clock frequency. */ extern uint32_t g_xtal32Freq; @@ -194,16 +233,10 @@ extern uint32_t g_xtal32Freq; kCLOCK_Sdramc0 \ } -/*! @brief Clock ip name array for MMCAU. */ -#define MMCAU_CLOCKS \ - { \ - kCLOCK_Mmcau0 \ - } - /*! @brief Clock ip name array for MPU. */ -#define MPU_CLOCKS \ - { \ - kCLOCK_Mpu0 \ +#define SYSMPU_CLOCKS \ + { \ + kCLOCK_Sysmpu0 \ } /*! @brief Clock ip name array for VREF. */ @@ -242,12 +275,6 @@ extern uint32_t g_xtal32Freq; kCLOCK_Crc0 \ } -/*! @brief Clock ip name array for LMEM. */ -#define LMEM_CLOCKS \ - { \ - kCLOCK_Lmem0 \ - } - /*! @brief Clock ip name array for I2C. */ #define I2C_CLOCKS \ { \ @@ -267,9 +294,9 @@ extern uint32_t g_xtal32Freq; } /*! @brief Clock ip name array for CMP. */ -#define CMP_CLOCKS \ - { \ - kCLOCK_Cmp0, kCLOCK_Cmp1, kCLOCK_Cmp2 \ +#define CMP_CLOCKS \ + { \ + kCLOCK_Cmp0, kCLOCK_Cmp1, kCLOCK_Cmp2, kCLOCK_Cmp3 \ } /*! @@ -334,9 +361,26 @@ typedef enum _clock_usb_src kCLOCK_UsbSrcPll0 = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(1U), /*!< Use PLL0. */ kCLOCK_UsbSrcUsbPfd = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(2U), /*!< Use USBPFDCLK. */ kCLOCK_UsbSrcIrc48M = SIM_SOPT2_USBSRC(1U) | SIM_SOPT2_PLLFLLSEL(3U), /*!< Use IRC48M. */ - kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U) /*!< Use USB_CLKIN. */ + kCLOCK_UsbSrcExt = SIM_SOPT2_USBSRC(0U), /*!< Use USB_CLKIN. */ + kCLOCK_UsbSrcUnused = 0xFFFFFFFFU, /*!< Used when the function does not + care the clock source. */ } clock_usb_src_t; +/*! @brief Source of the USB HS PHY. */ +typedef enum _clock_usb_phy_src +{ + kCLOCK_UsbPhySrcExt = 0U, /*!< Use external crystal. */ +} clock_usb_phy_src_t; + +/*! @brief Source of the USB HS PFD clock (USB1PFDCLK) */ +typedef enum _clock_usb_pfd_src +{ + kCLOCK_UsbPfdSrcExt = 0U, /*!< Use external crystal. */ + kCLOCK_UsbPfdSrcFracDivBy4 = 1U, /*!< Use PFD_FRAC output divided by 4. */ + kCLOCK_UsbPfdSrcFracDivBy2 = 2U, /*!< Use PFD_FRAC output divided by 2. */ + kCLOCK_UsbPfdSrcFrac = 3U, /*!< Use PFD_FRAC output. */ +} clock_usb_pfd_src_t; + /*------------------------------------------------------------------------------ clock_gate_t definition: @@ -402,6 +446,7 @@ typedef enum _clock_ip_name kCLOCK_Cmp0 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp1 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Cmp2 = CLK_GATE_DEFINE(0x1034U, 19U), + kCLOCK_Cmp3 = CLK_GATE_DEFINE(0x1034U, 19U), kCLOCK_Vref0 = CLK_GATE_DEFINE(0x1034U, 20U), kCLOCK_Lptmr0 = CLK_GATE_DEFINE(0x1038U, 0U), @@ -430,7 +475,7 @@ typedef enum _clock_ip_name kCLOCK_Flexbus0 = CLK_GATE_DEFINE(0x1040U, 0U), kCLOCK_Dma0 = CLK_GATE_DEFINE(0x1040U, 1U), - kCLOCK_Mpu0 = CLK_GATE_DEFINE(0x1040U, 2U), + kCLOCK_Sysmpu0 = CLK_GATE_DEFINE(0x1040U, 2U), kCLOCK_Sdramc0 = CLK_GATE_DEFINE(0x1040U, 3U), } clock_ip_name_t; @@ -447,7 +492,7 @@ typedef struct _sim_clock_config /*! @brief OSC work mode. */ typedef enum _osc_mode { - kOSC_ModeExt = 0U, /*!< Use external clock. */ + kOSC_ModeExt = 0U, /*!< Use an external clock. */ #if (defined(MCG_C2_EREFS_MASK) && !(defined(MCG_C2_EREFS0_MASK))) kOSC_ModeOscLowPower = MCG_C2_EREFS_MASK, /*!< Oscillator low power. */ #else @@ -498,8 +543,8 @@ typedef struct _oscer_config * @brief OSC Initialization Configuration Structure * * Defines the configuration data structure to initialize the OSC. - * When porting to a new board, please set the following members - * according to board setting: + * When porting to a new board, set the following members + * according to the board setting: * 1. freq: The external frequency. * 2. workMode: The OSC module mode. */ @@ -575,7 +620,7 @@ typedef enum _mcg_oscsel typedef enum _mcg_pll_clk_select { kMCG_PllClkSelPll0, /*!< PLL0 output clock is selected */ - kMCG_PllClkSelExtPll /* External PLL clock is selected */ + kMCG_PllClkSelExtPll /* The external PLL clock is selected */ } mcg_pll_clk_select_t; /*! @brief MCG clock monitor mode. */ @@ -596,8 +641,8 @@ enum _mcg_status kStatus_MCG_AtmDesiredFreqInvalid = MAKE_STATUS(kStatusGroup_MCG, 3), /*!< Invalid desired frequency for ATM. */ kStatus_MCG_AtmIrcUsed = MAKE_STATUS(kStatusGroup_MCG, 4), /*!< IRC is used when using ATM. */ kStatus_MCG_AtmHardwareFail = MAKE_STATUS(kStatusGroup_MCG, 5), /*!< Hardware fail occurs during ATM. */ - kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Could not change clock source because - it is used currently. */ + kStatus_MCG_SourceUsed = MAKE_STATUS(kStatusGroup_MCG, 6) /*!< Can't change the clock source because + it is in use. */ }; /*! @brief MCG status flags. */ @@ -621,11 +666,11 @@ enum _mcg_irclk_enable_mode /*! @brief MCG PLL clock enable mode definition. */ enum _mcg_pll_enable_mode { - kMCG_PllEnableIndependent = MCG_C5_PLLCLKEN0_MASK, /*!< MCGPLLCLK enable indepencent of - MCG clock mode. Generally, PLL + kMCG_PllEnableIndependent = MCG_C5_PLLCLKEN0_MASK, /*!< MCGPLLCLK enable independent of the + MCG clock mode. Generally, the PLL is disabled in FLL modes - (FEI/FBI/FEE/FBE), set PLL clock - enable independent will enable + (FEI/FBI/FEE/FBE). Setting the PLL clock + enable independent, enables the PLL in the FLL modes. */ kMCG_PllEnableInStop = MCG_C5_PLLSTEN0_MASK /*!< MCGPLLCLK enable in STOP mode. */ }; @@ -652,16 +697,16 @@ typedef struct _mcg_pll_config uint8_t vdiv; /*!< VCO divider VDIV. */ } mcg_pll_config_t; -/*! @brief MCG configure structure for mode change. +/*! @brief MCG mode change configuration structure * - * When porting to a new board, please set the following members - * according to board setting: - * 1. frdiv: If FLL uses the external reference clock, please set this - * value to make sure external reference clock divided by frdiv is - * in the range 31.25kHz to 39.0625kHz. + * When porting to a new board, set the following members + * according to the board setting: + * 1. frdiv: If the FLL uses the external reference clock, set this + * value to ensure that the external reference clock divided by frdiv is + * in the 31.25 kHz to 39.0625 kHz range. * 2. The PLL reference clock divider PRDIV: PLL reference clock frequency after - * PRDIV should be in the range of FSL_FEATURE_MCG_PLL_REF_MIN to - * FSL_FEATURE_MCG_PLL_REF_MAX. + * PRDIV should be in the FSL_FEATURE_MCG_PLL_REF_MIN to + * FSL_FEATURE_MCG_PLL_REF_MAX range. */ typedef struct _mcg_config { @@ -693,26 +738,6 @@ typedef struct _mcg_config extern "C" { #endif /* __cplusplus */ -/*! - * @brief Set the XTAL0 frequency based on board setting. - * - * @param freq The XTAL0/EXTAL0 input clock frequency in Hz. - */ -static inline void CLOCK_SetXtal0Freq(uint32_t freq) -{ - g_xtal0Freq = freq; -} - -/*! - * @brief Set the XTAL32/RTC_CLKIN frequency based on board setting. - * - * @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz. - */ -static inline void CLOCK_SetXtal32Freq(uint32_t freq) -{ - g_xtal32Freq = freq; -} - /*! * @brief Enable the clock for specific IP. * @@ -839,8 +864,12 @@ static inline void CLOCK_SetRtcClkOutClock(uint32_t src) /*! @brief Enable USB HS clock. * - * @param src USB HS clock source. - * @param freq The frequency specified by src. + * This function only enables the access to USB HS prepheral, upper layer + * should first call the @ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY + * clock to use USB HS. + * + * @param src USB HS does not care about the clock source, here must be @ref kCLOCK_UsbSrcUnused. + * @param freq USB HS does not care about the clock source, so this parameter is ignored. * @retval true The clock is set successfully. * @retval false The clock source is invalid to get proper USB HS clock. */ @@ -848,13 +877,49 @@ bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq); /*! @brief Disable USB HS clock. * - * Disable USB HS clock. + * Disable USB HS clock, this function should not be called after + * @ref CLOCK_DisableUsbhs0PhyPllClock. */ -static inline void CLOCK_DisableUsbhs0Clock(void) -{ - SIM->SOPT2 &= ~SIM_SOPT2_USBREGEN_MASK; - SIM->SCGC3 &= ~(SIM_SCGC3_USBHS_MASK | SIM_SCGC3_USBHSPHY_MASK); -} +void CLOCK_DisableUsbhs0Clock(void); + +/*! @brief Enable USB HS PHY PLL clock. + * + * This function enables the internal 480MHz USB PHY PLL clock. + * + * @param src USB HS PHY PLL clock source. + * @param freq The frequency specified by src. + * @retval true The clock is set successfully. + * @retval false The clock source is invalid to get proper USB HS clock. + */ +bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq); + +/*! @brief Disable USB HS PHY PLL clock. + * + * This function disables USB HS PHY PLL clock. + */ +void CLOCK_DisableUsbhs0PhyPllClock(void); + +/*! @brief Enable USB HS PFD clock. + * + * This function enables USB HS PFD clock. It should be called after function + * @ref CLOCK_EnableUsbhs0PhyPllClock. + * The PFD output clock is selected by the parameter @p src. When the @p src is + * @ref kCLOCK_UsbPfdSrcExt, then the PFD outout is from external crystal + * directly, in this case, the @p frac is not used. In other cases, the PFD_FRAC + * output clock frequency is 480MHz*18/frac, the PFD output frequency is based + * on the PFD_FRAC output. + * + * @param frac The value set to PFD_FRAC, it must be in the range of 18 to 35. + * @param src Source of the USB HS PFD clock (USB1PFDCLK). + */ +void CLOCK_EnableUsbhs0PfdClock(uint8_t frac, clock_usb_pfd_src_t src); + +/*! @brief Disable USB HS PFD clock. + * + * This function disables USB HS PFD clock. It should be called before function + * @ref CLOCK_DisableUsbhs0PhyPllClock. + */ +void CLOCK_DisableUsbhs0PfdClock(void); /*! @brief Enable USB FS clock. * @@ -997,9 +1062,9 @@ static inline void CLOCK_SetSimSafeDivs(void) /*@{*/ /*! - * @brief Get the MCG output clock(MCGOUTCLK) frequency. + * @brief Gets the MCG output clock (MCGOUTCLK) frequency. * - * This function gets the MCG output clock frequency (Hz) based on current MCG + * This function gets the MCG output clock frequency in Hz based on the current MCG * register value. * * @return The frequency of MCGOUTCLK. @@ -1007,40 +1072,40 @@ static inline void CLOCK_SetSimSafeDivs(void) uint32_t CLOCK_GetOutClkFreq(void); /*! - * @brief Get the MCG FLL clock(MCGFLLCLK) frequency. + * @brief Gets the MCG FLL clock (MCGFLLCLK) frequency. * - * This function gets the MCG FLL clock frequency (Hz) based on current MCG - * register value. The FLL is only enabled in FEI/FBI/FEE/FBE mode, in other - * modes, FLL is disabled in low power state. + * This function gets the MCG FLL clock frequency in Hz based on the current MCG + * register value. The FLL is enabled in FEI/FBI/FEE/FBE mode and + * disabled in low power state in other modes. * * @return The frequency of MCGFLLCLK. */ uint32_t CLOCK_GetFllFreq(void); /*! - * @brief Get the MCG internal reference clock(MCGIRCLK) frequency. + * @brief Gets the MCG internal reference clock (MCGIRCLK) frequency. * - * This function gets the MCG internal reference clock frequency (Hz) based - * on current MCG register value. + * This function gets the MCG internal reference clock frequency in Hz based + * on the current MCG register value. * * @return The frequency of MCGIRCLK. */ uint32_t CLOCK_GetInternalRefClkFreq(void); /*! - * @brief Get the MCG fixed frequency clock(MCGFFCLK) frequency. + * @brief Gets the MCG fixed frequency clock (MCGFFCLK) frequency. * - * This function gets the MCG fixed frequency clock frequency (Hz) based - * on current MCG register value. + * This function gets the MCG fixed frequency clock frequency in Hz based + * on the current MCG register value. * * @return The frequency of MCGFFCLK. */ uint32_t CLOCK_GetFixedFreqClkFreq(void); /*! - * @brief Get the MCG PLL0 clock(MCGPLL0CLK) frequency. + * @brief Gets the MCG PLL0 clock (MCGPLL0CLK) frequency. * - * This function gets the MCG PLL0 clock frequency (Hz) based on current MCG + * This function gets the MCG PLL0 clock frequency in Hz based on the current MCG * register value. * * @return The frequency of MCGPLL0CLK. @@ -1048,21 +1113,21 @@ uint32_t CLOCK_GetFixedFreqClkFreq(void); uint32_t CLOCK_GetPll0Freq(void); /*! - * @brief Get the MCG external PLL frequency. + * @brief Gets the MCG external PLL frequency. * - * This function gets the MCG external PLL frequency (Hz). + * This function gets the MCG external PLL frequency in Hz. * - * @return The frequency of MCG external PLL. + * @return The frequency of the MCG external PLL. */ uint32_t CLOCK_GetExtPllFreq(void); /*! - * @brief Set the MCG external PLL frequency. + * @brief Sets the MCG external PLL frequency. * - * This function sets the MCG external PLL frequency (Hz), the MCG external PLL - * frequency is passed in to MCG driver through this function. Please call this - * function after the external PLL frequency is changed, otherwise the APIs for - * get frequency may returns wrong value. + * This function sets the MCG external PLL frequency in Hz. The MCG external PLL + * frequency is passed to the MCG driver using this function. Call this + * function after the external PLL frequency is changed. Otherwise, the APIs, which are used to get + * the frequency, may return an incorrect value. * * @param The frequency of MCG external PLL. */ @@ -1074,12 +1139,12 @@ void CLOCK_SetExtPllFreq(uint32_t freq); /*@{*/ /*! - * @brief Enable or disable MCG low power. + * @brief Enables or disables the MCG low power. * - * Enable MCG low power will disable the PLL and FLL in bypass modes. That is, - * in FBE and PBE modes, enable low power will set MCG to BLPE mode, in FBI and - * PBI mode, enable low power will set MCG to BLPI mode. - * When disable MCG low power, the PLL or FLL will be enabled based on MCG setting. + * Enabling the MCG low power disables the PLL and FLL in bypass modes. In other words, + * in FBE and PBE modes, enabling low power sets the MCG to BLPE mode. In FBI and + * PBI modes, enabling low power sets the MCG to BLPI mode. + * When disabling the MCG low power, the PLL or FLL are enabled based on MCG settings. * * @param enable True to enable MCG low power, false to disable MCG low power. */ @@ -1096,42 +1161,56 @@ static inline void CLOCK_SetLowPowerEnable(bool enable) } /*! - * @brief Configure the Internal Reference clock (MCGIRCLK) + * @brief Configures the Internal Reference clock (MCGIRCLK). * - * This function setups the \c MCGIRCLK base on parameters. It selects the IRC - * source, if fast IRC is used, this function also sets the fast IRC divider. - * This function also sets whether enable \c MCGIRCLK in stop mode. - * Calling this function in FBI/PBI/BLPI modes may change the system clock, so - * it is not allowed to use this in these modes. + * This function sets the \c MCGIRCLK base on parameters. It also selects the IRC + * source. If the fast IRC is used, this function sets the fast IRC divider. + * This function also sets whether the \c MCGIRCLK is enabled in stop mode. + * Calling this function in FBI/PBI/BLPI modes may change the system clock. As a result, + * using the function in these modes it is not allowed. * * @param enableMode MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. * @param ircs MCGIRCLK clock source, choose fast or slow. * @param fcrdiv Fast IRC divider setting (\c FCRDIV). - * @retval kStatus_MCG_SourceUsed MCGIRCLK is used as system clock, should not configure MCGIRCLK. + * @retval kStatus_MCG_SourceUsed Because the internall reference clock is used as a clock source, + * the confuration should not be changed. Otherwise, a glitch occurs. * @retval kStatus_Success MCGIRCLK configuration finished successfully. */ status_t CLOCK_SetInternalRefClkConfig(uint8_t enableMode, mcg_irc_mode_t ircs, uint8_t fcrdiv); /*! - * @brief Select the MCG external reference clock. + * @brief Selects the MCG external reference clock. * - * Select the MCG external reference clock source, it changes the MCG_C7[OSCSEL] - * and wait for the clock source stable. Should not change external reference - * clock in FEE/FBE/BLPE/PBE/PEE mdes, so don't call this function in these modes. + * Selects the MCG external reference clock source, changes the MCG_C7[OSCSEL], + * and waits for the clock source to be stable. Because the external reference + * clock should not be changed in FEE/FBE/BLPE/PBE/PEE modes, do not call this function in these modes. * * @param oscsel MCG external reference clock source, MCG_C7[OSCSEL]. - * @retval kStatus_MCG_SourceUsed External reference clock is used, should not change. + * @retval kStatus_MCG_SourceUsed Because the external reference clock is used as a clock source, + * the confuration should not be changed. Otherwise, a glitch occurs. * @retval kStatus_Success External reference clock set successfully. */ status_t CLOCK_SetExternalRefClkConfig(mcg_oscsel_t oscsel); +/*! + * @brief Set the FLL external reference clock divider value. + * + * Sets the FLL external reference clock divider value, the register MCG_C1[FRDIV]. + * + * @param frdiv The FLL external reference clock divider value, MCG_C1[FRDIV]. + */ +static inline void CLOCK_SetFllExtRefDiv(uint8_t frdiv) +{ + MCG->C1 = (MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv); +} + /*! * @brief Enables the PLL0 in FLL mode. * - * This function setups the PLL0 in FLL mode, make sure the PLL reference - * clock is enabled before calling this function. This function reconfigures - * the PLL0, make sure the PLL0 is not used as a clock source while calling - * this function. The function CLOCK_CalcPllDiv can help to get the proper PLL + * This function sets us the PLL0 in FLL mode and reconfigures + * the PLL0. Ensure that the PLL reference + * clock is enabled before calling this function and that the PLL0 is not used as a clock source. + * The function CLOCK_CalcPllDiv gets the correct PLL * divider values. * * @param config Pointer to the configuration structure. @@ -1141,7 +1220,7 @@ void CLOCK_EnablePll0(mcg_pll_config_t const *config); /*! * @brief Disables the PLL0 in FLL mode. * - * This function disables the PLL0 in FLL mode, it should be used together with + * This function disables the PLL0 in FLL mode. It should be used together with the * @ref CLOCK_EnablePll0. */ static inline void CLOCK_DisablePll0(void) @@ -1150,70 +1229,80 @@ static inline void CLOCK_DisablePll0(void) } /*! - * @brief Calculates the PLL divider setting for desired output frequency. + * @brief Calculates the PLL divider setting for a desired output frequency. * - * This function calculates the proper reference clock divider (\c PRDIV) and - * VCO divider (\c VDIV) to generate desired PLL output frequency. It returns the - * closest frequency PLL could generate, the corresponding \c PRDIV/VDIV are - * returned from parameters. If desired frequency is not valid, this function + * This function calculates the correct reference clock divider (\c PRDIV) and + * VCO divider (\c VDIV) to generate a desired PLL output frequency. It returns the + * closest frequency match with the corresponding \c PRDIV/VDIV + * returned from parameters. If a desired frequency is not valid, this function * returns 0. * * @param refFreq PLL reference clock frequency. * @param desireFreq Desired PLL output frequency. * @param prdiv PRDIV value to generate desired PLL frequency. * @param vdiv VDIV value to generate desired PLL frequency. - * @return Closest frequency PLL could generate. + * @return Closest frequency match that the PLL was able generate. */ uint32_t CLOCK_CalcPllDiv(uint32_t refFreq, uint32_t desireFreq, uint8_t *prdiv, uint8_t *vdiv); +/*! + * @brief Set the PLL selection. + * + * This function sets the PLL selection between PLL0/PLL1/EXTPLL, and waits for + * change finished. + * + * @param pllcs The PLL to select. + */ +void CLOCK_SetPllClkSel(mcg_pll_clk_select_t pllcs); + /*@}*/ /*! @name MCG clock lock monitor functions. */ /*@{*/ /*! - * @brief Set the OSC0 clock monitor mode. + * @brief Sets the OSC0 clock monitor mode. * - * Set the OSC0 clock monitor mode, see @ref mcg_monitor_mode_t for details. + * This function sets the OSC0 clock monitor mode. See @ref mcg_monitor_mode_t for details. * - * @param mode The monitor mode to set. + * @param mode Monitor mode to set. */ void CLOCK_SetOsc0MonitorMode(mcg_monitor_mode_t mode); /*! - * @brief Set the RTC OSC clock monitor mode. + * @brief Sets the RTC OSC clock monitor mode. * - * Set the RTC OSC clock monitor mode, see @ref mcg_monitor_mode_t for details. + * This function sets the RTC OSC clock monitor mode. See @ref mcg_monitor_mode_t for details. * - * @param mode The monitor mode to set. + * @param mode Monitor mode to set. */ void CLOCK_SetRtcOscMonitorMode(mcg_monitor_mode_t mode); /*! - * @brief Set the PLL0 clock monitor mode. + * @brief Sets the PLL0 clock monitor mode. * - * Set the PLL0 clock monitor mode, see @ref mcg_monitor_mode_t for details. + * This function sets the PLL0 clock monitor mode. See @ref mcg_monitor_mode_t for details. * - * @param mode The monitor mode to set. + * @param mode Monitor mode to set. */ void CLOCK_SetPll0MonitorMode(mcg_monitor_mode_t mode); /*! - * @brief Set the external PLL clock monitor mode. + * @brief Sets the external PLL clock monitor mode. * - * Set the external PLL clock monitor mode, see @ref mcg_monitor_mode_t + * This function ets the external PLL clock monitor mode. See @ref mcg_monitor_mode_t * for details. * - * @param mode The monitor mode to set. + * @param mode Monitor mode to set. */ void CLOCK_SetExtPllMonitorMode(mcg_monitor_mode_t mode); /*! - * @brief Get the MCG status flags. + * @brief Gets the MCG status flags. * - * This function gets the MCG clock status flags, all the status flags are + * This function gets the MCG clock status flags. All status flags are * returned as a logical OR of the enumeration @ref _mcg_status_flags_t. To - * check specific flags, compare the return value with the flags. + * check a specific flag, compare the return value with the flag. * * Example: * @code @@ -1239,8 +1328,8 @@ uint32_t CLOCK_GetStatusFlags(void); /*! * @brief Clears the MCG status flags. * - * This function clears the MCG clock lock lost status. The parameter is logical - * OR value of the flags to clear, see @ref _mcg_status_flags_t. + * This function clears the MCG clock lock lost status. The parameter is a logical + * OR value of the flags to clear. See @ref _mcg_status_flags_t. * * Example: * @code @@ -1265,8 +1354,8 @@ void CLOCK_ClearStatusFlags(uint32_t mask); * @brief Configures the OSC external reference clock (OSCERCLK). * * This function configures the OSC external reference clock (OSCERCLK). - * For example, to enable the OSCERCLK in normal mode and stop mode, and also set - * the output divider to 1, as follows: + * This is an example to enable the OSCERCLK in normal and stop modes and also set + * the output divider to 1: * @code oscer_config_t config = @@ -1320,45 +1409,71 @@ static inline void OSC_SetCapLoad(OSC_Type *base, uint8_t capLoad) } /*! - * @brief Initialize OSC0. + * @brief Initializes the OSC0. * - * This function initializes OSC0 according to board configuration. + * This function initializes the OSC0 according to the board configuration. * * @param config Pointer to the OSC0 configuration structure. */ void CLOCK_InitOsc0(osc_config_t const *config); /*! - * @brief Deinitialize OSC0. + * @brief Deinitializes the OSC0. * - * This function deinitializes OSC0. + * This function deinitializes the OSC0. */ void CLOCK_DeinitOsc0(void); /* @} */ +/*! + * @name External clock frequency + * @{ + */ + +/*! + * @brief Sets the XTAL0 frequency based on board settings. + * + * @param freq The XTAL0/EXTAL0 input clock frequency in Hz. + */ +static inline void CLOCK_SetXtal0Freq(uint32_t freq) +{ + g_xtal0Freq = freq; +} + +/*! + * @brief Sets the XTAL32/RTC_CLKIN frequency based on board settings. + * + * @param freq The XTAL32/EXTAL32/RTC_CLKIN input clock frequency in Hz. + */ +static inline void CLOCK_SetXtal32Freq(uint32_t freq) +{ + g_xtal32Freq = freq; +} +/* @} */ + /*! * @name MCG auto-trim machine. * @{ */ /*! - * @brief Auto trim the internal reference clock. + * @brief Auto trims the internal reference clock. * - * This function trims the internal reference clock using external clock. If + * This function trims the internal reference clock by using the external clock. If * successful, it returns the kStatus_Success and the frequency after * trimming is received in the parameter @p actualFreq. If an error occurs, * the error code is returned. * - * @param extFreq External clock frequency, should be bus clock. - * @param desireFreq Frequency want to trim to. - * @param actualFreq Actual frequency after trim. + * @param extFreq External clock frequency, which should be a bus clock. + * @param desireFreq Frequency to trim to. + * @param actualFreq Actual frequency after trimming. * @param atms Trim fast or slow internal reference clock. * @retval kStatus_Success ATM success. - * @retval kStatus_MCG_AtmBusClockInvalid The bus clock is not in allowed range for ATM. + * @retval kStatus_MCG_AtmBusClockInvalid The bus clock is not in allowed range for the ATM. * @retval kStatus_MCG_AtmDesiredFreqInvalid MCGIRCLK could not be trimmed to the desired frequency. - * @retval kStatus_MCG_AtmIrcUsed Could not trim because MCGIRCLK is used as bus clock source. - * @retval kStatus_MCG_AtmHardwareFail Hardware fails during trim. + * @retval kStatus_MCG_AtmIrcUsed Could not trim because MCGIRCLK is used as a bus clock source. + * @retval kStatus_MCG_AtmHardwareFail Hardware fails while trimming. */ status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_t *actualFreq, mcg_atm_select_t atms); /* @} */ @@ -1369,260 +1484,265 @@ status_t CLOCK_TrimInternalRefClk(uint32_t extFreq, uint32_t desireFreq, uint32_ /*! * @brief Gets the current MCG mode. * - * This function checks the MCG registers and determine current MCG mode. + * This function checks the MCG registers and determines the current MCG mode. * - * @return Current MCG mode or error code, see @ref mcg_mode_t. + * @return Current MCG mode or error code; See @ref mcg_mode_t. */ mcg_mode_t CLOCK_GetMode(void); /*! - * @brief Set MCG to FEI mode. + * @brief Sets the MCG to FEI mode. * - * This function sets MCG to FEI mode. If could not set to FEI mode directly - * from current mode, this function returns error. @ref kMCG_Dmx32Default is used in this - * mode because using kMCG_Dmx32Fine with internal reference clock source - * might damage hardware. + * This function sets the MCG to FEI mode. If setting to FEI mode fails + * from the current mode, this function returns an error. * + * @param dmx32 DMX32 in FEI mode. * @param drs The DCO range selection. - * @param fllStableDelay Delay function to make sure FLL is stable, if pass - * in NULL, then does not delay. + * @param fllStableDelay Delay function to ensure that the FLL is stable. Passing + * NULL does not cause a delay. * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. + * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to a frequency above 32768 Hz. */ -status_t CLOCK_SetFeiMode(mcg_drs_t drs, void (*fllStableDelay)(void)); +status_t CLOCK_SetFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); /*! - * @brief Set MCG to FEE mode. + * @brief Sets the MCG to FEE mode. * - * This function sets MCG to FEE mode. If could not set to FEE mode directly - * from current mode, this function returns error. + * This function sets the MCG to FEE mode. If setting to FEE mode fails + * from the current mode, this function returns an error. * * @param frdiv FLL reference clock divider setting, FRDIV. * @param dmx32 DMX32 in FEE mode. * @param drs The DCO range selection. - * @param fllStableDelay Delay function to make sure FLL is stable, if pass - * in NULL, then does not delay. + * @param fllStableDelay Delay function to make sure FLL is stable. Passing + * NULL does not cause a delay. * * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. */ status_t CLOCK_SetFeeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); /*! - * @brief Set MCG to FBI mode. + * @brief Sets the MCG to FBI mode. * - * This function sets MCG to FBI mode. If could not set to FBI mode directly - * from current mode, this function returns error. + * This function sets the MCG to FBI mode. If setting to FBI mode fails + * from the current mode, this function returns an error. * + * @param dmx32 DMX32 in FBI mode. * @param drs The DCO range selection. - * @param fllStableDelay Delay function to make sure FLL is stable. If FLL - * is not used in FBI mode, this parameter could be NULL. Pass in - * NULL does not delay. + * @param fllStableDelay Delay function to make sure FLL is stable. If the FLL + * is not used in FBI mode, this parameter can be NULL. Passing + * NULL does not cause a delay. * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. + * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to frequency above 32768 Hz. */ -status_t CLOCK_SetFbiMode(mcg_drs_t drs, void (*fllStableDelay)(void)); +status_t CLOCK_SetFbiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); /*! - * @brief Set MCG to FBE mode. + * @brief Sets the MCG to FBE mode. * - * This function sets MCG to FBE mode. If could not set to FBE mode directly - * from current mode, this function returns error. + * This function sets the MCG to FBE mode. If setting to FBE mode fails + * from the current mode, this function returns an error. * * @param frdiv FLL reference clock divider setting, FRDIV. * @param dmx32 DMX32 in FBE mode. * @param drs The DCO range selection. - * @param fllStableDelay Delay function to make sure FLL is stable. If FLL - * is not used in FBE mode, this parameter could be NULL. Pass in NULL - * does not delay. + * @param fllStableDelay Delay function to make sure FLL is stable. If the FLL + * is not used in FBE mode, this parameter can be NULL. Passing NULL + * does not cause a delay. * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. */ status_t CLOCK_SetFbeMode(uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); /*! - * @brief Set MCG to BLPI mode. + * @brief Sets the MCG to BLPI mode. * - * This function sets MCG to BLPI mode. If could not set to BLPI mode directly - * from current mode, this function returns error. + * This function sets the MCG to BLPI mode. If setting to BLPI mode fails + * from the current mode, this function returns an error. * * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. */ status_t CLOCK_SetBlpiMode(void); /*! - * @brief Set MCG to BLPE mode. + * @brief Sets the MCG to BLPE mode. * - * This function sets MCG to BLPE mode. If could not set to BLPE mode directly - * from current mode, this function returns error. + * This function sets the MCG to BLPE mode. If setting to BLPE mode fails + * from the current mode, this function returns an error. * * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. */ status_t CLOCK_SetBlpeMode(void); /*! - * @brief Set MCG to PBE mode. + * @brief Sets the MCG to PBE mode. * - * This function sets MCG to PBE mode. If could not set to PBE mode directly - * from current mode, this function returns error. + * This function sets the MCG to PBE mode. If setting to PBE mode fails + * from the current mode, this function returns an error. * * @param pllcs The PLL selection, PLLCS. * @param config Pointer to the PLL configuration. * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. * * @note - * 1. The parameter \c pllcs selects the PLL, for some platforms, there is - * only one PLL, the parameter pllcs is kept for interface compatible. - * 2. The parameter \c config is the PLL configuration structure, on some - * platforms, could choose the external PLL directly. This means that the - * configuration structure is not necessary, pass in NULL for this case. + * 1. The parameter \c pllcs selects the PLL. For platforms with + * only one PLL, the parameter pllcs is kept for interface compatibility. + * 2. The parameter \c config is the PLL configuration structure. On some + * platforms, it is possible to choose the external PLL directly, which renders the + * configuration structure not necessary. In this case, pass in NULL. * For example: CLOCK_SetPbeMode(kMCG_OscselOsc, kMCG_PllClkSelExtPll, NULL); */ status_t CLOCK_SetPbeMode(mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config); /*! - * @brief Set MCG to PEE mode. + * @brief Sets the MCG to PEE mode. * - * This function sets MCG to PEE mode. + * This function sets the MCG to PEE mode. * * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. * - * @note This function only change CLKS to use PLL/FLL output. If the - * PRDIV/VDIV are different from PBE mode, please setup these - * settings in PBE mode and wait for stable then switch to PEE mode. + * @note This function only changes the CLKS to use the PLL/FLL output. If the + * PRDIV/VDIV are different than in the PBE mode, set them up + * in PBE mode and wait. When the clock is stable, switch to PEE mode. */ status_t CLOCK_SetPeeMode(void); /*! - * @brief Switch MCG to FBE mode quickly from external mode. + * @brief Switches the MCG to FBE mode from the external mode. * - * This function changes MCG from external modes (PEE/PBE/BLPE/FEE) to FBE mode quickly. - * It only changes to use external clock as the system clock souce and disable PLL, but does not - * configure FLL settings. This is a lite function with small code size, it is useful - * during mode switch. For example, to switch from PEE mode to FEI mode: + * This function switches the MCG from external modes (PEE/PBE/BLPE/FEE) to the FBE mode quickly. + * The external clock is used as the system clock souce and PLL is disabled. However, + * the FLL settings are not configured. This is a lite function with a small code size, which is useful + * during the mode switch. For example, to switch from PEE mode to FEI mode: * * @code * CLOCK_ExternalModeToFbeModeQuick(); * CLOCK_SetFeiMode(...); * @endcode * - * @retval kStatus_Success Change successfully. - * @retval kStatus_MCG_ModeInvalid Current mode is not external modes, should not call this function. + * @retval kStatus_Success Switched successfully. + * @retval kStatus_MCG_ModeInvalid If the current mode is not an external mode, do not call this function. */ status_t CLOCK_ExternalModeToFbeModeQuick(void); /*! - * @brief Switch MCG to FBI mode quickly from internal modes. + * @brief Switches the MCG to FBI mode from internal modes. * - * This function changes MCG from internal modes (PEI/PBI/BLPI/FEI) to FBI mode quickly. - * It only changes to use MCGIRCLK as the system clock souce and disable PLL, but does not - * configure FLL settings. This is a lite function with small code size, it is useful - * during mode switch. For example, to switch from PEI mode to FEE mode: + * This function switches the MCG from internal modes (PEI/PBI/BLPI/FEI) to the FBI mode quickly. + * The MCGIRCLK is used as the system clock souce and PLL is disabled. However, + * FLL settings are not configured. This is a lite function with a small code size, which is useful + * during the mode switch. For example, to switch from PEI mode to FEE mode: * * @code * CLOCK_InternalModeToFbiModeQuick(); * CLOCK_SetFeeMode(...); * @endcode * - * @retval kStatus_Success Change successfully. - * @retval kStatus_MCG_ModeInvalid Current mode is not internal mode, should not call this function. + * @retval kStatus_Success Switched successfully. + * @retval kStatus_MCG_ModeInvalid If the current mode is not an internal mode, do not call this function. */ status_t CLOCK_InternalModeToFbiModeQuick(void); /*! - * @brief Set MCG to FEI mode during system boot up. + * @brief Sets the MCG to FEI mode during system boot up. * - * This function sets MCG to FEI mode from reset mode, it could be used to - * set up MCG during system boot up. @ref kMCG_Dmx32Default is used in this - * mode because using kMCG_Dmx32Fine with internal reference clock source - * might damage hardware. + * This function sets the MCG to FEI mode from the reset mode. It can also be used to + * set up MCG during system boot up. * + * @param dmx32 DMX32 in FEI mode. * @param drs The DCO range selection. - * @param fllStableDelay Delay function to make sure FLL is stable. + * @param fllStableDelay Delay function to ensure that the FLL is stable. * * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. + * @note If @p dmx32 is set to kMCG_Dmx32Fine, the slow IRC must not be trimmed + * to frequency above 32768 Hz. */ -status_t CLOCK_BootToFeiMode(mcg_drs_t drs, void (*fllStableDelay)(void)); +status_t CLOCK_BootToFeiMode(mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); /*! - * @brief Set MCG to FEE mode during system bootup. + * @brief Sets the MCG to FEE mode during system bootup. * - * This function sets MCG to FEE mode from reset mode, it could be used to - * set up MCG during system boot up. + * This function sets MCG to FEE mode from the reset mode. It can also be used to + * set up the MCG during system boot up. * * @param oscsel OSC clock select, OSCSEL. * @param frdiv FLL reference clock divider setting, FRDIV. * @param dmx32 DMX32 in FEE mode. * @param drs The DCO range selection. - * @param fllStableDelay Delay function to make sure FLL is stable. + * @param fllStableDelay Delay function to ensure that the FLL is stable. * * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. */ status_t CLOCK_BootToFeeMode( mcg_oscsel_t oscsel, uint8_t frdiv, mcg_dmx32_t dmx32, mcg_drs_t drs, void (*fllStableDelay)(void)); /*! - * @brief Set MCG to BLPI mode during system boot up. + * @brief Sets the MCG to BLPI mode during system boot up. * - * This function sets MCG to BLPI mode from reset mode, it could be used to - * setup MCG during sytem boot up. + * This function sets the MCG to BLPI mode from the reset mode. It can also be used to + * set up the MCG during sytem boot up. * * @param fcrdiv Fast IRC divider, FCRDIV. * @param ircs The internal reference clock to select, IRCS. * @param ircEnableMode The MCGIRCLK enable mode, OR'ed value of @ref _mcg_irclk_enable_mode. * * @retval kStatus_MCG_SourceUsed Could not change MCGIRCLK setting. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. */ status_t CLOCK_BootToBlpiMode(uint8_t fcrdiv, mcg_irc_mode_t ircs, uint8_t ircEnableMode); /*! - * @brief Set MCG to BLPE mode during sytem boot up. + * @brief Sets the MCG to BLPE mode during sytem boot up. * - * This function sets MCG to BLPE mode from reset mode, it could be used to - * setup MCG during sytem boot up. + * This function sets the MCG to BLPE mode from the reset mode. It can also be used to + * set up the MCG during sytem boot up. * * @param oscsel OSC clock select, MCG_C7[OSCSEL]. * * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. */ status_t CLOCK_BootToBlpeMode(mcg_oscsel_t oscsel); /*! - * @brief Set MCG to PEE mode during system boot up. + * @brief Sets the MCG to PEE mode during system boot up. * - * This function sets MCG to PEE mode from reset mode, it could be used to - * setup MCG during system boot up. + * This function sets the MCG to PEE mode from reset mode. It can also be used to + * set up the MCG during system boot up. * * @param oscsel OSC clock select, MCG_C7[OSCSEL]. * @param pllcs The PLL selection, PLLCS. * @param config Pointer to the PLL configuration. * * @retval kStatus_MCG_ModeUnreachable Could not switch to the target mode. - * @retval kStatus_Success Switch to target mode successfully. + * @retval kStatus_Success Switched to the target mode successfully. */ status_t CLOCK_BootToPeeMode(mcg_oscsel_t oscsel, mcg_pll_clk_select_t pllcs, mcg_pll_config_t const *config); /*! - * @brief Set MCG to some target mode. + * @brief Sets the MCG to a target mode. * - * This function sets MCG to some target mode defined by the configure - * structure, if cannot switch to target mode directly, this function will - * choose the proper path. + * This function sets MCG to a target mode defined by the configuration + * structure. If switching to the target mode fails, this function + * chooses the correct path. * * @param config Pointer to the target MCG mode configuration structure. - * @return Return kStatus_Success if switch successfully, otherwise return error code #_mcg_status. + * @return Return kStatus_Success if switched successfully; Otherwise, it returns an error code #_mcg_status. * - * @note If external clock is used in the target mode, please make sure it is - * enabled, for example, if the OSC0 is used, please setup OSC0 correctly before - * this funciton. + * @note If the external clock is used in the target mode, ensure that it is + * enabled. For example, if the OSC0 is used, set up OSC0 correctly before calling this + * function. */ status_t CLOCK_SetMcgConfig(mcg_config_t const *config); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmp.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmp.c index 09885e7421..6a5f15a75b 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmp.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmp.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -45,8 +45,10 @@ static uint32_t CMP_GetInstance(CMP_Type *base); ******************************************************************************/ /*! @brief Pointers to CMP bases for each instance. */ static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to CMP clocks for each instance. */ -const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS; +static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Codes @@ -56,7 +58,7 @@ static uint32_t CMP_GetInstance(CMP_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_CMP_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_cmpBases); instance++) { if (s_cmpBases[instance] == base) { @@ -64,7 +66,7 @@ static uint32_t CMP_GetInstance(CMP_Type *base) } } - assert(instance < FSL_FEATURE_SOC_CMP_COUNT); + assert(instance < ARRAY_SIZE(s_cmpBases)); return instance; } @@ -75,8 +77,10 @@ void CMP_Init(CMP_Type *base, const cmp_config_t *config) uint8_t tmp8; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the clock. */ CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure. */ CMP_Enable(base, false); /* Disable the CMP module during configuring. */ @@ -123,8 +127,10 @@ void CMP_Deinit(CMP_Type *base) /* Disable the CMP module. */ CMP_Enable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable the clock. */ CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void CMP_GetDefaultConfig(cmp_config_t *config) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmp.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmp.h index 53d84a0f2d..5d16bf08de 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmp.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmp.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -38,7 +38,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -64,8 +63,8 @@ enum _cmp_interrupt_enable */ enum _cmp_status_flags { - kCMP_OutputRisingEventFlag = CMP_SCR_CFR_MASK, /*!< Rising-edge on compare output has occurred. */ - kCMP_OutputFallingEventFlag = CMP_SCR_CFF_MASK, /*!< Falling-edge on compare output has occurred. */ + kCMP_OutputRisingEventFlag = CMP_SCR_CFR_MASK, /*!< Rising-edge on the comparison output has occurred. */ + kCMP_OutputFallingEventFlag = CMP_SCR_CFF_MASK, /*!< Falling-edge on the comparison output has occurred. */ kCMP_OutputAssertEventFlag = CMP_SCR_COUT_MASK, /*!< Return the current value of the analog comparator output. */ }; @@ -85,20 +84,20 @@ typedef enum _cmp_hysteresis_mode */ typedef enum _cmp_reference_voltage_source { - kCMP_VrefSourceVin1 = 0U, /*!< Vin1 is selected as resistor ladder network supply reference Vin. */ - kCMP_VrefSourceVin2 = 1U, /*!< Vin2 is selected as resistor ladder network supply reference Vin. */ + kCMP_VrefSourceVin1 = 0U, /*!< Vin1 is selected as a resistor ladder network supply reference Vin. */ + kCMP_VrefSourceVin2 = 1U, /*!< Vin2 is selected as a resistor ladder network supply reference Vin. */ } cmp_reference_voltage_source_t; /*! - * @brief Configure the comparator. + * @brief Configures the comparator. */ typedef struct _cmp_config { bool enableCmp; /*!< Enable the CMP module. */ cmp_hysteresis_mode_t hysteresisMode; /*!< CMP Hysteresis mode. */ - bool enableHighSpeed; /*!< Enable High Speed (HS) comparison mode. */ - bool enableInvertOutput; /*!< Enable inverted comparator output. */ - bool useUnfilteredOutput; /*!< Set compare output(COUT) to equal COUTA(true) or COUT(false). */ + bool enableHighSpeed; /*!< Enable High-speed (HS) comparison mode. */ + bool enableInvertOutput; /*!< Enable the inverted comparator output. */ + bool useUnfilteredOutput; /*!< Set the compare output(COUT) to equal COUTA(true) or COUT(false). */ bool enablePinOut; /*!< The comparator output is available on the associated pin. */ #if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE bool enableTriggerMode; /*!< Enable the trigger mode. */ @@ -106,24 +105,24 @@ typedef struct _cmp_config } cmp_config_t; /*! - * @brief Configure the filter. + * @brief Configures the filter. */ typedef struct _cmp_filter_config { #if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT - bool enableSample; /*!< Using external SAMPLE as sampling clock input, or using divided bus clock. */ + bool enableSample; /*!< Using the external SAMPLE as a sampling clock input or using a divided bus clock. */ #endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */ - uint8_t filterCount; /*!< Filter Sample Count. Available range is 1-7, 0 would cause the filter disabled.*/ - uint8_t filterPeriod; /*!< Filter Sample Period. The divider to bus clock. Available range is 0-255. */ + uint8_t filterCount; /*!< Filter Sample Count. Available range is 1-7; 0 disables the filter.*/ + uint8_t filterPeriod; /*!< Filter Sample Period. The divider to the bus clock. Available range is 0-255. */ } cmp_filter_config_t; /*! - * @brief Configure the internal DAC. + * @brief Configures the internal DAC. */ typedef struct _cmp_dac_config { cmp_reference_voltage_source_t referenceVoltageSource; /*!< Supply voltage reference source. */ - uint8_t DACValue; /*!< Value for DAC Output Voltage. Available range is 0-63.*/ + uint8_t DACValue; /*!< Value for the DAC Output Voltage. Available range is 0-63.*/ } cmp_dac_config_t; #if defined(__cplusplus) @@ -142,28 +141,28 @@ extern "C" { /*! * @brief Initializes the CMP. * - * This function initializes the CMP module. The operations included are: + * This function initializes the CMP module. The operations included are as follows. * - Enabling the clock for CMP module. * - Configuring the comparator. * - Enabling the CMP module. - * Note: For some devices, multiple CMP instance share the same clock gate. In this case, to enable the clock for - * any instance enables all the CMPs. Check the chip reference manual for the clock assignment of the CMP. + * Note that for some devices, multiple CMP instances share the same clock gate. In this case, to enable the clock for + * any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP. * * @param base CMP peripheral base address. - * @param config Pointer to configuration structure. + * @param config Pointer to the configuration structure. */ void CMP_Init(CMP_Type *base, const cmp_config_t *config); /*! * @brief De-initializes the CMP module. * - * This function de-initializes the CMP module. The operations included are: + * This function de-initializes the CMP module. The operations included are as follows. * - Disabling the CMP module. * - Disabling the clock for CMP module. * * This function disables the clock for the CMP. - * Note: For some devices, multiple CMP instance shares the same clock gate. In this case, before disabling the - * clock for the CMP, ensure that all the CMP instances are not used. + * Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the + * clock for the CMP, ensure that all the CMP instances are not used. * * @param base CMP peripheral base address. */ @@ -173,7 +172,7 @@ void CMP_Deinit(CMP_Type *base); * @brief Enables/disables the CMP module. * * @param base CMP peripheral base address. - * @param enable Enable the module or not. + * @param enable Enables or disables the module. */ static inline void CMP_Enable(CMP_Type *base, bool enable) { @@ -190,7 +189,7 @@ static inline void CMP_Enable(CMP_Type *base, bool enable) /*! * @brief Initializes the CMP user configuration structure. * -* This function initializes the user configure structure to these default values: +* This function initializes the user configuration structure to these default values. * @code * config->enableCmp = true; * config->hysteresisMode = kCMP_HysteresisLevel0; @@ -208,7 +207,7 @@ void CMP_GetDefaultConfig(cmp_config_t *config); * @brief Sets the input channels for the comparator. * * This function sets the input channels for the comparator. - * Note that two input channels cannot be set as same in the application. When the user selects the same input + * Note that two input channels cannot be set the same way in the application. When the user selects the same input * from the analog mux to the positive and negative port, the comparator is disabled automatically. * * @param base CMP peripheral base address. @@ -229,13 +228,11 @@ void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negat * @brief Enables/disables the DMA request for rising/falling events. * * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of - * the DMA - * request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from the CMP - * if the - * DMA is disabled. + * the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from the CMP + * if the DMA is disabled. * * @param base CMP peripheral base address. - * @param enable Enable the feature or not. + * @param enable Enables or disables the feature. */ void CMP_EnableDMA(CMP_Type *base, bool enable); #endif /* FSL_FEATURE_CMP_HAS_DMA */ @@ -245,7 +242,7 @@ void CMP_EnableDMA(CMP_Type *base, bool enable); * @brief Enables/disables the window mode. * * @param base CMP peripheral base address. - * @param enable Enable the feature or not. + * @param enable Enables or disables the feature. */ static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable) { @@ -265,7 +262,7 @@ static inline void CMP_EnableWindowMode(CMP_Type *base, bool enable) * @brief Enables/disables the pass through mode. * * @param base CMP peripheral base address. - * @param enable Enable the feature or not. + * @param enable Enables or disables the feature. */ static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable) { @@ -284,7 +281,7 @@ static inline void CMP_EnablePassThroughMode(CMP_Type *base, bool enable) * @brief Configures the filter. * * @param base CMP peripheral base address. - * @param config Pointer to configuration structure. + * @param config Pointer to the configuration structure. */ void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config); @@ -292,7 +289,7 @@ void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config); * @brief Configures the internal DAC. * * @param base CMP peripheral base address. - * @param config Pointer to configuration structure. "NULL" is for disabling the feature. + * @param config Pointer to the configuration structure. "NULL" disables the feature. */ void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmt.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmt.c index 9e8831f998..8cf72bc7e7 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmt.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmt.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -46,8 +46,6 @@ #define CMT_CMTDIV_FOUR (4) /* CMT diver 8. */ #define CMT_CMTDIV_EIGHT (8) -/* CMT mode bit mask. */ -#define CMT_MODE_BIT_MASK (CMT_MSC_MCGEN_MASK | CMT_MSC_FSK_MASK | CMT_MSC_BASE_MASK) /******************************************************************************* * Prototypes @@ -64,14 +62,16 @@ static uint32_t CMT_GetInstance(CMT_Type *base); * Variables ******************************************************************************/ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to cmt clocks for each instance. */ -const clock_ip_name_t s_cmtClock[FSL_FEATURE_SOC_CMT_COUNT] = CMT_CLOCKS; +static const clock_ip_name_t s_cmtClock[FSL_FEATURE_SOC_CMT_COUNT] = CMT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Pointers to cmt bases for each instance. */ static CMT_Type *const s_cmtBases[] = CMT_BASE_PTRS; /*! @brief Pointers to cmt IRQ number for each instance. */ -const IRQn_Type s_cmtIrqs[] = CMT_IRQS; +static const IRQn_Type s_cmtIrqs[] = CMT_IRQS; /******************************************************************************* * Codes @@ -82,7 +82,7 @@ static uint32_t CMT_GetInstance(CMT_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_CMT_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_cmtBases); instance++) { if (s_cmtBases[instance] == base) { @@ -90,7 +90,7 @@ static uint32_t CMT_GetInstance(CMT_Type *base) } } - assert(instance < FSL_FEATURE_SOC_CMT_COUNT); + assert(instance < ARRAY_SIZE(s_cmtBases)); return instance; } @@ -113,8 +113,10 @@ void CMT_Init(CMT_Type *base, const cmt_config_t *config, uint32_t busClock_Hz) uint8_t divider; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Ungate clock. */ CLOCK_EnableClock(s_cmtClock[CMT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Sets clock divider. The divider set in pps should be set to make sycClock_Hz/divder = 8MHz */ @@ -144,15 +146,17 @@ void CMT_Deinit(CMT_Type *base) CMT_DisableInterrupts(base, kCMT_EndOfCycleInterruptEnable); DisableIRQ(s_cmtIrqs[CMT_GetInstance(base)]); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate the clock. */ CLOCK_DisableClock(s_cmtClock[CMT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulateConfig) { - uint8_t mscReg; + uint8_t mscReg = base->MSC; - /* Set the mode. */ + /* Judge the mode. */ if (mode != kCMT_DirectIROCtl) { assert(modulateConfig); @@ -166,13 +170,14 @@ void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulat /* Set carrier modulator. */ CMT_SetModulateMarkSpace(base, modulateConfig->markCount, modulateConfig->spaceCount); + mscReg &= ~ (CMT_MSC_FSK_MASK | CMT_MSC_BASE_MASK); + mscReg |= mode; + } + else + { + mscReg &= ~CMT_MSC_MCGEN_MASK; } - /* Set the CMT mode. */ - mscReg = base->MSC; - mscReg &= ~CMT_MODE_BIT_MASK; - mscReg |= mode; - base->MSC = mscReg; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmt.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmt.h index df0b2c9106..3d81f8a9a4 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmt.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_cmt.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,7 +37,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -45,8 +44,8 @@ /*! @name Driver version */ /*@{*/ -/*! @brief CMT driver version 2.0.0. */ -#define FSL_CMT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*! @brief CMT driver version 2.0.1. */ +#define FSL_CMT_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*@}*/ /*! @@ -128,15 +127,15 @@ enum _cmt_interrupt_enable }; /*! - * @brief CMT carrier generator and modulator configure structure + * @brief CMT carrier generator and modulator configuration structure * */ typedef struct _cmt_modulate_config { - uint8_t highCount1; /*!< The high time for carrier generator first register. */ - uint8_t lowCount1; /*!< The low time for carrier generator first register. */ - uint8_t highCount2; /*!< The high time for carrier generator second register for FSK mode. */ - uint8_t lowCount2; /*!< The low time for carrier generator second register for FSK mode. */ + uint8_t highCount1; /*!< The high-time for carrier generator first register. */ + uint8_t lowCount1; /*!< The low-time for carrier generator first register. */ + uint8_t highCount2; /*!< The high-time for carrier generator second register for FSK mode. */ + uint8_t lowCount2; /*!< The low-time for carrier generator second register for FSK mode. */ uint16_t markCount; /*!< The mark time for the modulator gate. */ uint16_t spaceCount; /*!< The space time for the modulator gate. */ } cmt_modulate_config_t; @@ -164,10 +163,10 @@ extern "C" { */ /*! - * @brief Gets the CMT default configuration structure. The purpose - * of this API is to get the default configuration structure for the CMT_Init(). - * Use the initialized structure unchanged in CMT_Init(), or modify - * some fields of the structure before calling the CMT_Init(). + * @brief Gets the CMT default configuration structure. This API + * gets the default configuration structure for the CMT_Init(). + * Use the initialized structure unchanged in CMT_Init() or modify + * fields of the structure before calling the CMT_Init(). * * @param config The CMT configuration structure pointer. */ @@ -216,7 +215,7 @@ void CMT_SetMode(CMT_Type *base, cmt_mode_t mode, cmt_modulate_config_t *modulat * * @param base CMT peripheral base address. * @return The CMT mode. - * kCMT_DirectIROCtl Carrier modulator is disabled, the IRO signal is directly in software control. + * kCMT_DirectIROCtl Carrier modulator is disabled; the IRO signal is directly in software control. * kCMT_TimeMode Carrier modulator is enabled in time mode. * kCMT_FSKMode Carrier modulator is enabled in FSK mode. * kCMT_BasebandMode Carrier modulator is enabled in baseband mode. @@ -235,11 +234,11 @@ uint32_t CMT_GetCMTFrequency(CMT_Type *base, uint32_t busClock_Hz); /*! * @brief Sets the primary data set for the CMT carrier generator counter. * - * This function sets the high time and low time of the primary data set for the + * This function sets the high-time and low-time of the primary data set for the * CMT carrier generator counter to control the period and the duty cycle of the * output carrier signal. - * If the CMT clock period is Tcmt, The period of the carrier generator signal equals - * (highCount + lowCount) * Tcmt. The duty cycle equals highCount / (highCount + lowCount). + * If the CMT clock period is Tcmt, the period of the carrier generator signal equals + * (highCount + lowCount) * Tcmt. The duty cycle equals to highCount / (highCount + lowCount). * * @param base CMT peripheral base address. * @param highCount The number of CMT clocks for carrier generator signal high time, @@ -261,10 +260,10 @@ static inline void CMT_SetCarrirGenerateCountOne(CMT_Type *base, uint32_t highCo /*! * @brief Sets the secondary data set for the CMT carrier generator counter. * - * This function is used for FSK mode setting the high time and low time of the secondary + * This function is used for FSK mode setting the high-time and low-time of the secondary * data set CMT carrier generator counter to control the period and the duty cycle * of the output carrier signal. - * If the CMT clock period is Tcmt, The period of the carrier generator signal equals + * If the CMT clock period is Tcmt, the period of the carrier generator signal equals * (highCount + lowCount) * Tcmt. The duty cycle equals highCount / (highCount + lowCount). * * @param base CMT peripheral base address. @@ -325,7 +324,7 @@ static inline void CMT_EnableExtendedSpace(CMT_Type *base, bool enable) } /*! - * @brief Sets IRO - infrared output signal state. + * @brief Sets the IRO (infrared output) signal state. * * Changes the states of the IRO signal when the kCMT_DirectIROMode mode is set * and the IRO signal is enabled. @@ -338,12 +337,12 @@ void CMT_SetIroState(CMT_Type *base, cmt_infrared_output_state_t state); /*! * @brief Enables the CMT interrupt. * - * This function enables the CMT interrupts according to the provided maskIf enabled. + * This function enables the CMT interrupts according to the provided mask if enabled. * The CMT only has the end of the cycle interrupt - an interrupt occurs at the end * of the modulator cycle. This interrupt provides a means for the user * to reload the new mark/space values into the CMT modulator data registers * and verify the modulator mark and space. - * For example, to enable the end of cycle, do the following: + * For example, to enable the end of cycle, do the following. * @code * CMT_EnableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable); * @endcode @@ -360,7 +359,7 @@ static inline void CMT_EnableInterrupts(CMT_Type *base, uint32_t mask) * * This function disables the CMT interrupts according to the provided maskIf enabled. * The CMT only has the end of the cycle interrupt. - * For example, to disable the end of cycle, do the following: + * For example, to disable the end of cycle, do the following. * @code * CMT_DisableInterrupts(CMT, kCMT_EndOfCycleInterruptEnable); * @endcode diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_common.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_common.h index 7061b62139..b20ec09973 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_common.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_common.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -34,8 +34,12 @@ #include #include #include -#include #include + +#if defined(__ICCARM__) +#include +#endif + #include "fsl_device_registers.h" /*! @@ -43,8 +47,6 @@ * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ @@ -56,11 +58,13 @@ #define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) /* Debug console type definition. */ -#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */ -#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console base on UART. */ -#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */ -#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console base on LPSCI. */ -#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console base on UART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console base on LPSCI. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console base on USBCDC. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console base on i.MX UART. */ /*! @brief Status group numbers. */ enum _status_groups @@ -87,6 +91,11 @@ enum _status_groups kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */ kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */ kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */ + kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */ + kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */ + kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */ + kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */ + kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */ kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */ kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */ kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */ @@ -101,6 +110,18 @@ enum _status_groups kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */ kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */ kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */ + kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */ + kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */ + kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */ + kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/ + kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */ + kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */ + kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */ + kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */ + kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */ + kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/ + kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */ + kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */ kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */ kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */ kStatusGroup_ApplicationRangeStart = 100, /*!< Starting number for application groups. */ @@ -127,6 +148,14 @@ typedef int32_t status_t; */ #include "fsl_clock.h" +/* + * Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral + */ +#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \ + (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0))) +#include "fsl_reset.h" +#endif + /*! @name Min/max macros */ /* @{ */ #if !defined(MIN) @@ -182,11 +211,20 @@ extern "C" { */ static inline void EnableIRQ(IRQn_Type interrupt) { + if (NotAvail_IRQn == interrupt) + { + return; + } + #if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0) if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX) #endif { +#if defined(__GIC_PRIO_BITS) + GIC_EnableIRQ(interrupt); +#else NVIC_EnableIRQ(interrupt); +#endif } } @@ -199,11 +237,20 @@ static inline void EnableIRQ(IRQn_Type interrupt) */ static inline void DisableIRQ(IRQn_Type interrupt) { + if (NotAvail_IRQn == interrupt) + { + return; + } + #if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT > 0) if (interrupt < FSL_FEATURE_INTMUX_IRQ_START_INDEX) #endif { +#if defined(__GIC_PRIO_BITS) + GIC_DisableIRQ(interrupt); +#else NVIC_DisableIRQ(interrupt); +#endif } } @@ -217,11 +264,19 @@ static inline void DisableIRQ(IRQn_Type interrupt) */ static inline uint32_t DisableGlobalIRQ(void) { +#if defined(CPSR_I_Msk) + uint32_t cpsr = __get_CPSR() & CPSR_I_Msk; + + __disable_irq(); + + return cpsr; +#else uint32_t regPrimask = __get_PRIMASK(); __disable_irq(); return regPrimask; +#endif } /*! @@ -236,7 +291,11 @@ static inline uint32_t DisableGlobalIRQ(void) */ static inline void EnableGlobalIRQ(uint32_t primask) { +#if defined(CPSR_I_Msk) + __set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask); +#else __set_PRIMASK(primask); +#endif } /*! @@ -244,9 +303,42 @@ static inline void EnableGlobalIRQ(uint32_t primask) * * @param irq IRQ number * @param irqHandler IRQ handler address + * @return The old IRQ handler address */ void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); +#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) +/*! + * @brief Enable specific interrupt for wake-up from deep-sleep mode. + * + * Enable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internally). + * + * @param interrupt The IRQ number. + */ +void EnableDeepSleepIRQ(IRQn_Type interrupt); + +/*! + * @brief Disable specific interrupt for wake-up from deep-sleep mode. + * + * Disable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internally). + * + * @param interrupt The IRQ number. + */ +void DisableDeepSleepIRQ(IRQn_Type interrupt); +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ + #if defined(__cplusplus) } #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_crc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_crc.c index f73647e1c7..dba1db8c46 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_crc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_crc.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -32,6 +32,11 @@ /******************************************************************************* * Definitions ******************************************************************************/ +/*! @internal @brief Has data register with name CRC. */ +#if defined(FSL_FEATURE_CRC_HAS_CRC_REG) && FSL_FEATURE_CRC_HAS_CRC_REG +#define DATA CRC +#define DATALL CRCLL +#endif #if defined(CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT) && CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT /* @brief Default user configuration structure for CRC-16-CCITT */ @@ -87,7 +92,7 @@ typedef struct _crc_module_config * * @param enable True or false for the selected CRC protocol Reflect In (refin) parameter. */ -static inline crc_transpose_type_t crc_GetTransposeTypeFromReflectIn(bool enable) +static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectIn(bool enable) { return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeBytes); } @@ -99,7 +104,7 @@ static inline crc_transpose_type_t crc_GetTransposeTypeFromReflectIn(bool enable * * @param enable True or false for the selected CRC protocol Reflect Out (refout) parameter. */ -static inline crc_transpose_type_t crc_GetTransposeTypeFromReflectOut(bool enable) +static inline crc_transpose_type_t CRC_GetTransposeTypeFromReflectOut(bool enable) { return ((enable) ? kCrcTransposeBitsAndBytes : kCrcTransposeNone); } @@ -113,7 +118,7 @@ static inline crc_transpose_type_t crc_GetTransposeTypeFromReflectOut(bool enabl * @param base CRC peripheral address. * @param config Pointer to protocol configuration structure. */ -static void crc_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *config) +static void CRC_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *config) { uint32_t crcControl; @@ -148,18 +153,18 @@ static void crc_ConfigureAndStart(CRC_Type *base, const crc_module_config_t *con * @param base CRC peripheral address. * @param protocolConfig Pointer to protocol configuration structure. */ -static void crc_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) +static void CRC_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) { crc_module_config_t moduleConfig; /* convert protocol to CRC peripheral module configuration, prepare for final checksum */ moduleConfig.polynomial = protocolConfig->polynomial; moduleConfig.seed = protocolConfig->seed; - moduleConfig.readTranspose = crc_GetTransposeTypeFromReflectOut(protocolConfig->reflectOut); - moduleConfig.writeTranspose = crc_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); + moduleConfig.readTranspose = CRC_GetTransposeTypeFromReflectOut(protocolConfig->reflectOut); + moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); moduleConfig.complementChecksum = protocolConfig->complementChecksum; moduleConfig.crcBits = protocolConfig->crcBits; - crc_ConfigureAndStart(base, &moduleConfig); + CRC_ConfigureAndStart(base, &moduleConfig); } /*! @@ -172,7 +177,7 @@ static void crc_SetProtocolConfig(CRC_Type *base, const crc_config_t *protocolCo * @param base CRC peripheral address. * @param protocolConfig Pointer to protocol configuration structure. */ -static void crc_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) +static void CRC_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protocolConfig) { crc_module_config_t moduleConfig; /* convert protocol to CRC peripheral module configuration, prepare for intermediate checksum */ @@ -180,25 +185,27 @@ static void crc_SetRawProtocolConfig(CRC_Type *base, const crc_config_t *protoco moduleConfig.seed = protocolConfig->seed; moduleConfig.readTranspose = kCrcTransposeNone; /* intermediate checksum does no transpose of data register read value */ - moduleConfig.writeTranspose = crc_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); + moduleConfig.writeTranspose = CRC_GetTransposeTypeFromReflectIn(protocolConfig->reflectIn); moduleConfig.complementChecksum = false; /* intermediate checksum does no xor of data register read value */ moduleConfig.crcBits = protocolConfig->crcBits; - crc_ConfigureAndStart(base, &moduleConfig); + CRC_ConfigureAndStart(base, &moduleConfig); } void CRC_Init(CRC_Type *base, const crc_config_t *config) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* ungate clock */ CLOCK_EnableClock(kCLOCK_Crc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* configure CRC module and write the seed */ if (config->crcResult == kCrcFinalChecksum) { - crc_SetProtocolConfig(base, config); + CRC_SetProtocolConfig(base, config); } else { - crc_SetRawProtocolConfig(base, config); + CRC_SetRawProtocolConfig(base, config); } } @@ -246,6 +253,11 @@ void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize) } } +uint32_t CRC_Get32bitResult(CRC_Type *base) +{ + return base->DATA; +} + uint16_t CRC_Get16bitResult(CRC_Type *base) { uint32_t retval; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_crc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_crc.h index ce0b60fbaf..247a9bac78 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_crc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_crc.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -34,28 +34,27 @@ #include "fsl_common.h" /*! - * @addtogroup crc_driver + * @addtogroup crc * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief CRC driver version. Version 2.0.0. */ -#define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*! @brief CRC driver version. Version 2.0.1. + * + * Current version: 2.0.1 + * + * Change log: + * - Version 2.0.1 + * - move DATA and DATALL macro definition from header file to source file + */ +#define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*@}*/ -/*! @internal @brief Has data register with name CRC. */ -#if defined(FSL_FEATURE_CRC_HAS_CRC_REG) && FSL_FEATURE_CRC_HAS_CRC_REG -#define DATA CRC -#define DATALL CRCLL -#endif - #ifndef CRC_DRIVER_CUSTOM_DEFAULTS /*! @brief Default configuration structure filled by CRC_GetDefaultConfig(). Use CRC16-CCIT-FALSE as defeault. */ #define CRC_DRIVER_USE_CRC16_CCIT_FALSE_AS_DEFAULT 1 @@ -108,31 +107,33 @@ extern "C" { /*! * @brief Enables and configures the CRC peripheral module. * - * This functions enables the clock gate in the Kinetis SIM module for the CRC peripheral. - * It also configures the CRC module and starts checksum computation by writing the seed. + * This function enables the clock gate in the SIM module for the CRC peripheral. + * It also configures the CRC module and starts a checksum computation by writing the seed. * * @param base CRC peripheral address. - * @param config CRC module configuration structure + * @param config CRC module configuration structure. */ void CRC_Init(CRC_Type *base, const crc_config_t *config); /*! * @brief Disables the CRC peripheral module. * - * This functions disables the clock gate in the Kinetis SIM module for the CRC peripheral. + * This function disables the clock gate in the SIM module for the CRC peripheral. * * @param base CRC peripheral address. */ static inline void CRC_Deinit(CRC_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* gate clock */ CLOCK_DisableClock(kCLOCK_Crc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } /*! - * @brief Loads default values to CRC protocol configuration structure. + * @brief Loads default values to the CRC protocol configuration structure. * - * Loads default values to CRC protocol configuration structure. The default values are: + * Loads default values to the CRC protocol configuration structure. The default values are as follows. * @code * config->polynomial = 0x1021; * config->seed = 0xFFFF; @@ -143,14 +144,14 @@ static inline void CRC_Deinit(CRC_Type *base) * config->crcResult = kCrcFinalChecksum; * @endcode * - * @param config CRC protocol configuration structure + * @param config CRC protocol configuration structure. */ void CRC_GetDefaultConfig(crc_config_t *config); /*! * @brief Writes data to the CRC module. * - * Writes input data buffer bytes to CRC data register. + * Writes input data buffer bytes to the CRC data register. * The configured type of transpose is applied. * * @param base CRC peripheral address. @@ -160,27 +161,24 @@ void CRC_GetDefaultConfig(crc_config_t *config); void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize); /*! - * @brief Reads 32-bit checksum from the CRC module. + * @brief Reads the 32-bit checksum from the CRC module. * - * Reads CRC data register (intermediate or final checksum). - * The configured type of transpose and complement are applied. + * Reads the CRC data register (either an intermediate or the final checksum). + * The configured type of transpose and complement is applied. * * @param base CRC peripheral address. - * @return intermediate or final 32-bit checksum, after configured transpose and complement operations. + * @return An intermediate or the final 32-bit checksum, after configured transpose and complement operations. */ -static inline uint32_t CRC_Get32bitResult(CRC_Type *base) -{ - return base->DATA; -} +uint32_t CRC_Get32bitResult(CRC_Type *base); /*! - * @brief Reads 16-bit checksum from the CRC module. + * @brief Reads a 16-bit checksum from the CRC module. * - * Reads CRC data register (intermediate or final checksum). - * The configured type of transpose and complement are applied. + * Reads the CRC data register (either an intermediate or the final checksum). + * The configured type of transpose and complement is applied. * * @param base CRC peripheral address. - * @return intermediate or final 16-bit checksum, after configured transpose and complement operations. + * @return An intermediate or the final 16-bit checksum, after configured transpose and complement operations. */ uint16_t CRC_Get16bitResult(CRC_Type *base); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dac.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dac.c index 2f83f5ee9e..8d13d62283 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dac.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dac.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -45,8 +45,10 @@ static uint32_t DAC_GetInstance(DAC_Type *base); ******************************************************************************/ /*! @brief Pointers to DAC bases for each instance. */ static DAC_Type *const s_dacBases[] = DAC_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to DAC clocks for each instance. */ -const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS; +static const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Codes @@ -56,7 +58,7 @@ static uint32_t DAC_GetInstance(DAC_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_DAC_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_dacBases); instance++) { if (s_dacBases[instance] == base) { @@ -64,7 +66,7 @@ static uint32_t DAC_GetInstance(DAC_Type *base) } } - assert(instance < FSL_FEATURE_SOC_DAC_COUNT); + assert(instance < ARRAY_SIZE(s_dacBases)); return instance; } @@ -75,8 +77,10 @@ void DAC_Init(DAC_Type *base, const dac_config_t *config) uint8_t tmp8; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the clock. */ CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure. */ /* DACx_C0. */ @@ -91,15 +95,18 @@ void DAC_Init(DAC_Type *base, const dac_config_t *config) } base->C0 = tmp8; - DAC_Enable(base, true); + /* DAC_Enable(base, true); */ + /* Tip: The DAC output can be enabled till then after user sets their own available data in application. */ } void DAC_Deinit(DAC_Type *base) { DAC_Enable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable the clock. */ CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void DAC_GetDefaultConfig(dac_config_t *config) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dac.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dac.h index 44e2d048bd..b71febf3bc 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dac.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dac.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -38,7 +38,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -46,8 +45,8 @@ /*! @name Driver version */ /*@{*/ -/*! @brief DAC driver version 2.0.0. */ -#define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*! @brief DAC driver version 2.0.1. */ +#define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*@}*/ /*! @@ -104,15 +103,15 @@ typedef enum _dac_buffer_watermark #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD kDAC_BufferWatermark1Word = 0U, /*!< 1 word away from the upper limit. */ #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_1_WORD */ -#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS kDAC_BufferWatermark2Word = 1U, /*!< 2 words away from the upper limit. */ -#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_2_WORD */ -#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_2_WORDS */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS kDAC_BufferWatermark3Word = 2U, /*!< 3 words away from the upper limit. */ -#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_3_WORD */ -#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD) && FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_3_WORDS */ +#if defined(FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS) && FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS kDAC_BufferWatermark4Word = 3U, /*!< 4 words away from the upper limit. */ -#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_4_WORD */ +#endif /* FSL_FEATURE_DAC_HAS_WATERMARK_4_WORDS */ } dac_buffer_watermark_t; #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ @@ -137,7 +136,7 @@ typedef enum _dac_buffer_work_mode typedef struct _dac_config { dac_reference_voltage_source_t referenceVoltageSource; /*!< Select the DAC reference voltage source. */ - bool enableLowPowerMode; /*!< Enable the low power mode. */ + bool enableLowPowerMode; /*!< Enable the low-power mode. */ } dac_config_t; /*! @@ -150,8 +149,8 @@ typedef struct _dac_buffer_config dac_buffer_watermark_t watermark; /*!< Select the buffer's watermark. */ #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */ dac_buffer_work_mode_t workMode; /*!< Select the buffer's work mode. */ - uint8_t upperLimit; /*!< Set the upper limit for buffer index. - Normally, 0-15 is available for buffer with 16 item. */ + uint8_t upperLimit; /*!< Set the upper limit for the buffer index. + Normally, 0-15 is available for a buffer with 16 items. */ } dac_buffer_config_t; /******************************************************************************* @@ -169,7 +168,7 @@ extern "C" { /*! * @brief Initializes the DAC module. * - * This function initializes the DAC module, including: + * This function initializes the DAC module including the following operations. * - Enabling the clock for DAC module. * - Configuring the DAC converter with a user configuration. * - Enabling the DAC module. @@ -182,7 +181,7 @@ void DAC_Init(DAC_Type *base, const dac_config_t *config); /*! * @brief De-initializes the DAC module. * - * This function de-initializes the DAC module, including: + * This function de-initializes the DAC module including the following operations. * - Disabling the DAC module. * - Disabling the clock for the DAC module. * @@ -193,7 +192,7 @@ void DAC_Deinit(DAC_Type *base); /*! * @brief Initializes the DAC user configuration structure. * - * This function initializes the user configuration structure to a default value. The default values are: + * This function initializes the user configuration structure to a default value. The default values are as follows. * @code * config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2; * config->enableLowPowerMode = false; @@ -206,7 +205,7 @@ void DAC_GetDefaultConfig(dac_config_t *config); * @brief Enables the DAC module. * * @param base DAC peripheral base address. - * @param enable Enables the feature or not. + * @param enable Enables or disables the feature. */ static inline void DAC_Enable(DAC_Type *base, bool enable) { @@ -231,7 +230,7 @@ static inline void DAC_Enable(DAC_Type *base, bool enable) * @brief Enables the DAC buffer. * * @param base DAC peripheral base address. - * @param enable Enables the feature or not. + * @param enable Enables or disables the feature. */ static inline void DAC_EnableBuffer(DAC_Type *base, bool enable) { @@ -256,7 +255,7 @@ void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config); /*! * @brief Initializes the DAC buffer configuration structure. * - * This function initializes the DAC buffer configuration structure to a default value. The default values are: + * This function initializes the DAC buffer configuration structure to default values. The default values are as follows. * @code * config->triggerMode = kDAC_BufferTriggerBySoftwareMode; * config->watermark = kDAC_BufferWatermark1Word; @@ -271,7 +270,7 @@ void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config); * @brief Enables the DMA for DAC buffer. * * @param base DAC peripheral base address. - * @param enable Enables the feature or not. + * @param enable Enables or disables the feature. */ static inline void DAC_EnableBufferDMA(DAC_Type *base, bool enable) { @@ -289,15 +288,15 @@ static inline void DAC_EnableBufferDMA(DAC_Type *base, bool enable) * @brief Sets the value for items in the buffer. * * @param base DAC peripheral base address. - * @param index Setting index for items in the buffer. The available index should not exceed the size of the DAC buffer. - * @param value Setting value for items in the buffer. 12-bits are available. + * @param index Setting the index for items in the buffer. The available index should not exceed the size of the DAC buffer. + * @param value Setting the value for items in the buffer. 12-bits are available. */ void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value); /*! - * @brief Triggers the buffer by software and updates the read pointer of the DAC buffer. + * @brief Triggers the buffer using software and updates the read pointer of the DAC buffer. * - * This function triggers the function by software. The read pointer of the DAC buffer is updated with one step + * This function triggers the function using software. The read pointer of the DAC buffer is updated with one step * after this function is called. Changing the read pointer depends on the buffer's work mode. * * @param base DAC peripheral base address. @@ -311,12 +310,12 @@ static inline void DAC_DoSoftwareTriggerBuffer(DAC_Type *base) * @brief Gets the current read pointer of the DAC buffer. * * This function gets the current read pointer of the DAC buffer. - * The current output value depends on the item indexed by the read pointer. It is updated - * by software trigger or hardware trigger. + * The current output value depends on the item indexed by the read pointer. It is updated either + * by a software trigger or a hardware trigger. * * @param base DAC peripheral base address. * - * @return Current read pointer of DAC buffer. + * @return The current read pointer of the DAC buffer. */ static inline uint8_t DAC_GetBufferReadPointer(DAC_Type *base) { @@ -327,11 +326,11 @@ static inline uint8_t DAC_GetBufferReadPointer(DAC_Type *base) * @brief Sets the current read pointer of the DAC buffer. * * This function sets the current read pointer of the DAC buffer. - * The current output value depends on the item indexed by the read pointer. It is updated by - * software trigger or hardware trigger. After the read pointer changes, the DAC output value also changes. + * The current output value depends on the item indexed by the read pointer. It is updated either by a + * software trigger or a hardware trigger. After the read pointer changes, the DAC output value also changes. * * @param base DAC peripheral base address. - * @param index Setting index value for the pointer. + * @param index Setting an index value for the pointer. */ void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dmamux.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dmamux.c index a288b9f22f..39ce9cfbea 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dmamux.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dmamux.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -52,8 +52,10 @@ static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base); /*! @brief Array to map DMAMUX instance number to base pointer. */ static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Array to map DMAMUX instance number to clock name. */ static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Code @@ -63,7 +65,7 @@ static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_DMAMUX_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_dmamuxBases); instance++) { if (s_dmamuxBases[instance] == base) { @@ -71,17 +73,21 @@ static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base) } } - assert(instance < FSL_FEATURE_SOC_DMAMUX_COUNT); + assert(instance < ARRAY_SIZE(s_dmamuxBases)); return instance; } void DMAMUX_Init(DMAMUX_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void DMAMUX_Deinit(DMAMUX_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dmamux.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dmamux.h index f4294d4dfa..071348b2c2 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dmamux.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dmamux.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -38,7 +38,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -46,8 +45,8 @@ /*! @name Driver version */ /*@{*/ -/*! @brief DMAMUX driver version 2.0.0. */ -#define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*! @brief DMAMUX driver version 2.0.2. */ +#define FSL_DMAMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*@}*/ /******************************************************************************* @@ -59,14 +58,14 @@ extern "C" { #endif /* __cplusplus */ /*! - * @name DMAMUX Initialize and De-initialize + * @name DMAMUX Initialization and de-initialization * @{ */ /*! - * @brief Initializes DMAMUX peripheral. + * @brief Initializes the DMAMUX peripheral. * - * This function ungate the DMAMUX clock. + * This function ungates the DMAMUX clock. * * @param base DMAMUX peripheral base address. * @@ -74,9 +73,9 @@ extern "C" { void DMAMUX_Init(DMAMUX_Type *base); /*! - * @brief Deinitializes DMAMUX peripheral. + * @brief Deinitializes the DMAMUX peripheral. * - * This function gate the DMAMUX clock. + * This function gates the DMAMUX clock. * * @param base DMAMUX peripheral base address. */ @@ -89,9 +88,9 @@ void DMAMUX_Deinit(DMAMUX_Type *base); */ /*! - * @brief Enable DMAMUX channel. + * @brief Enables the DMAMUX channel. * - * This function enable DMAMUX channel to work. + * This function enables the DMAMUX channel. * * @param base DMAMUX peripheral base address. * @param channel DMAMUX channel number. @@ -104,11 +103,11 @@ static inline void DMAMUX_EnableChannel(DMAMUX_Type *base, uint32_t channel) } /*! - * @brief Disable DMAMUX channel. + * @brief Disables the DMAMUX channel. * - * This function disable DMAMUX channel. + * This function disables the DMAMUX channel. * - * @note User must disable DMAMUX channel before configure it. + * @note The user must disable the DMAMUX channel before configuring it. * @param base DMAMUX peripheral base address. * @param channel DMAMUX channel number. */ @@ -120,13 +119,13 @@ static inline void DMAMUX_DisableChannel(DMAMUX_Type *base, uint32_t channel) } /*! - * @brief Configure DMAMUX channel source. + * @brief Configures the DMAMUX channel source. * * @param base DMAMUX peripheral base address. * @param channel DMAMUX channel number. - * @param source Channel source which is used to trigger DMA transfer. + * @param source Channel source, which is used to trigger the DMA transfer. */ -static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint8_t source) +static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint32_t source) { assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); @@ -135,9 +134,9 @@ static inline void DMAMUX_SetSource(DMAMUX_Type *base, uint32_t channel, uint8_t #if defined(FSL_FEATURE_DMAMUX_HAS_TRIG) && FSL_FEATURE_DMAMUX_HAS_TRIG > 0U /*! - * @brief Enable DMAMUX period trigger. + * @brief Enables the DMAMUX period trigger. * - * This function enable DMAMUX period trigger feature. + * This function enables the DMAMUX period trigger feature. * * @param base DMAMUX peripheral base address. * @param channel DMAMUX channel number. @@ -150,9 +149,9 @@ static inline void DMAMUX_EnablePeriodTrigger(DMAMUX_Type *base, uint32_t channe } /*! - * @brief Disable DMAMUX period trigger. + * @brief Disables the DMAMUX period trigger. * - * This function disable DMAMUX period trigger. + * This function disables the DMAMUX period trigger. * * @param base DMAMUX peripheral base address. * @param channel DMAMUX channel number. @@ -165,6 +164,31 @@ static inline void DMAMUX_DisablePeriodTrigger(DMAMUX_Type *base, uint32_t chann } #endif /* FSL_FEATURE_DMAMUX_HAS_TRIG */ +#if (defined(FSL_FEATURE_DMAMUX_HAS_A_ON) && FSL_FEATURE_DMAMUX_HAS_A_ON) +/*! + * @brief Enables the DMA channel to be always ON. + * + * This function enables the DMAMUX channel always ON feature. + * + * @param base DMAMUX peripheral base address. + * @param channel DMAMUX channel number. + * @param enable Switcher of the always ON feature. "true" means enabled, "false" means disabled. + */ +static inline void DMAMUX_EnableAlwaysOn(DMAMUX_Type *base, uint32_t channel, bool enable) +{ + assert(channel < FSL_FEATURE_DMAMUX_MODULE_CHANNEL); + + if (enable) + { + base->CHCFG[channel] |= DMAMUX_CHCFG_A_ON_MASK; + } + else + { + base->CHCFG[channel] &= ~DMAMUX_CHCFG_A_ON_MASK; + } +} +#endif /* FSL_FEATURE_DMAMUX_HAS_A_ON */ + /* @} */ #if defined(__cplusplus) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi.c index 5654ce7aac..d3b3f0aa5f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi.c @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* 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. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "fsl_dspi.h" @@ -65,27 +65,27 @@ static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pc /*! * @brief Master fill up the TX FIFO with data. - * This is not a public API as it is called from other driver functions. + * This is not a public API. */ static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle); /*! * @brief Master finish up a transfer. * It would call back if there is callback function and set the state to idle. - * This is not a public API as it is called from other driver functions. + * This is not a public API. */ static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle); /*! * @brief Slave fill up the TX FIFO with data. - * This is not a public API as it is called from other driver functions. + * This is not a public API. */ static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle); /*! * @brief Slave finish up a transfer. * It would call back if there is callback function and set the state to idle. - * This is not a public API as it is called from other driver functions. + * This is not a public API. */ static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle); @@ -100,7 +100,7 @@ static void DSPI_CommonIRQHandler(SPI_Type *base, void *param); /*! * @brief Master prepare the transfer. * Basically it set up dspi_master_handle . - * This is not a public API as it is called from other driver functions. fsl_dspi_edma.c also call this function. + * This is not a public API. */ static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer); @@ -123,11 +123,13 @@ static SPI_Type *const s_dspiBases[] = SPI_BASE_PTRS; /*! @brief Pointers to dspi IRQ number for each instance. */ static IRQn_Type const s_dspiIRQ[] = SPI_IRQS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to dspi clocks for each instance. */ static clock_ip_name_t const s_dspiClock[] = DSPI_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Pointers to dspi handles for each instance. */ -static void *g_dspiHandle[FSL_FEATURE_SOC_DSPI_COUNT]; +static void *g_dspiHandle[ARRAY_SIZE(s_dspiBases)]; /*! @brief Pointer to master IRQ handler for each instance. */ static dspi_master_isr_t s_dspiMasterIsr; @@ -135,6 +137,8 @@ static dspi_master_isr_t s_dspiMasterIsr; /*! @brief Pointer to slave IRQ handler for each instance. */ static dspi_slave_isr_t s_dspiSlaveIsr; +/* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/ +volatile uint8_t s_dummyData[ARRAY_SIZE(s_dspiBases)] = {0}; /********************************************************************************************************************** * Code *********************************************************************************************************************/ @@ -143,7 +147,7 @@ uint32_t DSPI_GetInstance(SPI_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_DSPI_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_dspiBases); instance++) { if (s_dspiBases[instance] == base) { @@ -151,16 +155,26 @@ uint32_t DSPI_GetInstance(SPI_Type *base) } } - assert(instance < FSL_FEATURE_SOC_DSPI_COUNT); + assert(instance < ARRAY_SIZE(s_dspiBases)); return instance; } +void DSPI_SetDummyData(SPI_Type *base, uint8_t dummyData) +{ + uint32_t instance = DSPI_GetInstance(base); + s_dummyData[instance] = dummyData; +} + void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz) { + assert(masterConfig); + uint32_t temp; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* enable DSPI clock */ CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ DSPI_Enable(base, true); DSPI_StopTransfer(base); @@ -196,11 +210,14 @@ void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, u DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_BetweenTransfer, srcClock_Hz, masterConfig->ctarConfig.betweenTransferDelayInNanoSec); + DSPI_SetDummyData(base, DSPI_DUMMY_DATA); DSPI_StartTransfer(base); } void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig) { + assert(masterConfig); + masterConfig->whichCtar = kDSPI_Ctar0; masterConfig->ctarConfig.baudRate = 500000; masterConfig->ctarConfig.bitsPerFrame = 8; @@ -223,10 +240,14 @@ void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig) void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig) { + assert(slaveConfig); + uint32_t temp = 0; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* enable DSPI clock */ CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ DSPI_Enable(base, true); DSPI_StopTransfer(base); @@ -250,11 +271,15 @@ void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig) SPI_CTAR_SLAVE_CPOL(slaveConfig->ctarConfig.cpol) | SPI_CTAR_SLAVE_CPHA(slaveConfig->ctarConfig.cpha); + DSPI_SetDummyData(base, DSPI_DUMMY_DATA); + DSPI_StartTransfer(base); } void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig) { + assert(slaveConfig); + slaveConfig->whichCtar = kDSPI_Ctar0; slaveConfig->ctarConfig.bitsPerFrame = 8; slaveConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh; @@ -271,8 +296,10 @@ void DSPI_Deinit(SPI_Type *base) DSPI_StopTransfer(base); DSPI_Enable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* disable DSPI clock */ CLOCK_DisableClock(s_dspiClock[DSPI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh) @@ -457,6 +484,8 @@ uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base, void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command) { + assert(command); + command->isPcsContinuous = false; command->whichCtar = kDSPI_Ctar0; command->whichPcs = kDSPI_Pcs0; @@ -466,6 +495,8 @@ void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command) void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data) { + assert(command); + /* First, clear Transmit Complete Flag (TCF) */ DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag); @@ -562,7 +593,7 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer) uint16_t wordToSend = 0; uint16_t wordReceived = 0; - uint8_t dummyData = DSPI_MASTER_DUMMY_DATA; + uint8_t dummyData = s_dummyData[DSPI_GetInstance(base)]; uint8_t bitsPerFrame; uint32_t command; @@ -598,6 +629,7 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer) command = DSPI_MasterGetFormattedCommand(&(commandStruct)); + commandStruct.isEndOfQueue = true; commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer); lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct)); @@ -626,25 +658,6 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer) { if (remainingSendByteCount == 1) { - while ((remainingReceiveByteCount - remainingSendByteCount) >= fifoSize) - { - if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) - { - if (rxData != NULL) - { - *(rxData) = DSPI_ReadData(base); - rxData++; - } - else - { - DSPI_ReadData(base); - } - remainingReceiveByteCount--; - - DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); - } - } - while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) { DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); @@ -702,20 +715,23 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer) DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); - if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) + while ((remainingReceiveByteCount - remainingSendByteCount) >= fifoSize) { - if (rxData != NULL) + if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) { - *(rxData) = DSPI_ReadData(base); - rxData++; - } - else - { - DSPI_ReadData(base); - } - remainingReceiveByteCount--; + if (rxData != NULL) + { + *(rxData) = DSPI_ReadData(base); + rxData++; + } + else + { + DSPI_ReadData(base); + } + remainingReceiveByteCount--; - DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + } } } } @@ -726,25 +742,6 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer) { if (remainingSendByteCount <= 2) { - while (((remainingReceiveByteCount - remainingSendByteCount) / 2) >= fifoSize) - { - if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) - { - wordReceived = DSPI_ReadData(base); - - if (rxData != NULL) - { - *rxData = wordReceived; - ++rxData; - *rxData = wordReceived >> 8; - ++rxData; - } - remainingReceiveByteCount -= 2; - - DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); - } - } - while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)) { DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); @@ -825,20 +822,23 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer) DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag); - if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) + while (((remainingReceiveByteCount - remainingSendByteCount) / 2) >= fifoSize) { - wordReceived = DSPI_ReadData(base); - - if (rxData != NULL) + if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag) { - *rxData = wordReceived; - ++rxData; - *rxData = wordReceived >> 8; - ++rxData; - } - remainingReceiveByteCount -= 2; + wordReceived = DSPI_ReadData(base); - DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + if (rxData != NULL) + { + *rxData = wordReceived; + ++rxData; + *rxData = wordReceived >> 8; + ++rxData; + } + remainingReceiveByteCount -= 2; + + DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag); + } } } } @@ -849,6 +849,9 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer) static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer) { + assert(handle); + assert(transfer); + dspi_command_data_config_t commandStruct; DSPI_StopTransfer(base); @@ -864,6 +867,7 @@ static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *han commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous); handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct)); + commandStruct.isEndOfQueue = true; commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer); handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct)); @@ -886,7 +890,8 @@ static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *han status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer) { - assert(handle && transfer); + assert(handle); + assert(transfer); /* If the transfer count is zero, then return immediately.*/ if (transfer->dataSize == 0) @@ -903,13 +908,10 @@ status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *ha handle->state = kDSPI_Busy; DSPI_MasterTransferPrepare(base, handle, transfer); - DSPI_StartTransfer(base); /* Enable the NVIC for DSPI peripheral. */ EnableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]); - DSPI_MasterTransferFillUpTxFifo(base, handle); - /* RX FIFO Drain request: RFDF_RE to enable RFDF interrupt * Since SPI is a synchronous interface, we only need to enable the RX interrupt. * The IRQ handler will get the status of RX and TX interrupt flags. @@ -917,7 +919,10 @@ status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *ha s_dspiMasterIsr = DSPI_MasterTransferHandleIRQ; DSPI_EnableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable); + DSPI_StartTransfer(base); + /* Fill up the Tx FIFO to trigger the transfer. */ + DSPI_MasterTransferFillUpTxFifo(base, handle); return kStatus_Success; } @@ -943,6 +948,8 @@ status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handl static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle) { + assert(handle); + /* Disable interrupt requests*/ DSPI_DisableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable); @@ -956,19 +963,20 @@ static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *ha status = kStatus_Success; } + handle->state = kDSPI_Idle; + if (handle->callback) { handle->callback(base, handle, status, handle->userData); } - - /* The transfer is complete.*/ - handle->state = kDSPI_Idle; } static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle) { + assert(handle); + uint16_t wordToSend = 0; - uint8_t dummyData = DSPI_MASTER_DUMMY_DATA; + uint8_t dummyData = s_dummyData[DSPI_GetInstance(base)]; /* If bits/frame is greater than one byte */ if (handle->bitsPerFrame > 8) @@ -1081,6 +1089,8 @@ static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle) { + assert(handle); + DSPI_StopTransfer(base); /* Disable interrupt requests*/ @@ -1091,6 +1101,8 @@ void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle) void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle) { + assert(handle); + /* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */ if (handle->remainingReceiveByteCount) { @@ -1212,7 +1224,8 @@ void DSPI_SlaveTransferCreateHandle(SPI_Type *base, status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer) { - assert(handle && transfer); + assert(handle); + assert(transfer); /* If receive length is zero */ if (transfer->dataSize == 0) @@ -1254,11 +1267,6 @@ status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *hand DSPI_FlushFifo(base, true, true); DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag); - DSPI_StartTransfer(base); - - /* Prepare data to transmit */ - DSPI_SlaveTransferFillUpTxFifo(base, handle); - s_dspiSlaveIsr = DSPI_SlaveTransferHandleIRQ; /* Enable RX FIFO drain request, the slave only use this interrupt */ @@ -1275,6 +1283,11 @@ status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *hand DSPI_EnableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable); } + DSPI_StartTransfer(base); + + /* Prepare data to transmit */ + DSPI_SlaveTransferFillUpTxFifo(base, handle); + return kStatus_Success; } @@ -1300,8 +1313,10 @@ status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle) { + assert(handle); + uint16_t transmitData = 0; - uint8_t dummyPattern = DSPI_SLAVE_DUMMY_DATA; + uint8_t dummyPattern = s_dummyData[DSPI_GetInstance(base)]; /* Service the transmitter, if transmit buffer provided, transmit the data, * else transmit dummy pattern @@ -1386,6 +1401,8 @@ static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t * static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle) { + assert(handle); + /* Disable interrupt requests */ DSPI_DisableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable | kDSPI_RxFifoOverflowInterruptEnable | kDSPI_RxFifoDrainRequestInterruptEnable); @@ -1406,16 +1423,18 @@ static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *hand status = kStatus_Success; } + handle->state = kDSPI_Idle; + if (handle->callback) { handle->callback(base, handle, status, handle->userData); } - - handle->state = kDSPI_Idle; } void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle) { + assert(handle); + DSPI_StopTransfer(base); /* Disable interrupt requests */ @@ -1429,7 +1448,9 @@ void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle) void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle) { - uint8_t dummyPattern = DSPI_SLAVE_DUMMY_DATA; + assert(handle); + + uint8_t dummyPattern = s_dummyData[DSPI_GetInstance(base)]; uint32_t dataReceived; uint32_t dataSend = 0; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi.h index 93da32fa2f..abfc7707d7 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -33,27 +33,24 @@ #include "fsl_common.h" /*! - * @addtogroup dspi + * @addtogroup dspi_driver * @{ */ -/*! @file */ - /********************************************************************************************************************** * Definitions *********************************************************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief DSPI driver version 2.1.0. */ -#define FSL_DSPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*! @brief DSPI driver version 2.2.0. */ +#define FSL_DSPI_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) /*@}*/ -/*! @name Dummy data */ -/*@{*/ -#define DSPI_MASTER_DUMMY_DATA (0x00U) /*!< Master dummy data used for tx if there is not txData. */ -#define DSPI_SLAVE_DUMMY_DATA (0x00U) /*!< Slave dummy data used for tx if there is not txData. */ -/*@}*/ +#ifndef DSPI_DUMMY_DATA +/*! @brief DSPI dummy data if there is no Tx data.*/ +#define DSPI_DUMMY_DATA (0x00U) /*!< Dummy data used for Tx if there is no txData. */ +#endif /*! @brief Status for the DSPI driver.*/ enum _dspi_status @@ -61,7 +58,7 @@ enum _dspi_status kStatus_DSPI_Busy = MAKE_STATUS(kStatusGroup_DSPI, 0), /*!< DSPI transfer is busy.*/ kStatus_DSPI_Error = MAKE_STATUS(kStatusGroup_DSPI, 1), /*!< DSPI driver error. */ kStatus_DSPI_Idle = MAKE_STATUS(kStatusGroup_DSPI, 2), /*!< DSPI is idle.*/ - kStatus_DSPI_OutOfRange = MAKE_STATUS(kStatusGroup_DSPI, 3) /*!< DSPI transfer out Of range. */ + kStatus_DSPI_OutOfRange = MAKE_STATUS(kStatusGroup_DSPI, 3) /*!< DSPI transfer out of range. */ }; /*! @brief DSPI status flags in SPIx_SR register.*/ @@ -75,7 +72,7 @@ enum _dspi_flags kDSPI_RxFifoDrainRequestFlag = SPI_SR_RFDF_MASK, /*!< Receive FIFO Drain Flag.*/ kDSPI_TxAndRxStatusFlag = SPI_SR_TXRXS_MASK, /*!< The module is in Stopped/Running state.*/ kDSPI_AllStatusFlag = SPI_SR_TCF_MASK | SPI_SR_EOQF_MASK | SPI_SR_TFUF_MASK | SPI_SR_TFFF_MASK | SPI_SR_RFOF_MASK | - SPI_SR_RFDF_MASK | SPI_SR_TXRXS_MASK /*!< All status above.*/ + SPI_SR_RFDF_MASK | SPI_SR_TXRXS_MASK /*!< All statuses above.*/ }; /*! @brief DSPI interrupt source.*/ @@ -109,8 +106,9 @@ typedef enum _dspi_master_slave_mode } dspi_master_slave_mode_t; /*! - * @brief DSPI Sample Point: Controls when the DSPI master samples SIN in Modified Transfer Format. This field is valid - * only when CPHA bit in CTAR register is 0. + * @brief DSPI Sample Point: Controls when the DSPI master samples SIN in the Modified Transfer Format. This field is + * valid + * only when the CPHA bit in the CTAR register is 0. */ typedef enum _dspi_master_sample_point { @@ -169,36 +167,37 @@ typedef enum _dspi_clock_phase typedef enum _dspi_shift_direction { kDSPI_MsbFirst = 0U, /*!< Data transfers start with most significant bit.*/ - kDSPI_LsbFirst = 1U /*!< Data transfers start with least significant bit.*/ + kDSPI_LsbFirst = 1U /*!< Data transfers start with least significant bit. + Shifting out of LSB is not supported for slave */ } dspi_shift_direction_t; /*! @brief DSPI delay type selection.*/ typedef enum _dspi_delay_type { kDSPI_PcsToSck = 1U, /*!< Pcs-to-SCK delay. */ - kDSPI_LastSckToPcs, /*!< Last SCK edge to Pcs delay. */ + kDSPI_LastSckToPcs, /*!< The last SCK edge to Pcs delay. */ kDSPI_BetweenTransfer /*!< Delay between transfers. */ } dspi_delay_type_t; /*! @brief DSPI Clock and Transfer Attributes Register (CTAR) selection.*/ typedef enum _dspi_ctar_selection { - kDSPI_Ctar0 = 0U, /*!< CTAR0 selection option for master or slave mode, note that CTAR0 and CTAR0_SLAVE are the + kDSPI_Ctar0 = 0U, /*!< CTAR0 selection option for master or slave mode; note that CTAR0 and CTAR0_SLAVE are the same register address. */ kDSPI_Ctar1 = 1U, /*!< CTAR1 selection option for master mode only. */ - kDSPI_Ctar2 = 2U, /*!< CTAR2 selection option for master mode only , note that some device do not support CTAR2. */ - kDSPI_Ctar3 = 3U, /*!< CTAR3 selection option for master mode only , note that some device do not support CTAR3. */ - kDSPI_Ctar4 = 4U, /*!< CTAR4 selection option for master mode only , note that some device do not support CTAR4. */ - kDSPI_Ctar5 = 5U, /*!< CTAR5 selection option for master mode only , note that some device do not support CTAR5. */ - kDSPI_Ctar6 = 6U, /*!< CTAR6 selection option for master mode only , note that some device do not support CTAR6. */ - kDSPI_Ctar7 = 7U /*!< CTAR7 selection option for master mode only , note that some device do not support CTAR7. */ + kDSPI_Ctar2 = 2U, /*!< CTAR2 selection option for master mode only; note that some devices do not support CTAR2. */ + kDSPI_Ctar3 = 3U, /*!< CTAR3 selection option for master mode only; note that some devices do not support CTAR3. */ + kDSPI_Ctar4 = 4U, /*!< CTAR4 selection option for master mode only; note that some devices do not support CTAR4. */ + kDSPI_Ctar5 = 5U, /*!< CTAR5 selection option for master mode only; note that some devices do not support CTAR5. */ + kDSPI_Ctar6 = 6U, /*!< CTAR6 selection option for master mode only; note that some devices do not support CTAR6. */ + kDSPI_Ctar7 = 7U /*!< CTAR7 selection option for master mode only; note that some devices do not support CTAR7. */ } dspi_ctar_selection_t; -#define DSPI_MASTER_CTAR_SHIFT (0U) /*!< DSPI master CTAR shift macro , internal used. */ -#define DSPI_MASTER_CTAR_MASK (0x0FU) /*!< DSPI master CTAR mask macro , internal used. */ -#define DSPI_MASTER_PCS_SHIFT (4U) /*!< DSPI master PCS shift macro , internal used. */ -#define DSPI_MASTER_PCS_MASK (0xF0U) /*!< DSPI master PCS mask macro , internal used. */ -/*! @brief Can use this enumeration for DSPI master transfer configFlags. */ +#define DSPI_MASTER_CTAR_SHIFT (0U) /*!< DSPI master CTAR shift macro; used internally. */ +#define DSPI_MASTER_CTAR_MASK (0x0FU) /*!< DSPI master CTAR mask macro; used internally. */ +#define DSPI_MASTER_PCS_SHIFT (4U) /*!< DSPI master PCS shift macro; used internally. */ +#define DSPI_MASTER_PCS_MASK (0xF0U) /*!< DSPI master PCS mask macro; used internally. */ +/*! @brief Use this enumeration for the DSPI master transfer configFlags. */ enum _dspi_transfer_config_flag_for_master { kDSPI_MasterCtar0 = 0U << DSPI_MASTER_CTAR_SHIFT, /*!< DSPI master transfer use CTAR0 setting. */ @@ -217,20 +216,21 @@ enum _dspi_transfer_config_flag_for_master kDSPI_MasterPcs4 = 4U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS4 signal. */ kDSPI_MasterPcs5 = 5U << DSPI_MASTER_PCS_SHIFT, /*!< DSPI master transfer use PCS5 signal. */ - kDSPI_MasterPcsContinuous = 1U << 20, /*!< Is PCS signal continuous. */ - kDSPI_MasterActiveAfterTransfer = 1U << 21, /*!< Is PCS signal active after last frame transfer.*/ + kDSPI_MasterPcsContinuous = 1U << 20, /*!< Indicates whether the PCS signal is continuous. */ + kDSPI_MasterActiveAfterTransfer = + 1U << 21, /*!< Indicates whether the PCS signal is active after the last frame transfer.*/ }; -#define DSPI_SLAVE_CTAR_SHIFT (0U) /*!< DSPI slave CTAR shift macro , internal used. */ -#define DSPI_SLAVE_CTAR_MASK (0x07U) /*!< DSPI slave CTAR mask macro , internal used. */ -/*! @brief Can use this enum for DSPI slave transfer configFlags. */ +#define DSPI_SLAVE_CTAR_SHIFT (0U) /*!< DSPI slave CTAR shift macro; used internally. */ +#define DSPI_SLAVE_CTAR_MASK (0x07U) /*!< DSPI slave CTAR mask macro; used internally. */ +/*! @brief Use this enumeration for the DSPI slave transfer configFlags. */ enum _dspi_transfer_config_flag_for_slave { kDSPI_SlaveCtar0 = 0U << DSPI_SLAVE_CTAR_SHIFT, /*!< DSPI slave transfer use CTAR0 setting. */ /*!< DSPI slave can only use PCS0. */ }; -/*! @brief DSPI transfer state, which is used for DSPI transactional APIs' state machine. */ +/*! @brief DSPI transfer state, which is used for DSPI transactional API state machine. */ enum _dspi_transfer_state { kDSPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver. */ @@ -238,15 +238,15 @@ enum _dspi_transfer_state kDSPI_Error /*!< Transfer error. */ }; -/*! @brief DSPI master command date configuration used for SPIx_PUSHR.*/ +/*! @brief DSPI master command date configuration used for the SPIx_PUSHR.*/ typedef struct _dspi_command_data_config { - bool isPcsContinuous; /*!< Option to enable the continuous assertion of chip select between transfers.*/ + bool isPcsContinuous; /*!< Option to enable the continuous assertion of the chip select between transfers.*/ dspi_ctar_selection_t whichCtar; /*!< The desired Clock and Transfer Attributes Register (CTAR) to use for CTAS.*/ dspi_which_pcs_t whichPcs; /*!< The desired PCS signal to use for the data transfer.*/ bool isEndOfQueue; /*!< Signals that the current transfer is the last in the queue.*/ - bool clearTransferCount; /*!< Clears SPI Transfer Counter (SPI_TCNT) before transmission starts.*/ + bool clearTransferCount; /*!< Clears the SPI Transfer Counter (SPI_TCNT) before transmission starts.*/ } dspi_command_data_config_t; /*! @brief DSPI master ctar configuration structure.*/ @@ -258,33 +258,33 @@ typedef struct _dspi_master_ctar_config dspi_clock_phase_t cpha; /*!< Clock phase. */ dspi_shift_direction_t direction; /*!< MSB or LSB data shift direction. */ - uint32_t pcsToSckDelayInNanoSec; /*!< PCS to SCK delay time with nanosecond , set to 0 sets the minimum - delay. It sets the boundary value if out of range that can be set.*/ - uint32_t lastSckToPcsDelayInNanoSec; /*!< Last SCK to PCS delay time with nanosecond , set to 0 sets the - minimum delay.It sets the boundary value if out of range that can be - set.*/ - uint32_t betweenTransferDelayInNanoSec; /*!< After SCK delay time with nanosecond , set to 0 sets the minimum - delay.It sets the boundary value if out of range that can be set.*/ + uint32_t pcsToSckDelayInNanoSec; /*!< PCS to SCK delay time in nanoseconds; setting to 0 sets the minimum + delay. It also sets the boundary value if out of range.*/ + uint32_t lastSckToPcsDelayInNanoSec; /*!< The last SCK to PCS delay time in nanoseconds; setting to 0 sets the + minimum delay. It also sets the boundary value if out of range.*/ + + uint32_t betweenTransferDelayInNanoSec; /*!< After the SCK delay time in nanoseconds; setting to 0 sets the minimum + delay. It also sets the boundary value if out of range.*/ } dspi_master_ctar_config_t; /*! @brief DSPI master configuration structure.*/ typedef struct _dspi_master_config { - dspi_ctar_selection_t whichCtar; /*!< Desired CTAR to use. */ + dspi_ctar_selection_t whichCtar; /*!< The desired CTAR to use. */ dspi_master_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */ - dspi_which_pcs_t whichPcs; /*!< Desired Peripheral Chip Select (pcs). */ - dspi_pcs_polarity_config_t pcsActiveHighOrLow; /*!< Desired PCS active high or low. */ + dspi_which_pcs_t whichPcs; /*!< The desired Peripheral Chip Select (pcs). */ + dspi_pcs_polarity_config_t pcsActiveHighOrLow; /*!< The desired PCS active high or low. */ - bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable . Note that continuous SCK is only + bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable. Note that the continuous SCK is only supported for CPHA = 1.*/ - bool enableRxFifoOverWrite; /*!< ROOE, Receive FIFO overflow overwrite enable. ROOE = 0, the incoming - data is ignored, the data from the transfer that generated the overflow - is either ignored. ROOE = 1, the incoming data is shifted in to the - shift to the shift register. */ + bool enableRxFifoOverWrite; /*!< ROOE, receive FIFO overflow overwrite enable. If ROOE = 0, the incoming + data is ignored and the data from the transfer that generated the overflow + is also ignored. If ROOE = 1, the incoming data is shifted to the + shift register. */ - bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if it's true.*/ - dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in Modified Transfer + bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if true.*/ + dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in the Modified Transfer Format. It's valid only when CPHA=0. */ } dspi_master_config_t; @@ -294,23 +294,23 @@ typedef struct _dspi_slave_ctar_config uint32_t bitsPerFrame; /*!< Bits per frame, minimum 4, maximum 16.*/ dspi_clock_polarity_t cpol; /*!< Clock polarity. */ dspi_clock_phase_t cpha; /*!< Clock phase. */ - /*!< Slave only supports MSB , does not support LSB.*/ + /*!< Slave only supports MSB and does not support LSB.*/ } dspi_slave_ctar_config_t; /*! @brief DSPI slave configuration structure.*/ typedef struct _dspi_slave_config { - dspi_ctar_selection_t whichCtar; /*!< Desired CTAR to use. */ + dspi_ctar_selection_t whichCtar; /*!< The desired CTAR to use. */ dspi_slave_ctar_config_t ctarConfig; /*!< Set the ctarConfig to the desired CTAR. */ - bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable. Note that continuous SCK is only + bool enableContinuousSCK; /*!< CONT_SCKE, continuous SCK enable. Note that the continuous SCK is only supported for CPHA = 1.*/ - bool enableRxFifoOverWrite; /*!< ROOE, Receive FIFO overflow overwrite enable. ROOE = 0, the incoming - data is ignored, the data from the transfer that generated the overflow - is either ignored. ROOE = 1, the incoming data is shifted in to the - shift to the shift register. */ - bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if it's true.*/ - dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in Modified Transfer + bool enableRxFifoOverWrite; /*!< ROOE, receive FIFO overflow overwrite enable. If ROOE = 0, the incoming + data is ignored and the data from the transfer that generated the overflow + is also ignored. If ROOE = 1, the incoming data is shifted to the + shift register. */ + bool enableModifiedTimingFormat; /*!< Enables a modified transfer format to be used if true.*/ + dspi_master_sample_point_t samplePoint; /*!< Controls when the module master samples SIN in the Modified Transfer Format. It's valid only when CPHA=0. */ } dspi_slave_config_t; @@ -357,7 +357,7 @@ typedef struct _dspi_transfer volatile size_t dataSize; /*!< Transfer bytes. */ uint32_t - configFlags; /*!< Transfer transfer configuration flags , set from _dspi_transfer_config_flag_for_master if the + configFlags; /*!< Transfer transfer configuration flags; set from _dspi_transfer_config_flag_for_master if the transfer is used for master or _dspi_transfer_config_flag_for_slave enumeration if the transfer is used for slave.*/ } dspi_transfer_t; @@ -365,38 +365,39 @@ typedef struct _dspi_transfer /*! @brief DSPI master transfer handle structure used for transactional API. */ struct _dspi_master_handle { - uint32_t bitsPerFrame; /*!< Desired number of bits per frame. */ - volatile uint32_t command; /*!< Desired data command. */ - volatile uint32_t lastCommand; /*!< Desired last data command. */ + uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */ + volatile uint32_t command; /*!< The desired data command. */ + volatile uint32_t lastCommand; /*!< The desired last data command. */ uint8_t fifoSize; /*!< FIFO dataSize. */ - volatile bool isPcsActiveAfterTransfer; /*!< Is PCS signal keep active after the last frame transfer.*/ - volatile bool isThereExtraByte; /*!< Is there extra byte.*/ + volatile bool + isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal is active after the last frame transfer.*/ + volatile bool isThereExtraByte; /*!< Indicates whether there are extra bytes.*/ uint8_t *volatile txData; /*!< Send buffer. */ uint8_t *volatile rxData; /*!< Receive buffer. */ - volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ - volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ - size_t totalByteCount; /*!< Number of transfer bytes*/ + volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/ + volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/ + size_t totalByteCount; /*!< A number of transfer bytes*/ - volatile uint8_t state; /*!< DSPI transfer state , _dspi_transfer_state.*/ + volatile uint8_t state; /*!< DSPI transfer state, see _dspi_transfer_state.*/ dspi_master_transfer_callback_t callback; /*!< Completion callback. */ void *userData; /*!< Callback user data. */ }; -/*! @brief DSPI slave transfer handle structure used for transactional API. */ +/*! @brief DSPI slave transfer handle structure used for the transactional API. */ struct _dspi_slave_handle { - uint32_t bitsPerFrame; /*!< Desired number of bits per frame. */ - volatile bool isThereExtraByte; /*!< Is there extra byte.*/ + uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */ + volatile bool isThereExtraByte; /*!< Indicates whether there are extra bytes.*/ uint8_t *volatile txData; /*!< Send buffer. */ uint8_t *volatile rxData; /*!< Receive buffer. */ - volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ - volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ - size_t totalByteCount; /*!< Number of transfer bytes*/ + volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/ + volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/ + size_t totalByteCount; /*!< A number of transfer bytes*/ volatile uint8_t state; /*!< DSPI transfer state.*/ @@ -421,18 +422,18 @@ extern "C" { /*! * @brief Initializes the DSPI master. * - * This function initializes the DSPI master configuration. An example use case is as follows: + * This function initializes the DSPI master configuration. This is an example use case. * @code * dspi_master_config_t masterConfig; * masterConfig.whichCtar = kDSPI_Ctar0; - * masterConfig.ctarConfig.baudRate = 500000000; + * masterConfig.ctarConfig.baudRate = 500000000U; * masterConfig.ctarConfig.bitsPerFrame = 8; * masterConfig.ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh; * masterConfig.ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge; * masterConfig.ctarConfig.direction = kDSPI_MsbFirst; - * masterConfig.ctarConfig.pcsToSckDelayInNanoSec = 1000000000 / masterConfig.ctarConfig.baudRate ; - * masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec = 1000000000 / masterConfig.ctarConfig.baudRate ; - * masterConfig.ctarConfig.betweenTransferDelayInNanoSec = 1000000000 / masterConfig.ctarConfig.baudRate ; + * masterConfig.ctarConfig.pcsToSckDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ; + * masterConfig.ctarConfig.lastSckToPcsDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ; + * masterConfig.ctarConfig.betweenTransferDelayInNanoSec = 1000000000U / masterConfig.ctarConfig.baudRate ; * masterConfig.whichPcs = kDSPI_Pcs0; * masterConfig.pcsActiveHighOrLow = kDSPI_PcsActiveLow; * masterConfig.enableContinuousSCK = false; @@ -443,8 +444,8 @@ extern "C" { * @endcode * * @param base DSPI peripheral address. - * @param masterConfig Pointer to structure dspi_master_config_t. - * @param srcClock_Hz Module source input clock in Hertz + * @param masterConfig Pointer to the structure dspi_master_config_t. + * @param srcClock_Hz Module source input clock in Hertz. */ void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz); @@ -452,8 +453,8 @@ void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, u * @brief Sets the dspi_master_config_t structure to default values. * * The purpose of this API is to get the configuration structure initialized for the DSPI_MasterInit(). - * User may use the initialized structure unchanged in DSPI_MasterInit() or modify the structure - * before calling DSPI_MasterInit(). + * Users may use the initialized structure unchanged in the DSPI_MasterInit() or modify the structure + * before calling the DSPI_MasterInit(). * Example: * @code * dspi_master_config_t masterConfig; @@ -466,7 +467,7 @@ void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig); /*! * @brief DSPI slave configuration. * - * This function initializes the DSPI slave configuration. An example use case is as follows: + * This function initializes the DSPI slave configuration. This is an example use case. * @code * dspi_slave_config_t slaveConfig; * slaveConfig->whichCtar = kDSPI_Ctar0; @@ -481,22 +482,22 @@ void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig); * @endcode * * @param base DSPI peripheral address. - * @param slaveConfig Pointer to structure dspi_master_config_t. + * @param slaveConfig Pointer to the structure dspi_master_config_t. */ void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig); /*! - * @brief Sets the dspi_slave_config_t structure to default values. + * @brief Sets the dspi_slave_config_t structure to a default value. * * The purpose of this API is to get the configuration structure initialized for the DSPI_SlaveInit(). - * User may use the initialized structure unchanged in DSPI_SlaveInit(), or modify the structure - * before calling DSPI_SlaveInit(). - * Example: + * Users may use the initialized structure unchanged in the DSPI_SlaveInit() or modify the structure + * before calling the DSPI_SlaveInit(). + * This is an example. * @code * dspi_slave_config_t slaveConfig; * DSPI_SlaveGetDefaultConfig(&slaveConfig); * @endcode - * @param slaveConfig pointer to dspi_slave_config_t structure. + * @param slaveConfig Pointer to the dspi_slave_config_t structure. */ void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig); @@ -510,7 +511,7 @@ void DSPI_Deinit(SPI_Type *base); * @brief Enables the DSPI peripheral and sets the MCR MDIS to 0. * * @param base DSPI peripheral address. - * @param enable pass true to enable module, false to disable module. + * @param enable Pass true to enable module, false to disable module. */ static inline void DSPI_Enable(SPI_Type *base, bool enable) { @@ -536,7 +537,7 @@ static inline void DSPI_Enable(SPI_Type *base, bool enable) /*! * @brief Gets the DSPI status flag state. * @param base DSPI peripheral address. - * @return The DSPI status(in SR register). + * @return DSPI status (in SR register). */ static inline uint32_t DSPI_GetStatusFlags(SPI_Type *base) { @@ -549,13 +550,13 @@ static inline uint32_t DSPI_GetStatusFlags(SPI_Type *base) * This function clears the desired status bit by using a write-1-to-clear. The user passes in the base and the * desired status bit to clear. The list of status bits is defined in the dspi_status_and_interrupt_request_t. The * function uses these bit positions in its algorithm to clear the desired flag state. - * Example usage: + * This is an example. * @code * DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag|kDSPI_EndOfQueueFlag); * @endcode * * @param base DSPI peripheral address. - * @param statusFlags The status flag , used from type dspi_flags. + * @param statusFlags The status flag used from the type dspi_flags. */ static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags) { @@ -574,15 +575,16 @@ static inline void DSPI_ClearStatusFlags(SPI_Type *base, uint32_t statusFlags) /*! * @brief Enables the DSPI interrupts. * - * This function configures the various interrupt masks of the DSPI. The parameters are base and an interrupt mask. + * This function configures the various interrupt masks of the DSPI. The parameters are a base and an interrupt mask. * Note, for Tx Fill and Rx FIFO drain requests, enable the interrupt request and disable the DMA request. + * Do not use this API(write to RSER register) while DSPI is in running state. * * @code * DSPI_EnableInterrupts(base, kDSPI_TxCompleteInterruptEnable | kDSPI_EndOfQueueInterruptEnable ); * @endcode * * @param base DSPI peripheral address. - * @param mask The interrupt mask, can use the enum _dspi_interrupt_enable. + * @param mask The interrupt mask; use the enum _dspi_interrupt_enable. */ void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask); @@ -594,7 +596,7 @@ void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask); * @endcode * * @param base DSPI peripheral address. - * @param mask The interrupt mask, can use the enum _dspi_interrupt_enable. + * @param mask The interrupt mask; use the enum _dspi_interrupt_enable. */ static inline void DSPI_DisableInterrupts(SPI_Type *base, uint32_t mask) { @@ -613,13 +615,13 @@ static inline void DSPI_DisableInterrupts(SPI_Type *base, uint32_t mask) /*! * @brief Enables the DSPI DMA request. * - * This function configures the Rx and Tx DMA mask of the DSPI. The parameters are base and a DMA mask. + * This function configures the Rx and Tx DMA mask of the DSPI. The parameters are a base and a DMA mask. * @code * DSPI_EnableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable); * @endcode * * @param base DSPI peripheral address. - * @param mask The interrupt mask can use the enum dspi_dma_enable. + * @param mask The interrupt mask; use the enum dspi_dma_enable. */ static inline void DSPI_EnableDMA(SPI_Type *base, uint32_t mask) { @@ -629,13 +631,13 @@ static inline void DSPI_EnableDMA(SPI_Type *base, uint32_t mask) /*! * @brief Disables the DSPI DMA request. * - * This function configures the Rx and Tx DMA mask of the DSPI. The parameters are base and a DMA mask. + * This function configures the Rx and Tx DMA mask of the DSPI. The parameters are a base and a DMA mask. * @code * SPI_DisableDMA(base, kDSPI_TxDmaEnable | kDSPI_RxDmaEnable); * @endcode * * @param base DSPI peripheral address. - * @param mask The interrupt mask can use the enum dspi_dma_enable. + * @param mask The interrupt mask; use the enum dspi_dma_enable. */ static inline void DSPI_DisableDMA(SPI_Type *base, uint32_t mask) { @@ -714,7 +716,7 @@ static inline bool DSPI_IsMaster(SPI_Type *base) /*! * @brief Starts the DSPI transfers and clears HALT bit in MCR. * - * This function sets the module to begin data transfer in either master or slave mode. + * This function sets the module to start data transfer in either master or slave mode. * * @param base DSPI peripheral address. */ @@ -723,9 +725,9 @@ static inline void DSPI_StartTransfer(SPI_Type *base) base->MCR &= ~SPI_MCR_HALT_MASK; } /*! - * @brief Stops (halts) DSPI transfers and sets HALT bit in MCR. + * @brief Stops DSPI transfers and sets the HALT bit in MCR. * - * This function stops data transfers in either master or slave mode. + * This function stops data transfers in either master or slave modes. * * @param base DSPI peripheral address. */ @@ -735,15 +737,15 @@ static inline void DSPI_StopTransfer(SPI_Type *base) } /*! - * @brief Enables (or disables) the DSPI FIFOs. + * @brief Enables or disables the DSPI FIFOs. * - * This function allows the caller to disable/enable the Tx and Rx FIFOs (independently). - * Note that to disable, the caller must pass in a logic 0 (false) for the particular FIFO configuration. To enable, - * the caller must pass in a logic 1 (true). + * This function allows the caller to disable/enable the Tx and Rx FIFOs independently. + * Note that to disable, pass in a logic 0 (false) for the particular FIFO configuration. To enable, + * pass in a logic 1 (true). * * @param base DSPI peripheral address. - * @param enableTxFifo Disables (false) the TX FIFO, else enables (true) the TX FIFO - * @param enableRxFifo Disables (false) the RX FIFO, else enables (true) the RX FIFO + * @param enableTxFifo Disables (false) the TX FIFO; Otherwise, enables (true) the TX FIFO + * @param enableRxFifo Disables (false) the RX FIFO; Otherwise, enables (true) the RX FIFO */ static inline void DSPI_SetFifoEnable(SPI_Type *base, bool enableTxFifo, bool enableRxFifo) { @@ -755,8 +757,8 @@ static inline void DSPI_SetFifoEnable(SPI_Type *base, bool enableTxFifo, bool en * @brief Flushes the DSPI FIFOs. * * @param base DSPI peripheral address. - * @param flushTxFifo Flushes (true) the Tx FIFO, else do not flush (false) the Tx FIFO - * @param flushRxFifo Flushes (true) the Rx FIFO, else do not flush (false) the Rx FIFO + * @param flushTxFifo Flushes (true) the Tx FIFO; Otherwise, does not flush (false) the Tx FIFO + * @param flushRxFifo Flushes (true) the Rx FIFO; Otherwise, does not flush (false) the Rx FIFO */ static inline void DSPI_FlushFifo(SPI_Type *base, bool flushTxFifo, bool flushRxFifo) { @@ -766,13 +768,13 @@ static inline void DSPI_FlushFifo(SPI_Type *base, bool flushTxFifo, bool flushRx /*! * @brief Configures the DSPI peripheral chip select polarity simultaneously. - * For example, PCS0 and PCS1 set to active low and other PCS set to active high. Note that the number of + * For example, PCS0 and PCS1 are set to active low and other PCS is set to active high. Note that the number of * PCSs is specific to the device. * @code * DSPI_SetAllPcsPolarity(base, kDSPI_Pcs0ActiveLow | kDSPI_Pcs1ActiveLow); @endcode * @param base DSPI peripheral address. - * @param mask The PCS polarity mask , can use the enum _dspi_pcs_polarity. + * @param mask The PCS polarity mask; use the enum _dspi_pcs_polarity. */ static inline void DSPI_SetAllPcsPolarity(SPI_Type *base, uint32_t mask) { @@ -801,19 +803,19 @@ uint32_t DSPI_MasterSetBaudRate(SPI_Type *base, * @brief Manually configures the delay prescaler and scaler for a particular CTAR. * * This function configures the PCS to SCK delay pre-scalar (PcsSCK) and scalar (CSSCK), after SCK delay pre-scalar - * (PASC) and scalar (ASC), and the delay after transfer pre-scalar (PDT)and scalar (DT). + * (PASC) and scalar (ASC), and the delay after transfer pre-scalar (PDT) and scalar (DT). * - * These delay names are available in type dspi_delay_type_t. + * These delay names are available in the type dspi_delay_type_t. * - * The user passes the delay to configure along with the prescaler and scaler value. - * This allows the user to directly set the prescaler/scaler values if they have pre-calculated them or if they simply - * wish to manually increment either value. + * The user passes the delay to the configuration along with the prescaler and scaler value. + * This allows the user to directly set the prescaler/scaler values if pre-calculated or + * to manually increment either value. * * @param base DSPI peripheral address. * @param whichCtar The desired Clock and Transfer Attributes Register (CTAR) of type dspi_ctar_selection_t. * @param prescaler The prescaler delay value (can be an integer 0, 1, 2, or 3). * @param scaler The scaler delay value (can be any integer between 0 to 15). - * @param whichDelay The desired delay to configure, must be of type dspi_delay_type_t + * @param whichDelay The desired delay to configure; must be of type dspi_delay_type_t */ void DSPI_MasterSetDelayScaler( SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay); @@ -821,19 +823,19 @@ void DSPI_MasterSetDelayScaler( /*! * @brief Calculates the delay prescaler and scaler based on the desired delay input in nanoseconds. * - * This function calculates the values for: + * This function calculates the values for the following. * PCS to SCK delay pre-scalar (PCSSCK) and scalar (CSSCK), or * After SCK delay pre-scalar (PASC) and scalar (ASC), or - * Delay after transfer pre-scalar (PDT)and scalar (DT). + * Delay after transfer pre-scalar (PDT) and scalar (DT). * - * These delay names are available in type dspi_delay_type_t. + * These delay names are available in the type dspi_delay_type_t. * - * The user passes which delay they want to configure along with the desired delay value in nanoseconds. The function - * calculates the values needed for the prescaler and scaler and returning the actual calculated delay as an exact + * The user passes which delay to configure along with the desired delay value in nanoseconds. The function + * calculates the values needed for the prescaler and scaler. Note that returning the calculated delay as an exact * delay match may not be possible. In this case, the closest match is calculated without going below the desired * delay value input. * It is possible to input a very large delay value that exceeds the capability of the part, in which case the maximum - * supported delay is returned. The higher level peripheral driver alerts the user of an out of range delay + * supported delay is returned. The higher-level peripheral driver alerts the user of an out of range delay * input. * * @param base DSPI peripheral address. @@ -853,11 +855,11 @@ uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base, * @brief Writes data into the data buffer for master mode. * * In master mode, the 16-bit data is appended to the 16-bit command info. The command portion - * provides characteristics of the data such as the optional continuous chip select + * provides characteristics of the data, such as the optional continuous chip select * operation between transfers, the desired Clock and Transfer Attributes register to use for the * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current * transfer is the last in the queue, and whether to clear the transfer count (normally needed when - * sending the first frame of a data packet). This is an example: + * sending the first frame of a data packet). This is an example. * @code * dspi_command_data_config_t commandConfig; * commandConfig.isPcsContinuous = true; @@ -869,7 +871,7 @@ uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base, @endcode * * @param base DSPI peripheral address. - * @param command Pointer to command structure. + * @param command Pointer to the command structure. * @param data The data word to be sent. */ static inline void DSPI_MasterWriteData(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data) @@ -883,14 +885,14 @@ static inline void DSPI_MasterWriteData(SPI_Type *base, dspi_command_data_config * @brief Sets the dspi_command_data_config_t structure to default values. * * The purpose of this API is to get the configuration structure initialized for use in the DSPI_MasterWrite_xx(). - * User may use the initialized structure unchanged in DSPI_MasterWrite_xx() or modify the structure - * before calling DSPI_MasterWrite_xx(). - * Example: + * Users may use the initialized structure unchanged in the DSPI_MasterWrite_xx() or modify the structure + * before calling the DSPI_MasterWrite_xx(). + * This is an example. * @code * dspi_command_data_config_t command; * DSPI_GetDefaultDataCommandConfig(&command); * @endcode - * @param command pointer to dspi_command_data_config_t structure. + * @param command Pointer to the dspi_command_data_config_t structure. */ void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command); @@ -898,11 +900,11 @@ void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command); * @brief Writes data into the data buffer master mode and waits till complete to return. * * In master mode, the 16-bit data is appended to the 16-bit command info. The command portion - * provides characteristics of the data such as the optional continuous chip select + * provides characteristics of the data, such as the optional continuous chip select * operation between transfers, the desired Clock and Transfer Attributes register to use for the * associated SPI frame, the desired PCS signal to use for the data transfer, whether the current * transfer is the last in the queue, and whether to clear the transfer count (normally needed when - * sending the first frame of a data packet). This is an example: + * sending the first frame of a data packet). This is an example. * @code * dspi_command_config_t commandConfig; * commandConfig.isPcsContinuous = true; @@ -915,10 +917,10 @@ void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command); * * Note that this function does not return until after the transmit is complete. Also note that the DSPI must be * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). Because the SPI is a synchronous protocol, - * receive data is available when transmit completes. + * the received data is available when the transmit completes. * * @param base DSPI peripheral address. - * @param command Pointer to command structure. + * @param command Pointer to the command structure. * @param data The data word to be sent. */ void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data); @@ -933,10 +935,10 @@ void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *co * improve performance in cases where the command structure is constant. For example, the user calls this function * before starting a transfer to generate the command word. When they are ready to transmit the data, they OR * this formatted command word with the desired data to transmit. This process increases transmit performance when - * compared to calling send functions such as DSPI_HAL_WriteDataMastermode which format the command word each time a + * compared to calling send functions, such as DSPI_HAL_WriteDataMastermode, which format the command word each time a * data word is to be sent. * - * @param command Pointer to command structure. + * @param command Pointer to the command structure. * @return The command word formatted to the PUSHR data register bit field. */ static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t *command) @@ -949,24 +951,25 @@ static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t /*! * @brief Writes a 32-bit data word (16-bit command appended with 16-bit data) into the data - * buffer, master mode and waits till complete to return. + * buffer master mode and waits till complete to return. * - * In this function, the user must append the 16-bit data to the 16-bit command info then provide the total 32-bit word + * In this function, the user must append the 16-bit data to the 16-bit command information and then provide the total +* 32-bit word * as the data to send. - * The command portion provides characteristics of the data such as the optional continuous chip select operation -* between - * transfers, the desired Clock and Transfer Attributes register to use for the associated SPI frame, the desired PCS + * The command portion provides characteristics of the data, such as the optional continuous chip select operation + * between transfers, the desired Clock and Transfer Attributes register to use for the associated SPI frame, the +* desired PCS * signal to use for the data transfer, whether the current transfer is the last in the queue, and whether to clear the * transfer count (normally needed when sending the first frame of a data packet). The user is responsible for * appending this command with the data to send. This is an example: * @code * dataWord = <16-bit command> | <16-bit data>; - * DSPI_HAL_WriteCommandDataMastermodeBlocking(base, dataWord); + * DSPI_MasterWriteCommandDataBlocking(base, dataWord); * @endcode * * Note that this function does not return until after the transmit is complete. Also note that the DSPI must be * enabled and running to transmit data (MCR[MDIS] & [HALT] = 0). - * Because the SPI is a synchronous protocol, the receive data is available when transmit completes. + * Because the SPI is a synchronous protocol, the received data is available when the transmit completes. * * For a blocking polling transfer, see methods below. * Option 1: @@ -985,7 +988,7 @@ static inline uint32_t DSPI_MasterGetFormattedCommand(dspi_command_data_config_t * DSPI_MasterWriteDataBlocking(base,&command,data_need_to_send_2); * * @param base DSPI peripheral address. - * @param data The data word (command and data combined) to be sent + * @param data The data word (command and data combined) to be sent. */ void DSPI_MasterWriteCommandDataBlocking(SPI_Type *base, uint32_t data); @@ -1024,6 +1027,14 @@ static inline uint32_t DSPI_ReadData(SPI_Type *base) return (base->POPR); } +/*! + * @brief Set up the dummy data. + * + * @param base DSPI peripheral address. + * @param dummyData Data to be transferred when tx buffer is NULL. + */ +void DSPI_SetDummyData(SPI_Type *base, uint8_t dummyData); + /*! *@} */ @@ -1037,13 +1048,13 @@ static inline uint32_t DSPI_ReadData(SPI_Type *base) /*! * @brief Initializes the DSPI master handle. * - * This function initializes the DSPI handle which can be used for other DSPI transactional APIs. Usually, for a + * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a * specified DSPI instance, call this API once to get the initialized handle. * * @param base DSPI peripheral base address. * @param handle DSPI handle pointer to dspi_master_handle_t. - * @param callback dspi callback. - * @param userData callback function parameter. + * @param callback DSPI callback. + * @param userData Callback function parameter. */ void DSPI_MasterTransferCreateHandle(SPI_Type *base, dspi_master_handle_t *handle, @@ -1053,12 +1064,11 @@ void DSPI_MasterTransferCreateHandle(SPI_Type *base, /*! * @brief DSPI master transfer data using polling. * - * This function transfers data with polling. This is a blocking function, which does not return until all transfers - * have been - * completed. + * This function transfers data using polling. This is a blocking function, which does not return until all transfers + * have been completed. * * @param base DSPI peripheral base address. - * @param transfer pointer to dspi_transfer_t structure. + * @param transfer Pointer to the dspi_transfer_t structure. * @return status of status_t. */ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer); @@ -1067,12 +1077,11 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer); * @brief DSPI master transfer data using interrupts. * * This function transfers data using interrupts. This is a non-blocking function, which returns right away. When all - data - * have been transferred, the callback function is called. + * data is transferred, the callback function is called. * @param base DSPI peripheral base address. - * @param handle pointer to dspi_master_handle_t structure which stores the transfer state. - * @param transfer pointer to dspi_transfer_t structure. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. + * @param transfer Pointer to the dspi_transfer_t structure. * @return status of status_t. */ status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer); @@ -1083,19 +1092,19 @@ status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *ha * This function gets the master transfer count. * * @param base DSPI peripheral base address. - * @param handle pointer to dspi_master_handle_t structure which stores the transfer state. - * @param count Number of bytes transferred so far by the non-blocking transaction. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. + * @param count The number of bytes transferred by using the non-blocking transaction. * @return status of status_t. */ status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handle, size_t *count); /*! - * @brief DSPI master aborts transfer using an interrupt. + * @brief DSPI master aborts a transfer using an interrupt. * * This function aborts a transfer using an interrupt. * * @param base DSPI peripheral base address. - * @param handle pointer to dspi_master_handle_t structure which stores the transfer state. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. */ void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle); @@ -1105,7 +1114,7 @@ void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle); * This function processes the DSPI transmit and receive IRQ. * @param base DSPI peripheral base address. - * @param handle pointer to dspi_master_handle_t structure which stores the transfer state. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. */ void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle); @@ -1115,10 +1124,10 @@ void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle); * This function initializes the DSPI handle, which can be used for other DSPI transactional APIs. Usually, for a * specified DSPI instance, call this API once to get the initialized handle. * - * @param handle DSPI handle pointer to dspi_slave_handle_t. + * @param handle DSPI handle pointer to the dspi_slave_handle_t. * @param base DSPI peripheral base address. * @param callback DSPI callback. - * @param userData callback function parameter. + * @param userData Callback function parameter. */ void DSPI_SlaveTransferCreateHandle(SPI_Type *base, dspi_slave_handle_t *handle, @@ -1129,12 +1138,11 @@ void DSPI_SlaveTransferCreateHandle(SPI_Type *base, * @brief DSPI slave transfers data using an interrupt. * * This function transfers data using an interrupt. This is a non-blocking function, which returns right away. When all - * data - * have been transferred, the callback function is called. + * data is transferred, the callback function is called. * * @param base DSPI peripheral base address. - * @param handle pointer to dspi_slave_handle_t structure which stores the transfer state. - * @param transfer pointer to dspi_transfer_t structure. + * @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state. + * @param transfer Pointer to the dspi_transfer_t structure. * @return status of status_t. */ status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer); @@ -1145,8 +1153,8 @@ status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *hand * This function gets the slave transfer count. * * @param base DSPI peripheral base address. - * @param handle pointer to dspi_master_handle_t structure which stores the transfer state. - * @param count Number of bytes transferred so far by the non-blocking transaction. + * @param handle Pointer to the dspi_master_handle_t structure which stores the transfer state. + * @param count The number of bytes transferred by using the non-blocking transaction. * @return status of status_t. */ status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, size_t *count); @@ -1154,10 +1162,10 @@ status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, /*! * @brief DSPI slave aborts a transfer using an interrupt. * - * This function aborts transfer using an interrupt. + * This function aborts a transfer using an interrupt. * * @param base DSPI peripheral base address. - * @param handle pointer to dspi_slave_handle_t structure which stores the transfer state. + * @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state. */ void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle); @@ -1167,7 +1175,7 @@ void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle); * This function processes the DSPI transmit and receive IRQ. * * @param base DSPI peripheral base address. - * @param handle pointer to dspi_slave_handle_t structure which stores the transfer state. + * @param handle Pointer to the dspi_slave_handle_t structure which stores the transfer state. */ void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi_edma.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi_edma.c index 4d9e129ff2..ef0d15174f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi_edma.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi_edma.c @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* 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. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "fsl_dspi_edma.h" @@ -57,7 +57,7 @@ typedef struct _dspi_slave_edma_private_handle ***********************************************************************************************************************/ /*! * @brief EDMA_DspiMasterCallback after the DSPI master transfer completed by using EDMA. -* This is not a public API as it is called from other driver functions. +* This is not a public API. */ static void EDMA_DspiMasterCallback(edma_handle_t *edmaHandle, void *g_dspiEdmaPrivateHandle, @@ -66,7 +66,7 @@ static void EDMA_DspiMasterCallback(edma_handle_t *edmaHandle, /*! * @brief EDMA_DspiSlaveCallback after the DSPI slave transfer completed by using EDMA. -* This is not a public API as it is called from other driver functions. +* This is not a public API. */ static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle, void *g_dspiEdmaPrivateHandle, @@ -102,6 +102,9 @@ void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base, edma_handle_t *edmaIntermediaryToTxRegHandle) { assert(handle); + assert(edmaRxRegToRxDataHandle); + assert(edmaTxDataToIntermediaryHandle); + assert(edmaIntermediaryToTxRegHandle); /* Zero the handle. */ memset(handle, 0, sizeof(*handle)); @@ -121,7 +124,8 @@ void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base, status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer) { - assert(handle && transfer); + assert(handle); + assert(transfer); /* If the transfer count is zero, then return immediately.*/ if (transfer->dataSize == 0) @@ -141,9 +145,11 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand return kStatus_DSPI_Busy; } + handle->state = kDSPI_Busy; + uint32_t instance = DSPI_GetInstance(base); uint16_t wordToSend = 0; - uint8_t dummyData = DSPI_MASTER_DUMMY_DATA; + uint8_t dummyData = DSPI_DUMMY_DATA; uint8_t dataAlreadyFed = 0; uint8_t dataFedMax = 2; @@ -156,9 +162,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand edma_transfer_config_t transferConfigB; edma_transfer_config_t transferConfigC; - handle->txBuffIfNull = ((uint32_t)DSPI_MASTER_DUMMY_DATA << 8) | DSPI_MASTER_DUMMY_DATA; - - handle->state = kDSPI_Busy; + handle->txBuffIfNull = ((uint32_t)DSPI_DUMMY_DATA << 8) | DSPI_DUMMY_DATA; dspi_command_data_config_t commandStruct; DSPI_StopTransfer(base); @@ -174,6 +178,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous); handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct)); + commandStruct.isEndOfQueue = true; commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer); handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct)); @@ -193,39 +198,70 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand handle->remainingReceiveByteCount = transfer->dataSize; handle->totalByteCount = transfer->dataSize; - /* this limits the amount of data we can transfer due to the linked channel. - * The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame + /* If using a shared RX/TX DMA request, then this limits the amount of data we can transfer + * due to the linked channel. The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame */ + uint32_t limited_size = 0; + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + limited_size = 32767u; + } + else + { + limited_size = 511u; + } + if (handle->bitsPerFrame > 8) { - if (transfer->dataSize > 1022) + if (transfer->dataSize > (limited_size << 1u)) { + handle->state = kDSPI_Idle; return kStatus_DSPI_OutOfRange; } } else { - if (transfer->dataSize > 511) + if (transfer->dataSize > limited_size) { + handle->state = kDSPI_Idle; return kStatus_DSPI_OutOfRange; } } + /*The data size should be even if the bitsPerFrame is greater than 8 (that is 2 bytes per frame in dspi) */ + if ((handle->bitsPerFrame > 8) && (transfer->dataSize & 0x1)) + { + handle->state = kDSPI_Idle; + return kStatus_InvalidArgument; + } + DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_DspiMasterCallback, &s_dspiMasterEdmaPrivateHandle[instance]); - handle->isThereExtraByte = false; - if (handle->bitsPerFrame > 8) - { - if (handle->remainingSendByteCount % 2 == 1) - { - handle->remainingSendByteCount++; - handle->remainingReceiveByteCount--; - handle->isThereExtraByte = true; - } - } + /* + (1)For DSPI instances with shared RX/TX DMA requests: Rx DMA request -> channel_A -> channel_B-> channel_C. + channel_A minor link to channel_B , channel_B minor link to channel_C. + + Already pushed 1 or 2 data in SPI_PUSHR , then start the DMA tansfer. + channel_A:SPI_POPR to rxData, + channel_B:next txData to handle->command (low 16 bits), + channel_C:handle->command (32 bits) to SPI_PUSHR, and use the scatter/gather to transfer the last data + (handle->lastCommand to SPI_PUSHR). + + (2)For DSPI instances with separate RX and TX DMA requests: + Rx DMA request -> channel_A + Tx DMA request -> channel_C -> channel_B . + channel_C major link to channel_B. + So need prepare the first data in "intermediary" before the DMA + transfer and then channel_B is used to prepare the next data to "intermediary" + + channel_A:SPI_POPR to rxData, + channel_C: handle->command (32 bits) to SPI_PUSHR, + channel_B: next txData to handle->command (low 16 bits), and use the scatter/gather to prepare the last data + (handle->lastCommand to handle->Command). + */ /*If dspi has separate dma request , prepare the first data in "intermediary" . else (dspi has shared dma request) , send first 2 data if there is fifo or send first 1 data if there is no fifo*/ @@ -243,22 +279,16 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand { if (handle->txData) { - if (handle->isThereExtraByte) - { - wordToSend = *(handle->txData) | ((uint32_t)dummyData << 8); - } - else - { - wordToSend = *(handle->txData); - ++handle->txData; /* increment to next data byte */ - wordToSend |= (unsigned)(*(handle->txData)) << 8U; - } + wordToSend = *(handle->txData); + ++handle->txData; /* increment to next data byte */ + wordToSend |= (unsigned)(*(handle->txData)) << 8U; } else { wordToSend = ((uint32_t)dummyData << 8) | dummyData; } handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend; + handle->command = handle->lastCommand; } else /* For all words except the last word , frame > 8bits */ { @@ -291,6 +321,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand if (handle->remainingSendByteCount == 1) { handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend; + handle->command = handle->lastCommand; } else { @@ -315,21 +346,13 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand { if (handle->txData) { - if (handle->isThereExtraByte) - { - wordToSend = *(handle->txData) | ((uint32_t)dummyData << 8); - } - else - { - wordToSend = *(handle->txData); - ++handle->txData; - wordToSend |= (unsigned)(*(handle->txData)) << 8U; - } + wordToSend = *(handle->txData); + ++handle->txData; + wordToSend |= (unsigned)(*(handle->txData)) << 8U; } else { wordToSend = ((uint32_t)dummyData << 8) | dummyData; - ; } handle->remainingSendByteCount = 0; base->PUSHR = (handle->lastCommand & 0xffff0000U) | wordToSend; @@ -347,7 +370,6 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand else { wordToSend = ((uint32_t)dummyData << 8) | dummyData; - ; } handle->remainingSendByteCount -= 2; base->PUSHR = (handle->command & 0xffff0000U) | wordToSend; @@ -404,7 +426,7 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand } } - /***channel_A *** used for carry the data from Rx_Data_Register(POPR) to User_Receive_Buffer*/ + /***channel_A *** used for carry the data from Rx_Data_Register(POPR) to User_Receive_Buffer(rxData)*/ EDMA_ResetChannel(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel); transferConfigA.srcAddr = (uint32_t)rxAddr; @@ -435,6 +457,10 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand transferConfigA.minorLoopBytes = 2; transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2; } + + /* Store the initially configured eDMA minor byte transfer count into the DSPI handle */ + handle->nbytes = transferConfigA.minorLoopBytes; + EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, &transferConfigA, NULL); EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, @@ -443,68 +469,10 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand /***channel_B *** used for carry the data from User_Send_Buffer to "intermediary" because the SPIx_PUSHR should write the 32bits at once time . Then use channel_C to carry the "intermediary" to SPIx_PUSHR. Note that the SPIx_PUSHR upper 16 bits are the "command" and the low 16bits are data */ + EDMA_ResetChannel(handle->edmaTxDataToIntermediaryHandle->base, handle->edmaTxDataToIntermediaryHandle->channel); - if (handle->remainingSendByteCount > 0) - { - if (handle->txData) - { - transferConfigB.srcAddr = (uint32_t)(handle->txData); - transferConfigB.srcOffset = 1; - } - else - { - transferConfigB.srcAddr = (uint32_t)(&handle->txBuffIfNull); - transferConfigB.srcOffset = 0; - } - - transferConfigB.destAddr = (uint32_t)(&handle->command); - transferConfigB.destOffset = 0; - - transferConfigB.srcTransferSize = kEDMA_TransferSize1Bytes; - - if (handle->bitsPerFrame <= 8) - { - transferConfigB.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigB.minorLoopBytes = 1; - - if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) - { - /*already prepared the first data in "intermediary" , so minus 1 */ - transferConfigB.majorLoopCounts = handle->remainingSendByteCount - 1; - } - else - { - /*Only enable channel_B minorlink to channel_C , so need to add one count due to the last time is - majorlink , the majorlink would not trigger the channel_C*/ - transferConfigB.majorLoopCounts = handle->remainingSendByteCount + 1; - } - } - else - { - transferConfigB.destTransferSize = kEDMA_TransferSize2Bytes; - transferConfigB.minorLoopBytes = 2; - if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) - { - /*already prepared the first data in "intermediary" , so minus 1 */ - transferConfigB.majorLoopCounts = handle->remainingSendByteCount / 2 - 1; - } - else - { - /*Only enable channel_B minorlink to channel_C , so need to add one count due to the last time is - * majorlink*/ - transferConfigB.majorLoopCounts = handle->remainingSendByteCount / 2 + 1; - } - } - - EDMA_SetTransferConfig(handle->edmaTxDataToIntermediaryHandle->base, - handle->edmaTxDataToIntermediaryHandle->channel, &transferConfigB, NULL); - } - - /***channel_C ***carry the "intermediary" to SPIx_PUSHR. used the edma Scatter Gather function on channel_C to - handle the last data */ - EDMA_ResetChannel(handle->edmaIntermediaryToTxRegHandle->base, handle->edmaIntermediaryToTxRegHandle->channel); - + /*Calculate the last data : handle->lastCommand*/ if (((handle->remainingSendByteCount > 0) && (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))) || ((((handle->remainingSendByteCount > 1) && (handle->bitsPerFrame <= 8)) || ((handle->remainingSendByteCount > 2) && (handle->bitsPerFrame > 8))) && @@ -536,17 +504,9 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand } else { - if (handle->isThereExtraByte) - { - handle->lastCommand = (handle->lastCommand & 0xffff0000U) | handle->txData[bufferIndex - 2] | - ((uint32_t)dummyData << 8); - } - else - { - handle->lastCommand = (handle->lastCommand & 0xffff0000U) | - ((uint32_t)handle->txData[bufferIndex - 1] << 8) | - handle->txData[bufferIndex - 2]; - } + handle->lastCommand = (handle->lastCommand & 0xffff0000U) | + ((uint32_t)handle->txData[bufferIndex - 1] << 8) | + handle->txData[bufferIndex - 2]; } } else @@ -563,8 +523,104 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand } } - if ((1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) || - ((1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) && (handle->remainingSendByteCount > 0))) + /*For DSPI instances with separate RX and TX DMA requests: use the scatter/gather to prepare the last data + * (handle->lastCommand) to handle->Command*/ + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + transferConfigB.srcAddr = (uint32_t) & (handle->lastCommand); + transferConfigB.destAddr = (uint32_t) & (handle->command); + transferConfigB.srcTransferSize = kEDMA_TransferSize4Bytes; + transferConfigB.destTransferSize = kEDMA_TransferSize4Bytes; + transferConfigB.srcOffset = 0; + transferConfigB.destOffset = 0; + transferConfigB.minorLoopBytes = 4; + transferConfigB.majorLoopCounts = 1; + + EDMA_TcdReset(softwareTCD); + EDMA_TcdSetTransferConfig(softwareTCD, &transferConfigB, NULL); + } + + /*User_Send_Buffer(txData) to intermediary(handle->command)*/ + if (((((handle->remainingSendByteCount > 2) && (handle->bitsPerFrame <= 8)) || + ((handle->remainingSendByteCount > 4) && (handle->bitsPerFrame > 8))) && + (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))) || + (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))) + { + if (handle->txData) + { + transferConfigB.srcAddr = (uint32_t)(handle->txData); + transferConfigB.srcOffset = 1; + } + else + { + transferConfigB.srcAddr = (uint32_t)(&handle->txBuffIfNull); + transferConfigB.srcOffset = 0; + } + + transferConfigB.destAddr = (uint32_t)(&handle->command); + transferConfigB.destOffset = 0; + + transferConfigB.srcTransferSize = kEDMA_TransferSize1Bytes; + + if (handle->bitsPerFrame <= 8) + { + transferConfigB.destTransferSize = kEDMA_TransferSize1Bytes; + transferConfigB.minorLoopBytes = 1; + + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + transferConfigB.majorLoopCounts = handle->remainingSendByteCount - 2; + } + else + { + /*Only enable channel_B minorlink to channel_C , so need to add one count due to the last time is + majorlink , the majorlink would not trigger the channel_C*/ + transferConfigB.majorLoopCounts = handle->remainingSendByteCount + 1; + } + } + else + { + transferConfigB.destTransferSize = kEDMA_TransferSize2Bytes; + transferConfigB.minorLoopBytes = 2; + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + transferConfigB.majorLoopCounts = handle->remainingSendByteCount / 2 - 2; + } + else + { + /*Only enable channel_B minorlink to channel_C , so need to add one count due to the last time is + * majorlink*/ + transferConfigB.majorLoopCounts = handle->remainingSendByteCount / 2 + 1; + } + } + + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + { + EDMA_SetTransferConfig(handle->edmaTxDataToIntermediaryHandle->base, + handle->edmaTxDataToIntermediaryHandle->channel, &transferConfigB, softwareTCD); + EDMA_EnableAutoStopRequest(handle->edmaIntermediaryToTxRegHandle->base, + handle->edmaIntermediaryToTxRegHandle->channel, false); + } + else + { + EDMA_SetTransferConfig(handle->edmaTxDataToIntermediaryHandle->base, + handle->edmaTxDataToIntermediaryHandle->channel, &transferConfigB, NULL); + } + } + else + { + EDMA_SetTransferConfig(handle->edmaTxDataToIntermediaryHandle->base, + handle->edmaTxDataToIntermediaryHandle->channel, &transferConfigB, NULL); + } + + /***channel_C ***carry the "intermediary" to SPIx_PUSHR. used the edma Scatter Gather function on channel_C to + handle the last data */ + + EDMA_ResetChannel(handle->edmaIntermediaryToTxRegHandle->base, handle->edmaIntermediaryToTxRegHandle->channel); + + /*For DSPI instances with shared RX/TX DMA requests: use the scatter/gather to prepare the last data + * (handle->lastCommand) to SPI_PUSHR*/ + if (((1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) && (handle->remainingSendByteCount > 0))) { transferConfigC.srcAddr = (uint32_t) & (handle->lastCommand); transferConfigC.destAddr = (uint32_t)txAddr; @@ -580,7 +636,8 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand } if (((handle->remainingSendByteCount > 1) && (handle->bitsPerFrame <= 8)) || - ((handle->remainingSendByteCount > 2) && (handle->bitsPerFrame > 8))) + ((handle->remainingSendByteCount > 2) && (handle->bitsPerFrame > 8)) || + (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))) { transferConfigC.srcAddr = (uint32_t)(&(handle->command)); transferConfigC.destAddr = (uint32_t)txAddr; @@ -590,18 +647,28 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand transferConfigC.srcOffset = 0; transferConfigC.destOffset = 0; transferConfigC.minorLoopBytes = 4; - - if (handle->bitsPerFrame <= 8) + if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) { - transferConfigC.majorLoopCounts = handle->remainingSendByteCount - 1; + if (handle->bitsPerFrame <= 8) + { + transferConfigC.majorLoopCounts = handle->remainingSendByteCount - 1; + } + else + { + transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2 - 1; + } + + EDMA_SetTransferConfig(handle->edmaIntermediaryToTxRegHandle->base, + handle->edmaIntermediaryToTxRegHandle->channel, &transferConfigC, softwareTCD); } else { - transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2 - 1; + transferConfigC.majorLoopCounts = 1; + + EDMA_SetTransferConfig(handle->edmaIntermediaryToTxRegHandle->base, + handle->edmaIntermediaryToTxRegHandle->channel, &transferConfigC, NULL); } - EDMA_SetTransferConfig(handle->edmaIntermediaryToTxRegHandle->base, - handle->edmaIntermediaryToTxRegHandle->channel, &transferConfigC, softwareTCD); EDMA_EnableAutoStopRequest(handle->edmaIntermediaryToTxRegHandle->base, handle->edmaIntermediaryToTxRegHandle->channel, false); } @@ -673,20 +740,15 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand &preemption_config_t); } - /*Set the channel link. - For DSPI instances with shared RX/TX DMA requests: Rx DMA request -> channel_A -> channel_B-> channel_C. - For DSPI instances with separate RX and TX DMA requests: - Rx DMA request -> channel_A - Tx DMA request -> channel_C -> channel_B . (so need prepare the first data in "intermediary" before the DMA - transfer and then channel_B is used to prepare the next data to "intermediary" ) */ + /*Set the channel link.*/ if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) { /*if there is Tx DMA request , carry the 32bits data (handle->command) to PUSHR first , then link to channelB - to prepare the next 32bits data (User_send_buffer to handle->command) */ + to prepare the next 32bits data (txData to handle->command) */ if (handle->remainingSendByteCount > 1) { EDMA_SetChannelLink(handle->edmaIntermediaryToTxRegHandle->base, - handle->edmaIntermediaryToTxRegHandle->channel, kEDMA_MinorLink, + handle->edmaIntermediaryToTxRegHandle->channel, kEDMA_MajorLink, handle->edmaTxDataToIntermediaryHandle->channel); } @@ -699,12 +761,6 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, kEDMA_MinorLink, handle->edmaTxDataToIntermediaryHandle->channel); - if (handle->isThereExtraByte) - { - EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, - kEDMA_MajorLink, handle->edmaTxDataToIntermediaryHandle->channel); - } - EDMA_SetChannelLink(handle->edmaTxDataToIntermediaryHandle->base, handle->edmaTxDataToIntermediaryHandle->channel, kEDMA_MinorLink, handle->edmaIntermediaryToTxRegHandle->channel); @@ -723,37 +779,28 @@ static void EDMA_DspiMasterCallback(edma_handle_t *edmaHandle, bool transferDone, uint32_t tcds) { + assert(edmaHandle); + assert(g_dspiEdmaPrivateHandle); + dspi_master_edma_private_handle_t *dspiEdmaPrivateHandle; dspiEdmaPrivateHandle = (dspi_master_edma_private_handle_t *)g_dspiEdmaPrivateHandle; - uint32_t dataReceived; - DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); - if (dspiEdmaPrivateHandle->handle->isThereExtraByte) - { - while (!((dspiEdmaPrivateHandle->base)->SR & SPI_SR_RFDF_MASK)) - { - } - dataReceived = (dspiEdmaPrivateHandle->base)->POPR; - if (dspiEdmaPrivateHandle->handle->rxData) - { - (dspiEdmaPrivateHandle->handle->rxData[dspiEdmaPrivateHandle->handle->totalByteCount - 1]) = dataReceived; - } - } + dspiEdmaPrivateHandle->handle->state = kDSPI_Idle; if (dspiEdmaPrivateHandle->handle->callback) { dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle, kStatus_Success, dspiEdmaPrivateHandle->handle->userData); } - - dspiEdmaPrivateHandle->handle->state = kDSPI_Idle; } void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle) { + assert(handle); + DSPI_StopTransfer(base); DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); @@ -783,7 +830,8 @@ status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle size_t bytes; - bytes = EDMA_GetRemainingBytes(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel); + bytes = (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base, + handle->edmaRxRegToRxDataHandle->channel); *count = handle->totalByteCount - bytes; @@ -798,6 +846,8 @@ void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base, edma_handle_t *edmaTxDataToTxRegHandle) { assert(handle); + assert(edmaRxRegToRxDataHandle); + assert(edmaTxDataToTxRegHandle); /* Zero the handle. */ memset(handle, 0, sizeof(*handle)); @@ -816,7 +866,8 @@ void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base, status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer) { - assert(handle && transfer); + assert(handle); + assert(transfer); /* If send/receive length is zero */ if (transfer->dataSize == 0) @@ -836,7 +887,7 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle return kStatus_DSPI_Busy; } - edma_tcd_t *softwareTCD = (edma_tcd_t *)((uint32_t)(&handle->dspiSoftwareTCD[1]) & (~0x1FU)); + handle->state = kDSPI_Busy; uint32_t instance = DSPI_GetInstance(base); uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT; @@ -846,54 +897,51 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle /* If using a shared RX/TX DMA request, then this limits the amount of data we can transfer * due to the linked channel. The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame */ - if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) + uint32_t limited_size = 0; + if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) { - if (handle->bitsPerFrame > 8) + limited_size = 32767u; + } + else + { + limited_size = 511u; + } + + if (handle->bitsPerFrame > 8) + { + if (transfer->dataSize > (limited_size << 1u)) { - if (transfer->dataSize > 1022) - { - return kStatus_DSPI_OutOfRange; - } + handle->state = kDSPI_Idle; + return kStatus_DSPI_OutOfRange; } - else + } + else + { + if (transfer->dataSize > limited_size) { - if (transfer->dataSize > 511) - { - return kStatus_DSPI_OutOfRange; - } + handle->state = kDSPI_Idle; + return kStatus_DSPI_OutOfRange; } } - if ((handle->bitsPerFrame > 8) && (transfer->dataSize < 2)) + /*The data size should be even if the bitsPerFrame is greater than 8 (that is 2 bytes per frame in dspi) */ + if ((handle->bitsPerFrame > 8) && (transfer->dataSize & 0x1)) { + handle->state = kDSPI_Idle; return kStatus_InvalidArgument; } EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_DspiSlaveCallback, &s_dspiSlaveEdmaPrivateHandle[instance]); - handle->state = kDSPI_Busy; - /* Store transfer information */ handle->txData = transfer->txData; handle->rxData = transfer->rxData; handle->remainingSendByteCount = transfer->dataSize; handle->remainingReceiveByteCount = transfer->dataSize; handle->totalByteCount = transfer->dataSize; - handle->errorCount = 0; - - handle->isThereExtraByte = false; - if (handle->bitsPerFrame > 8) - { - if (handle->remainingSendByteCount % 2 == 1) - { - handle->remainingSendByteCount++; - handle->remainingReceiveByteCount--; - handle->isThereExtraByte = true; - } - } uint16_t wordToSend = 0; - uint8_t dummyData = DSPI_SLAVE_DUMMY_DATA; + uint8_t dummyData = DSPI_DUMMY_DATA; uint8_t dataAlreadyFed = 0; uint8_t dataFedMax = 2; @@ -929,16 +977,9 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle { wordToSend = *(handle->txData); ++handle->txData; /* Increment to next data byte */ - if ((handle->remainingSendByteCount == 2) && (handle->isThereExtraByte)) - { - wordToSend |= (unsigned)(dummyData) << 8U; - ++handle->txData; /* Increment to next data byte */ - } - else - { - wordToSend |= (unsigned)(*(handle->txData)) << 8U; - ++handle->txData; /* Increment to next data byte */ - } + + wordToSend |= (unsigned)(*(handle->txData)) << 8U; + ++handle->txData; /* Increment to next data byte */ } else { @@ -1025,6 +1066,10 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle transferConfigA.minorLoopBytes = 2; transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2; } + + /* Store the initially configured eDMA minor byte transfer count into the DSPI handle */ + handle->nbytes = transferConfigA.minorLoopBytes; + EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, &transferConfigA, NULL); EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, @@ -1036,98 +1081,47 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle /***channel_C *** used for carry the data from User_Send_Buffer to Tx_Data_Register(PUSHR_SLAVE)*/ EDMA_ResetChannel(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel); - /*If there is extra byte , it would use the */ - if (handle->isThereExtraByte) - { - if (handle->txData) - { - handle->txLastData = - handle->txData[handle->remainingSendByteCount - 2] | ((uint32_t)DSPI_SLAVE_DUMMY_DATA << 8); - } - else - { - handle->txLastData = DSPI_SLAVE_DUMMY_DATA | ((uint32_t)DSPI_SLAVE_DUMMY_DATA << 8); - } - transferConfigC.srcAddr = (uint32_t)(&(handle->txLastData)); - transferConfigC.destAddr = (uint32_t)txAddr; - transferConfigC.srcTransferSize = kEDMA_TransferSize4Bytes; - transferConfigC.destTransferSize = kEDMA_TransferSize4Bytes; - transferConfigC.srcOffset = 0; - transferConfigC.destOffset = 0; - transferConfigC.minorLoopBytes = 4; - transferConfigC.majorLoopCounts = 1; + transferConfigC.destAddr = (uint32_t)txAddr; + transferConfigC.destOffset = 0; - EDMA_TcdReset(softwareTCD); - EDMA_TcdSetTransferConfig(softwareTCD, &transferConfigC, NULL); - } - - /*Set another transferConfigC*/ - if ((handle->isThereExtraByte) && (handle->remainingSendByteCount == 2)) + if (handle->txData) { - EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, - &transferConfigC, NULL); + transferConfigC.srcAddr = (uint32_t)(&(handle->txData[0])); + transferConfigC.srcOffset = 1; } else { - transferConfigC.destAddr = (uint32_t)txAddr; - transferConfigC.destOffset = 0; - - if (handle->txData) - { - transferConfigC.srcAddr = (uint32_t)(&(handle->txData[0])); - transferConfigC.srcOffset = 1; - } - else - { - transferConfigC.srcAddr = (uint32_t)(&handle->txBuffIfNull); - transferConfigC.srcOffset = 0; - if (handle->bitsPerFrame <= 8) - { - handle->txBuffIfNull = DSPI_SLAVE_DUMMY_DATA; - } - else - { - handle->txBuffIfNull = (DSPI_SLAVE_DUMMY_DATA << 8) | DSPI_SLAVE_DUMMY_DATA; - } - } - - transferConfigC.srcTransferSize = kEDMA_TransferSize1Bytes; - + transferConfigC.srcAddr = (uint32_t)(&handle->txBuffIfNull); + transferConfigC.srcOffset = 0; if (handle->bitsPerFrame <= 8) { - transferConfigC.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigC.minorLoopBytes = 1; - transferConfigC.majorLoopCounts = handle->remainingSendByteCount; + handle->txBuffIfNull = DSPI_DUMMY_DATA; } else { - transferConfigC.destTransferSize = kEDMA_TransferSize2Bytes; - transferConfigC.minorLoopBytes = 2; - if (handle->isThereExtraByte) - { - transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2 - 1; - } - else - { - transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2; - } + handle->txBuffIfNull = (DSPI_DUMMY_DATA << 8) | DSPI_DUMMY_DATA; } - - if (handle->isThereExtraByte) - { - EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, - &transferConfigC, softwareTCD); - EDMA_EnableAutoStopRequest(handle->edmaTxDataToTxRegHandle->base, - handle->edmaTxDataToTxRegHandle->channel, false); - } - else - { - EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, - &transferConfigC, NULL); - } - - EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle); } + + transferConfigC.srcTransferSize = kEDMA_TransferSize1Bytes; + + if (handle->bitsPerFrame <= 8) + { + transferConfigC.destTransferSize = kEDMA_TransferSize1Bytes; + transferConfigC.minorLoopBytes = 1; + transferConfigC.majorLoopCounts = handle->remainingSendByteCount; + } + else + { + transferConfigC.destTransferSize = kEDMA_TransferSize2Bytes; + transferConfigC.minorLoopBytes = 2; + transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2; + } + + EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, + &transferConfigC, NULL); + + EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle); } EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle); @@ -1195,37 +1189,28 @@ static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle, bool transferDone, uint32_t tcds) { + assert(edmaHandle); + assert(g_dspiEdmaPrivateHandle); + dspi_slave_edma_private_handle_t *dspiEdmaPrivateHandle; dspiEdmaPrivateHandle = (dspi_slave_edma_private_handle_t *)g_dspiEdmaPrivateHandle; - uint32_t dataReceived; - DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); - if (dspiEdmaPrivateHandle->handle->isThereExtraByte) - { - while (!((dspiEdmaPrivateHandle->base)->SR & SPI_SR_RFDF_MASK)) - { - } - dataReceived = (dspiEdmaPrivateHandle->base)->POPR; - if (dspiEdmaPrivateHandle->handle->rxData) - { - (dspiEdmaPrivateHandle->handle->rxData[dspiEdmaPrivateHandle->handle->totalByteCount - 1]) = dataReceived; - } - } + dspiEdmaPrivateHandle->handle->state = kDSPI_Idle; if (dspiEdmaPrivateHandle->handle->callback) { dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle, kStatus_Success, dspiEdmaPrivateHandle->handle->userData); } - - dspiEdmaPrivateHandle->handle->state = kDSPI_Idle; } void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle) { + assert(handle); + DSPI_StopTransfer(base); DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable); @@ -1254,7 +1239,8 @@ status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t size_t bytes; - bytes = EDMA_GetRemainingBytes(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel); + bytes = (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base, + handle->edmaRxRegToRxDataHandle->channel); *count = handle->totalByteCount - bytes; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi_edma.h index 326b7ee442..23e29ce298 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_dspi_edma.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,8 +37,6 @@ * @{ */ -/*! @file */ - /*********************************************************************************************************************** * Definitions **********************************************************************************************************************/ @@ -57,9 +55,9 @@ typedef struct _dspi_slave_edma_handle dspi_slave_edma_handle_t; * @brief Completion callback function pointer type. * * @param base DSPI peripheral base address. - * @param handle Pointer to the handle for the DSPI master. + * @param handle A pointer to the handle for the DSPI master. * @param status Success or error code describing whether the transfer completed. - * @param userData Arbitrary pointer-dataSized value passed from the application. + * @param userData An arbitrary pointer-dataSized value passed from the application. */ typedef void (*dspi_master_edma_transfer_callback_t)(SPI_Type *base, dspi_master_edma_handle_t *handle, @@ -69,38 +67,39 @@ typedef void (*dspi_master_edma_transfer_callback_t)(SPI_Type *base, * @brief Completion callback function pointer type. * * @param base DSPI peripheral base address. - * @param handle Pointer to the handle for the DSPI slave. + * @param handle A pointer to the handle for the DSPI slave. * @param status Success or error code describing whether the transfer completed. - * @param userData Arbitrary pointer-dataSized value passed from the application. + * @param userData An arbitrary pointer-dataSized value passed from the application. */ typedef void (*dspi_slave_edma_transfer_callback_t)(SPI_Type *base, dspi_slave_edma_handle_t *handle, status_t status, void *userData); -/*! @brief DSPI master eDMA transfer handle structure used for transactional API. */ +/*! @brief DSPI master eDMA transfer handle structure used for the transactional API. */ struct _dspi_master_edma_handle { - uint32_t bitsPerFrame; /*!< Desired number of bits per frame. */ - volatile uint32_t command; /*!< Desired data command. */ - volatile uint32_t lastCommand; /*!< Desired last data command. */ + uint32_t bitsPerFrame; /*!< The desired number of bits per frame. */ + volatile uint32_t command; /*!< The desired data command. */ + volatile uint32_t lastCommand; /*!< The desired last data command. */ uint8_t fifoSize; /*!< FIFO dataSize. */ - volatile bool isPcsActiveAfterTransfer; /*!< Is PCS signal keep active after the last frame transfer.*/ - volatile bool isThereExtraByte; /*!< Is there extra byte.*/ + volatile bool + isPcsActiveAfterTransfer; /*!< Indicates whether the PCS signal keeps active after the last frame transfer.*/ + + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + volatile uint8_t state; /*!< DSPI transfer state , _dspi_transfer_state.*/ uint8_t *volatile txData; /*!< Send buffer. */ uint8_t *volatile rxData; /*!< Receive buffer. */ - volatile size_t remainingSendByteCount; /*!< Number of bytes remaining to send.*/ - volatile size_t remainingReceiveByteCount; /*!< Number of bytes remaining to receive.*/ - size_t totalByteCount; /*!< Number of transfer bytes*/ + volatile size_t remainingSendByteCount; /*!< A number of bytes remaining to send.*/ + volatile size_t remainingReceiveByteCount; /*!< A number of bytes remaining to receive.*/ + size_t totalByteCount; /*!< A number of transfer bytes*/ uint32_t rxBuffIfNull; /*!< Used if there is not rxData for DMA purpose.*/ uint32_t txBuffIfNull; /*!< Used if there is not txData for DMA purpose.*/ - volatile uint8_t state; /*!< DSPI transfer state , _dspi_transfer_state.*/ - dspi_master_edma_transfer_callback_t callback; /*!< Completion callback. */ void *userData; /*!< Callback user data. */ @@ -111,33 +110,30 @@ struct _dspi_master_edma_handle edma_tcd_t dspiSoftwareTCD[2]; /*!CR; tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); @@ -134,8 +138,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config) void EDMA_Deinit(DMA_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate EDMA periphral clock */ CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void EDMA_GetDefaultConfig(edma_config_t *config) @@ -409,46 +415,32 @@ void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask) } } -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel) +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel) { assert(channel < FSL_FEATURE_EDMA_MODULE_CHANNEL); - uint32_t nbytes = 0; - uint32_t remainingBytes = 0; + uint32_t remainingCount = 0; if (DMA_CSR_DONE_MASK & base->TCD[channel].CSR) { - remainingBytes = 0; + remainingCount = 0; } else { - /* Calculate the nbytes */ - if (base->TCD[channel].NBYTES_MLOFFYES & (DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK)) - { - nbytes = (base->TCD[channel].NBYTES_MLOFFYES & DMA_NBYTES_MLOFFYES_NBYTES_MASK) >> - DMA_NBYTES_MLOFFYES_NBYTES_SHIFT; - } - else - { - nbytes = - (base->TCD[channel].NBYTES_MLOFFNO & DMA_NBYTES_MLOFFNO_NBYTES_MASK) >> DMA_NBYTES_MLOFFNO_NBYTES_SHIFT; - } /* Calculate the unfinished bytes */ if (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK) { - remainingBytes = ((base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> - DMA_CITER_ELINKYES_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> DMA_CITER_ELINKYES_CITER_SHIFT; } else { - remainingBytes = - ((base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT) * - nbytes; + remainingCount = + (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> DMA_CITER_ELINKNO_CITER_SHIFT; } } - return remainingBytes; + return remainingCount; } uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) @@ -497,14 +489,19 @@ void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel) uint32_t channelIndex; edma_tcd_t *tcdRegs; + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + handle->base = base; handle->channel = channel; /* Get the DMA instance number */ edmaInstance = EDMA_GetInstance(base); channelIndex = (edmaInstance * FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; s_EDMAHandle[channelIndex] = handle; + /* Enable NVIC interrupt */ - EnableIRQ(s_edmaIRQNumber[channelIndex]); + EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]); + /* Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set), CSR will be 0. Because in order to suit EDMA busy check mechanism in @@ -558,8 +555,8 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, assert(config != NULL); assert(srcAddr != NULL); assert(destAddr != NULL); - assert(srcWidth == 1U || srcWidth == 2U || srcWidth == 4U || srcWidth == 16U || srcWidth == 32U); - assert(destWidth == 1U || destWidth == 2U || destWidth == 4U || destWidth == 16U || destWidth == 32U); + assert((srcWidth == 1U) || (srcWidth == 2U) || (srcWidth == 4U) || (srcWidth == 16U) || (srcWidth == 32U)); + assert((destWidth == 1U) || (destWidth == 2U) || (destWidth == 4U) || (destWidth == 16U) || (destWidth == 32U)); assert(transferBytes % bytesEachRequest == 0); config->destAddr = (uint32_t)destAddr; @@ -825,11 +822,11 @@ void EDMA_HandleIRQ(edma_handle_t *handle) /* Clear EDMA interrupt flag */ handle->base->CINT = handle->channel; - if (handle->tcdPool == NULL) + if ((handle->tcdPool == NULL) && (handle->callback != NULL)) { (handle->callback)(handle, handle->userData, true, 0); } - else /* Use the TCD queue. */ + else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */ { uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA; uint32_t sga_index; @@ -839,19 +836,19 @@ void EDMA_HandleIRQ(edma_handle_t *handle) /* Check if transfer is already finished. */ transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0); - /* Get the offset of the current transfer TCD blcoks. */ + /* Get the offset of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga -= (uint32_t)handle->tcdPool; - /* Get the index of the current transfer TCD blcoks. */ + /* Get the index of the next transfer TCD blcoks to be loaded into the eDMA engine. */ sga_index = sga / sizeof(edma_tcd_t); /* Adjust header positions. */ if (transfer_done) { - /* New header shall point to the next TCD (current one is already finished) */ + /* New header shall point to the next TCD to be loaded (current one is already finished) */ new_header = sga_index; } else { - /* New header shall point to this descriptor (not finished yet) */ + /* New header shall point to this descriptor currently loaded (not finished yet) */ new_header = sga_index ? sga_index - 1U : handle->tcdSize - 1U; } /* Calculate the number of finished TCDs */ @@ -863,7 +860,7 @@ void EDMA_HandleIRQ(edma_handle_t *handle) } else { - /* Internal error occurs. */ + /* No TCD in the memory are going to be loaded or internal error occurs. */ tcds_done = 0; } } @@ -875,9 +872,9 @@ void EDMA_HandleIRQ(edma_handle_t *handle) tcds_done += handle->tcdSize; } } - /* Advance header to the point beyond the last finished TCD block. */ + /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */ handle->header = new_header; - /* Release TCD blocks. */ + /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */ handle->tcdUsed -= tcds_done; /* Invoke callback function. */ if (handle->callback) @@ -937,12 +934,260 @@ void DMA0_37_DriverIRQHandler(void) EDMA_HandleIRQ(s_EDMAHandle[7]); } } + +#if defined(DMA1) +void DMA1_04_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA1_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA1_26_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA1_37_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} +#endif #endif /* 8 channels (Shared) */ +/* 16 channels (Shared): K32H844P */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U + +void DMA0_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } +} + +void DMA0_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } +} + +void DMA0_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } +} + +void DMA0_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } +} + +void DMA0_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +#if defined(DMA1) +void DMA1_08_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } +} + +void DMA1_19_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } +} + +void DMA1_210_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } +} + +void DMA1_311_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } +} + +void DMA1_412_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA1_513_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA1_614_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA1_715_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } + if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif +#endif /* 16 channels (Shared) */ + /* 32 channels (Shared): k80 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U -void DMA0_DMA16_IRQHandler(void) +void DMA0_DMA16_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) { @@ -954,7 +1199,7 @@ void DMA0_DMA16_IRQHandler(void) } } -void DMA1_DMA17_IRQHandler(void) +void DMA1_DMA17_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) { @@ -966,7 +1211,7 @@ void DMA1_DMA17_IRQHandler(void) } } -void DMA2_DMA18_IRQHandler(void) +void DMA2_DMA18_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) { @@ -978,7 +1223,7 @@ void DMA2_DMA18_IRQHandler(void) } } -void DMA3_DMA19_IRQHandler(void) +void DMA3_DMA19_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) { @@ -990,7 +1235,7 @@ void DMA3_DMA19_IRQHandler(void) } } -void DMA4_DMA20_IRQHandler(void) +void DMA4_DMA20_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) { @@ -1002,7 +1247,7 @@ void DMA4_DMA20_IRQHandler(void) } } -void DMA5_DMA21_IRQHandler(void) +void DMA5_DMA21_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) { @@ -1014,7 +1259,7 @@ void DMA5_DMA21_IRQHandler(void) } } -void DMA6_DMA22_IRQHandler(void) +void DMA6_DMA22_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) { @@ -1026,7 +1271,7 @@ void DMA6_DMA22_IRQHandler(void) } } -void DMA7_DMA23_IRQHandler(void) +void DMA7_DMA23_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) { @@ -1038,7 +1283,7 @@ void DMA7_DMA23_IRQHandler(void) } } -void DMA8_DMA24_IRQHandler(void) +void DMA8_DMA24_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) { @@ -1050,7 +1295,7 @@ void DMA8_DMA24_IRQHandler(void) } } -void DMA9_DMA25_IRQHandler(void) +void DMA9_DMA25_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) { @@ -1062,7 +1307,7 @@ void DMA9_DMA25_IRQHandler(void) } } -void DMA10_DMA26_IRQHandler(void) +void DMA10_DMA26_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) { @@ -1074,7 +1319,7 @@ void DMA10_DMA26_IRQHandler(void) } } -void DMA11_DMA27_IRQHandler(void) +void DMA11_DMA27_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) { @@ -1086,7 +1331,7 @@ void DMA11_DMA27_IRQHandler(void) } } -void DMA12_DMA28_IRQHandler(void) +void DMA12_DMA28_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) { @@ -1098,7 +1343,7 @@ void DMA12_DMA28_IRQHandler(void) } } -void DMA13_DMA29_IRQHandler(void) +void DMA13_DMA29_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) { @@ -1110,7 +1355,7 @@ void DMA13_DMA29_IRQHandler(void) } } -void DMA14_DMA30_IRQHandler(void) +void DMA14_DMA30_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) { @@ -1122,7 +1367,7 @@ void DMA14_DMA30_IRQHandler(void) } } -void DMA15_DMA31_IRQHandler(void) +void DMA15_DMA31_DriverIRQHandler(void) { if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) { @@ -1135,6 +1380,202 @@ void DMA15_DMA31_IRQHandler(void) } #endif /* 32 channels (Shared) */ +/* 32 channels (Shared): MCIMX7U5_M4 */ +#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U + +void DMA0_0_4_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[0]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[4]); + } +} + +void DMA0_1_5_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[1]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[5]); + } +} + +void DMA0_2_6_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[2]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[6]); + } +} + +void DMA0_3_7_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[3]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[7]); + } +} + +void DMA0_8_12_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[8]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[12]); + } +} + +void DMA0_9_13_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[9]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[13]); + } +} + +void DMA0_10_14_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[10]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[14]); + } +} + +void DMA0_11_15_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[11]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[15]); + } +} + +void DMA0_16_20_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[16]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[20]); + } +} + +void DMA0_17_21_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[17]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[21]); + } +} + +void DMA0_18_22_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[18]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[22]); + } +} + +void DMA0_19_23_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[19]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[23]); + } +} + +void DMA0_24_28_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[24]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[28]); + } +} + +void DMA0_25_29_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[25]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[29]); + } +} + +void DMA0_26_30_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[26]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[30]); + } +} + +void DMA0_27_31_DriverIRQHandler(void) +{ + if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[27]); + } + if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & kEDMA_InterruptFlag) != 0U) + { + EDMA_HandleIRQ(s_EDMAHandle[31]); + } +} +#endif /* 32 channels (Shared): MCIMX7U5 */ + /* 4 channels (No Shared): kv10 */ #if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL > 0 diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_edma.h index ca9632e247..a97622d7e1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_edma.h @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* 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. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef _FSL_EDMA_H_ #define _FSL_EDMA_H_ @@ -34,11 +34,10 @@ #include "fsl_common.h" /*! - * @addtogroup edma_driver + * @addtogroup edma * @{ */ -/*! @file */ /******************************************************************************* * Definitions ******************************************************************************/ @@ -46,7 +45,7 @@ /*! @name Driver version */ /*@{*/ /*! @brief eDMA driver version */ -#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ +#define FSL_EDMA_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1. */ /*@}*/ /*! @brief Compute the offset unit from DCHPRI3 */ @@ -78,28 +77,28 @@ typedef enum _edma_modulo kEDMA_Modulo128bytes, /*!< Circular buffer size is 128 bytes. */ kEDMA_Modulo256bytes, /*!< Circular buffer size is 256 bytes. */ kEDMA_Modulo512bytes, /*!< Circular buffer size is 512 bytes. */ - kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1K bytes. */ - kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2K bytes. */ - kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4K bytes. */ - kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8K bytes. */ - kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16K bytes. */ - kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32K bytes. */ - kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64K bytes. */ - kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128K bytes. */ - kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256K bytes. */ - kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512K bytes. */ - kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1M bytes. */ - kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2M bytes. */ - kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4M bytes. */ - kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8M bytes. */ - kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16M bytes. */ - kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32M bytes. */ - kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64M bytes. */ - kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128M bytes. */ - kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256M bytes. */ - kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512M bytes. */ - kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1G bytes. */ - kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2G bytes. */ + kEDMA_Modulo1Kbytes, /*!< Circular buffer size is 1 K bytes. */ + kEDMA_Modulo2Kbytes, /*!< Circular buffer size is 2 K bytes. */ + kEDMA_Modulo4Kbytes, /*!< Circular buffer size is 4 K bytes. */ + kEDMA_Modulo8Kbytes, /*!< Circular buffer size is 8 K bytes. */ + kEDMA_Modulo16Kbytes, /*!< Circular buffer size is 16 K bytes. */ + kEDMA_Modulo32Kbytes, /*!< Circular buffer size is 32 K bytes. */ + kEDMA_Modulo64Kbytes, /*!< Circular buffer size is 64 K bytes. */ + kEDMA_Modulo128Kbytes, /*!< Circular buffer size is 128 K bytes. */ + kEDMA_Modulo256Kbytes, /*!< Circular buffer size is 256 K bytes. */ + kEDMA_Modulo512Kbytes, /*!< Circular buffer size is 512 K bytes. */ + kEDMA_Modulo1Mbytes, /*!< Circular buffer size is 1 M bytes. */ + kEDMA_Modulo2Mbytes, /*!< Circular buffer size is 2 M bytes. */ + kEDMA_Modulo4Mbytes, /*!< Circular buffer size is 4 M bytes. */ + kEDMA_Modulo8Mbytes, /*!< Circular buffer size is 8 M bytes. */ + kEDMA_Modulo16Mbytes, /*!< Circular buffer size is 16 M bytes. */ + kEDMA_Modulo32Mbytes, /*!< Circular buffer size is 32 M bytes. */ + kEDMA_Modulo64Mbytes, /*!< Circular buffer size is 64 M bytes. */ + kEDMA_Modulo128Mbytes, /*!< Circular buffer size is 128 M bytes. */ + kEDMA_Modulo256Mbytes, /*!< Circular buffer size is 256 M bytes. */ + kEDMA_Modulo512Mbytes, /*!< Circular buffer size is 512 M bytes. */ + kEDMA_Modulo1Gbytes, /*!< Circular buffer size is 1 G bytes. */ + kEDMA_Modulo2Gbytes, /*!< Circular buffer size is 2 G bytes. */ } edma_modulo_t; /*! @brief Bandwidth control */ @@ -143,7 +142,7 @@ enum _edma_error_status_flags #if defined(FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT) && FSL_FEATURE_EDMA_CHANNEL_GROUP_COUNT > 1 kEDMA_GroupPriorityErrorFlag = DMA_ES_GPE_MASK, /*!< Group priority is not unique. */ #endif - kEDMA_ValidFlag = DMA_ES_VLD_MASK, /*!< No error occurred, this bit will be 0, otherwise be 1 */ + kEDMA_ValidFlag = DMA_ES_VLD_MASK, /*!< No error occurred, this bit is 0. Otherwise, it is 1. */ }; /*! @brief eDMA interrupt source */ @@ -178,7 +177,7 @@ typedef struct _edma_config the link channel is itself. */ bool enableHaltOnError; /*!< Enable (true) transfer halt on error. Any error causes the HALT bit to set. Subsequently, all service requests are ignored until the HALT bit is cleared.*/ - bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method, or fixed priority + bool enableRoundRobinArbitration; /*!< Enable (true) round robin channel arbitration method or fixed priority arbitration is used for channel selection */ bool enableDebugMode; /*!< Enable(true) eDMA debug mode. When in debug mode, the eDMA stalls the start of a new channel. Executing channels are allowed to complete. */ @@ -212,15 +211,15 @@ typedef struct _edma_transfer_config form the next-state value as each source read is completed. */ int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to form the next-state value as each destination write is completed. */ - uint16_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ + uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/ uint32_t majorLoopCounts; /*!< Major loop iteration count. */ } edma_transfer_config_t; /*! @brief eDMA channel priority configuration */ typedef struct _edma_channel_Preemption_config { - bool enableChannelPreemption; /*!< If true: channel can be suspended by other channel with higher priority */ - bool enablePreemptAbility; /*!< If true: channel can suspend other channel with low priority */ + bool enableChannelPreemption; /*!< If true: a channel can be suspended by other channel with higher priority */ + bool enablePreemptAbility; /*!< If true: a channel can suspend other channel with low priority */ uint8_t channelPriority; /*!< Channel priority */ } edma_channel_Preemption_config_t; @@ -229,14 +228,14 @@ typedef struct _edma_minor_offset_config { bool enableSrcMinorOffset; /*!< Enable(true) or Disable(false) source minor loop offset. */ bool enableDestMinorOffset; /*!< Enable(true) or Disable(false) destination minor loop offset. */ - uint32_t minorOffset; /*!< Offset for minor loop mapping. */ + uint32_t minorOffset; /*!< Offset for a minor loop mapping. */ } edma_minor_offset_config_t; /*! * @brief eDMA TCD. * * This structure is same as TCD register which is described in reference manual, - * and is used to configure scatter/gather feature as a next hardware TCD. + * and is used to configure the scatter/gather feature as a next hardware TCD. */ typedef struct _edma_tcd { @@ -256,20 +255,21 @@ typedef struct _edma_tcd /*! @brief Callback for eDMA */ struct _edma_handle; -/*! @brief Define Callback function for eDMA. */ +/*! @brief Define callback function for eDMA. */ typedef void (*edma_callback)(struct _edma_handle *handle, void *userData, bool transferDone, uint32_t tcds); /*! @brief eDMA transfer handle structure */ typedef struct _edma_handle { - edma_callback callback; /*!< Callback function for major count exhausted. */ - void *userData; /*!< Callback function parameter. */ - DMA_Type *base; /*!< eDMA peripheral base address. */ - edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ - uint8_t channel; /*!< eDMA channel number. */ - volatile int8_t header; /*!< The first TCD index. */ - volatile int8_t tail; /*!< The last TCD index. */ - volatile int8_t tcdUsed; /*!< The number of used TCD slots. */ + edma_callback callback; /*!< Callback function for major count exhausted. */ + void *userData; /*!< Callback function parameter. */ + DMA_Type *base; /*!< eDMA peripheral base address. */ + edma_tcd_t *tcdPool; /*!< Pointer to memory stored TCDs. */ + uint8_t channel; /*!< eDMA channel number. */ + volatile int8_t header; /*!< The first TCD index. Should point to the next TCD to be loaded into the eDMA engine. */ + volatile int8_t tail; /*!< The last TCD index. Should point to the next TCD to be stored into the memory pool. */ + volatile int8_t tcdUsed; /*!< The number of used TCD slots. Should reflect the number of TCDs can be used/loaded in + the memory. */ volatile int8_t tcdSize; /*!< The total number of TCD slots in the queue. */ uint8_t flags; /*!< The status of the current channel. */ } edma_handle_t; @@ -282,24 +282,24 @@ extern "C" { #endif /* __cplusplus */ /*! - * @name eDMA initialization and De-initialization + * @name eDMA initialization and de-initialization * @{ */ /*! - * @brief Initializes eDMA peripheral. + * @brief Initializes the eDMA peripheral. * - * This function ungates the eDMA clock and configure eDMA peripheral according + * This function ungates the eDMA clock and configures the eDMA peripheral according * to the configuration structure. * * @param base eDMA peripheral base address. - * @param config Pointer to configuration structure, see "edma_config_t". - * @note This function enable the minor loop map feature. + * @param config A pointer to the configuration structure, see "edma_config_t". + * @note This function enables the minor loop map feature. */ void EDMA_Init(DMA_Type *base, const edma_config_t *config); /*! - * @brief Deinitializes eDMA peripheral. + * @brief Deinitializes the eDMA peripheral. * * This function gates the eDMA clock. * @@ -310,8 +310,8 @@ void EDMA_Deinit(DMA_Type *base); /*! * @brief Gets the eDMA default configuration structure. * - * This function sets the configuration structure to a default value. - * The default configuration is set to the following value: + * This function sets the configuration structure to default values. + * The default configuration is set to the following values. * @code * config.enableContinuousLinkMode = false; * config.enableHaltOnError = true; @@ -319,7 +319,7 @@ void EDMA_Deinit(DMA_Type *base); * config.enableDebugMode = false; * @endcode * - * @param config Pointer to eDMA configuration structure. + * @param config A pointer to the eDMA configuration structure. */ void EDMA_GetDefaultConfig(edma_config_t *config); @@ -330,22 +330,22 @@ void EDMA_GetDefaultConfig(edma_config_t *config); */ /*! - * @brief Sets all TCD registers to a default value. + * @brief Sets all TCD registers to default values. * - * This function sets TCD registers for this channel to default value. + * This function sets TCD registers for this channel to default values. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @note This function must not be called while the channel transfer is on-going, - * or it will case unpredicated results. - * @note This function will enable auto stop request feature. + * @note This function must not be called while the channel transfer is ongoing + * or it causes unpredictable results. + * @note This function enables the auto stop request feature. */ void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); /*! * @brief Configures the eDMA transfer attribute. * - * This function configure the transfer attribute, including source address, destination address, + * This function configures the transfer attribute, including source address, destination address, * transfer size, address offset, and so on. It also configures the scatter gather feature if the * user supplies the TCD address. * Example: @@ -361,11 +361,11 @@ void EDMA_ResetChannel(DMA_Type *base, uint32_t channel); * @param base eDMA peripheral base address. * @param channel eDMA channel number. * @param config Pointer to eDMA transfer configuration structure. - * @param nextTcd Point to TCD structure. It can be NULL if user + * @param nextTcd Point to TCD structure. It can be NULL if users * do not want to enable scatter/gather feature. - * @note If nextTcd is not NULL, it means scatter gather feature will be enabled. - * And DREQ bit will be cleared in the previous transfer configuration which - * will be set in eDMA_ResetChannel. + * @note If nextTcd is not NULL, it means scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the eDMA_ResetChannel. */ void EDMA_SetTransferConfig(DMA_Type *base, uint32_t channel, @@ -375,12 +375,12 @@ void EDMA_SetTransferConfig(DMA_Type *base, /*! * @brief Configures the eDMA minor offset feature. * - * Minor offset means signed-extended value added to source address or destination + * The minor offset means that the signed-extended value is added to the source address or destination * address after each minor loop. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param config Pointer to Minor offset configuration structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config); @@ -391,7 +391,7 @@ void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_mino * * @param base eDMA peripheral base address. * @param channel eDMA channel number - * @param config Pointer to channel preemption configuration structure. + * @param config A pointer to the channel preemption configuration structure. */ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, uint32_t channel, @@ -408,30 +408,31 @@ static inline void EDMA_SetChannelPreemptionConfig(DMA_Type *base, /*! * @brief Sets the channel link for the eDMA transfer. * - * This function configures minor link or major link mode. The minor link means that the channel link is - * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is exhausted. + * This function configures either the minor link or the major link mode. The minor link means that the channel link is + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param type Channel link type, it can be one of: + * @param type A channel link type, which can be one of the following: * @arg kEDMA_LinkNone * @arg kEDMA_MinorLink * @arg kEDMA_MajorLink * @param linkedChannel The linked channel number. - * @note User should ensure that DONE flag is cleared before call this interface, or the configuration will be invalid. + * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. */ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel); /*! * @brief Sets the bandwidth for the eDMA transfer. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences + * Because the eDMA processes the minor loop, it continuously generates read/write sequences * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param bandWidth Bandwidth setting, it can be one of: + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -439,7 +440,7 @@ void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_typ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth); /*! - * @brief Sets the source modulo and destination modulo for eDMA transfer. + * @brief Sets the source modulo and the destination modulo for the eDMA transfer. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data @@ -447,8 +448,8 @@ void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWi * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -458,7 +459,7 @@ void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, e * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable(ture) or disable(false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -475,7 +476,7 @@ static inline void EDMA_EnableAsyncRequest(DMA_Type *base, uint32_t channel, boo * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param enable The command for enable (true) or disable (false). + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, bool enable) { @@ -489,7 +490,7 @@ static inline void EDMA_EnableAutoStopRequest(DMA_Type *base, uint32_t channel, * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param mask The mask of interrupt source to be set. User need to use + * @param mask The mask of interrupt source to be set. Users need to use * the defined edma_interrupt_enable_t type. */ void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); @@ -499,7 +500,7 @@ void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mas * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param mask The mask of interrupt source to be set. Use + * @param mask The mask of the interrupt source to be set. Use * the defined edma_interrupt_enable_t type. */ void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask); @@ -516,15 +517,15 @@ void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t ma * This function sets all fields for this TCD structure to default value. * * @param tcd Pointer to the TCD structure. - * @note This function will enable auto stop request feature. + * @note This function enables the auto stop request feature. */ void EDMA_TcdReset(edma_tcd_t *tcd); /*! * @brief Configures the eDMA TCD transfer attribute. * - * TCD is a transfer control descriptor. The content of the TCD is the same as hardware TCD registers. - * STCD is used in scatter-gather mode. + * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. + * The STCD is used in the scatter-gather mode. * This function configures the TCD transfer attribute, including source address, destination address, * transfer size, address offset, and so on. It also configures the scatter gather feature if the * user supplies the next TCD address. @@ -540,33 +541,34 @@ void EDMA_TcdReset(edma_tcd_t *tcd); * * @param tcd Pointer to the TCD structure. * @param config Pointer to eDMA transfer configuration structure. - * @param nextTcd Pointer to the next TCD structure. It can be NULL if user + * @param nextTcd Pointer to the next TCD structure. It can be NULL if users * do not want to enable scatter/gather feature. - * @note TCD address should be 32 bytes aligned, or it will cause eDMA error. - * @note If nextTcd is not NULL, it means scatter gather feature will be enabled. - * And DREQ bit will be cleared in the previous transfer configuration which - * will be set in EDMA_TcdReset. + * @note TCD address should be 32 bytes aligned or it causes an eDMA error. + * @note If the nextTcd is not NULL, the scatter gather feature is enabled + * and DREQ bit is cleared in the previous transfer configuration, which + * is set in the EDMA_TcdReset. */ void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd); /*! * @brief Configures the eDMA TCD minor offset feature. * - * Minor offset is a signed-extended value added to the source address or destination + * A minor offset is a signed-extended value added to the source address or a destination * address after each minor loop. * - * @param tcd Point to the TCD structure. - * @param config Pointer to Minor offset configuration structure. + * @param tcd A point to the TCD structure. + * @param config A pointer to the minor offset configuration structure. */ void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config); /*! - * @brief Sets the channel link for eDMA TCD. + * @brief Sets the channel link for the eDMA TCD. * * This function configures either a minor link or a major link. The minor link means the channel link is - * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is exhausted. + * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is + * exhausted. * - * @note User should ensure that DONE flag is cleared before call this interface, or the configuration will be invalid. + * @note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. * @param tcd Point to the TCD structure. * @param type Channel link type, it can be one of: * @arg kEDMA_LinkNone @@ -579,11 +581,11 @@ void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint /*! * @brief Sets the bandwidth for the eDMA TCD. * - * In general, because the eDMA processes the minor loop, it continuously generates read/write sequences - * until the minor count is exhausted. Bandwidth forces the eDMA to stall after the completion of + * Because the eDMA processes the minor loop, it continuously generates read/write sequences + * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of * each read/write access to control the bus request bandwidth seen by the crossbar switch. - * @param tcd Point to the TCD structure. - * @param bandWidth Bandwidth setting, it can be one of: + * @param tcd A pointer to the TCD structure. + * @param bandWidth A bandwidth setting, which can be one of the following: * @arg kEDMABandwidthStallNone * @arg kEDMABandwidthStall4Cycle * @arg kEDMABandwidthStall8Cycle @@ -597,15 +599,15 @@ static inline void EDMA_TcdSetBandWidth(edma_tcd_t *tcd, edma_bandwidth_t bandWi } /*! - * @brief Sets the source modulo and destination modulo for eDMA TCD. + * @brief Sets the source modulo and the destination modulo for the eDMA TCD. * * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) * calculation is performed or the original register value. It provides the ability to implement a circular data * queue easily. * - * @param tcd Point to the TCD structure. - * @param srcModulo Source modulo value. - * @param destModulo Destination modulo value. + * @param tcd A pointer to the TCD structure. + * @param srcModulo A source modulo value. + * @param destModulo A destination modulo value. */ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo); @@ -614,8 +616,8 @@ void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t d * * If enabling the auto stop request, the eDMA hardware automatically disables the hardware channel request. * - * @param tcd Point to the TCD structure. - * @param enable The command for enable(ture) or disable(false). + * @param tcd A pointer to the TCD structure. + * @param enable The command to enable (true) or disable (false). */ static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) { @@ -629,7 +631,7 @@ static inline void EDMA_TcdEnableAutoStopRequest(edma_tcd_t *tcd, bool enable) * @brief Enables the interrupt source for the eDMA TCD. * * @param tcd Point to the TCD structure. - * @param mask The mask of interrupt source to be set. User need to use + * @param mask The mask of interrupt source to be set. Users need to use * the defined edma_interrupt_enable_t type. */ void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask); @@ -638,7 +640,7 @@ void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask); * @brief Disables the interrupt source for the eDMA TCD. * * @param tcd Point to the TCD structure. - * @param mask The mask of interrupt source to be set. User need to use + * @param mask The mask of interrupt source to be set. Users need to use * the defined edma_interrupt_enable_t type. */ void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask); @@ -680,7 +682,7 @@ static inline void EDMA_DisableChannelRequest(DMA_Type *base, uint32_t channel) } /*! - * @brief Starts the eDMA transfer by software trigger. + * @brief Starts the eDMA transfer by using the software trigger. * * This function starts a minor loop transfer. * @@ -701,25 +703,34 @@ static inline void EDMA_TriggerChannelStart(DMA_Type *base, uint32_t channel) */ /*! - * @brief Gets the Remaining bytes from the eDMA current channel TCD. + * @brief Gets the remaining major loop count from the eDMA current channel TCD. * * This function checks the TCD (Task Control Descriptor) status for a specified - * eDMA channel and returns the the number of bytes that have not finished. + * eDMA channel and returns the the number of major loop count that has not finished. * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @return Bytes have not been transferred yet for the current TCD. - * @note This function can only be used to get unfinished bytes of transfer without - * the next TCD, or it might be inaccuracy. + * @return Major loop count which has not been transferred yet for the current TCD. + * @note 1. This function can only be used to get unfinished major loop count of transfer without + * the next TCD, or it might be inaccuracy. + * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while + * the channel is running. + * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO + * register is needed while the eDMA IP does not support getting it while a channel is active. + * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine + * is working with while a channel is running. + * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example + * copied before enabling the channel) is needed. The formula to calculate it is shown below: + * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) */ -uint32_t EDMA_GetRemainingBytes(DMA_Type *base, uint32_t channel); +uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel); /*! * @brief Gets the eDMA channel error status flags. * * @param base eDMA peripheral base address. - * @return The mask of error status flags. User need to use the - * _edma_error_status_flags type to decode the return variables. + * @return The mask of error status flags. Users need to use the +* _edma_error_status_flags type to decode the return variables. */ static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) { @@ -731,7 +742,7 @@ static inline uint32_t EDMA_GetErrorStatusFlags(DMA_Type *base) * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @return The mask of channel status flags. User need to use the + * @return The mask of channel status flags. Users need to use the * _edma_channel_status_flags type to decode the return variables. */ uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel); @@ -741,7 +752,7 @@ uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel); * * @param base eDMA peripheral base address. * @param channel eDMA channel number. - * @param mask The mask of channel status to be cleared. User need to use + * @param mask The mask of channel status to be cleared. Users need to use * the defined _edma_channel_status_flags type. */ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask); @@ -754,8 +765,8 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas /*! * @brief Creates the eDMA handle. * - * This function is called if using transaction API for eDMA. This function - * initializes the internal state of eDMA handle. + * This function is called if using the transactional API for eDMA. This function + * initializes the internal state of the eDMA handle. * * @param handle eDMA handle pointer. The eDMA handle stores callback function and * parameters. @@ -765,12 +776,12 @@ void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mas void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel); /*! - * @brief Installs the TCDs memory pool into eDMA handle. + * @brief Installs the TCDs memory pool into the eDMA handle. * * This function is called after the EDMA_CreateHandle to use scatter/gather feature. * * @param handle eDMA handle pointer. - * @param tcdPool Memory pool to store TCDs. It must be 32 bytes aligned. + * @param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. * @param tcdSize The number of TCD slots. */ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize); @@ -778,12 +789,12 @@ void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t /*! * @brief Installs a callback function for the eDMA transfer. * - * This callback is called in eDMA IRQ handler. Use the callback to do something after + * This callback is called in the eDMA IRQ handler. Use the callback to do something after * the current major loop transfer completes. * * @param handle eDMA handle pointer. * @param callback eDMA callback function pointer. - * @param userData Parameter for callback function. + * @param userData A parameter for the callback function. */ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData); @@ -801,8 +812,8 @@ void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userD * @param transferBytes eDMA transfer bytes to be transferred. * @param type eDMA transfer type. * @note The data address and the data width must be consistent. For example, if the SRC - * is 4 bytes, so the source address must be 4 bytes aligned, or it shall result in - * source address error(SAE). + * is 4 bytes, the source address must be 4 bytes aligned, or it results in + * source address error (SAE). */ void EDMA_PrepareTransfer(edma_transfer_config_t *config, void *srcAddr, @@ -817,7 +828,7 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, * @brief Submits the eDMA transfer request. * * This function submits the eDMA transfer request according to the transfer configuration structure. - * If the user submits the transfer request repeatedly, this function packs an unprocessed request as + * If submitting the transfer request repeatedly, this function packs an unprocessed request as * a TCD and enables scatter/gather feature to process it in the next time. * * @param handle eDMA handle pointer. @@ -829,9 +840,9 @@ void EDMA_PrepareTransfer(edma_transfer_config_t *config, status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config); /*! - * @brief eDMA start transfer. + * @brief eDMA starts transfer. * - * This function enables the channel request. User can call this function after submitting the transfer request + * This function enables the channel request. Users can call this function after submitting the transfer request * or before submitting the transfer request. * * @param handle eDMA handle pointer. @@ -839,9 +850,9 @@ status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t void EDMA_StartTransfer(edma_handle_t *handle); /*! - * @brief eDMA stop transfer. + * @brief eDMA stops transfer. * - * This function disables the channel request to pause the transfer. User can call EDMA_StartTransfer() + * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() * again to resume the transfer. * * @param handle eDMA handle pointer. @@ -849,21 +860,41 @@ void EDMA_StartTransfer(edma_handle_t *handle); void EDMA_StopTransfer(edma_handle_t *handle); /*! - * @brief eDMA abort transfer. + * @brief eDMA aborts transfer. * * This function disables the channel request and clear transfer status bits. - * User can submit another transfer after calling this API. + * Users can submit another transfer after calling this API. * * @param handle DMA handle pointer. */ void EDMA_AbortTransfer(edma_handle_t *handle); /*! - * @brief eDMA IRQ handler for current major loop transfer complete. + * @brief eDMA IRQ handler for the current major loop transfer completion. * - * This function clears the channel major interrupt flag and call + * This function clears the channel major interrupt flag and calls * the callback function if it is not NULL. * + * Note: + * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. + * These include the final address adjustments and reloading of the BITER field into the CITER. + * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from + * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). + * + * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. + * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index + * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be + * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have + * been loaded into the eDMA engine at this point already.). + * + * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not + * load a new TCD) from the memory pool to the eDMA engine when major loop completes. + * Therefore, ensure that the header and tcdUsed updated are identical for them. + * tcdUsed are both 0 in this case as no TCD to be loaded. + * + * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for + * further details. + * * @param handle eDMA handle pointer. */ void EDMA_HandleIRQ(edma_handle_t *handle); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_enet.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_enet.c index fe6077fba8..674f525025 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_enet.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_enet.c @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* 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. -*/ + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "fsl_enet.h" @@ -90,10 +90,8 @@ #define ENET_IPV6VERSION 0x0006U /*! @brief Ethernet mac address length. */ #define ENET_FRAME_MACLEN 6U -/*! @brief Ethernet Frame header length. */ -#define ENET_FRAME_HEADERLEN 14U /*! @brief Ethernet VLAN header length. */ -#define ENET_FRAME_VLAN_HEADERLEN 18U +#define ENET_FRAME_VLAN_TAGLEN 4U /*! @brief MDC frequency. */ #define ENET_MDC_FREQUENCY 2500000U /*! @brief NanoSecond in one second. */ @@ -238,8 +236,10 @@ static status_t ENET_StoreRxFrameTime(ENET_Type *base, enet_handle_t *handle, en /*! @brief Pointers to enet handles for each instance. */ static enet_handle_t *s_ENETHandle[FSL_FEATURE_SOC_ENET_COUNT] = {NULL}; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to enet clocks for each instance. */ const clock_ip_name_t s_enetClock[] = ENET_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Pointers to enet transmit IRQ number for each instance. */ static const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS; @@ -259,6 +259,7 @@ static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS; static enet_isr_t s_enetTxIsr; static enet_isr_t s_enetRxIsr; static enet_isr_t s_enetErrIsr; +static enet_isr_t s_enetTsIsr; /******************************************************************************* * Code ******************************************************************************/ @@ -268,7 +269,7 @@ uint32_t ENET_GetInstance(ENET_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_ENET_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_enetBases); instance++) { if (s_enetBases[instance] == base) { @@ -276,7 +277,7 @@ uint32_t ENET_GetInstance(ENET_Type *base) } } - assert(instance < FSL_FEATURE_SOC_ENET_COUNT); + assert(instance < ARRAY_SIZE(s_enetBases)); return instance; } @@ -314,10 +315,11 @@ void ENET_Init(ENET_Type *base, assert(bufferConfig->rxBufferAlign); assert(macAddr); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) uint32_t instance = ENET_GetInstance(base); - /* Ungate ENET clock. */ CLOCK_EnableClock(s_enetClock[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Reset ENET module. */ ENET_Reset(base); @@ -346,8 +348,10 @@ void ENET_Deinit(ENET_Type *base) /* Disable ENET. */ base->ECR &= ~ENET_ECR_ETHEREN_MASK; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disables the clock source. */ CLOCK_DisableClock(s_enetClock[ENET_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *userData) @@ -407,7 +411,13 @@ static void ENET_SetMacController(ENET_Type *base, uint32_t tcr = 0; uint32_t ecr = 0; uint32_t macSpecialConfig = config->macSpecialConfig; - uint32_t instance = ENET_GetInstance(base); + uint32_t maxFrameLen = config->rxMaxFrameLen; + + /* Maximum frame length check. */ + if ((macSpecialConfig & kENET_ControlVLANTagEnable) && (maxFrameLen <= ENET_FRAME_MAX_FRAMELEN)) + { + maxFrameLen = (ENET_FRAME_MAX_FRAMELEN + ENET_FRAME_VLAN_TAGLEN); + } /* Configures MAC receive controller with user configure structure. */ rcr = ENET_RCR_NLC(!!(macSpecialConfig & kENET_ControlRxPayloadCheckEnable)) | @@ -417,16 +427,16 @@ static void ENET_SetMacController(ENET_Type *base, ENET_RCR_BC_REJ(!!(macSpecialConfig & kENET_ControlRxBroadCastRejectEnable)) | ENET_RCR_PROM(!!(macSpecialConfig & kENET_ControlPromiscuousEnable)) | ENET_RCR_MII_MODE(1) | ENET_RCR_RMII_MODE(config->miiMode) | ENET_RCR_RMII_10T(!config->miiSpeed) | - ENET_RCR_MAX_FL(config->rxMaxFrameLen) | ENET_RCR_CRCFWD(1); + ENET_RCR_MAX_FL(maxFrameLen) | ENET_RCR_CRCFWD(1); /* Receive setting for half duplex. */ if (config->miiDuplex == kENET_MiiHalfDuplex) { - rcr |= ENET_RCR_DRT(1); + rcr |= ENET_RCR_DRT_MASK; } /* Sets internal loop only for MII mode. */ if ((config->macSpecialConfig & kENET_ControlMIILoopEnable) && (config->miiMode == kENET_MiiMode)) { - rcr |= ENET_RCR_LOOP(1); + rcr |= ENET_RCR_LOOP_MASK; rcr &= ~ENET_RCR_DRT_MASK; } base->RCR = rcr; @@ -446,7 +456,7 @@ static void ENET_SetMacController(ENET_Type *base, uint32_t reemReg; base->OPD = config->pauseDuration; reemReg = ENET_RSEM_RX_SECTION_EMPTY(config->rxFifoEmptyThreshold); -#if FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD +#if defined (FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD) && FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD reemReg |= ENET_RSEM_STAT_SECTION_EMPTY(config->rxFifoStatEmptyThreshold); #endif /* FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD */ base->RSEM = reemReg; @@ -492,7 +502,22 @@ static void ENET_SetMacController(ENET_Type *base, ENET_SetSMI(base, srcClock_Hz, !!(config->macSpecialConfig & kENET_ControlSMIPreambleDisable)); } - /* Enables Ethernet interrupt and NVIC. */ +/* Enables Ethernet interrupt and NVIC. */ +#if defined(FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE) && FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE + if (config->intCoalesceCfg) + { + uint32_t intMask = (ENET_EIMR_TXB_MASK | ENET_EIMR_RXB_MASK); + + /* Clear all buffer interrupts. */ + base->EIMR &= ~intMask; + + /* Set the interrupt coalescence. */ + base->TXIC = ENET_TXIC_ICFT(config->intCoalesceCfg->txCoalesceFrameCount[0]) | + config->intCoalesceCfg->txCoalesceTimeCount[0] | ENET_TXIC_ICCS_MASK | ENET_TXIC_ICEN_MASK; + base->RXIC = ENET_RXIC_ICFT(config->intCoalesceCfg->rxCoalesceFrameCount[0]) | + config->intCoalesceCfg->rxCoalesceTimeCount[0] | ENET_RXIC_ICCS_MASK | ENET_RXIC_ICEN_MASK; + } +#endif /* FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE */ ENET_EnableInterrupts(base, config->interrupt); /* ENET control register setting. */ @@ -545,7 +570,6 @@ static void ENET_SetTxBufferDescriptors(volatile enet_tx_bd_struct_t *txBdStartA /* Increase the index. */ curBuffDescrip++; } - } static void ENET_SetRxBufferDescriptors(volatile enet_rx_bd_struct_t *rxBdStartAlign, @@ -688,6 +712,46 @@ void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_ base->MMFR = mmfr; } +#if defined(FSL_FEATURE_ENET_HAS_EXTEND_MDIO) && FSL_FEATURE_ENET_HAS_EXTEND_MDIO +void ENET_StartExtC45SMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data) +{ + uint32_t mmfr = 0; + + /* Parse the address from the input register. */ + uint16_t devAddr = (phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU; + uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU); + + /* Address write firstly. */ + mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | + ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr); + base->MMFR = mmfr; + + /* Build MII write command. */ + mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiWriteFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | + ENET_MMFR_TA(2) | ENET_MMFR_DATA(data); + base->MMFR = mmfr; +} + +void ENET_StartExtC45SMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg) +{ + uint32_t mmfr = 0; + + /* Parse the address from the input register. */ + uint16_t devAddr = (phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU; + uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU); + + /* Address write firstly. */ + mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | + ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr); + base->MMFR = mmfr; + + /* Build MII read command. */ + mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiReadFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | + ENET_MMFR_TA(2); + base->MMFR = mmfr; +} +#endif /* FSL_FEATURE_ENET_HAS_EXTEND_MDIO */ + void ENET_GetRxErrBeforeReadFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic) { assert(handle); @@ -769,13 +833,15 @@ status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length) assert(handle->rxBdCurrent); assert(length); + /* Reset the length to zero. */ + *length = 0; + uint16_t validLastMask = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent; /* Check the current buffer descriptor's empty flag. if empty means there is no frame received. */ if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK) { - *length = 0; return kStatus_ENET_RxFrameEmpty; } @@ -791,7 +857,6 @@ status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length) #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ ) { - *length = 0; return kStatus_ENET_RxFrameError; } /* FCS is removed by MAC. */ @@ -821,8 +886,9 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u uint32_t len = 0; uint32_t offset = 0; + uint16_t control; bool isLastBuff = false; - volatile enet_rx_bd_struct_t *curBuffDescrip; + volatile enet_rx_bd_struct_t *curBuffDescrip = handle->rxBdCurrent; status_t result = kStatus_Success; /* For data-NULL input, only update the buffer descriptor. */ @@ -830,37 +896,24 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u { do { - /* Get the current buffer descriptor. */ - curBuffDescrip = handle->rxBdCurrent; - /* Increase current buffer descriptor to the next one. */ - if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK) - { - handle->rxBdCurrent = handle->rxBdBase; - } - else - { - handle->rxBdCurrent++; - } + /* Update the control flag. */ + control = handle->rxBdCurrent->control; + /* Updates the receive buffer descriptors. */ + ENET_UpdateReadBuffers(base, handle); - /* The last buffer descriptor of a frame. */ - if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK) + /* Find the last buffer descriptor for the frame. */ + if (control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK) { - /* Find the last buffer descriptor for the frame*/ break; } - } while (handle->rxBdCurrent != handle->rxBdDirty); - /* Update all receive buffer descriptors for the whole frame. */ - ENET_UpdateReadBuffers(base, handle); + } while (handle->rxBdCurrent != curBuffDescrip); return result; } else { - /* Frame read from the MAC to user buffer and update the buffer descriptors. - Process the frame, a frame on several receive buffers are considered . */ - /* Get the current buffer descriptor. */ - curBuffDescrip = handle->rxBdCurrent; +/* A frame on one buffer or several receive buffers are both considered. */ #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE enet_ptp_time_data_t ptpTimestamp; bool isPtpEventMessage = false; @@ -871,16 +924,6 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u while (!isLastBuff) { - /* Increase current buffer descriptor to the next one. */ - if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK) - { - handle->rxBdCurrent = handle->rxBdBase; - } - else - { - handle->rxBdCurrent++; - } - /* The last buffer descriptor of a frame. */ if (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK) { @@ -900,28 +943,39 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u result = ENET_StoreRxFrameTime(base, handle, &ptpTimestamp); } #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ + + /* Updates the receive buffer descriptors. */ ENET_UpdateReadBuffers(base, handle); return result; } + else + { + /* Updates the receive buffer descriptors. */ + ENET_UpdateReadBuffers(base, handle); + } } else { - /* Store the fragments of a frame on several buffer descriptors. */ + /* Store a frame on several buffer descriptors. */ isLastBuff = false; - memcpy(data + offset, curBuffDescrip->buffer, handle->rxBuffSizeAlign); - offset += handle->rxBuffSizeAlign; + /* Length check. */ if (offset >= length) { break; } + + memcpy(data + offset, curBuffDescrip->buffer, handle->rxBuffSizeAlign); + offset += handle->rxBuffSizeAlign; + + /* Updates the receive buffer descriptors. */ + ENET_UpdateReadBuffers(base, handle); } /* Get the current buffer descriptor. */ curBuffDescrip = handle->rxBdCurrent; } - /* All error happens will break the while loop and arrive here to update receive buffers. */ - ENET_UpdateReadBuffers(base, handle); } + return kStatus_ENET_RxFrameFail; } @@ -929,26 +983,23 @@ static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle) { assert(handle); - do + /* Clears status. */ + handle->rxBdCurrent->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; + /* Sets the receive buffer descriptor with the empty flag. */ + handle->rxBdCurrent->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; + + /* Increase current buffer descriptor to the next one. */ + if (handle->rxBdCurrent->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK) { - /* Clears status. */ - handle->rxBdDirty->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; - /* Sets the receive buffer descriptor with the empty flag. */ - handle->rxBdDirty->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; - /* Increases the buffer descriptor to the next one. */ - if (handle->rxBdDirty->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK) - { - handle->rxBdDirty = handle->rxBdBase; - } - else - { - handle->rxBdDirty++; - } + handle->rxBdCurrent = handle->rxBdBase; + } + else + { + handle->rxBdCurrent++; + } - /* Actives the receive buffer descriptor. */ - base->RDAR = ENET_RDAR_RDAR_MASK; - - } while (handle->rxBdDirty != handle->rxBdCurrent); + /* Actives the receive buffer descriptor. */ + base->RDAR = ENET_RDAR_RDAR_MASK; } status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length) @@ -956,7 +1007,7 @@ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u assert(handle); assert(handle->txBdCurrent); assert(data); - assert(length <= (ENET_FRAME_MAX_VALNFRAMELEN - 4)); + assert(length <= ENET_FRAME_MAX_FRAMELEN); volatile enet_tx_bd_struct_t *curBuffDescrip = handle->txBdCurrent; uint32_t len = 0; @@ -985,6 +1036,11 @@ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u { curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; } + else + { + curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; + } + #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK); @@ -1013,6 +1069,10 @@ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u { curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; } + else + { + curBuffDescrip->controlExtend1 &= ~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; + } #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ /* Increase the buffer descriptor address. */ @@ -1034,6 +1094,7 @@ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u curBuffDescrip->length = handle->txBuffSizeAlign; len += handle->txBuffSizeAlign; /* Sets the control flag. */ + curBuffDescrip->control &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK; curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK; /* Active the transmit buffer descriptor*/ base->TDAR = ENET_TDAR_TDAR_MASK; @@ -1054,7 +1115,7 @@ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u } while (!(curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)); - return kStatus_ENET_TxFrameFail; + return kStatus_ENET_TxFrameBusy; } } @@ -1216,7 +1277,7 @@ static bool ENET_Ptp1588ParseFrame(uint8_t *data, enet_ptp_time_data_t *ptpTsDat /* Check for VLAN frame. */ if (*(uint16_t *)(buffer + ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET) == ENET_HTONS(ENET_8021QVLAN)) { - buffer += (ENET_FRAME_VLAN_HEADERLEN - ENET_FRAME_HEADERLEN); + buffer += ENET_FRAME_VLAN_TAGLEN; } ptpType = *(uint16_t *)(buffer + ENET_PTP1588_ETHL2_PACKETTYPE_OFFSET); @@ -1299,7 +1360,8 @@ void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_conf /* Enables the time stamp interrupt for the master clock on a device. */ ENET_EnableInterrupts(base, kENET_TsTimerInterrupt); - /* Enables the transmit interrupt to store the transmit frame time-stamp. */ + /* Enables only frame interrupt for transmit side to store the transmit + frame time-stamp when the whole frame is transmitted out. */ ENET_EnableInterrupts(base, kENET_TxFrameInterrupt); ENET_DisableInterrupts(base, kENET_TxBufferInterrupt); @@ -1318,6 +1380,7 @@ void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_conf /* Set the IRQ handler when the interrupt is enabled. */ s_enetTxIsr = ENET_TransmitIRQHandler; + s_enetTsIsr = ENET_Ptp1588TimerIRQHandler; EnableIRQ(s_enetTsIrqId[instance]); EnableIRQ(s_enetTxIrqId[instance]); } @@ -1624,8 +1687,8 @@ void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle) #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE if (base->EIR & kENET_TxFrameInterrupt) { - /* Store the transmit timestamp from the buffer descriptor should be done here. */ - ENET_StoreTxFrameTime(base, handle); + /* Store the transmit timestamp from the buffer descriptor should be done here. */ + ENET_StoreTxFrameTime(base, handle); } #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ @@ -1665,7 +1728,7 @@ void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle) uint32_t errMask = kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | kENET_PayloadRxInterrupt | kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt; - /* Check if the PTP time stamp interrupt happen. */ + /* Check if the error interrupt happen. */ if (kENET_WakeupInterrupt & base->EIR) { /* Clear the wakeup interrupt. */ @@ -1680,7 +1743,7 @@ void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle) } else { - /* Clear the time stamp interrupt. */ + /* Clear the error interrupt event status. */ errMask &= base->EIR; base->EIR = errMask; /* Callback function. */ @@ -1721,13 +1784,34 @@ void ENET_Ptp1588TimerIRQHandler(ENET_Type *base, enet_handle_t *handle) } } } - -void ENET_1588_Timer_IRQHandler(void) -{ - ENET_Ptp1588TimerIRQHandler(ENET, s_ENETHandle[0]); -} #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ +void ENET_CommonFrame0IRQHandler(ENET_Type *base) +{ + uint32_t event = base->EIR; + uint32_t instance = ENET_GetInstance(base); + + if (event & ENET_TX_INTERRUPT) + { + s_enetTxIsr(base, s_ENETHandle[instance]); + } + + if (event & ENET_RX_INTERRUPT) + { + s_enetRxIsr(base, s_ENETHandle[instance]); + } + + if (event & ENET_TS_INTERRUPT) + { + s_enetTsIsr(base, s_ENETHandle[instance]); + } + if (event & ENET_ERR_INTERRUPT) + { + s_enetErrIsr(base, s_ENETHandle[instance]); + } +} + +#if defined(ENET) void ENET_Transmit_IRQHandler(void) { s_enetTxIsr(ENET, s_ENETHandle[0]); @@ -1742,3 +1826,10 @@ void ENET_Error_IRQHandler(void) { s_enetErrIsr(ENET, s_ENETHandle[0]); } + +void ENET_1588_Timer_IRQHandler(void) +{ + s_enetTsIsr(ENET, s_ENETHandle[0]); +} +#endif + diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_enet.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_enet.h index f35da473cd..211a01138b 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_enet.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_enet.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,7 +37,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -46,7 +45,7 @@ /*! @name Driver version */ /*@{*/ /*! @brief Defines the driver version. */ -#define FSL_ENET_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ +#define FSL_ENET_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1. */ /*@}*/ /*! @name Control and status region bit masks of the receive buffer descriptor. */ @@ -124,18 +123,18 @@ #endif #define ENET_TX_INTERRUPT (kENET_TxFrameInterrupt | kENET_TxBufferInterrupt) #define ENET_RX_INTERRUPT (kENET_RxFrameInterrupt | kENET_RxBufferInterrupt) +#define ENET_TS_INTERRUPT (kENET_TsTimerInterrupt | kENET_TsAvailInterrupt) #define ENET_ERR_INTERRUPT (kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | \ kENET_LateCollisionInterrupt | kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt | kENET_PayloadRxInterrupt) + /*! @name Defines the maximum Ethernet frame size. */ /*@{*/ -#define ENET_FRAME_MAX_FRAMELEN 1518U /*!< Maximum Ethernet frame size. */ -#define ENET_FRAME_MAX_VALNFRAMELEN 1522U /*!< Maximum VLAN frame size. */ +#define ENET_FRAME_MAX_FRAMELEN 1518U /*!< Default maximum Ethernet frame size. */ /*@}*/ #define ENET_FIFO_MIN_RX_FULL 5U /*!< ENET minimum receive FIFO full. */ #define ENET_RX_MIN_BUFFERSIZE 256U /*!< ENET minimum buffer size. */ -#define ENET_BUFF_ALIGNMENT 16U /*!< Ethernet buffer alignment. */ /*! @brief Defines the PHY address scope for the ENET. */ #define ENET_PHY_MAXADDRESS (ENET_MMFR_PA_MASK >> ENET_MMFR_PA_SHIFT) @@ -191,6 +190,15 @@ typedef enum _enet_mii_read kENET_MiiReadNoCompliant = 3U /*!< Read frame operation, but not MII-compliant. */ } enet_mii_read_t; +#if defined (FSL_FEATURE_ENET_HAS_EXTEND_MDIO) && FSL_FEATURE_ENET_HAS_EXTEND_MDIO +/*! @brief Define the MII opcode for extended MDIO_CLAUSES_45 Frame. */ +typedef enum _enet_mii_extend_opcode { + kENET_MiiAddrWrite_C45 = 0U, /*!< Address Write operation. */ + kENET_MiiWriteFrame_C45 = 1U, /*!< Write frame operation for a valid MII management frame. */ + kENET_MiiReadFrame_C45 = 3U /*!< Read frame operation for a valid MII management frame. */ +} enet_mii_extend_opcode; +#endif /* FSL_FEATURE_ENET_HAS_EXTEND_MDIO */ + /*! @brief Defines a special configuration for ENET MAC controller. * * These control flags are provided for special user requirements. @@ -237,12 +245,9 @@ typedef enum _enet_interrupt_enable kENET_RetryLimitInterrupt = ENET_EIR_RL_MASK, /*!< Collision Retry Limit interrupt source */ kENET_UnderrunInterrupt = ENET_EIR_UN_MASK, /*!< Transmit FIFO underrun interrupt source */ kENET_PayloadRxInterrupt = ENET_EIR_PLR_MASK, /*!< Payload Receive interrupt source */ - kENET_WakeupInterrupt = ENET_EIR_WAKEUP_MASK /*!< WAKEUP interrupt source */ -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - , + kENET_WakeupInterrupt = ENET_EIR_WAKEUP_MASK, /*!< WAKEUP interrupt source */ kENET_TsAvailInterrupt = ENET_EIR_TS_AVAIL_MASK, /*!< TS AVAIL interrupt source for PTP */ kENET_TsTimerInterrupt = ENET_EIR_TS_TIMER_MASK /*!< TS WRAP interrupt source for PTP */ -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ } enet_interrupt_enable_t; /*! @brief Defines the common interrupt event for callback use. */ @@ -252,10 +257,8 @@ typedef enum _enet_event kENET_TxEvent, /*!< Transmit event. */ kENET_ErrEvent, /*!< Error event: BABR/BABT/EBERR/LC/RL/UN/PLR . */ kENET_WakeUpEvent, /*!< Wake up from sleep mode event. */ -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE kENET_TimeStampEvent, /*!< Time stamp event. */ kENET_TimeStampAvailEvent /*!< Time stamp available event.*/ -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ } enet_event_t; /*! @brief Defines the transmit accelerator configuration. */ @@ -380,15 +383,20 @@ typedef struct _enet_data_error_stats #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ } enet_data_error_stats_t; -/*! @brief Defines the receive buffer descriptor configure structure. +/*! @brief Defines the receive buffer descriptor configuration structure. * - * Note: For the internal DMA requirements, the buffers have a corresponding alignment requirement: - * 1. The aligned receive and transmit buffer size must be evenly divisible by 16. + * Note that for the internal DMA requirements, the buffers have a corresponding alignment requirements. + * 1. The aligned receive and transmit buffer size must be evenly divisible by ENET_BUFF_ALIGNMENT. + * when the data buffers are in cacheable region when cache is enabled, all those size should be + * aligned to the maximum value of "ENET_BUFF_ALIGNMENT" and the cache line size. * 2. The aligned transmit and receive buffer descriptor start address must be at - * least 64 bit aligned. However, it's recommended to be evenly divisible by 16. - * 3. The aligned transmit and receive buffer start address must be evenly divisible by 16. + * least 64 bit aligned. However, it's recommended to be evenly divisible by ENET_BUFF_ALIGNMENT. + * buffer descriptors should be put in non-cacheable region when cache is enabled. + * 3. The aligned transmit and receive data buffer start address must be evenly divisible by ENET_BUFF_ALIGNMENT. * Receive buffers should be continuous with the total size equal to "rxBdNumber * rxBuffSizeAlign". * Transmit buffers should be continuous with the total size equal to "txBdNumber * txBuffSizeAlign". + * when the data buffers are in cacheable region when cache is enabled, all those size should be + * aligned to the maximum value of "ENET_BUFF_ALIGNMENT" and the cache line size. */ typedef struct _enet_buffer_config { @@ -429,7 +437,7 @@ typedef struct _enet_ptp_time_data_ring enet_ptp_time_data_t *ptpTsData; /*!< PTP message data structure. */ } enet_ptp_time_data_ring_t; -/*! @brief Defines the ENET PTP configure structure. */ +/*! @brief Defines the ENET PTP configuration structure. */ typedef struct _enet_ptp_config { uint8_t ptpTsRxBuffNum; /*!< Receive 1588 timestamp buffer number*/ @@ -441,19 +449,28 @@ typedef struct _enet_ptp_config } enet_ptp_config_t; #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - +#if defined (FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE) && FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE +/*! @brief Defines the interrupt coalescing configure structure. */ +typedef struct _enet_intcoalesce_config +{ + uint8_t txCoalesceFrameCount[FSL_FEATURE_ENET_QUEUE]; /*!< Transmit interrupt coalescing frame count threshold. */ + uint16_t txCoalesceTimeCount[FSL_FEATURE_ENET_QUEUE]; /*!< Transmit interrupt coalescing timer count threshold. */ + uint8_t rxCoalesceFrameCount[FSL_FEATURE_ENET_QUEUE]; /*!< Receive interrupt coalescing frame count threshold. */ + uint16_t rxCoalesceTimeCount[FSL_FEATURE_ENET_QUEUE]; /*!< Receive interrupt coalescing timer count threshold. */ +} enet_intcoalesce_config_t; +#endif /* FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE */ /*! @brief Defines the basic configuration structure for the ENET device. * * Note: - * 1. macSpecialConfig is used for a special control configuration, A logical OR of + * 1. macSpecialConfig is used for a special control configuration, a logical OR of * "enet_special_control_flag_t". For a special configuration for MAC, * set this parameter to 0. - * 2. txWatermark is used for a cut-through operation. It is in steps of 64 bytes: + * 2. txWatermark is used for a cut-through operation. It is in steps of 64 bytes. * 0/1 - 64 bytes written to TX FIFO before transmission of a frame begins. * 2 - 128 bytes written to TX FIFO .... * 3 - 192 bytes written to TX FIFO .... - * The maximum of txWatermark is 0x2F - 4032 bytes written to TX FIFO .... + * The maximum of txWatermark is 0x2F - 4032 bytes written to TX FIFO. * txWatermark allows minimizing the transmit latency to set the txWatermark to 0 or 1 * or for larger bus access latency 3 or larger due to contention for the system bus. * 3. rxFifoFullThreshold is similar to the txWatermark for cut-through operation in RX. @@ -485,7 +502,7 @@ typedef struct _enet_config uint16_t pauseDuration; /*!< For flow control enabled case: Pause duration. */ uint8_t rxFifoEmptyThreshold; /*!< For flow control enabled case: when RX FIFO level reaches this value, it makes MAC generate XOFF pause frame. */ -#if FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD +#if defined (FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD) && FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD uint8_t rxFifoStatEmptyThreshold; /*!< For flow control enabled case: number of frames in the receive FIFO, independent of size, that can be accept. If the limit is reached, reception continues and a pause frame is triggered. */ @@ -494,6 +511,10 @@ typedef struct _enet_config the MAC receive ready status. */ uint8_t txFifoWatermark; /*!< For store and forward disable case, the data required in TX FIFO before a frame transmit start. */ +#if defined (FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE) && FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE + enet_intcoalesce_config_t *intCoalesceCfg; /* If the interrupt coalsecence is not required in the ring n(0,1,2), please set + to NULL. */ +#endif /* FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE */ } enet_config_t; /* Forward declaration of the handle typedef. */ @@ -507,7 +528,6 @@ struct _enet_handle { volatile enet_rx_bd_struct_t *rxBdBase; /*!< Receive buffer descriptor base address pointer. */ volatile enet_rx_bd_struct_t *rxBdCurrent; /*!< The current available receive buffer descriptor pointer. */ - volatile enet_rx_bd_struct_t *rxBdDirty; /*!< The dirty receive buffer descriptor needed to be updated from. */ volatile enet_tx_bd_struct_t *txBdBase; /*!< Transmit buffer descriptor base address pointer. */ volatile enet_tx_bd_struct_t *txBdCurrent; /*!< The current available transmit buffer descriptor pointer. */ volatile enet_tx_bd_struct_t *txBdDirty; /*!< The dirty transmit buffer descriptor needed to be updated from. */ @@ -533,7 +553,7 @@ extern "C" { #endif /*! - * @name Initialization and De-initialization + * @name Initialization and de-initialization * @{ */ @@ -541,10 +561,10 @@ extern "C" { * @brief Gets the ENET default configuration structure. * * The purpose of this API is to get the default ENET MAC controller - * configure structure for ENET_Init(). User may use the initialized - * structure unchanged in ENET_Init(), or modify some fields of the + * configuration structure for ENET_Init(). Users may use the initialized + * structure unchanged in ENET_Init() or modify fields of the * structure before calling ENET_Init(). - * Example: + * This is an example. @code enet_config_t config; ENET_GetDefaultConfig(&config); @@ -560,18 +580,18 @@ void ENET_GetDefaultConfig(enet_config_t *config); * * @param base ENET peripheral base address. * @param handle ENET handler pointer. - * @param config ENET mac configuration structure pointer. + * @param config ENET Mac configuration structure pointer. * The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig * can be used directly. It is also possible to verify the Mac configuration using other methods. * @param bufferConfig ENET buffer configuration structure pointer. * The buffer configuration should be prepared for ENET Initialization. - * @param macAddr ENET mac address of Ethernet device. This MAC address should be + * @param macAddr ENET mac address of the Ethernet device. This Mac address should be * provided. * @param srcClock_Hz The internal module clock source for MII clock. * - * @note ENET has two buffer descriptors: legacy buffer descriptors and - * enhanced 1588 buffer descriptors. The legacy descriptor is used by default. To - * use 1588 feature, use the enhanced 1588 buffer descriptor + * @note ENET has two buffer descriptors legacy buffer descriptors and + * enhanced IEEE 1588 buffer descriptors. The legacy descriptor is used by default. To + * use the IEEE 1588 feature, use the enhanced IEEE 1588 buffer descriptor * by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure() * to configure the 1588 feature and related buffers after calling ENET_Init(). */ @@ -593,8 +613,8 @@ void ENET_Deinit(ENET_Type *base); /*! * @brief Resets the ENET module. * - * This function restores the ENET module to reset state. - * Note that this function sets all registers to + * This function restores the ENET module to the reset state. + * Note that this function sets all registers to the * reset state. As a result, the ENET module can't work after calling this function. * * @param base ENET peripheral base address. @@ -621,7 +641,7 @@ static inline void ENET_Reset(ENET_Type *base) void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex); /*! - * @brief Sets the ENET SMI(serial management interface)- MII management interface. + * @brief Sets the ENET SMI (serial management interface) - MII management interface. * * @param base ENET peripheral base address. * @param srcClock_Hz This is the ENET module clock frequency. Normally it's the system clock. See clock distribution. @@ -634,7 +654,7 @@ void ENET_SetSMI(ENET_Type *base, uint32_t srcClock_Hz, bool isPreambleDisabled) /*! * @brief Gets the ENET SMI- MII management interface configuration. * - * This API is used to get the SMI configuration to check if the MII management + * This API is used to get the SMI configuration to check whether the MII management * interface has been set. * * @param base ENET peripheral base address. @@ -646,7 +666,7 @@ static inline bool ENET_GetSMI(ENET_Type *base) } /*! - * @brief Reads data from the PHY register through SMI interface. + * @brief Reads data from the PHY register through an SMI interface. * * @param base ENET peripheral base address. * @return The data read from PHY @@ -667,7 +687,7 @@ static inline uint32_t ENET_ReadSMIData(ENET_Type *base) void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_read_t operation); /*! - * @brief Starts a SMI write command. + * @brief Starts an SMI write command. * * @param base ENET peripheral base address. * @param phyAddr The PHY address. @@ -677,6 +697,31 @@ void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_ */ void ENET_StartSMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_write_t operation, uint32_t data); +#if defined (FSL_FEATURE_ENET_HAS_EXTEND_MDIO) && FSL_FEATURE_ENET_HAS_EXTEND_MDIO +/*! + * @brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI read command. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param phyReg The PHY register. For MDIO IEEE802.3 Clause 45, + * the phyReg is a 21-bits combination of the devaddr (5 bits device address) + * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr. + */ +void ENET_StartExtC45SMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg); + +/*! + * @brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI write command. + * + * @param base ENET peripheral base address. + * @param phyAddr The PHY address. + * @param phyReg The PHY register. For MDIO IEEE802.3 Clause 45, + * the phyReg is a 21-bits combination of the devaddr (5 bits device address) + * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr. + * @param data The data written to PHY. + */ +void ENET_StartExtC45SMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data); +#endif /* FSL_FEATURE_ENET_HAS_EXTEND_MDIO */ + /* @} */ /*! @@ -721,7 +766,7 @@ void ENET_LeaveMulticastGroup(ENET_Type *base, uint8_t *address); /* @} */ /*! - * @name Other basic operation + * @name Other basic operations * @{ */ @@ -762,13 +807,13 @@ static inline void ENET_EnableSleepMode(ENET_Type *base, bool enable) } /*! - * @brief Gets ENET transmit and receive accelerator functions from MAC controller. + * @brief Gets ENET transmit and receive accelerator functions from the MAC controller. * * @param base ENET peripheral base address. * @param txAccelOption The transmit accelerator option. The "enet_tx_accelerator_t" is - * recommended to be used to as the mask to get the exact the accelerator option. + * recommended as the mask to get the exact the accelerator option. * @param rxAccelOption The receive accelerator option. The "enet_rx_accelerator_t" is - * recommended to be used to as the mask to get the exact the accelerator option. + * recommended as the mask to get the exact the accelerator option. */ static inline void ENET_GetAccelFunction(ENET_Type *base, uint32_t *txAccelOption, uint32_t *rxAccelOption) { @@ -782,7 +827,7 @@ static inline void ENET_GetAccelFunction(ENET_Type *base, uint32_t *txAccelOptio /* @} */ /*! - * @name Interrupts. + * @name Interrupts * @{ */ @@ -791,7 +836,7 @@ static inline void ENET_GetAccelFunction(ENET_Type *base, uint32_t *txAccelOptio * * This function enables the ENET interrupt according to the provided mask. The mask * is a logical OR of enumeration members. See @ref enet_interrupt_enable_t. - * For example, to enable the TX frame interrupt and RX frame interrupt, do this: + * For example, to enable the TX frame interrupt and RX frame interrupt, do the following. * @code * ENET_EnableInterrupts(ENET, kENET_TxFrameInterrupt | kENET_RxFrameInterrupt); * @endcode @@ -810,7 +855,7 @@ static inline void ENET_EnableInterrupts(ENET_Type *base, uint32_t mask) * * This function disables the ENET interrupts according to the provided mask. The mask * is a logical OR of enumeration members. See @ref enet_interrupt_enable_t. - * For example, to disable the TX frame interrupt and RX frame interrupt, do this: + * For example, to disable the TX frame interrupt and RX frame interrupt, do the following. * @code * ENET_DisableInterrupts(ENET, kENET_TxFrameInterrupt | kENET_RxFrameInterrupt); * @endcode @@ -841,7 +886,7 @@ static inline uint32_t ENET_GetInterruptStatus(ENET_Type *base) * * This function clears enabled ENET interrupts according to the provided mask. The mask * is a logical OR of enumeration members. See the @ref enet_interrupt_enable_t. - * For example, to clear the TX frame interrupt and RX frame interrupt, do this: + * For example, to clear the TX frame interrupt and RX frame interrupt, do the following. * @code * ENET_ClearInterruptStatus(ENET, kENET_TxFrameInterrupt | kENET_RxFrameInterrupt); * @endcode @@ -863,8 +908,8 @@ static inline void ENET_ClearInterruptStatus(ENET_Type *base, uint32_t mask) */ /*! - * @brief Set the callback function. - * This API is provided for application callback required case when ENET + * @brief Sets the callback function. + * This API is provided for the application callback required case when ENET * interrupt is enabled. This API should be called after calling ENET_Init. * * @param handle ENET handler pointer. Should be provided by application. @@ -879,7 +924,7 @@ void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *use * This API must be called after the ENET_GetRxFrameSize and before the ENET_ReadFrame(). * If the ENET_GetRxFrameSize returns kStatus_ENET_RxFrameError, * the ENET_GetRxErrBeforeReadFrame can be used to get the exact error statistics. - * For example: + * This is an example. * @code * status = ENET_GetRxFrameSize(&g_handle, &length); * if (status == kStatus_ENET_RxFrameError) @@ -911,29 +956,54 @@ void ENET_GetRxErrBeforeReadFrame(enet_handle_t *handle, enet_data_error_stats_t */ status_t ENET_GetTxErrAfterSendFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic); #endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - /*! - * @brief Gets the size of the read frame. - * This function reads a received frame size from the ENET buffer descriptors. - * @note The FCS of the frame is removed by MAC controller and the size is the length without the FCS. - * After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to update the - * receive buffers If the result is not "kStatus_ENET_RxFrameEmpty". - * - * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. - * @param length The length of the valid frame received. - * @retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame. - * @retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data - * and NULL length to update the receive buffers. - * @retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame - * should be called with the right data buffer and the captured data length input. - */ +/*! +* @brief Gets the size of the read frame. +* This function gets a received frame size from the ENET buffer descriptors. +* @note The FCS of the frame is automatically removed by Mac and the size is the length without the FCS. +* After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to update the +* receive buffers If the result is not "kStatus_ENET_RxFrameEmpty". +* +* @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. +* @param length The length of the valid frame received. +* @retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame. +* @retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data +* and NULL length to update the receive buffers. +* @retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame +* should be called with the right data buffer and the captured data length input. +*/ status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length); /*! * @brief Reads a frame from the ENET device. * This function reads a frame (both the data and the length) from the ENET buffer descriptors. * The ENET_GetRxFrameSize should be used to get the size of the prepared data buffer. - * @note The FCS of the frame is removed by MAC controller and is not delivered to the application. - * + * This is an example. + * @code + * uint32_t length; + * enet_handle_t g_handle; + * //Get the received frame size firstly. + * status = ENET_GetRxFrameSize(&g_handle, &length); + * if (length != 0) + * { + * //Allocate memory here with the size of "length" + * uint8_t *data = memory allocate interface; + * if (!data) + * { + * ENET_ReadFrame(ENET, &g_handle, NULL, 0); + * //Add the console warning log. + * } + * else + * { + * status = ENET_ReadFrame(ENET, &g_handle, data, length); + * //Call stack input API to deliver the data to stack + * } + * } + * else if (status == kStatus_ENET_RxFrameError) + * { + * //Update the received buffer when a error frame is received. + * ENET_ReadFrame(ENET, &g_handle, NULL, 0); + * } + * @endcode * @param base ENET peripheral base address. * @param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. * @param data The data buffer provided by user to store the frame which memory size should be at least "length". @@ -952,8 +1022,10 @@ status_t ENET_ReadFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, u * @param data The data buffer provided by user to be send. * @param length The length of the data to be send. * @retval kStatus_Success Send frame succeed. - * @retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmit. - * @retval kStatus_ENET_TxFrameFail Transmit frame fail. + * @retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission. + * The transmit busy happens when the data send rate is over the MAC capacity. + * The waiting mechanism is recommended to be added after each call return with + * kStatus_ENET_TxFrameBusy. */ status_t ENET_SendFrame(ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length); @@ -981,6 +1053,14 @@ void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle); */ void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle); +/*! + * @brief the common IRQ handler for the tx/rx/error etc irq handler. + * + * This is used for the combined tx/rx/error interrupt for single ring (ring 0). + * + * @param base ENET peripheral base address. + */ +void ENET_CommonFrame0IRQHandler(ENET_Type *base); /* @} */ #ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE @@ -990,7 +1070,7 @@ void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle); */ /*! - * @brief Configures the ENET PTP 1588 feature with the basic configuration. + * @brief Configures the ENET PTP IEEE 1588 feature with the basic configuration. * The function sets the clock for PTP 1588 timer and enables * time stamp interrupts and transmit interrupts for PTP 1588 features. * This API should be called when the 1588 feature is enabled @@ -1044,7 +1124,7 @@ static inline void ENET_Ptp1588StopTimer(ENET_Type *base) void ENET_Ptp1588AdjustTimer(ENET_Type *base, uint32_t corrIncrease, uint32_t corrPeriod); /*! - * @brief Sets ENET PTP 1588 timer channel mode. + * @brief Sets the ENET PTP 1588 timer channel mode. * * @param base ENET peripheral base address. * @param channel The ENET PTP timer channel number. @@ -1064,8 +1144,55 @@ static inline void ENET_Ptp1588SetChannelMode(ENET_Type *base, base->CHANNEL[channel].TCSR = tcrReg; } +#if defined(FSL_FEATURE_ENET_HAS_TIMER_PWCONTROL) && FSL_FEATURE_ENET_HAS_TIMER_PWCONTROL /*! - * @brief Sets ENET PTP 1588 timer channel comparison value. + * @brief Sets ENET PTP 1588 timer channel mode pulse width. + * + * For the input "mode" in ENET_Ptp1588SetChannelMode, the kENET_PtpChannelPulseLowonCompare + * kENET_PtpChannelPulseHighonCompare only support the pulse width for one 1588 clock. + * this function is extended for control the pulse width from 1 to 32 1588 clock cycles. + * so call this function if you need to set the timer channel mode for + * kENET_PtpChannelPulseLowonCompare or kENET_PtpChannelPulseHighonCompare + * with pulse width more than one 1588 clock, + * + * @param base ENET peripheral base address. + * @param channel The ENET PTP timer channel number. + * @param isOutputLow True --- timer channel is configured for output compare + * pulse output low. + * false --- timer channel is configured for output compare + * pulse output high. + * @param pulseWidth The pulse width control value, range from 0 ~ 31. + * 0 --- pulse width is one 1588 clock cycle. + * 31 --- pulse width is thirty two 1588 clock cycles. + * @param intEnable Enables or disables the interrupt. + */ +static inline void ENET_Ptp1588SetChannelOutputPulseWidth(ENET_Type *base, + enet_ptp_timer_channel_t channel, + bool isOutputLow, + uint8_t pulseWidth, + bool intEnable) +{ + uint32_t tcrReg; + + tcrReg = ENET_TCSR_TIE(intEnable) | ENET_TCSR_TPWC(pulseWidth); + + if (isOutputLow) + { + tcrReg |= ENET_TCSR_TMODE(kENET_PtpChannelPulseLowonCompare); + } + else + { + tcrReg |= ENET_TCSR_TMODE(kENET_PtpChannelPulseHighonCompare); + } + + /* Disable channel mode first. */ + base->CHANNEL[channel].TCSR = 0; + base->CHANNEL[channel].TCSR = tcrReg; +} +#endif /* FSL_FEATURE_ENET_HAS_TIMER_PWCONTROL */ + +/*! + * @brief Sets the ENET PTP 1588 timer channel comparison value. * * @param base ENET peripheral base address. * @param channel The PTP timer channel, see "enet_ptp_timer_channel_t". diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ewm.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ewm.c index 1a71a07e58..f22eff941e 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ewm.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ewm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -40,7 +40,12 @@ void EWM_Init(EWM_Type *base, const ewm_config_t *config) uint32_t value = 0U; +#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \ + (defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE)) +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_EnableClock(kCLOCK_Ewm0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +#endif value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) | EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt); #if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER @@ -59,7 +64,12 @@ void EWM_Init(EWM_Type *base, const ewm_config_t *config) void EWM_Deinit(EWM_Type *base) { EWM_DisableInterrupts(base, kEWM_InterruptEnable); +#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \ + (defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE)) +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_DisableClock(kCLOCK_Ewm0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +#endif /* FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE */ } void EWM_GetDefaultConfig(ewm_config_t *config) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ewm.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ewm.h index a5c45b3fe7..aa32ed3c71 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ewm.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ewm.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -33,11 +33,10 @@ #include "fsl_common.h" /*! - * @addtogroup ewm_driver + * @addtogroup ewm * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -49,14 +48,14 @@ #define FSL_EWM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*@}*/ -/*! @brief Describes ewm clock source. */ +/*! @brief Describes EWM clock source. */ #if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT typedef enum _ewm_lpo_clock_source { - kEWM_LpoClockSource0 = 0U, /*!< ewm clock sourced from lpo_clk[0]*/ - kEWM_LpoClockSource1 = 1U, /*!< ewm clock sourced from lpo_clk[1]*/ - kEWM_LpoClockSource2 = 2U, /*!< ewm clock sourced from lpo_clk[2]*/ - kEWM_LpoClockSource3 = 3U, /*!< ewm clock sourced from lpo_clk[3]*/ + kEWM_LpoClockSource0 = 0U, /*!< EWM clock sourced from lpo_clk[0]*/ + kEWM_LpoClockSource1 = 1U, /*!< EWM clock sourced from lpo_clk[1]*/ + kEWM_LpoClockSource2 = 2U, /*!< EWM clock sourced from lpo_clk[2]*/ + kEWM_LpoClockSource3 = 3U, /*!< EWM clock sourced from lpo_clk[3]*/ } ewm_lpo_clock_source_t; #endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT */ @@ -77,18 +76,18 @@ typedef struct _ewm_config #if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER uint8_t prescaler; /*!< Clock prescaler value */ #endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ - uint8_t compareLowValue; /*!< Compare low register value */ - uint8_t compareHighValue; /*!< Compare high register value */ + uint8_t compareLowValue; /*!< Compare low-register value */ + uint8_t compareHighValue; /*!< Compare high-register value */ } ewm_config_t; /*! - * @brief EWM interrupt configuration structure, default settings all disabled. + * @brief EWM interrupt configuration structure with default settings all disabled. * - * This structure contains the settings for all of the EWM interrupt configurations. + * This structure contains the settings for all of EWM interrupt configurations. */ enum _ewm_interrupt_enable_t { - kEWM_InterruptEnable = EWM_CTRL_INTEN_MASK, /*!< Enable EWM to generate an interrupt*/ + kEWM_InterruptEnable = EWM_CTRL_INTEN_MASK, /*!< Enable the EWM to generate an interrupt*/ }; /*! @@ -98,7 +97,7 @@ enum _ewm_interrupt_enable_t */ enum _ewm_status_flags_t { - kEWM_RunningFlag = EWM_CTRL_EWMEN_MASK, /*!< Running flag, set when ewm is enabled*/ + kEWM_RunningFlag = EWM_CTRL_EWMEN_MASK, /*!< Running flag, set when EWM is enabled*/ }; /******************************************************************************* @@ -110,7 +109,7 @@ extern "C" { #endif /* __cplusplus */ /*! - * @name EWM Initialization and De-initialization + * @name EWM initialization and de-initialization * @{ */ @@ -119,10 +118,10 @@ extern "C" { * * This function is used to initialize the EWM. After calling, the EWM * runs immediately according to the configuration. - * Note that except for interrupt enable control bit, other control bits and registers are write once after a + * Note that, except for the interrupt enable control bit, other control bits and registers are write once after a * CPU reset. Modifying them more than once generates a bus transfer error. * - * Example: + * This is an example. * @code * ewm_config_t config; * EWM_GetDefaultConfig(&config); @@ -131,7 +130,7 @@ extern "C" { * @endcode * * @param base EWM peripheral base address - * @param config The configuration of EWM + * @param config The configuration of the EWM */ void EWM_Init(EWM_Type *base, const ewm_config_t *config); @@ -147,8 +146,8 @@ void EWM_Deinit(EWM_Type *base); /*! * @brief Initializes the EWM configuration structure. * - * This function initializes the EWM configure structure to default values. The default - * values are: + * This function initializes the EWM configuration structure to default values. The default + * values are as follows. * @code * ewmConfig->enableEwm = true; * ewmConfig->enableEwmInput = false; @@ -160,7 +159,7 @@ void EWM_Deinit(EWM_Type *base); * ewmConfig->compareHighValue = 0xFEU; * @endcode * - * @param config Pointer to EWM configuration structure. + * @param config Pointer to the EWM configuration structure. * @see ewm_config_t */ void EWM_GetDefaultConfig(ewm_config_t *config); @@ -179,7 +178,7 @@ void EWM_GetDefaultConfig(ewm_config_t *config); * * @param base EWM peripheral base address * @param mask The interrupts to enable - * The parameter can be combination of the following source if defined: + * The parameter can be combination of the following source if defined * @arg kEWM_InterruptEnable */ static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask) @@ -194,7 +193,7 @@ static inline void EWM_EnableInterrupts(EWM_Type *base, uint32_t mask) * * @param base EWM peripheral base address * @param mask The interrupts to disable - * The parameter can be combination of the following source if defined: + * The parameter can be combination of the following source if defined * @arg kEWM_InterruptEnable */ static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask) @@ -203,19 +202,19 @@ static inline void EWM_DisableInterrupts(EWM_Type *base, uint32_t mask) } /*! - * @brief Gets EWM all status flags. + * @brief Gets all status flags. * * This function gets all status flags. * - * Example for getting Running Flag: + * This is an example for getting the running flag. * @code * uint32_t status; * status = EWM_GetStatusFlags(ewm_base) & kEWM_RunningFlag; * @endcode * @param base EWM peripheral base address * @return State of the status flag: asserted (true) or not-asserted (false).@see _ewm_status_flags_t - * - true: related status flag has been set. - * - false: related status flag is not set. + * - True: a related status flag has been set. + * - False: a related status flag is not set. */ static inline uint32_t EWM_GetStatusFlags(EWM_Type *base) { @@ -223,9 +222,9 @@ static inline uint32_t EWM_GetStatusFlags(EWM_Type *base) } /*! - * @brief Service EWM. + * @brief Services the EWM. * - * This function reset EWM counter to zero. + * This function resets the EWM counter to zero. * * @param base EWM peripheral base address */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flash.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flash.c index 2add4e9635..f63e6c9814 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flash.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flash.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -38,6 +38,7 @@ * @name Misc utility defines * @{ */ +/*! @brief Alignment utility. */ #ifndef ALIGN_DOWN #define ALIGN_DOWN(x, a) ((x) & (uint32_t)(-((int32_t)(a)))) #endif @@ -45,18 +46,74 @@ #define ALIGN_UP(x, a) (-((int32_t)((uint32_t)(-((int32_t)(x))) & (uint32_t)(-((int32_t)(a)))))) #endif -#define BYTES_JOIN_TO_WORD_1_3(x, y) ((((uint32_t)(x)&0xFFU) << 24) | ((uint32_t)(y)&0xFFFFFFU)) -#define BYTES_JOIN_TO_WORD_2_2(x, y) ((((uint32_t)(x)&0xFFFFU) << 16) | ((uint32_t)(y)&0xFFFFU)) -#define BYTES_JOIN_TO_WORD_3_1(x, y) ((((uint32_t)(x)&0xFFFFFFU) << 8) | ((uint32_t)(y)&0xFFU)) -#define BYTES_JOIN_TO_WORD_1_1_2(x, y, z) \ - ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFU) << 16) | ((uint32_t)(z)&0xFFFFU)) -#define BYTES_JOIN_TO_WORD_1_2_1(x, y, z) \ - ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFFFU) << 8) | ((uint32_t)(z)&0xFFU)) -#define BYTES_JOIN_TO_WORD_2_1_1(x, y, z) \ - ((((uint32_t)(x)&0xFFFFU) << 16) | (((uint32_t)(y)&0xFFU) << 8) | ((uint32_t)(z)&0xFFU)) -#define BYTES_JOIN_TO_WORD_1_1_1_1(x, y, z, w) \ - ((((uint32_t)(x)&0xFFU) << 24) | (((uint32_t)(y)&0xFFU) << 16) | (((uint32_t)(z)&0xFFU) << 8) | \ - ((uint32_t)(w)&0xFFU)) +/*! @brief Join bytes to word utility. */ +#define B1P4(b) (((uint32_t)(b)&0xFFU) << 24) +#define B1P3(b) (((uint32_t)(b)&0xFFU) << 16) +#define B1P2(b) (((uint32_t)(b)&0xFFU) << 8) +#define B1P1(b) ((uint32_t)(b)&0xFFU) +#define B2P3(b) (((uint32_t)(b)&0xFFFFU) << 16) +#define B2P2(b) (((uint32_t)(b)&0xFFFFU) << 8) +#define B2P1(b) ((uint32_t)(b)&0xFFFFU) +#define B3P2(b) (((uint32_t)(b)&0xFFFFFFU) << 8) +#define B3P1(b) ((uint32_t)(b)&0xFFFFFFU) +#define BYTES_JOIN_TO_WORD_1_3(x, y) (B1P4(x) | B3P1(y)) +#define BYTES_JOIN_TO_WORD_2_2(x, y) (B2P3(x) | B2P1(y)) +#define BYTES_JOIN_TO_WORD_3_1(x, y) (B3P2(x) | B1P1(y)) +#define BYTES_JOIN_TO_WORD_1_1_2(x, y, z) (B1P4(x) | B1P3(y) | B2P1(z)) +#define BYTES_JOIN_TO_WORD_1_2_1(x, y, z) (B1P4(x) | B2P2(y) | B1P1(z)) +#define BYTES_JOIN_TO_WORD_2_1_1(x, y, z) (B2P3(x) | B1P2(y) | B1P1(z)) +#define BYTES_JOIN_TO_WORD_1_1_1_1(x, y, z, w) (B1P4(x) | B1P3(y) | B1P2(z) | B1P1(w)) +/*@}*/ + +/*! + * @name Secondary flash configuration + * @{ + */ +/*! @brief Indicates whether the secondary flash has its own protection register in flash module. */ +#if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) && defined(FTFE_FPROTS_PROTS_MASK) +#define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER (1) +#else +#define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER (0) +#endif + +/*! @brief Indicates whether the secondary flash has its own Execute-Only access register in flash module. */ +#if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) && defined(FTFE_FACSSS_SGSIZE_S_MASK) +#define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER (1) +#else +#define FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER (0) +#endif +/*@}*/ + +/*! + * @name Flash cache ands speculation control defines + * @{ + */ +#if defined(MCM_PLACR_CFCC_MASK) || defined(MCM_CPCR2_CCBC_MASK) +#define FLASH_CACHE_IS_CONTROLLED_BY_MCM (1) +#else +#define FLASH_CACHE_IS_CONTROLLED_BY_MCM (0) +#endif +#if defined(FMC_PFB0CR_CINV_WAY_MASK) || defined(FMC_PFB01CR_CINV_WAY_MASK) +#define FLASH_CACHE_IS_CONTROLLED_BY_FMC (1) +#else +#define FLASH_CACHE_IS_CONTROLLED_BY_FMC (0) +#endif +#if defined(MCM_PLACR_DFCS_MASK) +#define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (1) +#else +#define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM (0) +#endif +#if defined(MSCM_OCMDR_OCM1_MASK) || defined(MSCM_OCMDR_OCMC1_MASK) +#define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (1) +#else +#define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM (0) +#endif +#if defined(FMC_PFB0CR_S_INV_MASK) || defined(FMC_PFB0CR_S_B_INV_MASK) || defined(FMC_PFB01CR_S_INV_MASK) || \ + defined(FMC_PFB01CR_S_B_INV_MASK) +#define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (1) +#else +#define FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC (0) +#endif /*@}*/ /*! @brief Data flash IFR map Field*/ @@ -121,6 +178,7 @@ #define FTFx_ERASE_BLOCK 0x08U /*!< ERSBLK*/ #define FTFx_ERASE_SECTOR 0x09U /*!< ERSSCR*/ #define FTFx_PROGRAM_SECTION 0x0BU /*!< PGMSEC*/ +#define FTFx_GENERATE_CRC 0x0CU /*!< CRCGEN*/ #define FTFx_VERIFY_ALL_BLOCK 0x40U /*!< RD1ALL*/ #define FTFx_READ_ONCE 0x41U /*!< RDONCE or RDINDEX*/ #define FTFx_PROGRAM_ONCE 0x43U /*!< PGMONCE or PGMINDEX*/ @@ -191,20 +249,57 @@ #endif /*@}*/ +/*! + * @name Common flash register access info defines + * @{ + */ +#define FTFx_FCCOB3_REG (FTFx->FCCOB3) +#define FTFx_FCCOB5_REG (FTFx->FCCOB5) +#define FTFx_FCCOB6_REG (FTFx->FCCOB6) +#define FTFx_FCCOB7_REG (FTFx->FCCOB7) + +#if defined(FTFA_FPROTH0_PROT_MASK) || defined(FTFE_FPROTH0_PROT_MASK) || defined(FTFL_FPROTH0_PROT_MASK) +#define FTFx_FPROT_HIGH_REG (FTFx->FPROTH3) +#define FTFx_FPROTH3_REG (FTFx->FPROTH3) +#define FTFx_FPROTH2_REG (FTFx->FPROTH2) +#define FTFx_FPROTH1_REG (FTFx->FPROTH1) +#define FTFx_FPROTH0_REG (FTFx->FPROTH0) +#endif + +#if defined(FTFA_FPROTL0_PROT_MASK) || defined(FTFE_FPROTL0_PROT_MASK) || defined(FTFL_FPROTL0_PROT_MASK) +#define FTFx_FPROT_LOW_REG (FTFx->FPROTL3) +#define FTFx_FPROTL3_REG (FTFx->FPROTL3) +#define FTFx_FPROTL2_REG (FTFx->FPROTL2) +#define FTFx_FPROTL1_REG (FTFx->FPROTL1) +#define FTFx_FPROTL0_REG (FTFx->FPROTL0) +#elif defined(FTFA_FPROT0_PROT_MASK) || defined(FTFE_FPROT0_PROT_MASK) || defined(FTFL_FPROT0_PROT_MASK) +#define FTFx_FPROT_LOW_REG (FTFx->FPROT3) +#define FTFx_FPROTL3_REG (FTFx->FPROT3) +#define FTFx_FPROTL2_REG (FTFx->FPROT2) +#define FTFx_FPROTL1_REG (FTFx->FPROT1) +#define FTFx_FPROTL0_REG (FTFx->FPROT0) +#endif + +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER +#define FTFx_FPROTSH_REG (FTFx->FPROTSH) +#define FTFx_FPROTSL_REG (FTFx->FPROTSL) +#endif + +#define FTFx_XACCH3_REG (FTFx->XACCH3) +#define FTFx_XACCL3_REG (FTFx->XACCL3) + +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER +#define FTFx_XACCSH_REG (FTFx->XACCSH) +#define FTFx_XACCSL_REG (FTFx->XACCSL) +#endif +/*@}*/ + /*! * @brief Enumeration for access segment property. */ enum _flash_access_segment_property { - kFLASH_accessSegmentBase = 256UL, -}; - -/*! - * @brief Enumeration for acceleration ram property. - */ -enum _flash_acceleration_ram_property -{ - kFLASH_accelerationRamSize = 0x400U + kFLASH_AccessSegmentBase = 256UL, }; /*! @@ -212,25 +307,78 @@ enum _flash_acceleration_ram_property */ enum _flash_config_area_range { - kFLASH_configAreaStart = 0x400U, - kFLASH_configAreaEnd = 0x40FU + kFLASH_ConfigAreaStart = 0x400U, + kFLASH_ConfigAreaEnd = 0x40FU }; -/*! @brief program Flash block base address*/ -#define PFLASH_BLOCK_BASE 0x00U - -/*! @brief Total flash region count*/ -#define FSL_FEATURE_FTFx_REGION_COUNT (32U) - /*! * @name Flash register access type defines * @{ */ -#if FLASH_DRIVER_IS_FLASH_RESIDENT -#define FTFx_REG_ACCESS_TYPE volatile uint8_t * +#define FTFx_REG8_ACCESS_TYPE volatile uint8_t * #define FTFx_REG32_ACCESS_TYPE volatile uint32_t * -#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ - /*@}*/ +/*@}*/ + +/*! + * @brief MCM cache register access info defines. + */ +#if defined(MCM_PLACR_CFCC_MASK) +#define MCM_CACHE_CLEAR_MASK MCM_PLACR_CFCC_MASK +#define MCM_CACHE_CLEAR_SHIFT MCM_PLACR_CFCC_SHIFT +#if defined(MCM) +#define MCM0_CACHE_REG MCM->PLACR +#elif defined(MCM0) +#define MCM0_CACHE_REG MCM0->PLACR +#endif +#if defined(MCM1) +#define MCM1_CACHE_REG MCM1->PLACR +#endif +#elif defined(MCM_CPCR2_CCBC_MASK) +#define MCM_CACHE_CLEAR_MASK MCM_CPCR2_CCBC_MASK +#define MCM_CACHE_CLEAR_SHIFT MCM_CPCR2_CCBC_SHIFT +#if defined(MCM) +#define MCM0_CACHE_REG MCM->CPCR2 +#elif defined(MCM0) +#define MCM0_CACHE_REG MCM0->CPCR2 +#endif +#if defined(MCM1) +#define MCM1_CACHE_REG MCM1->CPCR2 +#endif +#endif + +/*! + * @brief MSCM cache register access info defines. + */ +#if defined(MSCM_OCMDR_OCM1_MASK) +#define MSCM_SPECULATION_DISABLE_MASK MSCM_OCMDR_OCM1_MASK +#define MSCM_SPECULATION_DISABLE_SHIFT MSCM_OCMDR_OCM1_SHIFT +#define MSCM_SPECULATION_DISABLE(x) MSCM_OCMDR_OCM1(x) +#elif defined(MSCM_OCMDR_OCMC1_MASK) +#define MSCM_SPECULATION_DISABLE_MASK MSCM_OCMDR_OCMC1_MASK +#define MSCM_SPECULATION_DISABLE_SHIFT MSCM_OCMDR_OCMC1_SHIFT +#define MSCM_SPECULATION_DISABLE(x) MSCM_OCMDR_OCMC1(x) +#endif + +/*! + * @brief MSCM prefetch speculation defines. + */ +#define MSCM_OCMDR_OCMC1_DFDS_MASK (0x10U) +#define MSCM_OCMDR_OCMC1_DFCS_MASK (0x20U) + +#define MSCM_OCMDR_OCMC1_DFDS_SHIFT (4U) +#define MSCM_OCMDR_OCMC1_DFCS_SHIFT (5U) + +/*! + * @brief Flash size encoding rule. + */ +#define FLASH_MEMORY_SIZE_ENCODING_RULE_K1_2 (0x00U) +#define FLASH_MEMORY_SIZE_ENCODING_RULE_K3 (0x01U) + +#if defined(K32W042S1M2_M0P_SERIES) || defined(K32W042S1M2_M4_SERIES) +#define FLASH_MEMORY_SIZE_ENCODING_RULE (FLASH_MEMORY_SIZE_ENCODING_RULE_K3) +#else +#define FLASH_MEMORY_SIZE_ENCODING_RULE (FLASH_MEMORY_SIZE_ENCODING_RULE_K1_2) +#endif /******************************************************************************* * Prototypes @@ -238,9 +386,9 @@ enum _flash_config_area_range #if FLASH_DRIVER_IS_FLASH_RESIDENT /*! @brief Copy flash_run_command() to RAM*/ -static void copy_flash_run_command(uint8_t *flashRunCommand); +static void copy_flash_run_command(uint32_t *flashRunCommand); /*! @brief Copy flash_cache_clear_command() to RAM*/ -static void copy_flash_cache_clear_command(uint8_t *flashCacheClearCommand); +static void copy_flash_common_bit_operation(uint32_t *flashCommonBitOperation); /*! @brief Check whether flash execute-in-ram functions are ready*/ static status_t flash_check_execute_in_ram_function_info(flash_config_t *config); #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ @@ -251,6 +399,9 @@ static status_t flash_command_sequence(flash_config_t *config); /*! @brief Perform the cache clear to the flash*/ void flash_cache_clear(flash_config_t *config); +/*! @brief Process the cache to the flash*/ +static void flash_cache_clear_process(flash_config_t *config, flash_cache_clear_process_t process); + /*! @brief Validates the range and alignment of the given address range.*/ static status_t flash_check_range(flash_config_t *config, uint32_t startAddress, @@ -291,44 +442,131 @@ static status_t flash_validate_swap_indicator_address(flash_config_t *config, ui static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option); #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ +/*! @brief Gets the flash protection information (region size, region count).*/ +static status_t flash_get_protection_info(flash_config_t *config, flash_protection_config_t *info); + +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL +/*! @brief Gets the flash Execute-Only access information (Segment size, Segment count).*/ +static status_t flash_get_access_info(flash_config_t *config, flash_access_config_t *info); +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + +#if FLASH_CACHE_IS_CONTROLLED_BY_MCM +/*! @brief Performs the cache clear to the flash by MCM.*/ +void mcm_flash_cache_clear(flash_config_t *config); +#endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */ + +#if FLASH_CACHE_IS_CONTROLLED_BY_FMC +/*! @brief Performs the cache clear to the flash by FMC.*/ +void fmc_flash_cache_clear(void); +#endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */ + +#if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM +/*! @brief Sets the prefetch speculation buffer to the flash by MSCM.*/ +void mscm_flash_prefetch_speculation_enable(bool enable); +#endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */ + +#if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC +/*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/ +void fmc_flash_prefetch_speculation_clear(void); +#endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */ + /******************************************************************************* * Variables ******************************************************************************/ /*! @brief Access to FTFx->FCCOB */ -#if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA -volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFA->FCCOB3; -#elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE -volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFE->FCCOB3; -#elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL -volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFL->FCCOB3; -#else -#error "Unknown flash controller" +volatile uint32_t *const kFCCOBx = (volatile uint32_t *)&FTFx_FCCOB3_REG; +/*! @brief Access to FTFx->FPROT */ +volatile uint32_t *const kFPROTL = (volatile uint32_t *)&FTFx_FPROT_LOW_REG; +#if defined(FTFx_FPROT_HIGH_REG) +volatile uint32_t *const kFPROTH = (volatile uint32_t *)&FTFx_FPROT_HIGH_REG; #endif -/*! @brief Access to FTFx->FPROT */ -#if defined(FSL_FEATURE_FLASH_IS_FTFA) && FSL_FEATURE_FLASH_IS_FTFA -volatile uint32_t *const kFPROT = (volatile uint32_t *)&FTFA->FPROT3; -#elif defined(FSL_FEATURE_FLASH_IS_FTFE) && FSL_FEATURE_FLASH_IS_FTFE -volatile uint32_t *const kFPROT = (volatile uint32_t *)&FTFE->FPROT3; -#elif defined(FSL_FEATURE_FLASH_IS_FTFL) && FSL_FEATURE_FLASH_IS_FTFL -volatile uint32_t *const kFPROT = (volatile uint32_t *)&FTFL->FPROT3; -#else -#error "Unknown flash controller" +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER +volatile uint8_t *const kFPROTSL = (volatile uint8_t *)&FTFx_FPROTSL_REG; +volatile uint8_t *const kFPROTSH = (volatile uint8_t *)&FTFx_FPROTSH_REG; #endif #if FLASH_DRIVER_IS_FLASH_RESIDENT /*! @brief A function pointer used to point to relocated flash_run_command() */ -static void (*callFlashRunCommand)(FTFx_REG_ACCESS_TYPE ftfx_fstat); -/*! @brief A function pointer used to point to relocated flash_cache_clear_command() */ -static void (*callFlashCacheClearCommand)(FTFx_REG32_ACCESS_TYPE ftfx_reg); +static void (*callFlashRunCommand)(FTFx_REG8_ACCESS_TYPE ftfx_fstat); +/*! @brief A function pointer used to point to relocated flash_common_bit_operation() */ +static void (*callFlashCommonBitOperation)(FTFx_REG32_ACCESS_TYPE base, + uint32_t bitMask, + uint32_t bitShift, + uint32_t bitValue); + +/*! + * @brief Position independent code of flash_run_command() + * + * Note1: The prototype of C function is shown as below: + * @code + * void flash_run_command(FTFx_REG8_ACCESS_TYPE ftfx_fstat) + * { + * // clear CCIF bit + * *ftfx_fstat = FTFx_FSTAT_CCIF_MASK; + * + * // Check CCIF bit of the flash status register, wait till it is set. + * // IP team indicates that this loop will always complete. + * while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK)) + * { + * } + * } + * @endcode + * Note2: The binary code is generated by IAR 7.70.1 + */ +const static uint16_t s_flashRunCommandFunctionCode[] = { + 0x2180, /* MOVS R1, #128 ; 0x80 */ + 0x7001, /* STRB R1, [R0] */ + /* @4: */ + 0x7802, /* LDRB R2, [R0] */ + 0x420a, /* TST R2, R1 */ + 0xd0fc, /* BEQ.N @4 */ + 0x4770 /* BX LR */ +}; + +/*! + * @brief Position independent code of flash_common_bit_operation() + * + * Note1: The prototype of C function is shown as below: + * @code + * void flash_common_bit_operation(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, uint32_t + * bitValue) + * { + * if (bitMask) + * { + * uint32_t value = (((uint32_t)(((uint32_t)(bitValue)) << bitShift)) & bitMask); + * *base = (*base & (~bitMask)) | value; + * } + * + * __ISB(); + * __DSB(); + * } + * @endcode + * Note2: The binary code is generated by IAR 7.70.1 + */ +const static uint16_t s_flashCommonBitOperationFunctionCode[] = { + 0xb510, /* PUSH {R4, LR} */ + 0x2900, /* CMP R1, #0 */ + 0xd005, /* BEQ.N @12 */ + 0x6804, /* LDR R4, [R0] */ + 0x438c, /* BICS R4, R4, R1 */ + 0x4093, /* LSLS R3, R3, R2 */ + 0x4019, /* ANDS R1, R1, R3 */ + 0x4321, /* ORRS R1, R1, R4 */ + 0x6001, /* STR R1, [R0] */ + /* @12: */ + 0xf3bf, 0x8f6f, /* ISB */ + 0xf3bf, 0x8f4f, /* DSB */ + 0xbd10 /* POP {R4, PC} */ +}; #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ #if (FLASH_DRIVER_IS_FLASH_RESIDENT && !FLASH_DRIVER_IS_EXPORTED) /*! @brief A static buffer used to hold flash_run_command() */ -static uint8_t s_flashRunCommand[kFLASH_executeInRamFunctionMaxSize]; -/*! @brief A static buffer used to hold flash_cache_clear_command() */ -static uint8_t s_flashCacheClearCommand[kFLASH_executeInRamFunctionMaxSize]; +static uint32_t s_flashRunCommand[kFLASH_ExecuteInRamFunctionMaxSizeInWords]; +/*! @brief A static buffer used to hold flash_common_bit_operation() */ +static uint32_t s_flashCommonBitOperation[kFLASH_ExecuteInRamFunctionMaxSizeInWords]; /*! @brief Flash execute-in-ram function information */ static flash_execute_in_ram_function_config_t s_flashExecuteInRamFunctionInfo; #endif @@ -351,6 +589,7 @@ static flash_execute_in_ram_function_config_t s_flashExecuteInRamFunctionInfo; * flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; * @endcode */ +#if (FLASH_MEMORY_SIZE_ENCODING_RULE == FLASH_MEMORY_SIZE_ENCODING_RULE_K1_2) const uint16_t kPFlashDensities[] = { 8, /* 0x0 - 8192, 8KB */ 16, /* 0x1 - 16384, 16KB */ @@ -369,6 +608,26 @@ const uint16_t kPFlashDensities[] = { 1536, /* 0xe - 1572864, 1.5MB */ /* 2048, 0xf - 2097152, 2MB */ }; +#elif(FLASH_MEMORY_SIZE_ENCODING_RULE == FLASH_MEMORY_SIZE_ENCODING_RULE_K3) +const uint16_t kPFlashDensities[] = { + 0, /* 0x0 - undefined */ + 0, /* 0x1 - undefined */ + 0, /* 0x2 - undefined */ + 0, /* 0x3 - undefined */ + 0, /* 0x4 - undefined */ + 0, /* 0x5 - undefined */ + 0, /* 0x6 - undefined */ + 0, /* 0x7 - undefined */ + 0, /* 0x8 - undefined */ + 0, /* 0x9 - undefined */ + 256, /* 0xa - 262144, 256KB */ + 0, /* 0xb - undefined */ + 1024, /* 0xc - 1048576, 1MB */ + 0, /* 0xd - undefined */ + 0, /* 0xe - undefined */ + 0, /* 0xf - undefined */ +}; +#endif /******************************************************************************* * Code @@ -376,39 +635,86 @@ const uint16_t kPFlashDensities[] = { status_t FLASH_Init(flash_config_t *config) { - uint32_t flashDensity; - if (config == NULL) { return kStatus_FLASH_InvalidArgument; } - /* calculate the flash density from SIM_FCFG1.PFSIZE */ - uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT; - /* PFSIZE=0xf means that on customer parts the IFR was not correctly programmed. - * We just use the pre-defined flash size in feature file here to support pre-production parts */ - if (pfsize == 0xf) +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED + if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash) { - flashDensity = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE; +/* calculate the flash density from SIM_FCFG1.PFSIZE */ +#if defined(SIM_FCFG1_CORE1_PFSIZE_MASK) + uint32_t flashDensity; + uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_CORE1_PFSIZE_MASK) >> SIM_FCFG1_CORE1_PFSIZE_SHIFT; + if (pfsize == 0xf) + { + flashDensity = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE; + } + else + { + flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; + } + config->PFlashTotalSize = flashDensity; +#else + /* Unused code to solve MISRA-C issue*/ + config->PFlashBlockBase = kPFlashDensities[0]; + config->PFlashTotalSize = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE; +#endif + config->PFlashBlockBase = FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS; + config->PFlashBlockCount = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT; + config->PFlashSectorSize = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SECTOR_SIZE; } else +#endif /* FLASH_SSD_IS_SECONDARY_FLASH_ENABLED */ { - flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; + uint32_t flashDensity; + +/* calculate the flash density from SIM_FCFG1.PFSIZE */ +#if defined(SIM_FCFG1_CORE0_PFSIZE_MASK) + uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_CORE0_PFSIZE_MASK) >> SIM_FCFG1_CORE0_PFSIZE_SHIFT; +#elif defined(SIM_FCFG1_PFSIZE_MASK) + uint8_t pfsize = (SIM->FCFG1 & SIM_FCFG1_PFSIZE_MASK) >> SIM_FCFG1_PFSIZE_SHIFT; +#else +#error "Unknown flash size" +#endif + /* PFSIZE=0xf means that on customer parts the IFR was not correctly programmed. + * We just use the pre-defined flash size in feature file here to support pre-production parts */ + if (pfsize == 0xf) + { + flashDensity = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE; + } + else + { + flashDensity = ((uint32_t)kPFlashDensities[pfsize]) << 10; + } + + /* fill out a few of the structure members */ + config->PFlashBlockBase = FSL_FEATURE_FLASH_PFLASH_START_ADDRESS; + config->PFlashTotalSize = flashDensity; + config->PFlashBlockCount = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT; + config->PFlashSectorSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE; } - /* fill out a few of the structure members */ - config->PFlashBlockBase = PFLASH_BLOCK_BASE; - config->PFlashTotalSize = flashDensity; - config->PFlashBlockCount = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT; - config->PFlashSectorSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_SECTOR_SIZE; - + { #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL - config->PFlashAccessSegmentSize = kFLASH_accessSegmentBase << FTFx->FACSS; - config->PFlashAccessSegmentCount = FTFx->FACSN; +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER + if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash) + { + config->PFlashAccessSegmentSize = kFLASH_AccessSegmentBase << FTFx->FACSSS; + config->PFlashAccessSegmentCount = FTFx->FACSNS; + } + else +#endif + { + config->PFlashAccessSegmentSize = kFLASH_AccessSegmentBase << FTFx->FACSS; + config->PFlashAccessSegmentCount = FTFx->FACSN; + } #else - config->PFlashAccessSegmentSize = 0; - config->PFlashAccessSegmentCount = 0; + config->PFlashAccessSegmentSize = 0; + config->PFlashAccessSegmentCount = 0; #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ + } config->PFlashCallback = NULL; @@ -418,7 +724,7 @@ status_t FLASH_Init(flash_config_t *config) { s_flashExecuteInRamFunctionInfo.activeFunctionCount = 0; s_flashExecuteInRamFunctionInfo.flashRunCommand = s_flashRunCommand; - s_flashExecuteInRamFunctionInfo.flashCacheClearCommand = s_flashCacheClearCommand; + s_flashExecuteInRamFunctionInfo.flashCommonBitOperation = s_flashCommonBitOperation; config->flashExecuteInRamFunctionInfo = &s_flashExecuteInRamFunctionInfo.activeFunctionCount; FLASH_PrepareExecuteInRamFunctions(config); } @@ -467,8 +773,8 @@ status_t FLASH_PrepareExecuteInRamFunctions(flash_config_t *config) flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo; copy_flash_run_command(flashExecuteInRamFunctionInfo->flashRunCommand); - copy_flash_cache_clear_command(flashExecuteInRamFunctionInfo->flashCacheClearCommand); - flashExecuteInRamFunctionInfo->activeFunctionCount = kFLASH_executeInRamFunctionTotalNum; + copy_flash_common_bit_operation(flashExecuteInRamFunctionInfo->flashCommonBitOperation); + flashExecuteInRamFunctionInfo->activeFunctionCount = kFLASH_ExecuteInRamFunctionTotalNum; return kStatus_FLASH_Success; } @@ -493,6 +799,8 @@ status_t FLASH_EraseAll(flash_config_t *config, uint32_t key) return returnCode; } + flash_cache_clear_process(config, kFLASH_CacheClearProcessPre); + /* calling flash command sequence function to execute the command */ returnCode = flash_command_sequence(config); @@ -513,22 +821,29 @@ status_t FLASH_EraseAll(flash_config_t *config, uint32_t key) status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBytes, uint32_t key) { uint32_t sectorSize; - flash_operation_config_t flashInfo; + flash_operation_config_t flashOperationInfo; uint32_t endAddress; /* storing end address */ uint32_t numberOfSectors; /* number of sectors calculated by endAddress */ status_t returnCode; - flash_get_matched_operation_info(config, start, &flashInfo); + flash_get_matched_operation_info(config, start, &flashOperationInfo); /* Check the supplied address range. */ - returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.sectorCmdAddressAligment); + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.sectorCmdAddressAligment); if (returnCode) { return returnCode; } - start = flashInfo.convertedAddress; - sectorSize = flashInfo.activeSectorSize; + /* Validate the user key */ + returnCode = flash_check_user_key(key); + if (returnCode) + { + return returnCode; + } + + start = flashOperationInfo.convertedAddress; + sectorSize = flashOperationInfo.activeSectorSize; /* calculating Flash end address */ endAddress = start + lengthInBytes - 1; @@ -541,6 +856,8 @@ status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBy endAddress = numberOfSectors * sectorSize - 1; } + flash_cache_clear_process(config, kFLASH_CacheClearProcessPre); + /* the start address will increment to the next sector address * until it reaches the endAdddress */ while (start <= endAddress) @@ -548,13 +865,6 @@ status_t FLASH_Erase(flash_config_t *config, uint32_t start, uint32_t lengthInBy /* preparing passing parameter to erase a flash block */ kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_ERASE_SECTOR, start); - /* Validate the user key */ - returnCode = flash_check_user_key(key); - if (returnCode) - { - return returnCode; - } - /* calling flash command sequence function to execute the command */ returnCode = flash_command_sequence(config); @@ -601,6 +911,8 @@ status_t FLASH_EraseAllUnsecure(flash_config_t *config, uint32_t key) return returnCode; } + flash_cache_clear_process(config, kFLASH_CacheClearProcessPre); + /* calling flash command sequence function to execute the command */ returnCode = flash_command_sequence(config); @@ -639,6 +951,8 @@ status_t FLASH_EraseAllExecuteOnlySegments(flash_config_t *config, uint32_t key) return returnCode; } + flash_cache_clear_process(config, kFLASH_CacheClearProcessPre); + /* calling flash command sequence function to execute the command */ returnCode = flash_command_sequence(config); @@ -650,33 +964,35 @@ status_t FLASH_EraseAllExecuteOnlySegments(flash_config_t *config, uint32_t key) status_t FLASH_Program(flash_config_t *config, uint32_t start, uint32_t *src, uint32_t lengthInBytes) { status_t returnCode; - flash_operation_config_t flashInfo; + flash_operation_config_t flashOperationInfo; if (src == NULL) { return kStatus_FLASH_InvalidArgument; } - flash_get_matched_operation_info(config, start, &flashInfo); + flash_get_matched_operation_info(config, start, &flashOperationInfo); /* Check the supplied address range. */ - returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.blockWriteUnitSize); + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.blockWriteUnitSize); if (returnCode) { return returnCode; } - start = flashInfo.convertedAddress; + start = flashOperationInfo.convertedAddress; + + flash_cache_clear_process(config, kFLASH_CacheClearProcessPre); while (lengthInBytes > 0) { /* preparing passing parameter to program the flash block */ kFCCOBx[1] = *src++; - if (4 == flashInfo.blockWriteUnitSize) + if (4 == flashOperationInfo.blockWriteUnitSize) { kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_LONGWORD, start); } - else if (8 == flashInfo.blockWriteUnitSize) + else if (8 == flashOperationInfo.blockWriteUnitSize) { kFCCOBx[2] = *src++; kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_PHRASE, start); @@ -702,10 +1018,10 @@ status_t FLASH_Program(flash_config_t *config, uint32_t start, uint32_t *src, ui else { /* update start address for next iteration */ - start += flashInfo.blockWriteUnitSize; + start += flashOperationInfo.blockWriteUnitSize; /* update lengthInBytes for next iteration */ - lengthInBytes -= flashInfo.blockWriteUnitSize; + lengthInBytes -= flashOperationInfo.blockWriteUnitSize; } } @@ -742,6 +1058,8 @@ status_t FLASH_ProgramOnce(flash_config_t *config, uint32_t index, uint32_t *src } #endif /* FLASH_PROGRAM_ONCE_IS_8BYTES_UNIT_SUPPORT */ + flash_cache_clear_process(config, kFLASH_CacheClearProcessPre); + /* calling flash command sequence function to execute the command */ returnCode = flash_command_sequence(config); @@ -755,7 +1073,7 @@ status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t * { status_t returnCode; uint32_t sectorSize; - flash_operation_config_t flashInfo; + flash_operation_config_t flashOperationInfo; #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD bool needSwitchFlexRamMode = false; #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ @@ -765,17 +1083,17 @@ status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t * return kStatus_FLASH_InvalidArgument; } - flash_get_matched_operation_info(config, start, &flashInfo); + flash_get_matched_operation_info(config, start, &flashOperationInfo); /* Check the supplied address range. */ - returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.sectionCmdAddressAligment); + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.sectionCmdAddressAligment); if (returnCode) { return returnCode; } - start = flashInfo.convertedAddress; - sectorSize = flashInfo.activeSectorSize; + start = flashOperationInfo.convertedAddress; + sectorSize = flashOperationInfo.activeSectorSize; #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD /* Switch function of FlexRAM if needed */ @@ -783,7 +1101,7 @@ status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t * { needSwitchFlexRamMode = true; - returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableAsRam); + returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableAsRam); if (returnCode != kStatus_FLASH_Success) { return kStatus_FLASH_SetFlexramAsRamError; @@ -791,6 +1109,8 @@ status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t * } #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + flash_cache_clear_process(config, kFLASH_CacheClearProcessPre); + while (lengthInBytes > 0) { /* Make sure the write operation doesn't span two sectors */ @@ -819,9 +1139,9 @@ status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t * uint32_t programSizeOfCurrentPass; uint32_t numberOfPhases; - if (lengthTobeProgrammedOfCurrentSector > kFLASH_accelerationRamSize) + if (lengthTobeProgrammedOfCurrentSector > kFLASH_AccelerationRamSize) { - programSizeOfCurrentPass = kFLASH_accelerationRamSize; + programSizeOfCurrentPass = kFLASH_AccelerationRamSize; } else { @@ -833,7 +1153,7 @@ status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t * /* Set start address of the data to be programmed */ kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_PROGRAM_SECTION, start + currentOffset); /* Set program size in terms of FEATURE_FLASH_SECTION_CMD_ADDRESS_ALIGMENT */ - numberOfPhases = programSizeOfCurrentPass / flashInfo.sectionCmdAddressAligment; + numberOfPhases = programSizeOfCurrentPass / flashOperationInfo.sectionCmdAddressAligment; kFCCOBx[1] = BYTES_JOIN_TO_WORD_2_2(numberOfPhases, 0xFFFFU); @@ -867,7 +1187,7 @@ status_t FLASH_ProgramSection(flash_config_t *config, uint32_t start, uint32_t * /* Restore function of FlexRAM if needed. */ if (needSwitchFlexRamMode) { - returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableForEeprom); + returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableForEeprom); if (returnCode != kStatus_FLASH_Success) { return kStatus_FLASH_RecoverFlexramAsEepromError; @@ -904,7 +1224,7 @@ status_t FLASH_EepromWrite(flash_config_t *config, uint32_t start, uint8_t *src, { needSwitchFlexRamMode = true; - returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableForEeprom); + returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableForEeprom); if (returnCode != kStatus_FLASH_Success) { return kStatus_FLASH_SetFlexramAsEepromError; @@ -950,7 +1270,7 @@ status_t FLASH_EepromWrite(flash_config_t *config, uint32_t start, uint8_t *src, /* Switch function of FlexRAM if needed */ if (needSwitchFlexRamMode) { - returnCode = FLASH_SetFlexramFunction(config, kFLASH_flexramFunctionOptionAvailableAsRam); + returnCode = FLASH_SetFlexramFunction(config, kFLASH_FlexramFunctionOptionAvailableAsRam); if (returnCode != kStatus_FLASH_Success) { return kStatus_FLASH_RecoverFlexramAsRamError; @@ -966,17 +1286,18 @@ status_t FLASH_ReadResource( flash_config_t *config, uint32_t start, uint32_t *dst, uint32_t lengthInBytes, flash_read_resource_option_t option) { status_t returnCode; - flash_operation_config_t flashInfo; + flash_operation_config_t flashOperationInfo; if ((config == NULL) || (dst == NULL)) { return kStatus_FLASH_InvalidArgument; } - flash_get_matched_operation_info(config, start, &flashInfo); + flash_get_matched_operation_info(config, start, &flashOperationInfo); /* Check the supplied address range. */ - returnCode = flash_check_resource_range(start, lengthInBytes, flashInfo.resourceCmdAddressAligment, option); + returnCode = + flash_check_resource_range(start, lengthInBytes, flashOperationInfo.resourceCmdAddressAligment, option); if (returnCode != kStatus_FLASH_Success) { return returnCode; @@ -986,11 +1307,11 @@ status_t FLASH_ReadResource( { /* preparing passing parameter */ kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_READ_RESOURCE, start); - if (flashInfo.resourceCmdAddressAligment == 4) + if (flashOperationInfo.resourceCmdAddressAligment == 4) { kFCCOBx[2] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); } - else if (flashInfo.resourceCmdAddressAligment == 8) + else if (flashOperationInfo.resourceCmdAddressAligment == 8) { kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_3(option, 0xFFFFFFU); } @@ -1008,14 +1329,14 @@ status_t FLASH_ReadResource( /* fetch data */ *dst++ = kFCCOBx[1]; - if (flashInfo.resourceCmdAddressAligment == 8) + if (flashOperationInfo.resourceCmdAddressAligment == 8) { *dst++ = kFCCOBx[2]; } /* update start address for next iteration */ - start += flashInfo.resourceCmdAddressAligment; + start += flashOperationInfo.resourceCmdAddressAligment; /* update lengthInBytes for next iteration */ - lengthInBytes -= flashInfo.resourceCmdAddressAligment; + lengthInBytes -= flashOperationInfo.resourceCmdAddressAligment; } return (returnCode); @@ -1075,7 +1396,7 @@ status_t FLASH_GetSecurityState(flash_config_t *config, flash_security_state_t * if (FLASH_SECURITY_STATE_UNSECURED == (registerValue & FTFx_FSEC_SEC_MASK)) { /* Flash in unsecured state */ - *state = kFLASH_securityStateNotSecure; + *state = kFLASH_SecurityStateNotSecure; } else { @@ -1084,12 +1405,12 @@ status_t FLASH_GetSecurityState(flash_config_t *config, flash_security_state_t * if (FLASH_SECURITY_STATE_KEYEN == (registerValue & FTFx_FSEC_KEYEN_MASK)) { /* Backdoor key security enabled */ - *state = kFLASH_securityStateBackdoorEnabled; + *state = kFLASH_SecurityStateBackdoorEnabled; } else { /* Backdoor key security disabled */ - *state = kFLASH_securityStateBackdoorDisabled; + *state = kFLASH_SecurityStateBackdoorDisabled; } } @@ -1146,22 +1467,22 @@ status_t FLASH_VerifyErase(flash_config_t *config, uint32_t start, uint32_t leng { /* Check arguments. */ uint32_t blockSize; - flash_operation_config_t flashInfo; + flash_operation_config_t flashOperationInfo; uint32_t nextBlockStartAddress; uint32_t remainingBytes; status_t returnCode; - flash_get_matched_operation_info(config, start, &flashInfo); + flash_get_matched_operation_info(config, start, &flashOperationInfo); - returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.sectionCmdAddressAligment); + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.sectionCmdAddressAligment); if (returnCode) { return returnCode; } - flash_get_matched_operation_info(config, start, &flashInfo); - start = flashInfo.convertedAddress; - blockSize = flashInfo.activeBlockSize; + flash_get_matched_operation_info(config, start, &flashOperationInfo); + start = flashOperationInfo.convertedAddress; + blockSize = flashOperationInfo.activeBlockSize; nextBlockStartAddress = ALIGN_UP(start, blockSize); if (nextBlockStartAddress == start) @@ -1180,7 +1501,7 @@ status_t FLASH_VerifyErase(flash_config_t *config, uint32_t start, uint32_t leng verifyLength = remainingBytes; } - numberOfPhrases = verifyLength / flashInfo.sectionCmdAddressAligment; + numberOfPhrases = verifyLength / flashOperationInfo.sectionCmdAddressAligment; /* Fill in verify section command parameters. */ kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_3(FTFx_VERIFY_SECTION, start); @@ -1210,22 +1531,22 @@ status_t FLASH_VerifyProgram(flash_config_t *config, uint32_t *failedData) { status_t returnCode; - flash_operation_config_t flashInfo; + flash_operation_config_t flashOperationInfo; if (expectedData == NULL) { return kStatus_FLASH_InvalidArgument; } - flash_get_matched_operation_info(config, start, &flashInfo); + flash_get_matched_operation_info(config, start, &flashOperationInfo); - returnCode = flash_check_range(config, start, lengthInBytes, flashInfo.checkCmdAddressAligment); + returnCode = flash_check_range(config, start, lengthInBytes, flashOperationInfo.checkCmdAddressAligment); if (returnCode) { return returnCode; } - start = flashInfo.convertedAddress; + start = flashOperationInfo.convertedAddress; while (lengthInBytes) { @@ -1251,9 +1572,9 @@ status_t FLASH_VerifyProgram(flash_config_t *config, break; } - lengthInBytes -= flashInfo.checkCmdAddressAligment; - expectedData += flashInfo.checkCmdAddressAligment / sizeof(*expectedData); - start += flashInfo.checkCmdAddressAligment; + lengthInBytes -= flashOperationInfo.checkCmdAddressAligment; + expectedData += flashOperationInfo.checkCmdAddressAligment / sizeof(*expectedData); + start += flashOperationInfo.checkCmdAddressAligment; } return (returnCode); @@ -1279,19 +1600,21 @@ status_t FLASH_IsProtected(flash_config_t *config, flash_protection_state_t *protection_state) { uint32_t endAddress; /* end address for protection check */ - uint32_t protectionRegionSize; /* size of flash protection region */ uint32_t regionCheckedCounter; /* increments each time the flash address was checked for * protection status */ uint32_t regionCounter; /* incrementing variable used to increment through the flash * protection regions */ uint32_t protectStatusCounter; /* increments each time a flash region was detected as protected */ - uint8_t flashRegionProtectStatus[FSL_FEATURE_FTFx_REGION_COUNT]; /* array of the protection status for each + uint8_t flashRegionProtectStatus[FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT]; /* array of the protection + * status for each * protection region */ - uint32_t flashRegionAddress[FSL_FEATURE_FTFx_REGION_COUNT + 1]; /* array of the start addresses for each flash - * protection region. Note this is REGION_COUNT+1 - * due to requiring the next start address after - * the end of flash for loop-check purposes below */ + uint32_t flashRegionAddress[FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT + + 1]; /* array of the start addresses for each flash + * protection region. Note this is REGION_COUNT+1 + * due to requiring the next start address after + * the end of flash for loop-check purposes below */ + flash_protection_config_t flashProtectionInfo; /* flash protection information */ status_t returnCode; if (protection_state == NULL) @@ -1306,28 +1629,24 @@ status_t FLASH_IsProtected(flash_config_t *config, return returnCode; } + /* Get necessary flash protection information. */ + returnCode = flash_get_protection_info(config, &flashProtectionInfo); + if (returnCode) + { + return returnCode; + } + /* calculating Flash end address */ endAddress = start + lengthInBytes; - /* Calculate the size of the flash protection region - * If the flash density is > 32KB, then protection region is 1/32 of total flash density - * Else if flash density is < 32KB, then flash protection region is set to 1KB */ - if (config->PFlashTotalSize > 32 * 1024) - { - protectionRegionSize = (config->PFlashTotalSize) / FSL_FEATURE_FTFx_REGION_COUNT; - } - else - { - protectionRegionSize = 1024; - } - /* populate the flashRegionAddress array with the start address of each flash region */ regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ /* populate up to 33rd element of array, this is the next address after end of flash array */ - while (regionCounter <= FSL_FEATURE_FTFx_REGION_COUNT) + while (regionCounter <= flashProtectionInfo.regionCount) { - flashRegionAddress[regionCounter] = config->PFlashBlockBase + protectionRegionSize * regionCounter; + flashRegionAddress[regionCounter] = + flashProtectionInfo.regionBase + flashProtectionInfo.regionSize * regionCounter; regionCounter++; } @@ -1341,24 +1660,80 @@ status_t FLASH_IsProtected(flash_config_t *config, * regionCounter is used to determine which FPROT[3:0] register to check for protection status * Note: FPROT=1 means NOT protected, FPROT=0 means protected */ regionCounter = 0; /* make sure regionCounter is initialized to 0 first */ - while (regionCounter < FSL_FEATURE_FTFx_REGION_COUNT) + while (regionCounter < flashProtectionInfo.regionCount) { - if (regionCounter < 8) +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER + if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash) { - flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT3) >> regionCounter) & (0x01u); - } - else if ((regionCounter >= 8) && (regionCounter < 16)) - { - flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT2) >> (regionCounter - 8)) & (0x01u); - } - else if ((regionCounter >= 16) && (regionCounter < 24)) - { - flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT1) >> (regionCounter - 16)) & (0x01u); + if (regionCounter < 8) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTSL_REG >> regionCounter) & (0x01u); + } + else if ((regionCounter >= 8) && (regionCounter < 16)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTSH_REG >> (regionCounter - 8)) & (0x01u); + } + else + { + break; + } } else +#endif { - flashRegionProtectStatus[regionCounter] = ((FTFx->FPROT0) >> (regionCounter - 24)) & (0x01u); + /* Note: So far protection region count may be 16/20/24/32/64 */ + if (regionCounter < 8) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL3_REG >> regionCounter) & (0x01u); + } + else if ((regionCounter >= 8) && (regionCounter < 16)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL2_REG >> (regionCounter - 8)) & (0x01u); + } +#if defined(FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT) && (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT > 16) +#if (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT == 20) + else if ((regionCounter >= 16) && (regionCounter < 20)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL1_REG >> (regionCounter - 16)) & (0x01u); + } +#else + else if ((regionCounter >= 16) && (regionCounter < 24)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL1_REG >> (regionCounter - 16)) & (0x01u); + } +#endif /* (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT == 20) */ +#endif +#if defined(FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT) && (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT > 24) + else if ((regionCounter >= 24) && (regionCounter < 32)) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTL0_REG >> (regionCounter - 24)) & (0x01u); + } +#endif +#if defined(FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT) && \ + (FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT == 64) + else if (regionCounter < 40) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH3_REG >> (regionCounter - 32)) & (0x01u); + } + else if (regionCounter < 48) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH2_REG >> (regionCounter - 40)) & (0x01u); + } + else if (regionCounter < 56) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH1_REG >> (regionCounter - 48)) & (0x01u); + } + else if (regionCounter < 64) + { + flashRegionProtectStatus[regionCounter] = (FTFx_FPROTH0_REG >> (regionCounter - 56)) & (0x01u); + } +#endif + else + { + break; + } } + regionCounter++; } @@ -1386,7 +1761,7 @@ status_t FLASH_IsProtected(flash_config_t *config, /* increment protectStatusCounter to indicate this region is protected */ protectStatusCounter++; } - start += protectionRegionSize; /* increment to an address within the next region */ + start += flashProtectionInfo.regionSize; /* increment to an address within the next region */ } regionCounter++; /* increment regionCounter to check for the next flash protection region */ } @@ -1394,18 +1769,18 @@ status_t FLASH_IsProtected(flash_config_t *config, /* if protectStatusCounter == 0, then no region of the desired flash region is protected */ if (protectStatusCounter == 0) { - *protection_state = kFLASH_protectionStateUnprotected; + *protection_state = kFLASH_ProtectionStateUnprotected; } /* if protectStatusCounter == regionCheckedCounter, then each region checked was protected */ else if (protectStatusCounter == regionCheckedCounter) { - *protection_state = kFLASH_protectionStateProtected; + *protection_state = kFLASH_ProtectionStateProtected; } /* if protectStatusCounter != regionCheckedCounter, then protection status is mixed * In other words, some regions are protected while others are unprotected */ else { - *protection_state = kFLASH_protectionStateMixed; + *protection_state = kFLASH_ProtectionStateMixed; } return (returnCode); @@ -1416,6 +1791,9 @@ status_t FLASH_IsExecuteOnly(flash_config_t *config, uint32_t lengthInBytes, flash_execute_only_access_state_t *access_state) { +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL + flash_access_config_t flashAccessInfo; /* flash Execute-Only information */ +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ status_t returnCode; if (access_state == NULL) @@ -1431,6 +1809,13 @@ status_t FLASH_IsExecuteOnly(flash_config_t *config, } #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL + /* Get necessary flash Execute-Only information. */ + returnCode = flash_get_access_info(config, &flashAccessInfo); + if (returnCode) + { + return returnCode; + } + { uint32_t executeOnlySegmentCounter = 0; @@ -1438,31 +1823,56 @@ status_t FLASH_IsExecuteOnly(flash_config_t *config, uint32_t endAddress = start + lengthInBytes; /* Aligning start address and end address */ - uint32_t alignedStartAddress = ALIGN_DOWN(start, config->PFlashAccessSegmentSize); - uint32_t alignedEndAddress = ALIGN_UP(endAddress, config->PFlashAccessSegmentSize); + uint32_t alignedStartAddress = ALIGN_DOWN(start, flashAccessInfo.SegmentSize); + uint32_t alignedEndAddress = ALIGN_UP(endAddress, flashAccessInfo.SegmentSize); uint32_t segmentIndex = 0; uint32_t maxSupportedExecuteOnlySegmentCount = - (alignedEndAddress - alignedStartAddress) / config->PFlashAccessSegmentSize; + (alignedEndAddress - alignedStartAddress) / flashAccessInfo.SegmentSize; while (start < endAddress) { uint32_t xacc; - segmentIndex = start / config->PFlashAccessSegmentSize; + segmentIndex = (start - flashAccessInfo.SegmentBase) / flashAccessInfo.SegmentSize; - if (segmentIndex < 32) +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER + if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash) { - xacc = *(const volatile uint32_t *)&FTFx->XACCL3; - } - else if (segmentIndex < config->PFlashAccessSegmentCount) - { - xacc = *(const volatile uint32_t *)&FTFx->XACCH3; - segmentIndex -= 32; + /* For secondary flash, The two XACCS registers allow up to 16 restricted segments of equal memory size. + */ + if (segmentIndex < 8) + { + xacc = *(const volatile uint8_t *)&FTFx_XACCSL_REG; + } + else if (segmentIndex < flashAccessInfo.SegmentCount) + { + xacc = *(const volatile uint8_t *)&FTFx_XACCSH_REG; + segmentIndex -= 8; + } + else + { + break; + } } else +#endif { - break; + /* For primary flash, The eight XACC registers allow up to 64 restricted segments of equal memory size. + */ + if (segmentIndex < 32) + { + xacc = *(const volatile uint32_t *)&FTFx_XACCL3_REG; + } + else if (segmentIndex < flashAccessInfo.SegmentCount) + { + xacc = *(const volatile uint32_t *)&FTFx_XACCH3_REG; + segmentIndex -= 32; + } + else + { + break; + } } /* Determine if this address range is in a execute-only protection flash segment. */ @@ -1471,24 +1881,24 @@ status_t FLASH_IsExecuteOnly(flash_config_t *config, executeOnlySegmentCounter++; } - start += config->PFlashAccessSegmentSize; + start += flashAccessInfo.SegmentSize; } if (executeOnlySegmentCounter < 1u) { - *access_state = kFLASH_accessStateUnLimited; + *access_state = kFLASH_AccessStateUnLimited; } else if (executeOnlySegmentCounter < maxSupportedExecuteOnlySegmentCount) { - *access_state = kFLASH_accessStateMixed; + *access_state = kFLASH_AccessStateMixed; } else { - *access_state = kFLASH_accessStateExecuteOnly; + *access_state = kFLASH_AccessStateExecuteOnly; } } #else - *access_state = kFLASH_accessStateUnLimited; + *access_state = kFLASH_AccessStateUnLimited; #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ return (returnCode); @@ -1503,27 +1913,27 @@ status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichPro switch (whichProperty) { - case kFLASH_propertyPflashSectorSize: + case kFLASH_PropertyPflashSectorSize: *value = config->PFlashSectorSize; break; - case kFLASH_propertyPflashTotalSize: + case kFLASH_PropertyPflashTotalSize: *value = config->PFlashTotalSize; break; - case kFLASH_propertyPflashBlockSize: + case kFLASH_PropertyPflashBlockSize: *value = config->PFlashTotalSize / FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT; break; - case kFLASH_propertyPflashBlockCount: - *value = config->PFlashBlockCount; + case kFLASH_PropertyPflashBlockCount: + *value = (uint32_t)config->PFlashBlockCount; break; - case kFLASH_propertyPflashBlockBaseAddr: + case kFLASH_PropertyPflashBlockBaseAddr: *value = config->PFlashBlockBase; break; - case kFLASH_propertyPflashFacSupport: + case kFLASH_PropertyPflashFacSupport: #if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) *value = FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL; #else @@ -1531,31 +1941,39 @@ status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichPro #endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ break; - case kFLASH_propertyPflashAccessSegmentSize: + case kFLASH_PropertyPflashAccessSegmentSize: *value = config->PFlashAccessSegmentSize; break; - case kFLASH_propertyPflashAccessSegmentCount: + case kFLASH_PropertyPflashAccessSegmentCount: *value = config->PFlashAccessSegmentCount; break; + case kFLASH_PropertyFlexRamBlockBaseAddr: + *value = config->FlexRAMBlockBase; + break; + + case kFLASH_PropertyFlexRamTotalSize: + *value = config->FlexRAMTotalSize; + break; + #if FLASH_SSD_IS_FLEXNVM_ENABLED - case kFLASH_propertyDflashSectorSize: + case kFLASH_PropertyDflashSectorSize: *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE; break; - case kFLASH_propertyDflashTotalSize: + case kFLASH_PropertyDflashTotalSize: *value = config->DFlashTotalSize; break; - case kFLASH_propertyDflashBlockSize: + case kFLASH_PropertyDflashBlockSize: *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SIZE; break; - case kFLASH_propertyDflashBlockCount: + case kFLASH_PropertyDflashBlockCount: *value = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT; break; - case kFLASH_propertyDflashBlockBaseAddr: + case kFLASH_PropertyDflashBlockBaseAddr: *value = config->DFlashBlockBase; break; - case kFLASH_propertyEepromTotalSize: + case kFLASH_PropertyEepromTotalSize: *value = config->EEpromTotalSize; break; #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ @@ -1567,6 +1985,65 @@ status_t FLASH_GetProperty(flash_config_t *config, flash_property_tag_t whichPro return kStatus_FLASH_Success; } +status_t FLASH_SetProperty(flash_config_t *config, flash_property_tag_t whichProperty, uint32_t value) +{ + status_t status = kStatus_FLASH_Success; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + switch (whichProperty) + { +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED + case kFLASH_PropertyFlashMemoryIndex: + if ((value != (uint32_t)kFLASH_MemoryIndexPrimaryFlash) && + (value != (uint32_t)kFLASH_MemoryIndexSecondaryFlash)) + { + return kStatus_FLASH_InvalidPropertyValue; + } + config->FlashMemoryIndex = (uint8_t)value; + break; +#endif /* FLASH_SSD_IS_SECONDARY_FLASH_ENABLED */ + + case kFLASH_PropertyFlashCacheControllerIndex: + if ((value != (uint32_t)kFLASH_CacheControllerIndexForCore0) && + (value != (uint32_t)kFLASH_CacheControllerIndexForCore1)) + { + return kStatus_FLASH_InvalidPropertyValue; + } + config->FlashCacheControllerIndex = (uint8_t)value; + break; + + case kFLASH_PropertyPflashSectorSize: + case kFLASH_PropertyPflashTotalSize: + case kFLASH_PropertyPflashBlockSize: + case kFLASH_PropertyPflashBlockCount: + case kFLASH_PropertyPflashBlockBaseAddr: + case kFLASH_PropertyPflashFacSupport: + case kFLASH_PropertyPflashAccessSegmentSize: + case kFLASH_PropertyPflashAccessSegmentCount: + case kFLASH_PropertyFlexRamBlockBaseAddr: + case kFLASH_PropertyFlexRamTotalSize: +#if FLASH_SSD_IS_FLEXNVM_ENABLED + case kFLASH_PropertyDflashSectorSize: + case kFLASH_PropertyDflashTotalSize: + case kFLASH_PropertyDflashBlockSize: + case kFLASH_PropertyDflashBlockCount: + case kFLASH_PropertyDflashBlockBaseAddr: + case kFLASH_PropertyEepromTotalSize: +#endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ + status = kStatus_FLASH_ReadOnlyProperty; + break; + default: /* catch inputs that are not recognized */ + status = kStatus_FLASH_UnknownProperty; + break; + } + + return status; +} + #if defined(FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD) && FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD status_t FLASH_SetFlexramFunction(flash_config_t *config, flash_flexram_function_option_t option) { @@ -1611,7 +2088,7 @@ status_t FLASH_SwapControl(flash_config_t *config, /* Make sure address provided is in the lower half of Program flash but not in the Flash Configuration Field */ if ((address >= (config->PFlashTotalSize / 2)) || - ((address >= kFLASH_configAreaStart) && (address <= kFLASH_configAreaEnd))) + ((address >= kFLASH_ConfigAreaStart) && (address <= kFLASH_ConfigAreaEnd))) { return kStatus_FLASH_SwapIndicatorAddressError; } @@ -1628,9 +2105,9 @@ status_t FLASH_SwapControl(flash_config_t *config, returnCode = flash_command_sequence(config); - returnInfo->flashSwapState = (flash_swap_state_t)FTFx->FCCOB5; - returnInfo->currentSwapBlockStatus = (flash_swap_block_status_t)FTFx->FCCOB6; - returnInfo->nextSwapBlockStatus = (flash_swap_block_status_t)FTFx->FCCOB7; + returnInfo->flashSwapState = (flash_swap_state_t)FTFx_FCCOB5_REG; + returnInfo->currentSwapBlockStatus = (flash_swap_block_status_t)FTFx_FCCOB6_REG; + returnInfo->nextSwapBlockStatus = (flash_swap_block_status_t)FTFx_FCCOB7_REG; return returnCode; } @@ -1646,23 +2123,23 @@ status_t FLASH_Swap(flash_config_t *config, uint32_t address, flash_swap_functio do { - returnCode = FLASH_SwapControl(config, address, kFLASH_swapControlOptionReportStatus, &returnInfo); + returnCode = FLASH_SwapControl(config, address, kFLASH_SwapControlOptionReportStatus, &returnInfo); if (returnCode != kStatus_FLASH_Success) { return returnCode; } - if (kFLASH_swapFunctionOptionDisable == option) + if (kFLASH_SwapFunctionOptionDisable == option) { - if (returnInfo.flashSwapState == kFLASH_swapStateDisabled) + if (returnInfo.flashSwapState == kFLASH_SwapStateDisabled) { return kStatus_FLASH_Success; } - else if (returnInfo.flashSwapState == kFLASH_swapStateUninitialized) + else if (returnInfo.flashSwapState == kFLASH_SwapStateUninitialized) { /* The swap system changed to the DISABLED state with Program flash block 0 * located at relative flash address 0x0_0000 */ - returnCode = FLASH_SwapControl(config, address, kFLASH_swapControlOptionDisableSystem, &returnInfo); + returnCode = FLASH_SwapControl(config, address, kFLASH_SwapControlOptionDisableSystem, &returnInfo); } else { @@ -1679,12 +2156,12 @@ status_t FLASH_Swap(flash_config_t *config, uint32_t address, flash_swap_functio * Complete. */ switch (returnInfo.flashSwapState) { - case kFLASH_swapStateUninitialized: + case kFLASH_SwapStateUninitialized: /* If current swap mode is Uninitialized, Initialize Swap to Initialized/READY state. */ returnCode = - FLASH_SwapControl(config, address, kFLASH_swapControlOptionIntializeSystem, &returnInfo); + FLASH_SwapControl(config, address, kFLASH_SwapControlOptionIntializeSystem, &returnInfo); break; - case kFLASH_swapStateReady: + case kFLASH_SwapStateReady: /* Validate whether the address provided to the swap system is matched to * swap indicator address in the IFR */ returnCode = flash_validate_swap_indicator_address(config, address); @@ -1692,23 +2169,23 @@ status_t FLASH_Swap(flash_config_t *config, uint32_t address, flash_swap_functio { /* If current swap mode is Initialized/Ready, Initialize Swap to UPDATE state. */ returnCode = - FLASH_SwapControl(config, address, kFLASH_swapControlOptionSetInUpdateState, &returnInfo); + FLASH_SwapControl(config, address, kFLASH_SwapControlOptionSetInUpdateState, &returnInfo); } break; - case kFLASH_swapStateUpdate: + case kFLASH_SwapStateUpdate: /* If current swap mode is Update, Erase indicator sector in non active block * to proceed swap system to update-erased state */ returnCode = FLASH_Erase(config, address + (config->PFlashTotalSize >> 1), - FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT, kFLASH_apiEraseKey); + FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT, kFLASH_ApiEraseKey); break; - case kFLASH_swapStateUpdateErased: + case kFLASH_SwapStateUpdateErased: /* If current swap mode is Update or Update-Erased, progress Swap to COMPLETE State */ returnCode = - FLASH_SwapControl(config, address, kFLASH_swapControlOptionSetInCompleteState, &returnInfo); + FLASH_SwapControl(config, address, kFLASH_SwapControlOptionSetInCompleteState, &returnInfo); break; - case kFLASH_swapStateComplete: + case kFLASH_SwapStateComplete: break; - case kFLASH_swapStateDisabled: + case kFLASH_SwapStateDisabled: /* When swap system is in disabled state, We need to clear swap system back to uninitialized * by issuing EraseAllBlocks command */ returnCode = kStatus_FLASH_SwapSystemNotInUninitialized; @@ -1722,7 +2199,7 @@ status_t FLASH_Swap(flash_config_t *config, uint32_t address, flash_swap_functio { break; } - } while (!((kFLASH_swapStateComplete == returnInfo.flashSwapState) && (kFLASH_swapFunctionOptionEnable == option))); + } while (!((kFLASH_SwapStateComplete == returnInfo.flashSwapState) && (kFLASH_SwapFunctionOptionEnable == option))); return returnCode; } @@ -1750,6 +2227,8 @@ status_t FLASH_ProgramPartition(flash_config_t *config, kFCCOBx[0] = BYTES_JOIN_TO_WORD_1_2_1(FTFx_PROGRAM_PARTITION, 0xFFFFU, option); kFCCOBx[1] = BYTES_JOIN_TO_WORD_1_1_2(eepromDataSizeCode, flexnvmPartitionCode, 0xFFFFU); + flash_cache_clear_process(config, kFLASH_CacheClearProcessPre); + /* calling flash command sequence function to execute the command */ returnCode = flash_command_sequence(config); @@ -1766,31 +2245,70 @@ status_t FLASH_ProgramPartition(flash_config_t *config, } #endif /* FSL_FEATURE_FLASH_HAS_PROGRAM_PARTITION_CMD */ -status_t FLASH_PflashSetProtection(flash_config_t *config, uint32_t protectStatus) +status_t FLASH_PflashSetProtection(flash_config_t *config, pflash_protection_status_t *protectStatus) { if (config == NULL) { return kStatus_FLASH_InvalidArgument; } - *kFPROT = protectStatus; - - if (protectStatus != *kFPROT) +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER + if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash) { - return kStatus_FLASH_CommandFailure; + *kFPROTSL = protectStatus->valueLow32b.prots16b.protsl; + if (protectStatus->valueLow32b.prots16b.protsl != *kFPROTSL) + { + return kStatus_FLASH_CommandFailure; + } + + *kFPROTSH = protectStatus->valueLow32b.prots16b.protsh; + if (protectStatus->valueLow32b.prots16b.protsh != *kFPROTSH) + { + return kStatus_FLASH_CommandFailure; + } + } + else +#endif + { + *kFPROTL = protectStatus->valueLow32b.protl32b; + if (protectStatus->valueLow32b.protl32b != *kFPROTL) + { + return kStatus_FLASH_CommandFailure; + } + +#if defined(FTFx_FPROT_HIGH_REG) + *kFPROTH = protectStatus->valueHigh32b.proth32b; + if (protectStatus->valueHigh32b.proth32b != *kFPROTH) + { + return kStatus_FLASH_CommandFailure; + } +#endif } return kStatus_FLASH_Success; } -status_t FLASH_PflashGetProtection(flash_config_t *config, uint32_t *protectStatus) +status_t FLASH_PflashGetProtection(flash_config_t *config, pflash_protection_status_t *protectStatus) { if ((config == NULL) || (protectStatus == NULL)) { return kStatus_FLASH_InvalidArgument; } - *protectStatus = *kFPROT; +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER + if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash) + { + protectStatus->valueLow32b.prots16b.protsl = *kFPROTSL; + protectStatus->valueLow32b.prots16b.protsh = *kFPROTSH; + } + else +#endif + { + protectStatus->valueLow32b.protl32b = *kFPROTL; +#if defined(FTFx_FPROT_HIGH_REG) + protectStatus->valueHigh32b.proth32b = *kFPROTH; +#endif + } return kStatus_FLASH_Success; } @@ -1881,70 +2399,215 @@ status_t FLASH_EepromGetProtection(flash_config_t *config, uint8_t *protectStatu } #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ -#if FLASH_DRIVER_IS_FLASH_RESIDENT -/*! - * @brief Run flash command - * - * This function should be copied to RAM for execution to make sure that code works - * properly even flash cache is disabled. - * It is for flash-resident bootloader only, not technically required for ROM or - * flashloader (RAM-resident bootloader). - */ -void flash_run_command(FTFx_REG_ACCESS_TYPE ftfx_fstat) +status_t FLASH_PflashSetPrefetchSpeculation(flash_prefetch_speculation_status_t *speculationStatus) { - /* clear CCIF bit */ - *ftfx_fstat = FTFx_FSTAT_CCIF_MASK; - - /* Check CCIF bit of the flash status register, wait till it is set. - * IP team indicates that this loop will always complete. */ - while (!((*ftfx_fstat) & FTFx_FSTAT_CCIF_MASK)) +#if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM { - } -} - -/*! - * @brief Be used for determining the size of flash_run_command() - * - * This function must be defined that lexically follows flash_run_command(), - * so we can determine the size of flash_run_command() at runtime and not worry - * about toolchain or code generation differences. - */ -void flash_run_command_end(void) -{ -} - -/*! - * @brief Copy flash_run_command() to RAM - * - * This function copys the memory between flash_run_command() and flash_run_command_end() - * into the buffer which is also means that copying flash_run_command() to RAM. - */ -static void copy_flash_run_command(uint8_t *flashRunCommand) -{ - /* Calculate the valid length of flash_run_command() memory. - * Set max size(64 bytes) as default function size, in case some compiler allocates - * flash_run_command_end ahead of flash_run_command. */ - uint32_t funcLength = kFLASH_executeInRamFunctionMaxSize; - uint32_t flash_run_command_start_addr = (uint32_t)flash_run_command & (~1U); - uint32_t flash_run_command_end_addr = (uint32_t)flash_run_command_end & (~1U); - if (flash_run_command_end_addr > flash_run_command_start_addr) - { - funcLength = flash_run_command_end_addr - flash_run_command_start_addr; - - assert(funcLength <= kFLASH_executeInRamFunctionMaxSize); - - /* In case some compiler allocates other function in the middle of flash_run_command - * and flash_run_command_end. */ - if (funcLength > kFLASH_executeInRamFunctionMaxSize) + FTFx_REG32_ACCESS_TYPE regBase; +#if defined(MCM) + regBase = (FTFx_REG32_ACCESS_TYPE)&MCM->PLACR; +#elif defined(MCM0) + regBase = (FTFx_REG32_ACCESS_TYPE)&MCM0->PLACR; +#endif + if (speculationStatus->instructionOption == kFLASH_prefetchSpeculationOptionDisable) { - funcLength = kFLASH_executeInRamFunctionMaxSize; + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { + return kStatus_FLASH_InvalidSpeculationOption; + } + else + { + *regBase |= MCM_PLACR_DFCS_MASK; + } + } + else + { + *regBase &= ~MCM_PLACR_DFCS_MASK; + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { + *regBase |= MCM_PLACR_EFDS_MASK; + } + else + { + *regBase &= ~MCM_PLACR_EFDS_MASK; + } } } +#elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC + { + FTFx_REG32_ACCESS_TYPE regBase; + uint32_t b0dpeMask, b0ipeMask; +#if defined(FMC_PFB01CR_B0DPE_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR; + b0dpeMask = FMC_PFB01CR_B0DPE_MASK; + b0ipeMask = FMC_PFB01CR_B0IPE_MASK; +#elif defined(FMC_PFB0CR_B0DPE_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR; + b0dpeMask = FMC_PFB0CR_B0DPE_MASK; + b0ipeMask = FMC_PFB0CR_B0IPE_MASK; +#endif + if (speculationStatus->instructionOption == kFLASH_prefetchSpeculationOptionEnable) + { + *regBase |= b0ipeMask; + } + else + { + *regBase &= ~b0ipeMask; + } + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { + *regBase |= b0dpeMask; + } + else + { + *regBase &= ~b0dpeMask; + } + +/* Invalidate Prefetch Speculation Buffer */ +#if defined(FMC_PFB01CR_S_INV_MASK) + FMC->PFB01CR |= FMC_PFB01CR_S_INV_MASK; +#elif defined(FMC_PFB01CR_S_B_INV_MASK) + FMC->PFB01CR |= FMC_PFB01CR_S_B_INV_MASK; +#elif defined(FMC_PFB0CR_S_INV_MASK) + FMC->PFB0CR |= FMC_PFB0CR_S_INV_MASK; +#elif defined(FMC_PFB0CR_S_B_INV_MASK) + FMC->PFB0CR |= FMC_PFB0CR_S_B_INV_MASK; +#endif + } +#elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM + { + FTFx_REG32_ACCESS_TYPE regBase; + uint32_t flashSpeculationMask, dataPrefetchMask; + regBase = (FTFx_REG32_ACCESS_TYPE)&MSCM->OCMDR[0]; + flashSpeculationMask = MSCM_OCMDR_OCMC1_DFCS_MASK; + dataPrefetchMask = MSCM_OCMDR_OCMC1_DFDS_MASK; + + if (speculationStatus->instructionOption == kFLASH_prefetchSpeculationOptionDisable) + { + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { + return kStatus_FLASH_InvalidSpeculationOption; + } + else + { + *regBase |= flashSpeculationMask; + } + } + else + { + *regBase &= ~flashSpeculationMask; + if (speculationStatus->dataOption == kFLASH_prefetchSpeculationOptionEnable) + { + *regBase &= ~dataPrefetchMask; + } + else + { + *regBase |= dataPrefetchMask; + } + } + } +#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ + + return kStatus_FLASH_Success; +} + +status_t FLASH_PflashGetPrefetchSpeculation(flash_prefetch_speculation_status_t *speculationStatus) +{ + memset(speculationStatus, 0, sizeof(flash_prefetch_speculation_status_t)); + + /* Assuming that all speculation options are enabled. */ + speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionEnable; + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionEnable; + +#if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MCM + { + uint32_t value; +#if defined(MCM) + value = MCM->PLACR; +#elif defined(MCM0) + value = MCM0->PLACR; +#endif + if (value & MCM_PLACR_DFCS_MASK) + { + /* Speculation buffer is off. */ + speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionDisable; + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + else + { + /* Speculation buffer is on for instruction. */ + if (!(value & MCM_PLACR_EFDS_MASK)) + { + /* Speculation buffer is off for data. */ + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + } + } +#elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC + { + uint32_t value; + uint32_t b0dpeMask, b0ipeMask; +#if defined(FMC_PFB01CR_B0DPE_MASK) + value = FMC->PFB01CR; + b0dpeMask = FMC_PFB01CR_B0DPE_MASK; + b0ipeMask = FMC_PFB01CR_B0IPE_MASK; +#elif defined(FMC_PFB0CR_B0DPE_MASK) + value = FMC->PFB0CR; + b0dpeMask = FMC_PFB0CR_B0DPE_MASK; + b0ipeMask = FMC_PFB0CR_B0IPE_MASK; +#endif + if (!(value & b0dpeMask)) + { + /* Do not prefetch in response to data references. */ + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + if (!(value & b0ipeMask)) + { + /* Do not prefetch in response to instruction fetches. */ + speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionDisable; + } + } +#elif FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM + { + uint32_t value; + uint32_t flashSpeculationMask, dataPrefetchMask; + value = MSCM->OCMDR[0]; + flashSpeculationMask = MSCM_OCMDR_OCMC1_DFCS_MASK; + dataPrefetchMask = MSCM_OCMDR_OCMC1_DFDS_MASK; + + if (value & flashSpeculationMask) + { + /* Speculation buffer is off. */ + speculationStatus->instructionOption = kFLASH_prefetchSpeculationOptionDisable; + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + else + { + /* Speculation buffer is on for instruction. */ + if (value & dataPrefetchMask) + { + /* Speculation buffer is off for data. */ + speculationStatus->dataOption = kFLASH_prefetchSpeculationOptionDisable; + } + } + } +#endif + + return kStatus_FLASH_Success; +} + +#if FLASH_DRIVER_IS_FLASH_RESIDENT +/*! + * @brief Copy PIC of flash_run_command() to RAM + */ +static void copy_flash_run_command(uint32_t *flashRunCommand) +{ + assert(sizeof(s_flashRunCommandFunctionCode) <= (kFLASH_ExecuteInRamFunctionMaxSizeInWords * 4)); /* Since the value of ARM function pointer is always odd, but the real start address - * of function memory should be even, that's why -1 and +1 operation exist. */ - memcpy((void *)flashRunCommand, (void *)flash_run_command_start_addr, funcLength); - callFlashRunCommand = (void (*)(FTFx_REG_ACCESS_TYPE ftfx_fstat))((uint32_t)flashRunCommand + 1); + * of function memory should be even, that's why +1 operation exist. */ + memcpy((void *)flashRunCommand, (void *)s_flashRunCommandFunctionCode, sizeof(s_flashRunCommandFunctionCode)); + callFlashRunCommand = (void (*)(FTFx_REG8_ACCESS_TYPE ftfx_fstat))((uint32_t)flashRunCommand + 1); } #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ @@ -1973,7 +2636,7 @@ static status_t flash_command_sequence(flash_config_t *config) /* We pass the ftfx_fstat address as a parameter to flash_run_comamnd() instead of using * pre-processed MICRO sentences or operating global variable in flash_run_comamnd() * to make sure that flash_run_command() will be compiled into position-independent code (PIC). */ - callFlashRunCommand((FTFx_REG_ACCESS_TYPE)(&FTFx->FSTAT)); + callFlashRunCommand((FTFx_REG8_ACCESS_TYPE)(&FTFx->FSTAT)); #else /* clear RDCOLERR & ACCERR & FPVIOL flag in flash status register */ FTFx->FSTAT = FTFx_FSTAT_RDCOLERR_MASK | FTFx_FSTAT_ACCERR_MASK | FTFx_FSTAT_FPVIOL_MASK; @@ -2015,100 +2678,173 @@ static status_t flash_command_sequence(flash_config_t *config) #if FLASH_DRIVER_IS_FLASH_RESIDENT /*! - * @brief Run flash cache clear command + * @brief Copy PIC of flash_common_bit_operation() to RAM * - * This function should be copied to RAM for execution to make sure that code works - * properly even flash cache is disabled. - * It is for flash-resident bootloader only, not technically required for ROM or - * flashloader (RAM-resident bootloader). */ -void flash_cache_clear_command(FTFx_REG32_ACCESS_TYPE ftfx_reg) +static void copy_flash_common_bit_operation(uint32_t *flashCommonBitOperation) { -#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS - *ftfx_reg |= MCM_PLACR_CFCC_MASK; -#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS -#if defined(FMC_PFB01CR_CINV_WAY_MASK) - *ftfx_reg = (*ftfx_reg & ~FMC_PFB01CR_CINV_WAY_MASK) | FMC_PFB01CR_CINV_WAY(~0); -#else - *ftfx_reg = (*ftfx_reg & ~FMC_PFB0CR_CINV_WAY_MASK) | FMC_PFB0CR_CINV_WAY(~0); -#endif -#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS - *ftfx_reg |= MSCM_OCMDR_OCMC1(2); - *ftfx_reg |= MSCM_OCMDR_OCMC1(1); -#else -/* #error "Unknown flash cache controller" */ -#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ - /* Memory barriers for good measure. - * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ - __ISB(); - __DSB(); -} - -/*! - * @brief Be used for determining the size of flash_cache_clear_command() - * - * This function must be defined that lexically follows flash_cache_clear_command(), - * so we can determine the size of flash_cache_clear_command() at runtime and not worry - * about toolchain or code generation differences. - */ -void flash_cache_clear_command_end(void) -{ -} - -/*! - * @brief Copy flash_cache_clear_command() to RAM - * - * This function copys the memory between flash_cache_clear_command() and flash_cache_clear_command_end() - * into the buffer which is also means that copying flash_cache_clear_command() to RAM. - */ -static void copy_flash_cache_clear_command(uint8_t *flashCacheClearCommand) -{ - /* Calculate the valid length of flash_cache_clear_command() memory. - * Set max size(64 bytes) as default function size, in case some compiler allocates - * flash_cache_clear_command_end ahead of flash_cache_clear_command. */ - uint32_t funcLength = kFLASH_executeInRamFunctionMaxSize; - uint32_t flash_cache_clear_command_start_addr = (uint32_t)flash_cache_clear_command & (~1U); - uint32_t flash_cache_clear_command_end_addr = (uint32_t)flash_cache_clear_command_end & (~1U); - if (flash_cache_clear_command_end_addr > flash_cache_clear_command_start_addr) - { - funcLength = flash_cache_clear_command_end_addr - flash_cache_clear_command_start_addr; - - assert(funcLength <= kFLASH_executeInRamFunctionMaxSize); - - /* In case some compiler allocates other function in the middle of flash_cache_clear_command - * and flash_cache_clear_command_end. */ - if (funcLength > kFLASH_executeInRamFunctionMaxSize) - { - funcLength = kFLASH_executeInRamFunctionMaxSize; - } - } + assert(sizeof(s_flashCommonBitOperationFunctionCode) <= (kFLASH_ExecuteInRamFunctionMaxSizeInWords * 4)); /* Since the value of ARM function pointer is always odd, but the real start address - * of function memory should be even, that's why -1 and +1 operation exist. */ - memcpy((void *)flashCacheClearCommand, (void *)flash_cache_clear_command_start_addr, funcLength); - callFlashCacheClearCommand = (void (*)(FTFx_REG32_ACCESS_TYPE ftfx_reg))((uint32_t)flashCacheClearCommand + 1); + * of function memory should be even, that's why +1 operation exist. */ + memcpy((void *)flashCommonBitOperation, (void *)s_flashCommonBitOperationFunctionCode, + sizeof(s_flashCommonBitOperationFunctionCode)); + callFlashCommonBitOperation = (void (*)(FTFx_REG32_ACCESS_TYPE base, uint32_t bitMask, uint32_t bitShift, + uint32_t bitValue))((uint32_t)flashCommonBitOperation + 1); + /* Workround for some devices which doesn't need this function */ + callFlashCommonBitOperation((FTFx_REG32_ACCESS_TYPE)0, 0, 0, 0); } #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ +#if FLASH_CACHE_IS_CONTROLLED_BY_MCM +/*! @brief Performs the cache clear to the flash by MCM.*/ +void mcm_flash_cache_clear(flash_config_t *config) +{ + FTFx_REG32_ACCESS_TYPE regBase = (FTFx_REG32_ACCESS_TYPE)&MCM0_CACHE_REG; + +#if defined(MCM0) && defined(MCM1) + if (config->FlashCacheControllerIndex == (uint8_t)kFLASH_CacheControllerIndexForCore1) + { + regBase = (FTFx_REG32_ACCESS_TYPE)&MCM1_CACHE_REG; + } +#endif + +#if FLASH_DRIVER_IS_FLASH_RESIDENT + callFlashCommonBitOperation(regBase, MCM_CACHE_CLEAR_MASK, MCM_CACHE_CLEAR_SHIFT, 1U); +#else /* !FLASH_DRIVER_IS_FLASH_RESIDENT */ + *regBase |= MCM_CACHE_CLEAR_MASK; + + /* Memory barriers for good measure. + * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ + __ISB(); + __DSB(); +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ +} +#endif /* FLASH_CACHE_IS_CONTROLLED_BY_MCM */ + +#if FLASH_CACHE_IS_CONTROLLED_BY_FMC +/*! @brief Performs the cache clear to the flash by FMC.*/ +void fmc_flash_cache_clear(void) +{ +#if FLASH_DRIVER_IS_FLASH_RESIDENT + FTFx_REG32_ACCESS_TYPE regBase = (FTFx_REG32_ACCESS_TYPE)0; +#if defined(FMC_PFB01CR_CINV_WAY_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR; + callFlashCommonBitOperation(regBase, FMC_PFB01CR_CINV_WAY_MASK, FMC_PFB01CR_CINV_WAY_SHIFT, 0xFU); +#else + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR; + callFlashCommonBitOperation(regBase, FMC_PFB0CR_CINV_WAY_MASK, FMC_PFB0CR_CINV_WAY_SHIFT, 0xFU); +#endif +#else /* !FLASH_DRIVER_IS_FLASH_RESIDENT */ +#if defined(FMC_PFB01CR_CINV_WAY_MASK) + FMC->PFB01CR = (FMC->PFB01CR & ~FMC_PFB01CR_CINV_WAY_MASK) | FMC_PFB01CR_CINV_WAY(~0); +#else + FMC->PFB0CR = (FMC->PFB0CR & ~FMC_PFB0CR_CINV_WAY_MASK) | FMC_PFB0CR_CINV_WAY(~0); +#endif + /* Memory barriers for good measure. + * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ + __ISB(); + __DSB(); +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ +} +#endif /* FLASH_CACHE_IS_CONTROLLED_BY_FMC */ + +#if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM +/*! @brief Performs the prefetch speculation buffer clear to the flash by MSCM.*/ +void mscm_flash_prefetch_speculation_enable(bool enable) +{ + uint8_t setValue; + if (enable) + { + setValue = 0x0U; + } + else + { + setValue = 0x3U; + } + +/* The OCMDR[0] is always used to prefetch main Pflash*/ +/* For device with FlexNVM support, the OCMDR[1] is used to prefetch Dflash. + * For device with secondary flash support, the OCMDR[1] is used to prefetch secondary Pflash. */ +#if FLASH_DRIVER_IS_FLASH_RESIDENT + callFlashCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&MSCM->OCMDR[0], MSCM_SPECULATION_DISABLE_MASK, + MSCM_SPECULATION_DISABLE_SHIFT, setValue); +#if FLASH_SSD_IS_FLEXNVM_ENABLED || BL_HAS_SECONDARY_INTERNAL_FLASH + callFlashCommonBitOperation((FTFx_REG32_ACCESS_TYPE)&MSCM->OCMDR[1], MSCM_SPECULATION_DISABLE_MASK, + MSCM_SPECULATION_DISABLE_SHIFT, setValue); +#endif +#else /* !FLASH_DRIVER_IS_FLASH_RESIDENT */ + MSCM->OCMDR[0] |= MSCM_SPECULATION_DISABLE(setValue); + + /* Memory barriers for good measure. + * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ + __ISB(); + __DSB(); +#if FLASH_SSD_IS_FLEXNVM_ENABLED || BL_HAS_SECONDARY_INTERNAL_FLASH + MSCM->OCMDR[1] |= MSCM_SPECULATION_DISABLE(setValue); + + /* Each cahce clear instaruction should be followed by below code*/ + __ISB(); + __DSB(); +#endif + +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ +} +#endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM */ + +#if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC +/*! @brief Performs the prefetch speculation buffer clear to the flash by FMC.*/ +void fmc_flash_prefetch_speculation_clear(void) +{ +#if FLASH_DRIVER_IS_FLASH_RESIDENT + FTFx_REG32_ACCESS_TYPE regBase = (FTFx_REG32_ACCESS_TYPE)0; +#if defined(FMC_PFB01CR_S_INV_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR; + callFlashCommonBitOperation(regBase, FMC_PFB01CR_S_INV_MASK, FMC_PFB01CR_S_INV_SHIFT, 1U); +#elif defined(FMC_PFB01CR_S_B_INV_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR; + callFlashCommonBitOperation(regBase, FMC_PFB01CR_S_B_INV_MASK, FMC_PFB01CR_S_B_INV_SHIFT, 1U); +#elif defined(FMC_PFB0CR_S_INV_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR; + callFlashCommonBitOperation(regBase, FMC_PFB0CR_S_INV_MASK, FMC_PFB0CR_S_INV_SHIFT, 1U); +#elif defined(FMC_PFB0CR_S_B_INV_MASK) + regBase = (FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR; + callFlashCommonBitOperation(regBase, FMC_PFB0CR_S_B_INV_MASK, FMC_PFB0CR_S_B_INV_SHIFT, 1U); +#endif +#else /* !FLASH_DRIVER_IS_FLASH_RESIDENT */ +#if defined(FMC_PFB01CR_S_INV_MASK) + FMC->PFB01CR |= FMC_PFB01CR_S_INV_MASK; +#elif defined(FMC_PFB01CR_S_B_INV_MASK) + FMC->PFB01CR |= FMC_PFB01CR_S_B_INV_MASK; +#elif defined(FMC_PFB0CR_S_INV_MASK) + FMC->PFB0CR |= FMC_PFB0CR_S_INV_MASK; +#elif defined(FMC_PFB0CR_S_B_INV_MASK) + FMC->PFB0CR |= FMC_PFB0CR_S_B_INV_MASK; +#endif + /* Memory barriers for good measure. + * All Cache, Branch predictor and TLB maintenance operations before this instruction complete */ + __ISB(); + __DSB(); +#endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ +} +#endif /* FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC */ + /*! * @brief Flash Cache Clear * - * This function is used to perform the cache clear to the flash. + * This function is used to perform the cache and prefetch speculation clear to the flash. */ -#if (defined(__GNUC__)) -/* #pragma GCC push_options */ -/* #pragma GCC optimize("O0") */ -void __attribute__((optimize("O0"))) flash_cache_clear(flash_config_t *config) -#else -#if (defined(__ICCARM__)) -#pragma optimize = none -#endif -#if (defined(__CC_ARM)) -#pragma push -#pragma O0 -#endif void flash_cache_clear(flash_config_t *config) -#endif +{ + flash_cache_clear_process(config, kFLASH_CacheClearProcessPost); +} + +/*! + * @brief Flash Cache Clear Process + * + * This function is used to perform the cache and prefetch speculation clear process to the flash. + */ +static void flash_cache_clear_process(flash_config_t *config, flash_cache_clear_process_t process) { #if FLASH_DRIVER_IS_FLASH_RESIDENT status_t returnCode = flash_check_execute_in_ram_function_info(config); @@ -2116,66 +2852,33 @@ void flash_cache_clear(flash_config_t *config) { return; } - -/* We pass the ftfx register address as a parameter to flash_cache_clear_comamnd() instead of using - * pre-processed MACROs or a global variable in flash_cache_clear_comamnd() - * to make sure that flash_cache_clear_command() will be compiled into position-independent code (PIC). */ -#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS -#if defined(MCM) - callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MCM->PLACR); -#endif -#if defined(MCM0) - callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MCM0->PLACR); -#endif -#if defined(MCM1) - callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MCM1->PLACR); -#endif -#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS -#if defined(FMC_PFB01CR_CINV_WAY_MASK) - callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&FMC->PFB01CR); -#else - callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&FMC->PFB0CR); -#endif -#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS - callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)&MSCM->OCMDR[0]); -#else - /* #error "Unknown flash cache controller" */ - /* meaningless code, just a workaround to solve warning*/ - callFlashCacheClearCommand((FTFx_REG32_ACCESS_TYPE)0); -#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ - -#else - -#if defined(FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MCM_FLASH_CACHE_CONTROLS -#if defined(MCM) - MCM->PLACR |= MCM_PLACR_CFCC_MASK; -#endif -#if defined(MCM0) - MCM0->PLACR |= MCM_PLACR_CFCC_MASK; -#endif -#if defined(MCM1) - MCM1->PLACR |= MCM_PLACR_CFCC_MASK; -#endif -#elif defined(FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_FMC_FLASH_CACHE_CONTROLS -#if defined(FMC_PFB01CR_CINV_WAY_MASK) - FMC->PFB01CR = (FMC->PFB01CR & ~FMC_PFB01CR_CINV_WAY_MASK) | FMC_PFB01CR_CINV_WAY(~0); -#else - FMC->PFB0CR = (FMC->PFB0CR & ~FMC_PFB0CR_CINV_WAY_MASK) | FMC_PFB0CR_CINV_WAY(~0); -#endif -#elif defined(FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS) && FSL_FEATURE_FLASH_HAS_MSCM_FLASH_CACHE_CONTROLS - MSCM->OCMDR[0] |= MSCM_OCMDR_OCMC1(2); - MSCM->OCMDR[0] |= MSCM_OCMDR_OCMC1(1); -#else -/* #error "Unknown flash cache controller" */ -#endif /* FSL_FEATURE_FTFx_MCM_FLASH_CACHE_CONTROLS */ #endif /* FLASH_DRIVER_IS_FLASH_RESIDENT */ + + /* We pass the ftfx register address as a parameter to flash_common_bit_operation() instead of using + * pre-processed MACROs or a global variable in flash_common_bit_operation() + * to make sure that flash_common_bit_operation() will be compiled into position-independent code (PIC). */ + if (process == kFLASH_CacheClearProcessPost) + { +#if FLASH_CACHE_IS_CONTROLLED_BY_MCM + mcm_flash_cache_clear(config); +#endif +#if FLASH_CACHE_IS_CONTROLLED_BY_FMC + fmc_flash_cache_clear(); +#endif +#if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM + mscm_flash_prefetch_speculation_enable(true); +#endif +#if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_FMC + fmc_flash_prefetch_speculation_clear(); +#endif + } + if (process == kFLASH_CacheClearProcessPre) + { +#if FLASH_PREFETCH_SPECULATION_IS_CONTROLLED_BY_MSCM + mscm_flash_prefetch_speculation_enable(false); +#endif + } } -#if (defined(__CC_ARM)) -#pragma pop -#endif -#if (defined(__GNUC__)) -/* #pragma GCC pop_options */ -#endif #if FLASH_DRIVER_IS_FLASH_RESIDENT /*! @brief Check whether flash execute-in-ram functions are ready */ @@ -2191,7 +2894,7 @@ static status_t flash_check_execute_in_ram_function_info(flash_config_t *config) flashExecuteInRamFunctionInfo = (flash_execute_in_ram_function_config_t *)config->flashExecuteInRamFunctionInfo; if ((config->flashExecuteInRamFunctionInfo) && - (kFLASH_executeInRamFunctionTotalNum == flashExecuteInRamFunctionInfo->activeFunctionCount)) + (kFLASH_ExecuteInRamFunctionTotalNum == flashExecuteInRamFunctionInfo->activeFunctionCount)) { return kStatus_FLASH_Success; } @@ -2217,21 +2920,19 @@ static status_t flash_check_range(flash_config_t *config, return kStatus_FLASH_AlignmentError; } -/* check for valid range of the target addresses */ -#if !FLASH_SSD_IS_FLEXNVM_ENABLED - if ((startAddress < config->PFlashBlockBase) || - ((startAddress + lengthInBytes) > (config->PFlashBlockBase + config->PFlashTotalSize))) -#else - if (!(((startAddress >= config->PFlashBlockBase) && - ((startAddress + lengthInBytes) <= (config->PFlashBlockBase + config->PFlashTotalSize))) || - ((startAddress >= config->DFlashBlockBase) && - ((startAddress + lengthInBytes) <= (config->DFlashBlockBase + config->DFlashTotalSize))))) + /* check for valid range of the target addresses */ + if ( +#if FLASH_SSD_IS_FLEXNVM_ENABLED + ((startAddress >= config->DFlashBlockBase) && + ((startAddress + lengthInBytes) <= (config->DFlashBlockBase + config->DFlashTotalSize))) || #endif + ((startAddress >= config->PFlashBlockBase) && + ((startAddress + lengthInBytes) <= (config->PFlashBlockBase + config->PFlashTotalSize)))) { - return kStatus_FLASH_AddressError; + return kStatus_FLASH_Success; } - return kStatus_FLASH_Success; + return kStatus_FLASH_AddressError; } /*! @brief Gets the right address, sector and block size of current flash type which is indicated by address.*/ @@ -2250,6 +2951,8 @@ static status_t flash_get_matched_operation_info(flash_config_t *config, #if FLASH_SSD_IS_FLEXNVM_ENABLED if ((address >= config->DFlashBlockBase) && (address <= (config->DFlashBlockBase + config->DFlashTotalSize))) { + /* When required by the command, address bit 23 selects between program flash memory + * (=0) and data flash memory (=1).*/ info->convertedAddress = address - config->DFlashBlockBase + 0x800000U; info->activeSectorSize = FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_SECTOR_SIZE; info->activeBlockSize = config->DFlashTotalSize / FSL_FEATURE_FLASH_FLEX_NVM_BLOCK_COUNT; @@ -2263,11 +2966,25 @@ static status_t flash_get_matched_operation_info(flash_config_t *config, else #endif /* FLASH_SSD_IS_FLEXNVM_ENABLED */ { - info->convertedAddress = address; + info->convertedAddress = address - config->PFlashBlockBase; info->activeSectorSize = config->PFlashSectorSize; info->activeBlockSize = config->PFlashTotalSize / config->PFlashBlockCount; +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED + if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash) + { +#if FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER || FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER + /* When required by the command, address bit 23 selects between main flash memory + * (=0) and secondary flash memory (=1).*/ + info->convertedAddress += 0x800000U; +#endif + info->blockWriteUnitSize = FSL_FEATURE_FLASH_PFLASH_1_BLOCK_WRITE_UNIT_SIZE; + } + else +#endif /* FLASH_SSD_IS_SECONDARY_FLASH_ENABLED */ + { + info->blockWriteUnitSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE; + } - info->blockWriteUnitSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_WRITE_UNIT_SIZE; info->sectorCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_SECTOR_CMD_ADDRESS_ALIGMENT; info->sectionCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_SECTION_CMD_ADDRESS_ALIGMENT; info->resourceCmdAddressAligment = FSL_FEATURE_FLASH_PFLASH_RESOURCE_CMD_ADDRESS_ALIGMENT; @@ -2281,7 +2998,7 @@ static status_t flash_get_matched_operation_info(flash_config_t *config, static status_t flash_check_user_key(uint32_t key) { /* Validate the user key */ - if (key != kFLASH_apiEraseKey) + if (key != kFLASH_ApiEraseKey) { return kStatus_FLASH_EraseKeyError; } @@ -2307,13 +3024,17 @@ static status_t flash_update_flexnvm_memory_partition_status(flash_config_t *con return kStatus_FLASH_InvalidArgument; } +#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD /* Get FlexNVM memory partition info from data flash IFR */ returnCode = FLASH_ReadResource(config, DFLASH_IFR_READRESOURCE_START_ADDRESS, (uint32_t *)&dataIFRReadOut, - sizeof(dataIFRReadOut), kFLASH_resourceOptionFlashIfr); + sizeof(dataIFRReadOut), kFLASH_ResourceOptionFlashIfr); if (returnCode != kStatus_FLASH_Success) { return kStatus_FLASH_PartitionStatusUpdateFailure; } +#else +#error "Cannot get FlexNVM memory partition info" +#endif /* Fill out partitioned EEPROM size */ dataIFRReadOut.EEPROMDataSetSize &= 0x0FU; @@ -2515,27 +3236,27 @@ static status_t flash_check_resource_range(uint32_t start, status = kStatus_FLASH_Success; maxReadbleAddress = start + lengthInBytes - 1; - if (option == kFLASH_resourceOptionVersionId) + if (option == kFLASH_ResourceOptionVersionId) { - if ((start != kFLASH_resourceRangeVersionIdStart) || - ((start + lengthInBytes - 1) != kFLASH_resourceRangeVersionIdEnd)) + if ((start != kFLASH_ResourceRangeVersionIdStart) || + ((start + lengthInBytes - 1) != kFLASH_ResourceRangeVersionIdEnd)) { status = kStatus_FLASH_InvalidArgument; } } - else if (option == kFLASH_resourceOptionFlashIfr) + else if (option == kFLASH_ResourceOptionFlashIfr) { - if (maxReadbleAddress < kFLASH_resourceRangePflashIfrSizeInBytes) + if (maxReadbleAddress < kFLASH_ResourceRangePflashIfrSizeInBytes) { } #if defined(FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP) && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP - else if ((start >= kFLASH_resourceRangePflashSwapIfrStart) && - (maxReadbleAddress <= kFLASH_resourceRangePflashSwapIfrEnd)) + else if ((start >= kFLASH_ResourceRangePflashSwapIfrStart) && + (maxReadbleAddress <= kFLASH_ResourceRangePflashSwapIfrEnd)) { } #endif /* FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP */ - else if ((start >= kFLASH_resourceRangeDflashIfrStart) && - (maxReadbleAddress <= kFLASH_resourceRangeDflashIfrEnd)) + else if ((start >= kFLASH_ResourceRangeDflashIfrStart) && + (maxReadbleAddress <= kFLASH_ResourceRangeDflashIfrEnd)) { } else @@ -2556,9 +3277,9 @@ static status_t flash_check_resource_range(uint32_t start, /*! @brief Validates the gived swap control option.*/ static status_t flash_check_swap_control_option(flash_swap_control_option_t option) { - if ((option == kFLASH_swapControlOptionIntializeSystem) || (option == kFLASH_swapControlOptionSetInUpdateState) || - (option == kFLASH_swapControlOptionSetInCompleteState) || (option == kFLASH_swapControlOptionReportStatus) || - (option == kFLASH_swapControlOptionDisableSystem)) + if ((option == kFLASH_SwapControlOptionIntializeSystem) || (option == kFLASH_SwapControlOptionSetInUpdateState) || + (option == kFLASH_SwapControlOptionSetInCompleteState) || (option == kFLASH_SwapControlOptionReportStatus) || + (option == kFLASH_SwapControlOptionDisableSystem)) { return kStatus_FLASH_Success; } @@ -2571,21 +3292,48 @@ static status_t flash_check_swap_control_option(flash_swap_control_option_t opti /*! @brief Validates the gived address to see if it is equal to swap indicator address in pflash swap IFR.*/ static status_t flash_validate_swap_indicator_address(flash_config_t *config, uint32_t address) { - flash_swap_ifr_field_config_t flashSwapIfrField; + flash_swap_ifr_field_data_t flashSwapIfrFieldData; uint32_t swapIndicatorAddress; status_t returnCode; - returnCode = FLASH_ReadResource(config, kFLASH_resourceRangePflashSwapIfrStart, (uint32_t *)&flashSwapIfrField, - sizeof(flash_swap_ifr_field_config_t), kFLASH_resourceOptionFlashIfr); +#if defined(FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD) && FSL_FEATURE_FLASH_HAS_READ_RESOURCE_CMD + returnCode = + FLASH_ReadResource(config, kFLASH_ResourceRangePflashSwapIfrStart, flashSwapIfrFieldData.flashSwapIfrData, + sizeof(flashSwapIfrFieldData.flashSwapIfrData), kFLASH_ResourceOptionFlashIfr); + if (returnCode != kStatus_FLASH_Success) { return returnCode; } +#else + { + /* From RM, the actual info are stored in FCCOB6,7 */ + uint32_t returnValue[2]; + returnCode = FLASH_ReadOnce(config, kFLASH_RecordIndexSwapAddr, returnValue, 4); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + flashSwapIfrFieldData.flashSwapIfrField.swapIndicatorAddress = (uint16_t)returnValue[0]; + returnCode = FLASH_ReadOnce(config, kFLASH_RecordIndexSwapEnable, returnValue, 4); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + flashSwapIfrFieldData.flashSwapIfrField.swapEnableWord = (uint16_t)returnValue[0]; + returnCode = FLASH_ReadOnce(config, kFLASH_RecordIndexSwapDisable, returnValue, 4); + if (returnCode != kStatus_FLASH_Success) + { + return returnCode; + } + flashSwapIfrFieldData.flashSwapIfrField.swapDisableWord = (uint16_t)returnValue[0]; + } +#endif - /* The high 2 byte value of Swap Indicator Address is stored in Program Flash Swap IFR Field, - * the low 4 bit value of Swap Indicator Address is always 4'b0000 */ - swapIndicatorAddress = - (uint32_t)flashSwapIfrField.swapIndicatorAddress * FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT; + /* The high bits value of Swap Indicator Address is stored in Program Flash Swap IFR Field, + * the low severval bit value of Swap Indicator Address is always 1'b0 */ + swapIndicatorAddress = (uint32_t)flashSwapIfrFieldData.flashSwapIfrField.swapIndicatorAddress * + FSL_FEATURE_FLASH_PFLASH_SWAP_CONTROL_CMD_ADDRESS_ALIGMENT; if (address != swapIndicatorAddress) { return kStatus_FLASH_SwapIndicatorAddressError; @@ -2599,8 +3347,8 @@ static status_t flash_validate_swap_indicator_address(flash_config_t *config, ui /*! @brief Validates the gived flexram function option.*/ static inline status_t flasn_check_flexram_function_option_range(flash_flexram_function_option_t option) { - if ((option != kFLASH_flexramFunctionOptionAvailableAsRam) && - (option != kFLASH_flexramFunctionOptionAvailableForEeprom)) + if ((option != kFLASH_FlexramFunctionOptionAvailableAsRam) && + (option != kFLASH_FlexramFunctionOptionAvailableForEeprom)) { return kStatus_FLASH_InvalidArgument; } @@ -2608,3 +3356,77 @@ static inline status_t flasn_check_flexram_function_option_range(flash_flexram_f return kStatus_FLASH_Success; } #endif /* FSL_FEATURE_FLASH_HAS_SET_FLEXRAM_FUNCTION_CMD */ + +/*! @brief Gets the flash protection information (region size, region count).*/ +static status_t flash_get_protection_info(flash_config_t *config, flash_protection_config_t *info) +{ + uint32_t pflashTotalSize; + + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Clean up info Structure*/ + memset(info, 0, sizeof(flash_protection_config_t)); + +/* Note: KW40 has a secondary flash, but it doesn't have independent protection register*/ +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && (!FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER) + pflashTotalSize = FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE + + FSL_FEATURE_FLASH_PFLASH_1_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_1_BLOCK_SIZE; + info->regionBase = FSL_FEATURE_FLASH_PFLASH_START_ADDRESS; +#else + pflashTotalSize = config->PFlashTotalSize; + info->regionBase = config->PFlashBlockBase; +#endif + +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_PROTECTION_REGISTER + if (config->FlashMemoryIndex == (uint8_t)kFLASH_MemoryIndexSecondaryFlash) + { + info->regionCount = FSL_FEATURE_FLASH_PFLASH_1_PROTECTION_REGION_COUNT; + } + else +#endif + { + info->regionCount = FSL_FEATURE_FLASH_PFLASH_PROTECTION_REGION_COUNT; + } + + /* Calculate the size of the flash protection region + * If the flash density is > 32KB, then protection region is 1/32 of total flash density + * Else if flash density is < 32KB, then flash protection region is set to 1KB */ + if (pflashTotalSize > info->regionCount * 1024) + { + info->regionSize = (pflashTotalSize) / info->regionCount; + } + else + { + info->regionSize = 1024; + } + + return kStatus_FLASH_Success; +} + +#if defined(FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL) && FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL +/*! @brief Gets the flash Execute-Only access information (Segment size, Segment count).*/ +static status_t flash_get_access_info(flash_config_t *config, flash_access_config_t *info) +{ + if (config == NULL) + { + return kStatus_FLASH_InvalidArgument; + } + + /* Clean up info Structure*/ + memset(info, 0, sizeof(flash_access_config_t)); + +/* Note: KW40 has a secondary flash, but it doesn't have independent access register*/ +#if FLASH_SSD_IS_SECONDARY_FLASH_ENABLED && (!FLASH_SSD_SECONDARY_FLASH_HAS_ITS_OWN_ACCESS_REGISTER) + info->SegmentBase = FSL_FEATURE_FLASH_PFLASH_START_ADDRESS; +#else + info->SegmentBase = config->PFlashBlockBase; +#endif + info->SegmentSize = config->PFlashAccessSegmentSize; + info->SegmentCount = config->PFlashAccessSegmentCount; + + return kStatus_FLASH_Success; +} +#endif /* FSL_FEATURE_FLASH_HAS_ACCESS_CONTROL */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flash.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flash.h index 63463e03cb..e143cb3e1f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flash.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flash.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2016, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -53,21 +53,21 @@ * @name Flash version * @{ */ -/*! @brief Construct the version number for drivers. */ +/*! @brief Constructs the version number for drivers. */ #if !defined(MAKE_VERSION) #define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) #endif -/*! @brief FLASH driver version for SDK*/ -#define FSL_FLASH_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */ +/*! @brief Flash driver version for SDK*/ +#define FSL_FLASH_DRIVER_VERSION (MAKE_VERSION(2, 3, 1)) /*!< Version 2.3.1. */ -/*! @brief FLASH driver version for ROM*/ +/*! @brief Flash driver version for ROM*/ enum _flash_driver_version_constants { - kFLASH_driverVersionName = 'F', /*!< Flash driver version name.*/ - kFLASH_driverVersionMajor = 2, /*!< Major flash driver version.*/ - kFLASH_driverVersionMinor = 1, /*!< Minor flash driver version.*/ - kFLASH_driverVersionBugfix = 0 /*!< Bugfix for flash driver version.*/ + kFLASH_DriverVersionName = 'F', /*!< Flash driver version name.*/ + kFLASH_DriverVersionMajor = 2, /*!< Major flash driver version.*/ + kFLASH_DriverVersionMinor = 3, /*!< Minor flash driver version.*/ + kFLASH_DriverVersionBugfix = 1 /*!< Bugfix for flash driver version.*/ }; /*@}*/ @@ -75,29 +75,41 @@ enum _flash_driver_version_constants * @name Flash configuration * @{ */ -/*! @brief Whether to support FlexNVM in flash driver */ +/*! @brief Indicates whether to support FlexNVM in the Flash driver */ #if !defined(FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT) -#define FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT 1 /*!< Enable FlexNVM support by default. */ +#define FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT 1 /*!< Enables the FlexNVM support by default. */ #endif -/*! @brief Whether the FlexNVM is enabled in flash driver */ +/*! @brief Indicates whether the FlexNVM is enabled in the Flash driver */ #define FLASH_SSD_IS_FLEXNVM_ENABLED (FLASH_SSD_CONFIG_ENABLE_FLEXNVM_SUPPORT && FSL_FEATURE_FLASH_HAS_FLEX_NVM) +/*! @brief Indicates whether to support Secondary flash in the Flash driver */ +#if !defined(FLASH_SSD_CONFIG_ENABLE_SECONDARY_FLASH_SUPPORT) +#define FLASH_SSD_CONFIG_ENABLE_SECONDARY_FLASH_SUPPORT 1 /*!< Enables the secondary flash support by default. */ +#endif + +/*! @brief Indicates whether the secondary flash is supported in the Flash driver */ +#if defined(FSL_FEATURE_FLASH_HAS_MULTIPLE_FLASH) || defined(FSL_FEATURE_FLASH_PFLASH_1_START_ADDRESS) +#define FLASH_SSD_IS_SECONDARY_FLASH_ENABLED (FLASH_SSD_CONFIG_ENABLE_SECONDARY_FLASH_SUPPORT) +#else +#define FLASH_SSD_IS_SECONDARY_FLASH_ENABLED (0) +#endif + /*! @brief Flash driver location. */ #if !defined(FLASH_DRIVER_IS_FLASH_RESIDENT) #if (!defined(BL_TARGET_ROM) && !defined(BL_TARGET_RAM)) -#define FLASH_DRIVER_IS_FLASH_RESIDENT 1 /*!< Used for flash resident application. */ +#define FLASH_DRIVER_IS_FLASH_RESIDENT 1 /*!< Used for the flash resident application. */ #else -#define FLASH_DRIVER_IS_FLASH_RESIDENT 0 /*!< Used for non-flash resident application. */ +#define FLASH_DRIVER_IS_FLASH_RESIDENT 0 /*!< Used for the non-flash resident application. */ #endif #endif /*! @brief Flash Driver Export option */ #if !defined(FLASH_DRIVER_IS_EXPORTED) #if (defined(BL_TARGET_ROM) || defined(BL_TARGET_FLASH)) -#define FLASH_DRIVER_IS_EXPORTED 1 /*!< Used for ROM bootloader. */ +#define FLASH_DRIVER_IS_EXPORTED 1 /*!< Used for the ROM bootloader. */ #else -#define FLASH_DRIVER_IS_EXPORTED 0 /*!< Used for SDK application. */ +#define FLASH_DRIVER_IS_EXPORTED 0 /*!< Used for the MCUXpresso SDK application. */ #endif #endif /*@}*/ @@ -118,7 +130,7 @@ enum _flash_driver_version_constants #define kStatusGroupFlashDriver 1 #endif -/*! @brief Construct a status code value from a group and code number. */ +/*! @brief Constructs a status code value from a group and a code number. */ #if !defined(MAKE_STATUS) #define MAKE_STATUS(group, code) ((((group)*100) + (code))) #endif @@ -128,37 +140,43 @@ enum _flash_driver_version_constants */ enum _flash_status { - kStatus_FLASH_Success = MAKE_STATUS(kStatusGroupGeneric, 0), /*!< Api is executed successfully*/ + kStatus_FLASH_Success = MAKE_STATUS(kStatusGroupGeneric, 0), /*!< API is executed successfully*/ kStatus_FLASH_InvalidArgument = MAKE_STATUS(kStatusGroupGeneric, 4), /*!< Invalid argument*/ kStatus_FLASH_SizeError = MAKE_STATUS(kStatusGroupFlashDriver, 0), /*!< Error size*/ kStatus_FLASH_AlignmentError = - MAKE_STATUS(kStatusGroupFlashDriver, 1), /*!< Parameter is not aligned with specified baseline*/ + MAKE_STATUS(kStatusGroupFlashDriver, 1), /*!< Parameter is not aligned with the specified baseline*/ kStatus_FLASH_AddressError = MAKE_STATUS(kStatusGroupFlashDriver, 2), /*!< Address is out of range */ kStatus_FLASH_AccessError = - MAKE_STATUS(kStatusGroupFlashDriver, 3), /*!< Invalid instruction codes and out-of bounds addresses */ + MAKE_STATUS(kStatusGroupFlashDriver, 3), /*!< Invalid instruction codes and out-of bound addresses */ kStatus_FLASH_ProtectionViolation = MAKE_STATUS( kStatusGroupFlashDriver, 4), /*!< The program/erase operation is requested to execute on protected areas */ kStatus_FLASH_CommandFailure = MAKE_STATUS(kStatusGroupFlashDriver, 5), /*!< Run-time error during command execution. */ - kStatus_FLASH_UnknownProperty = MAKE_STATUS(kStatusGroupFlashDriver, 6), /*!< Unknown property.*/ - kStatus_FLASH_EraseKeyError = MAKE_STATUS(kStatusGroupFlashDriver, 7), /*!< Api erase key is invalid.*/ - kStatus_FLASH_RegionExecuteOnly = MAKE_STATUS(kStatusGroupFlashDriver, 8), /*!< Current region is execute only.*/ + kStatus_FLASH_UnknownProperty = MAKE_STATUS(kStatusGroupFlashDriver, 6), /*!< Unknown property.*/ + kStatus_FLASH_EraseKeyError = MAKE_STATUS(kStatusGroupFlashDriver, 7), /*!< API erase key is invalid.*/ + kStatus_FLASH_RegionExecuteOnly = + MAKE_STATUS(kStatusGroupFlashDriver, 8), /*!< The current region is execute-only.*/ kStatus_FLASH_ExecuteInRamFunctionNotReady = - MAKE_STATUS(kStatusGroupFlashDriver, 9), /*!< Execute-in-ram function is not available.*/ + MAKE_STATUS(kStatusGroupFlashDriver, 9), /*!< Execute-in-RAM function is not available.*/ kStatus_FLASH_PartitionStatusUpdateFailure = MAKE_STATUS(kStatusGroupFlashDriver, 10), /*!< Failed to update partition status.*/ kStatus_FLASH_SetFlexramAsEepromError = - MAKE_STATUS(kStatusGroupFlashDriver, 11), /*!< Failed to set flexram as eeprom.*/ + MAKE_STATUS(kStatusGroupFlashDriver, 11), /*!< Failed to set FlexRAM as EEPROM.*/ kStatus_FLASH_RecoverFlexramAsRamError = - MAKE_STATUS(kStatusGroupFlashDriver, 12), /*!< Failed to recover flexram as ram.*/ - kStatus_FLASH_SetFlexramAsRamError = MAKE_STATUS(kStatusGroupFlashDriver, 13), /*!< Failed to set flexram as ram.*/ + MAKE_STATUS(kStatusGroupFlashDriver, 12), /*!< Failed to recover FlexRAM as RAM.*/ + kStatus_FLASH_SetFlexramAsRamError = MAKE_STATUS(kStatusGroupFlashDriver, 13), /*!< Failed to set FlexRAM as RAM.*/ kStatus_FLASH_RecoverFlexramAsEepromError = - MAKE_STATUS(kStatusGroupFlashDriver, 14), /*!< Failed to recover flexram as eeprom.*/ - kStatus_FLASH_CommandNotSupported = MAKE_STATUS(kStatusGroupFlashDriver, 15), /*!< Flash api is not supported.*/ + MAKE_STATUS(kStatusGroupFlashDriver, 14), /*!< Failed to recover FlexRAM as EEPROM.*/ + kStatus_FLASH_CommandNotSupported = MAKE_STATUS(kStatusGroupFlashDriver, 15), /*!< Flash API is not supported.*/ kStatus_FLASH_SwapSystemNotInUninitialized = - MAKE_STATUS(kStatusGroupFlashDriver, 16), /*!< Swap system is not in uninitialzed state.*/ + MAKE_STATUS(kStatusGroupFlashDriver, 16), /*!< Swap system is not in an uninitialzed state.*/ kStatus_FLASH_SwapIndicatorAddressError = - MAKE_STATUS(kStatusGroupFlashDriver, 17), /*!< Swap indicator address is invalid.*/ + MAKE_STATUS(kStatusGroupFlashDriver, 17), /*!< The swap indicator address is invalid.*/ + kStatus_FLASH_ReadOnlyProperty = MAKE_STATUS(kStatusGroupFlashDriver, 18), /*!< The flash property is read-only.*/ + kStatus_FLASH_InvalidPropertyValue = + MAKE_STATUS(kStatusGroupFlashDriver, 19), /*!< The flash property value is out of range.*/ + kStatus_FLASH_InvalidSpeculationOption = + MAKE_STATUS(kStatusGroupFlashDriver, 20), /*!< The option of flash prefetch speculation is invalid.*/ }; /*@}*/ @@ -166,13 +184,13 @@ enum _flash_status * @name Flash API key * @{ */ -/*! @brief Construct the four char code for flash driver API key. */ +/*! @brief Constructs the four character code for the Flash driver API key. */ #if !defined(FOUR_CHAR_CODE) #define FOUR_CHAR_CODE(a, b, c, d) (((d) << 24) | ((c) << 16) | ((b) << 8) | ((a))) #endif /*! - * @brief Enumeration for flash driver API keys. + * @brief Enumeration for Flash driver API keys. * * @note The resulting value is built with a byte order such that the string * being readable in expected order when viewed in a hex editor, if the value @@ -180,7 +198,7 @@ enum _flash_status */ enum _flash_driver_api_keys { - kFLASH_apiEraseKey = FOUR_CHAR_CODE('k', 'f', 'e', 'k') /*!< Key value used to validate all flash erase APIs.*/ + kFLASH_ApiEraseKey = FOUR_CHAR_CODE('k', 'f', 'e', 'k') /*!< Key value used to validate all flash erase APIs.*/ }; /*@}*/ @@ -189,10 +207,10 @@ enum _flash_driver_api_keys */ typedef enum _flash_margin_value { - kFLASH_marginValueNormal, /*!< Use the 'normal' read level for 1s.*/ - kFLASH_marginValueUser, /*!< Apply the 'User' margin to the normal read-1 level.*/ - kFLASH_marginValueFactory, /*!< Apply the 'Factory' margin to the normal read-1 level.*/ - kFLASH_marginValueInvalid /*!< Not real margin level, Used to determine the range of valid margin level. */ + kFLASH_MarginValueNormal, /*!< Use the 'normal' read level for 1s.*/ + kFLASH_MarginValueUser, /*!< Apply the 'User' margin to the normal read-1 level.*/ + kFLASH_MarginValueFactory, /*!< Apply the 'Factory' margin to the normal read-1 level.*/ + kFLASH_MarginValueInvalid /*!< Not real margin level, Used to determine the range of valid margin level. */ } flash_margin_value_t; /*! @@ -200,9 +218,9 @@ typedef enum _flash_margin_value */ typedef enum _flash_security_state { - kFLASH_securityStateNotSecure, /*!< Flash is not secure.*/ - kFLASH_securityStateBackdoorEnabled, /*!< Flash backdoor is enabled.*/ - kFLASH_securityStateBackdoorDisabled /*!< Flash backdoor is disabled.*/ + kFLASH_SecurityStateNotSecure, /*!< Flash is not secure.*/ + kFLASH_SecurityStateBackdoorEnabled, /*!< Flash backdoor is enabled.*/ + kFLASH_SecurityStateBackdoorDisabled /*!< Flash backdoor is disabled.*/ } flash_security_state_t; /*! @@ -210,9 +228,9 @@ typedef enum _flash_security_state */ typedef enum _flash_protection_state { - kFLASH_protectionStateUnprotected, /*!< Flash region is not protected.*/ - kFLASH_protectionStateProtected, /*!< Flash region is protected.*/ - kFLASH_protectionStateMixed /*!< Flash is mixed with protected and unprotected region.*/ + kFLASH_ProtectionStateUnprotected, /*!< Flash region is not protected.*/ + kFLASH_ProtectionStateProtected, /*!< Flash region is protected.*/ + kFLASH_ProtectionStateMixed /*!< Flash is mixed with protected and unprotected region.*/ } flash_protection_state_t; /*! @@ -220,9 +238,9 @@ typedef enum _flash_protection_state */ typedef enum _flash_execute_only_access_state { - kFLASH_accessStateUnLimited, /*!< Flash region is unLimited.*/ - kFLASH_accessStateExecuteOnly, /*!< Flash region is execute only.*/ - kFLASH_accessStateMixed /*!< Flash is mixed with unLimited and execute only region.*/ + kFLASH_AccessStateUnLimited, /*!< Flash region is unlimited.*/ + kFLASH_AccessStateExecuteOnly, /*!< Flash region is execute only.*/ + kFLASH_AccessStateMixed /*!< Flash is mixed with unlimited and execute only region.*/ } flash_execute_only_access_state_t; /*! @@ -230,41 +248,43 @@ typedef enum _flash_execute_only_access_state */ typedef enum _flash_property_tag { - kFLASH_propertyPflashSectorSize = 0x00U, /*!< Pflash sector size property.*/ - kFLASH_propertyPflashTotalSize = 0x01U, /*!< Pflash total size property.*/ - kFLASH_propertyPflashBlockSize = 0x02U, /*!< Pflash block size property.*/ - kFLASH_propertyPflashBlockCount = 0x03U, /*!< Pflash block count property.*/ - kFLASH_propertyPflashBlockBaseAddr = 0x04U, /*!< Pflash block base address property.*/ - kFLASH_propertyPflashFacSupport = 0x05U, /*!< Pflash fac support property.*/ - kFLASH_propertyPflashAccessSegmentSize = 0x06U, /*!< Pflash access segment size property.*/ - kFLASH_propertyPflashAccessSegmentCount = 0x07U, /*!< Pflash access segment count property.*/ - kFLASH_propertyFlexRamBlockBaseAddr = 0x08U, /*!< FlexRam block base address property.*/ - kFLASH_propertyFlexRamTotalSize = 0x09U, /*!< FlexRam total size property.*/ - kFLASH_propertyDflashSectorSize = 0x10U, /*!< Dflash sector size property.*/ - kFLASH_propertyDflashTotalSize = 0x11U, /*!< Dflash total size property.*/ - kFLASH_propertyDflashBlockSize = 0x12U, /*!< Dflash block count property.*/ - kFLASH_propertyDflashBlockCount = 0x13U, /*!< Dflash block base address property.*/ - kFLASH_propertyDflashBlockBaseAddr = 0x14U, /*!< Eeprom total size property.*/ - kFLASH_propertyEepromTotalSize = 0x15U + kFLASH_PropertyPflashSectorSize = 0x00U, /*!< Pflash sector size property.*/ + kFLASH_PropertyPflashTotalSize = 0x01U, /*!< Pflash total size property.*/ + kFLASH_PropertyPflashBlockSize = 0x02U, /*!< Pflash block size property.*/ + kFLASH_PropertyPflashBlockCount = 0x03U, /*!< Pflash block count property.*/ + kFLASH_PropertyPflashBlockBaseAddr = 0x04U, /*!< Pflash block base address property.*/ + kFLASH_PropertyPflashFacSupport = 0x05U, /*!< Pflash fac support property.*/ + kFLASH_PropertyPflashAccessSegmentSize = 0x06U, /*!< Pflash access segment size property.*/ + kFLASH_PropertyPflashAccessSegmentCount = 0x07U, /*!< Pflash access segment count property.*/ + kFLASH_PropertyFlexRamBlockBaseAddr = 0x08U, /*!< FlexRam block base address property.*/ + kFLASH_PropertyFlexRamTotalSize = 0x09U, /*!< FlexRam total size property.*/ + kFLASH_PropertyDflashSectorSize = 0x10U, /*!< Dflash sector size property.*/ + kFLASH_PropertyDflashTotalSize = 0x11U, /*!< Dflash total size property.*/ + kFLASH_PropertyDflashBlockSize = 0x12U, /*!< Dflash block size property.*/ + kFLASH_PropertyDflashBlockCount = 0x13U, /*!< Dflash block count property.*/ + kFLASH_PropertyDflashBlockBaseAddr = 0x14U, /*!< Dflash block base address property.*/ + kFLASH_PropertyEepromTotalSize = 0x15U, /*!< EEPROM total size property.*/ + kFLASH_PropertyFlashMemoryIndex = 0x20U, /*!< Flash memory index property.*/ + kFLASH_PropertyFlashCacheControllerIndex = 0x21U /*!< Flash cache controller index property.*/ } flash_property_tag_t; /*! - * @brief Constants for execute-in-ram flash function. + * @brief Constants for execute-in-RAM flash function. */ enum _flash_execute_in_ram_function_constants { - kFLASH_executeInRamFunctionMaxSize = 64U, /*!< Max size of execute-in-ram function.*/ - kFLASH_executeInRamFunctionTotalNum = 2U /*!< Total number of execute-in-ram functions.*/ + kFLASH_ExecuteInRamFunctionMaxSizeInWords = 16U, /*!< The maximum size of execute-in-RAM function.*/ + kFLASH_ExecuteInRamFunctionTotalNum = 2U /*!< Total number of execute-in-RAM functions.*/ }; /*! - * @brief Flash execute-in-ram function information. + * @brief Flash execute-in-RAM function information. */ typedef struct _flash_execute_in_ram_function_config { - uint32_t activeFunctionCount; /*!< Number of available execute-in-ram functions.*/ - uint8_t *flashRunCommand; /*!< execute-in-ram function: flash_run_command.*/ - uint8_t *flashCacheClearCommand; /*!< execute-in-ram function: flash_cache_clear_command.*/ + uint32_t activeFunctionCount; /*!< Number of available execute-in-RAM functions.*/ + uint32_t *flashRunCommand; /*!< Execute-in-RAM function: flash_run_command.*/ + uint32_t *flashCommonBitOperation; /*!< Execute-in-RAM function: flash_common_bit_operation.*/ } flash_execute_in_ram_function_config_t; /*! @@ -272,9 +292,9 @@ typedef struct _flash_execute_in_ram_function_config */ typedef enum _flash_read_resource_option { - kFLASH_resourceOptionFlashIfr = + kFLASH_ResourceOptionFlashIfr = 0x00U, /*!< Select code for Program flash 0 IFR, Program flash swap 0 IFR, Data flash 0 IFR */ - kFLASH_resourceOptionVersionId = 0x01U /*!< Select code for Version ID*/ + kFLASH_ResourceOptionVersionId = 0x01U /*!< Select code for the version ID*/ } flash_read_resource_option_t; /*! @@ -283,124 +303,262 @@ typedef enum _flash_read_resource_option enum _flash_read_resource_range { #if (FSL_FEATURE_FLASH_IS_FTFE == 1) - kFLASH_resourceRangePflashIfrSizeInBytes = 1024U, /*!< Pflash IFR size in byte.*/ - kFLASH_resourceRangeVersionIdSizeInBytes = 8U, /*!< Version ID IFR size in byte.*/ - kFLASH_resourceRangeVersionIdStart = 0x08U, /*!< Version ID IFR start address.*/ - kFLASH_resourceRangeVersionIdEnd = 0x0FU, /*!< Version ID IFR end address.*/ -#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */ - kFLASH_resourceRangePflashIfrSizeInBytes = 256U, /*!< Pflash IFR size in byte.*/ - kFLASH_resourceRangeVersionIdSizeInBytes = 8U, /*!< Version ID IFR size in byte.*/ - kFLASH_resourceRangeVersionIdStart = 0x00U, /*!< Version ID IFR start address.*/ - kFLASH_resourceRangeVersionIdEnd = 0x07U, /*!< Version ID IFR end address.*/ + kFLASH_ResourceRangePflashIfrSizeInBytes = 1024U, /*!< Pflash IFR size in byte.*/ + kFLASH_ResourceRangeVersionIdSizeInBytes = 8U, /*!< Version ID IFR size in byte.*/ + kFLASH_ResourceRangeVersionIdStart = 0x08U, /*!< Version ID IFR start address.*/ + kFLASH_ResourceRangeVersionIdEnd = 0x0FU, /*!< Version ID IFR end address.*/ + kFLASH_ResourceRangePflashSwapIfrStart = 0x40000U, /*!< Pflash swap IFR start address.*/ + kFLASH_ResourceRangePflashSwapIfrEnd = + (kFLASH_ResourceRangePflashSwapIfrStart + 0x3FFU), /*!< Pflash swap IFR end address.*/ +#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA = =1 */ + kFLASH_ResourceRangePflashIfrSizeInBytes = 256U, /*!< Pflash IFR size in byte.*/ + kFLASH_ResourceRangeVersionIdSizeInBytes = 8U, /*!< Version ID IFR size in byte.*/ + kFLASH_ResourceRangeVersionIdStart = 0x00U, /*!< Version ID IFR start address.*/ + kFLASH_ResourceRangeVersionIdEnd = 0x07U, /*!< Version ID IFR end address.*/ +#if 0x20000U == (FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE) + kFLASH_ResourceRangePflashSwapIfrStart = 0x8000U, /*!< Pflash swap IFR start address.*/ +#elif 0x40000U == (FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE) + kFLASH_ResourceRangePflashSwapIfrStart = 0x10000U, /*!< Pflash swap IFR start address.*/ +#elif 0x80000U == (FSL_FEATURE_FLASH_PFLASH_BLOCK_COUNT * FSL_FEATURE_FLASH_PFLASH_BLOCK_SIZE) + kFLASH_ResourceRangePflashSwapIfrStart = 0x20000U, /*!< Pflash swap IFR start address.*/ +#else + kFLASH_ResourceRangePflashSwapIfrStart = 0, #endif - kFLASH_resourceRangePflashSwapIfrStart = 0x40000U, /*!< Pflash swap IFR start address.*/ - kFLASH_resourceRangePflashSwapIfrEnd = 0x403FFU, /*!< Pflash swap IFR end address.*/ - kFLASH_resourceRangeDflashIfrStart = 0x800000U, /*!< Dflash IFR start address.*/ - kFLASH_resourceRangeDflashIfrEnd = 0x8003FFU, /*!< Dflash IFR end address.*/ + kFLASH_ResourceRangePflashSwapIfrEnd = + (kFLASH_ResourceRangePflashSwapIfrStart + 0xFFU), /*!< Pflash swap IFR end address.*/ +#endif + kFLASH_ResourceRangeDflashIfrStart = 0x800000U, /*!< Dflash IFR start address.*/ + kFLASH_ResourceRangeDflashIfrEnd = 0x8003FFU, /*!< Dflash IFR end address.*/ }; /*! - * @brief Enumeration for the two possilbe options of set flexram function command. + * @brief Enumeration for the index of read/program once record + */ +enum _k3_flash_read_once_index +{ + kFLASH_RecordIndexSwapAddr = 0xA1U, /*!< Index of Swap indicator address.*/ + kFLASH_RecordIndexSwapEnable = 0xA2U, /*!< Index of Swap system enable.*/ + kFLASH_RecordIndexSwapDisable = 0xA3U, /*!< Index of Swap system disable.*/ +}; + +/*! + * @brief Enumeration for the two possilbe options of set FlexRAM function command. */ typedef enum _flash_flexram_function_option { - kFLASH_flexramFunctionOptionAvailableAsRam = 0xFFU, /*!< Option used to make FlexRAM available as RAM */ - kFLASH_flexramFunctionOptionAvailableForEeprom = 0x00U /*!< Option used to make FlexRAM available for EEPROM */ + kFLASH_FlexramFunctionOptionAvailableAsRam = 0xFFU, /*!< An option used to make FlexRAM available as RAM */ + kFLASH_FlexramFunctionOptionAvailableForEeprom = 0x00U /*!< An option used to make FlexRAM available for EEPROM */ } flash_flexram_function_option_t; +/*! + * @brief Enumeration for acceleration RAM property. + */ +enum _flash_acceleration_ram_property +{ + kFLASH_AccelerationRamSize = 0x400U +}; + /*! * @brief Enumeration for the possible options of Swap function */ typedef enum _flash_swap_function_option { - kFLASH_swapFunctionOptionEnable = 0x00U, /*!< Option used to enable Swap function */ - kFLASH_swapFunctionOptionDisable = 0x01U /*!< Option used to Disable Swap function */ + kFLASH_SwapFunctionOptionEnable = 0x00U, /*!< An option used to enable the Swap function */ + kFLASH_SwapFunctionOptionDisable = 0x01U /*!< An option used to disable the Swap function */ } flash_swap_function_option_t; /*! - * @brief Enumeration for the possible options of Swap Control commands + * @brief Enumeration for the possible options of Swap control commands */ typedef enum _flash_swap_control_option { - kFLASH_swapControlOptionIntializeSystem = 0x01U, /*!< Option used to Intialize Swap System */ - kFLASH_swapControlOptionSetInUpdateState = 0x02U, /*!< Option used to Set Swap in Update State */ - kFLASH_swapControlOptionSetInCompleteState = 0x04U, /*!< Option used to Set Swap in Complete State */ - kFLASH_swapControlOptionReportStatus = 0x08U, /*!< Option used to Report Swap Status */ - kFLASH_swapControlOptionDisableSystem = 0x10U /*!< Option used to Disable Swap Status */ + kFLASH_SwapControlOptionIntializeSystem = 0x01U, /*!< An option used to initialize the Swap system */ + kFLASH_SwapControlOptionSetInUpdateState = 0x02U, /*!< An option used to set the Swap in an update state */ + kFLASH_SwapControlOptionSetInCompleteState = 0x04U, /*!< An option used to set the Swap in a complete state */ + kFLASH_SwapControlOptionReportStatus = 0x08U, /*!< An option used to report the Swap status */ + kFLASH_SwapControlOptionDisableSystem = 0x10U /*!< An option used to disable the Swap status */ } flash_swap_control_option_t; /*! - * @brief Enumeration for the possible flash swap status. + * @brief Enumeration for the possible flash Swap status. */ typedef enum _flash_swap_state { - kFLASH_swapStateUninitialized = 0x00U, /*!< Flash swap system is in uninitialized state.*/ - kFLASH_swapStateReady = 0x01U, /*!< Flash swap system is in ready state.*/ - kFLASH_swapStateUpdate = 0x02U, /*!< Flash swap system is in update state.*/ - kFLASH_swapStateUpdateErased = 0x03U, /*!< Flash swap system is in updateErased state.*/ - kFLASH_swapStateComplete = 0x04U, /*!< Flash swap system is in complete state.*/ - kFLASH_swapStateDisabled = 0x05U /*!< Flash swap system is in disabled state.*/ + kFLASH_SwapStateUninitialized = 0x00U, /*!< Flash Swap system is in an uninitialized state.*/ + kFLASH_SwapStateReady = 0x01U, /*!< Flash Swap system is in a ready state.*/ + kFLASH_SwapStateUpdate = 0x02U, /*!< Flash Swap system is in an update state.*/ + kFLASH_SwapStateUpdateErased = 0x03U, /*!< Flash Swap system is in an updateErased state.*/ + kFLASH_SwapStateComplete = 0x04U, /*!< Flash Swap system is in a complete state.*/ + kFLASH_SwapStateDisabled = 0x05U /*!< Flash Swap system is in a disabled state.*/ } flash_swap_state_t; /*! - * @breif Enumeration for the possible flash swap block status + * @breif Enumeration for the possible flash Swap block status */ typedef enum _flash_swap_block_status { - kFLASH_swapBlockStatusLowerHalfProgramBlocksAtZero = + kFLASH_SwapBlockStatusLowerHalfProgramBlocksAtZero = 0x00U, /*!< Swap block status is that lower half program block at zero.*/ - kFLASH_swapBlockStatusUpperHalfProgramBlocksAtZero = + kFLASH_SwapBlockStatusUpperHalfProgramBlocksAtZero = 0x01U, /*!< Swap block status is that upper half program block at zero.*/ } flash_swap_block_status_t; /*! - * @brief Flash Swap information. + * @brief Flash Swap information */ typedef struct _flash_swap_state_config { - flash_swap_state_t flashSwapState; /*!< Current swap system status.*/ - flash_swap_block_status_t currentSwapBlockStatus; /*!< Current swap block status.*/ - flash_swap_block_status_t nextSwapBlockStatus; /*!< Next swap block status.*/ + flash_swap_state_t flashSwapState; /*!chip = 0; fbConfig->writeProtect = 0; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flexcan.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flexcan.c index 15e1f55f43..f58f3f55f0 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flexcan.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flexcan.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -165,8 +165,6 @@ static void FLEXCAN_SetBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_ /******************************************************************************* * Variables ******************************************************************************/ -/* Array of FlexCAN handle. */ -static flexcan_handle_t *s_flexcanHandle[FSL_FEATURE_SOC_FLEXCAN_COUNT]; /* Array of FlexCAN peripheral base address. */ static CAN_Type *const s_flexcanBases[] = CAN_BASE_PTRS; @@ -179,8 +177,17 @@ static const IRQn_Type s_flexcanErrorIRQ[] = CAN_Error_IRQS; static const IRQn_Type s_flexcanBusOffIRQ[] = CAN_Bus_Off_IRQS; static const IRQn_Type s_flexcanMbIRQ[] = CAN_ORed_Message_buffer_IRQS; +/* Array of FlexCAN handle. */ +static flexcan_handle_t *s_flexcanHandle[ARRAY_SIZE(s_flexcanBases)]; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Array of FlexCAN clock name. */ static const clock_ip_name_t s_flexcanClock[] = FLEXCAN_CLOCKS; +#if defined(FLEXCAN_PERIPH_CLOCKS) +/* Array of FlexCAN serial clock name. */ +static const clock_ip_name_t s_flexcanPeriphClock[] = FLEXCAN_PERIPH_CLOCKS; +#endif /* FLEXCAN_PERIPH_CLOCKS */ +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* FlexCAN ISR for transactional APIs. */ static flexcan_isr_t s_flexcanIsr; @@ -194,7 +201,7 @@ uint32_t FLEXCAN_GetInstance(CAN_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_FLEXCAN_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_flexcanBases); instance++) { if (s_flexcanBases[instance] == base) { @@ -202,7 +209,7 @@ uint32_t FLEXCAN_GetInstance(CAN_Type *base) } } - assert(instance < FSL_FEATURE_SOC_FLEXCAN_COUNT); + assert(instance < ARRAY_SIZE(s_flexcanBases)); return instance; } @@ -314,9 +321,13 @@ static bool FLEXCAN_IsMbIntEnabled(CAN_Type *base, uint8_t mbIdx) else { if (base->IMASK2 & ((uint32_t)(1 << (mbIdx - 32)))) + { return true; + } else + { return false; + } } #endif } @@ -420,14 +431,25 @@ static void FLEXCAN_SetBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_ void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourceClock_Hz) { uint32_t mcrTemp; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + uint32_t instance; +#endif /* Assertion. */ assert(config); assert((config->maxMbNum > 0) && (config->maxMbNum <= FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base))); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + instance = FLEXCAN_GetInstance(base); /* Enable FlexCAN clock. */ - CLOCK_EnableClock(s_flexcanClock[FLEXCAN_GetInstance(base)]); + CLOCK_EnableClock(s_flexcanClock[instance]); +#if defined(FLEXCAN_PERIPH_CLOCKS) + /* Enable FlexCAN serial clock. */ + CLOCK_EnableClock(s_flexcanPeriphClock[instance]); +#endif /* FLEXCAN_PERIPH_CLOCKS */ +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +#if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE /* Disable FlexCAN Module. */ FLEXCAN_Enable(base, false); @@ -436,6 +458,7 @@ void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourc */ base->CTRL1 = (kFLEXCAN_ClkSrcOsc == config->clkSrc) ? base->CTRL1 & ~CAN_CTRL1_CLKSRC_MASK : base->CTRL1 | CAN_CTRL1_CLKSRC_MASK; +#endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */ /* Enable FlexCAN Module for configuartion. */ FLEXCAN_Enable(base, true); @@ -472,14 +495,24 @@ void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourc void FLEXCAN_Deinit(CAN_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + uint32_t instance; +#endif /* Reset all Register Contents. */ FLEXCAN_Reset(base); /* Disable FlexCAN module. */ FLEXCAN_Enable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + instance = FLEXCAN_GetInstance(base); +#if defined(FLEXCAN_PERIPH_CLOCKS) + /* Disable FlexCAN serial clock. */ + CLOCK_DisableClock(s_flexcanPeriphClock[instance]); +#endif /* FLEXCAN_PERIPH_CLOCKS */ /* Disable FlexCAN clock. */ - CLOCK_DisableClock(s_flexcanClock[FLEXCAN_GetInstance(base)]); + CLOCK_DisableClock(s_flexcanClock[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void FLEXCAN_GetDefaultConfig(flexcan_config_t *config) @@ -488,7 +521,9 @@ void FLEXCAN_GetDefaultConfig(flexcan_config_t *config) assert(config); /* Initialize FlexCAN Module config struct with default value. */ +#if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE config->clkSrc = kFLEXCAN_ClkSrcOsc; +#endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */ config->baudRate = 125000U; config->maxMbNum = 16; config->enableLoopBack = false; @@ -1293,13 +1328,13 @@ void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle) (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag | kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag)))); #else - while ((0 != FLEXCAN_GetMbStatusFlags(base, 0xFFFFFFFFU)) || - (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag | - kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag)))); + while ((0 != FLEXCAN_GetMbStatusFlags(base, 0xFFFFFFFFU)) || + (0 != (result & (kFLEXCAN_TxWarningIntFlag | kFLEXCAN_RxWarningIntFlag | kFLEXCAN_BusOffIntFlag | + kFLEXCAN_ErrorIntFlag | kFLEXCAN_WakeUpIntFlag)))); #endif } -#if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 0) +#if defined(CAN0) void CAN0_DriverIRQHandler(void) { assert(s_flexcanHandle[0]); @@ -1308,7 +1343,7 @@ void CAN0_DriverIRQHandler(void) } #endif -#if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 1) +#if defined(CAN1) void CAN1_DriverIRQHandler(void) { assert(s_flexcanHandle[1]); @@ -1317,7 +1352,7 @@ void CAN1_DriverIRQHandler(void) } #endif -#if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 2) +#if defined(CAN2) void CAN2_DriverIRQHandler(void) { assert(s_flexcanHandle[2]); @@ -1326,7 +1361,7 @@ void CAN2_DriverIRQHandler(void) } #endif -#if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 3) +#if defined(CAN3) void CAN3_DriverIRQHandler(void) { assert(s_flexcanHandle[3]); @@ -1335,7 +1370,7 @@ void CAN3_DriverIRQHandler(void) } #endif -#if (FSL_FEATURE_SOC_FLEXCAN_COUNT > 4) +#if defined(CAN4) void CAN4_DriverIRQHandler(void) { assert(s_flexcanHandle[4]); @@ -1343,3 +1378,30 @@ void CAN4_DriverIRQHandler(void) s_flexcanIsr(CAN4, s_flexcanHandle[4]); } #endif + +#if defined(DMA_CAN0) +void DMA_FLEXCAN0_DriverIRQHandler(void) +{ + assert(s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN0)]); + + s_flexcanIsr(DMA_CAN0, s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN0)]); +} +#endif + +#if defined(DMA_CAN1) +void DMA_FLEXCAN1_DriverIRQHandler(void) +{ + assert(s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN1)]); + + s_flexcanIsr(DMA_CAN0, s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN1)]); +} +#endif + +#if defined(DMA_CAN2) +void DMA_FLEXCAN2_DriverIRQHandler(void) +{ + assert(s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN2)]); + + s_flexcanIsr(DMA_CAN2, s_flexcanHandle[FLEXCAN_GetInstance(DMA_CAN2)]); +} +#endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flexcan.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flexcan.h index 13c28f357d..118badf58f 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flexcan.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_flexcan.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,15 +37,14 @@ * @{ */ - /****************************************************************************** * Definitions *****************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief FlexCAN driver version 2.1.0. */ -#define FLEXCAN_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*! @brief FlexCAN driver version 2.2.0. */ +#define FLEXCAN_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) /*@}*/ /*! @brief FlexCAN Frame ID helper macro. */ @@ -69,19 +68,18 @@ (FLEXCAN_ID_STD(id) << 1)) /*!< Standard Rx FIFO Mask helper macro Type A helper macro. */ #define FLEXCAN_RX_FIFO_STD_MASK_TYPE_B_HIGH(id, rtr, ide) \ (((uint32_t)((uint32_t)(rtr) << 31) | (uint32_t)((uint32_t)(ide) << 30)) | \ - (FLEXCAN_ID_STD(id) << 16)) /*!< Standard Rx FIFO Mask helper macro Type B upper part helper macro. */ + (((uint32_t)(id) & 0x7FF) << 19)) /*!< Standard Rx FIFO Mask helper macro Type B upper part helper macro. */ #define FLEXCAN_RX_FIFO_STD_MASK_TYPE_B_LOW(id, rtr, ide) \ (((uint32_t)((uint32_t)(rtr) << 15) | (uint32_t)((uint32_t)(ide) << 14)) | \ - FLEXCAN_ID_STD(id)) /*!< Standard Rx FIFO Mask helper macro Type B lower part helper macro. */ + (((uint32_t)(id) & 0x7FF) << 3)) /*!< Standard Rx FIFO Mask helper macro Type B lower part helper macro. */ #define FLEXCAN_RX_FIFO_STD_MASK_TYPE_C_HIGH(id) \ - ((FLEXCAN_ID_STD(id) & 0x7F8) << 21) /*!< Standard Rx FIFO Mask helper macro Type C upper part helper macro. */ -#define FLEXCAN_RX_FIFO_STD_MASK_TYPE_C_MID_HIGH(id) \ - ((FLEXCAN_ID_STD(id) & 0x7F8) << 13) /*!< Standard Rx FIFO Mask helper macro Type C mid-upper part helper macro. \ - */ + (((uint32_t)(id) & 0x7F8) << 21) /*!< Standard Rx FIFO Mask helper macro Type C upper part helper macro. */ +#define FLEXCAN_RX_FIFO_STD_MASK_TYPE_C_MID_HIGH(id) \ + (((uint32_t)(id) & 0x7F8) << 13) /*!< Standard Rx FIFO Mask helper macro Type C mid-upper part helper macro. */ #define FLEXCAN_RX_FIFO_STD_MASK_TYPE_C_MID_LOW(id) \ - ((FLEXCAN_ID_STD(id) & 0x7F8) << 5) /*!< Standard Rx FIFO Mask helper macro Type C mid-lower part helper macro. */ + (((uint32_t)(id) & 0x7F8) << 5) /*!< Standard Rx FIFO Mask helper macro Type C mid-lower part helper macro. */ #define FLEXCAN_RX_FIFO_STD_MASK_TYPE_C_LOW(id) \ - ((FLEXCAN_ID_STD(id) & 0x7F8) >> 3) /*!< Standard Rx FIFO Mask helper macro Type C lower part helper macro. */ + (((uint32_t)(id) & 0x7F8) >> 3) /*!< Standard Rx FIFO Mask helper macro Type C lower part helper macro. */ #define FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(id, rtr, ide) \ (((uint32_t)((uint32_t)(rtr) << 31) | (uint32_t)((uint32_t)(ide) << 30)) | \ (FLEXCAN_ID_EXT(id) << 1)) /*!< Extend Rx FIFO Mask helper macro Type A helper macro. */ @@ -157,7 +155,7 @@ enum _flexcan_status kStatus_FLEXCAN_RxFifoBusy = MAKE_STATUS(kStatusGroup_FLEXCAN, 6), /*!< Rx Message FIFO is Busy. */ kStatus_FLEXCAN_RxFifoIdle = MAKE_STATUS(kStatusGroup_FLEXCAN, 7), /*!< Rx Message FIFO is Idle. */ kStatus_FLEXCAN_RxFifoOverflow = MAKE_STATUS(kStatusGroup_FLEXCAN, 8), /*!< Rx Message FIFO is overflowed. */ - kStatus_FLEXCAN_RxFifoWarning = MAKE_STATUS(kStatusGroup_FLEXCAN, 0), /*!< Rx Message FIFO is almost overflowed. */ + kStatus_FLEXCAN_RxFifoWarning = MAKE_STATUS(kStatusGroup_FLEXCAN, 9), /*!< Rx Message FIFO is almost overflowed. */ kStatus_FLEXCAN_ErrorStatus = MAKE_STATUS(kStatusGroup_FLEXCAN, 10), /*!< FlexCAN Module Error and Status. */ kStatus_FLEXCAN_UnHandled = MAKE_STATUS(kStatusGroup_FLEXCAN, 11), /*!< UnHadled Interrupt asserted. */ }; @@ -176,12 +174,14 @@ typedef enum _flexcan_frame_type kFLEXCAN_FrameTypeRemote = 0x1U, /*!< Remote frame type attribute. */ } flexcan_frame_type_t; +#if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE /*! @brief FlexCAN clock source. */ typedef enum _flexcan_clock_source { kFLEXCAN_ClkSrcOsc = 0x0U, /*!< FlexCAN Protocol Engine clock from Oscillator. */ kFLEXCAN_ClkSrcPeri = 0x1U, /*!< FlexCAN Protocol Engine clock from Peripheral Clock. */ } flexcan_clock_source_t; +#endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */ /*! @brief FlexCAN Rx Fifo Filter type. */ typedef enum _flexcan_rx_fifo_filter_type @@ -195,7 +195,7 @@ typedef enum _flexcan_rx_fifo_filter_type } flexcan_rx_fifo_filter_type_t; /*! - * @brief FlexCAN Rx FIFO priority + * @brief FlexCAN Rx FIFO priority. * * The matching process starts from the Rx MB(or Rx FIFO) with higher priority. * If no MB(or Rx FIFO filter) is satisfied, the matching process goes on with @@ -326,7 +326,9 @@ typedef struct _flexcan_frame typedef struct _flexcan_config { uint32_t baudRate; /*!< FlexCAN baud rate in bps. */ +#if (!defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)) || !FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE flexcan_clock_source_t clkSrc; /*!< Clock source for FlexCAN Protocol Engine. */ +#endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */ uint8_t maxMbNum; /*!< The maximum number of Message Buffers used by user. */ bool enableLoopBack; /*!< Enable or Disable Loop Back Self Test Mode. */ bool enableSelfWakeup; /*!< Enable or Disable Self Wakeup Mode. */ @@ -366,7 +368,7 @@ typedef struct _flexcan_rx_mb_config /*! @brief FlexCAN Rx FIFO configuration structure. */ typedef struct _flexcan_rx_fifo_config { - uint32_t *idFilterTable; /*!< Pointer to FlexCAN Rx FIFO identifier filter table. */ + uint32_t *idFilterTable; /*!< Pointer to the FlexCAN Rx FIFO identifier filter table. */ uint8_t idFilterNum; /*!< The quantity of filter elements. */ flexcan_rx_fifo_filter_type_t idFilterType; /*!< The FlexCAN Rx FIFO Filter type. */ flexcan_rx_fifo_priority_t priority; /*!< The FlexCAN Rx FIFO receive priority. */ @@ -431,7 +433,7 @@ extern "C" { * * This function initializes the FlexCAN module with user-defined settings. * This example shows how to set up the flexcan_config_t parameters and how - * to call the FLEXCAN_Init function by passing in these parameters: + * to call the FLEXCAN_Init function by passing in these parameters. * @code * flexcan_config_t flexcanConfig; * flexcanConfig.clkSrc = kFLEXCAN_ClkSrcOsc; @@ -445,7 +447,7 @@ extern "C" { * @endcode * * @param base FlexCAN peripheral base address. - * @param config Pointer to user-defined configuration structure. + * @param config Pointer to the user-defined configuration structure. * @param sourceClock_Hz FlexCAN Protocol Engine clock source frequency in Hz. */ void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourceClock_Hz); @@ -453,18 +455,18 @@ void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *config, uint32_t sourc /*! * @brief De-initializes a FlexCAN instance. * - * This function disable the FlexCAN module clock and set all register value - * to reset value. + * This function disables the FlexCAN module clock and sets all register values + * to the reset value. * * @param base FlexCAN peripheral base address. */ void FLEXCAN_Deinit(CAN_Type *base); /*! - * @brief Get the default configuration structure. + * @brief Gets the default configuration structure. * - * This function initializes the FlexCAN configuration structure to default value. The default - * value are: + * This function initializes the FlexCAN configuration structure to default values. The default + * values are as follows. * flexcanConfig->clkSrc = KFLEXCAN_ClkSrcOsc; * flexcanConfig->baudRate = 125000U; * flexcanConfig->maxMbNum = 16; @@ -473,7 +475,7 @@ void FLEXCAN_Deinit(CAN_Type *base); * flexcanConfig->enableIndividMask = false; * flexcanConfig->enableDoze = false; * - * @param config Pointer to FlexCAN configuration structure. + * @param config Pointer to the FlexCAN configuration structure. */ void FLEXCAN_GetDefaultConfig(flexcan_config_t *config); @@ -503,7 +505,7 @@ void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *conf /*! * @brief Sets the FlexCAN receive message buffer global mask. * - * This function sets the global mask for FlexCAN message buffer in a matching process. + * This function sets the global mask for the FlexCAN message buffer in a matching process. * The configuration is only effective when the Rx individual mask is disabled in the FLEXCAN_Init(). * * @param base FlexCAN peripheral base address. @@ -524,12 +526,12 @@ void FLEXCAN_SetRxFifoGlobalMask(CAN_Type *base, uint32_t mask); /*! * @brief Sets the FlexCAN receive individual mask. * - * This function sets the individual mask for FlexCAN matching process. - * The configuration is only effective when the Rx individual mask is enabled in FLEXCAN_Init(). - * If Rx FIFO is disabled, the individual mask is applied to the corresponding Message Buffer. - * If Rx FIFO is enabled, the individual mask for Rx FIFO occupied Message Buffer is applied to - * the Rx Filter with same index. What calls for special attention is that only the first 32 - * individual masks can be used as Rx FIFO filter mask. + * This function sets the individual mask for the FlexCAN matching process. + * The configuration is only effective when the Rx individual mask is enabled in the FLEXCAN_Init(). + * If the Rx FIFO is disabled, the individual mask is applied to the corresponding Message Buffer. + * If the Rx FIFO is enabled, the individual mask for Rx FIFO occupied Message Buffer is applied to + * the Rx Filter with the same index. Note that only the first 32 + * individual masks can be used as the Rx FIFO filter mask. * * @param base FlexCAN peripheral base address. * @param maskIdx The Index of individual Mask. @@ -545,7 +547,7 @@ void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask) * * @param base FlexCAN peripheral base address. * @param mbIdx The Message Buffer index. - * @param enable Enable/Disable Tx Message Buffer. + * @param enable Enable/disable Tx Message Buffer. * - true: Enable Tx Message Buffer. * - false: Disable Tx Message Buffer. */ @@ -559,8 +561,8 @@ void FLEXCAN_SetTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable); * * @param base FlexCAN peripheral base address. * @param mbIdx The Message Buffer index. - * @param config Pointer to FlexCAN Message Buffer configuration structure. - * @param enable Enable/Disable Rx Message Buffer. + * @param config Pointer to the FlexCAN Message Buffer configuration structure. + * @param enable Enable/disable Rx Message Buffer. * - true: Enable Rx Message Buffer. * - false: Disable Rx Message Buffer. */ @@ -572,8 +574,8 @@ void FLEXCAN_SetRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_co * This function configures the Rx FIFO with given Rx FIFO configuration. * * @param base FlexCAN peripheral base address. - * @param config Pointer to FlexCAN Rx FIFO configuration structure. - * @param enable Enable/Disable Rx FIFO. + * @param config Pointer to the FlexCAN Rx FIFO configuration structure. + * @param enable Enable/disable Rx FIFO. * - true: Enable Rx FIFO. * - false: Disable Rx FIFO. */ @@ -676,7 +678,7 @@ static inline void FLEXCAN_ClearMbStatusFlags(CAN_Type *base, uint32_t mask) #endif { #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - base->IFLAG1 = (uint32_t)(mask & 0xFFFFFFFF); + base->IFLAG1 = (uint32_t)(mask & 0xFFFFFFFFU); base->IFLAG2 = (uint32_t)(mask >> 32); #else base->IFLAG1 = mask; @@ -691,9 +693,9 @@ static inline void FLEXCAN_ClearMbStatusFlags(CAN_Type *base, uint32_t mask) */ /*! - * @brief Enables FlexCAN interrupts according to provided mask. + * @brief Enables FlexCAN interrupts according to the provided mask. * - * This function enables the FlexCAN interrupts according to provided mask. The mask + * This function enables the FlexCAN interrupts according to the provided mask. The mask * is a logical OR of enumeration members, see @ref _flexcan_interrupt_enable. * * @param base FlexCAN peripheral base address. @@ -712,9 +714,9 @@ static inline void FLEXCAN_EnableInterrupts(CAN_Type *base, uint32_t mask) } /*! - * @brief Disables FlexCAN interrupts according to provided mask. + * @brief Disables FlexCAN interrupts according to the provided mask. * - * This function disables the FlexCAN interrupts according to provided mask. The mask + * This function disables the FlexCAN interrupts according to the provided mask. The mask * is a logical OR of enumeration members, see @ref _flexcan_interrupt_enable. * * @param base FlexCAN peripheral base address. @@ -735,7 +737,7 @@ static inline void FLEXCAN_DisableInterrupts(CAN_Type *base, uint32_t mask) /*! * @brief Enables FlexCAN Message Buffer interrupts. * - * This function enables the interrupts of given Message Buffers + * This function enables the interrupts of given Message Buffers. * * @param base FlexCAN peripheral base address. * @param mask The ORed FlexCAN Message Buffer mask. @@ -747,7 +749,7 @@ static inline void FLEXCAN_EnableMbInterrupts(CAN_Type *base, uint32_t mask) #endif { #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - base->IMASK1 |= (uint32_t)(mask & 0xFFFFFFFF); + base->IMASK1 |= (uint32_t)(mask & 0xFFFFFFFFU); base->IMASK2 |= (uint32_t)(mask >> 32); #else base->IMASK1 |= mask; @@ -757,7 +759,7 @@ static inline void FLEXCAN_EnableMbInterrupts(CAN_Type *base, uint32_t mask) /*! * @brief Disables FlexCAN Message Buffer interrupts. * - * This function disables the interrupts of given Message Buffers + * This function disables the interrupts of given Message Buffers. * * @param base FlexCAN peripheral base address. * @param mask The ORed FlexCAN Message Buffer mask. @@ -769,7 +771,7 @@ static inline void FLEXCAN_DisableMbInterrupts(CAN_Type *base, uint32_t mask) #endif { #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - base->IMASK1 &= ~((uint32_t)(mask & 0xFFFFFFFF)); + base->IMASK1 &= ~((uint32_t)(mask & 0xFFFFFFFFU)); base->IMASK2 &= ~((uint32_t)(mask >> 32)); #else base->IMASK1 &= ~mask; @@ -846,7 +848,7 @@ static inline void FLEXCAN_Enable(CAN_Type *base, bool enable) } /*! - * @brief Writes a FlexCAN Message to Transmit Message Buffer. + * @brief Writes a FlexCAN Message to the Transmit Message Buffer. * * This function writes a CAN Message to the specified Transmit Message Buffer * and changes the Message Buffer state to start CAN Message transmit. After @@ -938,7 +940,7 @@ status_t FLEXCAN_TransferReceiveFifoBlocking(CAN_Type *base, flexcan_frame_t *rx /*! * @brief Initializes the FlexCAN handle. * - * This function initializes the FlexCAN handle which can be used for other FlexCAN + * This function initializes the FlexCAN handle, which can be used for other FlexCAN * transactional APIs. Usually, for a specified FlexCAN instance, * call this API once to get the initialized handle. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ftm.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ftm.c index 85dc219425..9cca44b0e4 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ftm.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ftm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -72,8 +72,10 @@ static void FTM_SetReloadPoints(FTM_Type *base, uint32_t reloadPoints); /*! @brief Pointers to FTM bases for each instance. */ static FTM_Type *const s_ftmBases[] = FTM_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to FTM clocks for each instance. */ static const clock_ip_name_t s_ftmClocks[] = FTM_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Code @@ -228,8 +230,10 @@ status_t FTM_Init(FTM_Type *base, const ftm_config_t *config) return kStatus_Fail; } +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Ungate the FTM clock*/ CLOCK_EnableClock(s_ftmClocks[FTM_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure the fault mode, enable FTM mode and disable write protection */ base->MODE = FTM_MODE_FAULTM(config->faultMode) | FTM_MODE_FTMEN_MASK | FTM_MODE_WPDIS_MASK; @@ -266,7 +270,13 @@ status_t FTM_Init(FTM_Type *base, const ftm_config_t *config) #endif /* FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER */ /* FTM deadtime insertion control */ - base->DEADTIME = (FTM_DEADTIME_DTPS(config->deadTimePrescale) | FTM_DEADTIME_DTVAL(config->deadTimeValue)); + base->DEADTIME = (0u | +#if defined(FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE) && (FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE) + /* Has extended deadtime value register) */ + FTM_DEADTIME_DTVALEX(config->deadTimeValue >> 6) | +#endif /* FSL_FEATURE_FTM_HAS_EXTENDED_DEADTIME_VALUE */ + FTM_DEADTIME_DTPS(config->deadTimePrescale) | + FTM_DEADTIME_DTVAL(config->deadTimeValue)); /* FTM fault filter value */ reg = base->FLTCTRL; @@ -282,8 +292,10 @@ void FTM_Deinit(FTM_Type *base) /* Set clock source to none to disable counter */ base->SC &= ~(FTM_SC_CLKS_MASK); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate the FTM clock */ CLOCK_DisableClock(s_ftmClocks[FTM_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void FTM_GetDefaultConfig(ftm_config_t *config) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ftm.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ftm.h index 2fb1c08e49..8db81a633a 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ftm.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_ftm.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,7 +37,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -45,8 +44,8 @@ /*! @name Driver version */ /*@{*/ -#define FSL_FTM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ -/*@}*/ +#define FSL_FTM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2 */ + /*@}*/ /*! * @brief List of FTM channels @@ -162,7 +161,7 @@ typedef struct _ftm_phase_param typedef struct _ftm_fault_param { bool enableFaultInput; /*!< True: Fault input is enabled; false: Fault input is disabled */ - bool faultLevel; /*!< True: Fault polarity is active low i.e., '0' indicates a fault; + bool faultLevel; /*!< True: Fault polarity is active low; in other words, '0' indicates a fault; False: Fault polarity is active high */ bool useFaultFilter; /*!< True: Use the filtered fault signal; False: Use the direct path from fault input */ @@ -310,6 +309,17 @@ typedef enum _ftm_status_flags kFTM_ReloadFlag = (1U << 11) /*!< Reload Flag; Available only on certain SoC's */ } ftm_status_flags_t; +/*! + * @brief List of FTM Quad Decoder flags. + */ +enum _ftm_quad_decoder_flags +{ + kFTM_QuadDecoderCountingIncreaseFlag = FTM_QDCTRL_QUADIR_MASK, /*!< Counting direction is increasing (FTM counter + increment), or the direction is decreasing. */ + kFTM_QuadDecoderCountingOverflowOnTopFlag = FTM_QDCTRL_TOFDIR_MASK, /*!< Indicates if the TOF bit was set on the top + or the bottom of counting. */ +}; + /*! * @brief FTM configuration structure * @@ -333,7 +343,9 @@ typedef struct _ftm_config ftm_fault_mode_t faultMode; /*!< FTM fault control mode */ uint8_t faultFilterValue; /*!< Fault input filter value */ ftm_deadtime_prescale_t deadTimePrescale; /*!< The dead time prescalar value */ - uint8_t deadTimeValue; /*!< The dead time value */ + uint32_t deadTimeValue; /*!< The dead time value + deadTimeValue's available range is 0-1023 when register has DTVALEX, + otherwise its available range is 0-63. */ uint32_t extTriggers; /*!< External triggers to enable. Multiple trigger sources can be enabled by providing an OR'ed list of options available in enumeration ::ftm_external_trigger_t. */ @@ -359,7 +371,7 @@ extern "C" { /*! * @brief Ungates the FTM clock and configures the peripheral for basic operation. * - * @note This API should be called at the beginning of the application using the FTM driver. + * @note This API should be called at the beginning of the application which is using the FTM driver. * * @param base FTM peripheral base address * @param config Pointer to the user configuration structure. @@ -508,19 +520,6 @@ void FTM_SetupDualEdgeCapture(FTM_Type *base, /*! @}*/ -/*! - * @brief Configures the parameters and activates the quadrature decoder mode. - * - * @param base FTM peripheral base address - * @param phaseAParams Phase A configuration parameters - * @param phaseBParams Phase B configuration parameters - * @param quadMode Selects encoding mode used in quadrature decoder mode - */ -void FTM_SetupQuadDecode(FTM_Type *base, - const ftm_phase_params_t *phaseAParams, - const ftm_phase_params_t *phaseBParams, - ftm_quad_decode_mode_t quadMode); - /*! * @brief Sets up the working of the FTM fault protection. * @@ -593,6 +592,48 @@ void FTM_ClearStatusFlags(FTM_Type *base, uint32_t mask); /*! @}*/ +/*! + * @name Read and write the timer period + * @{ + */ + +/*! + * @brief Sets the timer period in units of ticks. + * + * Timers counts from 0 until it equals the count value set here. The count value is written to + * the MOD register. + * + * @note + * 1. This API allows the user to use the FTM module as a timer. Do not mix usage + * of this API with FTM's PWM setup API's. + * 2. Call the utility macros provided in the fsl_common.h to convert usec or msec to ticks. + * + * @param base FTM peripheral base address + * @param ticks A timer period in units of ticks, which should be equal or greater than 1. + */ +static inline void FTM_SetTimerPeriod(FTM_Type *base, uint32_t ticks) +{ + base->MOD = ticks; +} + +/*! + * @brief Reads the current timer counting value. + * + * This function returns the real-time timer counting value in a range from 0 to a + * timer period. + * + * @note Call the utility macros provided in the fsl_common.h to convert ticks to usec or msec. + * + * @param base FTM peripheral base address + * + * @return The current counter value in ticks + */ +static inline uint32_t FTM_GetCurrentTimerCount(FTM_Type *base) +{ + return (uint32_t)((base->CNT & FTM_CNT_COUNT_MASK) >> FTM_CNT_COUNT_SHIFT); +} + +/*! @}*/ /*! * @name Timer Start and Stop * @{ @@ -711,7 +752,7 @@ static inline void FTM_SetOutputMask(FTM_Type *base, ftm_chnl_t chnlNumber, bool #if defined(FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) && (FSL_FEATURE_FTM_HAS_ENABLE_PWM_OUTPUT) /*! - * @brief Allows user to enable an output on an FTM channel. + * @brief Allows users to enable an output on an FTM channel. * * To enable the PWM channel output call this function with val=true. For input mode, * call this function with val=false. @@ -816,6 +857,76 @@ static inline void FTM_SetInvertEnable(FTM_Type *base, ftm_chnl_t chnlPairNumber /*! @}*/ +/*! + * @name Quad Decoder + * @{ + */ + +/*! + * @brief Configures the parameters and activates the quadrature decoder mode. + * + * @param base FTM peripheral base address + * @param phaseAParams Phase A configuration parameters + * @param phaseBParams Phase B configuration parameters + * @param quadMode Selects encoding mode used in quadrature decoder mode + */ +void FTM_SetupQuadDecode(FTM_Type *base, + const ftm_phase_params_t *phaseAParams, + const ftm_phase_params_t *phaseBParams, + ftm_quad_decode_mode_t quadMode); + +/*! + * @brief Gets the FTM Quad Decoder flags. + * + * @param base FTM peripheral base address. + * @return Flag mask of FTM Quad Decoder, see #_ftm_quad_decoder_flags. + */ +static inline uint32_t FTM_GetQuadDecoderFlags(FTM_Type *base) +{ + return base->QDCTRL & (FTM_QDCTRL_QUADIR_MASK | FTM_QDCTRL_TOFDIR_MASK); +} + +/*! + * @brief Sets the modulo values for Quad Decoder. + * + * The modulo values configure the minimum and maximum values that the Quad decoder counter can reach. After the counter goes + * over, the counter value goes to the other side and decrease/increase again. + * + * @param base FTM peripheral base address. + * @param startValue The low limit value for Quad Decoder counter. + * @param overValue The high limit value for Quad Decoder counter. + */ +static inline void FTM_SetQuadDecoderModuloValue(FTM_Type *base, uint32_t startValue, uint32_t overValue) +{ + base->CNTIN = startValue; + base->MOD = overValue; +} + +/*! + * @brief Gets the current Quad Decoder counter value. + * + * @param base FTM peripheral base address. + * @return Current quad Decoder counter value. + */ +static inline uint32_t FTM_GetQuadDecoderCounterValue(FTM_Type *base) +{ + return base->CNT; +} + +/*! + * @brief Clears the current Quad Decoder counter value. + * + * The counter is set as the initial value. + * + * @param base FTM peripheral base address. + */ +static inline void FTM_ClearQuadDecoderCounterValue(FTM_Type *base) +{ + base->CNT = base->CNTIN; +} + +/*! @}*/ + /*! * @brief Enables or disables the FTM software trigger for PWM synchronization. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_gpio.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_gpio.c index 8fc068f2d6..b40ee3ac11 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_gpio.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_gpio.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -57,7 +57,7 @@ static uint32_t GPIO_GetInstance(GPIO_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_GPIO_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_gpioBases); instance++) { if (s_gpioBases[instance] == base) { @@ -65,7 +65,7 @@ static uint32_t GPIO_GetInstance(GPIO_Type *base) } } - assert(instance < FSL_FEATURE_SOC_GPIO_COUNT); + assert(instance < ARRAY_SIZE(s_gpioBases)); return instance; } @@ -103,6 +103,14 @@ void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask) portBase->ISFR = mask; } +#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER +void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute) +{ + base->GACR = ((uint32_t)attribute << GPIO_GACR_ACB0_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB1_SHIFT) | + ((uint32_t)attribute << GPIO_GACR_ACB2_SHIFT) | ((uint32_t)attribute << GPIO_GACR_ACB3_SHIFT); +} +#endif + #if defined(FSL_FEATURE_SOC_FGPIO_COUNT) && FSL_FEATURE_SOC_FGPIO_COUNT /******************************************************************************* @@ -130,7 +138,7 @@ static uint32_t FGPIO_GetInstance(FGPIO_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_FGPIO_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_fgpioBases); instance++) { if (s_fgpioBases[instance] == base) { @@ -138,7 +146,7 @@ static uint32_t FGPIO_GetInstance(FGPIO_Type *base) } } - assert(instance < FSL_FEATURE_SOC_FGPIO_COUNT); + assert(instance < ARRAY_SIZE(s_fgpioBases)); return instance; } @@ -176,4 +184,12 @@ void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask) portBase->ISFR = mask; } +#if defined(FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_FGPIO_HAS_ATTRIBUTE_CHECKER +void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute) +{ + base->GACR = (attribute << FGPIO_GACR_ACB0_SHIFT) | (attribute << FGPIO_GACR_ACB1_SHIFT) | + (attribute << FGPIO_GACR_ACB2_SHIFT) | (attribute << FGPIO_GACR_ACB3_SHIFT); +} +#endif + #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_gpio.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_gpio.h index 6eaaaa0874..410e2b8ee4 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_gpio.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_gpio.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,14 +12,14 @@ * 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 + * 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 SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * 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 @@ -38,38 +38,60 @@ * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief GPIO driver version 2.1.0. */ -#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*! @brief GPIO driver version 2.1.1. */ +#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*@}*/ -/*! @brief GPIO direction definition*/ +/*! @brief GPIO direction definition */ typedef enum _gpio_pin_direction { kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/ kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/ } gpio_pin_direction_t; +#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER +/*! @brief GPIO checker attribute */ +typedef enum _gpio_checker_attribute +{ + kGPIO_UsernonsecureRWUsersecureRWPrivilegedsecureRW = + 0x00U, /*!< User nonsecure:Read+Write; User Secure:Read+Write; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureRUsersecureRWPrivilegedsecureRW = + 0x01U, /*!< User nonsecure:Read; User Secure:Read+Write; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureNUsersecureRWPrivilegedsecureRW = + 0x02U, /*!< User nonsecure:None; User Secure:Read+Write; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureRUsersecureRPrivilegedsecureRW = + 0x03U, /*!< User nonsecure:Read; User Secure:Read; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureNUsersecureRPrivilegedsecureRW = + 0x04U, /*!< User nonsecure:None; User Secure:Read; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureNUsersecureNPrivilegedsecureRW = + 0x05U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read+Write */ + kGPIO_UsernonsecureNUsersecureNPrivilegedsecureR = + 0x06U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:Read */ + kGPIO_UsernonsecureNUsersecureNPrivilegedsecureN = + 0x07U, /*!< User nonsecure:None; User Secure:None; Privileged Secure:None */ + kGPIO_IgnoreAttributeCheck = 0x10U, /*!< Ignores the attribute check */ +} gpio_checker_attribute_t; +#endif + /*! * @brief The GPIO pin configuration structure. * - * Every pin can only be configured as either output pin or input pin at a time. - * If configured as a input pin, then leave the outputConfig unused - * Note : In some cases, the corresponding port property should be configured in advance - * with the PORT_SetPinConfig() + * Each pin can only be configured as either an output pin or an input pin at a time. + * If configured as an input pin, leave the outputConfig unused. + * Note that in some use cases, the corresponding port property should be configured in advance + * with the PORT_SetPinConfig(). */ typedef struct _gpio_pin_config { - gpio_pin_direction_t pinDirection; /*!< gpio direction, input or output */ - /* Output configurations, please ignore if configured as a input one */ - uint8_t outputLogic; /*!< Set default output logic, no use in input */ + gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */ + /* Output configurations; ignore if configured as an input pin */ + uint8_t outputLogic; /*!< Set a default output logic, which has no use in input */ } gpio_pin_config_t; /*! @} */ @@ -93,10 +115,10 @@ extern "C" { /*! * @brief Initializes a GPIO pin used by the board. * - * To initialize the GPIO, define a pin configuration, either input or output, in the user file. + * To initialize the GPIO, define a pin configuration, as either input or output, in the user file. * Then, call the GPIO_PinInit() function. * - * This is an example to define an input pin or output pin configuration: + * This is an example to define an input pin or an output pin configuration. * @code * // Define a digital input pin configuration, * gpio_pin_config_t config = @@ -112,7 +134,7 @@ extern "C" { * } * @endcode * - * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) * @param pin GPIO port pin number * @param config GPIO pin configuration pointer */ @@ -126,29 +148,29 @@ void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *config /*! * @brief Sets the output level of the multiple GPIO pins to the logic 1 or 0. * - * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param pin GPIO pin's number + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param pin GPIO pin number * @param output GPIO pin output logic level. - * - 0: corresponding pin output low logic level. - * - 1: corresponding pin output high logic level. + * - 0: corresponding pin output low-logic level. + * - 1: corresponding pin output high-logic level. */ static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t output) { if (output == 0U) { - base->PCOR = 1 << pin; + base->PCOR = 1U << pin; } else { - base->PSOR = 1 << pin; + base->PSOR = 1U << pin; } } /*! * @brief Sets the output level of the multiple GPIO pins to the logic 1. * - * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param mask GPIO pins' numbers macro + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro */ static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask) { @@ -158,8 +180,8 @@ static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask) /*! * @brief Sets the output level of the multiple GPIO pins to the logic 0. * - * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param mask GPIO pins' numbers macro + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro */ static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask) { @@ -167,10 +189,10 @@ static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t mask) } /*! - * @brief Reverses current output logic of the multiple GPIO pins. + * @brief Reverses the current output logic of the multiple GPIO pins. * - * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param mask GPIO pins' numbers macro + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro */ static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask) { @@ -182,13 +204,13 @@ static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t mask) /*@{*/ /*! - * @brief Reads the current input value of the whole GPIO port. + * @brief Reads the current input value of the GPIO port. * - * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param pin GPIO pin's number + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param pin GPIO pin number * @retval GPIO port input value - * - 0: corresponding pin input low logic level. - * - 1: corresponding pin input high logic level. + * - 0: corresponding pin input low-logic level. + * - 1: corresponding pin input high-logic level. */ static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin) { @@ -200,7 +222,7 @@ static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin) /*@{*/ /*! - * @brief Reads whole GPIO port interrupt status flag. + * @brief Reads the GPIO port interrupt status flag. * * If a pin is configured to generate the DMA request, the corresponding flag * is cleared automatically at the completion of the requested DMA transfer. @@ -208,20 +230,34 @@ static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin) * If configured for a level sensitive interrupt that remains asserted, the flag * is set again immediately. * - * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @retval Current GPIO port interrupt status flag, for example, 0x00010001 means the + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @retval The current GPIO port interrupt status flag, for example, 0x00010001 means the * pin 0 and 17 have the interrupt. */ uint32_t GPIO_GetPinsInterruptFlags(GPIO_Type *base); /*! - * @brief Clears multiple GPIO pins' interrupt status flag. + * @brief Clears multiple GPIO pin interrupt status flags. * - * @param base GPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param mask GPIO pins' numbers macro + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro */ void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask); +#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER +/*! + * @brief The GPIO module supports a device-specific number of data ports, organized as 32-bit + * words. Each 32-bit data port includes a GACR register, which defines the byte-level + * attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data + * bytes in the GACR follow a standard little endian + * data convention. + * + * @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.) + * @param mask GPIO pin number macro + */ +void GPIO_CheckAttributeBytes(GPIO_Type *base, gpio_checker_attribute_t attribute); +#endif + /*@}*/ /*! @} */ @@ -231,10 +267,10 @@ void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask); */ /* - * Introduce the FGPIO feature. + * Introduces the FGPIO feature. * - * The FGPIO features are only support on some of Kinetis chips. The FGPIO registers are aliased to the IOPORT - * interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and will therefore + * The FGPIO features are only support on some Kinetis MCUs. The FGPIO registers are aliased to the IOPORT + * interface. Accesses via the IOPORT interface occur in parallel with any instruction fetches and * complete in a single cycle. This aliased Fast GPIO memory map is called FGPIO. */ @@ -246,10 +282,10 @@ void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask); /*! * @brief Initializes a FGPIO pin used by the board. * - * To initialize the FGPIO driver, define a pin configuration, either input or output, in the user file. + * To initialize the FGPIO driver, define a pin configuration, as either input or output, in the user file. * Then, call the FGPIO_PinInit() function. * - * This is an example to define an input pin or output pin configuration: + * This is an example to define an input pin or an output pin configuration: * @code * // Define a digital input pin configuration, * gpio_pin_config_t config = @@ -265,7 +301,7 @@ void GPIO_ClearPinsInterruptFlags(GPIO_Type *base, uint32_t mask); * } * @endcode * - * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) * @param pin FGPIO port pin number * @param config FGPIO pin configuration pointer */ @@ -279,11 +315,11 @@ void FGPIO_PinInit(FGPIO_Type *base, uint32_t pin, const gpio_pin_config_t *conf /*! * @brief Sets the output level of the multiple FGPIO pins to the logic 1 or 0. * - * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param pin FGPIO pin's number + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param pin FGPIO pin number * @param output FGPIOpin output logic level. - * - 0: corresponding pin output low logic level. - * - 1: corresponding pin output high logic level. + * - 0: corresponding pin output low-logic level. + * - 1: corresponding pin output high-logic level. */ static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, uint8_t output) { @@ -300,8 +336,8 @@ static inline void FGPIO_WritePinOutput(FGPIO_Type *base, uint32_t pin, uint8_t /*! * @brief Sets the output level of the multiple FGPIO pins to the logic 1. * - * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param mask FGPIO pins' numbers macro + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro */ static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask) { @@ -311,8 +347,8 @@ static inline void FGPIO_SetPinsOutput(FGPIO_Type *base, uint32_t mask) /*! * @brief Sets the output level of the multiple FGPIO pins to the logic 0. * - * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param mask FGPIO pins' numbers macro + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro */ static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask) { @@ -320,10 +356,10 @@ static inline void FGPIO_ClearPinsOutput(FGPIO_Type *base, uint32_t mask) } /*! - * @brief Reverses current output logic of the multiple FGPIO pins. + * @brief Reverses the current output logic of the multiple FGPIO pins. * - * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param mask FGPIO pins' numbers macro + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro */ static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask) { @@ -335,13 +371,13 @@ static inline void FGPIO_TogglePinsOutput(FGPIO_Type *base, uint32_t mask) /*@{*/ /*! - * @brief Reads the current input value of the whole FGPIO port. + * @brief Reads the current input value of the FGPIO port. * - * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param pin FGPIO pin's number + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param pin FGPIO pin number * @retval FGPIO port input value - * - 0: corresponding pin input low logic level. - * - 1: corresponding pin input high logic level. + * - 0: corresponding pin input low-logic level. + * - 1: corresponding pin input high-logic level. */ static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin) { @@ -353,28 +389,42 @@ static inline uint32_t FGPIO_ReadPinInput(FGPIO_Type *base, uint32_t pin) /*@{*/ /*! - * @brief Reads the whole FGPIO port interrupt status flag. + * @brief Reads the FGPIO port interrupt status flag. * - * If a pin is configured to generate the DMA request, the corresponding flag + * If a pin is configured to generate the DMA request, the corresponding flag * is cleared automatically at the completion of the requested DMA transfer. * Otherwise, the flag remains set until a logic one is written to that flag. - * If configured for a level sensitive interrupt that remains asserted, the flag + * If configured for a level-sensitive interrupt that remains asserted, the flag * is set again immediately. * - * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @retval Current FGPIO port interrupt status flags, for example, 0x00010001 means the + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @retval The current FGPIO port interrupt status flags, for example, 0x00010001 means the * pin 0 and 17 have the interrupt. */ uint32_t FGPIO_GetPinsInterruptFlags(FGPIO_Type *base); /*! - * @brief Clears the multiple FGPIO pins' interrupt status flag. + * @brief Clears the multiple FGPIO pin interrupt status flag. * - * @param base FGPIO peripheral base pointer(GPIOA, GPIOB, GPIOC, and so on.) - * @param mask FGPIO pins' numbers macro + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro */ void FGPIO_ClearPinsInterruptFlags(FGPIO_Type *base, uint32_t mask); +#if defined(FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER) && FSL_FEATURE_GPIO_HAS_ATTRIBUTE_CHECKER +/*! + * @brief The FGPIO module supports a device-specific number of data ports, organized as 32-bit + * words. Each 32-bit data port includes a GACR register, which defines the byte-level + * attributes required for a successful access to the GPIO programming model. The attribute controls for the 4 data + * bytes in the GACR follow a standard little endian + * data convention. + * + * @param base FGPIO peripheral base pointer (FGPIOA, FGPIOB, FGPIOC, and so on.) + * @param mask FGPIO pin number macro + */ +void FGPIO_CheckAttributeBytes(FGPIO_Type *base, gpio_checker_attribute_t attribute); +#endif + /*@}*/ #endif /* FSL_FEATURE_SOC_FGPIO_COUNT */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c.c index e77a383239..6c9770af25 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -75,6 +75,19 @@ typedef void (*i2c_isr_t)(I2C_Type *base, void *i2cHandle); */ uint32_t I2C_GetInstance(I2C_Type *base); +/*! +* @brief Set SCL/SDA hold time, this API receives SCL stop hold time, calculate the +* closest SCL divider and MULT value for the SDA hold time, SCL start and SCL stop +* hold time. To reduce the ROM size, SDA/SCL hold value mapping table is not provided, +* assume SCL divider = SCL stop hold value *2 to get the closest SCL divider value and MULT +* value, then the related SDA hold time, SCL start and SCL stop hold time is used. +* +* @param base I2C peripheral base address. +* @param sourceClock_Hz I2C functional clock frequency in Hertz. +* @param sclStopHoldTime_ns SCL stop hold time in ns. +*/ +static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz); + /*! * @brief Set up master transfer, send slave address and decide the initial * transfer state. @@ -125,20 +138,22 @@ static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle); static void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT] = {NULL}; /*! @brief SCL clock divider used to calculate baudrate. */ -const uint16_t s_i2cDividerTable[] = {20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, - 48, 56, 68, 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, - 112, 128, 144, 160, 192, 240, 160, 192, 224, 256, 288, 320, 384, - 480, 320, 384, 448, 512, 576, 640, 768, 960, 640, 768, 896, 1024, - 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840}; +static const uint16_t s_i2cDividerTable[] = { + 20, 22, 24, 26, 28, 30, 34, 40, 28, 32, 36, 40, 44, 48, 56, 68, + 48, 56, 64, 72, 80, 88, 104, 128, 80, 96, 112, 128, 144, 160, 192, 240, + 160, 192, 224, 256, 288, 320, 384, 480, 320, 384, 448, 512, 576, 640, 768, 960, + 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840}; /*! @brief Pointers to i2c bases for each instance. */ static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS; /*! @brief Pointers to i2c IRQ number for each instance. */ -const IRQn_Type s_i2cIrqs[] = I2C_IRQS; +static const IRQn_Type s_i2cIrqs[] = I2C_IRQS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to i2c clocks for each instance. */ -const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS; +static const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Pointer to master IRQ handler for each instance. */ static i2c_isr_t s_i2cMasterIsr; @@ -155,7 +170,7 @@ uint32_t I2C_GetInstance(I2C_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_I2C_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_i2cBases); instance++) { if (s_i2cBases[instance] == base) { @@ -163,16 +178,63 @@ uint32_t I2C_GetInstance(I2C_Type *base) } } - assert(instance < FSL_FEATURE_SOC_I2C_COUNT); + assert(instance < ARRAY_SIZE(s_i2cBases)); return instance; } +static void I2C_SetHoldTime(I2C_Type *base, uint32_t sclStopHoldTime_ns, uint32_t sourceClock_Hz) +{ + uint32_t multiplier; + uint32_t computedSclHoldTime; + uint32_t absError; + uint32_t bestError = UINT32_MAX; + uint32_t bestMult = 0u; + uint32_t bestIcr = 0u; + uint8_t mult; + uint8_t i; + + /* Search for the settings with the lowest error. Mult is the MULT field of the I2C_F register, + * and ranges from 0-2. It selects the multiplier factor for the divider. */ + /* SDA hold time = bus period (s) * mul * SDA hold value. */ + /* SCL start hold time = bus period (s) * mul * SCL start hold value. */ + /* SCL stop hold time = bus period (s) * mul * SCL stop hold value. */ + + for (mult = 0u; (mult <= 2u) && (bestError != 0); ++mult) + { + multiplier = 1u << mult; + + /* Scan table to find best match. */ + for (i = 0u; i < sizeof(s_i2cDividerTable) / sizeof(s_i2cDividerTable[0]); ++i) + { + /* Assume SCL hold(stop) value = s_i2cDividerTable[i]/2. */ + computedSclHoldTime = ((multiplier * s_i2cDividerTable[i]) * 500000000U) / sourceClock_Hz; + absError = sclStopHoldTime_ns > computedSclHoldTime ? (sclStopHoldTime_ns - computedSclHoldTime) : + (computedSclHoldTime - sclStopHoldTime_ns); + + if (absError < bestError) + { + bestMult = mult; + bestIcr = i; + bestError = absError; + + /* If the error is 0, then we can stop searching because we won't find a better match. */ + if (absError == 0) + { + break; + } + } + } + } + + /* Set frequency register based on best settings. */ + base->F = I2C_F_MULT(bestMult) | I2C_F_ICR(bestIcr); +} + static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer) { status_t result = kStatus_Success; i2c_direction_t direction = xfer->direction; - uint16_t timeout = UINT16_MAX; /* Initialize the handle transfer information. */ handle->transfer = *xfer; @@ -183,27 +245,13 @@ static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t /* Initial transfer state. */ if (handle->transfer.subaddressSize > 0) { - handle->state = kSendCommandState; if (xfer->direction == kI2C_Read) { direction = kI2C_Write; } } - else - { - handle->state = kCheckAddressState; - } - /* Wait until the data register is ready for transmit. */ - while ((!(base->S & kI2C_TransferCompleteFlag)) && (--timeout)) - { - } - - /* Failed to start the transfer. */ - if (timeout == 0) - { - return kStatus_I2C_Timeout; - } + handle->state = kCheckAddressState; /* Clear all status before transfer. */ I2C_MasterClearStatusFlags(base, kClearFlags); @@ -265,34 +313,41 @@ static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_han result = kStatus_Success; } - if (result) - { - return result; - } - /* Handle Check address state to check the slave address is Acked in slave probe application. */ if (handle->state == kCheckAddressState) { if (statusFlags & kI2C_ReceiveNakFlag) { - return kStatus_I2C_Nak; + result = kStatus_I2C_Addr_Nak; } else { - if (handle->transfer.direction == kI2C_Write) + if (handle->transfer.subaddressSize > 0) { - /* Next state, send data. */ - handle->state = kSendDataState; + handle->state = kSendCommandState; } else { - /* Next state, receive data begin. */ - handle->state = kReceiveDataBeginState; + if (handle->transfer.direction == kI2C_Write) + { + /* Next state, send data. */ + handle->state = kSendDataState; + } + else + { + /* Next state, receive data begin. */ + handle->state = kReceiveDataBeginState; + } } } } + if (result) + { + return result; + } + /* Run state machine. */ switch (handle->state) { @@ -375,6 +430,10 @@ static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_han { result = I2C_MasterStop(base); } + else + { + base->C1 |= I2C_C1_TX_MASK; + } } /* Send NAK at the last receive byte. */ @@ -407,6 +466,7 @@ static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle) { s_i2cSlaveIsr(base, handle); } + __DSB(); } void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz) @@ -415,12 +475,26 @@ void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uin /* Temporary register for filter read. */ uint8_t fltReg; -#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION - uint8_t c2Reg; +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + uint8_t s2Reg; #endif - +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable I2C clock. */ CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset the module. */ + base->A1 = 0; + base->F = 0; + base->C1 = 0; + base->S = 0xFFU; + base->C2 = 0; +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + base->FLT = 0x50U; +#elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + base->FLT = 0x40U; +#endif + base->RA = 0; /* Disable I2C prior to configuring it. */ base->C1 &= ~(I2C_C1_IICEN_MASK); @@ -431,14 +505,6 @@ void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uin /* Configure baud rate. */ I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz); -#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION - /* Configure high drive feature. */ - c2Reg = base->C2; - c2Reg &= ~(I2C_C2_HDRS_MASK); - c2Reg |= I2C_C2_HDRS(masterConfig->enableHighDrive); - base->C2 = c2Reg; -#endif - /* Read out the FLT register. */ fltReg = base->FLT; @@ -455,6 +521,12 @@ void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uin /* Write the register value back to the filter register. */ base->FLT = fltReg; +/* Enable/Disable double buffering. */ +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + s2Reg = base->S2 & (~I2C_S2_DFEN_MASK); + base->S2 = s2Reg | I2C_S2_DFEN(masterConfig->enableDoubleBuffering); +#endif + /* Enable the I2C peripheral based on the configuration. */ base->C1 = I2C_C1_IICEN(masterConfig->enableMaster); } @@ -464,8 +536,10 @@ void I2C_MasterDeinit(I2C_Type *base) /* Disable I2C module. */ I2C_Enable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable I2C clock. */ CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig) @@ -475,11 +549,6 @@ void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig) /* Default baud rate at 100kbps. */ masterConfig->baudRate_Bps = 100000U; -/* Default pin high drive is disabled. */ -#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION - masterConfig->enableHighDrive = false; -#endif - /* Default stop hold enable is disabled. */ #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF masterConfig->enableStopHold = false; @@ -488,12 +557,21 @@ void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig) /* Default glitch filter value is no filter. */ masterConfig->glitchFilterWidth = 0U; +/* Default enable double buffering. */ +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + masterConfig->enableDoubleBuffering = true; +#endif + /* Enable the I2C peripheral. */ masterConfig->enableMaster = true; } void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask) { +#ifdef I2C_HAS_STOP_DETECT + uint8_t fltReg; +#endif + if (mask & kI2C_GlobalInterruptEnable) { base->C1 |= I2C_C1_IICIE_MASK; @@ -502,14 +580,28 @@ void I2C_EnableInterrupts(I2C_Type *base, uint32_t mask) #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT if (mask & kI2C_StopDetectInterruptEnable) { - base->FLT |= I2C_FLT_STOPIE_MASK; + fltReg = base->FLT; + + /* Keep STOPF flag. */ + fltReg &= ~I2C_FLT_STOPF_MASK; + + /* Stop detect enable. */ + fltReg |= I2C_FLT_STOPIE_MASK; + base->FLT = fltReg; } #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT if (mask & kI2C_StartStopDetectInterruptEnable) { - base->FLT |= I2C_FLT_SSIE_MASK; + fltReg = base->FLT; + + /* Keep STARTF and STOPF flags. */ + fltReg &= ~(I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK); + + /* Start and stop detect enable. */ + fltReg |= I2C_FLT_SSIE_MASK; + base->FLT = fltReg; } #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ } @@ -524,14 +616,14 @@ void I2C_DisableInterrupts(I2C_Type *base, uint32_t mask) #if defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT if (mask & kI2C_StopDetectInterruptEnable) { - base->FLT &= ~I2C_FLT_STOPIE_MASK; + base->FLT &= ~(I2C_FLT_STOPIE_MASK | I2C_FLT_STOPF_MASK); } #endif /* FSL_FEATURE_I2C_HAS_STOP_DETECT */ #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT if (mask & kI2C_StartStopDetectInterruptEnable) { - base->FLT &= ~I2C_FLT_SSIE_MASK; + base->FLT &= ~(I2C_FLT_SSIE_MASK | I2C_FLT_STOPF_MASK | I2C_FLT_STARTF_MASK); } #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ } @@ -623,7 +715,7 @@ status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_ base->F = savedMult & (~I2C_F_MULT_MASK); /* We are already in a transfer, so send a repeated start. */ - base->C1 |= I2C_C1_RSTA_MASK; + base->C1 |= I2C_C1_RSTA_MASK | I2C_C1_TX_MASK; /* Restore the multiplier factor. */ base->F = savedMult; @@ -690,7 +782,7 @@ uint32_t I2C_MasterGetStatusFlags(I2C_Type *base) return statusFlags; } -status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize) +status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags) { status_t result = kStatus_Success; uint8_t statusFlags = 0; @@ -728,7 +820,7 @@ status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t t result = kStatus_I2C_ArbitrationLost; } - if (statusFlags & kI2C_ReceiveNakFlag) + if ((statusFlags & kI2C_ReceiveNakFlag) && txSize) { base->S = kI2C_ReceiveNakFlag; result = kStatus_I2C_Nak; @@ -741,10 +833,19 @@ status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t t } } + if (((result == kStatus_Success) && (!(flags & kI2C_TransferNoStopFlag))) || (result == kStatus_I2C_Nak)) + { + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; + + /* Send stop. */ + result = I2C_MasterStop(base); + } + return result; } -status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize) +status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags) { status_t result = kStatus_Success; volatile uint8_t dummy = 0; @@ -786,8 +887,16 @@ status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize) /* Single byte use case. */ if (rxSize == 0) { - /* Read the final byte. */ - result = I2C_MasterStop(base); + if (!(flags & kI2C_TransferNoStopFlag)) + { + /* Issue STOP command before reading last byte. */ + result = I2C_MasterStop(base); + } + else + { + /* Change direction to Tx to avoid extra clocks. */ + base->C1 |= I2C_C1_TX_MASK; + } } if (rxSize == 1) @@ -840,72 +949,6 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer) return result; } - /* Send subaddress. */ - if (xfer->subaddressSize) - { - do - { - /* Wait until data transfer complete. */ - while (!(base->S & kI2C_IntPendingFlag)) - { - } - - /* Clear interrupt pending flag. */ - base->S = kI2C_IntPendingFlag; - - /* Check if there's transfer error. */ - result = I2C_CheckAndClearError(base, base->S); - - if (result) - { - if (result == kStatus_I2C_Nak) - { - I2C_MasterStop(base); - } - - return result; - } - - xfer->subaddressSize--; - base->D = ((xfer->subaddress) >> (8 * xfer->subaddressSize)); - - } while ((xfer->subaddressSize > 0) && (result == kStatus_Success)); - - if (xfer->direction == kI2C_Read) - { - /* Wait until data transfer complete. */ - while (!(base->S & kI2C_IntPendingFlag)) - { - } - - /* Clear pending flag. */ - base->S = kI2C_IntPendingFlag; - - /* Check if there's transfer error. */ - result = I2C_CheckAndClearError(base, base->S); - - if (result) - { - if (result == kStatus_I2C_Nak) - { - I2C_MasterStop(base); - } - - return result; - } - - /* Send repeated start and slave address. */ - result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, kI2C_Read); - - /* Return if error. */ - if (result) - { - return result; - } - } - } - - /* Wait until address + command transfer complete. */ while (!(base->S & kI2C_IntPendingFlag)) { } @@ -918,32 +961,92 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer) { if (result == kStatus_I2C_Nak) { + result = kStatus_I2C_Addr_Nak; + I2C_MasterStop(base); } return result; } + /* Send subaddress. */ + if (xfer->subaddressSize) + { + do + { + /* Clear interrupt pending flag. */ + base->S = kI2C_IntPendingFlag; + + xfer->subaddressSize--; + base->D = ((xfer->subaddress) >> (8 * xfer->subaddressSize)); + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + if (result == kStatus_I2C_Nak) + { + I2C_MasterStop(base); + } + + return result; + } + + } while ((xfer->subaddressSize > 0) && (result == kStatus_Success)); + + if (xfer->direction == kI2C_Read) + { + /* Clear pending flag. */ + base->S = kI2C_IntPendingFlag; + + /* Send repeated start and slave address. */ + result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, kI2C_Read); + + /* Return if error. */ + if (result) + { + return result; + } + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + if (result == kStatus_I2C_Nak) + { + result = kStatus_I2C_Addr_Nak; + + I2C_MasterStop(base); + } + + return result; + } + } + } + /* Transmit data. */ if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0)) { /* Send Data. */ - result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize); - - if (((result == kStatus_Success) && (!(xfer->flags & kI2C_TransferNoStopFlag))) || (result == kStatus_I2C_Nak)) - { - /* Clear the IICIF flag. */ - base->S = kI2C_IntPendingFlag; - - /* Send stop. */ - result = I2C_MasterStop(base); - } + result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags); } /* Receive Data. */ if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0)) { - result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize); + result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags); } return result; @@ -1006,11 +1109,37 @@ void I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle) { assert(handle); + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + /* Disable interrupt. */ I2C_DisableInterrupts(base, kI2C_GlobalInterruptEnable); /* Reset the state to idle. */ handle->state = kIdleState; + + /* Send STOP signal. */ + if (handle->transfer.direction == kI2C_Read) + { + base->C1 |= I2C_C1_TXAK_MASK; + while (!(base->S & kI2C_IntPendingFlag)) + { + } + base->S = kI2C_IntPendingFlag; + + base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + dummy = base->D; + } + else + { + while (!(base->S & kI2C_IntPendingFlag)) + { + } + base->S = kI2C_IntPendingFlag; + base->C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + } } status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count) @@ -1044,7 +1173,8 @@ void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle) if (isDone || result) { /* Send stop command if transfer done or received Nak. */ - if ((!(handle->transfer.flags & kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak)) + if ((!(handle->transfer.flags & kI2C_TransferNoStopFlag)) || (result == kStatus_I2C_Nak) || + (result == kStatus_I2C_Addr_Nak)) { /* Ensure stop command is a need. */ if ((base->C1 & I2C_C1_MST_MASK)) @@ -1070,13 +1200,28 @@ void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle) } } -void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig) +void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz) { assert(slaveConfig); uint8_t tmpReg; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset the module. */ + base->A1 = 0; + base->F = 0; + base->C1 = 0; + base->S = 0xFFU; + base->C2 = 0; +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + base->FLT = 0x50U; +#elif defined(FSL_FEATURE_I2C_HAS_STOP_DETECT) && FSL_FEATURE_I2C_HAS_STOP_DETECT + base->FLT = 0x40U; +#endif + base->RA = 0; /* Configure addressing mode. */ switch (slaveConfig->addressingMode) @@ -1101,15 +1246,20 @@ void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig) tmpReg &= ~I2C_C1_WUEN_MASK; base->C1 = tmpReg | I2C_C1_WUEN(slaveConfig->enableWakeUp) | I2C_C1_IICEN(slaveConfig->enableSlave); - /* Configure general call & baud rate control & high drive feature. */ + /* Configure general call & baud rate control. */ tmpReg = base->C2; tmpReg &= ~(I2C_C2_SBRC_MASK | I2C_C2_GCAEN_MASK); tmpReg |= I2C_C2_SBRC(slaveConfig->enableBaudRateCtl) | I2C_C2_GCAEN(slaveConfig->enableGeneralCall); -#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION - tmpReg &= ~I2C_C2_HDRS_MASK; - tmpReg |= I2C_C2_HDRS(slaveConfig->enableHighDrive); -#endif base->C2 = tmpReg; + +/* Enable/Disable double buffering. */ +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + tmpReg = base->S2 & (~I2C_S2_DFEN_MASK); + base->S2 = tmpReg | I2C_S2_DFEN(slaveConfig->enableDoubleBuffering); +#endif + + /* Set hold time. */ + I2C_SetHoldTime(base, slaveConfig->sclStopHoldTime_ns, srcClock_Hz); } void I2C_SlaveDeinit(I2C_Type *base) @@ -1117,8 +1267,10 @@ void I2C_SlaveDeinit(I2C_Type *base) /* Disable I2C module. */ I2C_Enable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable I2C clock. */ CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig) @@ -1134,48 +1286,106 @@ void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig) /* Slave address match waking up MCU from low power mode is disabled. */ slaveConfig->enableWakeUp = false; -#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION - /* Default pin high drive is disabled. */ - slaveConfig->enableHighDrive = false; -#endif - /* Independent slave mode baud rate at maximum frequency is disabled. */ slaveConfig->enableBaudRateCtl = false; +/* Default enable double buffering. */ +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + slaveConfig->enableDoubleBuffering = true; +#endif + + /* Set default SCL stop hold time to 4us which is minimum requirement in I2C spec. */ + slaveConfig->sclStopHoldTime_ns = 4000; + /* Enable the I2C peripheral. */ slaveConfig->enableSlave = true; } status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize) { - return I2C_MasterWriteBlocking(base, txBuff, txSize); + status_t result = kStatus_Success; + volatile uint8_t dummy = 0; + + /* Add this to avoid build warning. */ + dummy++; + +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Check start flag. */ + while (!(base->FLT & I2C_FLT_STARTF_MASK)) + { + } + /* Clear STARTF flag. */ + base->FLT |= I2C_FLT_STARTF_MASK; + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ + + /* Wait for address match flag. */ + while (!(base->S & kI2C_AddressMatchFlag)) + { + } + + /* Read dummy to release bus. */ + dummy = base->D; + + result = I2C_MasterWriteBlocking(base, txBuff, txSize, kI2C_TransferDefaultFlag); + + /* Switch to receive mode. */ + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + + /* Read dummy to release bus. */ + dummy = base->D; + + return result; } void I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize) { - /* Clear the IICIF flag. */ - base->S = kI2C_IntPendingFlag; + volatile uint8_t dummy = 0; - /* Wait until the data register is ready for receive. */ - while (!(base->S & kI2C_TransferCompleteFlag)) + /* Add this to avoid build warning. */ + dummy++; + +/* Wait until address match. */ +#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT + /* Check start flag. */ + while (!(base->FLT & I2C_FLT_STARTF_MASK)) { } + /* Clear STARTF flag. */ + base->FLT |= I2C_FLT_STARTF_MASK; + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; +#endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ + + /* Wait for address match and int pending flag. */ + while (!(base->S & kI2C_AddressMatchFlag)) + { + } + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Read dummy to release bus. */ + dummy = base->D; + + /* Clear the IICIF flag. */ + base->S = kI2C_IntPendingFlag; /* Setup the I2C peripheral to receive data. */ base->C1 &= ~(I2C_C1_TX_MASK); while (rxSize--) { + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } /* Clear the IICIF flag. */ base->S = kI2C_IntPendingFlag; /* Read from the data register. */ *rxBuff++ = base->D; - - /* Wait until data transfer complete. */ - while (!(base->S & kI2C_IntPendingFlag)) - { - } } } @@ -1226,7 +1436,7 @@ status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle handle->isBusy = true; /* Set up event mask. tx and rx are always enabled. */ - handle->eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent; + handle->eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | kI2C_SlaveGenaralcallEvent; /* Clear all flags. */ I2C_SlaveClearStatusFlags(base, kClearFlags); @@ -1315,7 +1525,10 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) } } - return; + if (!(status & kI2C_AddressMatchFlag)) + { + return; + } } #endif /* I2C_HAS_STOP_DETECT */ @@ -1328,7 +1541,7 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) /* Clear the interrupt flag. */ base->S = kI2C_IntPendingFlag; - xfer->event = kI2C_SlaveRepeatedStartEvent; + xfer->event = kI2C_SlaveStartEvent; if ((handle->eventMask & xfer->event) && (handle->callback)) { @@ -1385,31 +1598,12 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) handle->isBusy = true; xfer->event = kI2C_SlaveAddressMatchEvent; - if ((handle->eventMask & xfer->event) && (handle->callback)) - { - handle->callback(base, xfer, handle->userData); - } - /* Slave transmit, master reading from slave. */ if (status & kI2C_TransferDirectionFlag) { /* Change direction to send data. */ base->C1 |= I2C_C1_TX_MASK; - /* If we're out of data, invoke callback to get more. */ - if ((!xfer->data) || (!xfer->dataSize)) - { - xfer->event = kI2C_SlaveTransmitEvent; - - if (handle->callback) - { - handle->callback(base, xfer, handle->userData); - } - - /* Clear the transferred count now that we have a new buffer. */ - xfer->transferredCount = 0; - } - doTransmit = true; } else @@ -1417,6 +1611,30 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) /* Slave receive, master writing to slave. */ base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); + /* Read dummy to release the bus. */ + dummy = base->D; + + if (dummy == 0) + { + xfer->event = kI2C_SlaveGenaralcallEvent; + } + } + + if ((handle->eventMask & xfer->event) && (handle->callback)) + { + handle->callback(base, xfer, handle->userData); + } + } + /* Check transfer complete flag. */ + else if (status & kI2C_TransferCompleteFlag) + { + /* Slave transmit, master reading from slave. */ + if (status & kI2C_TransferDirectionFlag) + { + doTransmit = true; + } + else + { /* If we're out of data, invoke callback to get more. */ if ((!xfer->data) || (!xfer->dataSize)) { @@ -1431,20 +1649,6 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) xfer->transferredCount = 0; } - /* Read dummy to release the bus. */ - dummy = base->D; - } - } - /* Check transfer complete flag. */ - else if (status & kI2C_TransferCompleteFlag) - { - /* Slave transmit, master reading from slave. */ - if (status & kI2C_TransferDirectionFlag) - { - doTransmit = true; - } - else - { /* Slave receive, master writing to slave. */ uint8_t data = base->D; @@ -1480,6 +1684,20 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) /* Send data if there is the need. */ if (doTransmit) { + /* If we're out of data, invoke callback to get more. */ + if ((!xfer->data) || (!xfer->dataSize)) + { + xfer->event = kI2C_SlaveTransmitEvent; + + if (handle->callback) + { + handle->callback(base, xfer, handle->userData); + } + + /* Clear the transferred count now that we have a new buffer. */ + xfer->transferredCount = 0; + } + if (handle->transfer.dataSize) { /* Send data. */ @@ -1510,27 +1728,30 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) } } +#if defined(I2C0) void I2C0_DriverIRQHandler(void) { I2C_TransferCommonIRQHandler(I2C0, s_i2cHandle[0]); } +#endif -#if (FSL_FEATURE_SOC_I2C_COUNT > 1) +#if defined(I2C1) void I2C1_DriverIRQHandler(void) { I2C_TransferCommonIRQHandler(I2C1, s_i2cHandle[1]); } -#endif /* I2C COUNT > 1 */ +#endif -#if (FSL_FEATURE_SOC_I2C_COUNT > 2) +#if defined(I2C2) void I2C2_DriverIRQHandler(void) { I2C_TransferCommonIRQHandler(I2C2, s_i2cHandle[2]); } -#endif /* I2C COUNT > 2 */ -#if (FSL_FEATURE_SOC_I2C_COUNT > 3) +#endif + +#if defined(I2C3) void I2C3_DriverIRQHandler(void) { I2C_TransferCommonIRQHandler(I2C3, s_i2cHandle[3]); } -#endif /* I2C COUNT > 3 */ +#endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c.h index 41a9afbdd5..d55fd1d8ea 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,16 +37,14 @@ * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief I2C driver version 2.0.0. */ -#define FSL_I2C_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*! @brief I2C driver version 2.0.3. */ +#define FSL_I2C_DRIVER_VERSION (MAKE_VERSION(2, 0, 3)) /*@}*/ #if (defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT || \ @@ -62,6 +60,7 @@ enum _i2c_status kStatus_I2C_Nak = MAKE_STATUS(kStatusGroup_I2C, 2), /*!< NAK received during transfer. */ kStatus_I2C_ArbitrationLost = MAKE_STATUS(kStatusGroup_I2C, 3), /*!< Arbitration lost during transfer. */ kStatus_I2C_Timeout = MAKE_STATUS(kStatusGroup_I2C, 4), /*!< Wait event timeout. */ + kStatus_I2C_Addr_Nak = MAKE_STATUS(kStatusGroup_I2C, 5), /*!< NAK received during the address probe. */ }; /*! @@ -109,11 +108,11 @@ enum _i2c_interrupt_enable #endif /* FSL_FEATURE_I2C_HAS_START_STOP_DETECT */ }; -/*! @brief Direction of master and slave transfers. */ +/*! @brief The direction of master and slave transfers. */ typedef enum _i2c_direction { - kI2C_Write = 0x0U, /*!< Master transmit to slave. */ - kI2C_Read = 0x1U, /*!< Master receive from slave. */ + kI2C_Write = 0x0U, /*!< Master transmits to the slave. */ + kI2C_Read = 0x1U, /*!< Master receives from the slave. */ } i2c_direction_t; /*! @brief Addressing mode. */ @@ -126,17 +125,17 @@ typedef enum _i2c_slave_address_mode /*! @brief I2C transfer control flag. */ enum _i2c_master_transfer_flags { - kI2C_TransferDefaultFlag = 0x0U, /*!< Transfer starts with a start signal, stops with a stop signal. */ - kI2C_TransferNoStartFlag = 0x1U, /*!< Transfer starts without a start signal. */ - kI2C_TransferRepeatedStartFlag = 0x2U, /*!< Transfer starts with a repeated start signal. */ - kI2C_TransferNoStopFlag = 0x4U, /*!< Transfer ends without a stop signal. */ + kI2C_TransferDefaultFlag = 0x0U, /*!< A transfer starts with a start signal, stops with a stop signal. */ + kI2C_TransferNoStartFlag = 0x1U, /*!< A transfer starts without a start signal. */ + kI2C_TransferRepeatedStartFlag = 0x2U, /*!< A transfer starts with a repeated start signal. */ + kI2C_TransferNoStopFlag = 0x4U, /*!< A transfer ends without a stop signal. */ }; /*! * @brief Set of events sent to the callback for nonblocking slave transfers. * * These event enumerations are used for two related purposes. First, a bit mask created by OR'ing together - * events is passed to I2C_SlaveTransferNonBlocking() in order to specify which events to enable. + * events is passed to I2C_SlaveTransferNonBlocking() to specify which events to enable. * Then, when the slave callback is invoked, it is passed the current event through its @a transfer * parameter. * @@ -145,33 +144,35 @@ enum _i2c_master_transfer_flags typedef enum _i2c_slave_transfer_event { kI2C_SlaveAddressMatchEvent = 0x01U, /*!< Received the slave address after a start or repeated start. */ - kI2C_SlaveTransmitEvent = 0x02U, /*!< Callback is requested to provide data to transmit + kI2C_SlaveTransmitEvent = 0x02U, /*!< A callback is requested to provide data to transmit (slave-transmitter role). */ - kI2C_SlaveReceiveEvent = 0x04U, /*!< Callback is requested to provide a buffer in which to place received + kI2C_SlaveReceiveEvent = 0x04U, /*!< A callback is requested to provide a buffer in which to place received data (slave-receiver role). */ - kI2C_SlaveTransmitAckEvent = 0x08U, /*!< Callback needs to either transmit an ACK or NACK. */ + kI2C_SlaveTransmitAckEvent = 0x08U, /*!< A callback needs to either transmit an ACK or NACK. */ #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT - kI2C_SlaveRepeatedStartEvent = 0x10U, /*!< A repeated start was detected. */ + kI2C_SlaveStartEvent = 0x10U, /*!< A start/repeated start was detected. */ #endif - kI2C_SlaveCompletionEvent = 0x20U, /*!< A stop was detected or finished transfer, completing the transfer. */ + kI2C_SlaveCompletionEvent = 0x20U, /*!< A stop was detected or finished transfer, completing the transfer. */ + kI2C_SlaveGenaralcallEvent = 0x40U, /*!< Received the general call address after a start or repeated start. */ - /*! Bit mask of all available events. */ + /*! A bit mask of all available events. */ kI2C_SlaveAllEvents = kI2C_SlaveAddressMatchEvent | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | #if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_STOP_DETECT - kI2C_SlaveRepeatedStartEvent | + kI2C_SlaveStartEvent | #endif - kI2C_SlaveCompletionEvent, + kI2C_SlaveCompletionEvent | kI2C_SlaveGenaralcallEvent, } i2c_slave_transfer_event_t; /*! @brief I2C master user configuration. */ typedef struct _i2c_master_config { bool enableMaster; /*!< Enables the I2C peripheral at initialization time. */ -#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION - bool enableHighDrive; /*!< Controls the drive capability of the I2C pads. */ -#endif #if defined(FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF) && FSL_FEATURE_I2C_HAS_STOP_HOLD_OFF bool enableStopHold; /*!< Controls the stop hold enable. */ +#endif +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + bool enableDoubleBuffering; /*!< Controls double buffer enable; notice that + enabling the double buffer disables the clock stretch. */ #endif uint32_t baudRate_Bps; /*!< Baud rate configuration of I2C peripheral. */ uint8_t glitchFilterWidth; /*!< Controls the width of the glitch. */ @@ -181,15 +182,20 @@ typedef struct _i2c_master_config typedef struct _i2c_slave_config { bool enableSlave; /*!< Enables the I2C peripheral at initialization time. */ - bool enableGeneralCall; /*!< Enable general call addressing mode. */ - bool enableWakeUp; /*!< Enables/disables waking up MCU from low power mode. */ -#if defined(FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION) && FSL_FEATURE_I2C_HAS_HIGH_DRIVE_SELECTION - bool enableHighDrive; /*!< Controls the drive capability of the I2C pads. */ + bool enableGeneralCall; /*!< Enables the general call addressing mode. */ + bool enableWakeUp; /*!< Enables/disables waking up MCU from low-power mode. */ +#if defined(FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE) && FSL_FEATURE_I2C_HAS_DOUBLE_BUFFER_ENABLE + bool enableDoubleBuffering; /*!< Controls a double buffer enable; notice that + enabling the double buffer disables the clock stretch. */ #endif bool enableBaudRateCtl; /*!< Enables/disables independent slave baud rate on SCL in very fast I2C modes. */ - uint16_t slaveAddress; /*!< Slave address configuration. */ - uint16_t upperAddress; /*!< Maximum boundary slave address used in range matching mode. */ - i2c_slave_address_mode_t addressingMode; /*!< Addressing mode configuration of i2c_slave_address_mode_config_t. */ + uint16_t slaveAddress; /*!< A slave address configuration. */ + uint16_t upperAddress; /*!< A maximum boundary slave address used in a range matching mode. */ + i2c_slave_address_mode_t + addressingMode; /*!< An addressing mode configuration of i2c_slave_address_mode_config_t. */ + uint32_t sclStopHoldTime_ns; /*!< the delay from the rising edge of SCL (I2C clock) to the rising edge of SDA (I2C + data) while SCL is high (stop condition), SDA hold time and SCL start hold time + are also configured according to the SCL stop hold time. */ } i2c_slave_config_t; /*! @brief I2C master handle typedef. */ @@ -207,13 +213,13 @@ typedef struct _i2c_slave_handle i2c_slave_handle_t; /*! @brief I2C master transfer structure. */ typedef struct _i2c_master_transfer { - uint32_t flags; /*!< Transfer flag which controls the transfer. */ + uint32_t flags; /*!< A transfer flag which controls the transfer. */ uint8_t slaveAddress; /*!< 7-bit slave address. */ - i2c_direction_t direction; /*!< Transfer direction, read or write. */ - uint32_t subaddress; /*!< Sub address. Transferred MSB first. */ - uint8_t subaddressSize; /*!< Size of command buffer. */ - uint8_t *volatile data; /*!< Transfer buffer. */ - volatile size_t dataSize; /*!< Transfer size. */ + i2c_direction_t direction; /*!< A transfer direction, read or write. */ + uint32_t subaddress; /*!< A sub address. Transferred MSB first. */ + uint8_t subaddressSize; /*!< A size of the command buffer. */ + uint8_t *volatile data; /*!< A transfer buffer. */ + volatile size_t dataSize; /*!< A transfer size. */ } i2c_master_transfer_t; /*! @brief I2C master handle structure. */ @@ -221,20 +227,21 @@ struct _i2c_master_handle { i2c_master_transfer_t transfer; /*!< I2C master transfer copy. */ size_t transferSize; /*!< Total bytes to be transferred. */ - uint8_t state; /*!< Transfer state maintained during transfer. */ - i2c_master_transfer_callback_t completionCallback; /*!< Callback function called when transfer finished. */ - void *userData; /*!< Callback parameter passed to callback function. */ + uint8_t state; /*!< A transfer state maintained during transfer. */ + i2c_master_transfer_callback_t completionCallback; /*!< A callback function called when the transfer is finished. */ + void *userData; /*!< A callback parameter passed to the callback function. */ }; /*! @brief I2C slave transfer structure. */ typedef struct _i2c_slave_transfer { - i2c_slave_transfer_event_t event; /*!< Reason the callback is being invoked. */ - uint8_t *volatile data; /*!< Transfer buffer. */ - volatile size_t dataSize; /*!< Transfer size. */ + i2c_slave_transfer_event_t event; /*!< A reason that the callback is invoked. */ + uint8_t *volatile data; /*!< A transfer buffer. */ + volatile size_t dataSize; /*!< A transfer size. */ status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for #kI2C_SlaveCompletionEvent. */ - size_t transferredCount; /*!< Number of bytes actually transferred since start or last repeated start. */ + size_t transferredCount; /*!< A number of bytes actually transferred since the start or since the last repeated + start. */ } i2c_slave_transfer_t; /*! @brief I2C slave transfer callback typedef. */ @@ -243,11 +250,11 @@ typedef void (*i2c_slave_transfer_callback_t)(I2C_Type *base, i2c_slave_transfer /*! @brief I2C slave handle structure. */ struct _i2c_slave_handle { - bool isBusy; /*!< Whether transfer is busy. */ + volatile bool isBusy; /*!< Indicates whether a transfer is busy. */ i2c_slave_transfer_t transfer; /*!< I2C slave transfer copy. */ - uint32_t eventMask; /*!< Mask of enabled events. */ - i2c_slave_transfer_callback_t callback; /*!< Callback function called at transfer event. */ - void *userData; /*!< Callback parameter passed to callback. */ + uint32_t eventMask; /*!< A mask of enabled events. */ + i2c_slave_transfer_callback_t callback; /*!< A callback function called at the transfer event. */ + void *userData; /*!< A callback parameter passed to the callback. */ }; /******************************************************************************* @@ -267,12 +274,12 @@ extern "C" { * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock * and configure the I2C with master configuration. * - * @note This API should be called at the beginning of the application to use - * the I2C driver, or any operation to the I2C module could cause hard fault - * because clock is not enabled. The configuration structure can be filled by user - * from scratch, or be set with default values by I2C_MasterGetDefaultConfig(). + * @note This API should be called at the beginning of the application. + * Otherwise, any operation to the I2C module can cause a hard fault + * because the clock is not enabled. The configuration structure can be custom filled + * or it can be set with default values by using the I2C_MasterGetDefaultConfig(). * After calling this API, the master is ready to transfer. - * Example: + * This is an example. * @code * i2c_master_config_t config = { * .enableMaster = true, @@ -285,20 +292,20 @@ extern "C" { * @endcode * * @param base I2C base pointer - * @param masterConfig pointer to master configuration structure + * @param masterConfig A pointer to the master configuration structure * @param srcClock_Hz I2C peripheral clock frequency in Hz */ void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz); /*! * @brief Initializes the I2C peripheral. Call this API to ungate the I2C clock - * and initializes the I2C with slave configuration. + * and initialize the I2C with the slave configuration. * - * @note This API should be called at the beginning of the application to use - * the I2C driver, or any operation to the I2C module can cause a hard fault + * @note This API should be called at the beginning of the application. + * Otherwise, any operation to the I2C module can cause a hard fault * because the clock is not enabled. The configuration structure can partly be set - * with default values by I2C_SlaveGetDefaultConfig(), or can be filled by the user. - * Example + * with default values by I2C_SlaveGetDefaultConfig() or it can be custom filled by the user. + * This is an example. * @code * i2c_slave_config_t config = { * .enableSlave = true, @@ -307,15 +314,17 @@ void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uin * .slaveAddress = 0x1DU, * .enableWakeUp = false, * .enablehighDrive = false, - * .enableBaudRateCtl = false + * .enableBaudRateCtl = false, + * .sclStopHoldTime_ns = 4000 * }; - * I2C_SlaveInit(I2C0, &config); + * I2C_SlaveInit(I2C0, &config, 12000000U); * @endcode * * @param base I2C base pointer - * @param slaveConfig pointer to slave configuration structure + * @param slaveConfig A pointer to the slave configuration structure + * @param srcClock_Hz I2C peripheral clock frequency in Hz */ -void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig); +void I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz); /*! * @brief De-initializes the I2C master peripheral. Call this API to gate the I2C clock. @@ -335,28 +344,28 @@ void I2C_SlaveDeinit(I2C_Type *base); * @brief Sets the I2C master configuration structure to default values. * * The purpose of this API is to get the configuration structure initialized for use in the I2C_MasterConfigure(). - * Use the initialized structure unchanged in I2C_MasterConfigure(), or modify some fields of - * the structure before calling I2C_MasterConfigure(). - * Example: + * Use the initialized structure unchanged in the I2C_MasterConfigure() or modify + * the structure before calling the I2C_MasterConfigure(). + * This is an example. * @code * i2c_master_config_t config; * I2C_MasterGetDefaultConfig(&config); * @endcode - * @param masterConfig Pointer to the master configuration structure. + * @param masterConfig A pointer to the master configuration structure. */ void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig); /*! * @brief Sets the I2C slave configuration structure to default values. * - * The purpose of this API is to get the configuration structure initialized for use in I2C_SlaveConfigure(). + * The purpose of this API is to get the configuration structure initialized for use in the I2C_SlaveConfigure(). * Modify fields of the structure before calling the I2C_SlaveConfigure(). - * Example: + * This is an example. * @code * i2c_slave_config_t config; * I2C_SlaveGetDefaultConfig(&config); * @endcode - * @param slaveConfig Pointer to the slave configuration structure. + * @param slaveConfig A pointer to the slave configuration structure. */ void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig); @@ -364,7 +373,7 @@ void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig); * @brief Enables or disabless the I2C peripheral operation. * * @param base I2C base pointer - * @param enable pass true to enable module, false to disable module + * @param enable Pass true to enable and false to disable the module. */ static inline void I2C_Enable(I2C_Type *base, bool enable) { @@ -389,7 +398,7 @@ static inline void I2C_Enable(I2C_Type *base, bool enable) * @brief Gets the I2C status flags. * * @param base I2C base pointer - * @return status flag, use status flag to AND #_i2c_flags could get the related status. + * @return status flag, use status flag to AND #_i2c_flags to get the related status. */ uint32_t I2C_MasterGetStatusFlags(I2C_Type *base); @@ -397,7 +406,7 @@ uint32_t I2C_MasterGetStatusFlags(I2C_Type *base); * @brief Gets the I2C status flags. * * @param base I2C base pointer - * @return status flag, use status flag to AND #_i2c_flags could get the related status. + * @return status flag, use status flag to AND #_i2c_flags to get the related status. */ static inline uint32_t I2C_SlaveGetStatusFlags(I2C_Type *base) { @@ -407,11 +416,11 @@ static inline uint32_t I2C_SlaveGetStatusFlags(I2C_Type *base) /*! * @brief Clears the I2C status flag state. * - * The following status register flags can be cleared: kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag + * The following status register flags can be cleared kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag. * * @param base I2C base pointer * @param statusMask The status flag mask, defined in type i2c_status_flag_t. - * The parameter could be any combination of the following values: + * The parameter can be any combination of the following values: * @arg kI2C_StartDetectFlag (if available) * @arg kI2C_StopDetectFlag (if available) * @arg kI2C_ArbitrationLostFlag @@ -442,11 +451,11 @@ static inline void I2C_MasterClearStatusFlags(I2C_Type *base, uint32_t statusMas /*! * @brief Clears the I2C status flag state. * - * The following status register flags can be cleared: kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag + * The following status register flags can be cleared kI2C_ArbitrationLostFlag and kI2C_IntPendingFlag * * @param base I2C base pointer * @param statusMask The status flag mask, defined in type i2c_status_flag_t. - * The parameter could be any combination of the following values: + * The parameter can be any combination of the following values: * @arg kI2C_StartDetectFlag (if available) * @arg kI2C_StopDetectFlag (if available) * @arg kI2C_ArbitrationLostFlag @@ -574,19 +583,21 @@ status_t I2C_MasterStop(I2C_Type *base); status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction); /*! - * @brief Performs a polling send transaction on the I2C bus without a STOP signal. + * @brief Performs a polling send transaction on the I2C bus. * * @param base The I2C peripheral base pointer. * @param txBuff The pointer to the data to be transferred. * @param txSize The length in bytes of the data to be transferred. + * @param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag +* to issue a stop and kI2C_TransferNoStop to not send a stop. * @retval kStatus_Success Successfully complete the data transmission. * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. */ -status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize); +status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize, uint32_t flags); /*! - * @brief Performs a polling receive transaction on the I2C bus with a STOP signal. + * @brief Performs a polling receive transaction on the I2C bus. * * @note The I2C_MasterReadBlocking function stops the bus before reading the final byte. * Without stopping the bus prior for the final read, the bus issues another read, resulting @@ -595,10 +606,12 @@ status_t I2C_MasterWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t t * @param base I2C peripheral base pointer. * @param rxBuff The pointer to the data to store the received data. * @param rxSize The length in bytes of the data to be received. + * @param flags Transfer control flag to decide whether need to send a stop, use kI2C_TransferDefaultFlag +* to issue a stop and kI2C_TransferNoStop to not send a stop. * @retval kStatus_Success Successfully complete the data transmission. * @retval kStatus_I2C_Timeout Send stop signal failed, timeout. */ -status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize); +status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize, uint32_t flags); /*! * @brief Performs a polling send transaction on the I2C bus. @@ -650,7 +663,7 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer) * @param base I2C base pointer. * @param handle pointer to i2c_master_handle_t structure to store the transfer state. * @param callback pointer to user callback function. - * @param userData user paramater passed to the callback function. + * @param userData user parameter passed to the callback function. */ void I2C_MasterTransferCreateHandle(I2C_Type *base, i2c_master_handle_t *handle, @@ -660,15 +673,15 @@ void I2C_MasterTransferCreateHandle(I2C_Type *base, /*! * @brief Performs a master interrupt non-blocking transfer on the I2C bus. * - * @note Calling the API will return immediately after transfer initiates, user needs + * @note Calling the API returns immediately after transfer initiates. The user needs * to call I2C_MasterGetTransferCount to poll the transfer status to check whether - * the transfer is finished, if the return status is not kStatus_I2C_Busy, the transfer + * the transfer is finished. If the return status is not kStatus_I2C_Busy, the transfer * is finished. * * @param base I2C base pointer. * @param handle pointer to i2c_master_handle_t structure which stores the transfer state. * @param xfer pointer to i2c_master_transfer_t structure. - * @retval kStatus_Success Sucessully start the data transmission. + * @retval kStatus_Success Successfully start the data transmission. * @retval kStatus_I2C_Busy Previous transmission still not finished. * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c_edma.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c_edma.c index c8f7c20629..28a415e075 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c_edma.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c_edma.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -162,6 +162,26 @@ static void I2C_MasterTransferCallbackEDMA(edma_handle_t *handle, void *userData result = I2C_MasterStop(i2cPrivateHandle->base); } } + else + { + if (i2cPrivateHandle->handle->transfer.direction == kI2C_Read) + { + /* Change to send NAK at the last byte. */ + i2cPrivateHandle->base->C1 |= I2C_C1_TXAK_MASK; + + /* Wait the last data to be received. */ + while (!(i2cPrivateHandle->base->S & kI2C_TransferCompleteFlag)) + { + } + + /* Change direction to send. */ + i2cPrivateHandle->base->C1 |= I2C_C1_TX_MASK; + + /* Read the last data byte. */ + *(i2cPrivateHandle->handle->transfer.data + i2cPrivateHandle->handle->transfer.dataSize - 1) = + i2cPrivateHandle->base->D; + } + } i2cPrivateHandle->handle->state = kIdleState; @@ -203,7 +223,6 @@ static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base, assert(xfer); status_t result = kStatus_Success; - uint16_t timeout = UINT16_MAX; if (handle->state != kIdleState) { @@ -221,16 +240,6 @@ static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base, handle->state = kTransferDataState; - /* Wait until ready to complete. */ - while ((!(base->S & kI2C_TransferCompleteFlag)) && (--timeout)) - { - } - - /* Failed to start the transfer. */ - if (timeout == 0) - { - return kStatus_I2C_Timeout; - } /* Clear all status before transfer. */ I2C_MasterClearStatusFlags(base, kClearFlags); @@ -250,22 +259,55 @@ static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base, result = I2C_MasterStart(base, handle->transfer.slaveAddress, direction); } + if (result) + { + return result; + } + + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + /* Return if error. */ + if (result) + { + if (result == kStatus_I2C_Nak) + { + result = kStatus_I2C_Addr_Nak; + + if (I2C_MasterStop(base) != kStatus_Success) + { + result = kStatus_I2C_Timeout; + } + + if (handle->completionCallback) + { + (handle->completionCallback)(base, handle, result, handle->userData); + } + } + + return result; + } + /* Send subaddress. */ if (handle->transfer.subaddressSize) { do { - /* Wait until data transfer complete. */ - while (!(base->S & kI2C_IntPendingFlag)) - { - } - /* Clear interrupt pending flag. */ base->S = kI2C_IntPendingFlag; handle->transfer.subaddressSize--; base->D = ((handle->transfer.subaddress) >> (8 * handle->transfer.subaddressSize)); + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + /* Check if there's transfer error. */ result = I2C_CheckAndClearError(base, base->S); @@ -278,34 +320,34 @@ static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base, if (handle->transfer.direction == kI2C_Read) { - /* Wait until data transfer complete. */ - while (!(base->S & kI2C_IntPendingFlag)) - { - } - /* Clear pending flag. */ base->S = kI2C_IntPendingFlag; /* Send repeated start and slave address. */ result = I2C_MasterRepeatedStart(base, handle->transfer.slaveAddress, kI2C_Read); + + if (result) + { + return result; + } + + /* Wait until data transfer complete. */ + while (!(base->S & kI2C_IntPendingFlag)) + { + } + + /* Check if there's transfer error. */ + result = I2C_CheckAndClearError(base, base->S); + + if (result) + { + return result; + } } } - if (result) - { - return result; - } - - /* Wait until data transfer complete. */ - while (!(base->S & kI2C_IntPendingFlag)) - { - } - /* Clear pending flag. */ base->S = kI2C_IntPendingFlag; - - /* Check if there's transfer error. */ - result = I2C_CheckAndClearError(base, base->S); } return result; @@ -319,17 +361,7 @@ static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_ { transfer_config.srcAddr = (uint32_t)I2C_GetDataRegAddr(base); transfer_config.destAddr = (uint32_t)(handle->transfer.data); - - /* Send stop if kI2C_TransferNoStop flag is not asserted. */ - if (!(handle->transfer.flags & kI2C_TransferNoStopFlag)) - { - transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1); - } - else - { - transfer_config.majorLoopCounts = handle->transfer.dataSize; - } - + transfer_config.majorLoopCounts = (handle->transfer.dataSize - 1); transfer_config.srcTransferSize = kEDMA_TransferSize1Bytes; transfer_config.srcOffset = 0; transfer_config.destTransferSize = kEDMA_TransferSize1Bytes; @@ -348,6 +380,9 @@ static void I2C_MasterTransferEDMAConfig(I2C_Type *base, i2c_master_edma_handle_ transfer_config.minorLoopBytes = 1; } + /* Store the initially configured eDMA minor byte transfer count into the I2C handle */ + handle->nbytes = transfer_config.minorLoopBytes; + EDMA_SubmitTransfer(handle->dmaHandle, &transfer_config); EDMA_StartTransfer(handle->dmaHandle); } @@ -427,7 +462,7 @@ status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle if (handle->transfer.direction == kI2C_Read) { /* Change direction for receive. */ - base->C1 &= ~I2C_C1_TX_MASK; + base->C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK); /* Read dummy to release the bus. */ dummy = base->D; @@ -479,6 +514,11 @@ status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle { result = I2C_MasterStop(base); } + else + { + /* Change direction to send. */ + base->C1 |= I2C_C1_TX_MASK; + } /* Read the last byte of data. */ if (handle->transfer.direction == kI2C_Read) @@ -504,7 +544,9 @@ status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t if (kIdleState != handle->state) { - *count = (handle->transferSize - EDMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel)); + *count = (handle->transferSize - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); } else { diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c_edma.h index 234876d451..40cb648ea9 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_i2c_edma.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -39,31 +39,30 @@ * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ -/*! @brief I2C master edma handle typedef. */ +/*! @brief I2C master eDMA handle typedef. */ typedef struct _i2c_master_edma_handle i2c_master_edma_handle_t; -/*! @brief I2C master edma transfer callback typedef. */ +/*! @brief I2C master eDMA transfer callback typedef. */ typedef void (*i2c_master_edma_transfer_callback_t)(I2C_Type *base, i2c_master_edma_handle_t *handle, status_t status, void *userData); -/*! @brief I2C master edma transfer structure. */ +/*! @brief I2C master eDMA transfer structure. */ struct _i2c_master_edma_handle { - i2c_master_transfer_t transfer; /*!< I2C master transfer struct. */ + i2c_master_transfer_t transfer; /*!< I2C master transfer structure. */ size_t transferSize; /*!< Total bytes to be transferred. */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ uint8_t state; /*!< I2C master transfer status. */ edma_handle_t *dmaHandle; /*!< The eDMA handler used. */ i2c_master_edma_transfer_callback_t - completionCallback; /*!< Callback function called after edma transfer finished. */ - void *userData; /*!< Callback parameter passed to callback function. */ + completionCallback; /*!< A callback function called after the eDMA transfer is finished. */ + void *userData; /*!< A callback parameter passed to the callback function. */ }; /******************************************************************************* @@ -75,18 +74,18 @@ extern "C" { #endif /*_cplusplus. */ /*! - * @name I2C Block EDMA Transfer Operation + * @name I2C Block eDMA Transfer Operation * @{ */ /*! - * @brief Init the I2C handle which is used in transcational functions. + * @brief Initializes the I2C handle which is used in transcational functions. * * @param base I2C peripheral base address. - * @param handle pointer to i2c_master_edma_handle_t structure. - * @param callback pointer to user callback function. - * @param userData user param passed to the callback function. - * @param edmaHandle EDMA handle pointer. + * @param handle A pointer to the i2c_master_edma_handle_t structure. + * @param callback A pointer to the user callback function. + * @param userData A user parameter passed to the callback function. + * @param edmaHandle eDMA handle pointer. */ void I2C_MasterCreateEDMAHandle(I2C_Type *base, i2c_master_edma_handle_t *handle, @@ -95,33 +94,33 @@ void I2C_MasterCreateEDMAHandle(I2C_Type *base, edma_handle_t *edmaHandle); /*! - * @brief Performs a master edma non-blocking transfer on the I2C bus. + * @brief Performs a master eDMA non-blocking transfer on the I2C bus. * * @param base I2C peripheral base address. - * @param handle pointer to i2c_master_edma_handle_t structure. - * @param xfer pointer to transfer structure of i2c_master_transfer_t. - * @retval kStatus_Success Sucessully complete the data transmission. - * @retval kStatus_I2C_Busy Previous transmission still not finished. - * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + * @param handle A pointer to the i2c_master_edma_handle_t structure. + * @param xfer A pointer to the transfer structure of i2c_master_transfer_t. + * @retval kStatus_Success Sucessfully completed the data transmission. + * @retval kStatus_I2C_Busy A previous transmission is still not finished. + * @retval kStatus_I2C_Timeout Transfer error, waits for a signal timeout. * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. - * @retval kStataus_I2C_Nak Transfer error, receive Nak during transfer. + * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. */ status_t I2C_MasterTransferEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, i2c_master_transfer_t *xfer); /*! - * @brief Get master transfer status during a edma non-blocking transfer. + * @brief Gets a master transfer status during the eDMA non-blocking transfer. * * @param base I2C peripheral base address. - * @param handle pointer to i2c_master_edma_handle_t structure. - * @param count Number of bytes transferred so far by the non-blocking transaction. + * @param handle A pointer to the i2c_master_edma_handle_t structure. + * @param count A number of bytes transferred by the non-blocking transaction. */ status_t I2C_MasterTransferGetCountEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle, size_t *count); /*! - * @brief Abort a master edma non-blocking transfer in a early time. + * @brief Aborts a master eDMA non-blocking transfer early. * * @param base I2C peripheral base address. - * @param handle pointer to i2c_master_edma_handle_t structure. + * @param handle A pointer to the i2c_master_edma_handle_t structure. */ void I2C_MasterTransferAbortEDMA(I2C_Type *base, i2c_master_edma_handle_t *handle); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_llwu.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_llwu.c index c27b91e9f0..74b1001a88 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_llwu.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_llwu.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_llwu.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_llwu.h index 7c11572e80..d5a0037bb5 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_llwu.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_llwu.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -35,7 +35,6 @@ /*! @addtogroup llwu */ /*! @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -52,9 +51,9 @@ */ typedef enum _llwu_external_pin_mode { - kLLWU_ExternalPinDisable = 0U, /*!< Pin disabled as wakeup input. */ - kLLWU_ExternalPinRisingEdge = 1U, /*!< Pin enabled with rising edge detection. */ - kLLWU_ExternalPinFallingEdge = 2U, /*!< Pin enabled with falling edge detection.*/ + kLLWU_ExternalPinDisable = 0U, /*!< Pin disabled as a wakeup input. */ + kLLWU_ExternalPinRisingEdge = 1U, /*!< Pin enabled with the rising edge detection. */ + kLLWU_ExternalPinFallingEdge = 2U, /*!< Pin enabled with the falling edge detection.*/ kLLWU_ExternalPinAnyEdge = 3U /*!< Pin enabled with any change detection. */ } llwu_external_pin_mode_t; @@ -75,9 +74,9 @@ typedef enum _llwu_pin_filter_mode */ typedef struct _llwu_version_id { - uint16_t feature; /*!< Feature Specification Number. */ - uint8_t minor; /*!< Minor version number. */ - uint8_t major; /*!< Major version number. */ + uint16_t feature; /*!< A feature specification number. */ + uint8_t minor; /*!< The minor version number. */ + uint8_t major; /*!< The major version number. */ } llwu_version_id_t; #endif /* FSL_FEATURE_LLWU_HAS_VERID */ @@ -87,20 +86,20 @@ typedef struct _llwu_version_id */ typedef struct _llwu_param { - uint8_t filters; /*!< Number of pin filter. */ - uint8_t dmas; /*!< Number of wakeup DMA. */ - uint8_t modules; /*!< Number of wakeup module. */ - uint8_t pins; /*!< Number of wake up pin. */ + uint8_t filters; /*!< A number of the pin filter. */ + uint8_t dmas; /*!< A number of the wakeup DMA. */ + uint8_t modules; /*!< A number of the wakeup module. */ + uint8_t pins; /*!< A number of the wake up pin. */ } llwu_param_t; #endif /* FSL_FEATURE_LLWU_HAS_PARAM */ #if (defined(FSL_FEATURE_LLWU_HAS_PIN_FILTER) && FSL_FEATURE_LLWU_HAS_PIN_FILTER) /*! - * @brief External input pin filter control structure + * @brief An external input pin filter control structure */ typedef struct _llwu_external_pin_filter_mode { - uint32_t pinIndex; /*!< Pin number */ + uint32_t pinIndex; /*!< A pin number */ llwu_pin_filter_mode_t filterMode; /*!< Filter mode */ } llwu_external_pin_filter_mode_t; #endif /* FSL_FEATURE_LLWU_HAS_PIN_FILTER */ @@ -122,11 +121,11 @@ extern "C" { /*! * @brief Gets the LLWU version ID. * - * This function gets the LLWU version ID, including major version number, - * minor version number, and feature specification number. + * This function gets the LLWU version ID, including the major version number, + * the minor version number, and the feature specification number. * * @param base LLWU peripheral base address. - * @param versionId Pointer to version ID structure. + * @param versionId A pointer to the version ID structure. */ static inline void LLWU_GetVersionId(LLWU_Type *base, llwu_version_id_t *versionId) { @@ -138,11 +137,11 @@ static inline void LLWU_GetVersionId(LLWU_Type *base, llwu_version_id_t *version /*! * @brief Gets the LLWU parameter. * - * This function gets the LLWU parameter, including wakeup pin number, module - * number, DMA number, and pin filter number. + * This function gets the LLWU parameter, including a wakeup pin number, a module + * number, a DMA number, and a pin filter number. * * @param base LLWU peripheral base address. - * @param param Pointer to LLWU param structure. + * @param param A pointer to the LLWU parameter structure. */ static inline void LLWU_GetParam(LLWU_Type *base, llwu_param_t *param) { @@ -158,8 +157,8 @@ static inline void LLWU_GetParam(LLWU_Type *base, llwu_param_t *param) * as a wake up source. * * @param base LLWU peripheral base address. - * @param pinIndex pin index which to be enabled as external wakeup source, start from 1. - * @param pinMode pin configuration mode defined in llwu_external_pin_modes_t + * @param pinIndex A pin index to be enabled as an external wakeup source starting from 1. + * @param pinMode A pin configuration mode defined in the llwu_external_pin_modes_t. */ void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_external_pin_mode_t pinMode); @@ -167,11 +166,11 @@ void LLWU_SetExternalWakeupPinMode(LLWU_Type *base, uint32_t pinIndex, llwu_exte * @brief Gets the external wakeup source flag. * * This function checks the external pin flag to detect whether the MCU is - * woke up by the specific pin. + * woken up by the specific pin. * * @param base LLWU peripheral base address. - * @param pinIndex pin index, start from 1. - * @return true if the specific pin is wake up source. + * @param pinIndex A pin index, which starts from 1. + * @return True if the specific pin is a wakeup source. */ bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); @@ -181,7 +180,7 @@ bool LLWU_GetExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); * This function clears the external wakeup source flag for a specific pin. * * @param base LLWU peripheral base address. - * @param pinIndex pin index, start from 1. + * @param pinIndex A pin index, which starts from 1. */ void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ @@ -194,8 +193,8 @@ void LLWU_ClearExternalWakeupPinFlag(LLWU_Type *base, uint32_t pinIndex); * as a wake up source. * * @param base LLWU peripheral base address. - * @param moduleIndex module index which to be enabled as internal wakeup source, start from 1. - * @param enable enable or disable setting + * @param moduleIndex A module index to be enabled as an internal wakeup source starting from 1. + * @param enable An enable or a disable setting */ static inline void LLWU_EnableInternalModuleInterruptWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable) { @@ -213,31 +212,31 @@ static inline void LLWU_EnableInternalModuleInterruptWakup(LLWU_Type *base, uint * @brief Gets the external wakeup source flag. * * This function checks the external pin flag to detect whether the system is - * woke up by the specific pin. + * woken up by the specific pin. * * @param base LLWU peripheral base address. - * @param moduleIndex module index, start from 1. - * @return true if the specific pin is wake up source. + * @param moduleIndex A module index, which starts from 1. + * @return True if the specific pin is a wake up source. */ static inline bool LLWU_GetInternalWakeupModuleFlag(LLWU_Type *base, uint32_t moduleIndex) { +#if (defined(FSL_FEATURE_LLWU_HAS_MF) && FSL_FEATURE_LLWU_HAS_MF) #if (defined(FSL_FEATURE_LLWU_REG_BITWIDTH) && (FSL_FEATURE_LLWU_REG_BITWIDTH == 32)) return (bool)(base->MF & (1U << moduleIndex)); #else -#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) -#if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) return (bool)(base->MF5 & (1U << moduleIndex)); +#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ #else +#if (defined(FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN) && (FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN > 16)) return (bool)(base->F5 & (1U << moduleIndex)); -#endif /* FSL_FEATURE_LLWU_HAS_PF */ #else #if (defined(FSL_FEATURE_LLWU_HAS_PF) && FSL_FEATURE_LLWU_HAS_PF) return (bool)(base->PF3 & (1U << moduleIndex)); #else return (bool)(base->F3 & (1U << moduleIndex)); -#endif +#endif /* FSL_FEATURE_LLWU_HAS_PF */ #endif /* FSL_FEATURE_LLWU_HAS_EXTERNAL_PIN */ -#endif /* FSL_FEATURE_LLWU_REG_BITWIDTH */ +#endif /* FSL_FEATURE_LLWU_HAS_MF */ } #endif /* FSL_FEATURE_LLWU_HAS_INTERNAL_MODULE */ @@ -248,8 +247,8 @@ static inline bool LLWU_GetInternalWakeupModuleFlag(LLWU_Type *base, uint32_t mo * This function enables/disables the internal DMA that is used as a wake up source. * * @param base LLWU peripheral base address. - * @param moduleIndex Internal module index which used as DMA request source, start from 1. - * @param enable Enable or disable DMA request source + * @param moduleIndex An internal module index which is used as a DMA request source, starting from 1. + * @param enable Enable or disable the DMA request source */ static inline void LLWU_EnableInternalModuleDmaRequestWakup(LLWU_Type *base, uint32_t moduleIndex, bool enable) { @@ -271,8 +270,8 @@ static inline void LLWU_EnableInternalModuleDmaRequestWakup(LLWU_Type *base, uin * This function sets the pin filter configuration. * * @param base LLWU peripheral base address. - * @param filterIndex pin filter index which used to enable/disable the digital filter, start from 1. - * @param filterMode filter mode configuration + * @param filterIndex A pin filter index used to enable/disable the digital filter, starting from 1. + * @param filterMode A filter mode configuration */ void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_pin_filter_mode_t filterMode); @@ -282,18 +281,18 @@ void LLWU_SetPinFilterMode(LLWU_Type *base, uint32_t filterIndex, llwu_external_ * This function gets the pin filter flag. * * @param base LLWU peripheral base address. - * @param filterIndex pin filter index, start from 1. - * @return true if the flag is a source of existing a low-leakage power mode. + * @param filterIndex A pin filter index, which starts from 1. + * @return True if the flag is a source of the existing low-leakage power mode. */ bool LLWU_GetPinFilterFlag(LLWU_Type *base, uint32_t filterIndex); /*! - * @brief Clear the pin filter configuration. + * @brief Clears the pin filter configuration. * - * This function clear the pin filter flag. + * This function clears the pin filter flag. * * @param base LLWU peripheral base address. - * @param filterIndex pin filter index which to be clear the flag, start from 1. + * @param filterIndex A pin filter index to clear the flag, starting from 1. */ void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex); @@ -303,10 +302,10 @@ void LLWU_ClearPinFilterFlag(LLWU_Type *base, uint32_t filterIndex); /*! * @brief Sets the reset pin mode. * - * This function sets how the reset pin is used as a low leakage mode exit source. + * This function determines how the reset pin is used as a low leakage mode exit source. * - * @param pinEnable Enable reset pin filter - * @param pinFilterEnable Specify whether pin filter is enabled in Low-Leakage power mode. + * @param pinEnable Enable reset the pin filter + * @param pinFilterEnable Specify whether the pin filter is enabled in Low-Leakage power mode. */ void LLWU_SetResetPinMode(LLWU_Type *base, bool pinEnable, bool enableInLowLeakageMode); #endif /* FSL_FEATURE_LLWU_HAS_RESET_ENABLE */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lmem_cache.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lmem_cache.c index fb6f06c3ac..bff12af565 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lmem_cache.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lmem_cache.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -48,7 +48,7 @@ void LMEM_EnableCodeCache(LMEM_Type *base, bool enable) LMEM_CodeCacheInvalidateAll(base); /* Now enable the cache. */ - base->PCCCR |= LMEM_PCCCR_ENCACHE_MASK | LMEM_PCCCR_ENWRBUF_MASK; + base->PCCCR |= LMEM_PCCCR_ENCACHE_MASK; } else { @@ -56,7 +56,7 @@ void LMEM_EnableCodeCache(LMEM_Type *base, bool enable) LMEM_CodeCachePushAll(base); /* Now disable the cache. */ - base->PCCCR &= ~(LMEM_PCCCR_ENCACHE_MASK | LMEM_PCCCR_ENWRBUF_MASK); + base->PCCCR &= ~LMEM_PCCCR_ENCACHE_MASK; } } @@ -236,7 +236,7 @@ void LMEM_CodeCacheClearMultiLines(LMEM_Type *base, uint32_t address, uint32_t l } } } - +#if (!defined(FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE)) || !FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE status_t LMEM_CodeCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, lmem_cache_mode_t cacheMode) { uint32_t mode = base->PCCRMR; @@ -255,6 +255,7 @@ status_t LMEM_CodeCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, return kStatus_Success; } } +#endif /* FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE */ #if FSL_FEATURE_LMEM_HAS_SYSTEMBUS_CACHE void LMEM_EnableSystemCache(LMEM_Type *base, bool enable) @@ -265,7 +266,7 @@ void LMEM_EnableSystemCache(LMEM_Type *base, bool enable) LMEM_SystemCacheInvalidateAll(base); /* Now enable the cache. */ - base->PSCCR |= LMEM_PSCCR_ENCACHE_MASK | LMEM_PSCCR_ENWRBUF_MASK; + base->PSCCR |= LMEM_PSCCR_ENCACHE_MASK ; } else { @@ -273,7 +274,7 @@ void LMEM_EnableSystemCache(LMEM_Type *base, bool enable) LMEM_SystemCachePushAll(base); /* Now disable the cache. */ - base->PSCCR &= ~(LMEM_PSCCR_ENCACHE_MASK | LMEM_PSCCR_ENWRBUF_MASK); + base->PSCCR &= ~LMEM_PSCCR_ENCACHE_MASK; } } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lmem_cache.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lmem_cache.h index 9e69feb413..8df4cea3d3 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lmem_cache.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lmem_cache.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,7 +37,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -45,8 +44,8 @@ /*! @name Driver version */ /*@{*/ -/*! @brief LMEM controller driver version 2.0.0. */ -#define FSL_LMEM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*! @brief LMEM controller driver version 2.1.0. */ +#define FSL_LMEM_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*@}*/ #define LMEM_CACHE_LINE_SIZE (0x10U) /*!< Cache line is 16-bytes. */ @@ -55,9 +54,9 @@ /*! @brief LMEM cache mode options. */ typedef enum _lmem_cache_mode { - kLMEM_NonCacheable = 0x0U, /*!< CACHE mode: non-cacheable. */ - kLMEM_CacheWriteThrough = 0x2U, /*!< CACHE mode: write-through. */ - kLMEM_CacheWriteBack = 0x3U /*!< CACHE mode: write-back. */ + kLMEM_NonCacheable = 0x0U, /*!< Cache mode: non-cacheable. */ + kLMEM_CacheWriteThrough = 0x2U, /*!< Cache mode: write-through. */ + kLMEM_CacheWriteBack = 0x3U /*!< Cache mode: write-back. */ } lmem_cache_mode_t; /*! @brief LMEM cache regions. */ @@ -106,7 +105,7 @@ extern "C" { /*! * @brief Enables/disables the processor code bus cache. * This function enables/disables the cache. The function first invalidates the entire cache - * and then enables/disable both the cache and write buffers. + * and then enables/disables both the cache and write buffers. * * @param base LMEM peripheral base address. * @param enable The enable or disable flag. @@ -115,6 +114,26 @@ extern "C" { */ void LMEM_EnableCodeCache(LMEM_Type *base, bool enable); +/*! + * @brief Enables/disables the processor code bus write buffer. + * + * @param base LMEM peripheral base address. + * @param enable The enable or disable flag. + * true - enable the code bus write buffer. + * false - disable the code bus write buffer. + */ +static inline void LMEM_EnableCodeWriteBuffer(LMEM_Type *base, bool enable) +{ + if (enable) + { + base->PCCCR |= LMEM_PCCCR_ENWRBUF_MASK; + } + else + { + base->PCCCR &= ~LMEM_PCCCR_ENWRBUF_MASK; + } +} + /*! * @brief Invalidates the processor code bus cache. * This function invalidates the cache both ways, which means that @@ -163,10 +182,10 @@ void LMEM_CodeCacheInvalidateLine(LMEM_Type *base, uint32_t address); * This function invalidates multiple lines in the cache * based on the physical address and length in bytes passed in by the * user. If the function detects that the length meets or exceeds half the - * cache. Then the function performs an entire cache invalidate function, which is + * cache, the function performs an entire cache invalidate function, which is * more efficient than invalidating the cache line-by-line. - * The need to check half the total amount of cache is due to the fact that the cache consists of - * two ways and that line commands based on the physical address searches both ways. + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. * Invalidate - Unconditionally clear valid and modified bits of a cache entry. * * @param base LMEM peripheral base address. @@ -197,8 +216,8 @@ void LMEM_CodeCachePushLine(LMEM_Type *base, uint32_t address); * user. If the function detects that the length meets or exceeds half of the * cache, the function performs an cache push function, which is * more efficient than pushing the modified lines in the cache line-by-line. - * The need to check half the total amount of cache is due to the fact that the cache consists of - * two ways and that line commands based on the physical address searches both ways. + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. * Push - Push a cache entry if it is valid and modified, then clear the modified bit. If * the entry is not valid or not modified, leave as is. This action does not clear the valid * bit. A cache push is synonymous with a cache flush. @@ -230,8 +249,8 @@ void LMEM_CodeCacheClearLine(LMEM_Type *base, uint32_t address); * user. If the function detects that the length meets or exceeds half the total amount of * cache, the function performs a cache clear function which is * more efficient than clearing the lines in the cache line-by-line. - * The need to check half the total amount of cache is due to the fact that the cache consists of - * two ways and that line commands based on the physical address searches both ways. + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. * Clear - Push a cache entry if it is valid and modified, then clear the valid and * modify bits. If entry not valid or not modified, clear the valid bit. * @@ -242,6 +261,7 @@ void LMEM_CodeCacheClearLine(LMEM_Type *base, uint32_t address); */ void LMEM_CodeCacheClearMultiLines(LMEM_Type *base, uint32_t address, uint32_t length); +#if (!defined(FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE)) || !FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE /*! * @brief Demotes the cache mode of a region in processor code bus cache. * This function allows the user to demote the cache mode of a region within the device's @@ -264,6 +284,7 @@ void LMEM_CodeCacheClearMultiLines(LMEM_Type *base, uint32_t address, uint32_t l * kStatus_Fail The cache demote operation is failure. */ status_t LMEM_CodeCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, lmem_cache_mode_t cacheMode); +#endif /* FSL_FEATURE_LMEM_SUPPORT_ICACHE_DEMOTE_REMOVE */ /*@}*/ @@ -285,6 +306,26 @@ status_t LMEM_CodeCacheDemoteRegion(LMEM_Type *base, lmem_cache_region_t region, */ void LMEM_EnableSystemCache(LMEM_Type *base, bool enable); +/*! + * @brief Enables/disables the processor system bus write buffer. + * + * @param base LMEM peripheral base address. + * @param enable The enable or disable flag. + * true - enable the system bus write buffer. + * false - disable the system bus write buffer. + */ +static inline void LMEM_EnableSystemWriteBuffer(LMEM_Type *base, bool enable) +{ + if (enable) + { + base->PSCCR |= LMEM_PSCCR_ENWRBUF_MASK; + } + else + { + base->PSCCR &= ~LMEM_PSCCR_ENWRBUF_MASK; + } +} + /*! * @brief Invalidates the processor system bus cache. * This function invalidates the entire cache both ways. @@ -320,7 +361,7 @@ void LMEM_SystemCacheClearAll(LMEM_Type *base); * @brief Invalidates a specific line in the processor system bus cache. * This function invalidates a specific line in the cache * based on the physical address passed in by the user. - * Invalidate - Unconditionally clear valid and modify bits of a cache entry + * Invalidate - Unconditionally clears valid and modify bits of a cache entry. * * @param base LMEM peripheral base address. Should be 16-byte aligned address. * If not, it is changed to the 16-byte aligned memory address. @@ -335,8 +376,8 @@ void LMEM_SystemCacheInvalidateLine(LMEM_Type *base, uint32_t address); * user. If the function detects that the length meets or exceeds half of the * cache, the function performs an entire cache invalidate function (which is * more efficient than invalidating the cache line-by-line). - * The need to check half the total amount of cache is due to the fact that the cache consists of - * two ways and that line commands based on the physical address searches both ways. + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. * Invalidate - Unconditionally clear valid and modify bits of a cache entry * * @param base LMEM peripheral base address. @@ -367,8 +408,8 @@ void LMEM_SystemCachePushLine(LMEM_Type *base, uint32_t address); * user. If the function detects that the length meets or exceeds half of the * cache, the function performs an entire cache push function (which is * more efficient than pushing the modified lines in the cache line-by-line). - * The need to check half the total amount of cache is due to the fact that the cache consists of - * two ways and that line commands based on the physical address searches both ways. + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. * Push - Push a cache entry if it is valid and modified, then clear the modify bit. If * the entry is not valid or not modified, leave as is. This action does not clear the valid * bit. A cache push is synonymous with a cache flush. @@ -400,8 +441,8 @@ void LMEM_SystemCacheClearLine(LMEM_Type *base, uint32_t address); * user. If the function detects that the length meets or exceeds half of the * cache, the function performs an entire cache clear function (which is * more efficient than clearing the lines in the cache line-by-line). - * The need to check half the total amount of cache is due to the fact that the cache consists of - * two ways and that line commands based on the physical address searches both ways. + * Because the cache consists of two ways and line commands based on the physical address searches both ways, + * check half the total amount of cache. * Clear - Push a cache entry if it is valid and modified, then clear the valid and * modify bits. If the entry is not valid or not modified, clear the valid bit. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lptmr.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lptmr.c index b3dcc89d55..67b3b9785c 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lptmr.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lptmr.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -48,9 +48,17 @@ static uint32_t LPTMR_GetInstance(LPTMR_Type *base); /*! @brief Pointers to LPTMR bases for each instance. */ static LPTMR_Type *const s_lptmrBases[] = LPTMR_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to LPTMR clocks for each instance. */ static const clock_ip_name_t s_lptmrClocks[] = LPTMR_CLOCKS; +#if defined(LPTMR_PERIPH_CLOCKS) +/* Array of LPTMR functional clock name. */ +static const clock_ip_name_t s_lptmrPeriphClocks[] = LPTMR_PERIPH_CLOCKS; +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + /******************************************************************************* * Code ******************************************************************************/ @@ -59,7 +67,7 @@ static uint32_t LPTMR_GetInstance(LPTMR_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_LPTMR_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_lptmrBases); instance++) { if (s_lptmrBases[instance] == base) { @@ -67,7 +75,7 @@ static uint32_t LPTMR_GetInstance(LPTMR_Type *base) } } - assert(instance < FSL_FEATURE_SOC_LPTMR_COUNT); + assert(instance < ARRAY_SIZE(s_lptmrBases)); return instance; } @@ -76,8 +84,17 @@ void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config) { assert(config); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + + uint32_t instance = LPTMR_GetInstance(base); + /* Ungate the LPTMR clock*/ - CLOCK_EnableClock(s_lptmrClocks[LPTMR_GetInstance(base)]); + CLOCK_EnableClock(s_lptmrClocks[instance]); +#if defined(LPTMR_PERIPH_CLOCKS) + CLOCK_EnableClock(s_lptmrPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure the timers operation mode and input pin setup */ base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) | @@ -92,8 +109,17 @@ void LPTMR_Deinit(LPTMR_Type *base) { /* Disable the LPTMR and reset the internal logic */ base->CSR &= ~LPTMR_CSR_TEN_MASK; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + + uint32_t instance = LPTMR_GetInstance(base); + /* Gate the LPTMR clock*/ - CLOCK_DisableClock(s_lptmrClocks[LPTMR_GetInstance(base)]); + CLOCK_DisableClock(s_lptmrClocks[instance]); +#if defined(LPTMR_PERIPH_CLOCKS) + CLOCK_DisableClock(s_lptmrPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void LPTMR_GetDefaultConfig(lptmr_config_t *config) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lptmr.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lptmr.h index fd3cb1ed24..6cc909b314 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lptmr.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lptmr.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -33,22 +33,20 @@ #include "fsl_common.h" /*! - * @addtogroup lptmr_driver + * @addtogroup lptmr * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -#define FSL_LPTMR_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +#define FSL_LPTMR_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1 */ /*@}*/ -/*! @brief LPTMR pin selection, used in pulse counter mode.*/ +/*! @brief LPTMR pin selection used in pulse counter mode.*/ typedef enum _lptmr_pin_select { kLPTMR_PinSelectInput_0 = 0x0U, /*!< Pulse counter input 0 is selected */ @@ -57,7 +55,7 @@ typedef enum _lptmr_pin_select kLPTMR_PinSelectInput_3 = 0x3U /*!< Pulse counter input 3 is selected */ } lptmr_pin_select_t; -/*! @brief LPTMR pin polarity, used in pulse counter mode.*/ +/*! @brief LPTMR pin polarity used in pulse counter mode.*/ typedef enum _lptmr_pin_polarity { kLPTMR_PinPolarityActiveHigh = 0x0U, /*!< Pulse Counter input source is active-high */ @@ -104,13 +102,13 @@ typedef enum _lptmr_prescaler_clock_select kLPTMR_PrescalerClock_3 = 0x3U, /*!< Prescaler/glitch filter clock 3 selected. */ } lptmr_prescaler_clock_select_t; -/*! @brief List of LPTMR interrupts */ +/*! @brief List of the LPTMR interrupts */ typedef enum _lptmr_interrupt_enable { kLPTMR_TimerInterruptEnable = LPTMR_CSR_TIE_MASK, /*!< Timer interrupt enable */ } lptmr_interrupt_enable_t; -/*! @brief List of LPTMR status flags */ +/*! @brief List of the LPTMR status flags */ typedef enum _lptmr_status_flags { kLPTMR_TimerCompareFlag = LPTMR_CSR_TCF_MASK, /*!< Timer compare flag */ @@ -121,18 +119,18 @@ typedef enum _lptmr_status_flags * * This structure holds the configuration settings for the LPTMR peripheral. To initialize this * structure to reasonable defaults, call the LPTMR_GetDefaultConfig() function and pass a - * pointer to your config structure instance. + * pointer to your configuration structure instance. * - * The config struct can be made const so it resides in flash + * The configuration struct can be made constant so it resides in flash. */ typedef struct _lptmr_config { lptmr_timer_mode_t timerMode; /*!< Time counter mode or pulse counter mode */ lptmr_pin_select_t pinSelect; /*!< LPTMR pulse input pin select; used only in pulse counter mode */ lptmr_pin_polarity_t pinPolarity; /*!< LPTMR pulse input pin polarity; used only in pulse counter mode */ - bool enableFreeRunning; /*!< true: enable free running, counter is reset on overflow - false: counter is reset when the compare flag is set */ - bool bypassPrescaler; /*!< true: bypass prescaler; false: use clock from prescaler */ + bool enableFreeRunning; /*!< True: enable free running, counter is reset on overflow + False: counter is reset when the compare flag is set */ + bool bypassPrescaler; /*!< True: bypass prescaler; false: use clock from prescaler */ lptmr_prescaler_clock_select_t prescalerClockSource; /*!< LPTMR clock source */ lptmr_prescaler_glitch_value_t value; /*!< Prescaler or glitch filter value */ } lptmr_config_t; @@ -151,26 +149,26 @@ extern "C" { */ /*! - * @brief Ungate the LPTMR clock and configures the peripheral for basic operation. + * @brief Ungates the LPTMR clock and configures the peripheral for a basic operation. * * @note This API should be called at the beginning of the application using the LPTMR driver. * * @param base LPTMR peripheral base address - * @param config Pointer to user's LPTMR config structure. + * @param config A pointer to the LPTMR configuration structure. */ void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config); /*! - * @brief Gate the LPTMR clock + * @brief Gates the LPTMR clock. * * @param base LPTMR peripheral base address */ void LPTMR_Deinit(LPTMR_Type *base); /*! - * @brief Fill in the LPTMR config struct with the default settings + * @brief Fills in the LPTMR configuration structure with default settings. * - * The default values are: + * The default values are as follows. * @code * config->timerMode = kLPTMR_TimerModeTimeCounter; * config->pinSelect = kLPTMR_PinSelectInput_0; @@ -180,7 +178,7 @@ void LPTMR_Deinit(LPTMR_Type *base); * config->prescalerClockSource = kLPTMR_PrescalerClock_1; * config->value = kLPTMR_Prescale_Glitch_0; * @endcode - * @param config Pointer to user's LPTMR config structure. + * @param config A pointer to the LPTMR configuration structure. */ void LPTMR_GetDefaultConfig(lptmr_config_t *config); @@ -200,7 +198,12 @@ void LPTMR_GetDefaultConfig(lptmr_config_t *config); */ static inline void LPTMR_EnableInterrupts(LPTMR_Type *base, uint32_t mask) { - base->CSR |= mask; + uint32_t reg = base->CSR; + + /* Clear the TCF bit so that we don't clear this w1c bit when writing back */ + reg &= ~(LPTMR_CSR_TCF_MASK); + reg |= mask; + base->CSR = reg; } /*! @@ -208,11 +211,16 @@ static inline void LPTMR_EnableInterrupts(LPTMR_Type *base, uint32_t mask) * * @param base LPTMR peripheral base address * @param mask The interrupts to disable. This is a logical OR of members of the - * enumeration ::lptmr_interrupt_enable_t + * enumeration ::lptmr_interrupt_enable_t. */ static inline void LPTMR_DisableInterrupts(LPTMR_Type *base, uint32_t mask) { - base->CSR &= ~mask; + uint32_t reg = base->CSR; + + /* Clear the TCF bit so that we don't clear this w1c bit when writing back */ + reg &= ~(LPTMR_CSR_TCF_MASK); + reg &= ~mask; + base->CSR = reg; } /*! @@ -236,7 +244,7 @@ static inline uint32_t LPTMR_GetEnabledInterrupts(LPTMR_Type *base) */ /*! - * @brief Gets the LPTMR status flags + * @brief Gets the LPTMR status flags. * * @param base LPTMR peripheral base address * @@ -249,11 +257,11 @@ static inline uint32_t LPTMR_GetStatusFlags(LPTMR_Type *base) } /*! - * @brief Clears the LPTMR status flags + * @brief Clears the LPTMR status flags. * * @param base LPTMR peripheral base address * @param mask The status flags to clear. This is a logical OR of members of the - * enumeration ::lptmr_status_flags_t + * enumeration ::lptmr_status_flags_t. */ static inline void LPTMR_ClearStatusFlags(LPTMR_Type *base, uint32_t mask) { @@ -263,47 +271,48 @@ static inline void LPTMR_ClearStatusFlags(LPTMR_Type *base, uint32_t mask) /*! @}*/ /*! - * @name Read and Write the timer period + * @name Read and write the timer period * @{ */ /*! * @brief Sets the timer period in units of count. * - * Timers counts from 0 till it equals the count value set here. The count value is written to + * Timers counts from 0 until it equals the count value set here. The count value is written to * the CMR register. * * @note * 1. The TCF flag is set with the CNR equals the count provided here and then increments. - * 2. User can call the utility macros provided in fsl_common.h to convert to ticks + * 2. Call the utility macros provided in the fsl_common.h to convert to ticks. * * @param base LPTMR peripheral base address - * @param ticks Timer period in units of ticks + * @param ticks A timer period in units of ticks, which should be equal or greater than 1. */ -static inline void LPTMR_SetTimerPeriod(LPTMR_Type *base, uint16_t ticks) +static inline void LPTMR_SetTimerPeriod(LPTMR_Type *base, uint32_t ticks) { - base->CMR = ticks; + assert(ticks > 0); + base->CMR = ticks - 1; } /*! * @brief Reads the current timer counting value. * - * This function returns the real-time timer counting value, in a range from 0 to a + * This function returns the real-time timer counting value in a range from 0 to a * timer period. * - * @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec + * @note Call the utility macros provided in the fsl_common.h to convert ticks to usec or msec. * * @param base LPTMR peripheral base address * - * @return Current counter value in ticks + * @return The current counter value in ticks */ -static inline uint16_t LPTMR_GetCurrentTimerCount(LPTMR_Type *base) +static inline uint32_t LPTMR_GetCurrentTimerCount(LPTMR_Type *base) { - /* Must first write any value to the CNR. This will synchronize and register the current value + /* Must first write any value to the CNR. This synchronizes and registers the current value * of the CNR into a temporary register which can then be read */ base->CNR = 0U; - return (uint16_t)base->CNR; + return (uint32_t)((base->CNR & LPTMR_CNR_COUNTER_MASK) >> LPTMR_CNR_COUNTER_SHIFT); } /*! @}*/ @@ -314,30 +323,40 @@ static inline uint16_t LPTMR_GetCurrentTimerCount(LPTMR_Type *base) */ /*! - * @brief Starts the timer counting. + * @brief Starts the timer. * * After calling this function, the timer counts up to the CMR register value. - * Each time the timer reaches CMR value and then increments, it generates a - * trigger pulse and sets the timeout interrupt flag. An interrupt will also be + * Each time the timer reaches the CMR value and then increments, it generates a + * trigger pulse and sets the timeout interrupt flag. An interrupt is also * triggered if the timer interrupt is enabled. * * @param base LPTMR peripheral base address */ static inline void LPTMR_StartTimer(LPTMR_Type *base) { - base->CSR |= LPTMR_CSR_TEN_MASK; + uint32_t reg = base->CSR; + + /* Clear the TCF bit to avoid clearing the w1c bit when writing back. */ + reg &= ~(LPTMR_CSR_TCF_MASK); + reg |= LPTMR_CSR_TEN_MASK; + base->CSR = reg; } /*! - * @brief Stops the timer counting. + * @brief Stops the timer. * - * This function stops the timer counting and resets the timer's counter register + * This function stops the timer and resets the timer's counter register. * * @param base LPTMR peripheral base address */ static inline void LPTMR_StopTimer(LPTMR_Type *base) { - base->CSR &= ~LPTMR_CSR_TEN_MASK; + uint32_t reg = base->CSR; + + /* Clear the TCF bit to avoid clearing the w1c bit when writing back. */ + reg &= ~(LPTMR_CSR_TCF_MASK); + reg &= ~LPTMR_CSR_TEN_MASK; + base->CSR = reg; } /*! @}*/ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart.c index b1b015f6f4..9a83b5698d 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -109,9 +109,23 @@ static lpuart_handle_t *s_lpuartHandle[FSL_FEATURE_SOC_LPUART_COUNT]; /* Array of LPUART peripheral base address. */ static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS; /* Array of LPUART IRQ number. */ +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS; +static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS; +#else static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS; +#endif +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Array of LPUART clock name. */ static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS; + +#if defined(LPUART_PERIPH_CLOCKS) +/* Array of LPUART functional clock name. */ +static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS; +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + /* LPUART ISR for transactional APIs. */ static lpuart_isr_t s_lpuartIsr; @@ -123,7 +137,7 @@ uint32_t LPUART_GetInstance(LPUART_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_LPUART_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_lpuartBases); instance++) { if (s_lpuartBases[instance] == base) { @@ -131,13 +145,15 @@ uint32_t LPUART_GetInstance(LPUART_Type *base) } } - assert(instance < FSL_FEATURE_SOC_LPUART_COUNT); + assert(instance < ARRAY_SIZE(s_lpuartBases)); return instance; } static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle) { + assert(handle); + size_t size; if (handle->rxRingBufferTail > handle->rxRingBufferHead) @@ -154,6 +170,8 @@ static size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_han static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle) { + assert(handle); + bool full; if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U)) @@ -169,6 +187,8 @@ static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length) { + assert(data); + size_t i; /* The Non Blocking write data API assume user have ensured there is enough space in @@ -181,33 +201,48 @@ static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length) { + assert(data); + size_t i; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || + ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); +#endif /* The Non Blocking read data API assume user have ensured there is enough space in peripheral to write. */ for (i = 0; i < length; i++) { +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (isSevenDataBits) + { + data[i] = (base->DATA & 0x7F); + } + else + { + data[i] = base->DATA; + } +#else data[i] = base->DATA; +#endif } } -void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz) +status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz) { assert(config); + assert(config->baudRate_Bps); #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark); assert(FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark); #endif + uint32_t temp; uint16_t sbr, sbrTemp; uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; - /* Enable lpuart clock */ - CLOCK_EnableClock(s_lpuartClock[LPUART_GetInstance(base)]); - - /* Disable LPUART TX RX before setting. */ - base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); - /* This LPUART instantiation uses a slightly different baud rate calculation * The idea is to use the best OSR (over-sampling rate) possible * Note, OSR is typically hard-set to 16 in other LPUART instantiations @@ -248,34 +283,75 @@ void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcC /* Check to see if actual baud rate is within 3% of desired baud rate * based on the best calculate OSR value */ - if (baudDiff < ((config->baudRate_Bps / 100) * 3)) + if (baudDiff > ((config->baudRate_Bps / 100) * 3)) { - temp = base->BAUD; - - /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. - * If so, then "BOTHEDGE" sampling must be turned on */ - if ((osr > 3) && (osr < 8)) - { - temp |= LPUART_BAUD_BOTHEDGE_MASK; - } - - /* program the osr value (bit value is one less than actual value) */ - temp &= ~LPUART_BAUD_OSR_MASK; - temp |= LPUART_BAUD_OSR(osr - 1); - - /* write the sbr value to the BAUD registers */ - temp &= ~LPUART_BAUD_SBR_MASK; - base->BAUD = temp | LPUART_BAUD_SBR(sbr); + /* Unacceptable baud rate difference of more than 3%*/ + return kStatus_LPUART_BaudrateNotSupport; } +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + + uint32_t instance = LPUART_GetInstance(base); + + /* Enable lpuart clock */ + CLOCK_EnableClock(s_lpuartClock[instance]); +#if defined(LPUART_PERIPH_CLOCKS) + CLOCK_EnableClock(s_lpuartPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL + /*Reset all internal logic and registers, except the Global Register */ + LPUART_SoftwareReset(base); +#else + /* Disable LPUART TX RX before setting. */ + base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); +#endif + + temp = base->BAUD; + + /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. + * If so, then "BOTHEDGE" sampling must be turned on */ + if ((osr > 3) && (osr < 8)) + { + temp |= LPUART_BAUD_BOTHEDGE_MASK; + } + + /* program the osr value (bit value is one less than actual value) */ + temp &= ~LPUART_BAUD_OSR_MASK; + temp |= LPUART_BAUD_OSR(osr - 1); + + /* write the sbr value to the BAUD registers */ + temp &= ~LPUART_BAUD_SBR_MASK; + base->BAUD = temp | LPUART_BAUD_SBR(sbr); + /* Set bit count and parity mode. */ base->BAUD &= ~LPUART_BAUD_M10_MASK; temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK); - if (kLPUART_ParityDisabled != config->parityMode) + temp |= (uint8_t)config->parityMode; + +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (kLPUART_SevenDataBits == config->dataBitsCount) { - temp |= (LPUART_CTRL_M_MASK | (uint8_t)config->parityMode); + if (kLPUART_ParityDisabled != config->parityMode) + { + temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */ + } + else + { + temp |= LPUART_CTRL_M7_MASK; + } + } + else +#endif + { + if (kLPUART_ParityDisabled != config->parityMode) + { + temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */ + } } base->CTRL = temp; @@ -298,17 +374,27 @@ void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcC #endif /* Clear all status flags */ - temp = (LPUART_STAT_LBKDIF_MASK | LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - temp |= LPUART_STAT_IDLE_MASK; + temp |= LPUART_STAT_LBKDIF_MASK; #endif #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); #endif + /* Set data bits order. */ + if (config->isMsb) + { + temp |= LPUART_STAT_MSBF_MASK; + } + else + { + temp &= ~LPUART_STAT_MSBF_MASK; + } + base->STAT |= temp; /* Enable TX/RX base on configure structure. */ @@ -324,6 +410,8 @@ void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcC } base->CTRL = temp; + + return kStatus_Success; } void LPUART_Deinit(LPUART_Type *base) { @@ -341,11 +429,11 @@ void LPUART_Deinit(LPUART_Type *base) } /* Clear all status flags */ - temp = (LPUART_STAT_LBKDIF_MASK | LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - temp |= LPUART_STAT_IDLE_MASK; + temp |= LPUART_STAT_LBKDIF_MASK; #endif #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING @@ -357,15 +445,27 @@ void LPUART_Deinit(LPUART_Type *base) /* Disable the module. */ base->CTRL = 0; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + uint32_t instance = LPUART_GetInstance(base); + /* Disable lpuart clock */ - CLOCK_DisableClock(s_lpuartClock[LPUART_GetInstance(base)]); + CLOCK_DisableClock(s_lpuartClock[instance]); + +#if defined(LPUART_PERIPH_CLOCKS) + CLOCK_DisableClock(s_lpuartPeriphClocks[instance]); +#endif + +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void LPUART_GetDefaultConfig(lpuart_config_t *config) { assert(config); + config->baudRate_Bps = 115200U; config->parityMode = kLPUART_ParityDisabled; + config->dataBitsCount = kLPUART_EightDataBits; + config->isMsb = false; #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT config->stopBitCount = kLPUART_OneStopBit; #endif @@ -377,18 +477,14 @@ void LPUART_GetDefaultConfig(lpuart_config_t *config) config->enableRx = false; } -void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) { + assert(baudRate_Bps); + uint32_t temp, oldCtrl; uint16_t sbr, sbrTemp; uint32_t osr, osrTemp, tempDiff, calculatedBaud, baudDiff; - /* Store CTRL before disable Tx and Rx */ - oldCtrl = base->CTRL; - - /* Disable LPUART TX RX before setting. */ - base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); - /* This LPUART instantiation uses a slightly different baud rate calculation * The idea is to use the best OSR (over-sampling rate) possible * Note, OSR is typically hard-set to 16 in other LPUART instantiations @@ -431,6 +527,12 @@ void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcCl * based on the best calculate OSR value */ if (baudDiff < ((baudRate_Bps / 100) * 3)) { + /* Store CTRL before disable Tx and Rx */ + oldCtrl = base->CTRL; + + /* Disable LPUART TX RX before setting. */ + base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); + temp = base->BAUD; /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. @@ -447,17 +549,25 @@ void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcCl /* write the sbr value to the BAUD registers */ temp &= ~LPUART_BAUD_SBR_MASK; base->BAUD = temp | LPUART_BAUD_SBR(sbr); - } - /* Restore CTRL. */ - base->CTRL = oldCtrl; + /* Restore CTRL. */ + base->CTRL = oldCtrl; + + return kStatus_Success; + } + else + { + /* Unacceptable baud rate difference of more than 3%*/ + return kStatus_LPUART_BaudrateNotSupport; + } } void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask) { base->BAUD |= ((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - base->FIFO |= ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); + base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) | + ((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); #endif mask &= 0xFFFFFF00U; base->CTRL |= mask; @@ -467,7 +577,8 @@ void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask) { base->BAUD &= ~((mask << 8) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - base->FIFO &= ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); + base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) & + ~((mask << 8) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); #endif mask &= 0xFFFFFF00U; base->CTRL &= ~mask; @@ -503,24 +614,24 @@ status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask) status_t status; #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO temp = (uint32_t)base->FIFO; - temp &= (uint32_t)(~(kLPUART_TxFifoOverflowFlag | kLPUART_RxFifoUnderflowFlag)); - temp |= mask & (kLPUART_TxFifoOverflowFlag | kLPUART_RxFifoUnderflowFlag); + temp &= (uint32_t)(~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)); + temp |= (mask << 16) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK); base->FIFO = temp; #endif temp = (uint32_t)base->STAT; #if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - temp &= (uint32_t)(~(kLPUART_LinBreakFlag)); - temp |= mask & kLPUART_LinBreakFlag; + temp &= (uint32_t)(~(LPUART_STAT_LBKDIF_MASK)); + temp |= mask & LPUART_STAT_LBKDIF_MASK; #endif - temp &= (uint32_t)(~(kLPUART_RxActiveEdgeFlag | kLPUART_IdleLineFlag | kLPUART_RxOverrunFlag | - kLPUART_NoiseErrorFlag | kLPUART_FramingErrorFlag | kLPUART_ParityErrorFlag)); - temp |= mask & (kLPUART_RxActiveEdgeFlag | kLPUART_IdleLineFlag | kLPUART_RxOverrunFlag | kLPUART_NoiseErrorFlag | - kLPUART_FramingErrorFlag | kLPUART_ParityErrorFlag); + temp &= (uint32_t)(~(LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK)); + temp |= mask & (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | + LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); #if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING - temp &= (uint32_t)(~(kLPUART_DataMatch2Flag | kLPUART_DataMatch2Flag)); - temp |= mask & (kLPUART_DataMatch2Flag | kLPUART_DataMatch2Flag); + temp &= (uint32_t)(~(LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK)); + temp |= mask & (LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK); #endif - base->STAT |= temp; + base->STAT = temp; /* If some flags still pending. */ if (mask & LPUART_GetStatusFlags(base)) { @@ -540,6 +651,8 @@ status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask) void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length) { + assert(data); + /* This API can only ensure that the data is written into the data buffer but can't ensure all data in the data buffer are sent into the transmit shift buffer. */ while (length--) @@ -553,7 +666,15 @@ void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length) status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length) { + assert(data); + uint32_t statusFlag; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || + ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); +#endif while (length--) { @@ -589,7 +710,18 @@ status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length) return kStatus_LPUART_ParityError; } } +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (isSevenDataBits) + { + *(data++) = (base->DATA & 0x7F); + } + else + { + *(data++) = base->DATA; + } +#else *(data++) = base->DATA; +#endif } return kStatus_Success; @@ -603,6 +735,12 @@ void LPUART_TransferCreateHandle(LPUART_Type *base, assert(handle); uint32_t instance; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || + ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); +#endif /* Zero the handle. */ memset(handle, 0, sizeof(lpuart_handle_t)); @@ -615,6 +753,11 @@ void LPUART_TransferCreateHandle(LPUART_Type *base, handle->callback = callback; handle->userData = userData; +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + /* Initial seven data bits flag */ + handle->isSevenDataBits = isSevenDataBits; +#endif + #if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO /* Note: Take care of the RX FIFO, RX interrupt request only assert when received bytes @@ -624,7 +767,7 @@ void LPUART_TransferCreateHandle(LPUART_Type *base, 5 bytes are received. the last byte will be saved in FIFO but not trigger RX interrupt because the water mark is 2. */ - base->WATER &= (~LPUART_WATER_RXWATER_SHIFT); + base->WATER &= (~LPUART_WATER_RXWATER_MASK); #endif /* Get instance from peripheral base address. */ @@ -635,8 +778,13 @@ void LPUART_TransferCreateHandle(LPUART_Type *base, s_lpuartIsr = LPUART_TransferHandleIRQ; - /* Enable interrupt in NVIC. */ +/* Enable interrupt in NVIC. */ +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ + EnableIRQ(s_lpuartRxIRQ[instance]); + EnableIRQ(s_lpuartTxIRQ[instance]); +#else EnableIRQ(s_lpuartIRQ[instance]); +#endif } void LPUART_TransferStartRingBuffer(LPUART_Type *base, @@ -645,18 +793,16 @@ void LPUART_TransferStartRingBuffer(LPUART_Type *base, size_t ringBufferSize) { assert(handle); + assert(ringBuffer); /* Setup the ring buffer address */ - if (ringBuffer) - { - handle->rxRingBuffer = ringBuffer; - handle->rxRingBufferSize = ringBufferSize; - handle->rxRingBufferHead = 0U; - handle->rxRingBufferTail = 0U; + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; - /* Enable the interrupt to accept the data when user need the ring buffer. */ - LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); - } + /* Enable the interrupt to accept the data when user need the ring buffer. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable); } void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle) @@ -676,13 +822,12 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle) status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer) { - status_t status; + assert(handle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } + status_t status; /* Return error if current TX busy. */ if (kLPUART_TxBusy == handle->txState) @@ -707,6 +852,8 @@ status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *hand void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle) { + assert(handle); + LPUART_DisableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_TransmissionCompleteInterruptEnable); handle->txDataSize = 0; @@ -715,16 +862,14 @@ void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle) status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) { + assert(handle); + assert(count); + if (kLPUART_TxIdle == handle->txState) { return kStatus_NoTransferInProgress; } - if (!count) - { - return kStatus_InvalidArgument; - } - *count = handle->txDataSizeAll - handle->txDataSize; return kStatus_Success; @@ -735,6 +880,11 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, lpuart_transfer_t *xfer, size_t *receivedBytes) { + assert(handle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + uint32_t i; status_t status; /* How many bytes to copy from ring buffer to user memory. */ @@ -743,13 +893,6 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, size_t bytesToReceive; /* How many bytes currently have received. */ size_t bytesCurrentReceived; - uint32_t regPrimask = 0U; - - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } /* How to get data: 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize @@ -773,8 +916,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, /* If RX ring buffer is used. */ if (handle->rxRingBuffer) { - /* Disable IRQ, protect ring buffer. */ - regPrimask = DisableGlobalIRQ(); + /* Disable LPUART RX IRQ, protect ring buffer. */ + LPUART_DisableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable); /* How many bytes in RX ring buffer currently. */ bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle); @@ -811,8 +954,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, handle->rxDataSizeAll = bytesToReceive; handle->rxState = kLPUART_RxBusy; } - /* Enable IRQ if previously enabled. */ - EnableGlobalIRQ(regPrimask); + /* Enable LPUART RX IRQ if previously enabled. */ + LPUART_EnableInterrupts(base, kLPUART_RxDataRegFullInterruptEnable); /* Call user callback since all data are received. */ if (0 == bytesToReceive) @@ -849,6 +992,8 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle) { + assert(handle); + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ if (!handle->rxRingBuffer) { @@ -862,16 +1007,14 @@ void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle) status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) { + assert(handle); + assert(count); + if (kLPUART_RxIdle == handle->rxState) { return kStatus_NoTransferInProgress; } - if (!count) - { - return kStatus_InvalidArgument; - } - *count = handle->rxDataSizeAll - handle->rxDataSize; return kStatus_Success; @@ -879,19 +1022,17 @@ status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *hand void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle) { + assert(handle); + uint8_t count; uint8_t tempCount; - volatile uint8_t dummy; - - assert(handle); /* If RX overrun. */ if (LPUART_STAT_OR_MASK & base->STAT) { - /* Read base->DATA, otherwise the RX does not work. */ - dummy = base->DATA; - /* Avoid optimization */ - dummy++; + /* Clear overrun flag, otherwise the RX does not work. */ + base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK); + /* Trigger callback. */ if (handle->callback) { @@ -964,8 +1105,19 @@ void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle) } } - /* Read data. */ +/* Read data. */ +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + if (handle->isSevenDataBits) + { + handle->rxRingBuffer[handle->rxRingBufferHead] = (base->DATA & 0x7F); + } + else + { + handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA; + } +#else handle->rxRingBuffer[handle->rxRingBufferHead] = base->DATA; +#endif /* Increase handle->rxRingBufferHead. */ if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) @@ -1033,71 +1185,113 @@ void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle) void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle) { - /* TODO: To be implemented. */ + /* To be implemented by User. */ } #if defined(LPUART0) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART0_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); +} +void LPUART0_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART0, s_lpuartHandle[0]); +} +#else void LPUART0_DriverIRQHandler(void) { s_lpuartIsr(LPUART0, s_lpuartHandle[0]); } -void LPUART0_RX_TX_DriverIRQHandler(void) -{ - LPUART0_DriverIRQHandler(); -} +#endif #endif #if defined(LPUART1) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART1_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); +} +void LPUART1_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART1, s_lpuartHandle[1]); +} +#else void LPUART1_DriverIRQHandler(void) { s_lpuartIsr(LPUART1, s_lpuartHandle[1]); } -void LPUART1_RX_TX_DriverIRQHandler(void) -{ - LPUART1_DriverIRQHandler(); -} +#endif #endif #if defined(LPUART2) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART2_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART2, s_lpuartHandle[2]); +} +void LPUART2_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART2, s_lpuartHandle[2]); +} +#else void LPUART2_DriverIRQHandler(void) { s_lpuartIsr(LPUART2, s_lpuartHandle[2]); } -void LPUART2_RX_TX_DriverIRQHandler(void) -{ - LPUART2_DriverIRQHandler(); -} +#endif #endif #if defined(LPUART3) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART3_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART3, s_lpuartHandle[3]); +} +void LPUART3_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART3, s_lpuartHandle[3]); +} +#else void LPUART3_DriverIRQHandler(void) { s_lpuartIsr(LPUART3, s_lpuartHandle[3]); } -void LPUART3_RX_TX_DriverIRQHandler(void) -{ - LPUART3_DriverIRQHandler(); -} +#endif #endif #if defined(LPUART4) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART4_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART4, s_lpuartHandle[4]); +} +void LPUART4_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART4, s_lpuartHandle[4]); +} +#else void LPUART4_DriverIRQHandler(void) { s_lpuartIsr(LPUART4, s_lpuartHandle[4]); } -void LPUART4_RX_TX_DriverIRQHandler(void) -{ - LPUART4_DriverIRQHandler(); -} +#endif #endif #if defined(LPUART5) +#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ +void LPUART5_TX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART5, s_lpuartHandle[5]); +} +void LPUART5_RX_DriverIRQHandler(void) +{ + s_lpuartIsr(LPUART5, s_lpuartHandle[5]); +} +#else void LPUART5_DriverIRQHandler(void) { s_lpuartIsr(LPUART5, s_lpuartHandle[5]); } -void LPUART5_RX_TX_DriverIRQHandler(void) -{ - LPUART5_DriverIRQHandler(); -} +#endif #endif diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart.h index a357400b56..0c60f82d88 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,36 +37,35 @@ * @{ */ -/*! @file*/ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief LPUART driver version 2.1.0. */ -#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*! @brief LPUART driver version 2.2.3. */ +#define FSL_LPUART_DRIVER_VERSION (MAKE_VERSION(2, 2, 3)) /*@}*/ /*! @brief Error codes for the LPUART driver. */ enum _lpuart_status { - kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */ - kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */ - kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */ - kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */ - kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */ - kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */ - kStatus_LPUART_FlagCannotClearManually = - MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */ - kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */ + kStatus_LPUART_TxBusy = MAKE_STATUS(kStatusGroup_LPUART, 0), /*!< TX busy */ + kStatus_LPUART_RxBusy = MAKE_STATUS(kStatusGroup_LPUART, 1), /*!< RX busy */ + kStatus_LPUART_TxIdle = MAKE_STATUS(kStatusGroup_LPUART, 2), /*!< LPUART transmitter is idle. */ + kStatus_LPUART_RxIdle = MAKE_STATUS(kStatusGroup_LPUART, 3), /*!< LPUART receiver is idle. */ + kStatus_LPUART_TxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 4), /*!< TX FIFO watermark too large */ + kStatus_LPUART_RxWatermarkTooLarge = MAKE_STATUS(kStatusGroup_LPUART, 5), /*!< RX FIFO watermark too large */ + kStatus_LPUART_FlagCannotClearManually = MAKE_STATUS(kStatusGroup_LPUART, 6), /*!< Some flag can't manually clear */ + kStatus_LPUART_Error = MAKE_STATUS(kStatusGroup_LPUART, 7), /*!< Error happens on LPUART. */ kStatus_LPUART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_LPUART, 8), /*!< LPUART RX software ring buffer overrun. */ kStatus_LPUART_RxHardwareOverrun = MAKE_STATUS(kStatusGroup_LPUART, 9), /*!< LPUART RX receiver overrun. */ kStatus_LPUART_NoiseError = MAKE_STATUS(kStatusGroup_LPUART, 10), /*!< LPUART noise error. */ kStatus_LPUART_FramingError = MAKE_STATUS(kStatusGroup_LPUART, 11), /*!< LPUART framing error. */ kStatus_LPUART_ParityError = MAKE_STATUS(kStatusGroup_LPUART, 12), /*!< LPUART parity error. */ + kStatus_LPUART_BaudrateNotSupport = + MAKE_STATUS(kStatusGroup_LPUART, 13), /*!< Baudrate is not support in current clock source */ }; /*! @brief LPUART parity mode. */ @@ -77,6 +76,15 @@ typedef enum _lpuart_parity_mode kLPUART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */ } lpuart_parity_mode_t; +/*! @brief LPUART data bits count. */ +typedef enum _lpuart_data_bits +{ + kLPUART_EightDataBits = 0x0U, /*!< Eight data bit */ +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + kLPUART_SevenDataBits = 0x1U, /*!< Seven data bit */ +#endif +} lpuart_data_bits_t; + /*! @brief LPUART stop bit count. */ typedef enum _lpuart_stop_bit_count { @@ -158,11 +166,13 @@ enum _lpuart_flags #endif }; -/*! @brief LPUART configure structure. */ +/*! @brief LPUART configuration structure. */ typedef struct _lpuart_config { - uint32_t baudRate_Bps; /*!< LPUART baud rate */ - lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ + uint32_t baudRate_Bps; /*!< LPUART baud rate */ + lpuart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ + lpuart_data_bits_t dataBitsCount; /*!< Data bits count, eight (default), seven */ + bool isMsb; /*!< Data bits order, LSB (default), MSB */ #if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT lpuart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */ #endif @@ -206,7 +216,11 @@ struct _lpuart_handle void *userData; /*!< LPUART callback function parameter.*/ volatile uint8_t txState; /*!< TX transfer state. */ - volatile uint8_t rxState; /*!< RX transfer state */ + volatile uint8_t rxState; /*!< RX transfer state. */ + +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + bool isSevenDataBits; /*!< Seven data bits flag. */ +#endif }; /******************************************************************************* @@ -217,32 +231,59 @@ struct _lpuart_handle extern "C" { #endif /* _cplusplus */ +#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL + +/*! + * @name Software Reset + * @{ + */ + +/*! + * @brief Resets the LPUART using software. + * + * This function resets all internal logic and registers except the Global Register. + * Remains set until cleared by software. + * + * @param base LPUART peripheral base address. + */ +static inline void LPUART_SoftwareReset(LPUART_Type *base) +{ + base->GLOBAL |= LPUART_GLOBAL_RST_MASK; + base->GLOBAL &= ~LPUART_GLOBAL_RST_MASK; +} +/* @} */ +#endif /*FSL_FEATURE_LPUART_HAS_GLOBAL*/ + /*! * @name Initialization and deinitialization * @{ */ /*! -* @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock. -* -* This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function -* to configure the configuration structure and get the default configuration. -* The example below shows how to use this API to configure the LPUART. -* @code -* lpuart_config_t lpuartConfig; -* lpuartConfig.baudRate_Bps = 115200U; -* lpuartConfig.parityMode = kLPUART_ParityDisabled; -* lpuartConfig.stopBitCount = kLPUART_OneStopBit; -* lpuartConfig.txFifoWatermark = 0; -* lpuartConfig.rxFifoWatermark = 1; -* LPUART_Init(LPUART1, &lpuartConfig, 20000000U); -* @endcode -* -* @param base LPUART peripheral base address. -* @param config Pointer to a user-defined configuration structure. -* @param srcClock_Hz LPUART clock source frequency in HZ. -*/ -void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz); + * @brief Initializes an LPUART instance with the user configuration structure and the peripheral clock. + * + * This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function + * to configure the configuration structure and get the default configuration. + * The example below shows how to use this API to configure the LPUART. + * @code + * lpuart_config_t lpuartConfig; + * lpuartConfig.baudRate_Bps = 115200U; + * lpuartConfig.parityMode = kLPUART_ParityDisabled; + * lpuartConfig.dataBitsCount = kLPUART_EightDataBits; + * lpuartConfig.isMsb = false; + * lpuartConfig.stopBitCount = kLPUART_OneStopBit; + * lpuartConfig.txFifoWatermark = 0; + * lpuartConfig.rxFifoWatermark = 1; + * LPUART_Init(LPUART1, &lpuartConfig, 20000000U); + * @endcode + * + * @param base LPUART peripheral base address. + * @param config Pointer to a user-defined configuration structure. + * @param srcClock_Hz LPUART clock source frequency in HZ. + * @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_Success LPUART initialize succeed + */ +status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz); /*! * @brief Deinitializes a LPUART instance. @@ -260,6 +301,8 @@ void LPUART_Deinit(LPUART_Type *base); * values are: * lpuartConfig->baudRate_Bps = 115200U; * lpuartConfig->parityMode = kLPUART_ParityDisabled; + * lpuartConfig->dataBitsCount = kLPUART_EightDataBits; + * lpuartConfig->isMsb = false; * lpuartConfig->stopBitCount = kLPUART_OneStopBit; * lpuartConfig->txFifoWatermark = 0; * lpuartConfig->rxFifoWatermark = 1; @@ -282,8 +325,10 @@ void LPUART_GetDefaultConfig(lpuart_config_t *config); * @param base LPUART peripheral base address. * @param baudRate_Bps LPUART baudrate to be set. * @param srcClock_Hz LPUART clock source frequency in HZ. + * @retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source. + * @retval kStatus_Success Set baudrate succeeded. */ -void LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); +status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); /* @} */ @@ -512,24 +557,40 @@ static inline void LPUART_WriteByte(LPUART_Type *base, uint8_t data) } /*! - * @brief Reads the RX register. + * @brief Reads the receiver register. * - * This function reads data from the TX register directly. The upper layer must - * ensure that the RX register is full or that the TX FIFO has data before calling this function. + * This function reads data from the receiver register directly. The upper layer must + * ensure that the receiver register is full or that the RX FIFO has data before calling this function. * * @param base LPUART peripheral base address. * @return Data read from data register. */ static inline uint8_t LPUART_ReadByte(LPUART_Type *base) { +#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT + uint32_t ctrl = base->CTRL; + bool isSevenDataBits = + ((ctrl & LPUART_CTRL_M7_MASK) || + ((!(ctrl & LPUART_CTRL_M7_MASK)) && (!(ctrl & LPUART_CTRL_M_MASK)) && (ctrl & LPUART_CTRL_PE_MASK))); + + if (isSevenDataBits) + { + return (base->DATA & 0x7F); + } + else + { + return base->DATA; + } +#else return base->DATA; +#endif } /*! - * @brief Writes to transmitter register using a blocking method. + * @brief Writes to the transmitter register using a blocking method. * * This function polls the transmitter register, waits for the register to be empty or for TX FIFO to have - * room and then writes data to the transmitter buffer. + * room, and writes data to the transmitter buffer. * * @note This function does not check whether all data has been sent out to the bus. * Before disabling the transmitter, check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is @@ -542,10 +603,10 @@ static inline uint8_t LPUART_ReadByte(LPUART_Type *base) void LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length); /*! -* @brief Reads the RX data register using a blocking method. +* @brief Reads the receiver data register using a blocking method. * - * This function polls the RX register, waits for the RX register full or RX FIFO - * has data then reads data from the TX register. + * This function polls the receiver register, waits for the receiver register full or receiver FIFO + * has data, and reads data from the TX register. * * @param base LPUART peripheral base address. * @param data Start address of the buffer to store the received data. @@ -601,7 +662,7 @@ void LPUART_TransferCreateHandle(LPUART_Type *base, * * @param base LPUART peripheral base address. * @param handle LPUART handle pointer. - * @param xfer LPUART transfer structure, refer to #lpuart_transfer_t. + * @param xfer LPUART transfer structure, see #lpuart_transfer_t. * @retval kStatus_Success Successfully start the data transmission. * @retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register. * @retval kStatus_InvalidArgument Invalid argument. @@ -631,7 +692,7 @@ void LPUART_TransferStartRingBuffer(LPUART_Type *base, size_t ringBufferSize); /*! - * @brief Abort the background transfer and uninstall the ring buffer. + * @brief Aborts the background transfer and uninstalls the ring buffer. * * This function aborts the background transfer and uninstalls the ring buffer. * @@ -644,7 +705,7 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle); * @brief Aborts the interrupt-driven data transmit. * * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out - * how many bytes are still not sent out. + * how many bytes are not sent out. * * @param base LPUART peripheral base address. * @param handle LPUART handle pointer. @@ -652,10 +713,10 @@ void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle); void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle); /*! - * @brief Get the number of bytes that have been written to LPUART TX register. + * @brief Gets the number of bytes that have been written to the LPUART transmitter register. * * This function gets the number of bytes that have been written to LPUART TX - * register by interrupt method. + * register by an interrupt method. * * @param base LPUART peripheral base address. * @param handle LPUART handle pointer. @@ -686,7 +747,7 @@ status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, * * @param base LPUART peripheral base address. * @param handle LPUART handle pointer. - * @param xfer LPUART transfer structure, refer to #uart_transfer_t. + * @param xfer LPUART transfer structure, see #uart_transfer_t. * @param receivedBytes Bytes received from the ring buffer directly. * @retval kStatus_Success Successfully queue the transfer into the transmit queue. * @retval kStatus_LPUART_RxBusy Previous receive request is not finished. @@ -709,7 +770,7 @@ status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle); /*! - * @brief Get the number of bytes that have been received. + * @brief Gets the number of bytes that have been received. * * This function gets the number of bytes that have been received. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart_edma.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart_edma.c index b4242f6262..24da483147 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart_edma.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart_edma.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -98,6 +98,8 @@ extern uint32_t LPUART_GetInstance(LPUART_Type *base); static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) { + assert(param); + lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param; /* Avoid the warning for unused variables. */ @@ -118,6 +120,8 @@ static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool tra static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) { + assert(param); + lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param; /* Avoid warning for unused parameters. */ @@ -138,11 +142,11 @@ static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool } void LPUART_TransferCreateHandleEDMA(LPUART_Type *base, - lpuart_edma_handle_t *handle, - lpuart_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *txEdmaHandle, - edma_handle_t *rxEdmaHandle) + lpuart_edma_handle_t *handle, + lpuart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle) { assert(handle); @@ -189,19 +193,18 @@ void LPUART_TransferCreateHandleEDMA(LPUART_Type *base, EDMA_SetCallback(handle->rxEdmaHandle, LPUART_ReceiveEDMACallback, &s_edmaPrivateHandle[instance]); } } + status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer) { + assert(handle); assert(handle->txEdmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); edma_transfer_config_t xferConfig; status_t status; - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } - /* If previous TX not finished. */ if (kLPUART_TxBusy == handle->txState) { @@ -216,6 +219,9 @@ status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral); + /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */ + handle->nbytes = sizeof(uint8_t); + /* Submit transfer. */ EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig); EDMA_StartTransfer(handle->txEdmaHandle); @@ -231,17 +237,15 @@ status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer) { + assert(handle); assert(handle->rxEdmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); edma_transfer_config_t xferConfig; status_t status; - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } - /* If previous RX not finished. */ if (kLPUART_RxBusy == handle->rxState) { @@ -256,6 +260,9 @@ status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpu EDMA_PrepareTransfer(&xferConfig, (void *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data, sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory); + /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */ + handle->nbytes = sizeof(uint8_t); + /* Submit transfer. */ EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig); EDMA_StartTransfer(handle->rxEdmaHandle); @@ -271,6 +278,7 @@ status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpu void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle) { + assert(handle); assert(handle->txEdmaHandle); /* Disable LPUART TX EDMA. */ @@ -284,6 +292,7 @@ void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handl void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle) { + assert(handle); assert(handle->rxEdmaHandle); /* Disable LPUART RX EDMA. */ @@ -297,38 +306,36 @@ void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *ha status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count) { + assert(handle); assert(handle->rxEdmaHandle); + assert(count); if (kLPUART_RxIdle == handle->rxState) { return kStatus_NoTransferInProgress; } - if (!count) - { - return kStatus_InvalidArgument; - } - - *count = handle->rxDataSizeAll - EDMA_GetRemainingBytes(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel); + *count = handle->rxDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel); return kStatus_Success; } status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count) { + assert(handle); assert(handle->txEdmaHandle); + assert(count); if (kLPUART_TxIdle == handle->txState) { return kStatus_NoTransferInProgress; } - if (!count) - { - return kStatus_InvalidArgument; - } - - *count = handle->txDataSizeAll - EDMA_GetRemainingBytes(handle->txEdmaHandle->base, handle->txEdmaHandle->channel); + *count = handle->txDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel); return kStatus_Success; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart_edma.h index 35e922e125..79565c688d 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_lpuart_edma.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -39,8 +39,6 @@ * @{ */ -/*! @file*/ - /******************************************************************************* * Definitions ******************************************************************************/ @@ -67,6 +65,8 @@ struct _lpuart_edma_handle edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */ edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + volatile uint8_t txState; /*!< TX transfer state. */ volatile uint8_t rxState; /*!< RX transfer state */ }; @@ -94,11 +94,11 @@ extern "C" { * @param rxEdmaHandle User requested DMA handle for RX DMA transfer. */ void LPUART_TransferCreateHandleEDMA(LPUART_Type *base, - lpuart_edma_handle_t *handle, - lpuart_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *txEdmaHandle, - edma_handle_t *rxEdmaHandle); + lpuart_edma_handle_t *handle, + lpuart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle); /*! * @brief Sends data using eDMA. @@ -123,7 +123,7 @@ status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart * * @param base LPUART peripheral base address. * @param handle Pointer to lpuart_edma_handle_t structure. - * @param xfer LPUART eDMA transfer structure, refer to #lpuart_transfer_t. + * @param xfer LPUART eDMA transfer structure, see #lpuart_transfer_t. * @retval kStatus_Success if succeed, others fail. * @retval kStatus_LPUART_RxBusy Previous transfer ongoing. * @retval kStatus_InvalidArgument Invalid argument. @@ -151,9 +151,9 @@ void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handl void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle); /*! - * @brief Get the number of bytes that have been written to LPUART TX register. + * @brief Gets the number of bytes written to the LPUART TX register. * - * This function gets the number of bytes that have been written to LPUART TX + * This function gets the number of bytes written to the LPUART TX * register by DMA. * * @param base LPUART peripheral base address. @@ -166,9 +166,9 @@ void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *ha status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count); /*! - * @brief Get the number of bytes that have been received. + * @brief Gets the number of received bytes. * - * This function gets the number of bytes that have been received. + * This function gets the number of received bytes. * * @param base LPUART peripheral base address. * @param handle LPUART handle pointer. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_mpu.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_mpu.c deleted file mode 100644 index 926eff9641..0000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_mpu.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * 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. - */ - -#include "fsl_mpu.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Defines the register numbers of the region descriptor configure. */ -#define MPU_REGIONDESCRIPTOR_WROD_REGNUM (4U) - -/******************************************************************************* - * Variables - ******************************************************************************/ - -const clock_ip_name_t g_mpuClock[FSL_FEATURE_SOC_MPU_COUNT] = MPU_CLOCKS; - -/******************************************************************************* - * Codes - ******************************************************************************/ - -void MPU_Init(MPU_Type *base, const mpu_config_t *config) -{ - assert(config); - uint8_t count; - - /* Un-gate MPU clock */ - CLOCK_EnableClock(g_mpuClock[0]); - - /* Initializes the regions. */ - for (count = 1; count < FSL_FEATURE_MPU_DESCRIPTOR_COUNT; count++) - { - base->WORD[count][3] = 0; /* VLD/VID+PID. */ - base->WORD[count][0] = 0; /* Start address. */ - base->WORD[count][1] = 0; /* End address. */ - base->WORD[count][2] = 0; /* Access rights. */ - base->RGDAAC[count] = 0; /* Alternate access rights. */ - } - - /* MPU configure. */ - while (config) - { - MPU_SetRegionConfig(base, &(config->regionConfig)); - config = config->next; - } - /* Enable MPU. */ - MPU_Enable(base, true); -} - -void MPU_Deinit(MPU_Type *base) -{ - /* Disable MPU. */ - MPU_Enable(base, false); - - /* Gate the clock. */ - CLOCK_DisableClock(g_mpuClock[0]); -} - -void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform) -{ - assert(hardwareInform); - - uint32_t cesReg = base->CESR; - - hardwareInform->hardwareRevisionLevel = (cesReg & MPU_CESR_HRL_MASK) >> MPU_CESR_HRL_SHIFT; - hardwareInform->slavePortsNumbers = (cesReg & MPU_CESR_NSP_MASK) >> MPU_CESR_NSP_SHIFT; - hardwareInform->regionsNumbers = (mpu_region_total_num_t)((cesReg & MPU_CESR_NRGD_MASK) >> MPU_CESR_NRGD_SHIFT); -} - -void MPU_SetRegionConfig(MPU_Type *base, const mpu_region_config_t *regionConfig) -{ - assert(regionConfig); - - uint32_t wordReg = 0; - uint8_t count; - uint8_t number = regionConfig->regionNum; - - /* The start and end address of the region descriptor. */ - base->WORD[number][0] = regionConfig->startAddress; - base->WORD[number][1] = regionConfig->endAddress; - - /* The region descriptor access rights control. */ - for (count = 0; count < MPU_REGIONDESCRIPTOR_WROD_REGNUM; count++) - { - wordReg |= MPU_WORD_LOW_MASTER(count, (((uint32_t)regionConfig->accessRights1[count].superAccessRights << 3U) | - (uint8_t)regionConfig->accessRights1[count].userAccessRights)) | - MPU_WORD_HIGH_MASTER(count, ((uint32_t)regionConfig->accessRights2[count].readEnable << 1U | - (uint8_t)regionConfig->accessRights2[count].writeEnable)); - -#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER - wordReg |= MPU_WORD_MASTER_PE(count, regionConfig->accessRights1[count].processIdentifierEnable); -#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ - } - - /* Set region descriptor access rights. */ - base->WORD[number][2] = wordReg; - - wordReg = MPU_WORD_VLD(1); -#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER - wordReg |= MPU_WORD_PID(regionConfig->processIdentifier) | MPU_WORD_PIDMASK(regionConfig->processIdMask); -#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ - - base->WORD[number][3] = wordReg; -} - -void MPU_SetRegionAddr(MPU_Type *base, mpu_region_num_t regionNum, uint32_t startAddr, uint32_t endAddr) -{ - base->WORD[regionNum][0] = startAddr; - base->WORD[regionNum][1] = endAddr; -} - -void MPU_SetRegionLowMasterAccessRights(MPU_Type *base, - mpu_region_num_t regionNum, - mpu_master_t masterNum, - const mpu_low_masters_access_rights_t *accessRights) -{ - assert(accessRights); -#if FSL_FEATURE_MPU_HAS_MASTER4 - assert(masterNum < kMPU_Master4); -#endif - uint32_t mask = MPU_WORD_LOW_MASTER_MASK(masterNum); - uint32_t right = base->RGDAAC[regionNum]; - -#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER - mask |= MPU_LOW_MASTER_PE_MASK(masterNum); -#endif - - /* Build rights control value. */ - right &= ~mask; - right |= MPU_WORD_LOW_MASTER(masterNum, - ((uint32_t)(accessRights->superAccessRights << 3U) | accessRights->userAccessRights)); -#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER - right |= MPU_WORD_MASTER_PE(masterNum, accessRights->processIdentifierEnable); -#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ - - /* Set low master region access rights. */ - base->RGDAAC[regionNum] = right; -} - -void MPU_SetRegionHighMasterAccessRights(MPU_Type *base, - mpu_region_num_t regionNum, - mpu_master_t masterNum, - const mpu_high_masters_access_rights_t *accessRights) -{ - assert(accessRights); -#if FSL_FEATURE_MPU_HAS_MASTER3 - assert(masterNum > kMPU_Master3); -#endif - uint32_t mask = MPU_WORD_HIGH_MASTER_MASK(masterNum); - uint32_t right = base->RGDAAC[regionNum]; - - /* Build rights control value. */ - right &= ~mask; - right |= MPU_WORD_HIGH_MASTER((masterNum - (uint8_t)kMPU_RegionNum04), - (((uint32_t)accessRights->readEnable << 1U) | accessRights->writeEnable)); - /* Set low master region access rights. */ - base->RGDAAC[regionNum] = right; -} - -bool MPU_GetSlavePortErrorStatus(MPU_Type *base, mpu_slave_t slaveNum) -{ - uint8_t sperr; - - sperr = ((base->CESR & MPU_CESR_SPERR_MASK) >> MPU_CESR_SPERR_SHIFT) & (0x1U << slaveNum); - - return (sperr != 0) ? true : false; -} - -void MPU_GetDetailErrorAccessInfo(MPU_Type *base, mpu_slave_t slaveNum, mpu_access_err_info_t *errInform) -{ - assert(errInform); - - uint16_t value; - - /* Error address. */ - errInform->address = base->SP[slaveNum].EAR; - - /* Error detail information. */ - value = (base->SP[slaveNum].EDR & MPU_EDR_EACD_MASK) >> MPU_EDR_EACD_SHIFT; - if (!value) - { - errInform->accessControl = kMPU_NoRegionHit; - } - else if (!(value & (uint16_t)(value - 1))) - { - errInform->accessControl = kMPU_NoneOverlappRegion; - } - else - { - errInform->accessControl = kMPU_OverlappRegion; - } - - value = base->SP[slaveNum].EDR; - errInform->master = (mpu_master_t)((value & MPU_EDR_EMN_MASK) >> MPU_EDR_EMN_SHIFT); - errInform->attributes = (mpu_err_attributes_t)((value & MPU_EDR_EATTR_MASK) >> MPU_EDR_EATTR_SHIFT); - errInform->accessType = (mpu_err_access_type_t)((value & MPU_EDR_ERW_MASK) >> MPU_EDR_ERW_SHIFT); -#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER - errInform->processorIdentification = (uint8_t)((value & MPU_EDR_EPID_MASK) >> MPU_EDR_EPID_SHIFT); -#endif - - /*!< Clears error slave port bit. */ - value = (base->CESR & ~MPU_CESR_SPERR_MASK) | (0x1U << slaveNum); - base->CESR = value; -} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_mpu.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_mpu.h deleted file mode 100644 index acdcfd1be3..0000000000 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_mpu.h +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * 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. - */ -#ifndef _FSL_MPU_H_ -#define _FSL_MPU_H_ - -#include "fsl_common.h" - -/*! - * @addtogroup mpu - * @{ - */ - -/*! @file */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/*! @name Driver version */ -/*@{*/ -/*! @brief MPU driver version 2.0.0. */ -#define FSL_MPU_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) -/*@}*/ - -/*! @brief MPU low master bit shift. */ -#define MPU_WORD_LOW_MASTER_SHIFT(n) (n * 6) - -/*! @brief MPU low master bit mask. */ -#define MPU_WORD_LOW_MASTER_MASK(n) (0x1Fu << MPU_WORD_LOW_MASTER_SHIFT(n)) - -/*! @brief MPU low master bit width. */ -#define MPU_WORD_LOW_MASTER_WIDTH 5 - -/*! @brief MPU low master priority setting. */ -#define MPU_WORD_LOW_MASTER(n, x) \ - (((uint32_t)(((uint32_t)(x)) << MPU_WORD_LOW_MASTER_SHIFT(n))) & MPU_WORD_LOW_MASTER_MASK(n)) - -/*! @brief MPU low master process enable bit shift. */ -#define MPU_LOW_MASTER_PE_SHIFT(n) (n * 6 + 5) - -/*! @brief MPU low master process enable bit mask. */ -#define MPU_LOW_MASTER_PE_MASK(n) (0x1u << MPU_LOW_MASTER_PE_SHIFT(n)) - -/*! @brief MPU low master process enable width. */ -#define MPU_WORD_MASTER_PE_WIDTH 1 - -/*! @brief MPU low master process enable setting. */ -#define MPU_WORD_MASTER_PE(n, x) \ - (((uint32_t)(((uint32_t)(x)) << MPU_LOW_MASTER_PE_SHIFT(n))) & MPU_LOW_MASTER_PE_MASK(n)) - -/*! @brief MPU high master bit shift. */ -#define MPU_WORD_HIGH_MASTER_SHIFT(n) (n * 2 + 24) - -/*! @brief MPU high master bit mask. */ -#define MPU_WORD_HIGH_MASTER_MASK(n) (0x03u << MPU_WORD_HIGH_MASTER_SHIFT(n)) - -/*! @brief MPU high master bit width. */ -#define MPU_WORD_HIGH_MASTER_WIDTH 2 - -/*! @brief MPU high master priority setting. */ -#define MPU_WORD_HIGH_MASTER(n, x) \ - (((uint32_t)(((uint32_t)(x)) << MPU_WORD_HIGH_MASTER_SHIFT(n))) & MPU_WORD_HIGH_MASTER_MASK(n)) - -/*! @brief MPU region number. */ -typedef enum _mpu_region_num -{ -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 0U - kMPU_RegionNum00 = 0U, /*!< MPU region number 0. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 1U - kMPU_RegionNum01 = 1U, /*!< MPU region number 1. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 2U - kMPU_RegionNum02 = 2U, /*!< MPU region number 2. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 3U - kMPU_RegionNum03 = 3U, /*!< MPU region number 3. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 4U - kMPU_RegionNum04 = 4U, /*!< MPU region number 4. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 5U - kMPU_RegionNum05 = 5U, /*!< MPU region number 5. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 6U - kMPU_RegionNum06 = 6U, /*!< MPU region number 6. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 7U - kMPU_RegionNum07 = 7U, /*!< MPU region number 7. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 8U - kMPU_RegionNum08 = 8U, /*!< MPU region number 8. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 9U - kMPU_RegionNum09 = 9U, /*!< MPU region number 9. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 10U - kMPU_RegionNum10 = 10U, /*!< MPU region number 10. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 11U - kMPU_RegionNum11 = 11U, /*!< MPU region number 11. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 12U - kMPU_RegionNum12 = 12U, /*!< MPU region number 12. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 13U - kMPU_RegionNum13 = 13U, /*!< MPU region number 13. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 14U - kMPU_RegionNum14 = 14U, /*!< MPU region number 14. */ -#endif -#if FSL_FEATURE_MPU_DESCRIPTOR_COUNT > 15U - kMPU_RegionNum15 = 15U, /*!< MPU region number 15. */ -#endif -} mpu_region_num_t; - -/*! @brief MPU master number. */ -typedef enum _mpu_master -{ -#if FSL_FEATURE_MPU_HAS_MASTER0 - kMPU_Master0 = 0U, /*!< MPU master core. */ -#endif -#if FSL_FEATURE_MPU_HAS_MASTER1 - kMPU_Master1 = 1U, /*!< MPU master defined in SoC. */ -#endif -#if FSL_FEATURE_MPU_HAS_MASTER2 - kMPU_Master2 = 2U, /*!< MPU master defined in SoC. */ -#endif -#if FSL_FEATURE_MPU_HAS_MASTER3 - kMPU_Master3 = 3U, /*!< MPU master defined in SoC. */ -#endif -#if FSL_FEATURE_MPU_HAS_MASTER4 - kMPU_Master4 = 4U, /*!< MPU master defined in SoC. */ -#endif -#if FSL_FEATURE_MPU_HAS_MASTER5 - kMPU_Master5 = 5U, /*!< MPU master defined in SoC. */ -#endif -#if FSL_FEATURE_MPU_HAS_MASTER6 - kMPU_Master6 = 6U, /*!< MPU master defined in SoC. */ -#endif -#if FSL_FEATURE_MPU_HAS_MASTER7 - kMPU_Master7 = 7U /*!< MPU master defined in SoC. */ -#endif -} mpu_master_t; - -/*! @brief Describes the number of MPU regions. */ -typedef enum _mpu_region_total_num -{ - kMPU_8Regions = 0x0U, /*!< MPU supports 8 regions. */ - kMPU_12Regions = 0x1U, /*!< MPU supports 12 regions. */ - kMPU_16Regions = 0x2U /*!< MPU supports 16 regions. */ -} mpu_region_total_num_t; - -/*! @brief MPU slave port number. */ -typedef enum _mpu_slave -{ - kMPU_Slave0 = 4U, /*!< MPU slave port 0. */ - kMPU_Slave1 = 3U, /*!< MPU slave port 1. */ - kMPU_Slave2 = 2U, /*!< MPU slave port 2. */ - kMPU_Slave3 = 1U, /*!< MPU slave port 3. */ - kMPU_Slave4 = 0U /*!< MPU slave port 4. */ -} mpu_slave_t; - -/*! @brief MPU error access control detail. */ -typedef enum _mpu_err_access_control -{ - kMPU_NoRegionHit = 0U, /*!< No region hit error. */ - kMPU_NoneOverlappRegion = 1U, /*!< Access single region error. */ - kMPU_OverlappRegion = 2U /*!< Access overlapping region error. */ -} mpu_err_access_control_t; - -/*! @brief MPU error access type. */ -typedef enum _mpu_err_access_type -{ - kMPU_ErrTypeRead = 0U, /*!< MPU error access type --- read. */ - kMPU_ErrTypeWrite = 1U /*!< MPU error access type --- write. */ -} mpu_err_access_type_t; - -/*! @brief MPU access error attributes.*/ -typedef enum _mpu_err_attributes -{ - kMPU_InstructionAccessInUserMode = 0U, /*!< Access instruction error in user mode. */ - kMPU_DataAccessInUserMode = 1U, /*!< Access data error in user mode. */ - kMPU_InstructionAccessInSupervisorMode = 2U, /*!< Access instruction error in supervisor mode. */ - kMPU_DataAccessInSupervisorMode = 3U /*!< Access data error in supervisor mode. */ -} mpu_err_attributes_t; - -/*! @brief MPU access rights in supervisor mode for master port 0 ~ port 3. */ -typedef enum _mpu_supervisor_access_rights -{ - kMPU_SupervisorReadWriteExecute = 0U, /*!< Read write and execute operations are allowed in supervisor mode. */ - kMPU_SupervisorReadExecute = 1U, /*!< Read and execute operations are allowed in supervisor mode. */ - kMPU_SupervisorReadWrite = 2U, /*!< Read write operations are allowed in supervisor mode. */ - kMPU_SupervisorEqualToUsermode = 3U /*!< Access permission equal to user mode. */ -} mpu_supervisor_access_rights_t; - -/*! @brief MPU access rights in user mode for master port 0 ~ port 3. */ -typedef enum _mpu_user_access_rights -{ - kMPU_UserNoAccessRights = 0U, /*!< No access allowed in user mode. */ - kMPU_UserExecute = 1U, /*!< Execute operation is allowed in user mode. */ - kMPU_UserWrite = 2U, /*!< Write operation is allowed in user mode. */ - kMPU_UserWriteExecute = 3U, /*!< Write and execute operations are allowed in user mode. */ - kMPU_UserRead = 4U, /*!< Read is allowed in user mode. */ - kMPU_UserReadExecute = 5U, /*!< Read and execute operations are allowed in user mode. */ - kMPU_UserReadWrite = 6U, /*!< Read and write operations are allowed in user mode. */ - kMPU_UserReadWriteExecute = 7U /*!< Read write and execute operations are allowed in user mode. */ -} mpu_user_access_rights_t; - -/*! @brief MPU hardware basic information. */ -typedef struct _mpu_hardware_info -{ - uint8_t hardwareRevisionLevel; /*!< Specifies the MPU's hardware and definition reversion level. */ - uint8_t slavePortsNumbers; /*!< Specifies the number of slave ports connected to MPU. */ - mpu_region_total_num_t regionsNumbers; /*!< Indicates the number of region descriptors implemented. */ -} mpu_hardware_info_t; - -/*! @brief MPU detail error access information. */ -typedef struct _mpu_access_err_info -{ - mpu_master_t master; /*!< Access error master. */ - mpu_err_attributes_t attributes; /*!< Access error attributes. */ - mpu_err_access_type_t accessType; /*!< Access error type. */ - mpu_err_access_control_t accessControl; /*!< Access error control. */ - uint32_t address; /*!< Access error address. */ -#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER - uint8_t processorIdentification; /*!< Access error processor identification. */ -#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ -} mpu_access_err_info_t; - -/*! @brief MPU access rights for low master master port 0 ~ port 3. */ -typedef struct _mpu_low_masters_access_rights -{ - mpu_supervisor_access_rights_t superAccessRights; /*!< Master access rights in supervisor mode. */ - mpu_user_access_rights_t userAccessRights; /*!< Master access rights in user mode. */ -#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER - bool processIdentifierEnable; /*!< Enables or disables process identifier. */ -#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ -} mpu_low_masters_access_rights_t; - -/*! @brief MPU access rights mode for high master port 4 ~ port 7. */ -typedef struct _mpu_high_masters_access_rights -{ - bool writeEnable; /*!< Enables or disables write permission. */ - bool readEnable; /*!< Enables or disables read permission. */ -} mpu_high_masters_access_rights_t; - -/*! - * @brief MPU region configuration structure. - * - * This structure is used to configure the regionNum region. - * The accessRights1[0] ~ accessRights1[3] are used to configure the four low master - * numbers: master 0 ~ master 3. The accessRights2[0] ~ accessRights2[3] are - * used to configure the four high master numbers: master 4 ~ master 7. - * The master port assignment is the chip configuration. Normally, the core is the - * master 0, debugger is the master 1. - * Note: MPU assigns a priority scheme where the debugger is treated as the highest - * priority master followed by the core and then all the remaining masters. - * MPU protection does not allow writes from the core to affect the "regionNum 0" start - * and end address nor the permissions associated with the debugger. It can only write - * the permission fields associated with the other masters. This protection guarantee - * the debugger always has access to the entire address space and those rights can't - * be changed by the core or any other bus master. Prepare - * the region configuration when regionNum is kMPU_RegionNum00. - */ -typedef struct _mpu_region_config -{ - mpu_region_num_t regionNum; /*!< MPU region number. */ - uint32_t startAddress; /*!< Memory region start address. Note: bit0 ~ bit4 always be marked as 0 by MPU. The actual - start address is 0-modulo-32 byte address. */ - uint32_t endAddress; /*!< Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by MPU. The actual end - address is 31-modulo-32 byte address. */ - mpu_low_masters_access_rights_t accessRights1[4]; /*!< Low masters access permission. */ - mpu_high_masters_access_rights_t accessRights2[4]; /*!< High masters access permission. */ -#if FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER - uint8_t processIdentifier; /*!< Process identifier used when "processIdentifierEnable" set with true. */ - uint8_t - processIdMask; /*!< Process identifier mask. The setting bit will ignore the same bit in process identifier. */ -#endif /* FSL_FEATURE_MPU_HAS_PROCESS_IDENTIFIER */ -} mpu_region_config_t; - -/*! - * @brief The configuration structure for the MPU initialization. - * - * This structure is used when calling the MPU_Init function. - */ -typedef struct _mpu_config -{ - mpu_region_config_t regionConfig; /*!< region access permission. */ - struct _mpu_config *next; /*!< pointer to the next structure. */ -} mpu_config_t; - -/******************************************************************************* - * API - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* _cplusplus */ - -/*! - * @name Initialization and deinitialization - * @{ - */ - -/*! - * @brief Initializes the MPU with the user configuration structure. - * - * This function configures the MPU module with the user-defined configuration. - * - * @param base MPU peripheral base address. - * @param config The pointer to the configuration structure. - */ -void MPU_Init(MPU_Type *base, const mpu_config_t *config); - -/*! - * @brief Deinitializes the MPU regions. - * - * @param base MPU peripheral base address. - */ -void MPU_Deinit(MPU_Type *base); - -/* @}*/ - -/*! - * @name Basic Control Operations - * @{ - */ - -/*! - * @brief Enables/disables the MPU globally. - * - * Call this API to enable or disable the MPU module. - * - * @param base MPU peripheral base address. - * @param enable True enable MPU, false disable MPU. - */ -static inline void MPU_Enable(MPU_Type *base, bool enable) -{ - if (enable) - { - /* Enable the MPU globally. */ - base->CESR |= MPU_CESR_VLD_MASK; - } - else - { /* Disable the MPU globally. */ - base->CESR &= ~MPU_CESR_VLD_MASK; - } -} - -/*! - * @brief Enables/disables the MPU for a special region. - * - * When MPU is enabled, call this API to disable an unused region - * of an enabled MPU. Call this API to minimize the power dissipation. - * - * @param base MPU peripheral base address. - * @param number MPU region number. - * @param enable True enable the special region MPU, false disable the special region MPU. - */ -static inline void MPU_RegionEnable(MPU_Type *base, mpu_region_num_t number, bool enable) -{ - if (enable) - { - /* Enable the #number region MPU. */ - base->WORD[number][3] |= MPU_WORD_VLD_MASK; - } - else - { /* Disable the #number region MPU. */ - base->WORD[number][3] &= ~MPU_WORD_VLD_MASK; - } -} - -/*! - * @brief Gets the MPU basic hardware information. - * - * @param base MPU peripheral base address. - * @param hardwareInform The pointer to the MPU hardware information structure. See "mpu_hardware_info_t". - */ -void MPU_GetHardwareInfo(MPU_Type *base, mpu_hardware_info_t *hardwareInform); - -/*! - * @brief Sets the MPU region. - * - * Note: Due to the MPU protection, the kMPU_RegionNum00 does not allow writes from the - * core to affect the start and end address nor the permissions associated with - * the debugger. It can only write the permission fields associated - * with the other masters. - * - * @param base MPU peripheral base address. - * @param regionConfig The pointer to the MPU user configuration structure. See "mpu_region_config_t". - */ -void MPU_SetRegionConfig(MPU_Type *base, const mpu_region_config_t *regionConfig); - -/*! - * @brief Sets the region start and end address. - * - * Memory region start address. Note: bit0 ~ bit4 is always marked as 0 by MPU. - * The actual start address by MPU is 0-modulo-32 byte address. - * Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by MPU. - * The actual end address used by MPU is 31-modulo-32 byte address. - * Note: Due to the MPU protection, the startAddr and endAddr can't be - * changed by the core when regionNum is "kMPU_RegionNum00". - * - * @param base MPU peripheral base address. - * @param regionNum MPU region number. - * @param startAddr Region start address. - * @param endAddr Region end address. - */ -void MPU_SetRegionAddr(MPU_Type *base, mpu_region_num_t regionNum, uint32_t startAddr, uint32_t endAddr); - -/*! - * @brief Sets the MPU region access rights for low master port 0 ~ port 3. - * This can be used to change the region access rights for any master port for any region. - * - * @param base MPU peripheral base address. - * @param regionNum MPU region number. - * @param masterNum MPU master number. Should range from kMPU_Master0 ~ kMPU_Master3. - * @param accessRights The pointer to the MPU access rights configuration. See "mpu_low_masters_access_rights_t". - */ -void MPU_SetRegionLowMasterAccessRights(MPU_Type *base, - mpu_region_num_t regionNum, - mpu_master_t masterNum, - const mpu_low_masters_access_rights_t *accessRights); - -/*! - * @brief Sets the MPU region access rights for high master port 4 ~ port 7. - * This can be used to change the region access rights for any master port for any region. - * - * @param base MPU peripheral base address. - * @param regionNum MPU region number. - * @param masterNum MPU master number. Should range from kMPU_Master4 ~ kMPU_Master7. - * @param accessRights The pointer to the MPU access rights configuration. See "mpu_high_masters_access_rights_t". - */ -void MPU_SetRegionHighMasterAccessRights(MPU_Type *base, - mpu_region_num_t regionNum, - mpu_master_t masterNum, - const mpu_high_masters_access_rights_t *accessRights); - -/*! - * @brief Gets the numbers of slave ports where errors occur. - * - * @param base MPU peripheral base address. - * @param slaveNum MPU slave port number. - * @return The slave ports error status. - * true - error happens in this slave port. - * false - error didn't happen in this slave port. - */ -bool MPU_GetSlavePortErrorStatus(MPU_Type *base, mpu_slave_t slaveNum); - -/*! - * @brief Gets the MPU detailed error access information. - * - * @param base MPU peripheral base address. - * @param slaveNum MPU slave port number. - * @param errInform The pointer to the MPU access error information. See "mpu_access_err_info_t". - */ -void MPU_GetDetailErrorAccessInfo(MPU_Type *base, mpu_slave_t slaveNum, mpu_access_err_info_t *errInform); - -/* @} */ - -#if defined(__cplusplus) -} -#endif - -/*! @}*/ - -#endif /* _FSL_MPU_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pdb.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pdb.c index b5c9b88ec6..1fc4a9a486 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pdb.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pdb.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -45,8 +45,10 @@ static uint32_t PDB_GetInstance(PDB_Type *base); ******************************************************************************/ /*! @brief Pointers to PDB bases for each instance. */ static PDB_Type *const s_pdbBases[] = PDB_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to PDB clocks for each instance. */ -const clock_ip_name_t s_pdbClocks[] = PDB_CLOCKS; +static const clock_ip_name_t s_pdbClocks[] = PDB_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Codes @@ -56,7 +58,7 @@ static uint32_t PDB_GetInstance(PDB_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_PDB_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_pdbBases); instance++) { if (s_pdbBases[instance] == base) { @@ -64,7 +66,7 @@ static uint32_t PDB_GetInstance(PDB_Type *base) } } - assert(instance < FSL_FEATURE_SOC_PDB_COUNT); + assert(instance < ARRAY_SIZE(s_pdbBases)); return instance; } @@ -75,8 +77,10 @@ void PDB_Init(PDB_Type *base, const pdb_config_t *config) uint32_t tmp32; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the clock. */ CLOCK_EnableClock(s_pdbClocks[PDB_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure. */ /* PDBx_SC. */ @@ -98,8 +102,10 @@ void PDB_Deinit(PDB_Type *base) { PDB_Enable(base, false); /* Disable the PDB module. */ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable the clock. */ CLOCK_DisableClock(s_pdbClocks[PDB_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void PDB_GetDefaultConfig(pdb_config_t *config) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pdb.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pdb.h index 1f05b61b26..3dec946346 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pdb.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pdb.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -38,7 +38,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -67,32 +66,32 @@ enum _pdb_status_flags enum _pdb_adc_pretrigger_flags { /* PDB PreTrigger channel match flags. */ - kPDB_ADCPreTriggerChannel0Flag = PDB_S_CF(1U << 0), /*!< Pre-Trigger 0 flag. */ - kPDB_ADCPreTriggerChannel1Flag = PDB_S_CF(1U << 1), /*!< Pre-Trigger 1 flag. */ -#if (PDB_DLY_COUNT > 2) - kPDB_ADCPreTriggerChannel2Flag = PDB_S_CF(1U << 2), /*!< Pre-Trigger 2 flag. */ - kPDB_ADCPreTriggerChannel3Flag = PDB_S_CF(1U << 3), /*!< Pre-Trigger 3 flag. */ -#endif /* PDB_DLY_COUNT > 2 */ -#if (PDB_DLY_COUNT > 4) - kPDB_ADCPreTriggerChannel4Flag = PDB_S_CF(1U << 4), /*!< Pre-Trigger 4 flag. */ - kPDB_ADCPreTriggerChannel5Flag = PDB_S_CF(1U << 5), /*!< Pre-Trigger 5 flag. */ - kPDB_ADCPreTriggerChannel6Flag = PDB_S_CF(1U << 6), /*!< Pre-Trigger 6 flag. */ - kPDB_ADCPreTriggerChannel7Flag = PDB_S_CF(1U << 7), /*!< Pre-Trigger 7 flag. */ -#endif /* PDB_DLY_COUNT > 4 */ + kPDB_ADCPreTriggerChannel0Flag = PDB_S_CF(1U << 0), /*!< Pre-trigger 0 flag. */ + kPDB_ADCPreTriggerChannel1Flag = PDB_S_CF(1U << 1), /*!< Pre-trigger 1 flag. */ +#if (PDB_DLY_COUNT2 > 2) + kPDB_ADCPreTriggerChannel2Flag = PDB_S_CF(1U << 2), /*!< Pre-trigger 2 flag. */ + kPDB_ADCPreTriggerChannel3Flag = PDB_S_CF(1U << 3), /*!< Pre-trigger 3 flag. */ +#endif /* PDB_DLY_COUNT2 > 2 */ +#if (PDB_DLY_COUNT2 > 4) + kPDB_ADCPreTriggerChannel4Flag = PDB_S_CF(1U << 4), /*!< Pre-trigger 4 flag. */ + kPDB_ADCPreTriggerChannel5Flag = PDB_S_CF(1U << 5), /*!< Pre-trigger 5 flag. */ + kPDB_ADCPreTriggerChannel6Flag = PDB_S_CF(1U << 6), /*!< Pre-trigger 6 flag. */ + kPDB_ADCPreTriggerChannel7Flag = PDB_S_CF(1U << 7), /*!< Pre-trigger 7 flag. */ +#endif /* PDB_DLY_COUNT2 > 4 */ /* PDB PreTrigger channel error flags. */ - kPDB_ADCPreTriggerChannel0ErrorFlag = PDB_S_ERR(1U << 0), /*!< Pre-Trigger 0 Error. */ - kPDB_ADCPreTriggerChannel1ErrorFlag = PDB_S_ERR(1U << 1), /*!< Pre-Trigger 1 Error. */ -#if (PDB_DLY_COUNT > 2) - kPDB_ADCPreTriggerChannel2ErrorFlag = PDB_S_ERR(1U << 2), /*!< Pre-Trigger 2 Error. */ - kPDB_ADCPreTriggerChannel3ErrorFlag = PDB_S_ERR(1U << 3), /*!< Pre-Trigger 3 Error. */ -#endif /* PDB_DLY_COUNT > 2 */ -#if (PDB_DLY_COUNT > 4) - kPDB_ADCPreTriggerChannel4ErrorFlag = PDB_S_ERR(1U << 4), /*!< Pre-Trigger 4 Error. */ - kPDB_ADCPreTriggerChannel5ErrorFlag = PDB_S_ERR(1U << 5), /*!< Pre-Trigger 5 Error. */ - kPDB_ADCPreTriggerChannel6ErrorFlag = PDB_S_ERR(1U << 6), /*!< Pre-Trigger 6 Error. */ - kPDB_ADCPreTriggerChannel7ErrorFlag = PDB_S_ERR(1U << 7), /*!< Pre-Trigger 7 Error. */ -#endif /* PDB_DLY_COUNT > 4 */ + kPDB_ADCPreTriggerChannel0ErrorFlag = PDB_S_ERR(1U << 0), /*!< Pre-trigger 0 Error. */ + kPDB_ADCPreTriggerChannel1ErrorFlag = PDB_S_ERR(1U << 1), /*!< Pre-trigger 1 Error. */ +#if (PDB_DLY_COUNT2 > 2) + kPDB_ADCPreTriggerChannel2ErrorFlag = PDB_S_ERR(1U << 2), /*!< Pre-trigger 2 Error. */ + kPDB_ADCPreTriggerChannel3ErrorFlag = PDB_S_ERR(1U << 3), /*!< Pre-trigger 3 Error. */ +#endif /* PDB_DLY_COUNT2 > 2 */ +#if (PDB_DLY_COUNT2 > 4) + kPDB_ADCPreTriggerChannel4ErrorFlag = PDB_S_ERR(1U << 4), /*!< Pre-trigger 4 Error. */ + kPDB_ADCPreTriggerChannel5ErrorFlag = PDB_S_ERR(1U << 5), /*!< Pre-trigger 5 Error. */ + kPDB_ADCPreTriggerChannel6ErrorFlag = PDB_S_ERR(1U << 6), /*!< Pre-trigger 6 Error. */ + kPDB_ADCPreTriggerChannel7ErrorFlag = PDB_S_ERR(1U << 7), /*!< Pre-trigger 7 Error. */ +#endif /* PDB_DLY_COUNT2 > 4 */ }; /*! @@ -108,7 +107,7 @@ enum _pdb_interrupt_enable * @brief PDB load value mode. * * Selects the mode to load the internal values after doing the load operation (write 1 to PDBx_SC[LDOK]). - * These values are for: + * These values are for the following operations. * - PDB counter (PDBx_MOD, PDBx_IDLY) * - ADC trigger (PDBx_CHnDLYm) * - DAC trigger (PDBx_DACINTx) @@ -158,7 +157,7 @@ typedef enum _pdb_divider_multiplication_factor * @brief Trigger input source * * Selects the trigger input source for the PDB. The trigger input source can be internal or external (EXTRG pin), or - * the software trigger. Refer to chip configuration details for the actual PDB input trigger connections. + * the software trigger. See chip configuration details for the actual PDB input trigger connections. */ typedef enum _pdb_trigger_input_source { @@ -177,7 +176,7 @@ typedef enum _pdb_trigger_input_source kPDB_TriggerInput12 = 12U, /*!< Trigger-In 12. */ kPDB_TriggerInput13 = 13U, /*!< Trigger-In 13. */ kPDB_TriggerInput14 = 14U, /*!< Trigger-In 14. */ - kPDB_TriggerSoftware = 15U, /*!< Trigger-In 15. */ + kPDB_TriggerSoftware = 15U, /*!< Trigger-In 15, software trigger. */ } pdb_trigger_input_source_t; /*! @@ -193,15 +192,15 @@ typedef struct _pdb_config } pdb_config_t; /*! - * @brief PDB ADC Pre-Trigger configuration. + * @brief PDB ADC Pre-trigger configuration. */ typedef struct _pdb_adc_pretrigger_config { - uint32_t enablePreTriggerMask; /*!< PDB Channel Pre-Trigger Enable. */ - uint32_t enableOutputMask; /*!< PDB Channel Pre-Trigger Output Select. + uint32_t enablePreTriggerMask; /*!< PDB Channel Pre-trigger Enable. */ + uint32_t enableOutputMask; /*!< PDB Channel Pre-trigger Output Select. PDB channel's corresponding pre-trigger asserts when the counter reaches the channel delay register. */ - uint32_t enableBackToBackOperationMask; /*!< PDB Channel Pre-Trigger Back-to-Back Operation Enable. + uint32_t enableBackToBackOperationMask; /*!< PDB Channel pre-trigger Back-to-Back Operation Enable. Back-to-back operation enables the ADC conversions complete to trigger the next PDB channel pre-trigger and trigger output, so that the ADC conversions can be triggered on next set of configuration and results @@ -230,29 +229,29 @@ extern "C" { */ /*! - * @brief Initializes the PDB module. + * @brief Initializes the PDB module. * - * This function is to make the initialization for PDB module. The operations includes are: + * This function initializes the PDB module. The operations included are as follows. * - Enable the clock for PDB instance. * - Configure the PDB module. * - Enable the PDB module. * * @param base PDB peripheral base address. - * @param config Pointer to configuration structure. See "pdb_config_t". + * @param config Pointer to the configuration structure. See "pdb_config_t". */ void PDB_Init(PDB_Type *base, const pdb_config_t *config); /*! - * @brief De-initializes the PDB module. + * @brief De-initializes the PDB module. * * @param base PDB peripheral base address. */ void PDB_Deinit(PDB_Type *base); /*! - * @brief Initializes the PDB user configure structure. + * @brief Initializes the PDB user configuration structure. * - * This function initializes the user configure structure to default value. the default value are: + * This function initializes the user configuration structure to a default value. The default values are as follows. * @code * config->loadValueMode = kPDB_LoadValueImmediately; * config->prescalerDivider = kPDB_PrescalerDivider1; @@ -302,7 +301,7 @@ static inline void PDB_DoSoftwareTrigger(PDB_Type *base) /*! * @brief Loads the counter values. * - * This function is to load the counter values from their internal buffer. + * This function loads the counter values from the internal buffer. * See "pdb_load_value_mode_t" about PDB's load mode. * * @param base PDB peripheral base address. @@ -382,7 +381,7 @@ static inline void PDB_ClearStatusFlags(PDB_Type *base, uint32_t mask) } /*! - * @brief Specifies the period of the counter. + * @brief Specifies the counter period. * * @param base PDB peripheral base address. * @param value Setting value for the modulus. 16-bit is available. @@ -405,7 +404,7 @@ static inline uint32_t PDB_GetCounterValue(PDB_Type *base) } /*! - * @brief Sets the value for PDB counter delay event. + * @brief Sets the value for the PDB counter delay event. * * @param base PDB peripheral base address. * @param value Setting value for PDB counter delay event. 16-bit is available. @@ -417,16 +416,16 @@ static inline void PDB_SetCounterDelayValue(PDB_Type *base, uint32_t value) /* @} */ /*! - * @name ADC Pre-Trigger + * @name ADC Pre-trigger * @{ */ /*! - * @brief Configures the ADC PreTrigger in PDB module. + * @brief Configures the ADC pre-trigger in the PDB module. * * @param base PDB peripheral base address. * @param channel Channel index for ADC instance. - * @param config Pointer to configuration structure. See "pdb_adc_pretrigger_config_t". + * @param config Pointer to the configuration structure. See "pdb_adc_pretrigger_config_t". */ static inline void PDB_SetADCPreTriggerConfig(PDB_Type *base, uint32_t channel, pdb_adc_pretrigger_config_t *config) { @@ -434,30 +433,31 @@ static inline void PDB_SetADCPreTriggerConfig(PDB_Type *base, uint32_t channel, assert(NULL != config); base->CH[channel].C1 = PDB_C1_BB(config->enableBackToBackOperationMask) | PDB_C1_TOS(config->enableOutputMask) | - PDB_C1_EN(config->enableOutputMask); + PDB_C1_EN(config->enablePreTriggerMask); } /*! - * @brief Sets the value for ADC Pre-Trigger delay event. + * @brief Sets the value for the ADC pre-trigger delay event. * - * This function is to set the value for ADC Pre-Trigger delay event. IT Specifies the delay value for the channel's - * corresponding pre-trigger. The pre-trigger asserts when the PDB counter is equal to the setting value here. + * This function sets the value for ADC pre-trigger delay event. It specifies the delay value for the channel's + * corresponding pre-trigger. The pre-trigger asserts when the PDB counter is equal to the set value. * * @param base PDB peripheral base address. * @param channel Channel index for ADC instance. * @param preChannel Channel group index for ADC instance. - * @param value Setting value for ADC Pre-Trigger delay event. 16-bit is available. + * @param value Setting value for ADC pre-trigger delay event. 16-bit is available. */ static inline void PDB_SetADCPreTriggerDelayValue(PDB_Type *base, uint32_t channel, uint32_t preChannel, uint32_t value) { assert(channel < PDB_C1_COUNT); - assert(preChannel < PDB_DLY_COUNT); + assert(preChannel < PDB_DLY_COUNT2); + /* xx_COUNT2 is actually the count for pre-triggers in header file. xx_COUNT is used for the count of channels. */ base->CH[channel].DLY[preChannel] = PDB_DLY_DLY(value); } /*! - * @brief Gets the ADC Pre-Trigger's status flags. + * @brief Gets the ADC pre-trigger's status flags. * * @param base PDB peripheral base address. * @param channel Channel index for ADC instance. @@ -472,7 +472,7 @@ static inline uint32_t PDB_GetADCPreTriggerStatusFlags(PDB_Type *base, uint32_t } /*! - * @brief Clears the ADC Pre-Trigger's status flags. + * @brief Clears the ADC pre-trigger status flags. * * @param base PDB peripheral base address. * @param channel Channel index for ADC instance. @@ -494,19 +494,19 @@ static inline void PDB_ClearADCPreTriggerStatusFlags(PDB_Type *base, uint32_t ch */ /*! - * @brief Configures the DAC trigger in PDB module. + * @brief Configures the DAC trigger in the PDB module. * * @param base PDB peripheral base address. * @param channel Channel index for DAC instance. - * @param config Pointer to configuration structure. See "pdb_dac_trigger_config_t". + * @param config Pointer to the configuration structure. See "pdb_dac_trigger_config_t". */ void PDB_SetDACTriggerConfig(PDB_Type *base, uint32_t channel, pdb_dac_trigger_config_t *config); /*! * @brief Sets the value for the DAC interval event. * - * This fucntion is to set the value for DAC interval event. DAC interval trigger would trigger the DAC module to update - * buffer when the DAC interval counter is equal to the setting value here. + * This fucntion sets the value for DAC interval event. DAC interval trigger triggers the DAC module to update + * the buffer when the DAC interval counter is equal to the set value. * * @param base PDB peripheral base address. * @param channel Channel index for DAC instance. @@ -532,7 +532,7 @@ static inline void PDB_SetDACTriggerIntervalValue(PDB_Type *base, uint32_t chann * * @param base PDB peripheral base address. * @param channelMask Channel mask value for multiple pulse out trigger channel. - * @param enable Enable the feature or not. + * @param enable Whether the feature is enabled or not. */ static inline void PDB_EnablePulseOutTrigger(PDB_Type *base, uint32_t channelMask, bool enable) { @@ -547,11 +547,11 @@ static inline void PDB_EnablePulseOutTrigger(PDB_Type *base, uint32_t channelMas } /*! - * @brief Sets event values for pulse out trigger. + * @brief Sets event values for the pulse out trigger. * - * This function is used to set event values for pulse output trigger. - * These pulse output trigger delay values specify the delay for the PDB Pulse-Out. Pulse-Out goes high when the PDB - * counter is equal to the pulse output high value (value1). Pulse-Out goes low when the PDB counter is equal to the + * This function is used to set event values for the pulse output trigger. + * These pulse output trigger delay values specify the delay for the PDB Pulse-out. Pulse-out goes high when the PDB + * counter is equal to the pulse output high value (value1). Pulse-out goes low when the PDB counter is equal to the * pulse output low value (value2). * * @param base PDB peripheral base address. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pit.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pit.c index 1f2fdfe8b4..e5c3c4e013 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pit.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pit.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -48,8 +48,10 @@ static uint32_t PIT_GetInstance(PIT_Type *base); /*! @brief Pointers to PIT bases for each instance. */ static PIT_Type *const s_pitBases[] = PIT_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to PIT clocks for each instance. */ static const clock_ip_name_t s_pitClocks[] = PIT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Code @@ -59,7 +61,7 @@ static uint32_t PIT_GetInstance(PIT_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_PIT_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_pitBases); instance++) { if (s_pitBases[instance] == base) { @@ -67,7 +69,7 @@ static uint32_t PIT_GetInstance(PIT_Type *base) } } - assert(instance < FSL_FEATURE_SOC_PIT_COUNT); + assert(instance < ARRAY_SIZE(s_pitBases)); return instance; } @@ -76,8 +78,10 @@ void PIT_Init(PIT_Type *base, const pit_config_t *config) { assert(config); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Ungate the PIT clock*/ CLOCK_EnableClock(s_pitClocks[PIT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Enable PIT timers */ base->MCR &= ~PIT_MCR_MDIS_MASK; @@ -98,8 +102,10 @@ void PIT_Deinit(PIT_Type *base) /* Disable PIT timers */ base->MCR |= PIT_MCR_MDIS_MASK; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate the PIT clock*/ CLOCK_DisableClock(s_pitClocks[PIT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } #if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pit.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pit.h index 61606e7e8b..99c30e1e4b 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pit.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pit.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -33,11 +33,10 @@ #include "fsl_common.h" /*! - * @addtogroup pit_driver + * @addtogroup pit * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -73,13 +72,13 @@ typedef enum _pit_status_flags } pit_status_flags_t; /*! - * @brief PIT config structure + * @brief PIT configuration structure * * This structure holds the configuration settings for the PIT peripheral. To initialize this * structure to reasonable defaults, call the PIT_GetDefaultConfig() function and pass a * pointer to your config structure instance. * - * The config struct can be made const so it resides in flash + * The configuration structure can be made constant so it resides in flash. */ typedef struct _pit_config { @@ -100,30 +99,30 @@ extern "C" { */ /*! - * @brief Ungates the PIT clock, enables the PIT module and configures the peripheral for basic operation. + * @brief Ungates the PIT clock, enables the PIT module, and configures the peripheral for basic operations. * * @note This API should be called at the beginning of the application using the PIT driver. * * @param base PIT peripheral base address - * @param config Pointer to user's PIT config structure + * @param config Pointer to the user's PIT config structure */ void PIT_Init(PIT_Type *base, const pit_config_t *config); /*! - * @brief Gate the PIT clock and disable the PIT module + * @brief Gates the PIT clock and disables the PIT module. * * @param base PIT peripheral base address */ void PIT_Deinit(PIT_Type *base); /*! - * @brief Fill in the PIT config struct with the default settings + * @brief Fills in the PIT configuration structure with the default settings. * - * The default values are: + * The default values are as follows. * @code * config->enableRunInDebug = false; * @endcode - * @param config Pointer to user's PIT config structure. + * @param config Pointer to the onfiguration structure. */ static inline void PIT_GetDefaultConfig(pit_config_t *config) { @@ -140,9 +139,9 @@ static inline void PIT_GetDefaultConfig(pit_config_t *config) * * When a timer has a chain mode enabled, it only counts after the previous * timer has expired. If the timer n-1 has counted down to 0, counter n - * decrements the value by one. Each timer is 32-bits, this allows the developers + * decrements the value by one. Each timer is 32-bits, which allows the developers * to chain timers together and form a longer timer (64-bits and larger). The first timer - * (timer 0) cannot be chained to any other timer. + * (timer 0) can't be chained to any other timer. * * @param base PIT peripheral base address * @param channel Timer channel number which is chained with the previous timer @@ -219,7 +218,7 @@ static inline uint32_t PIT_GetEnabledInterrupts(PIT_Type *base, pit_chnl_t chann */ /*! - * @brief Gets the PIT status flags + * @brief Gets the PIT status flags. * * @param base PIT peripheral base address * @param channel Timer channel number @@ -256,11 +255,11 @@ static inline void PIT_ClearStatusFlags(PIT_Type *base, pit_chnl_t channel, uint * @brief Sets the timer period in units of count. * * Timers begin counting from the value set by this function until it reaches 0, - * then it will generate an interrupt and load this regiter value again. - * Writing a new value to this register will not restart the timer; instead the value - * will be loaded after the timer expires. + * then it generates an interrupt and load this register value again. + * Writing a new value to this register does not restart the timer. Instead, the value + * is loaded after the timer expires. * - * @note User can call the utility macros provided in fsl_common.h to convert to ticks + * @note Users can call the utility macros provided in fsl_common.h to convert to ticks. * * @param base PIT peripheral base address * @param channel Timer channel number @@ -277,7 +276,7 @@ static inline void PIT_SetTimerPeriod(PIT_Type *base, pit_chnl_t channel, uint32 * This function returns the real-time timer counting value, in a range from 0 to a * timer period. * - * @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec + * @note Users can call the utility macros provided in fsl_common.h to convert ticks to usec or msec. * * @param base PIT peripheral base address * @param channel Timer channel number diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pmc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pmc.c index 82d7b7ace1..bcdd5cb823 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pmc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pmc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pmc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pmc.h index c60c19c01e..99fc149fc2 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pmc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_pmc.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -35,7 +35,6 @@ /*! @addtogroup pmc */ /*! @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -49,36 +48,36 @@ #if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV) /*! - * @brief Low-Voltage Detect Voltage Select + * @brief Low-voltage Detect Voltage Select */ typedef enum _pmc_low_volt_detect_volt_select { - kPMC_LowVoltDetectLowTrip = 0U, /*!< Low trip point selected (VLVD = VLVDL )*/ - kPMC_LowVoltDetectHighTrip = 1U /*!< High trip point selected (VLVD = VLVDH )*/ + kPMC_LowVoltDetectLowTrip = 0U, /*!< Low-trip point selected (VLVD = VLVDL )*/ + kPMC_LowVoltDetectHighTrip = 1U /*!< High-trip point selected (VLVD = VLVDH )*/ } pmc_low_volt_detect_volt_select_t; #endif #if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) /*! - * @brief Low-Voltage Warning Voltage Select + * @brief Low-voltage Warning Voltage Select */ typedef enum _pmc_low_volt_warning_volt_select { - kPMC_LowVoltWarningLowTrip = 0U, /*!< Low trip point selected (VLVW = VLVW1)*/ + kPMC_LowVoltWarningLowTrip = 0U, /*!< Low-trip point selected (VLVW = VLVW1)*/ kPMC_LowVoltWarningMid1Trip = 1U, /*!< Mid 1 trip point selected (VLVW = VLVW2)*/ kPMC_LowVoltWarningMid2Trip = 2U, /*!< Mid 2 trip point selected (VLVW = VLVW3)*/ - kPMC_LowVoltWarningHighTrip = 3U /*!< High trip point selected (VLVW = VLVW4)*/ + kPMC_LowVoltWarningHighTrip = 3U /*!< High-trip point selected (VLVW = VLVW4)*/ } pmc_low_volt_warning_volt_select_t; #endif #if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) /*! - * @brief High-Voltage Detect Voltage Select + * @brief High-voltage Detect Voltage Select */ typedef enum _pmc_high_volt_detect_volt_select { - kPMC_HighVoltDetectLowTrip = 0U, /*!< Low trip point selected (VHVD = VHVDL )*/ - kPMC_HighVoltDetectHighTrip = 1U /*!< High trip point selected (VHVD = VHVDH )*/ + kPMC_HighVoltDetectLowTrip = 0U, /*!< Low-trip point selected (VHVD = VHVDL )*/ + kPMC_HighVoltDetectHighTrip = 1U /*!< High-trip point selected (VHVD = VHVDH )*/ } pmc_high_volt_detect_volt_select_t; #endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ @@ -88,8 +87,8 @@ typedef enum _pmc_high_volt_detect_volt_select */ typedef enum _pmc_bandgap_buffer_drive_select { - kPMC_BandgapBufferDriveLow = 0U, /*!< Low drive. */ - kPMC_BandgapBufferDriveHigh = 1U /*!< High drive. */ + kPMC_BandgapBufferDriveLow = 0U, /*!< Low-drive. */ + kPMC_BandgapBufferDriveHigh = 1U /*!< High-drive. */ } pmc_bandgap_buffer_drive_select_t; #endif /* FSL_FEATURE_PMC_HAS_BGBDS */ @@ -126,37 +125,37 @@ typedef struct _pmc_param #endif /* FSL_FEATURE_PMC_HAS_PARAM */ /*! - * @brief Low-Voltage Detect Configuration Structure + * @brief Low-voltage Detect Configuration Structure */ typedef struct _pmc_low_volt_detect_config { - bool enableInt; /*!< Enable interrupt when low voltage detect*/ - bool enableReset; /*!< Enable system reset when low voltage detect*/ + bool enableInt; /*!< Enable interrupt when Low-voltage detect*/ + bool enableReset; /*!< Enable system reset when Low-voltage detect*/ #if (defined(FSL_FEATURE_PMC_HAS_LVDV) && FSL_FEATURE_PMC_HAS_LVDV) - pmc_low_volt_detect_volt_select_t voltSelect; /*!< Low voltage detect trip point voltage selection*/ + pmc_low_volt_detect_volt_select_t voltSelect; /*!< Low-voltage detect trip point voltage selection*/ #endif } pmc_low_volt_detect_config_t; /*! - * @brief Low-Voltage Warning Configuration Structure + * @brief Low-voltage Warning Configuration Structure */ typedef struct _pmc_low_volt_warning_config { - bool enableInt; /*!< Enable interrupt when low voltage warning*/ + bool enableInt; /*!< Enable interrupt when low-voltage warning*/ #if (defined(FSL_FEATURE_PMC_HAS_LVWV) && FSL_FEATURE_PMC_HAS_LVWV) - pmc_low_volt_warning_volt_select_t voltSelect; /*!< Low voltage warning trip point voltage selection*/ + pmc_low_volt_warning_volt_select_t voltSelect; /*!< Low-voltage warning trip point voltage selection*/ #endif } pmc_low_volt_warning_config_t; #if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) /*! - * @brief High-Voltage Detect Configuration Structure + * @brief High-voltage Detect Configuration Structure */ typedef struct _pmc_high_volt_detect_config { - bool enableInt; /*!< Enable interrupt when high voltage detect*/ - bool enableReset; /*!< Enable system reset when high voltage detect*/ - pmc_high_volt_detect_volt_select_t voltSelect; /*!< High voltage detect trip point voltage selection*/ + bool enableInt; /*!< Enable interrupt when high-voltage detect*/ + bool enableReset; /*!< Enable system reset when high-voltage detect*/ + pmc_high_volt_detect_volt_select_t voltSelect; /*!< High-voltage detect trip point voltage selection*/ } pmc_high_volt_detect_config_t; #endif /* FSL_FEATURE_PMC_HAS_HVDSC1 */ @@ -172,7 +171,7 @@ typedef struct _pmc_bandgap_buffer_config bool enable; /*!< Enable bandgap buffer. */ #endif #if (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) - bool enableInLowPowerMode; /*!< Enable bandgap buffer in low power mode. */ + bool enableInLowPowerMode; /*!< Enable bandgap buffer in low-power mode. */ #endif /* FSL_FEATURE_PMC_HAS_BGEN */ #if (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS) pmc_bandgap_buffer_drive_select_t drive; /*!< Bandgap buffer drive select. */ @@ -196,7 +195,7 @@ extern "C" { * @brief Gets the PMC version ID. * * This function gets the PMC version ID, including major version number, - * minor version number and feature specification number. + * minor version number, and a feature specification number. * * @param base PMC peripheral base address. * @param versionId Pointer to version ID structure. @@ -211,7 +210,7 @@ static inline void PMC_GetVersionId(PMC_Type *base, pmc_version_id_t *versionId) /*! * @brief Gets the PMC parameter. * - * This function gets the PMC parameter, including VLPO enable and HVD enable. + * This function gets the PMC parameter including the VLPO enable and the HVD enable. * * @param base PMC peripheral base address. * @param param Pointer to PMC param structure. @@ -220,26 +219,25 @@ void PMC_GetParam(PMC_Type *base, pmc_param_t *param); #endif /*! - * @brief Configure the low voltage detect setting. + * @brief Configures the low-voltage detect setting. * - * This function configures the low voltage detect setting, including the trip - * point voltage setting, enable interrupt or not, enable system reset or not. + * This function configures the low-voltage detect setting, including the trip + * point voltage setting, enables or disables the interrupt, enables or disables the system reset. * * @param base PMC peripheral base address. - * @param config Low-Voltage detect configuration structure. + * @param config Low-voltage detect configuration structure. */ void PMC_ConfigureLowVoltDetect(PMC_Type *base, const pmc_low_volt_detect_config_t *config); /*! - * @brief Get Low-Voltage Detect Flag status + * @brief Gets the Low-voltage Detect Flag status. * - * This function reads the current LVDF status. If it returns 1, a low - * voltage event is detected. + * This function reads the current LVDF status. If it returns 1, a low-voltage event is detected. * * @param base PMC peripheral base address. - * @return Current low voltage detect flag - * - true: Low-Voltage detected - * - false: Low-Voltage not detected + * @return Current low-voltage detect flag + * - true: Low-voltage detected + * - false: Low-voltage not detected */ static inline bool PMC_GetLowVoltDetectFlag(PMC_Type *base) { @@ -247,9 +245,9 @@ static inline bool PMC_GetLowVoltDetectFlag(PMC_Type *base) } /*! - * @brief Acknowledge to clear the Low-Voltage Detect flag + * @brief Acknowledges clearing the Low-voltage Detect flag. * - * This function acknowledges the low voltage detection errors (write 1 to + * This function acknowledges the low-voltage detection errors (write 1 to * clear LVDF). * * @param base PMC peripheral base address. @@ -260,18 +258,18 @@ static inline void PMC_ClearLowVoltDetectFlag(PMC_Type *base) } /*! - * @brief Configure the low voltage warning setting. + * @brief Configures the low-voltage warning setting. * - * This function configures the low voltage warning setting, including the trip - * point voltage setting and enable interrupt or not. + * This function configures the low-voltage warning setting, including the trip + * point voltage setting and enabling or disabling the interrupt. * * @param base PMC peripheral base address. - * @param config Low-Voltage warning configuration structure. + * @param config Low-voltage warning configuration structure. */ void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_config_t *config); /*! - * @brief Get Low-Voltage Warning Flag status + * @brief Gets the Low-voltage Warning Flag status. * * This function polls the current LVWF status. When 1 is returned, it * indicates a low-voltage warning event. LVWF is set when V Supply transitions @@ -279,8 +277,8 @@ void PMC_ConfigureLowVoltWarning(PMC_Type *base, const pmc_low_volt_warning_conf * * @param base PMC peripheral base address. * @return Current LVWF status - * - true: Low-Voltage Warning Flag is set. - * - false: the Low-Voltage Warning does not happen. + * - true: Low-voltage Warning Flag is set. + * - false: the Low-voltage Warning does not happen. */ static inline bool PMC_GetLowVoltWarningFlag(PMC_Type *base) { @@ -288,7 +286,7 @@ static inline bool PMC_GetLowVoltWarningFlag(PMC_Type *base) } /*! - * @brief Acknowledge to Low-Voltage Warning flag + * @brief Acknowledges the Low-voltage Warning flag. * * This function acknowledges the low voltage warning errors (write 1 to * clear LVWF). @@ -302,26 +300,26 @@ static inline void PMC_ClearLowVoltWarningFlag(PMC_Type *base) #if (defined(FSL_FEATURE_PMC_HAS_HVDSC1) && FSL_FEATURE_PMC_HAS_HVDSC1) /*! - * @brief Configure the high voltage detect setting. + * @brief Configures the high-voltage detect setting. * - * This function configures the high voltage detect setting, including the trip - * point voltage setting, enable interrupt or not, enable system reset or not. + * This function configures the high-voltage detect setting, including the trip + * point voltage setting, enabling or disabling the interrupt, enabling or disabling the system reset. * * @param base PMC peripheral base address. - * @param config High-Voltage detect configuration structure. + * @param config High-voltage detect configuration structure. */ void PMC_ConfigureHighVoltDetect(PMC_Type *base, const pmc_high_volt_detect_config_t *config); /*! - * @brief Get High-Voltage Detect Flag status + * @brief Gets the High-voltage Detect Flag status. * * This function reads the current HVDF status. If it returns 1, a low * voltage event is detected. * * @param base PMC peripheral base address. - * @return Current high voltage detect flag - * - true: High-Voltage detected - * - false: High-Voltage not detected + * @return Current high-voltage detect flag + * - true: High-voltage detected + * - false: High-voltage not detected */ static inline bool PMC_GetHighVoltDetectFlag(PMC_Type *base) { @@ -329,9 +327,9 @@ static inline bool PMC_GetHighVoltDetectFlag(PMC_Type *base) } /*! - * @brief Acknowledge to clear the High-Voltage Detect flag + * @brief Acknowledges clearing the High-voltage Detect flag. * - * This function acknowledges the high voltage detection errors (write 1 to + * This function acknowledges the high-voltage detection errors (write 1 to * clear HVDF). * * @param base PMC peripheral base address. @@ -346,10 +344,10 @@ static inline void PMC_ClearHighVoltDetectFlag(PMC_Type *base) (defined(FSL_FEATURE_PMC_HAS_BGEN) && FSL_FEATURE_PMC_HAS_BGEN) || \ (defined(FSL_FEATURE_PMC_HAS_BGBDS) && FSL_FEATURE_PMC_HAS_BGBDS)) /*! - * @brief Configure the PMC bandgap + * @brief Configures the PMC bandgap. * * This function configures the PMC bandgap, including the drive select and - * behavior in low power mode. + * behavior in low-power mode. * * @param base PMC peripheral base address. * @param config Pointer to the configuration structure @@ -378,7 +376,7 @@ static inline bool PMC_GetPeriphIOIsolationFlag(PMC_Type *base) } /*! - * @brief Acknowledge to Peripherals and I/O pads isolation flag. + * @brief Acknowledges the isolation flag to Peripherals and I/O pads. * * This function clears the ACK Isolation flag. Writing one to this setting * when it is set releases the I/O pads and certain peripherals to their normal @@ -394,9 +392,9 @@ static inline void PMC_ClearPeriphIOIsolationFlag(PMC_Type *base) #if (defined(FSL_FEATURE_PMC_HAS_REGONS) && FSL_FEATURE_PMC_HAS_REGONS) /*! - * @brief Gets the Regulator regulation status. + * @brief Gets the regulator regulation status. * - * This function returns the regulator to a run regulation status. It provides + * This function returns the regulator to run a regulation status. It provides * the current status of the internal voltage regulator. * * @param base PMC peripheral base address. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_port.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_port.h index 790518ccd3..eb8e77e6dd 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_port.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_port.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,14 +12,14 @@ * 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 + * 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 SDRVL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * 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 @@ -33,59 +33,65 @@ #include "fsl_common.h" /*! - * @addtogroup port_driver + * @addtogroup port * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! Version 2.0.1. */ -#define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*! Version 2.0.2. */ +#define FSL_PORT_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*@}*/ +#if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE /*! @brief Internal resistor pull feature selection */ enum _port_pull { - kPORT_PullDisable = 0U, /*!< internal pull-up/down resistor is disabled. */ - kPORT_PullDown = 2U, /*!< internal pull-down resistor is enabled. */ - kPORT_PullUp = 3U, /*!< internal pull-up resistor is enabled. */ + kPORT_PullDisable = 0U, /*!< Internal pull-up/down resistor is disabled. */ + kPORT_PullDown = 2U, /*!< Internal pull-down resistor is enabled. */ + kPORT_PullUp = 3U, /*!< Internal pull-up resistor is enabled. */ }; +#endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */ +#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE /*! @brief Slew rate selection */ enum _port_slew_rate { - kPORT_FastSlewRate = 0U, /*!< fast slew rate is configured. */ - kPORT_SlowSlewRate = 1U, /*!< slow slew rate is configured. */ + kPORT_FastSlewRate = 0U, /*!< Fast slew rate is configured. */ + kPORT_SlowSlewRate = 1U, /*!< Slow slew rate is configured. */ }; +#endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */ #if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN -/*! @brief Internal resistor pull feature enable/disable */ +/*! @brief Open Drain feature enable/disable */ enum _port_open_drain_enable { - kPORT_OpenDrainDisable = 0U, /*!< internal pull-down resistor is disabled. */ - kPORT_OpenDrainEnable = 1U, /*!< internal pull-up resistor is enabled. */ + kPORT_OpenDrainDisable = 0U, /*!< Open drain output is disabled. */ + kPORT_OpenDrainEnable = 1U, /*!< Open drain output is enabled. */ }; #endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ +#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER /*! @brief Passive filter feature enable/disable */ enum _port_passive_filter_enable { - kPORT_PassiveFilterDisable = 0U, /*!< fast slew rate is configured. */ - kPORT_PassiveFilterEnable = 1U, /*!< slow slew rate is configured. */ + kPORT_PassiveFilterDisable = 0U, /*!< Passive input filter is disabled. */ + kPORT_PassiveFilterEnable = 1U, /*!< Passive input filter is enabled. */ }; +#endif +#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH /*! @brief Configures the drive strength. */ enum _port_drive_strength { - kPORT_LowDriveStrength = 0U, /*!< low drive strength is configured. */ - kPORT_HighDriveStrength = 1U, /*!< high drive strength is configured. */ + kPORT_LowDriveStrength = 0U, /*!< Low-drive strength is configured. */ + kPORT_HighDriveStrength = 1U, /*!< High-drive strength is configured. */ }; +#endif /* FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH */ #if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK /*! @brief Unlock/lock the pin control register field[15:0] */ @@ -96,18 +102,28 @@ enum _port_lock_register }; #endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ +#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH /*! @brief Pin mux selection */ typedef enum _port_mux { - kPORT_PinDisabledOrAnalog = 0U, /*!< corresponding pin is disabled, but is used as an analog pin. */ - kPORT_MuxAsGpio = 1U, /*!< corresponding pin is configured as GPIO. */ - kPORT_MuxAlt2 = 2U, /*!< chip-specific */ - kPORT_MuxAlt3 = 3U, /*!< chip-specific */ - kPORT_MuxAlt4 = 4U, /*!< chip-specific */ - kPORT_MuxAlt5 = 5U, /*!< chip-specific */ - kPORT_MuxAlt6 = 6U, /*!< chip-specific */ - kPORT_MuxAlt7 = 7U, /*!< chip-specific */ + kPORT_PinDisabledOrAnalog = 0U, /*!< Corresponding pin is disabled, but is used as an analog pin. */ + kPORT_MuxAsGpio = 1U, /*!< Corresponding pin is configured as GPIO. */ + kPORT_MuxAlt2 = 2U, /*!< Chip-specific */ + kPORT_MuxAlt3 = 3U, /*!< Chip-specific */ + kPORT_MuxAlt4 = 4U, /*!< Chip-specific */ + kPORT_MuxAlt5 = 5U, /*!< Chip-specific */ + kPORT_MuxAlt6 = 6U, /*!< Chip-specific */ + kPORT_MuxAlt7 = 7U, /*!< Chip-specific */ + kPORT_MuxAlt8 = 8U, /*!< Chip-specific */ + kPORT_MuxAlt9 = 9U, /*!< Chip-specific */ + kPORT_MuxAlt10 = 10U, /*!< Chip-specific */ + kPORT_MuxAlt11 = 11U, /*!< Chip-specific */ + kPORT_MuxAlt12 = 12U, /*!< Chip-specific */ + kPORT_MuxAlt13 = 13U, /*!< Chip-specific */ + kPORT_MuxAlt14 = 14U, /*!< Chip-specific */ + kPORT_MuxAlt15 = 15U, /*!< Chip-specific */ } port_mux_t; +#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */ /*! @brief Configures the interrupt generation condition. */ typedef enum _port_interrupt @@ -129,8 +145,8 @@ typedef enum _port_interrupt kPORT_InterruptEitherEdge = 0xBU, /*!< Interrupt on either edge. */ kPORT_InterruptLogicOne = 0xCU, /*!< Interrupt when logic one. */ #if defined(FSL_FEATURE_PORT_HAS_IRQC_TRIGGER) && FSL_FEATURE_PORT_HAS_IRQC_TRIGGER - kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high trigger output. */ - kPORT_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low trigger output. */ + kPORT_ActiveHighTriggerOutputEnable = 0xDU, /*!< Enable active high-trigger output. */ + kPORT_ActiveLowTriggerOutputEnable = 0xEU, /*!< Enable active low-trigger output. */ #endif } port_interrupt_t; @@ -150,44 +166,76 @@ typedef struct _port_digital_filter_config } port_digital_filter_config_t; #endif /* FSL_FEATURE_PORT_HAS_DIGITAL_FILTER */ -/*! @brief PORT pin config structure */ +#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH +/*! @brief PORT pin configuration structure */ typedef struct _port_pin_config { - uint16_t pullSelect : 2; /*!< no-pull/pull-down/pull-up select */ - uint16_t slewRate : 1; /*!< fast/slow slew rate Configure */ - uint16_t : 1; - uint16_t passiveFilterEnable : 1; /*!< passive filter enable/disable */ -#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN - uint16_t openDrainEnable : 1; /*!< open drain enable/disable */ +#if defined(FSL_FEATURE_PORT_HAS_PULL_ENABLE) && FSL_FEATURE_PORT_HAS_PULL_ENABLE + uint16_t pullSelect : 2; /*!< No-pull/pull-down/pull-up select */ +#else + uint16_t : 2; +#endif /* FSL_FEATURE_PORT_HAS_PULL_ENABLE */ + +#if defined(FSL_FEATURE_PORT_HAS_SLEW_RATE) && FSL_FEATURE_PORT_HAS_SLEW_RATE + uint16_t slewRate : 1; /*!< Fast/slow slew rate Configure */ #else uint16_t : 1; -#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ - uint16_t driveStrength : 1; /*!< fast/slow drive strength configure */ +#endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */ + uint16_t : 1; - uint16_t mux : 3; /*!< pin mux Configure */ + +#if defined(FSL_FEATURE_PORT_HAS_PASSIVE_FILTER) && FSL_FEATURE_PORT_HAS_PASSIVE_FILTER + uint16_t passiveFilterEnable : 1; /*!< Passive filter enable/disable */ +#else + uint16_t : 1; +#endif /* FSL_FEATURE_PORT_HAS_PASSIVE_FILTER */ + +#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN + uint16_t openDrainEnable : 1; /*!< Open drain enable/disable */ +#else + uint16_t : 1; +#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */ + +#if defined(FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH) && FSL_FEATURE_PORT_HAS_DRIVE_STRENGTH + uint16_t driveStrength : 1; /*!< Fast/slow drive strength configure */ +#else + uint16_t : 1; +#endif + + uint16_t : 1; + +#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH + uint16_t mux : 3; /*!< Pin mux Configure */ +#else + uint16_t : 3; +#endif + uint16_t : 4; + #if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK - uint16_t lockRegister : 1; /*!< lock/unlock the pcr field[15:0] */ + uint16_t lockRegister : 1; /*!< Lock/unlock the PCR field[15:0] */ #else uint16_t : 1; #endif /* FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK */ } port_pin_config_t; +#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */ /******************************************************************************* - * API - ******************************************************************************/ +* API +******************************************************************************/ #if defined(__cplusplus) extern "C" { #endif +#if defined(FSL_FEATURE_PORT_PCR_MUX_WIDTH) && FSL_FEATURE_PORT_PCR_MUX_WIDTH /*! @name Configuration */ /*@{*/ /*! * @brief Sets the port PCR register. * - * This is an example to define an input pin or output pin PCR configuration: + * This is an example to define an input pin or output pin PCR configuration. * @code * // Define a digital input pin PCR configuration * port_pin_config_t config = { @@ -203,7 +251,7 @@ extern "C" { * * @param base PORT peripheral base pointer. * @param pin PORT pin number. - * @param config PORT PCR register configure structure. + * @param config PORT PCR register configuration structure. */ static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_pin_config_t *config) { @@ -215,7 +263,7 @@ static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_p /*! * @brief Sets the port PCR register for multiple pins. * - * This is an example to define input pins or output pins PCR configuration: + * This is an example to define input pins or output pins PCR configuration. * @code * // Define a digital input pin PCR configuration * port_pin_config_t config = { @@ -231,8 +279,8 @@ static inline void PORT_SetPinConfig(PORT_Type *base, uint32_t pin, const port_p * @endcode * * @param base PORT peripheral base pointer. - * @param mask PORT pins' numbers macro. - * @param config PORT PCR register configure structure. + * @param mask PORT pin number macro. + * @param config PORT PCR register configuration structure. */ static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, const port_pin_config_t *config) { @@ -265,15 +313,16 @@ static inline void PORT_SetMultiplePinsConfig(PORT_Type *base, uint32_t mask, co * - #kPORT_MuxAlt6 : chip-specific. * - #kPORT_MuxAlt7 : chip-specific. * @Note : This function is NOT recommended to use together with the PORT_SetPinsConfig, because - * the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux will - * be reset to zero : kPORT_PinDisabledOrAnalog). - * This function is recommended to use in the case you just need to reset the pin mux + * the PORT_SetPinsConfig need to configure the pin mux anyway (Otherwise the pin mux is + * reset to zero : kPORT_PinDisabledOrAnalog). + * This function is recommended to use to reset the pin mux * */ static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux) { base->PCR[pin] = (base->PCR[pin] & ~PORT_PCR_MUX_MASK) | PORT_PCR_MUX(mux); } +#endif /* FSL_FEATURE_PORT_PCR_MUX_WIDTH */ #if defined(FSL_FEATURE_PORT_HAS_DIGITAL_FILTER) && FSL_FEATURE_PORT_HAS_DIGITAL_FILTER @@ -281,7 +330,7 @@ static inline void PORT_SetPinMux(PORT_Type *base, uint32_t pin, port_mux_t mux) * @brief Enables the digital filter in one port, each bit of the 32-bit register represents one pin. * * @param base PORT peripheral base pointer. - * @param mask PORT pins' numbers macro. + * @param mask PORT pin number macro. */ static inline void PORT_EnablePinsDigitalFilter(PORT_Type *base, uint32_t mask, bool enable) { @@ -334,8 +383,8 @@ static inline void PORT_SetDigitalFilterConfig(PORT_Type *base, const port_digit * - #kPORT_InterruptFallingEdge: Interrupt on falling edge. * - #kPORT_InterruptEitherEdge : Interrupt on either edge. * - #kPORT_InterruptLogicOne : Interrupt when logic one. - * - #kPORT_ActiveHighTriggerOutputEnable : Enable active high trigger output(if the trigger states exit). - * - #kPORT_ActiveLowTriggerOutputEnable : Enable active low trigger output(if the trigger states exit). + * - #kPORT_ActiveHighTriggerOutputEnable : Enable active high-trigger output (if the trigger states exit). + * - #kPORT_ActiveLowTriggerOutputEnable : Enable active low-trigger output (if the trigger states exit). */ static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, port_interrupt_t config) { @@ -351,9 +400,9 @@ static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, por * If configured for a level sensitive interrupt that remains asserted, the flag * is set again immediately. * - * @param base PORT peripheral base pointer. + * @param base PORT peripheral base pointer. * @return Current port interrupt status flags, for example, 0x00010001 means the - * pin 0 and 17 have the interrupt. + * pin 0 and 16 have the interrupt. */ static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base) { @@ -361,10 +410,10 @@ static inline uint32_t PORT_GetPinsInterruptFlags(PORT_Type *base) } /*! - * @brief Clears the multiple pins' interrupt status flag. + * @brief Clears the multiple pin interrupt status flag. * * @param base PORT peripheral base pointer. - * @param mask PORT pins' numbers macro. + * @param mask PORT pin number macro. */ static inline void PORT_ClearPinsInterruptFlags(PORT_Type *base, uint32_t mask) { diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rcm.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rcm.c index 538f6872a3..0d738643b5 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rcm.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rcm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -32,6 +32,8 @@ void RCM_ConfigureResetPinFilter(RCM_Type *base, const rcm_reset_pin_filter_config_t *config) { + assert(config); + #if (defined(FSL_FEATURE_RCM_REG_WIDTH) && (FSL_FEATURE_RCM_REG_WIDTH == 32)) uint32_t reg; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rcm.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rcm.h index 81e25559ea..99b843aaf3 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rcm.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rcm.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -35,7 +35,6 @@ /*! @addtogroup rcm */ /*! @{*/ -/*! @file */ /******************************************************************************* * Definitions @@ -43,8 +42,8 @@ /*! @name Driver version */ /*@{*/ -/*! @brief RCM driver version 2.0.0. */ -#define FSL_RCM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*! @brief RCM driver version 2.0.1. */ +#define FSL_RCM_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*@}*/ /*! @@ -57,7 +56,7 @@ typedef enum _rcm_reset_source #if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) kRCM_SourceWakeup = RCM_SRS_WAKEUP_MASK, /*!< Low-leakage wakeup reset */ #endif - kRCM_SourceLvd = RCM_SRS_LVD_MASK, /*!< low voltage detect reset */ + kRCM_SourceLvd = RCM_SRS_LVD_MASK, /*!< Low-voltage detect reset */ #if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) kRCM_SourceLoc = RCM_SRS_LOC_MASK, /*!< Loss of clock reset */ #endif /* FSL_FEATURE_RCM_HAS_LOC */ @@ -85,7 +84,7 @@ typedef enum _rcm_reset_source #if (defined(FSL_FEATURE_RCM_HAS_WAKEUP) && FSL_FEATURE_RCM_HAS_WAKEUP) kRCM_SourceWakeup = RCM_SRS0_WAKEUP_MASK, /*!< Low-leakage wakeup reset */ #endif - kRCM_SourceLvd = RCM_SRS0_LVD_MASK, /*!< low voltage detect reset */ + kRCM_SourceLvd = RCM_SRS0_LVD_MASK, /*!< Low-voltage detect reset */ #if (defined(FSL_FEATURE_RCM_HAS_LOC) && FSL_FEATURE_RCM_HAS_LOC) kRCM_SourceLoc = RCM_SRS0_LOC_MASK, /*!< Loss of clock reset */ #endif /* FSL_FEATURE_RCM_HAS_LOC */ @@ -99,7 +98,7 @@ typedef enum _rcm_reset_source kRCM_SourceJtag = RCM_SRS1_JTAG_MASK << 8U, /*!< JTAG generated reset */ #endif /* FSL_FEATURE_RCM_HAS_JTAG */ kRCM_SourceLockup = RCM_SRS1_LOCKUP_MASK << 8U, /*!< Core lock up reset */ - kRCM_SourceSw = RCM_SRS1_SW_MASK, /*!< Software reset */ + kRCM_SourceSw = RCM_SRS1_SW_MASK << 8U, /*!< Software reset */ #if (defined(FSL_FEATURE_RCM_HAS_MDM_AP) && FSL_FEATURE_RCM_HAS_MDM_AP) kRCM_SourceMdmap = RCM_SRS1_MDM_AP_MASK << 8U, /*!< MDM-AP system reset */ #endif /* FSL_FEATURE_RCM_HAS_MDM_AP */ @@ -112,7 +111,7 @@ typedef enum _rcm_reset_source } rcm_reset_source_t; /*! - * @brief Reset pin filter select in Run and Wait modes + * @brief Reset pin filter select in Run and Wait modes. */ typedef enum _rcm_run_wait_filter_mode { @@ -136,7 +135,7 @@ typedef enum _rcm_boot_rom_config #if (defined(FSL_FEATURE_RCM_HAS_SRIE) && FSL_FEATURE_RCM_HAS_SRIE) /*! - * @brief Max delay time from interrupt asserts to system reset. + * @brief Maximum delay time from interrupt asserts to system reset. */ typedef enum _rcm_reset_delay { @@ -187,7 +186,7 @@ typedef struct _rcm_version_id #endif /*! - * @brief Reset pin filter configuration + * @brief Reset pin filter configuration. */ typedef struct _rcm_reset_pin_filter_config { @@ -214,7 +213,7 @@ extern "C" { * the minor version number, and the feature specification number. * * @param base RCM peripheral base address. - * @param versionId Pointer to version ID structure. + * @param versionId Pointer to the version ID structure. */ static inline void RCM_GetVersionId(RCM_Type *base, rcm_version_id_t *versionId) { @@ -229,7 +228,7 @@ static inline void RCM_GetVersionId(RCM_Type *base, rcm_version_id_t *versionId) * This function gets the RCM parameter that indicates whether the corresponding reset source is implemented. * Use source masks defined in the rcm_reset_source_t to get the desired source status. * - * Example: + * This is an example. @code uint32_t status; @@ -252,7 +251,7 @@ static inline uint32_t RCM_GetResetSourceImplementedStatus(RCM_Type *base) * This function gets the current reset source status. Use source masks * defined in the rcm_reset_source_t to get the desired source status. * - * Example: + * This is an example. @code uint32_t resetStatus; @@ -283,9 +282,9 @@ static inline uint32_t RCM_GetPreviousResetSources(RCM_Type *base) * @brief Gets the sticky reset source status. * * This function gets the current reset source status that has not been cleared - * by software for some specific source. + * by software for a specific source. * - * Example: + * This is an example. @code uint32_t resetStatus; @@ -316,7 +315,7 @@ static inline uint32_t RCM_GetStickyResetSources(RCM_Type *base) * * This function clears the sticky system reset flags indicated by source masks. * - * Example: + * This is an example. @code // Clears multiple reset sources. RCM_ClearStickyResetSources(kRCM_SourceWdog | kRCM_SourcePin); @@ -403,7 +402,7 @@ void RCM_SetForceBootRomSource(RCM_Type *base, rcm_boot_rom_config_t config); /*! * @brief Sets the system reset interrupt configuration. * - * For graceful shutdown, the RCM supports delaying the assertion of the system + * For a graceful shut down, the RCM supports delaying the assertion of the system * reset for a period of time when the reset interrupt is generated. This function * can be used to enable the interrupt and the delay period. The interrupts * are passed in as bit mask. See rcm_int_t for details. For example, to diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rnga.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rnga.c index 9be27499ef..6f0adc66f5 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rnga.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rnga.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -181,10 +181,14 @@ static uint32_t rnga_ReadEntropy(RNG_Type *base); void RNGA_Init(RNG_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the clock gate. */ CLOCK_EnableClock(kCLOCK_Rnga0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ CLOCK_DisableClock(kCLOCK_Rnga0); /* To solve the release version on twrkm43z75m */ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_EnableClock(kCLOCK_Rnga0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Reset the registers for RNGA module to reset state. */ RNG_WR_CR(base, 0); @@ -194,8 +198,10 @@ void RNGA_Init(RNG_Type *base) void RNGA_Deinit(RNG_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable the clock for RNGA module.*/ CLOCK_DisableClock(kCLOCK_Rnga0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } /*! diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rnga.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rnga.h index 04950a4540..92f5bff8be 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rnga.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rnga.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -34,11 +34,10 @@ #if defined(FSL_FEATURE_SOC_RNG_COUNT) && FSL_FEATURE_SOC_RNG_COUNT /*! - * @addtogroup rnga_driver + * @addtogroup rnga * @{ */ -/*! @file */ /******************************************************************************* * Definitions diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rtc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rtc.c index 898a544a46..d68055a269 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rtc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rtc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -74,6 +74,8 @@ static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datet ******************************************************************************/ static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime) { + assert(datetime); + /* Table of days in a month for a non leap year. First entry in the table is not used, * valid months start from 1 */ @@ -88,13 +90,13 @@ static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime) } /* Adjust the days in February for a leap year */ - if (!(datetime->year & 3U)) + if ((((datetime->year & 3U) == 0) && (datetime->year % 100 != 0)) || (datetime->year % 400 == 0)) { daysPerMonth[2] = 29U; } /* Check the validity of the day */ - if (datetime->day > daysPerMonth[datetime->month]) + if ((datetime->day > daysPerMonth[datetime->month]) || (datetime->day < 1U)) { return false; } @@ -104,6 +106,9 @@ static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime) static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime) { + assert(datetime); + + /* Number of days from begin of the non Leap-year*/ /* Number of days from begin of the non Leap-year*/ uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U}; uint32_t seconds; @@ -131,6 +136,8 @@ static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime) static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime) { + assert(datetime); + uint32_t x; uint32_t secondsRemaining, days; uint16_t daysInYear; @@ -204,7 +211,9 @@ void RTC_Init(RTC_Type *base, const rtc_config_t *config) uint32_t reg; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_EnableClock(kCLOCK_Rtc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Issue a software reset if timer is invalid */ if (RTC_GetStatusFlags(RTC) & kRTC_TimeInvalidFlag) @@ -216,7 +225,7 @@ void RTC_Init(RTC_Type *base, const rtc_config_t *config) /* Setup the update mode and supervisor access mode */ reg &= ~(RTC_CR_UM_MASK | RTC_CR_SUP_MASK); reg |= RTC_CR_UM(config->updateMode) | RTC_CR_SUP(config->supervisorAccess); -#if defined(FSL_FEATURE_RTC_HAS_WAKEUP_PIN) && FSL_FEATURE_RTC_HAS_WAKEUP_PIN +#if defined(FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION) && FSL_FEATURE_RTC_HAS_WAKEUP_PIN_SELECTION /* Setup the wakeup pin select */ reg &= ~(RTC_CR_WPS_MASK); reg |= RTC_CR_WPS(config->wakeupSelect); @@ -340,6 +349,8 @@ void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask) void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter) { + assert(counter); + *counter = (((uint64_t)base->MCHR << 32) | ((uint64_t)base->MCLR)); } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rtc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rtc.h index 063d1d40c3..99effc6dcb 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rtc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_rtc.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -33,11 +33,10 @@ #include "fsl_common.h" /*! - * @addtogroup rtc_driver + * @addtogroup rtc * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -65,15 +64,19 @@ typedef enum _rtc_status_flags kRTC_AlarmFlag = RTC_SR_TAF_MASK /*!< Alarm flag*/ } rtc_status_flags_t; +#if (defined(FSL_FEATURE_RTC_HAS_OSC_SCXP) && FSL_FEATURE_RTC_HAS_OSC_SCXP) + /*! @brief List of RTC Oscillator capacitor load settings */ typedef enum _rtc_osc_cap_load { - kRTC_Capacitor_2p = RTC_CR_SC2P_MASK, /*!< 2pF capacitor load */ - kRTC_Capacitor_4p = RTC_CR_SC4P_MASK, /*!< 4pF capacitor load */ - kRTC_Capacitor_8p = RTC_CR_SC8P_MASK, /*!< 8pF capacitor load */ - kRTC_Capacitor_16p = RTC_CR_SC16P_MASK /*!< 16pF capacitor load */ + kRTC_Capacitor_2p = RTC_CR_SC2P_MASK, /*!< 2 pF capacitor load */ + kRTC_Capacitor_4p = RTC_CR_SC4P_MASK, /*!< 4 pF capacitor load */ + kRTC_Capacitor_8p = RTC_CR_SC8P_MASK, /*!< 8 pF capacitor load */ + kRTC_Capacitor_16p = RTC_CR_SC16P_MASK /*!< 16 pF capacitor load */ } rtc_osc_cap_load_t; +#endif /* FSL_FEATURE_SCG_HAS_OSC_SCXP */ + /*! @brief Structure is used to hold the date and time */ typedef struct _rtc_datetime { @@ -96,7 +99,7 @@ typedef struct _rtc_datetime */ typedef struct _rtc_config { - bool wakeupSelect; /*!< true: Wakeup pin outputs the 32KHz clock; + bool wakeupSelect; /*!< true: Wakeup pin outputs the 32 KHz clock; false:Wakeup pin used to wakeup the chip */ bool updateMode; /*!< true: Registers can be written even when locked under certain conditions, false: No writes allowed when registers are locked */ @@ -122,17 +125,17 @@ extern "C" { /*! * @brief Ungates the RTC clock and configures the peripheral for basic operation. * - * This function will issue a software reset if the timer invalid flag is set. + * This function issues a software reset if the timer invalid flag is set. * * @note This API should be called at the beginning of the application using the RTC driver. * * @param base RTC peripheral base address - * @param config Pointer to user's RTC config structure. + * @param config Pointer to the user's RTC configuration structure. */ void RTC_Init(RTC_Type *base, const rtc_config_t *config); /*! - * @brief Stop the timer and gate the RTC clock + * @brief Stops the timer and gate the RTC clock. * * @param base RTC peripheral base address */ @@ -141,14 +144,16 @@ static inline void RTC_Deinit(RTC_Type *base) /* Stop the RTC timer */ base->SR &= ~RTC_SR_TCE_MASK; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate the module clock */ CLOCK_DisableClock(kCLOCK_Rtc0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } /*! - * @brief Fill in the RTC config struct with the default settings + * @brief Fills in the RTC config struct with the default settings. * - * The default values are: + * The default values are as follows. * @code * config->wakeupSelect = false; * config->updateMode = false; @@ -156,7 +161,7 @@ static inline void RTC_Deinit(RTC_Type *base) * config->compensationInterval = 0; * config->compensationTime = 0; * @endcode - * @param config Pointer to user's RTC config structure. + * @param config Pointer to the user's RTC configuration structure. */ void RTC_GetDefaultConfig(rtc_config_t *config); @@ -170,11 +175,11 @@ void RTC_GetDefaultConfig(rtc_config_t *config); /*! * @brief Sets the RTC date and time according to the given time structure. * - * The RTC counter must be stopped prior to calling this function as writes to the RTC - * seconds register will fail if the RTC counter is running. + * The RTC counter must be stopped prior to calling this function because writes to the RTC + * seconds register fail if the RTC counter is running. * * @param base RTC peripheral base address - * @param datetime Pointer to structure where the date and time details to set are stored + * @param datetime Pointer to the structure where the date and time details are stored. * * @return kStatus_Success: Success in setting the time and starting the RTC * kStatus_InvalidArgument: Error because the datetime format is incorrect @@ -185,18 +190,18 @@ status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime); * @brief Gets the RTC time and stores it in the given time structure. * * @param base RTC peripheral base address - * @param datetime Pointer to structure where the date and time details are stored. + * @param datetime Pointer to the structure where the date and time details are stored. */ void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime); /*! - * @brief Sets the RTC alarm time + * @brief Sets the RTC alarm time. * * The function checks whether the specified alarm time is greater than the present * time. If not, the function does not set the alarm and returns an error. * * @param base RTC peripheral base address - * @param alarmTime Pointer to structure where the alarm time is stored. + * @param alarmTime Pointer to the structure where the alarm time is stored. * * @return kStatus_Success: success in setting the RTC alarm * kStatus_InvalidArgument: Error because the alarm datetime format is incorrect @@ -208,7 +213,7 @@ status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime); * @brief Returns the RTC alarm time. * * @param base RTC peripheral base address - * @param datetime Pointer to structure where the alarm date and time details are stored. + * @param datetime Pointer to the structure where the alarm date and time details are stored. */ void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime); @@ -264,7 +269,7 @@ static inline uint32_t RTC_GetEnabledInterrupts(RTC_Type *base) */ /*! - * @brief Gets the RTC status flags + * @brief Gets the RTC status flags. * * @param base RTC peripheral base address * @@ -319,6 +324,8 @@ static inline void RTC_StopTimer(RTC_Type *base) /*! @}*/ +#if (defined(FSL_FEATURE_RTC_HAS_OSC_SCXP) && FSL_FEATURE_RTC_HAS_OSC_SCXP) + /*! * @brief This function sets the specified capacitor configuration for the RTC oscillator. * @@ -336,6 +343,8 @@ static inline void RTC_SetOscCapLoad(RTC_Type *base, uint32_t capLoad) base->CR = reg; } +#endif /* FSL_FEATURE_SCG_HAS_OSC_SCXP */ + /*! * @brief Performs a software reset on the RTC module. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai.c index c38165ec04..73ea64fa4e 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -95,15 +95,17 @@ static void SAI_ReadNonBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWi /******************************************************************************* * Variables ******************************************************************************/ -/*!@brief SAI handle pointer */ -sai_handle_t *s_saiHandle[FSL_FEATURE_SOC_I2S_COUNT][2]; /* Base pointer array */ static I2S_Type *const s_saiBases[] = I2S_BASE_PTRS; +/*!@brief SAI handle pointer */ +sai_handle_t *s_saiHandle[ARRAY_SIZE(s_saiBases)][2]; /* IRQ number array */ static const IRQn_Type s_saiTxIRQ[] = I2S_TX_IRQS; static const IRQn_Type s_saiRxIRQ[] = I2S_RX_IRQS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Clock name array */ static const clock_ip_name_t s_saiClock[] = SAI_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Pointer to tx IRQ handler for each instance. */ static sai_tx_isr_t s_saiTxIsr; /*! @brief Pointer to tx IRQ handler for each instance. */ @@ -181,7 +183,7 @@ uint32_t SAI_GetInstance(I2S_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_I2S_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_saiBases); instance++) { if (s_saiBases[instance] == base) { @@ -189,7 +191,7 @@ uint32_t SAI_GetInstance(I2S_Type *base) } } - assert(instance < FSL_FEATURE_SOC_I2S_COUNT); + assert(instance < ARRAY_SIZE(s_saiBases)); return instance; } @@ -237,8 +239,10 @@ void SAI_TxInit(I2S_Type *base, const sai_config_t *config) { uint32_t val = 0; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the SAI clock */ CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) /* Master clock source setting */ @@ -339,8 +343,10 @@ void SAI_RxInit(I2S_Type *base, const sai_config_t *config) { uint32_t val = 0; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable SAI clock first. */ CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) /* Master clock source setting */ @@ -441,7 +447,9 @@ void SAI_Deinit(I2S_Type *base) { SAI_TxEnable(base, false); SAI_RxEnable(base, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_DisableClock(s_saiClock[SAI_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void SAI_TxGetDefaultConfig(sai_config_t *config) @@ -632,7 +640,7 @@ void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint uint32_t i = 0; uint8_t bytesPerWord = bitWidth / 8U; - for (i = 0; i < size; i++) + while (i < size) { /* Wait until it can write data */ while (!(base->TCSR & I2S_TCSR_FWF_MASK)) @@ -641,6 +649,7 @@ void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint SAI_WriteNonBlocking(base, channel, bitWidth, buffer, bytesPerWord); buffer += bytesPerWord; + i += bytesPerWord; } /* Wait until the last data is sent */ @@ -654,7 +663,7 @@ void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8 uint32_t i = 0; uint8_t bytesPerWord = bitWidth / 8U; - for (i = 0; i < size; i++) + while (i < size) { /* Wait until data is received */ while (!(base->RCSR & I2S_RCSR_FWF_MASK)) @@ -663,6 +672,7 @@ void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8 SAI_ReadNonBlocking(base, channel, bitWidth, buffer, bytesPerWord); buffer += bytesPerWord; + i += bytesPerWord; } } @@ -670,6 +680,9 @@ void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transf { assert(handle); + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + s_saiHandle[SAI_GetInstance(base)][0] = handle; handle->callback = callback; @@ -686,6 +699,9 @@ void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transf { assert(handle); + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + s_saiHandle[SAI_GetInstance(base)][1] = handle; handle->callback = callback; @@ -1024,19 +1040,30 @@ void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle) } #if defined(I2S0) -#if defined(FSL_FEATURE_SAI_INT_SOURCE_NUM) && (FSL_FEATURE_SAI_INT_SOURCE_NUM == 1) void I2S0_DriverIRQHandler(void) { - if ((s_saiHandle[0][1]) && ((I2S0->RCSR & kSAI_FIFOWarningFlag) || (I2S0->RCSR & kSAI_FIFOErrorFlag))) +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if ((s_saiHandle[0][1]) && ((I2S0->RCSR & kSAI_FIFORequestFlag) || (I2S0->RCSR & kSAI_FIFOErrorFlag)) && + ((I2S0->RCSR & kSAI_FIFORequestInterruptEnable) || (I2S0->RCSR & kSAI_FIFOErrorInterruptEnable))) +#else + if ((s_saiHandle[0][1]) && ((I2S0->RCSR & kSAI_FIFOWarningFlag) || (I2S0->RCSR & kSAI_FIFOErrorFlag)) && + ((I2S0->RCSR & kSAI_FIFOWarningInterruptEnable) || (I2S0->RCSR & kSAI_FIFOErrorInterruptEnable))) +#endif { s_saiRxIsr(I2S0, s_saiHandle[0][1]); } - if ((s_saiHandle[0][0]) && ((I2S0->TCSR & kSAI_FIFOWarningFlag) || (I2S0->TCSR & kSAI_FIFOErrorFlag))) +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if ((s_saiHandle[0][0]) && ((I2S0->TCSR & kSAI_FIFORequestFlag) || (I2S0->TCSR & kSAI_FIFOErrorFlag)) && + ((I2S0->TCSR & kSAI_FIFORequestInterruptEnable) || (I2S0->TCSR & kSAI_FIFOErrorInterruptEnable))) +#else + if ((s_saiHandle[0][0]) && ((I2S0->TCSR & kSAI_FIFOWarningFlag) || (I2S0->TCSR & kSAI_FIFOErrorFlag)) && + ((I2S0->TCSR & kSAI_FIFOWarningInterruptEnable) || (I2S0->TCSR & kSAI_FIFOErrorInterruptEnable))) +#endif { s_saiTxIsr(I2S0, s_saiHandle[0][0]); } } -#else + void I2S0_Tx_DriverIRQHandler(void) { assert(s_saiHandle[0][0]); @@ -1048,10 +1075,33 @@ void I2S0_Rx_DriverIRQHandler(void) assert(s_saiHandle[0][1]); s_saiRxIsr(I2S0, s_saiHandle[0][1]); } -#endif /* FSL_FEATURE_SAI_INT_SOURCE_NUM */ #endif /* I2S0*/ #if defined(I2S1) +void I2S1_DriverIRQHandler(void) +{ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if ((s_saiHandle[1][1]) && ((I2S1->RCSR & kSAI_FIFORequestFlag) || (I2S1->RCSR & kSAI_FIFOErrorFlag)) && + ((I2S1->RCSR & kSAI_FIFORequestInterruptEnable) || (I2S1->RCSR & kSAI_FIFOErrorInterruptEnable))) +#else + if ((s_saiHandle[1][1]) && ((I2S1->RCSR & kSAI_FIFOWarningFlag) || (I2S1->RCSR & kSAI_FIFOErrorFlag)) && + ((I2S1->RCSR & kSAI_FIFOWarningInterruptEnable) || (I2S1->RCSR & kSAI_FIFOErrorInterruptEnable))) +#endif + { + s_saiRxIsr(I2S1, s_saiHandle[1][1]); + } +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if ((s_saiHandle[1][0]) && ((I2S1->TCSR & kSAI_FIFORequestFlag) || (I2S1->TCSR & kSAI_FIFOErrorFlag)) && + ((I2S1->TCSR & kSAI_FIFORequestInterruptEnable) || (I2S1->TCSR & kSAI_FIFOErrorInterruptEnable))) +#else + if ((s_saiHandle[1][0]) && ((I2S1->TCSR & kSAI_FIFOWarningFlag) || (I2S1->TCSR & kSAI_FIFOErrorFlag)) && + ((I2S1->TCSR & kSAI_FIFOWarningInterruptEnable) || (I2S1->TCSR & kSAI_FIFOErrorInterruptEnable))) +#endif + { + s_saiTxIsr(I2S1, s_saiHandle[1][0]); + } +} + void I2S1_Tx_DriverIRQHandler(void) { assert(s_saiHandle[1][0]); @@ -1063,4 +1113,80 @@ void I2S1_Rx_DriverIRQHandler(void) assert(s_saiHandle[1][1]); s_saiRxIsr(I2S1, s_saiHandle[1][1]); } +#endif /* I2S1*/ + +#if defined(I2S2) +void I2S2_DriverIRQHandler(void) +{ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if ((s_saiHandle[2][1]) && ((I2S2->RCSR & kSAI_FIFORequestFlag) || (I2S2->RCSR & kSAI_FIFOErrorFlag)) && + ((I2S2->RCSR & kSAI_FIFORequestInterruptEnable) || (I2S2->RCSR & kSAI_FIFOErrorInterruptEnable))) +#else + if ((s_saiHandle[2][1]) && ((I2S2->RCSR & kSAI_FIFOWarningFlag) || (I2S2->RCSR & kSAI_FIFOErrorFlag)) && + ((I2S2->RCSR & kSAI_FIFOWarningInterruptEnable) || (I2S2->RCSR & kSAI_FIFOErrorInterruptEnable))) #endif + { + s_saiRxIsr(I2S2, s_saiHandle[2][1]); + } +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if ((s_saiHandle[2][0]) && ((I2S2->TCSR & kSAI_FIFORequestFlag) || (I2S2->TCSR & kSAI_FIFOErrorFlag)) && + ((I2S2->TCSR & kSAI_FIFORequestInterruptEnable) || (I2S2->TCSR & kSAI_FIFOErrorInterruptEnable))) +#else + if ((s_saiHandle[2][0]) && ((I2S2->TCSR & kSAI_FIFOWarningFlag) || (I2S2->TCSR & kSAI_FIFOErrorFlag)) && + ((I2S2->TCSR & kSAI_FIFOWarningInterruptEnable) || (I2S2->TCSR & kSAI_FIFOErrorInterruptEnable))) +#endif + { + s_saiTxIsr(I2S2, s_saiHandle[2][0]); + } +} + +void I2S2_Tx_DriverIRQHandler(void) +{ + assert(s_saiHandle[2][0]); + s_saiTxIsr(I2S2, s_saiHandle[2][0]); +} + +void I2S2_Rx_DriverIRQHandler(void) +{ + assert(s_saiHandle[2][1]); + s_saiRxIsr(I2S2, s_saiHandle[2][1]); +} +#endif /* I2S2*/ + +#if defined(I2S3) +void I2S3_DriverIRQHandler(void) +{ +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if ((s_saiHandle[3][1]) && ((I2S3->RCSR & kSAI_FIFORequestFlag) || (I2S3->RCSR & kSAI_FIFOErrorFlag)) && + ((I2S3->RCSR & kSAI_FIFORequestInterruptEnable) || (I2S3->RCSR & kSAI_FIFOErrorInterruptEnable))) +#else + if ((s_saiHandle[3][1]) && ((I2S3->RCSR & kSAI_FIFOWarningFlag) || (I2S3->RCSR & kSAI_FIFOErrorFlag)) && + ((I2S3->RCSR & kSAI_FIFOWarningInterruptEnable) || (I2S3->RCSR & kSAI_FIFOErrorInterruptEnable))) +#endif + { + s_saiRxIsr(I2S3, s_saiHandle[3][1]); + } +#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) + if ((s_saiHandle[3][0]) && ((I2S3->TCSR & kSAI_FIFORequestFlag) || (I2S3->TCSR & kSAI_FIFOErrorFlag)) && + ((I2S3->TCSR & kSAI_FIFORequestInterruptEnable) || (I2S3->TCSR & kSAI_FIFOErrorInterruptEnable))) +#else + if ((s_saiHandle[3][0]) && ((I2S3->TCSR & kSAI_FIFOWarningFlag) || (I2S3->TCSR & kSAI_FIFOErrorFlag)) && + ((I2S3->TCSR & kSAI_FIFOWarningInterruptEnable) || (I2S3->TCSR & kSAI_FIFOErrorInterruptEnable))) +#endif + { + s_saiTxIsr(I2S3, s_saiHandle[3][0]); + } +} + +void I2S3_Tx_DriverIRQHandler(void) +{ + assert(s_saiHandle[3][0]); + s_saiTxIsr(I2S3, s_saiHandle[3][0]); +} + +void I2S3_Rx_DriverIRQHandler(void) +{ + assert(s_saiHandle[3][1]); + s_saiRxIsr(I2S3, s_saiHandle[3][1]); +} +#endif /* I2S3*/ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai.h index cb38688cd9..64a2f667fc 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -38,14 +38,13 @@ * @{ */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -#define FSL_SAI_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) /*!< Version 2.1.1 */ +#define FSL_SAI_DRIVER_VERSION (MAKE_VERSION(2, 1, 2)) /*!< Version 2.1.2 */ /*@}*/ /*! @brief SAI return status*/ @@ -186,16 +185,16 @@ typedef struct _sai_config /*! @brief Audio sample rate */ typedef enum _sai_sample_rate { - kSAI_SampleRate8KHz = 8000U, /*!< Sample rate 8000Hz */ - kSAI_SampleRate11025Hz = 11025U, /*!< Sample rate 11025Hz */ - kSAI_SampleRate12KHz = 12000U, /*!< Sample rate 12000Hz */ - kSAI_SampleRate16KHz = 16000U, /*!< Sample rate 16000Hz */ - kSAI_SampleRate22050Hz = 22050U, /*!< Sample rate 22050Hz */ - kSAI_SampleRate24KHz = 24000U, /*!< Sample rate 24000Hz */ - kSAI_SampleRate32KHz = 32000U, /*!< Sample rate 32000Hz */ - kSAI_SampleRate44100Hz = 44100U, /*!< Sample rate 44100Hz */ - kSAI_SampleRate48KHz = 48000U, /*!< Sample rate 48000Hz */ - kSAI_SampleRate96KHz = 96000U /*!< Sample rate 96000Hz */ + kSAI_SampleRate8KHz = 8000U, /*!< Sample rate 8000 Hz */ + kSAI_SampleRate11025Hz = 11025U, /*!< Sample rate 11025 Hz */ + kSAI_SampleRate12KHz = 12000U, /*!< Sample rate 12000 Hz */ + kSAI_SampleRate16KHz = 16000U, /*!< Sample rate 16000 Hz */ + kSAI_SampleRate22050Hz = 22050U, /*!< Sample rate 22050 Hz */ + kSAI_SampleRate24KHz = 24000U, /*!< Sample rate 24000 Hz */ + kSAI_SampleRate32KHz = 32000U, /*!< Sample rate 32000 Hz */ + kSAI_SampleRate44100Hz = 44100U, /*!< Sample rate 44100 Hz */ + kSAI_SampleRate48KHz = 48000U, /*!< Sample rate 48000 Hz */ + kSAI_SampleRate96KHz = 96000U /*!< Sample rate 96000 Hz */ } sai_sample_rate_t; /*! @brief Audio word width */ @@ -211,7 +210,7 @@ typedef enum _sai_word_width typedef struct _sai_transfer_format { uint32_t sampleRate_Hz; /*!< Sample rate of audio data */ - uint32_t bitWidth; /*!< Data length of audio data, usually 8/16/24/32bits */ + uint32_t bitWidth; /*!< Data length of audio data, usually 8/16/24/32 bits */ sai_mono_stereo_t stereo; /*!< Mono or stereo */ uint32_t masterClockHz; /*!< Master clock frequency in Hz */ #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) @@ -239,7 +238,7 @@ struct _sai_handle uint32_t state; /*!< Transfer status */ sai_transfer_callback_t callback; /*!< Callback function called at transfer event*/ void *userData; /*!< Callback parameter passed to callback function*/ - uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32bits */ + uint8_t bitWidth; /*!< Bit width for transfer, 8/16/24/32 bits */ uint8_t channel; /*!< Transfer channel */ sai_transfer_t saiQueue[SAI_XFER_QUEUE_SIZE]; /*!< Transfer queue storing queued transfer */ size_t transferSize[SAI_XFER_QUEUE_SIZE]; /*!< Data bytes need to transfer */ @@ -301,7 +300,7 @@ void SAI_RxInit(I2S_Type *base, const sai_config_t *config); * This API initializes the configuration structure for use in SAI_TxConfig(). * The initialized structure can remain unchanged in SAI_TxConfig(), or it can be modified * before calling SAI_TxConfig(). - * Example: + * This is an example. @code sai_config_t config; SAI_TxGetDefaultConfig(&config); @@ -317,7 +316,7 @@ void SAI_TxGetDefaultConfig(sai_config_t *config); * This API initializes the configuration structure for use in SAI_RxConfig(). * The initialized structure can remain unchanged in SAI_RxConfig() or it can be modified * before calling SAI_RxConfig(). - * Example: + * This is an example. @code sai_config_t config; SAI_RxGetDefaultConfig(&config); @@ -356,7 +355,7 @@ void SAI_TxReset(I2S_Type *base); void SAI_RxReset(I2S_Type *base); /*! - * @brief Enables/disables SAI Tx. + * @brief Enables/disables the SAI Tx. * * @param base SAI base pointer * @param enable True means enable SAI Tx, false means disable. @@ -364,7 +363,7 @@ void SAI_RxReset(I2S_Type *base); void SAI_TxEnable(I2S_Type *base, bool enable); /*! - * @brief Enables/disables SAI Rx. + * @brief Enables/disables the SAI Rx. * * @param base SAI base pointer * @param enable True means enable SAI Rx, false means disable. @@ -418,7 +417,7 @@ static inline uint32_t SAI_RxGetStatusFlag(I2S_Type *base) * @brief Clears the SAI Rx status flag state. * * @param base SAI base pointer - * @param mask State mask. It can be a combination of the following source if defined: + * @param mask State mask. It can be a combination of the following sources if defined. * @arg kSAI_WordStartFlag * @arg kSAI_SyncErrorFlag * @arg kSAI_FIFOErrorFlag @@ -436,11 +435,11 @@ static inline void SAI_RxClearStatusFlags(I2S_Type *base, uint32_t mask) */ /*! - * @brief Enables SAI Tx interrupt requests. + * @brief Enables the SAI Tx interrupt requests. * * @param base SAI base pointer * @param mask interrupt source - * The parameter can be a combination of the following source if defined: + * The parameter can be a combination of the following sources if defined. * @arg kSAI_WordStartInterruptEnable * @arg kSAI_SyncErrorInterruptEnable * @arg kSAI_FIFOWarningInterruptEnable @@ -453,11 +452,11 @@ static inline void SAI_TxEnableInterrupts(I2S_Type *base, uint32_t mask) } /*! - * @brief Enables SAI Rx interrupt requests. + * @brief Enables the SAI Rx interrupt requests. * * @param base SAI base pointer * @param mask interrupt source - * The parameter can be a combination of the following source if defined: + * The parameter can be a combination of the following sources if defined. * @arg kSAI_WordStartInterruptEnable * @arg kSAI_SyncErrorInterruptEnable * @arg kSAI_FIFOWarningInterruptEnable @@ -470,11 +469,11 @@ static inline void SAI_RxEnableInterrupts(I2S_Type *base, uint32_t mask) } /*! - * @brief Disables SAI Tx interrupt requests. + * @brief Disables the SAI Tx interrupt requests. * * @param base SAI base pointer * @param mask interrupt source - * The parameter can be a combination of the following source if defined: + * The parameter can be a combination of the following sources if defined. * @arg kSAI_WordStartInterruptEnable * @arg kSAI_SyncErrorInterruptEnable * @arg kSAI_FIFOWarningInterruptEnable @@ -487,11 +486,11 @@ static inline void SAI_TxDisableInterrupts(I2S_Type *base, uint32_t mask) } /*! - * @brief Disables SAI Rx interrupt requests. + * @brief Disables the SAI Rx interrupt requests. * * @param base SAI base pointer * @param mask interrupt source - * The parameter can be a combination of the following source if defined: + * The parameter can be a combination of the following sources if defined. * @arg kSAI_WordStartInterruptEnable * @arg kSAI_SyncErrorInterruptEnable * @arg kSAI_FIFOWarningInterruptEnable @@ -511,10 +510,10 @@ static inline void SAI_RxDisableInterrupts(I2S_Type *base, uint32_t mask) */ /*! - * @brief Enables/disables SAI Tx DMA requests. + * @brief Enables/disables the SAI Tx DMA requests. * @param base SAI base pointer * @param mask DMA source - * The parameter can be combination of the following source if defined: + * The parameter can be combination of the following sources if defined. * @arg kSAI_FIFOWarningDMAEnable * @arg kSAI_FIFORequestDMAEnable * @param enable True means enable DMA, false means disable DMA. @@ -532,10 +531,10 @@ static inline void SAI_TxEnableDMA(I2S_Type *base, uint32_t mask, bool enable) } /*! - * @brief Enables/disables SAI Rx DMA requests. + * @brief Enables/disables the SAI Rx DMA requests. * @param base SAI base pointer * @param mask DMA source - * The parameter can be a combination of the following source if defined: + * The parameter can be a combination of the following sources if defined. * @arg kSAI_FIFOWarningDMAEnable * @arg kSAI_FIFORequestDMAEnable * @param enable True means enable DMA, false means disable DMA. @@ -555,7 +554,7 @@ static inline void SAI_RxEnableDMA(I2S_Type *base, uint32_t mask, bool enable) /*! * @brief Gets the SAI Tx data register address. * - * This API is used to provide a transfer address for SAI DMA transfer configuration. + * This API is used to provide a transfer address for the SAI DMA transfer configuration. * * @param base SAI base pointer. * @param channel Which data channel used. @@ -569,7 +568,7 @@ static inline uint32_t SAI_TxGetDataRegisterAddress(I2S_Type *base, uint32_t cha /*! * @brief Gets the SAI Rx data register address. * - * This API is used to provide a transfer address for SAI DMA transfer configuration. + * This API is used to provide a transfer address for the SAI DMA transfer configuration. * * @param base SAI base pointer. * @param channel Which data channel used. @@ -594,10 +593,10 @@ static inline uint32_t SAI_RxGetDataRegisterAddress(I2S_Type *base, uint32_t cha * format to be transferred. * * @param base SAI base pointer. - * @param format Pointer to SAI audio data format structure. + * @param format Pointer to the SAI audio data format structure. * @param mclkSourceClockHz SAI master clock source frequency in Hz. - * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master - * clock, this value should equals to masterClockHz in format. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master + * clock, this value should equal the masterClockHz. */ void SAI_TxSetFormat(I2S_Type *base, sai_transfer_format_t *format, @@ -611,10 +610,10 @@ void SAI_TxSetFormat(I2S_Type *base, * format to be transferred. * * @param base SAI base pointer. - * @param format Pointer to SAI audio data format structure. + * @param format Pointer to the SAI audio data format structure. * @param mclkSourceClockHz SAI master clock source frequency in Hz. - * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master - * clock, this value should equals to masterClockHz in format. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master + * clock, this value should equal the masterClockHz. */ void SAI_RxSetFormat(I2S_Type *base, sai_transfer_format_t *format, @@ -628,7 +627,7 @@ void SAI_RxSetFormat(I2S_Type *base, * * @param base SAI base pointer. * @param channel Data channel used. - * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param bitWidth How many bits in an audio word; usually 8/16/24/32 bits. * @param buffer Pointer to the data to be written. * @param size Bytes to be written. */ @@ -653,14 +652,14 @@ static inline void SAI_WriteData(I2S_Type *base, uint32_t channel, uint32_t data * * @param base SAI base pointer. * @param channel Data channel used. - * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. + * @param bitWidth How many bits in an audio word; usually 8/16/24/32 bits. * @param buffer Pointer to the data to be read. * @param size Bytes to be read. */ void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size); /*! - * @brief Reads data from SAI FIFO. + * @brief Reads data from the SAI FIFO. * * @param base SAI base pointer. * @param channel Data channel used. @@ -681,26 +680,26 @@ static inline uint32_t SAI_ReadData(I2S_Type *base, uint32_t channel) /*! * @brief Initializes the SAI Tx handle. * - * This function initializes the Tx handle for SAI Tx transactional APIs. Call - * this function one time to get the handle initialized. + * This function initializes the Tx handle for the SAI Tx transactional APIs. Call + * this function once to get the handle initialized. * * @param base SAI base pointer * @param handle SAI handle pointer. - * @param callback pointer to user callback function - * @param userData user parameter passed to the callback function + * @param callback Pointer to the user callback function. + * @param userData User parameter passed to the callback function */ void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData); /*! * @brief Initializes the SAI Rx handle. * - * This function initializes the Rx handle for SAI Rx transactional APIs. Call - * this function one time to get the handle initialized. + * This function initializes the Rx handle for the SAI Rx transactional APIs. Call + * this function once to get the handle initialized. * * @param base SAI base pointer. * @param handle SAI handle pointer. - * @param callback pointer to user callback function - * @param userData user parameter passed to the callback function + * @param callback Pointer to the user callback function. + * @param userData User parameter passed to the callback function. */ void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData); @@ -712,11 +711,11 @@ void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transf * * @param base SAI base pointer. * @param handle SAI handle pointer. - * @param format Pointer to SAI audio data format structure. + * @param format Pointer to the SAI audio data format structure. * @param mclkSourceClockHz SAI master clock source frequency in Hz. * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master - * clock, this value should equal to masterClockHz in format. - * @return Status of this function. Return value is one of status_t. + * clock, this value should equal the masterClockHz in format. + * @return Status of this function. Return value is the status_t. */ status_t SAI_TransferTxSetFormat(I2S_Type *base, sai_handle_t *handle, @@ -732,10 +731,10 @@ status_t SAI_TransferTxSetFormat(I2S_Type *base, * * @param base SAI base pointer. * @param handle SAI handle pointer. - * @param format Pointer to SAI audio data format structure. + * @param format Pointer to the SAI audio data format structure. * @param mclkSourceClockHz SAI master clock source frequency in Hz. - * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master - * clock, this value should equals to masterClockHz in format. + * @param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master + * clock, this value should equal the masterClockHz in format. * @return Status of this function. Return value is one of status_t. */ status_t SAI_TransferRxSetFormat(I2S_Type *base, @@ -752,9 +751,9 @@ status_t SAI_TransferRxSetFormat(I2S_Type *base, * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer * is finished. * - * @param base SAI base pointer - * @param handle pointer to sai_handle_t structure which stores the transfer state - * @param xfer pointer to sai_transfer_t structure + * @param base SAI base pointer. + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. + * @param xfer Pointer to the sai_transfer_t structure. * @retval kStatus_Success Successfully started the data receive. * @retval kStatus_SAI_TxBusy Previous receive still not finished. * @retval kStatus_InvalidArgument The input parameter is invalid. @@ -770,8 +769,8 @@ status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_t * is finished. * * @param base SAI base pointer - * @param handle pointer to sai_handle_t structure which stores the transfer state - * @param xfer pointer to sai_transfer_t structure + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. + * @param xfer Pointer to the sai_transfer_t structure. * @retval kStatus_Success Successfully started the data receive. * @retval kStatus_SAI_RxBusy Previous receive still not finished. * @retval kStatus_InvalidArgument The input parameter is invalid. @@ -782,7 +781,7 @@ status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sa * @brief Gets a set byte count. * * @param base SAI base pointer. - * @param handle pointer to sai_handle_t structure which stores the transfer state. + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. * @param count Bytes count sent. * @retval kStatus_Success Succeed get the transfer count. * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. @@ -793,7 +792,7 @@ status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t * * @brief Gets a received byte count. * * @param base SAI base pointer. - * @param handle pointer to sai_handle_t structure which stores the transfer state. + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. * @param count Bytes count received. * @retval kStatus_Success Succeed get the transfer count. * @retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. @@ -807,18 +806,18 @@ status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_ * to abort the transfer early. * * @param base SAI base pointer. - * @param handle pointer to sai_handle_t structure which stores the transfer state. + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. */ void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle); /*! * @brief Aborts the the current IRQ receive. * - * @note This API can be called any time when an interrupt non-blocking transfer initiates + * @note This API can be called when an interrupt non-blocking transfer initiates * to abort the transfer early. * * @param base SAI base pointer - * @param handle pointer to sai_handle_t structure which stores the transfer state. + * @param handle Pointer to the sai_handle_t structure which stores the transfer state. */ void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle); @@ -826,7 +825,7 @@ void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle); * @brief Tx interrupt handler. * * @param base SAI base pointer. - * @param handle pointer to sai_handle_t structure. + * @param handle Pointer to the sai_handle_t structure. */ void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle); @@ -834,7 +833,7 @@ void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle); * @brief Tx interrupt handler. * * @param base SAI base pointer. - * @param handle pointer to sai_handle_t structure. + * @param handle Pointer to the sai_handle_t structure. */ void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai_edma.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai_edma.c index 9b1b2f6c49..dce5a87bfa 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai_edma.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai_edma.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -132,6 +132,9 @@ void SAI_TransferTxCreateHandleEDMA( uint32_t instance = SAI_GetInstance(base); + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + /* Set sai base to handle */ handle->dmaHandle = dmaHandle; handle->callback = callback; @@ -157,6 +160,9 @@ void SAI_TransferRxCreateHandleEDMA( uint32_t instance = SAI_GetInstance(base); + /* Zero the handle */ + memset(handle, 0, sizeof(*handle)); + /* Set sai base to handle */ handle->dmaHandle = dmaHandle; handle->callback = callback; @@ -187,7 +193,14 @@ void SAI_TransferTxSetFormatEDMA(I2S_Type *base, SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); /* Get the tranfer size from format, this should be used in EDMA configuration */ - handle->bytesPerFrame = format->bitWidth / 8U; + if (format->bitWidth == 24U) + { + handle->bytesPerFrame = 4U; + } + else + { + handle->bytesPerFrame = format->bitWidth / 8U; + } /* Update the data channel SAI used */ handle->channel = format->channel; @@ -210,7 +223,14 @@ void SAI_TransferRxSetFormatEDMA(I2S_Type *base, SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); /* Get the tranfer size from format, this should be used in EDMA configuration */ - handle->bytesPerFrame = format->bitWidth / 8U; + if (format->bitWidth == 24U) + { + handle->bytesPerFrame = 4U; + } + else + { + handle->bytesPerFrame = format->bitWidth / 8U; + } /* Update the data channel SAI used */ handle->channel = format->channel; @@ -253,6 +273,9 @@ status_t SAI_TransferSendEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_tra EDMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (void *)destAddr, handle->bytesPerFrame, handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_MemoryToPeripheral); + /* Store the initially configured eDMA minor byte transfer count into the SAI handle */ + handle->nbytes = handle->count * handle->bytesPerFrame; + EDMA_SubmitTransfer(handle->dmaHandle, &config); /* Start DMA transfer */ @@ -298,6 +321,9 @@ status_t SAI_TransferReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_ EDMA_PrepareTransfer(&config, (void *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame, handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_PeripheralToMemory); + /* Store the initially configured eDMA minor byte transfer count into the SAI handle */ + handle->nbytes = handle->count * handle->bytesPerFrame; + EDMA_SubmitTransfer(handle->dmaHandle, &config); /* Start DMA transfer */ @@ -322,6 +348,9 @@ void SAI_TransferAbortSendEDMA(I2S_Type *base, sai_edma_handle_t *handle) /* Disable DMA enable bit */ SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); + /* Disable Tx */ + SAI_TxEnable(base, false); + /* Set the handle state */ handle->state = kSAI_Idle; } @@ -336,6 +365,9 @@ void SAI_TransferAbortReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle) /* Disable DMA enable bit */ SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); + /* Disable Rx */ + SAI_RxEnable(base, false); + /* Set the handle state */ handle->state = kSAI_Idle; } @@ -353,7 +385,8 @@ status_t SAI_TransferGetSendCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, else { *count = (handle->transferSize[handle->queueDriver] - - EDMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel)); + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); } return status; @@ -372,7 +405,8 @@ status_t SAI_TransferGetReceiveCountEDMA(I2S_Type *base, sai_edma_handle_t *hand else { *count = (handle->transferSize[handle->queueDriver] - - EDMA_GetRemainingBytes(handle->dmaHandle->base, handle->dmaHandle->channel)); + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); } return status; diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai_edma.h index 44506fa039..9ae05db0e9 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sai_edma.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -38,8 +38,6 @@ * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ @@ -53,6 +51,7 @@ typedef void (*sai_edma_callback_t)(I2S_Type *base, sai_edma_handle_t *handle, s struct _sai_edma_handle { edma_handle_t *dmaHandle; /*!< DMA handler for SAI send */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ uint8_t bytesPerFrame; /*!< Bytes in a frame */ uint8_t channel; /*!< Which data channel */ uint8_t count; /*!< The transfer data count in a DMA request */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdhc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdhc.c index d2774eeabc..3151cd22ed 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdhc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdhc.c @@ -1,34 +1,28 @@ /* * Copyright (c) 2016, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * - * Redistribution and use in source and binary forms, with or without - * modification, + * 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 + * 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 + * 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 + * 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 + * 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 SL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES + * 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 + * 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. @@ -42,12 +36,8 @@ /*! @brief Clock setting */ /* Max SD clock divisor from base clock */ #define SDHC_MAX_DVS ((SDHC_SYSCTL_DVS_MASK >> SDHC_SYSCTL_DVS_SHIFT) + 1U) -#define SDHC_INITIAL_DVS (1U) /* Initial value of SD clock divisor */ -#define SDHC_INITIAL_CLKFS (2U) /* Initial value of SD clock frequency selector */ -#define SDHC_NEXT_DVS(x) ((x) += 1U) #define SDHC_PREV_DVS(x) ((x) -= 1U) #define SDHC_MAX_CLKFS ((SDHC_SYSCTL_SDCLKFS_MASK >> SDHC_SYSCTL_SDCLKFS_SHIFT) + 1U) -#define SDHC_NEXT_CLKFS(x) ((x) <<= 1U) #define SDHC_PREV_CLKFS(x) ((x) >>= 1U) /* Typedef for interrupt handler. */ @@ -85,8 +75,9 @@ static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal * @param base SDHC peripheral base address. * @param command Command to be sent. * @param data Data to be transferred. + * @param DMA mode selection */ -static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data); +static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data, sdhc_dma_mode_t dmaMode); /*! * @brief Receive command response @@ -94,7 +85,7 @@ static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_da * @param base SDHC peripheral base address. * @param command Command to be sent. */ -static void SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command); +static status_t SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command); /*! * @brief Read DATAPORT when buffer enable bit is set. @@ -230,8 +221,10 @@ static SDHC_Type *const s_sdhcBase[] = SDHC_BASE_PTRS; /*! @brief SDHC IRQ name array */ static const IRQn_Type s_sdhcIRQ[] = SDHC_IRQS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief SDHC clock array name */ static const clock_ip_name_t s_sdhcClock[] = SDHC_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* SDHC ISR for transactional APIs. */ static sdhc_isr_t s_sdhcIsr; @@ -243,12 +236,12 @@ static uint32_t SDHC_GetInstance(SDHC_Type *base) { uint8_t instance = 0; - while ((instance < FSL_FEATURE_SOC_SDHC_COUNT) && (s_sdhcBase[instance] != base)) + while ((instance < ARRAY_SIZE(s_sdhcBase)) && (s_sdhcBase[instance] != base)) { instance++; } - assert(instance < FSL_FEATURE_SOC_SDHC_COUNT); + assert(instance < ARRAY_SIZE(s_sdhcBase)); return instance; } @@ -256,7 +249,6 @@ static uint32_t SDHC_GetInstance(SDHC_Type *base) static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal) { uint32_t interruptEnabled; /* The Interrupt status flags to be enabled */ - sdhc_dma_mode_t dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT); bool cardDetectDat3 = (bool)(base->PROCTL & SDHC_PROCTL_D3CD_MASK); /* Disable all interrupts */ @@ -267,23 +259,12 @@ static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal interruptEnabled = (kSDHC_CommandIndexErrorFlag | kSDHC_CommandCrcErrorFlag | kSDHC_CommandEndBitErrorFlag | kSDHC_CommandTimeoutFlag | kSDHC_CommandCompleteFlag | kSDHC_DataTimeoutFlag | kSDHC_DataCrcErrorFlag | - kSDHC_DataEndBitErrorFlag | kSDHC_DataCompleteFlag | kSDHC_AutoCommand12ErrorFlag); + kSDHC_DataEndBitErrorFlag | kSDHC_DataCompleteFlag | kSDHC_AutoCommand12ErrorFlag | kSDHC_BufferReadReadyFlag | + kSDHC_BufferWriteReadyFlag | kSDHC_DmaErrorFlag | kSDHC_DmaCompleteFlag); if (cardDetectDat3) { interruptEnabled |= (kSDHC_CardInsertionFlag | kSDHC_CardRemovalFlag); } - switch (dmaMode) - { - case kSDHC_DmaModeAdma1: - case kSDHC_DmaModeAdma2: - interruptEnabled |= (kSDHC_DmaErrorFlag | kSDHC_DmaCompleteFlag); - break; - case kSDHC_DmaModeNo: - interruptEnabled |= (kSDHC_BufferReadReadyFlag | kSDHC_BufferWriteReadyFlag); - break; - default: - break; - } SDHC_EnableInterruptStatus(base, interruptEnabled); if (usingInterruptSignal) @@ -292,48 +273,47 @@ static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal } } -static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data) +static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data, sdhc_dma_mode_t dmaMode) { uint32_t flags = 0U; sdhc_transfer_config_t sdhcTransferConfig = {0}; - sdhc_dma_mode_t dmaMode; /* Define the flag corresponding to each response type. */ switch (command->responseType) { - case kSDHC_ResponseTypeNone: + case kCARD_ResponseTypeNone: break; - case kSDHC_ResponseTypeR1: /* Response 1 */ + case kCARD_ResponseTypeR1: /* Response 1 */ flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); break; - case kSDHC_ResponseTypeR1b: /* Response 1 with busy */ + case kCARD_ResponseTypeR1b: /* Response 1 with busy */ flags |= (kSDHC_ResponseLength48BusyFlag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); break; - case kSDHC_ResponseTypeR2: /* Response 2 */ + case kCARD_ResponseTypeR2: /* Response 2 */ flags |= (kSDHC_ResponseLength136Flag | kSDHC_EnableCrcCheckFlag); break; - case kSDHC_ResponseTypeR3: /* Response 3 */ + case kCARD_ResponseTypeR3: /* Response 3 */ flags |= (kSDHC_ResponseLength48Flag); break; - case kSDHC_ResponseTypeR4: /* Response 4 */ + case kCARD_ResponseTypeR4: /* Response 4 */ flags |= (kSDHC_ResponseLength48Flag); break; - case kSDHC_ResponseTypeR5: /* Response 5 */ + case kCARD_ResponseTypeR5: /* Response 5 */ flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); break; - case kSDHC_ResponseTypeR5b: /* Response 5 with busy */ + case kCARD_ResponseTypeR5b: /* Response 5 with busy */ flags |= (kSDHC_ResponseLength48BusyFlag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); break; - case kSDHC_ResponseTypeR6: /* Response 6 */ + case kCARD_ResponseTypeR6: /* Response 6 */ flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); break; - case kSDHC_ResponseTypeR7: /* Response 7 */ + case kCARD_ResponseTypeR7: /* Response 7 */ flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag); break; default: break; } - if (command->type == kSDHC_CommandTypeAbort) + if (command->type == kCARD_CommandTypeAbort) { flags |= kSDHC_CommandTypeAbortFlag; } @@ -341,7 +321,7 @@ static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_da if (data) { flags |= kSDHC_DataPresentFlag; - dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT); + if (dmaMode != kSDHC_DmaModeNo) { flags |= kSDHC_EnableDmaFlag; @@ -375,14 +355,14 @@ static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_da SDHC_SetTransferConfig(base, &sdhcTransferConfig); } -static void SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command) +static status_t SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command) { uint32_t i; - if (command->responseType != kSDHC_ResponseTypeNone) + if (command->responseType != kCARD_ResponseTypeNone) { command->response[0U] = SDHC_GetCommandResponse(base, 0U); - if (command->responseType == kSDHC_ResponseTypeR2) + if (command->responseType == kCARD_ResponseTypeR2) { command->response[1U] = SDHC_GetCommandResponse(base, 1U); command->response[2U] = SDHC_GetCommandResponse(base, 2U); @@ -401,6 +381,18 @@ static void SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command } while (i--); } } + /* check response error flag */ + if ((command->responseErrorFlags != 0U) && + ((command->responseType == kCARD_ResponseTypeR1) || (command->responseType == kCARD_ResponseTypeR1b) || + (command->responseType == kCARD_ResponseTypeR6) || (command->responseType == kCARD_ResponseTypeR5))) + { + if (((command->responseErrorFlags) & (command->response[0U])) != 0U) + { + return kStatus_SDHC_SendCommandFailed; + } + } + + return kStatus_Success; } static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords) @@ -411,10 +403,10 @@ static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t t uint32_t readWatermark = ((base->WML & SDHC_WML_RDWML_MASK) >> SDHC_WML_RDWML_SHIFT); /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ if (data->blockSize % sizeof(uint32_t) != 0U) { data->blockSize += @@ -458,10 +450,10 @@ static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) status_t error = kStatus_Success; /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ if (data->blockSize % sizeof(uint32_t) != 0U) { data->blockSize += @@ -487,13 +479,12 @@ static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) { transferredWords = SDHC_ReadDataPort(base, data, transferredWords); } - - /* Clear buffer enable flag to trigger transfer. Clear data error flag when SDHC encounter error */ - SDHC_ClearInterruptStatusFlags(base, (kSDHC_BufferReadReadyFlag | kSDHC_DataErrorFlag)); + /* clear buffer ready and error */ + SDHC_ClearInterruptStatusFlags(base, kSDHC_BufferReadReadyFlag | kSDHC_DataErrorFlag); } /* Clear data complete flag after the last read operation. */ - SDHC_ClearInterruptStatusFlags(base, kSDHC_DataCompleteFlag); + SDHC_ClearInterruptStatusFlags(base, kSDHC_DataCompleteFlag | kSDHC_DataErrorFlag); return error; } @@ -506,10 +497,10 @@ static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t uint32_t writeWatermark = ((base->WML & SDHC_WML_WRWML_MASK) >> SDHC_WML_WRWML_SHIFT); /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ if (data->blockSize % sizeof(uint32_t) != 0U) { data->blockSize += @@ -553,10 +544,10 @@ static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) status_t error = kStatus_Success; /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ if (data->blockSize % sizeof(uint32_t) != 0U) { data->blockSize += @@ -598,6 +589,7 @@ static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data) error = kStatus_Fail; } } + SDHC_ClearInterruptStatusFlags(base, (kSDHC_DataCompleteFlag | kSDHC_DataErrorFlag)); return error; @@ -619,7 +611,7 @@ static status_t SDHC_SendCommandBlocking(SDHC_Type *base, sdhc_command_t *comman /* Receive response when command completes successfully. */ if (error == kStatus_Success) { - SDHC_ReceiveCommandResponse(base, command); + error = SDHC_ReceiveCommandResponse(base, command); } SDHC_ClearInterruptStatusFlags(base, (kSDHC_CommandCompleteFlag | kSDHC_CommandErrorFlag)); @@ -748,7 +740,11 @@ static void SDHC_TransferHandleData(SDHC_Type *base, sdhc_handle_t *handle, uint { handle->transferredWords = SDHC_WriteDataPort(base, handle->data, handle->transferredWords); } - else if ((interruptFlags & kSDHC_DataCompleteFlag) && (handle->callback.TransferComplete)) + else + { + } + + if ((interruptFlags & kSDHC_DataCompleteFlag) && (handle->callback.TransferComplete)) { handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData); } @@ -787,8 +783,10 @@ void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config) uint32_t proctl; uint32_t wml; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable SDHC clock. */ CLOCK_EnableClock(s_sdhcClock[SDHC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Reset SDHC. */ SDHC_Reset(base, kSDHC_ResetAll, 100); @@ -822,8 +820,10 @@ void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config) void SDHC_Deinit(SDHC_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable clock. */ CLOCK_DisableClock(s_sdhcClock[SDHC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } bool SDHC_Reset(SDHC_Type *base, uint32_t mask, uint32_t timeout) @@ -877,44 +877,83 @@ uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busCloc assert(srcClock_Hz != 0U); assert((busClock_Hz != 0U) && (busClock_Hz <= srcClock_Hz)); - uint32_t divisor; - uint32_t prescaler; - uint32_t sysctl; - uint32_t nearestFrequency = 0; + uint32_t totalDiv = 0U; + uint32_t divisor = 0U; + uint32_t prescaler = 0U; + uint32_t sysctl = 0U; + uint32_t nearestFrequency = 0U; - divisor = SDHC_INITIAL_DVS; - prescaler = SDHC_INITIAL_CLKFS; + /* calucate total divisor first */ + totalDiv = srcClock_Hz / busClock_Hz; + + if (totalDiv != 0U) + { + /* calucate the divisor (srcClock_Hz / divisor) <= busClock_Hz */ + if ((srcClock_Hz / totalDiv) > busClock_Hz) + { + totalDiv++; + } + + /* divide the total divisor to div and prescaler */ + if (totalDiv > SDHC_MAX_DVS) + { + prescaler = totalDiv / SDHC_MAX_DVS; + /* prescaler must be a value which equal 2^n and smaller than SDHC_MAX_CLKFS */ + while (((SDHC_MAX_CLKFS % prescaler) != 0U) || (prescaler == 1U)) + { + prescaler++; + } + /* calucate the divisor */ + divisor = totalDiv / prescaler; + /* fine tuning the divisor until divisor * prescaler >= totalDiv */ + while ((divisor * prescaler) < totalDiv) + { + divisor++; + } + nearestFrequency = srcClock_Hz / divisor / prescaler; + } + else + { + divisor = totalDiv; + prescaler = 0U; + nearestFrequency = srcClock_Hz / divisor; + } + } + /* in this condition , srcClock_Hz = busClock_Hz, */ + else + { + /* total divider = 1U */ + divisor = 0U; + prescaler = 0U; + nearestFrequency = srcClock_Hz; + } + + /* calucate the value write to register */ + if (divisor != 0U) + { + SDHC_PREV_DVS(divisor); + } + /* calucate the value write to register */ + if (prescaler != 0U) + { + SDHC_PREV_CLKFS(prescaler); + } /* Disable SD clock. It should be disabled before changing the SD clock frequency.*/ base->SYSCTL &= ~SDHC_SYSCTL_SDCLKEN_MASK; - if (busClock_Hz > 0U) + /* Set the SD clock frequency divisor, SD clock frequency select, data timeout counter value. */ + sysctl = base->SYSCTL; + sysctl &= ~(SDHC_SYSCTL_DVS_MASK | SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DTOCV_MASK); + sysctl |= (SDHC_SYSCTL_DVS(divisor) | SDHC_SYSCTL_SDCLKFS(prescaler) | SDHC_SYSCTL_DTOCV(0xEU)); + base->SYSCTL = sysctl; + + /* Wait until the SD clock is stable. */ + while (!(base->PRSSTAT & SDHC_PRSSTAT_SDSTB_MASK)) { - while ((srcClock_Hz / prescaler / SDHC_MAX_DVS > busClock_Hz) && (prescaler < SDHC_MAX_CLKFS)) - { - SDHC_NEXT_CLKFS(prescaler); - } - while ((srcClock_Hz / prescaler / divisor > busClock_Hz) && (divisor < SDHC_MAX_DVS)) - { - SDHC_NEXT_DVS(divisor); - } - nearestFrequency = srcClock_Hz / prescaler / divisor; - SDHC_PREV_CLKFS(prescaler); - SDHC_PREV_DVS(divisor); - - /* Set the SD clock frequency divisor, SD clock frequency select, data timeout counter value. */ - sysctl = base->SYSCTL; - sysctl &= ~(SDHC_SYSCTL_DVS_MASK | SDHC_SYSCTL_SDCLKFS_MASK | SDHC_SYSCTL_DTOCV_MASK); - sysctl |= (SDHC_SYSCTL_DVS(divisor) | SDHC_SYSCTL_SDCLKFS(prescaler) | SDHC_SYSCTL_DTOCV(0xEU)); - base->SYSCTL = sysctl; - - /* Wait until the SD clock is stable. */ - while (!(base->PRSSTAT & SDHC_PRSSTAT_SDSTB_MASK)) - { - } - /* Enable the SD clock. */ - base->SYSCTL |= SDHC_SYSCTL_SDCLKEN_MASK; } + /* Enable the SD clock. */ + base->SYSCTL |= SDHC_SYSCTL_SDCLKEN_MASK; return nearestFrequency; } @@ -1008,7 +1047,7 @@ void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config) uint32_t mmcboot = 0U; mmcboot = (SDHC_MMCBOOT_DTOCVACK(config->ackTimeoutCount) | SDHC_MMCBOOT_BOOTMODE(config->bootMode) | - SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount)); + SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount)); if (config->enableBootAck) { mmcboot |= SDHC_MMCBOOT_BOOTACK_MASK; @@ -1032,7 +1071,7 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base, uint32_t dataBytes) { status_t error = kStatus_Success; - const uint32_t *startAddress; + const uint32_t *startAddress = data; uint32_t entries; uint32_t i; #if defined FSL_SDHC_ENABLE_ADMA1 @@ -1044,14 +1083,19 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base, (!data) || (!dataBytes) #if !defined FSL_SDHC_ENABLE_ADMA1 || (dmaMode == kSDHC_DmaModeAdma1) -#else - /* Buffer address configured in ADMA1 descriptor must be 4KB aligned. */ - || ((dmaMode == kSDHC_DmaModeAdma1) && (((uint32_t)data % SDHC_ADMA1_LENGTH_ALIGN) != 0U)) -#endif /* FSL_SDHC_ENABLE_ADMA1 */ +#endif ) { error = kStatus_InvalidArgument; } + else if (((dmaMode == kSDHC_DmaModeAdma2) && (((uint32_t)startAddress % SDHC_ADMA2_LENGTH_ALIGN) != 0U)) +#if defined FSL_SDHC_ENABLE_ADMA1 + || ((dmaMode == kSDHC_DmaModeAdma1) && (((uint32_t)startAddress % SDHC_ADMA1_LENGTH_ALIGN) != 0U)) +#endif + ) + { + error = kStatus_SDHC_DMADataBufferAddrNotAlign; + } else { switch (dmaMode) @@ -1071,7 +1115,6 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base, sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */ } - startAddress = data; /* Check if ADMA descriptor's number is enough. */ entries = ((dataBytes / SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U); /* ADMA1 needs two descriptors to finish a transfer */ @@ -1113,22 +1156,24 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base, /* When use ADMA, disable simple DMA */ base->DSADDR = 0U; base->ADSADDR = (uint32_t)table; + /* disable the buffer ready flag in DMA mode */ + SDHC_DisableInterruptSignal(base, kSDHC_BufferReadReadyFlag | kSDHC_BufferWriteReadyFlag); + SDHC_DisableInterruptStatus(base, kSDHC_BufferReadReadyFlag | kSDHC_BufferWriteReadyFlag); } break; #endif /* FSL_SDHC_ENABLE_ADMA1 */ case kSDHC_DmaModeAdma2: /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ + * Add non aligned access support ,user need make sure your buffer size is big + * enough to hold the data,in other words,user need make sure the buffer size + * is 4 byte aligned + */ if (dataBytes % sizeof(uint32_t) != 0U) { dataBytes += sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */ } - startAddress = data; /* Check if ADMA descriptor's number is enough. */ entries = ((dataBytes / SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U); if (entries > ((tableWords * sizeof(uint32_t)) / sizeof(sdhc_adma2_descriptor_t))) @@ -1165,6 +1210,9 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base, /* When use ADMA, disable simple DMA */ base->DSADDR = 0U; base->ADSADDR = (uint32_t)table; + /* disable the buffer read flag in DMA mode */ + SDHC_DisableInterruptSignal(base, kSDHC_BufferReadReadyFlag | kSDHC_BufferWriteReadyFlag); + SDHC_DisableInterruptStatus(base, kSDHC_BufferReadReadyFlag | kSDHC_BufferWriteReadyFlag); } break; default: @@ -1187,44 +1235,53 @@ status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t ad /* make sure the cmd/block count is valid */ if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT))) { - error = kStatus_InvalidArgument; + return kStatus_InvalidArgument; } - else - { - /* Wait until command/data bus out of busy status. */ - while (SDHC_GetPresentStatusFlags(base) & kSDHC_CommandInhibitFlag) - { - } - while (data && (SDHC_GetPresentStatusFlags(base) & kSDHC_DataInhibitFlag)) - { - } - /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ - if (data && (kStatus_Success != SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords, - (data->rxData ? data->rxData : data->txData), - (data->blockCount * data->blockSize)))) + /* Wait until command/data bus out of busy status. */ + while (SDHC_GetPresentStatusFlags(base) & kSDHC_CommandInhibitFlag) + { + } + while (data && (SDHC_GetPresentStatusFlags(base) & kSDHC_DataInhibitFlag)) + { + } + + /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ + if (data && (NULL != admaTable)) + { + error = + SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords, + (data->rxData ? data->rxData : data->txData), (data->blockCount * data->blockSize)); + /* in this situation , we disable the DMA instead of polling transfer mode */ + if (error == kStatus_SDHC_DMADataBufferAddrNotAlign) { - error = kStatus_SDHC_PrepareAdmaDescriptorFailed; + dmaMode = kSDHC_DmaModeNo; + SDHC_EnableInterruptStatus(base, kSDHC_BufferReadReadyFlag | kSDHC_BufferWriteReadyFlag); + } + else if (error != kStatus_Success) + { + return error; } else { - /* Send command and receive data. */ - SDHC_StartTransfer(base, command, data); - if (kStatus_Success != SDHC_SendCommandBlocking(base, command)) - { - error = kStatus_SDHC_SendCommandFailed; - } - else if (data && (kStatus_Success != SDHC_TransferDataBlocking(dmaMode, base, data))) - { - error = kStatus_SDHC_TransferDataFailed; - } - else - { - } } } - return error; + /* Send command and receive data. */ + SDHC_StartTransfer(base, command, data, dmaMode); + if (kStatus_Success != SDHC_SendCommandBlocking(base, command)) + { + return kStatus_SDHC_SendCommandFailed; + } + else if (data && (kStatus_Success != SDHC_TransferDataBlocking(dmaMode, base, data))) + { + return kStatus_SDHC_TransferDataFailed; + } + else + { + } + + return kStatus_Success; } void SDHC_TransferCreateHandle(SDHC_Type *base, @@ -1271,40 +1328,49 @@ status_t SDHC_TransferNonBlocking( /* make sure cmd/block count is valid */ if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT))) { - error = kStatus_InvalidArgument; + return kStatus_InvalidArgument; } - else + + /* Wait until command/data bus out of busy status. */ + if ((SDHC_GetPresentStatusFlags(base) & kSDHC_CommandInhibitFlag) || + (data && (SDHC_GetPresentStatusFlags(base) & kSDHC_DataInhibitFlag))) { - /* Wait until command/data bus out of busy status. */ - if ((SDHC_GetPresentStatusFlags(base) & kSDHC_CommandInhibitFlag) || - (data && (SDHC_GetPresentStatusFlags(base) & kSDHC_DataInhibitFlag))) + return kStatus_SDHC_BusyTransferring; + } + + /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ + if (data && (NULL != admaTable)) + { + error = + SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords, + (data->rxData ? data->rxData : data->txData), (data->blockCount * data->blockSize)); + /* in this situation , we disable the DMA instead of polling transfer mode */ + if (error == kStatus_SDHC_DMADataBufferAddrNotAlign) { - error = kStatus_SDHC_BusyTransferring; + /* change to polling mode */ + dmaMode = kSDHC_DmaModeNo; + SDHC_EnableInterruptSignal(base, kSDHC_BufferReadReadyFlag | kSDHC_BufferWriteReadyFlag); + SDHC_EnableInterruptStatus(base, kSDHC_BufferReadReadyFlag | kSDHC_BufferWriteReadyFlag); + } + else if (error != kStatus_Success) + { + return error; } else { - /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ - if (data && (kStatus_Success != SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords, - (data->rxData ? data->rxData : data->txData), - (data->blockCount * data->blockSize)))) - { - error = kStatus_SDHC_PrepareAdmaDescriptorFailed; - } - else - { - /* Save command and data into handle before transferring. */ - handle->command = command; - handle->data = data; - handle->interruptFlags = 0U; - /* transferredWords will only be updated in ISR when transfer way is DATAPORT. */ - handle->transferredWords = 0U; - - SDHC_StartTransfer(base, command, data); - } } } - return error; + /* Save command and data into handle before transferring. */ + handle->command = command; + handle->data = data; + handle->interruptFlags = 0U; + /* transferredWords will only be updated in ISR when transfer way is DATAPORT. */ + handle->transferredWords = 0U; + + SDHC_StartTransfer(base, command, data, dmaMode); + + return kStatus_Success; } void SDHC_TransferHandleIRQ(SDHC_Type *base, sdhc_handle_t *handle) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdhc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdhc.h index 4976649d91..336b9618e5 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdhc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdhc.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,14 +12,14 @@ * 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 + * 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 SL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * 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 @@ -43,8 +43,8 @@ /*! @name Driver version */ /*@{*/ -/*! @brief Driver version 2.1.2. */ -#define FSL_SDHC_DRIVER_VERSION (MAKE_VERSION(2U, 1U, 2U)) +/*! @brief Driver version 2.1.5. */ +#define FSL_SDHC_DRIVER_VERSION (MAKE_VERSION(2U, 1U, 5U)) /*@}*/ /*! @brief Maximum block count can be set one time */ @@ -57,6 +57,8 @@ enum _sdhc_status kStatus_SDHC_PrepareAdmaDescriptorFailed = MAKE_STATUS(kStatusGroup_SDHC, 1U), /*!< Set DMA descriptor failed */ kStatus_SDHC_SendCommandFailed = MAKE_STATUS(kStatusGroup_SDHC, 2U), /*!< Send command failed */ kStatus_SDHC_TransferDataFailed = MAKE_STATUS(kStatusGroup_SDHC, 3U), /*!< Transfer data failed */ + kStatus_SDHC_DMADataBufferAddrNotAlign = + MAKE_STATUS(kStatusGroup_SDHC, 4U), /*!< data buffer addr not align in DMA mode */ }; /*! @brief Host controller capabilities flag mask */ @@ -282,32 +284,32 @@ typedef enum _sdhc_boot_mode } sdhc_boot_mode_t; /*! @brief The command type */ -typedef enum _sdhc_command_type +typedef enum _sdhc_card_command_type { - kSDHC_CommandTypeNormal = 0U, /*!< Normal command */ - kSDHC_CommandTypeSuspend = 1U, /*!< Suspend command */ - kSDHC_CommandTypeResume = 2U, /*!< Resume command */ - kSDHC_CommandTypeAbort = 3U, /*!< Abort command */ -} sdhc_command_type_t; + kCARD_CommandTypeNormal = 0U, /*!< Normal command */ + kCARD_CommandTypeSuspend = 1U, /*!< Suspend command */ + kCARD_CommandTypeResume = 2U, /*!< Resume command */ + kCARD_CommandTypeAbort = 3U, /*!< Abort command */ +} sdhc_card_command_type_t; /*! * @brief The command response type. * * Define the command response type from card to host controller. */ -typedef enum _sdhc_response_type +typedef enum _sdhc_card_response_type { - kSDHC_ResponseTypeNone = 0U, /*!< Response type: none */ - kSDHC_ResponseTypeR1 = 1U, /*!< Response type: R1 */ - kSDHC_ResponseTypeR1b = 2U, /*!< Response type: R1b */ - kSDHC_ResponseTypeR2 = 3U, /*!< Response type: R2 */ - kSDHC_ResponseTypeR3 = 4U, /*!< Response type: R3 */ - kSDHC_ResponseTypeR4 = 5U, /*!< Response type: R4 */ - kSDHC_ResponseTypeR5 = 6U, /*!< Response type: R5 */ - kSDHC_ResponseTypeR5b = 7U, /*!< Response type: R5b */ - kSDHC_ResponseTypeR6 = 8U, /*!< Response type: R6 */ - kSDHC_ResponseTypeR7 = 9U, /*!< Response type: R7 */ -} sdhc_response_type_t; + kCARD_ResponseTypeNone = 0U, /*!< Response type: none */ + kCARD_ResponseTypeR1 = 1U, /*!< Response type: R1 */ + kCARD_ResponseTypeR1b = 2U, /*!< Response type: R1b */ + kCARD_ResponseTypeR2 = 3U, /*!< Response type: R2 */ + kCARD_ResponseTypeR3 = 4U, /*!< Response type: R3 */ + kCARD_ResponseTypeR4 = 5U, /*!< Response type: R4 */ + kCARD_ResponseTypeR5 = 6U, /*!< Response type: R5 */ + kCARD_ResponseTypeR5b = 7U, /*!< Response type: R5b */ + kCARD_ResponseTypeR6 = 8U, /*!< Response type: R6 */ + kCARD_ResponseTypeR7 = 9U, /*!< Response type: R7 */ +} sdhc_card_response_type_t; /*! @brief The alignment size for ADDRESS filed in ADMA1's descriptor */ #define SDHC_ADMA1_ADDRESS_ALIGN (4096U) @@ -477,7 +479,8 @@ typedef struct _sdhc_config * @brief Card data descriptor * * Defines a structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card - * driver want to ignore the error event to read/write all the data not to stop read/write immediately when error event + * driver + * want to ignore the error event to read/write all the data not to stop read/write immediately when error event * happen for example bus testing procedure for MMC card. */ typedef struct _sdhc_data @@ -497,11 +500,13 @@ typedef struct _sdhc_data */ typedef struct _sdhc_command { - uint32_t index; /*!< Command index */ - uint32_t argument; /*!< Command argument */ - sdhc_command_type_t type; /*!< Command type */ - sdhc_response_type_t responseType; /*!< Command response type */ - uint32_t response[4U]; /*!< Response for this command */ + uint32_t index; /*!< Command index */ + uint32_t argument; /*!< Command argument */ + sdhc_card_command_type_t type; /*!< Command type */ + sdhc_card_response_type_t responseType; /*!< Command response type */ + uint32_t response[4U]; /*!< Response for this command */ + uint32_t responseErrorFlags; /*!< response error flag, the flag which need to check + the command reponse*/ } sdhc_command_t; /*! @brief Transfer state */ @@ -829,7 +834,8 @@ static inline void SDHC_SetDataBusWidth(SDHC_Type *base, sdhc_data_bus_width_t w * @brief Sets the card transfer-related configuration. * * This function fills the card transfer-related command argument/transfer flag/data size. The command and data are sent - * by SDHC after calling this function. + by + * SDHC after calling this function. * * Example: @code @@ -929,7 +935,8 @@ static inline void SDHC_EnableCardDetectTest(SDHC_Type *base, bool enable) * * This function sets the card detection test level to indicate whether the card is inserted into the SDHC when DAT[3]/ * CD pin is selected as a card detection pin. This function can also assert the pin logic when DAT[3]/CD pin is - * selected as the card detection pin. + * selected + * as the card detection pin. * * @param base SDHC peripheral base address. * @param high True to set the card detect level to high. @@ -1007,7 +1014,10 @@ static inline void SDHC_SetForceEvent(SDHC_Type *base, uint32_t mask) * @brief Transfers the command/data using a blocking method. * * This function waits until the command response/data is received or the SDHC encounters an error by polling the status - * flag. The application must not call this API in multiple threads at the same time. Because of that this API doesn't support + * flag. + * This function support non word align data addr transfer support, if data buffer addr is not align in DMA mode, + * the API will continue finish the transfer by polling IO directly + * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support * the re-entry mechanism. * * @note There is no need to call the API 'SDHC_TransferCreateHandle' when calling this API. @@ -1044,7 +1054,10 @@ void SDHC_TransferCreateHandle(SDHC_Type *base, * @brief Transfers the command/data using an interrupt and an asynchronous method. * * This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an - * error. The application must not call this API in multiple threads at the same time. Because of that this API doesn't support + * error. + * This function support non word align data addr transfer support, if data buffer addr is not align in DMA mode, + * the API will continue finish the transfer by polling IO directly + * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support * the re-entry mechanism. * * @note Call the API 'SDHC_TransferCreateHandle' when calling this API. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdramc.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdramc.c index ad672cfd60..baf432ed8b 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdramc.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdramc.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,7 +37,6 @@ /*! @brief Define macros for SDRAM driver. */ #define SDRAMC_ONEMILLSEC_NANOSECONDS (1000000U) #define SDRAMC_ONESECOND_MILLISECONDS (1000U) -#define SDRAMC_TIMEOUT_COUNT (0xFFFFU) /******************************************************************************* * Prototypes @@ -53,8 +52,10 @@ static uint32_t SDRAMC_GetInstance(SDRAM_Type *base); * Variables ******************************************************************************/ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to SDRAMC clocks for each instance. */ -const clock_ip_name_t s_sdramClock[FSL_FEATURE_SOC_SDRAM_COUNT] = SDRAM_CLOCKS; +static const clock_ip_name_t s_sdramClock[FSL_FEATURE_SOC_SDRAM_COUNT] = SDRAM_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /*! @brief Pointers to SDRAMC bases for each instance. */ static SDRAM_Type *const s_sdramcBases[] = SDRAM_BASE_PTRS; @@ -67,7 +68,7 @@ static uint32_t SDRAMC_GetInstance(SDRAM_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_SDRAM_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_sdramcBases); instance++) { if (s_sdramcBases[instance] == base) { @@ -75,7 +76,7 @@ static uint32_t SDRAMC_GetInstance(SDRAM_Type *base) } } - assert(instance < FSL_FEATURE_SOC_SDRAM_COUNT); + assert(instance < ARRAY_SIZE(s_sdramcBases)); return instance; } @@ -92,8 +93,10 @@ void SDRAMC_Init(SDRAM_Type *base, sdramc_config_t *configure) uint32_t count; uint32_t index; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Un-gate sdram controller clock. */ CLOCK_EnableClock(s_sdramClock[SDRAMC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Initialize sdram Auto refresh timing. */ count = refreshConfig->sdramRefreshRow * (refreshConfig->busClock_Hz / SDRAMC_ONESECOND_MILLISECONDS); @@ -119,50 +122,23 @@ void SDRAMC_Deinit(SDRAM_Type *base) SDRAMC_EnableOperateValid(base, kSDRAMC_Block0, false); SDRAMC_EnableOperateValid(base, kSDRAMC_Block1, false); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable SDRAM clock. */ CLOCK_DisableClock(s_sdramClock[SDRAMC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } -status_t SDRAMC_SendCommand(SDRAM_Type *base, sdramc_block_selection_t block, sdramc_command_t command) +void SDRAMC_SendCommand(SDRAM_Type *base, sdramc_block_selection_t block, sdramc_command_t command) { - status_t result = kStatus_Success; - uint32_t count = SDRAMC_TIMEOUT_COUNT; - switch (command) { /* Initiate mrs command. */ case kSDRAMC_ImrsCommand: base->BLOCK[block].AC |= SDRAM_AC_IMRS_MASK; - while (count--) - { - if (!(base->BLOCK[block].AC & SDRAM_AC_IMRS_MASK)) - { - break; - } - } - - if (!count) - { - /* Timeout the mrs command is unfinished. */ - result = kStatus_Fail; - } - break; + break; /* Initiate precharge command. */ case kSDRAMC_PrechargeCommand: base->BLOCK[block].AC |= SDRAM_AC_IP_MASK; - while (count--) - { - if (!(base->BLOCK[block].AC & SDRAM_AC_IP_MASK)) - { - break; - } - } - - /* Timeout the precharge command is unfinished. */ - if (!count) - { - result = kStatus_Fail; - } break; /* Enable Auto refresh command. */ case kSDRAMC_AutoRefreshEnableCommand: @@ -183,5 +159,4 @@ status_t SDRAMC_SendCommand(SDRAM_Type *base, sdramc_block_selection_t block, sd default: break; } - return result; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdramc.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdramc.h index 4da5ad756f..c409fe456e 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdramc.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sdramc.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,7 +37,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -45,8 +44,8 @@ /*! @name Driver version */ /*@{*/ -/*! @brief SDRAMC driver version 2.0.0. */ -#define FSL_SDRAMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*! @brief SDRAMC driver version 2.1.0. */ +#define FSL_SDRAMC_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*@}*/ /*! @brief SDRAM controller auto-refresh timing. */ @@ -60,14 +59,14 @@ typedef enum _sdramc_refresh_time /*! * @brief Setting latency for SDRAM controller timing specifications. * - * The latency setting will affects the following SDRAM timing specifications: + * The latency setting affects the following SDRAM timing specifications: * - trcd: SRAS assertion to SCAS assertion \n * - tcasl: SCAS assertion to data out \n * - tras: ACTV command to Precharge command \n * - trp: Precharge command to ACTV command \n * - trwl, trdl: Last data input to Precharge command \n * - tep: Last data out to Precharge command \n - * the details of the latency setting and timing specifications are shown on the following table list: \n + * The details of the latency setting and timing specifications are shown in the following table list. \n * latency trcd: tcasl tras trp trwl,trdl tep \n * 0 1 bus clock 1 bus clock 2 bus clocks 1 bus clock 1 bus clock 1 bus clock \n * 1 2 bus clock 2 bus clock 4 bus clocks 2 bus clock 1 bus clock 1 bus clock \n @@ -219,10 +218,10 @@ void SDRAMC_Deinit(SDRAM_Type *base); /*! * @brief Sends the SDRAM command. - * This function sends the command to SDRAM. There are precharge command, initialize MRS command, + * This function sends commands to SDRAM. The commands are precharge command, initialization MRS command, * auto-refresh enable/disable command, and self-refresh enter/exit commands. - * Note the self-refresh enter/exit commands are all blocks setting and "block" - * are ignored. Ensure to set the right "block" when send other commands. + * Note that the self-refresh enter/exit commands are all blocks setting and "block" + * is ignored. Ensure to set the correct "block" when send other commands. * * @param base SDRAM controller peripheral base address. * @param block The block selection. @@ -233,13 +232,8 @@ void SDRAMC_Deinit(SDRAM_Type *base); * kSDRAMC_SelfrefreshExitCommand - Exit self-refresh command \n * kSDRAMC_AutoRefreshEnableCommand - Enable auto refresh command \n * kSDRAMC_AutoRefreshDisableCommand - Disable auto refresh command - * @return Command execution status. - * All commands except the "initialize MRS command" and "precharge command" - * return kStatus_Success directly. - * For "initialize MRS command" and "precharge command" - * return kStatus_Success when the command success else return kStatus_Fail. */ -status_t SDRAMC_SendCommand(SDRAM_Type *base, sdramc_block_selection_t block, sdramc_command_t command); +void SDRAMC_SendCommand(SDRAM_Type *base, sdramc_block_selection_t block, sdramc_command_t command); /*! * @brief Enables/disables the write protection. @@ -261,11 +255,11 @@ static inline void SDRAMC_EnableWriteProtect(SDRAM_Type *base, sdramc_block_sele } /*! - * @brief Enables/disables the operation valid. + * @brief Enables/disables the valid operation. * * @param base SDRAM peripheral base address. * @param block The block which is selected. - * @param enable True enable the operation valid, false disable the operation valid. + * @param enable True enable the valid operation; false disable the valid operation. */ static inline void SDRAMC_EnableOperateValid(SDRAM_Type *base, sdramc_block_selection_t block, bool enable) { diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sim.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sim.c index 3a4b801b7b..ade512f030 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sim.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sim.c @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* 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. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include "fsl_sim.h" diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sim.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sim.h index a3b6918884..0a0e4fb309 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sim.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sim.h @@ -1,32 +1,32 @@ /* -* Copyright (c) 2015, Freescale Semiconductor, Inc. -* 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. -*/ + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ #ifndef _FSL_SIM_H_ #define _FSL_SIM_H_ @@ -36,7 +36,6 @@ /*! @addtogroup sim */ /*! @{*/ -/*! @file */ /******************************************************************************* * Definitions @@ -90,10 +89,10 @@ extern "C" { * @brief Sets the USB voltage regulator setting. * * This function configures whether the USB voltage regulator is enabled in - * normal RUN mode, STOP/VLPS/LLS/VLLS modes and VLPR/VLPW modes. The configurations - * are passed in as mask value of \ref _sim_usb_volt_reg_enable_mode. For example, enable + * normal RUN mode, STOP/VLPS/LLS/VLLS modes, and VLPR/VLPW modes. The configurations + * are passed in as mask value of \ref _sim_usb_volt_reg_enable_mode. For example, to enable * USB voltage regulator in RUN/VLPR/VLPW modes and disable in STOP/VLPS/LLS/VLLS mode, - * please use: + * use: * * SIM_SetUsbVoltRegulatorEnableMode(kSIM_UsbVoltRegEnable | kSIM_UsbVoltRegEnableInLowPower); * @@ -103,16 +102,16 @@ void SIM_SetUsbVoltRegulatorEnableMode(uint32_t mask); #endif /* FSL_FEATURE_SIM_OPT_HAS_USB_VOLTAGE_REGULATOR */ /*! - * @brief Get the unique identification register value. + * @brief Gets the unique identification register value. * * @param uid Pointer to the structure to save the UID value. */ void SIM_GetUniqueId(sim_uid_t *uid); /*! - * @brief Set the flash enable mode. + * @brief Sets the flash enable mode. * - * @param mode The mode to set, see \ref _sim_flash_mode for mode details. + * @param mode The mode to set; see \ref _sim_flash_mode for mode details. */ static inline void SIM_SetFlashMode(uint8_t mode) { 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 0018cf7dce..dacf193476 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,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -29,6 +29,7 @@ */ #include "fsl_smc.h" +#include "fsl_flash.h" #if (defined(FSL_FEATURE_SMC_HAS_PARAM) && FSL_FEATURE_SMC_HAS_PARAM) void SMC_GetParam(SMC_Type *base, smc_param_t *param) @@ -41,6 +42,39 @@ void SMC_GetParam(SMC_Type *base, smc_param_t *param) } #endif /* FSL_FEATURE_SMC_HAS_PARAM */ +void SMC_PreEnterStopModes(void) +{ + flash_prefetch_speculation_status_t speculationStatus = + { + kFLASH_prefetchSpeculationOptionDisable, /* Disable instruction speculation.*/ + kFLASH_prefetchSpeculationOptionDisable, /* Disable data speculation.*/ + }; + + __disable_irq(); + __ISB(); + + /* + * Before enter stop modes, the flash cache prefetch should be disabled. + * Otherwise the prefetch might be interrupted by stop, then the data and + * and instruction from flash are wrong. + */ + FLASH_PflashSetPrefetchSpeculation(&speculationStatus); +} + +void SMC_PostExitStopModes(void) +{ + flash_prefetch_speculation_status_t speculationStatus = + { + kFLASH_prefetchSpeculationOptionEnable, /* Enable instruction speculation.*/ + kFLASH_prefetchSpeculationOptionEnable, /* Enable data speculation.*/ + }; + + FLASH_PflashSetPrefetchSpeculation(&speculationStatus); + + __enable_irq(); + __ISB(); +} + status_t SMC_SetPowerModeRun(SMC_Type *base) { uint8_t reg; @@ -73,7 +107,9 @@ status_t SMC_SetPowerModeWait(SMC_Type *base) { /* configure Normal Wait mode */ SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + __DSB(); __WFI(); + __ISB(); return kStatus_Success; } @@ -101,7 +137,9 @@ 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(); /* check whether the power mode enter Stop mode succeed */ if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) @@ -148,16 +186,12 @@ status_t SMC_SetPowerModeVlpr(SMC_Type *base 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; } @@ -177,7 +211,9 @@ 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(); /* check whether the power mode enter VLPS mode succeed */ if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) @@ -231,7 +267,9 @@ 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(); /* check whether the power mode enter LLS mode succeed */ if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) @@ -345,7 +383,9 @@ 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(); /* check whether the power mode enter LLS mode succeed */ if (base->PMCTRL & SMC_PMCTRL_STOPA_MASK) 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 5149f87e34..168ce83501 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,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -36,7 +36,6 @@ /*! @addtogroup smc */ /*! @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -44,8 +43,8 @@ /*! @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.3. */ +#define FSL_SMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 3)) /*@}*/ /*! @@ -54,14 +53,14 @@ 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) @@ -107,10 +106,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 +119,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; @@ -155,7 +154,7 @@ typedef enum _smc_partial_stop_mode } smc_partial_stop_option_t; /*! - * @brief SMC configuration status + * @brief SMC configuration status. */ enum _smc_status { @@ -190,7 +189,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 +204,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 +241,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 +256,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 +273,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 +288,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 +305,45 @@ 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. + */ +static inline void SMC_PreEnterWaitModes(void) +{ + __disable_irq(); + __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. + */ +static inline void SMC_PostExitWaitModes(void) +{ + __enable_irq(); + __ISB(); +} + +/*! + * @brief Configures the system to RUN power mode. * * @param base SMC peripheral base address. * @return SMC configuration error code. @@ -315,7 +352,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 +361,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 +369,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 +379,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 +388,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 +397,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 +405,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 +416,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 +425,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 +436,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_K66F/drivers/fsl_sysmpu.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sysmpu.c new file mode 100755 index 0000000000..b89a7b20e4 --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sysmpu.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sysmpu.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +const clock_ip_name_t g_sysmpuClock[FSL_FEATURE_SOC_SYSMPU_COUNT] = SYSMPU_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Codes + ******************************************************************************/ + +void SYSMPU_Init(SYSMPU_Type *base, const sysmpu_config_t *config) +{ + assert(config); + uint8_t count; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Un-gate SYSMPU clock */ + CLOCK_EnableClock(g_sysmpuClock[0]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Initializes the regions. */ + for (count = 1; count < FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT; count++) + { + base->WORD[count][3] = 0; /* VLD/VID+PID. */ + base->WORD[count][0] = 0; /* Start address. */ + base->WORD[count][1] = 0; /* End address. */ + base->WORD[count][2] = 0; /* Access rights. */ + base->RGDAAC[count] = 0; /* Alternate access rights. */ + } + + /* SYSMPU configure. */ + while (config) + { + SYSMPU_SetRegionConfig(base, &(config->regionConfig)); + config = config->next; + } + /* Enable SYSMPU. */ + SYSMPU_Enable(base, true); +} + +void SYSMPU_Deinit(SYSMPU_Type *base) +{ + /* Disable SYSMPU. */ + SYSMPU_Enable(base, false); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the clock. */ + CLOCK_DisableClock(g_sysmpuClock[0]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void SYSMPU_GetHardwareInfo(SYSMPU_Type *base, sysmpu_hardware_info_t *hardwareInform) +{ + assert(hardwareInform); + + uint32_t cesReg = base->CESR; + + hardwareInform->hardwareRevisionLevel = (cesReg & SYSMPU_CESR_HRL_MASK) >> SYSMPU_CESR_HRL_SHIFT; + hardwareInform->slavePortsNumbers = (cesReg & SYSMPU_CESR_NSP_MASK) >> SYSMPU_CESR_NSP_SHIFT; + hardwareInform->regionsNumbers = (sysmpu_region_total_num_t)((cesReg & SYSMPU_CESR_NRGD_MASK) >> SYSMPU_CESR_NRGD_SHIFT); +} + +void SYSMPU_SetRegionConfig(SYSMPU_Type *base, const sysmpu_region_config_t *regionConfig) +{ + assert(regionConfig); + assert(regionConfig->regionNum < FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT); + + uint32_t wordReg = 0; + uint8_t msPortNum; + uint8_t regNumber = regionConfig->regionNum; + + /* The start and end address of the region descriptor. */ + base->WORD[regNumber][0] = regionConfig->startAddress; + base->WORD[regNumber][1] = regionConfig->endAddress; + + /* Set the privilege rights for master 0 ~ master 3. */ + for (msPortNum = 0; msPortNum < SYSMPU_MASTER_RWATTRIBUTE_START_PORT; msPortNum++) + { + wordReg |= SYSMPU_REGION_RWXRIGHTS_MASTER( + msPortNum, (((uint32_t)regionConfig->accessRights1[msPortNum].superAccessRights << 3U) | + (uint32_t)regionConfig->accessRights1[msPortNum].userAccessRights)); + +#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER + wordReg |= + SYSMPU_REGION_RWXRIGHTS_MASTER_PE(msPortNum, regionConfig->accessRights1[msPortNum].processIdentifierEnable); +#endif /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */ + } + +#if FSL_FEATURE_SYSMPU_MASTER_COUNT > SYSMPU_MASTER_RWATTRIBUTE_START_PORT + /* Set the normal read write rights for master 4 ~ master 7. */ + for (msPortNum = SYSMPU_MASTER_RWATTRIBUTE_START_PORT; msPortNum < FSL_FEATURE_SYSMPU_MASTER_COUNT; + msPortNum++) + { + wordReg |= SYSMPU_REGION_RWRIGHTS_MASTER(msPortNum, + ((uint32_t)regionConfig->accessRights2[msPortNum - SYSMPU_MASTER_RWATTRIBUTE_START_PORT].readEnable << 1U | + (uint32_t)regionConfig->accessRights2[msPortNum - SYSMPU_MASTER_RWATTRIBUTE_START_PORT].writeEnable)); + } +#endif /* FSL_FEATURE_SYSMPU_MASTER_COUNT > SYSMPU_MASTER_RWATTRIBUTE_START_PORT */ + + /* Set region descriptor access rights. */ + base->WORD[regNumber][2] = wordReg; + + wordReg = SYSMPU_WORD_VLD(1); +#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER + wordReg |= SYSMPU_WORD_PID(regionConfig->processIdentifier) | SYSMPU_WORD_PIDMASK(regionConfig->processIdMask); +#endif /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */ + + base->WORD[regNumber][3] = wordReg; +} + +void SYSMPU_SetRegionAddr(SYSMPU_Type *base, uint32_t regionNum, uint32_t startAddr, uint32_t endAddr) +{ + assert(regionNum < FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT); + + base->WORD[regionNum][0] = startAddr; + base->WORD[regionNum][1] = endAddr; +} + +void SYSMPU_SetRegionRwxMasterAccessRights(SYSMPU_Type *base, + uint32_t regionNum, + uint32_t masterNum, + const sysmpu_rwxrights_master_access_control_t *accessRights) +{ + assert(accessRights); + assert(regionNum < FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT); + assert(masterNum < SYSMPU_MASTER_RWATTRIBUTE_START_PORT); + + uint32_t mask = SYSMPU_REGION_RWXRIGHTS_MASTER_MASK(masterNum); + uint32_t right = base->RGDAAC[regionNum]; + +#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER + mask |= SYSMPU_REGION_RWXRIGHTS_MASTER_PE_MASK(masterNum); +#endif + + /* Build rights control value. */ + right &= ~mask; + right |= SYSMPU_REGION_RWXRIGHTS_MASTER( + masterNum, ((uint32_t)(accessRights->superAccessRights << 3U) | accessRights->userAccessRights)); +#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER + right |= SYSMPU_REGION_RWXRIGHTS_MASTER_PE(masterNum, accessRights->processIdentifierEnable); +#endif /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */ + + /* Set low master region access rights. */ + base->RGDAAC[regionNum] = right; +} + +#if FSL_FEATURE_SYSMPU_MASTER_COUNT > 4 +void SYSMPU_SetRegionRwMasterAccessRights(SYSMPU_Type *base, + uint32_t regionNum, + uint32_t masterNum, + const sysmpu_rwrights_master_access_control_t *accessRights) +{ + assert(accessRights); + assert(regionNum < FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT); + assert(masterNum >= SYSMPU_MASTER_RWATTRIBUTE_START_PORT); + assert(masterNum <= (FSL_FEATURE_SYSMPU_MASTER_COUNT - 1)); + + uint32_t mask = SYSMPU_REGION_RWRIGHTS_MASTER_MASK(masterNum); + uint32_t right = base->RGDAAC[regionNum]; + + /* Build rights control value. */ + right &= ~mask; + right |= + SYSMPU_REGION_RWRIGHTS_MASTER(masterNum, (((uint32_t)accessRights->readEnable << 1U) | accessRights->writeEnable)); + /* Set low master region access rights. */ + base->RGDAAC[regionNum] = right; +} +#endif /* FSL_FEATURE_SYSMPU_MASTER_COUNT > 4 */ + +bool SYSMPU_GetSlavePortErrorStatus(SYSMPU_Type *base, sysmpu_slave_t slaveNum) +{ + uint8_t sperr; + + sperr = ((base->CESR & SYSMPU_CESR_SPERR_MASK) >> SYSMPU_CESR_SPERR_SHIFT) & (0x1U << (FSL_FEATURE_SYSMPU_SLAVE_COUNT - slaveNum - 1)); + + return (sperr != 0) ? true : false; +} + +void SYSMPU_GetDetailErrorAccessInfo(SYSMPU_Type *base, sysmpu_slave_t slaveNum, sysmpu_access_err_info_t *errInform) +{ + assert(errInform); + + uint16_t value; + uint32_t cesReg; + + /* Error address. */ + errInform->address = base->SP[slaveNum].EAR; + + /* Error detail information. */ + value = (base->SP[slaveNum].EDR & SYSMPU_EDR_EACD_MASK) >> SYSMPU_EDR_EACD_SHIFT; + if (!value) + { + errInform->accessControl = kSYSMPU_NoRegionHit; + } + else if (!(value & (uint16_t)(value - 1))) + { + errInform->accessControl = kSYSMPU_NoneOverlappRegion; + } + else + { + errInform->accessControl = kSYSMPU_OverlappRegion; + } + + value = base->SP[slaveNum].EDR; + errInform->master = (uint32_t)((value & SYSMPU_EDR_EMN_MASK) >> SYSMPU_EDR_EMN_SHIFT); + errInform->attributes = (sysmpu_err_attributes_t)((value & SYSMPU_EDR_EATTR_MASK) >> SYSMPU_EDR_EATTR_SHIFT); + errInform->accessType = (sysmpu_err_access_type_t)((value & SYSMPU_EDR_ERW_MASK) >> SYSMPU_EDR_ERW_SHIFT); +#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER + errInform->processorIdentification = (uint8_t)((value & SYSMPU_EDR_EPID_MASK) >> SYSMPU_EDR_EPID_SHIFT); +#endif + + /* Clears error slave port bit. */ + cesReg = (base->CESR & ~SYSMPU_CESR_SPERR_MASK) | ((0x1U << (FSL_FEATURE_SYSMPU_SLAVE_COUNT - slaveNum - 1)) << SYSMPU_CESR_SPERR_SHIFT); + base->CESR = cesReg; +} diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sysmpu.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sysmpu.h new file mode 100755 index 0000000000..6341a31e9d --- /dev/null +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_sysmpu.h @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SYSMPU_H_ +#define _FSL_SYSMPU_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup sysmpu + * @{ + */ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief SYSMPU driver version 2.2.0. */ +#define FSL_SYSMPU_DRIVER_VERSION (MAKE_VERSION(2, 2, 0)) +/*@}*/ + +/*! @brief define the start master port with read and write attributes. */ +#define SYSMPU_MASTER_RWATTRIBUTE_START_PORT (4) + +/*! @brief SYSMPU the bit shift for masters with privilege rights: read write and execute. */ +#define SYSMPU_REGION_RWXRIGHTS_MASTER_SHIFT(n) (n * 6) + +/*! @brief SYSMPU masters with read, write and execute rights bit mask. */ +#define SYSMPU_REGION_RWXRIGHTS_MASTER_MASK(n) (0x1Fu << SYSMPU_REGION_RWXRIGHTS_MASTER_SHIFT(n)) + +/*! @brief SYSMPU masters with read, write and execute rights bit width. */ +#define SYSMPU_REGION_RWXRIGHTS_MASTER_WIDTH 5 + +/*! @brief SYSMPU masters with read, write and execute rights priority setting. */ +#define SYSMPU_REGION_RWXRIGHTS_MASTER(n, x) \ + (((uint32_t)(((uint32_t)(x)) << SYSMPU_REGION_RWXRIGHTS_MASTER_SHIFT(n))) & SYSMPU_REGION_RWXRIGHTS_MASTER_MASK(n)) + +/*! @brief SYSMPU masters with read, write and execute rights process enable bit shift. */ +#define SYSMPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n) (n * 6 + SYSMPU_REGION_RWXRIGHTS_MASTER_WIDTH) + +/*! @brief SYSMPU masters with read, write and execute rights process enable bit mask. */ +#define SYSMPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n) (0x1u << SYSMPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n)) + +/*! @brief SYSMPU masters with read, write and execute rights process enable setting. */ +#define SYSMPU_REGION_RWXRIGHTS_MASTER_PE(n, x) \ + (((uint32_t)(((uint32_t)(x)) << SYSMPU_REGION_RWXRIGHTS_MASTER_PE_SHIFT(n))) & SYSMPU_REGION_RWXRIGHTS_MASTER_PE_MASK(n)) + +/*! @brief SYSMPU masters with normal read write permission bit shift. */ +#define SYSMPU_REGION_RWRIGHTS_MASTER_SHIFT(n) ((n - SYSMPU_MASTER_RWATTRIBUTE_START_PORT) * 2 + 24) + +/*! @brief SYSMPU masters with normal read write rights bit mask. */ +#define SYSMPU_REGION_RWRIGHTS_MASTER_MASK(n) (0x3u << SYSMPU_REGION_RWRIGHTS_MASTER_SHIFT(n)) + +/*! @brief SYSMPU masters with normal read write rights priority setting. */ +#define SYSMPU_REGION_RWRIGHTS_MASTER(n, x) \ + (((uint32_t)(((uint32_t)(x)) << SYSMPU_REGION_RWRIGHTS_MASTER_SHIFT(n))) & SYSMPU_REGION_RWRIGHTS_MASTER_MASK(n)) + + +/*! @brief Describes the number of SYSMPU regions. */ +typedef enum _sysmpu_region_total_num +{ + kSYSMPU_8Regions = 0x0U, /*!< SYSMPU supports 8 regions. */ + kSYSMPU_12Regions = 0x1U, /*!< SYSMPU supports 12 regions. */ + kSYSMPU_16Regions = 0x2U /*!< SYSMPU supports 16 regions. */ +} sysmpu_region_total_num_t; + +/*! @brief SYSMPU slave port number. */ +typedef enum _sysmpu_slave +{ + kSYSMPU_Slave0 = 0U, /*!< SYSMPU slave port 0. */ + kSYSMPU_Slave1 = 1U, /*!< SYSMPU slave port 1. */ + kSYSMPU_Slave2 = 2U, /*!< SYSMPU slave port 2. */ + kSYSMPU_Slave3 = 3U, /*!< SYSMPU slave port 3. */ + kSYSMPU_Slave4 = 4U, /*!< SYSMPU slave port 4. */ +#if FSL_FEATURE_SYSMPU_SLAVE_COUNT > 5 + kSYSMPU_Slave5 = 5U, /*!< SYSMPU slave port 5. */ +#endif +#if FSL_FEATURE_SYSMPU_SLAVE_COUNT > 6 + kSYSMPU_Slave6 = 6U, /*!< SYSMPU slave port 6. */ +#endif +#if FSL_FEATURE_SYSMPU_SLAVE_COUNT > 7 + kSYSMPU_Slave7 = 7U, /*!< SYSMPU slave port 7. */ +#endif +} sysmpu_slave_t; + +/*! @brief SYSMPU error access control detail. */ +typedef enum _sysmpu_err_access_control +{ + kSYSMPU_NoRegionHit = 0U, /*!< No region hit error. */ + kSYSMPU_NoneOverlappRegion = 1U, /*!< Access single region error. */ + kSYSMPU_OverlappRegion = 2U /*!< Access overlapping region error. */ +} sysmpu_err_access_control_t; + +/*! @brief SYSMPU error access type. */ +typedef enum _sysmpu_err_access_type +{ + kSYSMPU_ErrTypeRead = 0U, /*!< SYSMPU error access type --- read. */ + kSYSMPU_ErrTypeWrite = 1U /*!< SYSMPU error access type --- write. */ +} sysmpu_err_access_type_t; + +/*! @brief SYSMPU access error attributes.*/ +typedef enum _sysmpu_err_attributes +{ + kSYSMPU_InstructionAccessInUserMode = 0U, /*!< Access instruction error in user mode. */ + kSYSMPU_DataAccessInUserMode = 1U, /*!< Access data error in user mode. */ + kSYSMPU_InstructionAccessInSupervisorMode = 2U, /*!< Access instruction error in supervisor mode. */ + kSYSMPU_DataAccessInSupervisorMode = 3U /*!< Access data error in supervisor mode. */ +} sysmpu_err_attributes_t; + +/*! @brief SYSMPU access rights in supervisor mode for bus master 0 ~ 3. */ +typedef enum _sysmpu_supervisor_access_rights +{ + kSYSMPU_SupervisorReadWriteExecute = 0U, /*!< Read write and execute operations are allowed in supervisor mode. */ + kSYSMPU_SupervisorReadExecute = 1U, /*!< Read and execute operations are allowed in supervisor mode. */ + kSYSMPU_SupervisorReadWrite = 2U, /*!< Read write operations are allowed in supervisor mode. */ + kSYSMPU_SupervisorEqualToUsermode = 3U /*!< Access permission equal to user mode. */ +} sysmpu_supervisor_access_rights_t; + +/*! @brief SYSMPU access rights in user mode for bus master 0 ~ 3. */ +typedef enum _sysmpu_user_access_rights +{ + kSYSMPU_UserNoAccessRights = 0U, /*!< No access allowed in user mode. */ + kSYSMPU_UserExecute = 1U, /*!< Execute operation is allowed in user mode. */ + kSYSMPU_UserWrite = 2U, /*!< Write operation is allowed in user mode. */ + kSYSMPU_UserWriteExecute = 3U, /*!< Write and execute operations are allowed in user mode. */ + kSYSMPU_UserRead = 4U, /*!< Read is allowed in user mode. */ + kSYSMPU_UserReadExecute = 5U, /*!< Read and execute operations are allowed in user mode. */ + kSYSMPU_UserReadWrite = 6U, /*!< Read and write operations are allowed in user mode. */ + kSYSMPU_UserReadWriteExecute = 7U /*!< Read write and execute operations are allowed in user mode. */ +} sysmpu_user_access_rights_t; + +/*! @brief SYSMPU hardware basic information. */ +typedef struct _sysmpu_hardware_info +{ + uint8_t hardwareRevisionLevel; /*!< Specifies the SYSMPU's hardware and definition reversion level. */ + uint8_t slavePortsNumbers; /*!< Specifies the number of slave ports connected to SYSMPU. */ + sysmpu_region_total_num_t regionsNumbers; /*!< Indicates the number of region descriptors implemented. */ +} sysmpu_hardware_info_t; + +/*! @brief SYSMPU detail error access information. */ +typedef struct _sysmpu_access_err_info +{ + uint32_t master; /*!< Access error master. */ + sysmpu_err_attributes_t attributes; /*!< Access error attributes. */ + sysmpu_err_access_type_t accessType; /*!< Access error type. */ + sysmpu_err_access_control_t accessControl; /*!< Access error control. */ + uint32_t address; /*!< Access error address. */ +#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER + uint8_t processorIdentification; /*!< Access error processor identification. */ +#endif /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */ +} sysmpu_access_err_info_t; + +/*! @brief SYSMPU read/write/execute rights control for bus master 0 ~ 3. */ +typedef struct _sysmpu_rwxrights_master_access_control +{ + sysmpu_supervisor_access_rights_t superAccessRights; /*!< Master access rights in supervisor mode. */ + sysmpu_user_access_rights_t userAccessRights; /*!< Master access rights in user mode. */ +#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER + bool processIdentifierEnable; /*!< Enables or disables process identifier. */ +#endif /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */ +} sysmpu_rwxrights_master_access_control_t; + +/*! @brief SYSMPU read/write access control for bus master 4 ~ 7. */ +typedef struct _sysmpu_rwrights_master_access_control +{ + bool writeEnable; /*!< Enables or disables write permission. */ + bool readEnable; /*!< Enables or disables read permission. */ +} sysmpu_rwrights_master_access_control_t; + +/*! + * @brief SYSMPU region configuration structure. + * + * This structure is used to configure the regionNum region. + * The accessRights1[0] ~ accessRights1[3] are used to configure the bus master + * 0 ~ 3 with the privilege rights setting. The accessRights2[0] ~ accessRights2[3] + * are used to configure the high master 4 ~ 7 with the normal read write permission. + * The master port assignment is the chip configuration. Normally, the core is the + * master 0, debugger is the master 1. + * Note that the SYSMPU assigns a priority scheme where the debugger is treated as the highest + * priority master followed by the core and then all the remaining masters. + * SYSMPU protection does not allow writes from the core to affect the "regionNum 0" start + * and end address nor the permissions associated with the debugger. It can only write + * the permission fields associated with the other masters. This protection guarantees that + * the debugger always has access to the entire address space and those rights can't + * be changed by the core or any other bus master. Prepare + * the region configuration when regionNum is 0. + */ +typedef struct _sysmpu_region_config +{ + uint32_t regionNum; /*!< SYSMPU region number, range form 0 ~ FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1. */ + uint32_t startAddress; /*!< Memory region start address. Note: bit0 ~ bit4 always be marked as 0 by SYSMPU. The actual + start address is 0-modulo-32 byte address. */ + uint32_t endAddress; /*!< Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by SYSMPU. The actual end + address is 31-modulo-32 byte address. */ + sysmpu_rwxrights_master_access_control_t accessRights1[4]; /*!< Masters with read, write and execute rights setting. */ + sysmpu_rwrights_master_access_control_t accessRights2[4]; /*!< Masters with normal read write rights setting. */ +#if FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER + uint8_t processIdentifier; /*!< Process identifier used when "processIdentifierEnable" set with true. */ + uint8_t + processIdMask; /*!< Process identifier mask. The setting bit will ignore the same bit in process identifier. */ +#endif /* FSL_FEATURE_SYSMPU_HAS_PROCESS_IDENTIFIER */ +} sysmpu_region_config_t; + +/*! + * @brief The configuration structure for the SYSMPU initialization. + * + * This structure is used when calling the SYSMPU_Init function. + */ +typedef struct _sysmpu_config +{ + sysmpu_region_config_t regionConfig; /*!< Region access permission. */ + struct _sysmpu_config *next; /*!< Pointer to the next structure. */ +} sysmpu_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes the SYSMPU with the user configuration structure. + * + * This function configures the SYSMPU module with the user-defined configuration. + * + * @param base SYSMPU peripheral base address. + * @param config The pointer to the configuration structure. + */ +void SYSMPU_Init(SYSMPU_Type *base, const sysmpu_config_t *config); + +/*! + * @brief Deinitializes the SYSMPU regions. + * + * @param base SYSMPU peripheral base address. + */ +void SYSMPU_Deinit(SYSMPU_Type *base); + +/* @}*/ + +/*! + * @name Basic Control Operations + * @{ + */ + +/*! + * @brief Enables/disables the SYSMPU globally. + * + * Call this API to enable or disable the SYSMPU module. + * + * @param base SYSMPU peripheral base address. + * @param enable True enable SYSMPU, false disable SYSMPU. + */ +static inline void SYSMPU_Enable(SYSMPU_Type *base, bool enable) +{ + if (enable) + { + /* Enable the SYSMPU globally. */ + base->CESR |= SYSMPU_CESR_VLD_MASK; + } + else + { /* Disable the SYSMPU globally. */ + base->CESR &= ~SYSMPU_CESR_VLD_MASK; + } +} + +/*! + * @brief Enables/disables the SYSMPU for a special region. + * + * When SYSMPU is enabled, call this API to disable an unused region + * of an enabled SYSMPU. Call this API to minimize the power dissipation. + * + * @param base SYSMPU peripheral base address. + * @param number SYSMPU region number. + * @param enable True enable the special region SYSMPU, false disable the special region SYSMPU. + */ +static inline void SYSMPU_RegionEnable(SYSMPU_Type *base, uint32_t number, bool enable) +{ + if (enable) + { + /* Enable the #number region SYSMPU. */ + base->WORD[number][3] |= SYSMPU_WORD_VLD_MASK; + } + else + { /* Disable the #number region SYSMPU. */ + base->WORD[number][3] &= ~SYSMPU_WORD_VLD_MASK; + } +} + +/*! + * @brief Gets the SYSMPU basic hardware information. + * + * @param base SYSMPU peripheral base address. + * @param hardwareInform The pointer to the SYSMPU hardware information structure. See "sysmpu_hardware_info_t". + */ +void SYSMPU_GetHardwareInfo(SYSMPU_Type *base, sysmpu_hardware_info_t *hardwareInform); + +/*! + * @brief Sets the SYSMPU region. + * + * Note: Due to the SYSMPU protection, the region number 0 does not allow writes from + * core to affect the start and end address nor the permissions associated with + * the debugger. It can only write the permission fields associated + * with the other masters. + * + * @param base SYSMPU peripheral base address. + * @param regionConfig The pointer to the SYSMPU user configuration structure. See "sysmpu_region_config_t". + */ +void SYSMPU_SetRegionConfig(SYSMPU_Type *base, const sysmpu_region_config_t *regionConfig); + +/*! + * @brief Sets the region start and end address. + * + * Memory region start address. Note: bit0 ~ bit4 is always marked as 0 by SYSMPU. + * The actual start address by SYSMPU is 0-modulo-32 byte address. + * Memory region end address. Note: bit0 ~ bit4 always be marked as 1 by SYSMPU. + * The end address used by the SYSMPU is 31-modulo-32 byte address. + * Note: Due to the SYSMPU protection, the startAddr and endAddr can't be + * changed by the core when regionNum is 0. + * + * @param base SYSMPU peripheral base address. + * @param regionNum SYSMPU region number. The range is from 0 to + * FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1. + * @param startAddr Region start address. + * @param endAddr Region end address. + */ +void SYSMPU_SetRegionAddr(SYSMPU_Type *base, uint32_t regionNum, uint32_t startAddr, uint32_t endAddr); + +/*! + * @brief Sets the SYSMPU region access rights for masters with read, write, and execute rights. + * The SYSMPU access rights depend on two board classifications of bus masters. + * The privilege rights masters and the normal rights masters. + * The privilege rights masters have the read, write, and execute access rights. + * Except the normal read and write rights, the execute rights are also + * allowed for these masters. The privilege rights masters normally range from + * bus masters 0 - 3. However, the maximum master number is device-specific. + * See the "SYSMPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX". + * The normal rights masters access rights control see + * "SYSMPU_SetRegionRwMasterAccessRights()". + * + * @param base SYSMPU peripheral base address. + * @param regionNum SYSMPU region number. Should range from 0 to + * FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1. + * @param masterNum SYSMPU bus master number. Should range from 0 to + * SYSMPU_PRIVILEGED_RIGHTS_MASTER_MAX_INDEX. + * @param accessRights The pointer to the SYSMPU access rights configuration. See "sysmpu_rwxrights_master_access_control_t". + */ +void SYSMPU_SetRegionRwxMasterAccessRights(SYSMPU_Type *base, + uint32_t regionNum, + uint32_t masterNum, + const sysmpu_rwxrights_master_access_control_t *accessRights); +#if FSL_FEATURE_SYSMPU_MASTER_COUNT > 4 +/*! + * @brief Sets the SYSMPU region access rights for masters with read and write rights. + * The SYSMPU access rights depend on two board classifications of bus masters. + * The privilege rights masters and the normal rights masters. + * The normal rights masters only have the read and write access permissions. + * The privilege rights access control see "SYSMPU_SetRegionRwxMasterAccessRights". + * + * @param base SYSMPU peripheral base address. + * @param regionNum SYSMPU region number. The range is from 0 to + * FSL_FEATURE_SYSMPU_DESCRIPTOR_COUNT - 1. + * @param masterNum SYSMPU bus master number. Should range from SYSMPU_MASTER_RWATTRIBUTE_START_PORT + * to ~ FSL_FEATURE_SYSMPU_MASTER_COUNT - 1. + * @param accessRights The pointer to the SYSMPU access rights configuration. See "sysmpu_rwrights_master_access_control_t". + */ +void SYSMPU_SetRegionRwMasterAccessRights(SYSMPU_Type *base, + uint32_t regionNum, + uint32_t masterNum, + const sysmpu_rwrights_master_access_control_t *accessRights); +#endif /* FSL_FEATURE_SYSMPU_MASTER_COUNT > 4 */ +/*! + * @brief Gets the numbers of slave ports where errors occur. + * + * @param base SYSMPU peripheral base address. + * @param slaveNum SYSMPU slave port number. + * @return The slave ports error status. + * true - error happens in this slave port. + * false - error didn't happen in this slave port. + */ +bool SYSMPU_GetSlavePortErrorStatus(SYSMPU_Type *base, sysmpu_slave_t slaveNum); + +/*! + * @brief Gets the SYSMPU detailed error access information. + * + * @param base SYSMPU peripheral base address. + * @param slaveNum SYSMPU slave port number. + * @param errInform The pointer to the SYSMPU access error information. See "sysmpu_access_err_info_t". + */ +void SYSMPU_GetDetailErrorAccessInfo(SYSMPU_Type *base, sysmpu_slave_t slaveNum, sysmpu_access_err_info_t *errInform); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SYSMPU_H_ */ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tpm.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tpm.c index 079c06df58..9a390a2be4 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tpm.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tpm.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -53,8 +53,10 @@ static uint32_t TPM_GetInstance(TPM_Type *base); /*! @brief Pointers to TPM bases for each instance. */ static TPM_Type *const s_tpmBases[] = TPM_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to TPM clocks for each instance. */ static const clock_ip_name_t s_tpmClocks[] = TPM_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Code @@ -82,8 +84,10 @@ void TPM_Init(TPM_Type *base, const tpm_config_t *config) { assert(config); +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Enable the module clock */ CLOCK_EnableClock(s_tpmClocks[TPM_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ #if defined(FSL_FEATURE_TPM_HAS_GLOBAL) && FSL_FEATURE_TPM_HAS_GLOBAL /* TPM reset is available on certain SoC's */ @@ -118,8 +122,10 @@ void TPM_Deinit(TPM_Type *base) { /* Stop the counter */ base->SC &= ~TPM_SC_CMOD_MASK; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate the TPM clock */ CLOCK_DisableClock(s_tpmClocks[TPM_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void TPM_GetDefaultConfig(tpm_config_t *config) @@ -162,6 +168,12 @@ status_t TPM_SetupPwm(TPM_Type *base, assert(pwmFreq_Hz); assert(numOfChnls); assert(srcClock_Hz); +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + if(mode == kTPM_CombinedPwm) + { + assert(FSL_FEATURE_TPM_COMBINE_HAS_EFFECTn(base)); + } +#endif uint32_t mod; uint32_t tpmClock = (srcClock_Hz / (1U << (base->SC & TPM_SC_PS_MASK))); @@ -169,8 +181,12 @@ status_t TPM_SetupPwm(TPM_Type *base, uint8_t i; #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL - /* Clear quadrature Decoder mode because in quadrature Decoder mode PWM doesn't operate*/ - base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + /* The TPM's QDCTRL register required to be effective */ + if( FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(base) ) + { + /* Clear quadrature Decoder mode because in quadrature Decoder mode PWM doesn't operate*/ + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } #endif switch (mode) @@ -351,6 +367,12 @@ void TPM_UpdatePwmDutycycle(TPM_Type *base, uint8_t dutyCyclePercent) { assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); +#if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE + if(currentPwmMode == kTPM_CombinedPwm) + { + assert(FSL_FEATURE_TPM_COMBINE_HAS_EFFECTn(base)); + } +#endif uint16_t cnv, mod; @@ -401,7 +423,7 @@ void TPM_UpdateChnlEdgeLevelSelect(TPM_Type *base, tpm_chnl_t chnlNumber, uint8_ /* Wait till mode change to disable channel is acknowledged */ while ((base->CONTROLS[chnlNumber].CnSC & - (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) { } @@ -424,16 +446,24 @@ void TPM_SetupInputCapture(TPM_Type *base, tpm_chnl_t chnlNumber, tpm_input_capt assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL - /* Clear quadrature Decoder mode for channel 0 or 1*/ - if ((chnlNumber == 0) || (chnlNumber == 1)) + /* The TPM's QDCTRL register required to be effective */ + if( FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(base) ) { - base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + /* Clear quadrature Decoder mode for channel 0 or 1*/ + if ((chnlNumber == 0) || (chnlNumber == 1)) + { + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } } #endif #if defined(FSL_FEATURE_TPM_HAS_COMBINE) && FSL_FEATURE_TPM_HAS_COMBINE - /* Clear the combine bit for chnlNumber */ - base->COMBINE &= ~(1U << TPM_COMBINE_SHIFT * (chnlNumber / 2)); + /* The TPM's COMBINE register required to be effective */ + if( FSL_FEATURE_TPM_COMBINE_HAS_EFFECTn(base) ) + { + /* Clear the combine bit for chnlNumber */ + base->COMBINE &= ~(1U << TPM_COMBINE_SHIFT * (chnlNumber / 2)); + } #endif /* When switching mode, disable channel first */ @@ -464,10 +494,14 @@ void TPM_SetupOutputCompare(TPM_Type *base, assert(chnlNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base)); #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL - /* Clear quadrature Decoder mode for channel 0 or 1 */ - if ((chnlNumber == 0) || (chnlNumber == 1)) + /* The TPM's QDCTRL register required to be effective */ + if( FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(base) ) { - base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + /* Clear quadrature Decoder mode for channel 0 or 1 */ + if ((chnlNumber == 0) || (chnlNumber == 1)) + { + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } } #endif @@ -502,13 +536,19 @@ void TPM_SetupDualEdgeCapture(TPM_Type *base, { assert(edgeParam); assert(chnlPairNumber < FSL_FEATURE_TPM_CHANNEL_COUNTn(base) / 2); + assert(FSL_FEATURE_TPM_COMBINE_HAS_EFFECTn(base)); uint32_t reg; -/* Clear quadrature Decoder mode for channel 0 or 1*/ + #if defined(FSL_FEATURE_TPM_HAS_QDCTRL) && FSL_FEATURE_TPM_HAS_QDCTRL - if (chnlPairNumber == 0) + /* The TPM's QDCTRL register required to be effective */ + if( FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(base) ) { - base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + /* Clear quadrature Decoder mode for channel 0 or 1*/ + if (chnlPairNumber == 0) + { + base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK; + } } #endif @@ -518,7 +558,7 @@ void TPM_SetupDualEdgeCapture(TPM_Type *base, /* Wait till mode change to disable channel is acknowledged */ while ((base->CONTROLS[chnlPairNumber * 2].CnSC & - (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) { } @@ -527,7 +567,7 @@ void TPM_SetupDualEdgeCapture(TPM_Type *base, /* Wait till mode change to disable channel is acknowledged */ while ((base->CONTROLS[chnlPairNumber * 2 + 1].CnSC & - (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) + (TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK))) { } @@ -589,6 +629,7 @@ void TPM_SetupQuadDecode(TPM_Type *base, { assert(phaseAParams); assert(phaseBParams); + assert(FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(base)); base->CONTROLS[0].CnSC &= ~(TPM_CnSC_MSA_MASK | TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK); diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tpm.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tpm.h index a15e44c1fb..a1694b37d3 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tpm.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tpm.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,8 +37,6 @@ * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ @@ -525,6 +523,47 @@ static inline void TPM_ClearStatusFlags(TPM_Type *base, uint32_t mask) /*! @}*/ +/*! + * @name Read and write the timer period + * @{ + */ + +/*! + * @brief Sets the timer period in units of ticks. + * + * Timers counts from 0 until it equals the count value set here. The count value is written to + * the MOD register. + * + * @note + * 1. This API allows the user to use the TPM module as a timer. Do not mix usage + * of this API with TPM's PWM setup API's. + * 2. Call the utility macros provided in the fsl_common.h to convert usec or msec to ticks. + * + * @param base TPM peripheral base address + * @param ticks A timer period in units of ticks, which should be equal or greater than 1. + */ +static inline void TPM_SetTimerPeriod(TPM_Type *base, uint32_t ticks) +{ + base->MOD = ticks; +} + +/*! + * @brief Reads the current timer counting value. + * + * This function returns the real-time timer counting value in a range from 0 to a + * timer period. + * + * @note Call the utility macros provided in the fsl_common.h to convert ticks to usec or msec. + * + * @param base TPM peripheral base address + * + * @return The current counter value in ticks + */ +static inline uint32_t TPM_GetCurrentTimerCount(TPM_Type *base) +{ + return (uint32_t)((base->CNT & TPM_CNT_COUNT_MASK) >> TPM_CNT_COUNT_SHIFT); +} + /*! * @name Timer Start and Stop * @{ diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tsi_v4.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tsi_v4.c index 6acb64e7e0..c299c90f63 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tsi_v4.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tsi_v4.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -36,7 +36,9 @@ void TSI_Init(TSI_Type *base, const tsi_config_t *config) bool is_module_enabled = false; bool is_int_enabled = false; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_EnableClock(kCLOCK_Tsi0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ if (base->GENCS & TSI_GENCS_TSIEN_MASK) { is_module_enabled = true; @@ -47,18 +49,31 @@ void TSI_Init(TSI_Type *base, const tsi_config_t *config) is_int_enabled = true; TSI_DisableInterrupts(base, kTSI_GlobalInterruptEnable); } - - TSI_SetHighThreshold(base, config->thresh); - TSI_SetLowThreshold(base, config->thresl); - TSI_SetElectrodeOSCPrescaler(base, config->prescaler); - TSI_SetReferenceChargeCurrent(base, config->refchrg); - TSI_SetElectrodeChargeCurrent(base, config->extchrg); - TSI_SetNumberOfScans(base, config->nscn); - TSI_SetAnalogMode(base, config->mode); - TSI_SetOscVoltageRails(base, config->dvolt); - TSI_SetElectrodeSeriesResistor(base, config->resistor); - TSI_SetFilterBits(base, config->filter); - + + if(config->mode == kTSI_AnalogModeSel_Capacitive) + { + TSI_SetHighThreshold(base, config->thresh); + TSI_SetLowThreshold(base, config->thresl); + TSI_SetElectrodeOSCPrescaler(base, config->prescaler); + TSI_SetReferenceChargeCurrent(base, config->refchrg); + TSI_SetElectrodeChargeCurrent(base, config->extchrg); + TSI_SetNumberOfScans(base, config->nscn); + TSI_SetAnalogMode(base, config->mode); + TSI_SetOscVoltageRails(base, config->dvolt); + } + else /* For noise modes */ + { + TSI_SetHighThreshold(base, config->thresh); + TSI_SetLowThreshold(base, config->thresl); + TSI_SetElectrodeOSCPrescaler(base, config->prescaler); + TSI_SetReferenceChargeCurrent(base, config->refchrg); + TSI_SetNumberOfScans(base, config->nscn); + TSI_SetAnalogMode(base, config->mode); + TSI_SetOscVoltageRails(base, config->dvolt); + TSI_SetElectrodeSeriesResistor(base, config->resistor); + TSI_SetFilterBits(base, config->filter); + } + if (is_module_enabled) { TSI_EnableModule(base, true); @@ -74,7 +89,9 @@ void TSI_Deinit(TSI_Type *base) base->GENCS = 0U; base->DATA = 0U; base->TSHD = 0U; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) CLOCK_DisableClock(kCLOCK_Tsi0); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void TSI_GetNormalModeDefaultConfig(tsi_config_t *userConfig) @@ -82,13 +99,11 @@ void TSI_GetNormalModeDefaultConfig(tsi_config_t *userConfig) userConfig->thresh = 0U; userConfig->thresl = 0U; userConfig->prescaler = kTSI_ElecOscPrescaler_2div; - userConfig->extchrg = kTSI_ExtOscChargeCurrent_4uA; + userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA; userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA; userConfig->nscn = kTSI_ConsecutiveScansNumber_5time; userConfig->mode = kTSI_AnalogModeSel_Capacitive; userConfig->dvolt = kTSI_OscVolRailsOption_0; - userConfig->resistor = kTSI_SeriesResistance_32k; - userConfig->filter = kTSI_FilterBits_3; } void TSI_GetLowPowerModeDefaultConfig(tsi_config_t *userConfig) @@ -96,13 +111,11 @@ void TSI_GetLowPowerModeDefaultConfig(tsi_config_t *userConfig) userConfig->thresh = 400U; userConfig->thresl = 0U; userConfig->prescaler = kTSI_ElecOscPrescaler_2div; - userConfig->extchrg = kTSI_ExtOscChargeCurrent_4uA; + userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA; userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA; userConfig->nscn = kTSI_ConsecutiveScansNumber_5time; userConfig->mode = kTSI_AnalogModeSel_Capacitive; userConfig->dvolt = kTSI_OscVolRailsOption_0; - userConfig->resistor = kTSI_SeriesResistance_32k; - userConfig->filter = kTSI_FilterBits_3; } void TSI_Calibrate(TSI_Type *base, tsi_calibration_data_t *calBuff) @@ -135,44 +148,56 @@ void TSI_Calibrate(TSI_Type *base, tsi_calibration_data_t *calBuff) void TSI_EnableInterrupts(TSI_Type *base, uint32_t mask) { + uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK); + if (mask & kTSI_GlobalInterruptEnable) { - base->GENCS |= TSI_GENCS_TSIIEN_MASK; + regValue |= TSI_GENCS_TSIIEN_MASK; } if (mask & kTSI_OutOfRangeInterruptEnable) { - base->GENCS &= ~TSI_GENCS_ESOR_MASK; + regValue &= (~TSI_GENCS_ESOR_MASK); } if (mask & kTSI_EndOfScanInterruptEnable) { - base->GENCS |= TSI_GENCS_ESOR_MASK; + regValue |= TSI_GENCS_ESOR_MASK; } + + base->GENCS = regValue; /* write value to register */ } void TSI_DisableInterrupts(TSI_Type *base, uint32_t mask) { + uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK); + if (mask & kTSI_GlobalInterruptEnable) { - base->GENCS &= ~TSI_GENCS_TSIIEN_MASK; + regValue &= (~TSI_GENCS_TSIIEN_MASK); } if (mask & kTSI_OutOfRangeInterruptEnable) { - base->GENCS |= TSI_GENCS_ESOR_MASK; + regValue |= TSI_GENCS_ESOR_MASK; } if (mask & kTSI_EndOfScanInterruptEnable) { - base->GENCS &= ~TSI_GENCS_ESOR_MASK; + regValue &= (~TSI_GENCS_ESOR_MASK); } + + base->GENCS = regValue; /* write value to register */ } void TSI_ClearStatusFlags(TSI_Type *base, uint32_t mask) { + uint32_t regValue = base->GENCS & (~ALL_FLAGS_MASK); + if (mask & kTSI_EndOfScanFlag) { - base->GENCS = (base->GENCS & ~(TSI_GENCS_EOSF_MASK | TSI_GENCS_OUTRGF_MASK)) | TSI_GENCS_EOSF_MASK; + regValue |= TSI_GENCS_EOSF_MASK; } if (mask & kTSI_OutOfRangeFlag) { - base->GENCS = (base->GENCS & ~(TSI_GENCS_EOSF_MASK | TSI_GENCS_OUTRGF_MASK)) | TSI_GENCS_OUTRGF_MASK; + regValue |= TSI_GENCS_OUTRGF_MASK; } + + base->GENCS = regValue; /* write value to register */ } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tsi_v4.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tsi_v4.h index d389a4d505..3c204807db 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tsi_v4.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_tsi_v4.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,7 +37,6 @@ * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -45,10 +44,13 @@ /*! @name Driver version */ /*@{*/ -/*! @brief TSI driver version 2.0.0. */ -#define FSL_TSI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*! @brief TSI driver version */ +#define FSL_TSI_DRIVER_VERSION (MAKE_VERSION(2, 1, 2)) /*@}*/ +/*! @brief TSI status flags macro collection */ +#define ALL_FLAGS_MASK (TSI_GENCS_EOSF_MASK | TSI_GENCS_OUTRGF_MASK) + /*! @brief resistor bit shift in EXTCHRG bit-field */ #define TSI_V4_EXTCHRG_RESISTOR_BIT_SHIFT TSI_GENCS_EXTCHRG_SHIFT @@ -57,11 +59,11 @@ /*! @brief macro of clearing the resistor bit in EXTCHRG bit-field */ #define TSI_V4_EXTCHRG_RESISTOR_BIT_CLEAR \ - ((uint32_t)((~TSI_GENCS_EXTCHRG_MASK) | (3U << TSI_V4_EXTCHRG_FILTER_BITS_SHIFT))) + ((uint32_t)((~(ALL_FLAGS_MASK | TSI_GENCS_EXTCHRG_MASK)) | (3U << TSI_V4_EXTCHRG_FILTER_BITS_SHIFT))) /*! @brief macro of clearing the filter bits in EXTCHRG bit-field */ #define TSI_V4_EXTCHRG_FILTER_BITS_CLEAR \ - ((uint32_t)((~TSI_GENCS_EXTCHRG_MASK) | (1U << TSI_V4_EXTCHRG_RESISTOR_BIT_SHIFT))) + ((uint32_t)((~(ALL_FLAGS_MASK | TSI_GENCS_EXTCHRG_MASK)) | (1U << TSI_V4_EXTCHRG_RESISTOR_BIT_SHIFT))) /*! * @brief TSI number of scan intervals for each electrode. @@ -286,13 +288,11 @@ void TSI_Deinit(TSI_Type *base); * The user configure is set to these values: * @code userConfig->prescaler = kTSI_ElecOscPrescaler_2div; - userConfig->extchrg = kTSI_ExtOscChargeCurrent_4uA; + userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA; userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA; userConfig->nscn = kTSI_ConsecutiveScansNumber_10time; userConfig->mode = kTSI_AnalogModeSel_Capacitive; userConfig->dvolt = kTSI_OscVolRailsOption_0; - userConfig->resistor = kTSI_SeriesResistance_32k; - userConfig->filter = kTSI_FilterBits_1; userConfig->thresh = 0U; userConfig->thresl = 0U; @endcode @@ -308,13 +308,11 @@ void TSI_GetNormalModeDefaultConfig(tsi_config_t *userConfig); * The user configure is set to these values: * @code userConfig->prescaler = kTSI_ElecOscPrescaler_2div; - userConfig->extchrg = kTSI_ExtOscChargeCurrent_4uA; + userConfig->extchrg = kTSI_ExtOscChargeCurrent_500nA; userConfig->refchrg = kTSI_RefOscChargeCurrent_4uA; userConfig->nscn = kTSI_ConsecutiveScansNumber_10time; userConfig->mode = kTSI_AnalogModeSel_Capacitive; userConfig->dvolt = kTSI_OscVolRailsOption_0; - userConfig->resistor = kTSI_SeriesResistance_32k; - userConfig->filter = kTSI_FilterBits_1; userConfig->thresh = 400U; userConfig->thresl = 0U; @endcode @@ -417,7 +415,7 @@ static inline bool TSI_IsScanInProgress(TSI_Type *base) */ static inline void TSI_SetElectrodeOSCPrescaler(TSI_Type *base, tsi_electrode_osc_prescaler_t prescaler) { - base->GENCS = ((base->GENCS) & ~TSI_GENCS_PS_MASK) | (TSI_GENCS_PS(prescaler)); + base->GENCS = (base->GENCS & ~(TSI_GENCS_PS_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_PS(prescaler)); } /*! @@ -429,7 +427,7 @@ static inline void TSI_SetElectrodeOSCPrescaler(TSI_Type *base, tsi_electrode_os */ static inline void TSI_SetNumberOfScans(TSI_Type *base, tsi_n_consecutive_scans_t number) { - base->GENCS = ((base->GENCS) & ~TSI_GENCS_NSCN_MASK) | (TSI_GENCS_NSCN(number)); + base->GENCS = (base->GENCS & ~(TSI_GENCS_NSCN_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_NSCN(number)); } /*! @@ -445,11 +443,11 @@ static inline void TSI_EnableModule(TSI_Type *base, bool enable) { if (enable) { - base->GENCS |= TSI_GENCS_TSIEN_MASK; /* Enable module */ + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) | TSI_GENCS_TSIEN_MASK; /* Enable module */ } else { - base->GENCS &= ~TSI_GENCS_TSIEN_MASK; /* Disable module */ + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) & (~TSI_GENCS_TSIEN_MASK); /* Disable module */ } } @@ -467,11 +465,11 @@ static inline void TSI_EnableLowPower(TSI_Type *base, bool enable) { if (enable) { - base->GENCS |= TSI_GENCS_STPE_MASK; /* Module enabled in low power stop modes */ + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) | TSI_GENCS_STPE_MASK; /* Module enabled in low power stop modes */ } else { - base->GENCS &= ~TSI_GENCS_STPE_MASK; /* Module disabled in low power stop modes */ + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) & (~TSI_GENCS_STPE_MASK); /* Module disabled in low power stop modes */ } } @@ -488,11 +486,11 @@ static inline void TSI_EnableHardwareTriggerScan(TSI_Type *base, bool enable) { if (enable) { - base->GENCS |= TSI_GENCS_STM_MASK; /* Enable hardware trigger scan */ + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) | TSI_GENCS_STM_MASK; /* Enable hardware trigger scan */ } else { - base->GENCS &= ~TSI_GENCS_STM_MASK; /* Enable software trigger scan */ + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) & (~TSI_GENCS_STM_MASK); /* Enable software trigger scan */ } } @@ -567,12 +565,12 @@ static inline void TSI_EnableEndOfScanDmaTransferOnly(TSI_Type *base, bool enabl { if (enable) { - base->GENCS |= TSI_GENCS_EOSDMEO_MASK; /* Enable End of Scan DMA transfer request only; */ + base->GENCS = (base->GENCS & ~ALL_FLAGS_MASK) | TSI_GENCS_EOSDMEO_MASK; /* Enable End of Scan DMA transfer request only; */ } else { - base->GENCS &= - ~TSI_GENCS_EOSDMEO_MASK; /* Both End-of-Scan and Out-of-Range can generate DMA transfer request. */ + base->GENCS = + (base->GENCS & ~ALL_FLAGS_MASK) & (~TSI_GENCS_EOSDMEO_MASK); /* Both End-of-Scan and Out-of-Range can generate DMA transfer request. */ } } #endif /* End of (FSL_FEATURE_TSI_HAS_END_OF_SCAN_DMA_ENABLE == 1)*/ @@ -625,7 +623,7 @@ static inline void TSI_SetHighThreshold(TSI_Type *base, uint16_t high_threshold) */ static inline void TSI_SetAnalogMode(TSI_Type *base, tsi_analog_mode_t mode) { - base->GENCS = ((base->GENCS) & ~TSI_GENCS_MODE_MASK) | (TSI_GENCS_MODE(mode)); + base->GENCS = (base->GENCS & ~(TSI_GENCS_MODE_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_MODE(mode)); } /*! @@ -648,7 +646,7 @@ static inline uint8_t TSI_GetNoiseModeResult(TSI_Type *base) */ static inline void TSI_SetReferenceChargeCurrent(TSI_Type *base, tsi_reference_osc_charge_current_t current) { - base->GENCS = ((base->GENCS) & ~TSI_GENCS_REFCHRG_MASK) | (TSI_GENCS_REFCHRG(current)); + base->GENCS = (base->GENCS & ~(TSI_GENCS_REFCHRG_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_REFCHRG(current)); } /*! @@ -660,7 +658,7 @@ static inline void TSI_SetReferenceChargeCurrent(TSI_Type *base, tsi_reference_o */ static inline void TSI_SetElectrodeChargeCurrent(TSI_Type *base, tsi_external_osc_charge_current_t current) { - base->GENCS = ((base->GENCS) & ~TSI_GENCS_EXTCHRG_MASK) | (TSI_GENCS_EXTCHRG(current)); + base->GENCS = (base->GENCS & ~(TSI_GENCS_EXTCHRG_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_EXTCHRG(current)); } /*! @@ -672,7 +670,7 @@ static inline void TSI_SetElectrodeChargeCurrent(TSI_Type *base, tsi_external_os */ static inline void TSI_SetOscVoltageRails(TSI_Type *base, tsi_osc_voltage_rails_t dvolt) { - base->GENCS = ((base->GENCS) & ~TSI_GENCS_DVOLT_MASK) | (TSI_GENCS_DVOLT(dvolt)); + base->GENCS = (base->GENCS & ~(TSI_GENCS_DVOLT_MASK | ALL_FLAGS_MASK)) | (TSI_GENCS_DVOLT(dvolt)); } /*! diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart.c index b0b92399db..17d9260027 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,10 +37,12 @@ /* UART transfer state. */ enum _uart_tansfer_states { - kUART_TxIdle, /* TX idle. */ - kUART_TxBusy, /* TX busy. */ - kUART_RxIdle, /* RX idle. */ - kUART_RxBusy /* RX busy. */ + kUART_TxIdle, /* TX idle. */ + kUART_TxBusy, /* TX busy. */ + kUART_RxIdle, /* RX idle. */ + kUART_RxBusy, /* RX busy. */ + kUART_RxFramingError, /* Rx framing error */ + kUART_RxParityError /* Rx parity error */ }; /* Typedef for interrupt handler. */ @@ -138,8 +140,10 @@ static UART_Type *const s_uartBases[] = UART_BASE_PTRS; /* Array of UART IRQ number. */ static const IRQn_Type s_uartIRQ[] = UART_RX_TX_IRQS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Array of UART clock name. */ static const clock_ip_name_t s_uartClock[] = UART_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* UART ISR for transactional APIs. */ static uart_isr_t s_uartIsr; @@ -169,6 +173,8 @@ uint32_t UART_GetInstance(UART_Type *base) static size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle) { + assert(handle); + size_t size; if (handle->rxRingBufferTail > handle->rxRingBufferHead) @@ -185,6 +191,8 @@ static size_t UART_TransferGetRxRingBufferLength(uart_handle_t *handle) static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle) { + assert(handle); + bool full; if (UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) @@ -199,36 +207,72 @@ static bool UART_TransferIsRxRingBufferFull(uart_handle_t *handle) return full; } -void UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz) +status_t UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz) { assert(config); + assert(config->baudRate_Bps); #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->txFifoWatermark); assert(FSL_FEATURE_UART_FIFO_SIZEn(base) >= config->rxFifoWatermark); #endif - uint16_t sbr; - uint8_t temp; - - /* Enable uart clock */ - CLOCK_EnableClock(s_uartClock[UART_GetInstance(base)]); - - /* Disable UART TX RX before setting. */ - base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); + uint16_t sbr = 0; + uint8_t temp = 0; + uint32_t baudDiff = 0; /* Calculate the baud rate modulo divisor, sbr*/ sbr = srcClock_Hz / (config->baudRate_Bps * 16); + /* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */ + if (sbr == 0) + { + sbr = 1; + } +#if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT + /* Determine if a fractional divider is needed to fine tune closer to the + * desired baud, each value of brfa is in 1/32 increments, + * hence the multiply-by-32. */ + uint32_t tempBaud = 0; + + uint16_t brfa = (2 * srcClock_Hz / (config->baudRate_Bps)) - 32 * sbr; + + /* Calculate the baud rate based on the temporary SBR values and BRFA */ + tempBaud = (srcClock_Hz * 2 / ((sbr * 32 + brfa))); + baudDiff = + (tempBaud > config->baudRate_Bps) ? (tempBaud - config->baudRate_Bps) : (config->baudRate_Bps - tempBaud); + +#else + /* Calculate the baud rate based on the temporary SBR values */ + baudDiff = (srcClock_Hz / (sbr * 16)) - config->baudRate_Bps; + + /* Select the better value between sbr and (sbr + 1) */ + if (baudDiff > (config->baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))))) + { + baudDiff = config->baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))); + sbr++; + } +#endif + + /* next, check to see if actual baud rate is within 3% of desired baud rate + * based on the calculate SBR value */ + if (baudDiff > ((config->baudRate_Bps / 100) * 3)) + { + /* Unacceptable baud rate difference of more than 3%*/ + return kStatus_UART_BaudrateNotSupport; + } + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable uart clock */ + CLOCK_EnableClock(s_uartClock[UART_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Disable UART TX RX before setting. */ + base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); /* Write the sbr value to the BDH and BDL registers*/ base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); base->BDL = (uint8_t)sbr; #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT - /* Determine if a fractional divider is needed to fine tune closer to the - * desired baud, each value of brfa is in 1/32 increments, - * hence the multiply-by-32. */ - uint16_t brfa = (32 * srcClock_Hz / (config->baudRate_Bps * 16)) - 32 * sbr; - /* Write the brfa value to the register*/ base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); #endif @@ -274,6 +318,8 @@ void UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_H } base->C2 = temp; + + return kStatus_Success; } void UART_Deinit(UART_Type *base) @@ -292,8 +338,10 @@ void UART_Deinit(UART_Type *base) /* Disable the module. */ base->C2 = 0; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Disable uart clock */ CLOCK_DisableClock(s_uartClock[UART_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void UART_GetDefaultConfig(uart_config_t *config) @@ -313,61 +361,101 @@ void UART_GetDefaultConfig(uart_config_t *config) config->enableRx = false; } -void UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +status_t UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) { - uint16_t sbr; + assert(baudRate_Bps); + + uint16_t sbr = 0; + uint32_t baudDiff = 0; uint8_t oldCtrl; - /* Store C2 before disable Tx and Rx */ - oldCtrl = base->C2; - - /* Disable UART TX RX before setting. */ - base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); - /* Calculate the baud rate modulo divisor, sbr*/ sbr = srcClock_Hz / (baudRate_Bps * 16); - - /* Write the sbr value to the BDH and BDL registers*/ - base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); - base->BDL = (uint8_t)sbr; - + /* set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate */ + if (sbr == 0) + { + sbr = 1; + } #if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT /* Determine if a fractional divider is needed to fine tune closer to the * desired baud, each value of brfa is in 1/32 increments, * hence the multiply-by-32. */ - uint16_t brfa = (32 * srcClock_Hz / (baudRate_Bps * 16)) - 32 * sbr; + uint32_t tempBaud = 0; - /* Write the brfa value to the register*/ - base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); + uint16_t brfa = (2 * srcClock_Hz / (baudRate_Bps)) - 32 * sbr; + + /* Calculate the baud rate based on the temporary SBR values and BRFA */ + tempBaud = (srcClock_Hz * 2 / ((sbr * 32 + brfa))); + baudDiff = (tempBaud > baudRate_Bps) ? (tempBaud - baudRate_Bps) : (baudRate_Bps - tempBaud); +#else + /* Calculate the baud rate based on the temporary SBR values */ + baudDiff = (srcClock_Hz / (sbr * 16)) - baudRate_Bps; + + /* Select the better value between sbr and (sbr + 1) */ + if (baudDiff > (baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))))) + { + baudDiff = baudRate_Bps - (srcClock_Hz / (16 * (sbr + 1))); + sbr++; + } #endif - /* Restore C2. */ - base->C2 = oldCtrl; + /* next, check to see if actual baud rate is within 3% of desired baud rate + * based on the calculate SBR value */ + if (baudDiff < ((baudRate_Bps / 100) * 3)) + { + /* Store C2 before disable Tx and Rx */ + oldCtrl = base->C2; + + /* Disable UART TX RX before setting. */ + base->C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK); + + /* Write the sbr value to the BDH and BDL registers*/ + base->BDH = (base->BDH & ~UART_BDH_SBR_MASK) | (uint8_t)(sbr >> 8); + base->BDL = (uint8_t)sbr; + +#if defined(FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT) && FSL_FEATURE_UART_HAS_BAUD_RATE_FINE_ADJUST_SUPPORT + /* Write the brfa value to the register*/ + base->C4 = (base->C4 & ~UART_C4_BRFA_MASK) | (brfa & UART_C4_BRFA_MASK); +#endif + /* Restore C2. */ + base->C2 = oldCtrl; + + return kStatus_Success; + } + else + { + /* Unacceptable baud rate difference of more than 3%*/ + return kStatus_UART_BaudrateNotSupport; + } } void UART_EnableInterrupts(UART_Type *base, uint32_t mask) { + mask &= kUART_AllInterruptsEnable; + /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) */ - base->BDH |= (mask & 0xFF); - base->C2 |= ((mask >> 8) & 0xFF); - base->C3 |= ((mask >> 16) & 0xFF); + base->BDH |= mask; + base->C2 |= (mask >> 8); + base->C3 |= (mask >> 16); #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO - base->CFIFO |= ((mask >> 24) & 0xFF); + base->CFIFO |= (mask >> 24); #endif } void UART_DisableInterrupts(UART_Type *base, uint32_t mask) { + mask &= kUART_AllInterruptsEnable; + /* The interrupt mask is combined by control bits from several register: ((CFIFO<<24) | (C3<<16) | (C2<<8) |(BDH)) */ - base->BDH &= ~(mask & 0xFF); - base->C2 &= ~((mask >> 8) & 0xFF); - base->C3 &= ~((mask >> 16) & 0xFF); + base->BDH &= ~mask; + base->C2 &= ~(mask >> 8); + base->C3 &= ~(mask >> 16); #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO - base->CFIFO &= ~((mask >> 24) & 0xFF); + base->CFIFO &= ~(mask >> 24); #endif } @@ -381,7 +469,7 @@ uint32_t UART_GetEnabledInterrupts(UART_Type *base) temp |= ((uint32_t)(base->CFIFO) << 24); #endif - return temp; + return temp & kUART_AllInterruptsEnable; } uint32_t UART_GetStatusFlags(UART_Type *base) @@ -418,14 +506,24 @@ status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask) base->SFIFO = (uint8_t)(mask >> 24); #endif - if (mask & (kUART_IdleLineFlag | kUART_RxOverrunFlag | kUART_NoiseErrorFlag | kUART_FramingErrorFlag | - kUART_ParityErrorFlag)) + if (mask & (kUART_IdleLineFlag | kUART_NoiseErrorFlag | kUART_FramingErrorFlag | kUART_ParityErrorFlag)) { /* Read base->D to clear the flags. */ (void)base->S1; (void)base->D; } + if (mask & kUART_RxOverrunFlag) + { + /* Read base->D to clear the flags and Flush all data in FIFO. */ + (void)base->S1; + (void)base->D; +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ + base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; +#endif + } + /* If some flags still pending. */ if (mask & UART_GetStatusFlags(base)) { @@ -457,6 +555,8 @@ void UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length) static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t length) { + assert(data); + size_t i; /* The Non Blocking write data API assume user have ensured there is enough space in @@ -469,6 +569,8 @@ static void UART_WriteNonBlocking(UART_Type *base, const uint8_t *data, size_t l status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length) { + assert(data); + uint32_t statusFlag; while (length--) @@ -509,6 +611,8 @@ status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length) static void UART_ReadNonBlocking(UART_Type *base, uint8_t *data, size_t length) { + assert(data); + size_t i; /* The Non Blocking read data API assume user have ensured there is enough space in @@ -558,7 +662,6 @@ void UART_TransferCreateHandle(UART_Type *base, s_uartHandle[instance] = handle; s_uartIsr = UART_TransferHandleIRQ; - /* Enable interrupt in NVIC. */ EnableIRQ(s_uartIRQ[instance]); } @@ -566,17 +669,21 @@ void UART_TransferCreateHandle(UART_Type *base, void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize) { assert(handle); + assert(ringBuffer); /* Setup the ringbuffer address */ - if (ringBuffer) - { - handle->rxRingBuffer = ringBuffer; - handle->rxRingBufferSize = ringBufferSize; - handle->rxRingBufferHead = 0U; - handle->rxRingBufferTail = 0U; + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; - /* Enable the interrupt to accept the data when user need the ring buffer. */ - UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + /* Enable the interrupt to accept the data when user need the ring buffer. */ + UART_EnableInterrupts( + base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | kUART_FramingErrorInterruptEnable); + /* Enable parity error interrupt when parity mode is enable*/ + if (UART_C1_PE_MASK & base->C1) + { + UART_EnableInterrupts(base, kUART_ParityErrorInterruptEnable); } } @@ -586,7 +693,13 @@ void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle) if (handle->rxState == kUART_RxIdle) { - UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | + kUART_FramingErrorInterruptEnable); + /* Disable parity error interrupt when parity mode is enable*/ + if (UART_C1_PE_MASK & base->C1) + { + UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable); + } } handle->rxRingBuffer = NULL; @@ -597,13 +710,12 @@ void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle) status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer) { - status_t status; + assert(handle); + assert(xfer); + assert(xfer->dataSize); + assert(xfer->data); - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } + status_t status; /* Return error if current TX busy. */ if (kUART_TxBusy == handle->txState) @@ -628,6 +740,8 @@ status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, ua void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle) { + assert(handle); + UART_DisableInterrupts(base, kUART_TxDataRegEmptyInterruptEnable | kUART_TransmissionCompleteInterruptEnable); handle->txDataSize = 0; @@ -636,16 +750,14 @@ void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle) status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) { + assert(handle); + assert(count); + if (kUART_TxIdle == handle->txState) { return kStatus_NoTransferInProgress; } - if (!count) - { - return kStatus_InvalidArgument; - } - *count = handle->txDataSizeAll - handle->txDataSize; return kStatus_Success; @@ -656,6 +768,11 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base, uart_transfer_t *xfer, size_t *receivedBytes) { + assert(handle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + uint32_t i; status_t status; /* How many bytes to copy from ring buffer to user memory. */ @@ -664,13 +781,6 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base, size_t bytesToReceive; /* How many bytes currently have received. */ size_t bytesCurrentReceived; - uint32_t regPrimask = 0U; - - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } /* How to get data: 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize @@ -694,8 +804,8 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base, /* If RX ring buffer is used. */ if (handle->rxRingBuffer) { - /* Disable IRQ, protect ring buffer. */ - regPrimask = DisableGlobalIRQ(); + /* Disable UART RX IRQ, protect ring buffer. */ + UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable); /* How many bytes in RX ring buffer currently. */ bytesToCopy = UART_TransferGetRxRingBufferLength(handle); @@ -733,8 +843,8 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base, handle->rxState = kUART_RxBusy; } - /* Enable IRQ if previously enabled. */ - EnableGlobalIRQ(regPrimask); + /* Enable UART RX IRQ if previously enabled. */ + UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable); /* Call user callback since all data are received. */ if (0 == bytesToReceive) @@ -753,8 +863,14 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base, handle->rxDataSizeAll = bytesToReceive; handle->rxState = kUART_RxBusy; - /* Enable RX interrupt. */ - UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + /* Enable RX/Rx overrun/framing error interrupt. */ + UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | + kUART_FramingErrorInterruptEnable); + /* Enable parity error interrupt when parity mode is enable*/ + if (UART_C1_PE_MASK & base->C1) + { + UART_EnableInterrupts(base, kUART_ParityErrorInterruptEnable); + } } /* Return the how many bytes have read. */ @@ -771,11 +887,19 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base, void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle) { + assert(handle); + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ if (!handle->rxRingBuffer) { /* Disable RX interrupt. */ - UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | + kUART_FramingErrorInterruptEnable); + /* Disable parity error interrupt when parity mode is enable*/ + if (UART_C1_PE_MASK & base->C1) + { + UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable); + } } handle->rxDataSize = 0U; @@ -784,6 +908,9 @@ void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle) status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, uint32_t *count) { + assert(handle); + assert(count); + if (kUART_RxIdle == handle->rxState) { return kStatus_NoTransferInProgress; @@ -801,17 +928,67 @@ status_t UART_TransferGetReceiveCount(UART_Type *base, uart_handle_t *handle, ui void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle) { + assert(handle); + uint8_t count; uint8_t tempCount; - assert(handle); + /* If RX framing error */ + if (UART_S1_FE_MASK & base->S1) + { + /* Read base->D to clear framing error flag, otherwise the RX does not work. */ + while (base->S1 & UART_S1_RDRF_MASK) + { + (void)base->D; + } +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ + base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; +#endif + + handle->rxState = kUART_RxFramingError; + handle->rxDataSize = 0U; + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_UART_FramingError, handle->userData); + } + } + + /* If RX parity error */ + if (UART_S1_PF_MASK & base->S1) + { + /* Read base->D to clear parity error flag, otherwise the RX does not work. */ + while (base->S1 & UART_S1_RDRF_MASK) + { + (void)base->D; + } +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ + base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; +#endif + + handle->rxState = kUART_RxParityError; + handle->rxDataSize = 0U; + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_UART_ParityError, handle->userData); + } + } /* If RX overrun. */ if (UART_S1_OR_MASK & base->S1) { - /* Read base->D, otherwise the RX does not work. */ - (void)base->D; - + /* Read base->D to clear overrun flag, otherwise the RX does not work. */ + while (base->S1 & UART_S1_RDRF_MASK) + { + (void)base->D; + } +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + /* Flush FIFO date, otherwise FIFO pointer will be in unknown state. */ + base->CFIFO |= UART_CFIFO_RXFLUSH_MASK; +#endif /* Trigger callback. */ if (handle->callback) { @@ -898,16 +1075,38 @@ void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle) } } } - /* If no receive requst pending, stop RX interrupt. */ + else if (!handle->rxDataSize) { - UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable); + /* Disable RX interrupt/overrun interrupt/fram error interrupt */ + UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | + kUART_FramingErrorInterruptEnable); + + /* Disable parity error interrupt when parity mode is enable*/ + if (UART_C1_PE_MASK & base->C1) + { + UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable); + } } else { } } + /* If framing error or parity error happened, stop the RX interrupt when ues no ring buffer */ + if (((handle->rxState == kUART_RxFramingError) || (handle->rxState == kUART_RxParityError)) && + (!handle->rxRingBuffer)) + { + UART_DisableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable | + kUART_FramingErrorInterruptEnable); + + /* Disable parity error interrupt when parity mode is enable*/ + if (UART_C1_PE_MASK & base->C1) + { + UART_DisableInterrupts(base, kUART_ParityErrorInterruptEnable); + } + } + /* Send data register empty and the interrupt is enabled. */ if ((base->S1 & UART_S1_TDRE_MASK) && (base->C2 & UART_C2_TIE_MASK)) { @@ -952,7 +1151,7 @@ void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle) void UART_TransferHandleErrorIRQ(UART_Type *base, uart_handle_t *handle) { - /* TODO: To be implemented. */ + /* To be implemented by User. */ } #if defined(UART0) @@ -992,7 +1191,6 @@ void UART2_RX_TX_DriverIRQHandler(void) { UART2_DriverIRQHandler(); } - #endif #if defined(UART3) diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart.h index 3eec4e66b5..451baa9ffd 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -37,16 +37,14 @@ * @{ */ -/*! @file */ - /******************************************************************************* * Definitions ******************************************************************************/ /*! @name Driver version */ /*@{*/ -/*! @brief UART driver version 2.1.0. */ -#define FSL_UART_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*! @brief UART driver version 2.1.4. */ +#define FSL_UART_DRIVER_VERSION (MAKE_VERSION(2, 1, 4)) /*@}*/ /*! @brief Error codes for the UART driver. */ @@ -66,6 +64,8 @@ enum _uart_status kStatus_UART_NoiseError = MAKE_STATUS(kStatusGroup_UART, 10), /*!< UART noise error. */ kStatus_UART_FramingError = MAKE_STATUS(kStatusGroup_UART, 11), /*!< UART framing error. */ kStatus_UART_ParityError = MAKE_STATUS(kStatusGroup_UART, 12), /*!< UART parity error. */ + kStatus_UART_BaudrateNotSupport = + MAKE_STATUS(kStatusGroup_UART, 13), /*!< Baudrate is not support in current clock source */ }; /*! @brief UART parity mode. */ @@ -103,10 +103,23 @@ enum _uart_interrupt_enable kUART_FramingErrorInterruptEnable = (UART_C3_FEIE_MASK << 16), /*!< Framing error flag interrupt. */ kUART_ParityErrorInterruptEnable = (UART_C3_PEIE_MASK << 16), /*!< Parity error flag interrupt. */ #if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO - kUART_RxFifoOverflowInterruptEnable = (UART_CFIFO_TXOFE_MASK << 24), /*!< TX FIFO overflow interrupt. */ - kUART_TxFifoOverflowInterruptEnable = (UART_CFIFO_RXUFE_MASK << 24), /*!< RX FIFO underflow interrupt. */ + kUART_RxFifoOverflowInterruptEnable = (UART_CFIFO_RXOFE_MASK << 24), /*!< RX FIFO overflow interrupt. */ + kUART_TxFifoOverflowInterruptEnable = (UART_CFIFO_TXOFE_MASK << 24), /*!< TX FIFO overflow interrupt. */ kUART_RxFifoUnderflowInterruptEnable = (UART_CFIFO_RXUFE_MASK << 24), /*!< RX FIFO underflow interrupt. */ #endif + kUART_AllInterruptsEnable = +#if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT + kUART_LinBreakInterruptEnable | +#endif + kUART_RxActiveEdgeInterruptEnable | kUART_TxDataRegEmptyInterruptEnable | + kUART_TransmissionCompleteInterruptEnable | kUART_RxDataRegFullInterruptEnable | kUART_IdleLineInterruptEnable | + kUART_RxOverrunInterruptEnable | kUART_NoiseErrorInterruptEnable | kUART_FramingErrorInterruptEnable | + kUART_ParityErrorInterruptEnable +#if defined(FSL_FEATURE_UART_HAS_FIFO) && FSL_FEATURE_UART_HAS_FIFO + | + kUART_RxFifoOverflowInterruptEnable | kUART_TxFifoOverflowInterruptEnable | kUART_RxFifoUnderflowInterruptEnable +#endif + , }; /*! @@ -128,13 +141,16 @@ enum _uart_flags kUART_ParityErrorFlag = (UART_S1_PF_MASK), /*!< If parity enabled, sets upon parity error detection */ #if defined(FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_UART_HAS_LIN_BREAK_DETECT kUART_LinBreakFlag = - (UART_S2_LBKDIF_MASK << 8), /*!< LIN break detect interrupt flag, sets when - LIN break char detected and LIN circuit enabled */ + (UART_S2_LBKDIF_MASK + << 8), /*!< LIN break detect interrupt flag, sets when + LIN break char detected and LIN circuit enabled */ #endif - kUART_RxActiveEdgeFlag = (UART_S2_RXEDGIF_MASK << 8), /*!< RX pin active edge interrupt flag, - sets when active edge detected */ - kUART_RxActiveFlag = (UART_S2_RAF_MASK << 8), /*!< Receiver Active Flag (RAF), - sets at beginning of valid start bit */ + kUART_RxActiveEdgeFlag = + (UART_S2_RXEDGIF_MASK << 8), /*!< RX pin active edge interrupt flag, + sets when active edge detected */ + kUART_RxActiveFlag = + (UART_S2_RAF_MASK << 8), /*!< Receiver Active Flag (RAF), + sets at beginning of valid start bit */ #if defined(FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS) && FSL_FEATURE_UART_HAS_EXTENDED_DATA_REGISTER_FLAGS kUART_NoiseErrorInRxDataRegFlag = (UART_ED_NOISY_MASK << 16), /*!< Noisy bit, sets if noise detected. */ kUART_ParityErrorInRxDataRegFlag = (UART_ED_PARITYE_MASK << 16), /*!< Paritye bit, sets if parity error detected. */ @@ -213,11 +229,11 @@ extern "C" { */ /*! - * @brief Initializes a UART instance with user configuration structure and peripheral clock. + * @brief Initializes a UART instance with a user configuration structure and peripheral clock. * * This function configures the UART module with the user-defined settings. The user can configure the configuration * structure and also get the default configuration by using the UART_GetDefaultConfig() function. - * Example below shows how to use this API to configure UART. + * The example below shows how to use this API to configure UART. * @code * uart_config_t uartConfig; * uartConfig.baudRate_Bps = 115200U; @@ -229,10 +245,12 @@ extern "C" { * @endcode * * @param base UART peripheral base address. - * @param config Pointer to user-defined configuration structure. + * @param config Pointer to the user-defined configuration structure. * @param srcClock_Hz UART clock source frequency in HZ. + * @retval kStatus_UART_BaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_Success Status UART initialize succeed */ -void UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz); +status_t UART_Init(UART_Type *base, const uart_config_t *config, uint32_t srcClock_Hz); /*! * @brief Deinitializes a UART instance. @@ -247,7 +265,7 @@ void UART_Deinit(UART_Type *base); * @brief Gets the default configuration structure. * * This function initializes the UART configuration structure to a default value. The default - * values are: + * values are as follows. * uartConfig->baudRate_Bps = 115200U; * uartConfig->bitCountPerChar = kUART_8BitsPerChar; * uartConfig->parityMode = kUART_ParityDisabled; @@ -272,9 +290,11 @@ void UART_GetDefaultConfig(uart_config_t *config); * * @param base UART peripheral base address. * @param baudRate_Bps UART baudrate to be set. - * @param srcClock_Hz UART clock source freqency in HZ. + * @param srcClock_Hz UART clock source freqency in Hz. + * @retval kStatus_UART_BaudrateNotSupport Baudrate is not support in the current clock source. + * @retval kStatus_Success Set baudrate succeeded. */ -void UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); +status_t UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); /* @} */ @@ -284,12 +304,12 @@ void UART_SetBaudRate(UART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_ */ /*! - * @brief Get UART status flags. + * @brief Gets UART status flags. * - * This function get all UART status flags, the flags are returned as the logical - * OR value of the enumerators @ref _uart_flags. To check specific status, + * This function gets all UART status flags. The flags are returned as the logical + * OR value of the enumerators @ref _uart_flags. To check a specific status, * compare the return value with enumerators in @ref _uart_flags. - * For example, to check whether the TX is empty: + * For example, to check whether the TX is empty, do the following. * @code * if (kUART_TxDataRegEmptyFlag & UART_GetStatusFlags(UART1)) * { @@ -305,19 +325,19 @@ uint32_t UART_GetStatusFlags(UART_Type *base); /*! * @brief Clears status flags with the provided mask. * - * This function clears UART status flags with a provided mask. Automatically cleared flag + * This function clears UART status flags with a provided mask. An automatically cleared flag * can't be cleared by this function. - * Some flags can only be cleared or set by hardware itself. These flags are: + * These flags can only be cleared or set by hardware. * kUART_TxDataRegEmptyFlag, kUART_TransmissionCompleteFlag, kUART_RxDataRegFullFlag, * kUART_RxActiveFlag, kUART_NoiseErrorInRxDataRegFlag, kUART_ParityErrorInRxDataRegFlag, * kUART_TxFifoEmptyFlag,kUART_RxFifoEmptyFlag - * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. + * Note that this API should be called when the Tx/Rx is idle. Otherwise it has no effect. * * @param base UART peripheral base address. - * @param mask The status flags to be cleared, it is logical OR value of @ref _uart_flags. + * @param mask The status flags to be cleared; it is logical OR value of @ref _uart_flags. * @retval kStatus_UART_FlagCannotClearManually The flag can't be cleared by this function but * it is cleared automatically by hardware. - * @retval kStatus_Success Status in the mask are cleared. + * @retval kStatus_Success Status in the mask is cleared. */ status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask); @@ -333,7 +353,7 @@ status_t UART_ClearStatusFlags(UART_Type *base, uint32_t mask); * * This function enables the UART interrupts according to the provided mask. The mask * is a logical OR of enumeration members. See @ref _uart_interrupt_enable. - * For example, to enable TX empty interrupt and RX full interrupt: + * For example, to enable TX empty interrupt and RX full interrupt, do the following. * @code * UART_EnableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); * @endcode @@ -348,7 +368,7 @@ void UART_EnableInterrupts(UART_Type *base, uint32_t mask); * * This function disables the UART interrupts according to the provided mask. The mask * is a logical OR of enumeration members. See @ref _uart_interrupt_enable. - * For example, to disable TX empty interrupt and RX full interrupt: + * For example, to disable TX empty interrupt and RX full interrupt do the following. * @code * UART_DisableInterrupts(UART1,kUART_TxDataRegEmptyInterruptEnable | kUART_RxDataRegFullInterruptEnable); * @endcode @@ -363,9 +383,9 @@ void UART_DisableInterrupts(UART_Type *base, uint32_t mask); * * This function gets the enabled UART interrupts. The enabled interrupts are returned * as the logical OR value of the enumerators @ref _uart_interrupt_enable. To check - * specific interrupts enable status, compare the return value with enumerators + * a specific interrupts enable status, compare the return value with enumerators * in @ref _uart_interrupt_enable. - * For example, to check whether TX empty interrupt is enabled: + * For example, to check whether TX empty interrupt is enabled, do the following. * @code * uint32_t enabledInterrupts = UART_GetEnabledInterrupts(UART1); * @@ -394,7 +414,7 @@ uint32_t UART_GetEnabledInterrupts(UART_Type *base); * This function returns the UART data register address, which is mainly used by DMA/eDMA. * * @param base UART peripheral base address. - * @return UART data register address which are used both by transmitter and receiver. + * @return UART data register addresses which are used both by the transmitter and the receiver. */ static inline uint32_t UART_GetDataRegisterAddress(UART_Type *base) { @@ -526,7 +546,7 @@ static inline void UART_WriteByte(UART_Type *base, uint8_t data) /*! * @brief Reads the RX register directly. * - * This function reads data from the TX register directly. The upper layer must + * This function reads data from the RX register directly. The upper layer must * ensure that the RX register is full or that the TX FIFO has data before calling this function. * * @param base UART peripheral base address. @@ -543,7 +563,7 @@ static inline uint8_t UART_ReadByte(UART_Type *base) * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO * to have room and writes data to the TX buffer. * - * @note This function does not check whether all the data has been sent out to the bus. + * @note This function does not check whether all data is sent out to the bus. * Before disabling the TX, check kUART_TransmissionCompleteFlag to ensure that the TX is * finished. * @@ -557,15 +577,15 @@ void UART_WriteBlocking(UART_Type *base, const uint8_t *data, size_t length); * @brief Read RX data register using a blocking method. * * This function polls the RX register, waits for the RX register to be full or for RX FIFO to - * have data and read data from the TX register. + * have data, and reads data from the TX register. * * @param base UART peripheral base address. * @param data Start address of the buffer to store the received data. * @param length Size of the buffer. - * @retval kStatus_UART_RxHardwareOverrun Receiver overrun happened while receiving data. - * @retval kStatus_UART_NoiseError Noise error happened while receiving data. - * @retval kStatus_UART_FramingError Framing error happened while receiving data. - * @retval kStatus_UART_ParityError Parity error happened while receiving data. + * @retval kStatus_UART_RxHardwareOverrun Receiver overrun occurred while receiving data. + * @retval kStatus_UART_NoiseError A noise error occurred while receiving data. + * @retval kStatus_UART_FramingError A framing error occurred while receiving data. + * @retval kStatus_UART_ParityError A parity error occurred while receiving data. * @retval kStatus_Success Successfully received all data. */ status_t UART_ReadBlocking(UART_Type *base, uint8_t *data, size_t length); @@ -600,16 +620,16 @@ void UART_TransferCreateHandle(UART_Type *base, * This function sets up the RX ring buffer to a specific UART handle. * * When the RX ring buffer is used, data received are stored into the ring buffer even when the - * user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received + * user doesn't call the UART_TransferReceiveNonBlocking() API. If data is already received * in the ring buffer, the user can get the received data from the ring buffer directly. * * @note When using the RX ring buffer, one byte is reserved for internal use. In other - * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data. + * words, if @p ringBufferSize is 32, only 31 bytes are used for saving data. * * @param base UART peripheral base address. * @param handle UART handle pointer. * @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer. - * @param ringBufferSize size of the ring buffer. + * @param ringBufferSize Size of the ring buffer. */ void UART_TransferStartRingBuffer(UART_Type *base, uart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize); @@ -632,23 +652,23 @@ void UART_TransferStopRingBuffer(UART_Type *base, uart_handle_t *handle); * function and passes the @ref kStatus_UART_TxIdle as status parameter. * * @note The kStatus_UART_TxIdle is passed to the upper layer when all data is written - * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX, + * to the TX register. However, it does not ensure that all data is sent out. Before disabling the TX, * check the kUART_TransmissionCompleteFlag to ensure that the TX is finished. * * @param base UART peripheral base address. * @param handle UART handle pointer. * @param xfer UART transfer structure. See #uart_transfer_t. * @retval kStatus_Success Successfully start the data transmission. - * @retval kStatus_UART_TxBusy Previous transmission still not finished, data not all written to TX register yet. + * @retval kStatus_UART_TxBusy Previous transmission still not finished; data not all written to TX register yet. * @retval kStatus_InvalidArgument Invalid argument. */ status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, uart_transfer_t *xfer); /*! - * @brief Aborts the interrupt driven data transmit. + * @brief Aborts the interrupt-driven data transmit. * - * This function aborts the interrupt driven data sending. The user can get the remainBytes to find out - * how many bytes are still not sent out. + * This function aborts the interrupt-driven data sending. The user can get the remainBytes to find out + * how many bytes are not sent out. * * @param base UART peripheral base address. * @param handle UART handle pointer. @@ -656,16 +676,16 @@ status_t UART_TransferSendNonBlocking(UART_Type *base, uart_handle_t *handle, ua void UART_TransferAbortSend(UART_Type *base, uart_handle_t *handle); /*! - * @brief Get the number of bytes that have been written to UART TX register. + * @brief Gets the number of bytes written to the UART TX register. * - * This function gets the number of bytes that have been written to UART TX - * register by interrupt method. + * This function gets the number of bytes written to the UART TX + * register by using the interrupt method. * * @param base UART peripheral base address. * @param handle UART handle pointer. * @param count Send bytes count. * @retval kStatus_NoTransferInProgress No send in progress. - * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_InvalidArgument The parameter is invalid. * @retval kStatus_Success Get successfully through the parameter \p count; */ status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint32_t *count); @@ -690,7 +710,7 @@ status_t UART_TransferGetSendCount(UART_Type *base, uart_handle_t *handle, uint3 * * @param base UART peripheral base address. * @param handle UART handle pointer. - * @param xfer UART transfer structure, refer to #uart_transfer_t. + * @param xfer UART transfer structure, see #uart_transfer_t. * @param receivedBytes Bytes received from the ring buffer directly. * @retval kStatus_Success Successfully queue the transfer into transmit queue. * @retval kStatus_UART_RxBusy Previous receive request is not finished. @@ -705,7 +725,7 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base, * @brief Aborts the interrupt-driven data receiving. * * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to know - * how many bytes not received yet. + * how many bytes are not received yet. * * @param base UART peripheral base address. * @param handle UART handle pointer. @@ -713,7 +733,7 @@ status_t UART_TransferReceiveNonBlocking(UART_Type *base, void UART_TransferAbortReceive(UART_Type *base, uart_handle_t *handle); /*! - * @brief Get the number of bytes that have been received. + * @brief Gets the number of bytes that have been received. * * This function gets the number of bytes that have been received. * @@ -739,7 +759,7 @@ void UART_TransferHandleIRQ(UART_Type *base, uart_handle_t *handle); /*! * @brief UART Error IRQ handle function. * - * This function handle the UART error IRQ request. + * This function handles the UART error IRQ request. * * @param base UART peripheral base address. * @param handle UART handle pointer. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart_edma.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart_edma.c index 3673404486..c51e493463 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart_edma.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart_edma.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -125,6 +125,8 @@ extern uint32_t UART_GetInstance(UART_Type *base); static void UART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) { + assert(param); + uart_edma_private_handle_t *uartPrivateHandle = (uart_edma_private_handle_t *)param; /* Avoid the warning for unused variables. */ @@ -145,6 +147,8 @@ static void UART_SendEDMACallback(edma_handle_t *handle, void *param, bool trans static void UART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) { + assert(param); + uart_edma_private_handle_t *uartPrivateHandle = (uart_edma_private_handle_t *)param; /* Avoid warning for unused parameters. */ @@ -165,11 +169,11 @@ static void UART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool tr } void UART_TransferCreateHandleEDMA(UART_Type *base, - uart_edma_handle_t *handle, - uart_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *txEdmaHandle, - edma_handle_t *rxEdmaHandle) + uart_edma_handle_t *handle, + uart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle) { assert(handle); @@ -219,17 +223,15 @@ void UART_TransferCreateHandleEDMA(UART_Type *base, status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer) { + assert(handle); assert(handle->txEdmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); edma_transfer_config_t xferConfig; status_t status; - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } - /* If previous TX not finished. */ if (kUART_TxBusy == handle->txState) { @@ -244,6 +246,9 @@ status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfe EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), (void *)UART_GetDataRegisterAddress(base), sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_MemoryToPeripheral); + /* Store the initially configured eDMA minor byte transfer count into the UART handle */ + handle->nbytes = sizeof(uint8_t); + /* Submit transfer. */ EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig); EDMA_StartTransfer(handle->txEdmaHandle); @@ -259,17 +264,15 @@ status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfe status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer) { + assert(handle); assert(handle->rxEdmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); edma_transfer_config_t xferConfig; status_t status; - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } - /* If previous RX not finished. */ if (kUART_RxBusy == handle->rxState) { @@ -284,6 +287,9 @@ status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_tran EDMA_PrepareTransfer(&xferConfig, (void *)UART_GetDataRegisterAddress(base), sizeof(uint8_t), xfer->data, sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory); + /* Store the initially configured eDMA minor byte transfer count into the UART handle */ + handle->nbytes = sizeof(uint8_t); + /* Submit transfer. */ EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig); EDMA_StartTransfer(handle->rxEdmaHandle); @@ -299,6 +305,7 @@ status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_tran void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle) { + assert(handle); assert(handle->txEdmaHandle); /* Disable UART TX EDMA. */ @@ -312,6 +319,7 @@ void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle) void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle) { + assert(handle); assert(handle->rxEdmaHandle); /* Disable UART RX EDMA. */ @@ -325,38 +333,36 @@ void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle) status_t UART_TransferGetReceiveCountEDMA(UART_Type *base, uart_edma_handle_t *handle, uint32_t *count) { + assert(handle); assert(handle->rxEdmaHandle); + assert(count); if (kUART_RxIdle == handle->rxState) { return kStatus_NoTransferInProgress; } - if (!count) - { - return kStatus_InvalidArgument; - } - - *count = handle->rxDataSizeAll - EDMA_GetRemainingBytes(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel); + *count = handle->rxDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel); return kStatus_Success; } status_t UART_TransferGetSendCountEDMA(UART_Type *base, uart_edma_handle_t *handle, uint32_t *count) { + assert(handle); assert(handle->txEdmaHandle); + assert(count); if (kUART_TxIdle == handle->txState) { return kStatus_NoTransferInProgress; } - if (!count) - { - return kStatus_InvalidArgument; - } - - *count = handle->txDataSizeAll - EDMA_GetRemainingBytes(handle->txEdmaHandle->base, handle->txEdmaHandle->channel); + *count = handle->txDataSizeAll - + (uint32_t)handle->nbytes * + EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel); return kStatus_Success; } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart_edma.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart_edma.h index 52cc7373a9..e411ffd7a4 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart_edma.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_uart_edma.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -39,8 +39,6 @@ * @{ */ -/*! @file*/ - /******************************************************************************* * Definitions ******************************************************************************/ @@ -67,6 +65,8 @@ struct _uart_edma_handle edma_handle_t *txEdmaHandle; /*!< The eDMA TX channel used. */ edma_handle_t *rxEdmaHandle; /*!< The eDMA RX channel used. */ + uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */ + volatile uint8_t txState; /*!< TX transfer state. */ volatile uint8_t rxState; /*!< RX transfer state */ }; @@ -87,18 +87,18 @@ extern "C" { /*! * @brief Initializes the UART handle which is used in transactional functions. * @param base UART peripheral base address. - * @param handle Pointer to uart_edma_handle_t structure. + * @param handle Pointer to the uart_edma_handle_t structure. * @param callback UART callback, NULL means no callback. * @param userData User callback function data. - * @param rxEdmaHandle User requested DMA handle for RX DMA transfer. - * @param txEdmaHandle User requested DMA handle for TX DMA transfer. + * @param rxEdmaHandle User-requested DMA handle for RX DMA transfer. + * @param txEdmaHandle User-requested DMA handle for TX DMA transfer. */ void UART_TransferCreateHandleEDMA(UART_Type *base, - uart_edma_handle_t *handle, - uart_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *txEdmaHandle, - edma_handle_t *rxEdmaHandle); + uart_edma_handle_t *handle, + uart_edma_transfer_callback_t callback, + void *userData, + edma_handle_t *txEdmaHandle, + edma_handle_t *rxEdmaHandle); /*! * @brief Sends data using eDMA. @@ -109,23 +109,23 @@ void UART_TransferCreateHandleEDMA(UART_Type *base, * @param base UART peripheral base address. * @param handle UART handle pointer. * @param xfer UART eDMA transfer structure. See #uart_transfer_t. - * @retval kStatus_Success if succeed, others failed. - * @retval kStatus_UART_TxBusy Previous transfer on going. + * @retval kStatus_Success if succeeded; otherwise failed. + * @retval kStatus_UART_TxBusy Previous transfer ongoing. * @retval kStatus_InvalidArgument Invalid argument. */ status_t UART_SendEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer); /*! - * @brief Receive data using eDMA. + * @brief Receives data using eDMA. * * This function receives data using eDMA. This is a non-blocking function, which returns * right away. When all data is received, the receive callback function is called. * * @param base UART peripheral base address. - * @param handle Pointer to uart_edma_handle_t structure. + * @param handle Pointer to the uart_edma_handle_t structure. * @param xfer UART eDMA transfer structure. See #uart_transfer_t. - * @retval kStatus_Success if succeed, others failed. - * @retval kStatus_UART_RxBusy Previous transfer on going. + * @retval kStatus_Success if succeeded; otherwise failed. + * @retval kStatus_UART_RxBusy Previous transfer ongoing. * @retval kStatus_InvalidArgument Invalid argument. */ status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_transfer_t *xfer); @@ -136,7 +136,7 @@ status_t UART_ReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle, uart_tran * This function aborts sent data using eDMA. * * @param base UART peripheral base address. - * @param handle Pointer to uart_edma_handle_t structure. + * @param handle Pointer to the uart_edma_handle_t structure. */ void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle); @@ -146,12 +146,12 @@ void UART_TransferAbortSendEDMA(UART_Type *base, uart_edma_handle_t *handle); * This function aborts receive data using eDMA. * * @param base UART peripheral base address. - * @param handle Pointer to uart_edma_handle_t structure. + * @param handle Pointer to the uart_edma_handle_t structure. */ void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle); /*! - * @brief Get the number of bytes that have been written to UART TX register. + * @brief Gets the number of bytes that have been written to UART TX register. * * This function gets the number of bytes that have been written to UART TX * register by DMA. @@ -166,9 +166,9 @@ void UART_TransferAbortReceiveEDMA(UART_Type *base, uart_edma_handle_t *handle); status_t UART_TransferGetSendCountEDMA(UART_Type *base, uart_edma_handle_t *handle, uint32_t *count); /*! - * @brief Get the number of bytes that have been received. + * @brief Gets the number of received bytes. * - * This function gets the number of bytes that have been received. + * This function gets the number of received bytes. * * @param base UART peripheral base address. * @param handle UART handle pointer. diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_vref.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_vref.c index 0854ca0757..24f2d1dc28 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_vref.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_vref.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -50,8 +50,10 @@ static uint32_t VREF_GetInstance(VREF_Type *base); /*! @brief Pointers to VREF bases for each instance. */ static VREF_Type *const s_vrefBases[] = VREF_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /*! @brief Pointers to VREF clocks for each instance. */ static const clock_ip_name_t s_vrefClocks[] = VREF_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /******************************************************************************* * Code @@ -62,7 +64,7 @@ static uint32_t VREF_GetInstance(VREF_Type *base) uint32_t instance; /* Find the instance index from base address mappings. */ - for (instance = 0; instance < FSL_FEATURE_SOC_VREF_COUNT; instance++) + for (instance = 0; instance < ARRAY_SIZE(s_vrefBases); instance++) { if (s_vrefBases[instance] == base) { @@ -70,7 +72,7 @@ static uint32_t VREF_GetInstance(VREF_Type *base) } } - assert(instance < FSL_FEATURE_SOC_VREF_COUNT); + assert(instance < ARRAY_SIZE(s_vrefBases)); return instance; } @@ -81,15 +83,24 @@ void VREF_Init(VREF_Type *base, const vref_config_t *config) uint8_t reg = 0U; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Ungate clock for VREF */ CLOCK_EnableClock(s_vrefClocks[VREF_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ /* Configure VREF to a known state */ #if defined(FSL_FEATURE_VREF_HAS_CHOP_OSC) && FSL_FEATURE_VREF_HAS_CHOP_OSC /* Set chop oscillator bit */ base->TRM |= VREF_TRM_CHOPEN_MASK; #endif /* FSL_FEATURE_VREF_HAS_CHOP_OSC */ + /* Get current SC register */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + reg = base->VREFH_SC; +#else reg = base->SC; +#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + /* Clear old buffer mode selection bits */ + reg &= ~VREF_SC_MODE_LV_MASK; /* Set buffer Mode selection and Regulator enable bit */ reg |= VREF_SC_MODE_LV(config->bufferMode) | VREF_SC_REGEN(1U); #if defined(FSL_FEATURE_VREF_HAS_COMPENSATION) && FSL_FEATURE_VREF_HAS_COMPENSATION @@ -99,30 +110,51 @@ void VREF_Init(VREF_Type *base, const vref_config_t *config) /* Enable VREF module */ reg |= VREF_SC_VREFEN(1U); /* Update bit-field from value to Status and Control register */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + base->VREFH_SC = reg; +#else base->SC = reg; +#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ #if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE reg = base->VREFL_TRM; - /* Clear old select external voltage reference and VREFL (0.4 V) reference buffer enable bits*/ + /* Clear old select external voltage reference and VREFL (0.4 V) reference buffer enable bits */ reg &= ~(VREF_VREFL_TRM_VREFL_EN_MASK | VREF_VREFL_TRM_VREFL_SEL_MASK); /* Select external voltage reference and set VREFL (0.4 V) reference buffer enable */ reg |= VREF_VREFL_TRM_VREFL_SEL(config->enableExternalVoltRef) | VREF_VREFL_TRM_VREFL_EN(config->enableLowRef); base->VREFL_TRM = reg; #endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 + reg = base->TRM4; + /* Clear old select internal voltage reference bit (2.1V) */ + reg &= ~VREF_TRM4_VREF2V1_EN_MASK; + /* Select internal voltage reference (2.1V) */ + reg |= VREF_TRM4_VREF2V1_EN(config->enable2V1VoltRef); + base->TRM4 = reg; +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ + /* Wait until internal voltage stable */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + while ((base->VREFH_SC & VREF_SC_VREFST_MASK) == 0) +#else while ((base->SC & VREF_SC_VREFST_MASK) == 0) +#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ { } } void VREF_Deinit(VREF_Type *base) { +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) /* Gate clock for VREF */ CLOCK_DisableClock(s_vrefClocks[VREF_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ } void VREF_GetDefaultConfig(vref_config_t *config) { + assert(config); + /* Set High power buffer mode in */ #if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE config->bufferMode = kVREF_ModeHighPowerBuffer; @@ -136,6 +168,11 @@ void VREF_GetDefaultConfig(vref_config_t *config) /* Set VREFL (0.4 V) reference buffer disable */ config->enableLowRef = false; #endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 + /* Disable internal voltage reference (2.1V) */ + config->enable2V1VoltRef = false; +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ } void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue) @@ -147,10 +184,30 @@ void VREF_SetTrimVal(VREF_Type *base, uint8_t trimValue) reg = ((reg & ~VREF_TRM_TRIM_MASK) | VREF_TRM_TRIM(trimValue)); base->TRM = reg; /* Wait until internal voltage stable */ +#if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE + while ((base->VREFH_SC & VREF_SC_VREFST_MASK) == 0) +#else + while ((base->SC & VREF_SC_VREFST_MASK) == 0) +#endif/* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ + { + } +} + +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 +void VREF_SetTrim2V1Val(VREF_Type *base, uint8_t trimValue) +{ + uint8_t reg = 0U; + + /* Set TRIM bits value in voltage reference (2V1) */ + reg = base->TRM4; + reg = ((reg & ~VREF_TRM4_TRIM2V1_MASK) | VREF_TRM4_TRIM2V1(trimValue)); + base->TRM4 = reg; + /* Wait until internal voltage stable */ while ((base->SC & VREF_SC_VREFST_MASK) == 0) { } } +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ #if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue) @@ -165,7 +222,8 @@ void VREF_SetLowReferenceTrimVal(VREF_Type *base, uint8_t trimValue) reg = ((reg & ~VREF_VREFL_TRM_VREFL_TRIM_MASK) | VREF_VREFL_TRM_VREFL_TRIM(trimValue)); base->VREFL_TRM = reg; /* Wait until internal voltage stable */ - while ((base->SC & VREF_SC_VREFST_MASK) == 0) + + while ((base->VREFH_SC & VREF_SC_VREFST_MASK) == 0) { } } diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_vref.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_vref.h index 79378863bb..6c6c014b91 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_vref.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_vref.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -38,7 +38,6 @@ * @{ */ -/*! @file */ /****************************************************************************** * Definitions @@ -46,12 +45,11 @@ /*! @name Driver version */ /*@{*/ -#define FSL_VREF_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ +#define FSL_VREF_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) /*!< Version 2.1.0. */ /*@}*/ /* Those macros below defined to support SoC family which have VREFL (0.4V) reference */ #if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE -#define SC VREFH_SC #define VREF_SC_MODE_LV VREF_VREFH_SC_MODE_LV #define VREF_SC_REGEN VREF_VREFH_SC_REGEN #define VREF_SC_VREFEN VREF_VREFH_SC_VREFEN @@ -80,8 +78,8 @@ typedef enum _vref_buffer_mode { kVREF_ModeBandgapOnly = 0U, /*!< Bandgap on only, for stabilization and startup */ #if defined(FSL_FEATURE_VREF_MODE_LV_TYPE) && FSL_FEATURE_VREF_MODE_LV_TYPE - kVREF_ModeHighPowerBuffer = 1U, /*!< High power buffer mode enabled */ - kVREF_ModeLowPowerBuffer = 2U /*!< Low power buffer mode enabled */ + kVREF_ModeHighPowerBuffer = 1U, /*!< High-power buffer mode enabled */ + kVREF_ModeLowPowerBuffer = 2U /*!< Low-power buffer mode enabled */ #else kVREF_ModeTightRegulationBuffer = 2U /*!< Tight regulation buffer enabled */ #endif /* FSL_FEATURE_VREF_MODE_LV_TYPE */ @@ -97,6 +95,9 @@ typedef struct _vref_config bool enableLowRef; /*!< Set VREFL (0.4 V) reference buffer enable or disable */ bool enableExternalVoltRef; /*!< Select external voltage reference or not (internal) */ #endif /* FSL_FEATURE_VREF_HAS_LOW_REFERENCE */ +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 + bool enable2V1VoltRef; /*!< Enable Internal Voltage Reference (2.1V) */ +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ } vref_config_t; /****************************************************************************** @@ -115,11 +116,11 @@ extern "C" { /*! * @brief Enables the clock gate and configures the VREF module according to the configuration structure. * - * This function must be called before calling all the other VREF driver functions, + * This function must be called before calling all other VREF driver functions, * read/write registers, and configurations with user-defined settings. * The example below shows how to set up vref_config_t parameters and - * how to call the VREF_Init function by passing in these parameters: - * Example: + * how to call the VREF_Init function by passing in these parameters. + * This is an example. * @code * vref_config_t vrefConfig; * vrefConfig.bufferMode = kVREF_ModeHighPowerBuffer; @@ -137,7 +138,7 @@ void VREF_Init(VREF_Type *base, const vref_config_t *config); * @brief Stops and disables the clock for the VREF module. * * This function should be called to shut down the module. - * Example: + * This is an example. * @code * vref_config_t vrefUserConfig; * VREF_Init(VREF); @@ -153,8 +154,8 @@ void VREF_Deinit(VREF_Type *base); /*! * @brief Initializes the VREF configuration structure. * - * This function initializes the VREF configuration structure to a default value. - * Example: + * This function initializes the VREF configuration structure to default values. + * This is an example. * @code * vrefConfig->bufferMode = kVREF_ModeHighPowerBuffer; * vrefConfig->enableExternalVoltRef = false; @@ -166,9 +167,9 @@ void VREF_Deinit(VREF_Type *base); void VREF_GetDefaultConfig(vref_config_t *config); /*! - * @brief Sets a TRIM value for reference voltage. + * @brief Sets a TRIM value for the reference voltage. * - * This function sets a TRIM value for reference voltage. + * This function sets a TRIM value for the reference voltage. * Note that the TRIM value maximum is 0x3F. * * @param base VREF peripheral address. @@ -188,13 +189,40 @@ static inline uint8_t VREF_GetTrimVal(VREF_Type *base) { return (base->TRM & VREF_TRM_TRIM_MASK); } + +#if defined(FSL_FEATURE_VREF_HAS_TRM4) && FSL_FEATURE_VREF_HAS_TRM4 +/*! + * @brief Sets a TRIM value for the reference voltage (2V1). + * + * This function sets a TRIM value for the reference voltage (2V1). + * Note that the TRIM value maximum is 0x3F. + * + * @param base VREF peripheral address. + * @param trimValue Value of the trim register to set the output reference voltage (maximum 0x3F (6-bit)). + */ +void VREF_SetTrim2V1Val(VREF_Type *base, uint8_t trimValue); + +/*! + * @brief Reads the value of the TRIM meaning output voltage (2V1). + * + * This function gets the TRIM value from the VREF_TRM4 register. + * + * @param base VREF peripheral address. + * @return Six-bit value of trim setting. + */ +static inline uint8_t VREF_GetTrim2V1Val(VREF_Type *base) +{ + return (base->TRM4 & VREF_TRM4_TRIM2V1_MASK); +} +#endif /* FSL_FEATURE_VREF_HAS_TRM4 */ + #if defined(FSL_FEATURE_VREF_HAS_LOW_REFERENCE) && FSL_FEATURE_VREF_HAS_LOW_REFERENCE /*! - * @brief Sets the TRIM value for low voltage reference. + * @brief Sets the TRIM value for the low voltage reference. * * This function sets the TRIM value for low reference voltage. - * NOTE: + * Note the following. * - The TRIM value maximum is 0x05U * - The values 111b and 110b are not valid/allowed. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_wdog.c b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_wdog.c index 489798ca88..781ac133c1 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_wdog.c +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_wdog.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * diff --git a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_wdog.h b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_wdog.h index 949a9a8e04..580adb95a0 100644 --- a/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_wdog.h +++ b/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/drivers/fsl_wdog.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2015, Freescale Semiconductor, Inc. - * All rights reserved. + * Copyright 2016-2017 NXP * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: @@ -12,7 +12,7 @@ * 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 + * 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. * @@ -33,11 +33,10 @@ #include "fsl_common.h" /*! - * @addtogroup wdog_driver + * @addtogroup wdog * @{ */ -/*! @file */ /******************************************************************************* * Definitions @@ -136,7 +135,7 @@ typedef struct _wdog_test_config */ enum _wdog_interrupt_enable_t { - kWDOG_InterruptEnable = WDOG_STCTRLH_IRQRSTEN_MASK, /*!< WDOG timeout will generate interrupt before reset*/ + kWDOG_InterruptEnable = WDOG_STCTRLH_IRQRSTEN_MASK, /*!< WDOG timeout generates an interrupt before reset*/ }; /*! @@ -164,10 +163,10 @@ extern "C" { */ /*! - * @brief Initializes WDOG configure sturcture. + * @brief Initializes the WDOG configuration sturcture. * - * This function initializes the WDOG configure structure to default value. The default - * value are: + * This function initializes the WDOG configuration structure to default values. The default + * values are as follows. * @code * wdogConfig->enableWdog = true; * wdogConfig->clockSource = kWDOG_LpoClockSource; @@ -182,7 +181,7 @@ extern "C" { * wdogConfig->timeoutValue = 0xFFFFU; * @endcode * - * @param config Pointer to WDOG config structure. + * @param config Pointer to the WDOG configuration structure. * @see wdog_config_t */ void WDOG_GetDefaultConfig(wdog_config_t *config); @@ -191,10 +190,10 @@ void WDOG_GetDefaultConfig(wdog_config_t *config); * @brief Initializes the WDOG. * * This function initializes the WDOG. When called, the WDOG runs according to the configuration. - * If user wants to reconfigure WDOG without forcing a reset first, enableUpdate must be set to true - * in configuration. + * To reconfigure WDOG without forcing a reset first, enableUpdate must be set to true + * in the configuration. * - * Example: + * This is an example. * @code * wdog_config_t config; * WDOG_GetDefaultConfig(&config); @@ -212,18 +211,18 @@ void WDOG_Init(WDOG_Type *base, const wdog_config_t *config); * @brief Shuts down the WDOG. * * This function shuts down the WDOG. - * Make sure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which means that the register update is enabled. + * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which indicates that the register update is enabled. */ void WDOG_Deinit(WDOG_Type *base); /*! - * @brief Configures WDOG functional test. + * @brief Configures the WDOG functional test. * * This function is used to configure the WDOG functional test. When called, the WDOG goes into test mode * and runs according to the configuration. - * Make sure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which means that the register update is enabled. + * Ensure that the WDOG_STCTRLH.ALLOWUPDATE is 1 which means that the register update is enabled. * - * Example: + * This is an example. * @code * wdog_test_config_t test_config; * test_config.testMode = kWDOG_QuickTest; @@ -259,9 +258,9 @@ static inline void WDOG_Enable(WDOG_Type *base) /*! * @brief Disables the WDOG module. * - * This function write value into WDOG_STCTRLH register to disable the WDOG, it is a write-once register, - * make sure that the WCT window is still open and this register has not been written in this WCT - * while this function is called. + * This function writes a value into the WDOG_STCTRLH register to disable the WDOG. It is a write-once register. + * Ensure that the WCT window is still open and that register has not been written to in this WCT + * while the function is called. * * @param base WDOG peripheral base address */ @@ -271,15 +270,15 @@ static inline void WDOG_Disable(WDOG_Type *base) } /*! - * @brief Enable WDOG interrupt. + * @brief Enables the WDOG interrupt. * - * This function write value into WDOG_STCTRLH register to enable WDOG interrupt, it is a write-once register, - * make sure that the WCT window is still open and this register has not been written in this WCT - * while this function is called. + * This function writes a value into the WDOG_STCTRLH register to enable the WDOG interrupt. It is a write-once register. + * Ensure that the WCT window is still open and the register has not been written to in this WCT + * while the function is called. * * @param base WDOG peripheral base address * @param mask The interrupts to enable - * The parameter can be combination of the following source if defined: + * The parameter can be combination of the following source if defined. * @arg kWDOG_InterruptEnable */ static inline void WDOG_EnableInterrupts(WDOG_Type *base, uint32_t mask) @@ -288,15 +287,15 @@ static inline void WDOG_EnableInterrupts(WDOG_Type *base, uint32_t mask) } /*! - * @brief Disable WDOG interrupt. + * @brief Disables the WDOG interrupt. * - * This function write value into WDOG_STCTRLH register to disable WDOG interrupt, it is a write-once register, - * make sure that the WCT window is still open and this register has not been written in this WCT - * while this function is called. + * This function writes a value into the WDOG_STCTRLH register to disable the WDOG interrupt. It is a write-once register. + * Ensure that the WCT window is still open and the register has not been written to in this WCT + * while the function is called. * * @param base WDOG peripheral base address * @param mask The interrupts to disable - * The parameter can be combination of the following source if defined: + * The parameter can be combination of the following source if defined. * @arg kWDOG_InterruptEnable */ static inline void WDOG_DisableInterrupts(WDOG_Type *base, uint32_t mask) @@ -305,50 +304,50 @@ static inline void WDOG_DisableInterrupts(WDOG_Type *base, uint32_t mask) } /*! - * @brief Gets WDOG all status flags. + * @brief Gets the WDOG all status flags. * * This function gets all status flags. * - * Example for getting Running Flag: + * This is an example for getting the Running Flag. * @code * uint32_t status; - * status = WDOG_GetStatusFlags(wdog_base) & kWDOG_RunningFlag; + * status = WDOG_GetStatusFlags (wdog_base) & kWDOG_RunningFlag; * @endcode * @param base WDOG peripheral base address * @return State of the status flag: asserted (true) or not-asserted (false).@see _wdog_status_flags_t - * - true: related status flag has been set. - * - false: related status flag is not set. + * - true: a related status flag has been set. + * - false: a related status flag is not set. */ uint32_t WDOG_GetStatusFlags(WDOG_Type *base); /*! - * @brief Clear WDOG flag. + * @brief Clears the WDOG flag. * - * This function clears WDOG status flag. + * This function clears the WDOG status flag. * - * Example for clearing timeout(interrupt) flag: + * This is an example for clearing the timeout (interrupt) flag. * @code * WDOG_ClearStatusFlags(wdog_base,kWDOG_TimeoutFlag); * @endcode * @param base WDOG peripheral base address * @param mask The status flags to clear. - * The parameter could be any combination of the following values: + * The parameter could be any combination of the following values. * kWDOG_TimeoutFlag */ void WDOG_ClearStatusFlags(WDOG_Type *base, uint32_t mask); /*! - * @brief Set the WDOG timeout value. + * @brief Sets the WDOG timeout value. * * This function sets the timeout value. * It should be ensured that the time-out value for the WDOG is always greater than * 2xWCT time + 20 bus clock cycles. - * This function write value into WDOG_TOVALH and WDOG_TOVALL registers which are wirte-once. - * Make sure the WCT window is still open and these two registers have not been written in this WCT - * while this function is called. + * This function writes a value into WDOG_TOVALH and WDOG_TOVALL registers which are wirte-once. + * Ensure the WCT window is still open and the two registers have not been written to in this WCT + * while the function is called. * * @param base WDOG peripheral base address - * @param timeoutCount WDOG timeout value, count of WDOG clock tick. + * @param timeoutCount WDOG timeout value; count of WDOG clock tick. */ static inline void WDOG_SetTimeoutValue(WDOG_Type *base, uint32_t timeoutCount) { @@ -360,9 +359,9 @@ static inline void WDOG_SetTimeoutValue(WDOG_Type *base, uint32_t timeoutCount) * @brief Sets the WDOG window value. * * This function sets the WDOG window value. - * This function write value into WDOG_WINH and WDOG_WINL registers which are wirte-once. - * Make sure the WCT window is still open and these two registers have not been written in this WCT - * while this function is called. + * This function writes a value into WDOG_WINH and WDOG_WINL registers which are wirte-once. + * Ensure the WCT window is still open and the two registers have not been written to in this WCT + * while the function is called. * * @param base WDOG peripheral base address * @param windowValue WDOG window value. @@ -378,7 +377,7 @@ static inline void WDOG_SetWindowValue(WDOG_Type *base, uint32_t windowValue) * * This function unlocks the WDOG register written. * Before starting the unlock sequence and following congfiguration, disable the global interrupts. - * Otherwise, an interrupt could effectively invalidate the unlock sequence and the WCT may expire, + * Otherwise, an interrupt may invalidate the unlocking sequence and the WCT may expire. * After the configuration finishes, re-enable the global interrupts. * * @param base WDOG peripheral base address @@ -393,7 +392,7 @@ static inline void WDOG_Unlock(WDOG_Type *base) * @brief Refreshes the WDOG timer. * * This function feeds the WDOG. - * This function should be called before WDOG timer is in timeout. Otherwise, a reset is asserted. + * This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted. * * @param base WDOG peripheral base address */ @@ -405,7 +404,7 @@ void WDOG_Refresh(WDOG_Type *base); * This function gets the WDOG reset count value. * * @param base WDOG peripheral base address - * @return WDOG reset count value + * @return WDOG reset count value. */ static inline uint16_t WDOG_GetResetCount(WDOG_Type *base) {