K66F: Update to SDK 2.2

Signed-off-by: Mahadevan Mahesh <Mahesh.Mahadevan@nxp.com>
pull/5268/head
Mahadevan Mahesh 2017-08-25 13:33:11 -05:00 committed by adbridge
parent d9d6f593c0
commit 2efa469d0b
107 changed files with 10092 additions and 5948 deletions

View File

@ -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 */

View File

@ -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();
CLOCK_BootToBlpiMode(g_defaultClockConfigVlpr.mcgConfig.fcrdiv, g_defaultClockConfigVlpr.mcgConfig.ircs,
g_defaultClockConfigVlpr.mcgConfig.irclkEnableMode);
CLOCK_SetSimConfig(&g_defaultClockConfigVlpr.simConfig);
SystemCoreClock = g_defaultClockConfigVlpr.coreClock;
SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll);
SMC_SetPowerModeVlpr(SMC);
while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr)
{
}
MCG->C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
}
void BOARD_BootClockRUN(void)
/*******************************************************************************
********************* 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 **/
/*******************************************************************************
* Variables for BOARD_BootClockHSRUN configuration
******************************************************************************/
const mcg_config_t mcgConfig_BOARD_BootClockHSRUN =
{
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;
}

View File

@ -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_ */

View File

@ -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 @@ 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)
{

View File

@ -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.
*

View File

@ -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

View File

@ -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)

View File

@ -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
**
** ###################################################################
*/

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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
**
** ###################################################################
*/

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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. */
@ -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);

View File

@ -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)))
@ -1734,8 +1880,12 @@ 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)
{
/* 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);

View File

@ -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)

View File

@ -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,27 +141,27 @@ 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
* 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);

View File

@ -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);
}
/* Set the CMT mode. */
mscReg = base->MSC;
mscReg &= ~CMT_MODE_BIT_MASK;
mscReg &= ~ (CMT_MSC_FSK_MASK | CMT_MSC_BASE_MASK);
mscReg |= mode;
}
else
{
mscReg &= ~CMT_MSC_MCGEN_MASK;
}
/* Set the CMT mode. */
base->MSC = mscReg;
}

View File

@ -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

View File

@ -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 <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#if defined(__ICCARM__)
#include <stddef.h>
#endif
#include "fsl_device_registers.h"
/*!
@ -43,8 +47,6 @@
* @{
*/
/*! @file */
/*******************************************************************************
* Definitions
******************************************************************************/
@ -61,6 +63,8 @@
#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

View File

@ -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;

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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 */
}

View File

@ -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)

View File

@ -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.
*
@ -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,6 +715,8 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
while ((remainingReceiveByteCount - remainingSendByteCount) >= fifoSize)
{
if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
{
if (rxData != NULL)
@ -720,31 +735,13 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
}
}
}
}
else
{
while (remainingSendByteCount > 0)
{
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,6 +822,8 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
while (((remainingReceiveByteCount - remainingSendByteCount) / 2) >= fifoSize)
{
if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
{
wordReceived = DSPI_ReadData(base);
@ -843,12 +842,16 @@ status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
}
}
}
}
return kStatus_Success;
}
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;

View File

@ -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)
{
@ -803,17 +805,17 @@ uint32_t DSPI_MasterSetBaudRate(SPI_Type *base,
* 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).
*
* 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).
*
* 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);

View File

@ -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 @@ 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*/
@ -242,23 +278,17 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
if (handle->remainingSendByteCount <= 2)
{
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;
}
}
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
{
@ -314,22 +345,14 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
if (handle->remainingSendByteCount <= 2)
{
if (handle->txData)
{
if (handle->isThereExtraByte)
{
wordToSend = *(handle->txData) | ((uint32_t)dummyData << 8);
}
else
{
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))) &&
@ -535,20 +503,12 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
handle->lastCommand = (handle->lastCommand & 0xffff0000U) | handle->txData[bufferIndex - 1];
}
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];
}
}
}
else
{
if (handle->bitsPerFrame <= 8)
@ -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,7 +647,8 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
transferConfigC.srcOffset = 0;
transferConfigC.destOffset = 0;
transferConfigC.minorLoopBytes = 4;
if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
{
if (handle->bitsPerFrame <= 8)
{
transferConfigC.majorLoopCounts = handle->remainingSendByteCount - 1;
@ -602,6 +660,15 @@ status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *hand
EDMA_SetTransferConfig(handle->edmaIntermediaryToTxRegHandle->base,
handle->edmaIntermediaryToTxRegHandle->channel, &transferConfigC, softwareTCD);
}
else
{
transferConfigC.majorLoopCounts = 1;
EDMA_SetTransferConfig(handle->edmaIntermediaryToTxRegHandle->base,
handle->edmaIntermediaryToTxRegHandle->channel, &transferConfigC, NULL);
}
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))
{
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;
}
}
}
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,17 +977,10 @@ 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 */
}
}
else
{
wordToSend = ((uint32_t)dummyData << 8) | dummyData;
@ -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,39 +1081,6 @@ 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;
EDMA_TcdReset(softwareTCD);
EDMA_TcdSetTransferConfig(softwareTCD, &transferConfigC, NULL);
}
/*Set another transferConfigC*/
if ((handle->isThereExtraByte) && (handle->remainingSendByteCount == 2))
{
EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
&transferConfigC, NULL);
}
else
{
transferConfigC.destAddr = (uint32_t)txAddr;
transferConfigC.destOffset = 0;
@ -1083,11 +1095,11 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
transferConfigC.srcOffset = 0;
if (handle->bitsPerFrame <= 8)
{
handle->txBuffIfNull = DSPI_SLAVE_DUMMY_DATA;
handle->txBuffIfNull = DSPI_DUMMY_DATA;
}
else
{
handle->txBuffIfNull = (DSPI_SLAVE_DUMMY_DATA << 8) | DSPI_SLAVE_DUMMY_DATA;
handle->txBuffIfNull = (DSPI_DUMMY_DATA << 8) | DSPI_DUMMY_DATA;
}
}
@ -1103,32 +1115,14 @@ status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle
{
transferConfigC.destTransferSize = kEDMA_TransferSize2Bytes;
transferConfigC.minorLoopBytes = 2;
if (handle->isThereExtraByte)
{
transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2 - 1;
}
else
{
transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2;
}
}
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);
}
}
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;

View File

@ -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]; /*!<SoftwareTCD , internal used*/
};
/*! @brief DSPI slave eDMA transfer handle structure used for transactional API.*/
/*! @brief DSPI slave eDMA transfer handle structure used for the transactional API.*/
struct _dspi_slave_edma_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. */
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.*/
uint32_t txLastData; /*!< Used if there is an extra byte when 16bits per frame for DMA purpose.*/
volatile uint8_t state; /*!< DSPI transfer state.*/
uint8_t nbytes; /*!< eDMA minor byte transfer count initially configured. */
uint32_t errorCount; /*!< Error count for slave transfer.*/
volatile uint8_t state; /*!< DSPI transfer state.*/
dspi_slave_edma_transfer_callback_t callback; /*!< Completion callback. */
void *userData; /*!< Callback user data. */
edma_handle_t *edmaRxRegToRxDataHandle; /*!<edma_handle_t handle point used for RxReg to RxData buff*/
edma_handle_t *edmaTxDataToTxRegHandle; /*!<edma_handle_t handle point used for TxData to TxReg*/
edma_tcd_t dspiSoftwareTCD[2]; /*!<SoftwareTCD , internal used*/
};
/***********************************************************************************************************************
@ -153,9 +149,10 @@ extern "C" {
* @brief Initializes the DSPI master eDMA handle.
*
* This function initializes the DSPI eDMA handle which can be used for other DSPI transactional APIs. Usually, for a
* specified DSPI instance, user need only call this API once to get the initialized handle.
* specified DSPI instance, call this API once to get the initialized handle.
*
* Note that DSPI eDMA has separated (RX and TX as two sources) or shared (RX and TX are the same source) DMA request source.
* Note that DSPI eDMA has separated (RX and TX as two sources) or shared (RX and TX are the same source) DMA request
* source.
* (1) For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
* TX DMAMUX source for edmaIntermediaryToTxRegHandle.
* (2) For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
@ -163,7 +160,7 @@ extern "C" {
* @param base DSPI peripheral base address.
* @param handle DSPI handle pointer to dspi_master_edma_handle_t.
* @param callback DSPI callback.
* @param userData callback function parameter.
* @param userData A callback function parameter.
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
* @param edmaTxDataToIntermediaryHandle edmaTxDataToIntermediaryHandle pointer to edma_handle_t.
* @param edmaIntermediaryToTxRegHandle edmaIntermediaryToTxRegHandle pointer to edma_handle_t.
@ -179,34 +176,34 @@ void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base,
/*!
* @brief DSPI master transfer data using eDMA.
*
* This function transfer data using eDMA. This is non-blocking function, which returns right away. When all data
* have been transfer, the callback function is called.
* This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
* is transferred, the callback function is called.
*
* @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_edma_handle_t structure which stores the transfer state.
* @param transfer pointer to dspi_transfer_t structure.
* @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
* @param transfer A pointer to the dspi_transfer_t structure.
* @return status of status_t.
*/
status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer);
/*!
* @brief DSPI master aborts a transfer which using eDMA.
* @brief DSPI master aborts a transfer which is using eDMA.
*
* This function aborts a transfer which using eDMA.
* This function aborts a transfer which is using eDMA.
*
* @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_edma_handle_t structure which stores the transfer state.
* @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
*/
void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle);
/*!
* @brief Gets the master eDMA transfer count.
*
* This function get the master eDMA transfer count.
* This function gets the master eDMA transfer count.
*
* @param base DSPI peripheral base address.
* @param handle pointer to dspi_master_edma_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction.
* @param handle A pointer to the dspi_master_edma_handle_t structure which stores the transfer state.
* @param count A number of bytes transferred by the non-blocking transaction.
* @return status of status_t.
*/
status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, size_t *count);
@ -217,7 +214,8 @@ status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle
* This function initializes the DSPI eDMA 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.
*
* Note that DSPI eDMA has separated (RN and TX in 2 sources) or shared (RX and TX are the same source) DMA request source.
* Note that DSPI eDMA has separated (RN and TX in 2 sources) or shared (RX and TX are the same source) DMA request
* source.
* (1)For the separated DMA request source, enable and set the RX DMAMUX source for edmaRxRegToRxDataHandle and
* TX DMAMUX source for edmaTxDataToTxRegHandle.
* (2)For the shared DMA request source, enable and set the RX/RX DMAMUX source for the edmaRxRegToRxDataHandle.
@ -225,7 +223,7 @@ status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle
* @param base DSPI peripheral base address.
* @param handle DSPI handle pointer to dspi_slave_edma_handle_t.
* @param callback DSPI callback.
* @param userData callback function parameter.
* @param userData A callback function parameter.
* @param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t.
* @param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t.
*/
@ -239,25 +237,25 @@ void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base,
/*!
* @brief DSPI slave transfer data using eDMA.
*
* This function transfer data using eDMA. This is non-blocking function, which returns right away. When all data
* have been transfer, the callback function is called.
* Note that slave EDMA transfer cannot support the situation that transfer_size is 1 when the bitsPerFrame is greater
* than 8 .
* This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data
* is transferred, the callback function is called.
* Note that the slave eDMA transfer doesn't support transfer_size is 1 when the bitsPerFrame is greater
* than eight.
* @param base DSPI peripheral base address.
* @param handle pointer to dspi_slave_edma_handle_t structure which stores the transfer state.
* @param transfer pointer to dspi_transfer_t structure.
* @param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
* @param transfer A pointer to the dspi_transfer_t structure.
* @return status of status_t.
*/
status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer);
/*!
* @brief DSPI slave aborts a transfer which using eDMA.
* @brief DSPI slave aborts a transfer which is using eDMA.
*
* This function aborts a transfer which using eDMA.
* This function aborts a transfer which is using eDMA.
*
* @param base DSPI peripheral base address.
* @param handle pointer to dspi_slave_edma_handle_t structure which stores the transfer state.
* @param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
*/
void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle);
@ -267,8 +265,8 @@ void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handl
* This function gets the slave eDMA transfer count.
*
* @param base DSPI peripheral base address.
* @param handle pointer to dspi_slave_edma_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction.
* @param handle A pointer to the dspi_slave_edma_handle_t structure which stores the transfer state.
* @param count A number of bytes transferred so far by the non-blocking transaction.
* @return status of status_t.
*/
status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, size_t *count);

View File

@ -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.
*
@ -63,11 +63,13 @@ static void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd);
/*! @brief Array to map EDMA instance number to base pointer. */
static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Array to map EDMA instance number to clock name. */
static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*! @brief Array to map EDMA instance number to IRQ number. */
static const IRQn_Type s_edmaIRQNumber[] = DMA_CHN_IRQS;
static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS;
/*! @brief Pointers to transfer handle for each EDMA channel. */
static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT];
@ -81,7 +83,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base)
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < FSL_FEATURE_SOC_EDMA_COUNT; instance++)
for (instance = 0; instance < ARRAY_SIZE(s_edmaBases); instance++)
{
if (s_edmaBases[instance] == base)
{
@ -89,7 +91,7 @@ static uint32_t EDMA_GetInstance(DMA_Type *base)
}
}
assert(instance < FSL_FEATURE_SOC_EDMA_COUNT);
assert(instance < ARRAY_SIZE(s_edmaBases));
return instance;
}
@ -122,8 +124,10 @@ void EDMA_Init(DMA_Type *base, const edma_config_t *config)
uint32_t tmpreg;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate EDMA periphral clock */
CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Configure EDMA peripheral according to the configuration structure. */
tmpreg = base->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

View File

@ -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 @@
#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 */
@ -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,7 +255,7 @@ 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 */
@ -267,9 +266,10 @@ typedef struct _edma_handle
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. */
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,24 +703,33 @@ 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
* @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
* @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,7 +812,7 @@ 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
* 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,
@ -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);

View File

@ -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.
*
@ -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;
@ -493,6 +503,21 @@ static void ENET_SetMacController(ENET_Type *base,
}
/* 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->rxBdDirty->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
handle->rxBdCurrent->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->rxBdCurrent->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
/* Increase current buffer descriptor to the next one. */
if (handle->rxBdCurrent->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)
{
handle->rxBdDirty = handle->rxBdBase;
handle->rxBdCurrent = handle->rxBdBase;
}
else
{
handle->rxBdDirty++;
handle->rxBdCurrent++;
}
/* Actives the receive buffer descriptor. */
base->RDAR = ENET_RDAR_RDAR_MASK;
} while (handle->rxBdDirty != handle->rxBdCurrent);
}
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]);
}
@ -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

View File

@ -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.
@ -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)
@ -913,8 +958,8 @@ status_t ENET_GetTxErrAfterSendFrame(enet_handle_t *handle, enet_data_error_stat
#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.
* 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".
*
@ -932,8 +977,33 @@ 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".

View File

@ -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)

View File

@ -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
*/

View File

@ -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 FLEXBUS_GetInstance(FB_Type *base);
/*! @brief Pointers to FLEXBUS bases for each instance. */
static FB_Type *const s_flexbusBases[] = FB_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to FLEXBUS clocks for each instance. */
static const clock_ip_name_t s_flexbusClocks[] = FLEXBUS_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
@ -62,7 +64,7 @@ static uint32_t FLEXBUS_GetInstance(FB_Type *base)
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < FSL_FEATURE_SOC_FB_COUNT; instance++)
for (instance = 0; instance < ARRAY_SIZE(s_flexbusBases); instance++)
{
if (s_flexbusBases[instance] == base)
{
@ -70,7 +72,7 @@ static uint32_t FLEXBUS_GetInstance(FB_Type *base)
}
}
assert(instance < FSL_FEATURE_SOC_FB_COUNT);
assert(instance < ARRAY_SIZE(s_flexbusBases));
return instance;
}
@ -84,8 +86,10 @@ void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config)
uint32_t chip = 0;
uint32_t reg_value = 0;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Ungate clock for FLEXBUS */
CLOCK_EnableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Reset all the register to default state */
for (chip = 0; chip < FB_CSAR_COUNT; chip++)
@ -168,8 +172,10 @@ void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config)
void FLEXBUS_Deinit(FB_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Gate clock for FLEXBUS */
CLOCK_EnableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]);
CLOCK_DisableClock(s_flexbusClocks[FLEXBUS_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
void FLEXBUS_GetDefaultConfig(flexbus_config_t *config)

View File

@ -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,7 +45,7 @@
/*! @name Driver version */
/*@{*/
#define FSL_FLEXBUS_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */
#define FSL_FLEXBUS_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) /*!< Version 2.0.1. */
/*@}*/
/*!
@ -197,11 +196,11 @@ extern "C" {
*
* This function enables the clock gate for FlexBus module.
* Only chip 0 is validated and set to known values. Other chips are disabled.
* NOTE: In this function, certain parameters, depending on external memories, must
* be set before using FLEXBUS_Init() function.
* Note that in this function, certain parameters, depending on external memories, must
* be set before using the FLEXBUS_Init() function.
* This example shows how to set up the uart_state_t and the
* flexbus_config_t parameters and how to call the FLEXBUS_Init function by passing
* in these parameters:
* in these parameters.
@code
flexbus_config_t flexbusConfig;
FLEXBUS_GetDefaultConfig(&flexbusConfig);
@ -212,7 +211,7 @@ extern "C" {
@endcode
*
* @param base FlexBus peripheral address.
* @param config Pointer to the configure structure
* @param config Pointer to the configuration structure
*/
void FLEXBUS_Init(FB_Type *base, const flexbus_config_t *config);
@ -229,7 +228,7 @@ void FLEXBUS_Deinit(FB_Type *base);
* @brief Initializes the FlexBus configuration structure.
*
* This function initializes the FlexBus configuration structure to default value. The default
* values are:
* values are.
@code
fbConfig->chip = 0;
fbConfig->writeProtect = 0;

View File

@ -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,10 +321,14 @@ 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;
@ -1299,7 +1334,7 @@ void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle)
#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

View File

@ -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. */
(((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) \
((FLEXCAN_ID_STD(id) & 0x7F8) << 13) /*!< Standard Rx FIFO Mask helper macro Type C mid-upper part helper macro. \
*/
(((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.
*

View File

@ -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)

View File

@ -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,7 +44,7 @@
/*! @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 */
/*@}*/
/*!
@ -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.
*

View File

@ -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 */

View File

@ -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,16 +38,14 @@
* @{
*/
/*! @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 */
@ -57,19 +55,43 @@ typedef enum _gpio_pin_direction
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 =
@ -127,20 +149,20 @@ 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 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;
}
}
@ -148,7 +170,7 @@ static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t pin, uint8_t ou
* @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 mask GPIO pin number macro
*/
static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t mask)
{
@ -159,7 +181,7 @@ 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 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 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 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.
@ -209,19 +231,33 @@ static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t pin)
* 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
* @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 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
* 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 */

View File

@ -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;
}
/* Clear all status before transfer. */
I2C_MasterClearStatusFlags(base, kClearFlags);
@ -265,18 +313,19 @@ 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.subaddressSize > 0)
{
handle->state = kSendCommandState;
}
else
{
@ -292,6 +341,12 @@ static status_t I2C_MasterTransferRunStateMachine(I2C_Type *base, i2c_master_han
}
}
}
}
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,9 +887,17 @@ status_t I2C_MasterReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize)
/* Single byte use case. */
if (rxSize == 0)
{
/* Read the final byte. */
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,19 +949,42 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
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;
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))
{
}
/* Clear interrupt pending flag. */
base->S = kI2C_IntPendingFlag;
/* Check if there's transfer error. */
result = I2C_CheckAndClearError(base, base->S);
@ -866,34 +998,13 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
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);
@ -902,10 +1013,8 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
{
return result;
}
}
}
/* Wait until address + command transfer complete. */
/* Wait until data transfer complete. */
while (!(base->S & kI2C_IntPendingFlag))
{
}
@ -913,37 +1022,31 @@ status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer)
/* 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;
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,8 +1525,11 @@ void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle)
}
}
if (!(status & kI2C_AddressMatchFlag))
{
return;
}
}
#endif /* I2C_HAS_STOP_DETECT */
#if defined(FSL_FEATURE_I2C_HAS_START_STOP_DETECT) && FSL_FEATURE_I2C_HAS_START_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

View File

@ -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_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.
*/

View File

@ -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,18 +320,11 @@ 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)
{
@ -301,11 +336,18 @@ static status_t I2C_InitTransferStateMachineEDMA(I2C_Type *base,
{
}
/* Clear pending flag. */
base->S = kI2C_IntPendingFlag;
/* Check if there's transfer error. */
result = I2C_CheckAndClearError(base, base->S);
if (result)
{
return result;
}
}
}
/* Clear pending flag. */
base->S = kI2C_IntPendingFlag;
}
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.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
{

View File

@ -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);

View File

@ -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.
*

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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.
*

View File

@ -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)

View File

@ -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;
}
/*! @}*/

View File

@ -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,8 +283,32 @@ 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))
{
/* 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.
@ -266,16 +325,33 @@ void LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcC
/* 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);
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)
{
if (kLPUART_ParityDisabled != config->parityMode)
{
temp |= (LPUART_CTRL_M_MASK | (uint8_t)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;
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,8 +710,19 @@ 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. */
@ -636,7 +779,12 @@ void LPUART_TransferCreateHandle(LPUART_Type *base,
s_lpuartIsr = LPUART_TransferHandleIRQ;
/* 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,10 +793,9 @@ 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;
@ -657,7 +804,6 @@ void LPUART_TransferStartRingBuffer(LPUART_Type *base,
/* 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)
{
@ -965,7 +1106,18 @@ void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle)
}
/* 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

View File

@ -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 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. */
@ -58,8 +56,7 @@ enum _lpuart_status
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_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. */
@ -67,6 +64,8 @@ enum _lpuart_status
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 */
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,6 +231,29 @@ 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
* @{
@ -232,6 +269,8 @@ extern "C" {
* 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;
@ -241,8 +280,10 @@ extern "C" {
* @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
*/
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);
/*!
* @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.
*

View File

@ -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. */
@ -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;
}

View File

@ -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 */
};
@ -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.

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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)

View File

@ -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
@ -232,13 +231,13 @@ extern "C" {
/*!
* @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);
@ -250,9 +249,9 @@ void PDB_Init(PDB_Type *base, const pdb_config_t *config);
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.

View File

@ -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

View File

@ -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

View File

@ -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.
*

View File

@ -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.

View File

@ -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,28 +166,59 @@ 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 */
#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;
uint16_t passiveFilterEnable : 1; /*!< passive filter enable/disable */
#endif /* FSL_FEATURE_PORT_HAS_SLEW_RATE */
uint16_t : 1;
#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 */
uint16_t openDrainEnable : 1; /*!< Open drain enable/disable */
#else
uint16_t : 1;
#endif /* FSL_FEATURE_PORT_HAS_OPEN_DRAIN */
uint16_t driveStrength : 1; /*!< fast/slow drive strength configure */
#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;
uint16_t mux : 3; /*!< pin mux Configure */
#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
@ -181,13 +228,14 @@ typedef struct _port_pin_config
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)
{
@ -353,7 +402,7 @@ static inline void PORT_SetPinInterruptConfig(PORT_Type *base, uint32_t pin, por
*
* @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)
{

View File

@ -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;

View File

@ -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

View File

@ -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 */
}
/*!

View File

@ -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

View File

@ -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));
}

View File

@ -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,6 +64,8 @@ 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
{
@ -74,6 +75,8 @@ typedef enum _rtc_osc_cap_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
{
@ -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.
*

View File

@ -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*/

View File

@ -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*/
@ -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);

View File

@ -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 */
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 */
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;

View File

@ -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 */

View File

@ -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)
@ -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;
}
@ -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,31 +877,71 @@ 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)
{
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);
@ -914,7 +954,6 @@ uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busCloc
}
/* Enable the SD clock. */
base->SYSCTL |= SDHC_SYSCTL_SDCLKEN_MASK;
}
return nearestFrequency;
}
@ -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,6 +1156,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 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 */
@ -1128,7 +1174,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_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,10 +1235,9 @@ 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)
{
@ -1200,31 +1247,41 @@ status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t ad
}
/* 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))))
if (data && (NULL != admaTable))
{
error = kStatus_SDHC_PrepareAdmaDescriptorFailed;
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)
{
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,27 +1328,39 @@ 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)))
{
error = kStatus_SDHC_BusyTransferring;
return kStatus_SDHC_BusyTransferring;
}
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))))
if (data && (NULL != admaTable))
{
error = kStatus_SDHC_PrepareAdmaDescriptorFailed;
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)
{
/* 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
{
}
}
/* Save command and data into handle before transferring. */
handle->command = command;
handle->data = data;
@ -1299,12 +1368,9 @@ status_t SDHC_TransferNonBlocking(
/* transferredWords will only be updated in ISR when transfer way is DATAPORT. */
handle->transferredWords = 0U;
SDHC_StartTransfer(base, command, data);
}
}
}
SDHC_StartTransfer(base, command, data, dmaMode);
return error;
return kStatus_Success;
}
void SDHC_TransferHandleIRQ(SDHC_Type *base, sdhc_handle_t *handle)

View File

@ -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
@ -499,9 +502,11 @@ 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 */
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.

View File

@ -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;
/* 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;
}

View File

@ -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)
{

View File

@ -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.
*

View File

@ -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 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)
{

View File

@ -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)

View File

@ -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.

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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
/* 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;
@ -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
/* The TPM's QDCTRL register required to be effective */
if( FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(base) )
{
/* 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
/* 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,11 +494,15 @@ 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
/* The TPM's QDCTRL register required to be effective */
if( FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(base) )
{
/* Clear quadrature Decoder mode for channel 0 or 1 */
if ((chnlNumber == 0) || (chnlNumber == 1))
{
base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
}
}
#endif
/* When switching mode, disable channel first */
@ -502,14 +536,20 @@ 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
/* The TPM's QDCTRL register required to be effective */
if( FSL_FEATURE_TPM_QDCTRL_HAS_EFFECTn(base) )
{
/* Clear quadrature Decoder mode for channel 0 or 1*/
if (chnlPairNumber == 0)
{
base->QDCTRL &= ~TPM_QDCTRL_QUADEN_MASK;
}
}
#endif
/* Unlock: When switching mode, disable channel first */
@ -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);

View File

@ -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
* @{

View File

@ -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;
@ -48,6 +50,8 @@ void TSI_Init(TSI_Type *base, const tsi_config_t *config)
TSI_DisableInterrupts(base, kTSI_GlobalInterruptEnable);
}
if(config->mode == kTSI_AnalogModeSel_Capacitive)
{
TSI_SetHighThreshold(base, config->thresh);
TSI_SetLowThreshold(base, config->thresl);
TSI_SetElectrodeOSCPrescaler(base, config->prescaler);
@ -56,8 +60,19 @@ void TSI_Init(TSI_Type *base, const tsi_config_t *config)
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)
{
@ -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 */
}

View File

@ -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));
}
/*!

View File

@ -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.
*
@ -40,7 +40,9 @@ enum _uart_tansfer_states
kUART_TxIdle, /* TX idle. */
kUART_TxBusy, /* TX busy. */
kUART_RxIdle, /* RX idle. */
kUART_RxBusy /* RX busy. */
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;
/* Calculate the baud rate modulo divisor, sbr*/
sbr = srcClock_Hz / (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 / (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
/* 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);
/* 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;
#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;
/* 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;
/* Enable the interrupt to accept the data when user need the ring buffer. */
UART_EnableInterrupts(base, kUART_RxDataRegFullInterruptEnable | kUART_RxOverrunInterruptEnable);
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. */
/* 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)

Some files were not shown because too many files have changed in this diff Show More