summaryrefslogtreecommitdiff
path: root/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers')
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_clock.c2827
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_clock.h1293
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_common.c225
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_common.h648
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_emc.c445
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_emc.h364
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c411
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.h64
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_gpio.c302
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_gpio.h364
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_iocon.h288
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_power.c20
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_power.h225
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_reset.c132
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_reset.h277
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_usart.c981
-rw-r--r--FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_usart.h721
17 files changed, 9587 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_clock.c b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_clock.c
new file mode 100644
index 000000000..98cf2bcee
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_clock.c
@@ -0,0 +1,2827 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016 - 2019 , NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_clock.h"
+#include "fsl_power.h"
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.clock"
+#endif
+#define NVALMAX (0x100U)
+#define PVALMAX (0x20U)
+#define MVALMAX (0x8000U)
+
+#define USB_NVALMAX (0x4U)
+#define USB_PVALMAX (0x8U)
+#define USB_MVALMAX (0x100U)
+
+#define PLL_MAX_N_DIV 0x100U
+#define USB_PLL_MAX_N_DIV 0x100U
+
+#define PLL_MDEC_VAL_P (0U) /*!< MDEC is in bits 16 downto 0 */
+#define PLL_MDEC_VAL_M (0x1FFFFUL << PLL_MDEC_VAL_P) /*!< NDEC is in bits 9 downto 0 */
+#define PLL_NDEC_VAL_P (0U) /*!< NDEC is in bits 9:0 */
+#define PLL_NDEC_VAL_M (0x3FFUL << PLL_NDEC_VAL_P)
+#define PLL_PDEC_VAL_P (0U) /*!< PDEC is in bits 6:0 */
+#define PLL_PDEC_VAL_M (0x7FUL << PLL_PDEC_VAL_P)
+
+#define PLL_MIN_CCO_FREQ_MHZ (275000000U)
+#define PLL_MAX_CCO_FREQ_MHZ (550000000U)
+#define PLL_LOWER_IN_LIMIT (4000U) /*!< Minimum PLL input rate */
+#define PLL_MIN_IN_SSMODE (2000000U)
+#define PLL_MAX_IN_SSMODE (4000000U)
+
+/*!< Middle of the range values for spread-spectrum */
+#define PLL_SSCG_MF_FREQ_VALUE 4U
+#define PLL_SSCG_MC_COMP_VALUE 2U
+#define PLL_SSCG_MR_DEPTH_VALUE 4U
+#define PLL_SSCG_DITHER_VALUE 0U
+
+/*!< USB PLL CCO MAX AND MIN FREQ */
+#define USB_PLL_MIN_CCO_FREQ_MHZ (156000000U)
+#define USB_PLL_MAX_CCO_FREQ_MHZ (320000000U)
+#define USB_PLL_LOWER_IN_LIMIT (1000000U) /*!< Minimum PLL input rate */
+
+#define USB_PLL_MSEL_VAL_P (0U) /*!< MSEL is in bits 7 downto 0 */
+#define USB_PLL_MSEL_VAL_M (0xFFU)
+#define USB_PLL_PSEL_VAL_P (8U) /*!< PDEC is in bits 9:8 */
+#define USB_PLL_PSEL_VAL_M (0x3U)
+#define USB_PLL_NSEL_VAL_P (10U) /*!< NDEC is in bits 11:10 */
+#define USB_PLL_NSEL_VAL_M (0x3U)
+
+/*!< SWITCH USB POSTDIVIDER FOR REGITSER WRITING */
+#define SWITCH_USB_PSEL(x) \
+ (((x) == 0x0U) ? 0x1U : ((x) == 0x1U) ? 0x02U : ((x) == 0x2U) ? 0x4U : ((x) == 3U) ? 0x8U : 0U)
+
+/*!< SYS PLL NDEC reg */
+#define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M)
+/*!< SYS PLL PDEC reg */
+#define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M)
+/*!< SYS PLL MDEC reg */
+#define PLL_MDEC_VAL_SET(value) (((unsigned long)(value) << PLL_MDEC_VAL_P) & PLL_MDEC_VAL_M)
+
+/*!< SYS PLL NSEL reg */
+#define USB_PLL_NSEL_VAL_SET(value) (((unsigned long)(value)&USB_PLL_NSEL_VAL_M) << USB_PLL_NSEL_VAL_P)
+/*!< SYS PLL PSEL reg */
+#define USB_PLL_PSEL_VAL_SET(value) (((unsigned long)(value)&USB_PLL_PSEL_VAL_M) << USB_PLL_PSEL_VAL_P)
+/*!< SYS PLL MSEL reg */
+#define USB_PLL_MSEL_VAL_SET(value) (((unsigned long)(value)&USB_PLL_MSEL_VAL_M) << USB_PLL_MSEL_VAL_P)
+
+/*!< FRAC control */
+#define AUDIO_PLL_FRACT_MD_P (0U)
+#define AUDIO_PLL_FRACT_MD_INT_P (15U)
+#define AUDIO_PLL_FRACT_MD_M (0x7FFFUL << AUDIO_PLL_FRACT_MD_P)
+#define AUDIO_PLL_FRACT_MD_INT_M (0x7FUL << AUDIO_PLL_FRACT_MD_INT_P)
+
+#define AUDIO_PLL_MD_FRACT_SET(value) (((unsigned long)(value) << AUDIO_PLL_FRACT_MD_P) & PLL_FRAC_MD_FRACT_M)
+#define AUDIO_PLL_MD_INT_SET(value) (((unsigned long)(value) << AUDIO_PLL_FRACT_MD_INT_P) & AUDIO_PLL_FRACT_MD_INT_M)
+
+/* Saved value of PLL output rate, computed whenever needed to save run-time
+ computation on each call to retrive the PLL rate. */
+static uint32_t s_Pll_Freq;
+static uint32_t s_Usb_Pll_Freq;
+static uint32_t s_Audio_Pll_Freq;
+
+/** External clock rate on the CLKIN pin in Hz. If not used,
+ set this to 0. Otherwise, set it to the exact rate in Hz this pin is
+ being driven at. */
+static const uint32_t g_I2S_Mclk_Freq = 0U;
+static const uint32_t g_Ext_Clk_Freq = 12000000U;
+static const uint32_t g_Lcd_Clk_In_Freq = 0U;
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/* Find encoded NDEC value for raw N value, max N = NVALMAX */
+static uint32_t pllEncodeN(uint32_t N);
+/* Find decoded N value for raw NDEC value */
+static uint32_t pllDecodeN(uint32_t NDEC);
+/* Find encoded PDEC value for raw P value, max P = PVALMAX */
+static uint32_t pllEncodeP(uint32_t P);
+/* Find decoded P value for raw PDEC value */
+static uint32_t pllDecodeP(uint32_t PDEC);
+/* Find encoded MDEC value for raw M value, max M = MVALMAX */
+static uint32_t pllEncodeM(uint32_t M);
+/* Find decoded M value for raw MDEC value */
+static uint32_t pllDecodeM(uint32_t MDEC);
+/* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
+static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR);
+/* Get predivider (N) from PLL NDEC setting */
+static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg);
+/* Get postdivider (P) from PLL PDEC setting */
+static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg);
+/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
+static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg);
+/* Convert the binary to fractional part */
+static double Binary2Fractional(uint32_t binaryPart);
+/* Calculate the powerTimes' power of 2 */
+static uint32_t power2Cal(uint32_t powerTimes);
+/* Get the greatest common divisor */
+static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n);
+/* Set PLL output based on desired output rate */
+static pll_error_t CLOCK_GetPllConfig(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup);
+
+/* Update local PLL rate variable */
+static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup);
+static void CLOCK_GetAudioPLLOutFromSetupUpdate(pll_setup_t *pSetup);
+
+/*!
+ * @brief Set fro clock frequency.
+ * Due to LPC540xx 0A silicon and LPC540xx 1B silicon have different ROM addresses for set fro
+ * frequency api, so add this api to get rom version.
+ * @param base romVersion pointer to recieve rom version.
+ */
+#if defined(FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION) && \
+ (FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION)
+static uint32_t CLOCK_GetRomVersion(uint8_t *romVersion);
+#endif
+
+static const uint8_t wdtFreqLookup[32] = {0, 8, 12, 15, 18, 20, 24, 26, 28, 30, 32, 34, 36, 38, 40, 41,
+ 42, 44, 45, 46, 48, 49, 50, 52, 53, 54, 56, 57, 58, 59, 60, 61};
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+#if defined(FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION) && \
+ (FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION)
+static uint32_t CLOCK_GetRomVersion(uint8_t *romVersion)
+{
+ uint32_t command[5] = {0U}, result[4] = {0U};
+
+ command[0] = 55U;
+ result[0] = 0;
+ result[1] = 0;
+ ((void (*)(uint32_t cmd[5], uint32_t stat[4]))FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION)(command, result);
+
+ *romVersion = (uint8_t)(result[1]);
+
+ return result[0];
+}
+#endif
+
+/**
+ * brief
+ * Initialize the Core clock to given frequency (12, 48 or 96 MHz), this API is implememnt in ROM code.
+ * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed
+ * output is enabled.
+ * Usage: CLOCK_SetupFROClocking(frequency), (frequency must be one of 12, 48 or 96 MHz)
+ * Note: Need to make sure ROM and OTP has power(PDRUNCFG0[17,29]= 0U) before calling this API since this API is
+ * implemented in ROM code and the FROHF TRIM value is stored in OTP
+ *
+ * param froFreq target fro frequency.
+ * return Nothing
+ */
+
+void CLOCK_SetupFROClocking(uint32_t froFreq)
+{
+ uint32_t froRomAddr = 0U;
+#if defined(FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION) && \
+ (FSL_FROHF_SETTING_API_ADDRESS_DETERMINE_BY_ROM_VERSION)
+ uint8_t romVersion = 0U;
+
+ if (CLOCK_GetRomVersion(&romVersion) == (uint32_t)kStatus_Success)
+ {
+ if (romVersion == FSL_ROM_VERSION_1B)
+ {
+ froRomAddr = FSL_ROM_VERSION_1B_FRO_SETTING_ADDR;
+ }
+ else
+ {
+ froRomAddr = FSL_ROM_VERSION_0A_FRO_SETTING_ADDR;
+ }
+
+ (*((void (*)(uint32_t funcname))(froRomAddr)))(froFreq);
+ }
+#else
+ froRomAddr = FSL_ROM_VERSION_0A_FRO_SETTING_ADDR;
+
+ (*((void (*)(uint32_t))(froRomAddr)))(froFreq);
+#endif
+}
+
+/* Clock Selection for IP */
+/**
+ * brief Configure the clock selection muxes.
+ * param connection : Clock to be configured.
+ * return Nothing
+ */
+void CLOCK_AttachClk(clock_attach_id_t connection)
+{
+ uint8_t mux;
+ uint8_t sel;
+ uint16_t item;
+ uint32_t tmp32 = (uint32_t)connection;
+ uint32_t i;
+ volatile uint32_t *pClkSel;
+
+ pClkSel = &(SYSCON->STICKCLKSEL);
+
+ if (kNONE_to_NONE != connection)
+ {
+ for (i = 0U; i < 2U; i++)
+ {
+ if (tmp32 == 0U)
+ {
+ break;
+ }
+ item = (uint16_t)GET_ID_ITEM(tmp32);
+ if (item != 0UL)
+ {
+ mux = GET_ID_ITEM_MUX(item);
+ sel = GET_ID_ITEM_SEL(item);
+ if (mux == CM_ASYNCAPB)
+ {
+ SYSCON->ASYNCAPBCTRL = SYSCON_ASYNCAPBCTRL_ENABLE(1);
+ ASYNC_SYSCON->ASYNCAPBCLKSELA = sel;
+ }
+ else
+ {
+ ((volatile uint32_t *)pClkSel)[mux] = sel;
+ }
+ }
+ tmp32 = GET_ID_NEXT_ITEM(tmp32); /* pick up next descriptor */
+ }
+ }
+}
+
+/* Return the actual clock attach id */
+/**
+ * brief Get the actual clock attach id.
+ * This fuction uses the offset in input attach id, then it reads the actual source value in
+ * the register and combine the offset to obtain an actual attach id.
+ * param attachId : Clock attach id to get.
+ * return Clock source value.
+ */
+clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId)
+{
+ uint8_t mux;
+ uint8_t actualSel;
+ uint32_t tmp32 = (uint32_t)attachId;
+ uint32_t i;
+ uint32_t actualAttachId = 0U;
+ uint32_t selector = GET_ID_SELECTOR(tmp32);
+ volatile uint32_t *pClkSel;
+
+ pClkSel = &(SYSCON->STICKCLKSEL);
+
+ if (kNONE_to_NONE == attachId)
+ {
+ return kNONE_to_NONE;
+ }
+
+ for (i = 0U; i < 2U; i++)
+ {
+ mux = GET_ID_ITEM_MUX(tmp32);
+ if (tmp32 != 0UL)
+ {
+ if (mux == CM_ASYNCAPB)
+ {
+ actualSel = (uint8_t)(ASYNC_SYSCON->ASYNCAPBCLKSELA);
+ }
+ else
+ {
+ actualSel = (uint8_t)(((volatile uint32_t *)pClkSel)[mux]);
+ }
+
+ /* Consider the combination of two registers */
+ actualAttachId |= CLK_ATTACH_ID(mux, actualSel, i);
+ }
+ tmp32 = GET_ID_NEXT_ITEM(tmp32); /*!< pick up next descriptor */
+ }
+
+ actualAttachId |= selector;
+
+ return (clock_attach_id_t)actualAttachId;
+}
+
+/* Set IP Clock Divider */
+/**
+ * brief Setup peripheral clock dividers.
+ * param div_name : Clock divider name
+ * param divided_by_value: Value to be divided
+ * param reset : Whether to reset the divider counter.
+ * return Nothing
+ */
+void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset)
+{
+ volatile uint32_t *pClkDiv;
+
+ pClkDiv = &(SYSCON->SYSTICKCLKDIV);
+ if (reset)
+ {
+ ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 29U;
+ }
+ if (divided_by_value == 0U) /*!< halt */
+ {
+ ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = 1UL << 30U;
+ }
+ else
+ {
+ ((volatile uint32_t *)pClkDiv)[(uint8_t)div_name] = (divided_by_value - 1U);
+ }
+}
+
+/* Get CLOCK OUT Clk */
+/*! brief Return Frequency of ClockOut
+ * return Frequency of ClockOut
+ */
+uint32_t CLOCK_GetClockOutClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->CLKOUTSELA)
+ {
+ case 0U:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+
+ case 1U:
+ freq = CLOCK_GetExtClkFreq();
+ break;
+
+ case 2U:
+ freq = CLOCK_GetWdtOscFreq();
+ break;
+
+ case 3U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+
+ case 4U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+
+ case 5U:
+ freq = CLOCK_GetUsbPllOutFreq();
+ break;
+
+ case 6U:
+ freq = CLOCK_GetAudioPllOutFreq();
+ break;
+
+ case 7U:
+ freq = CLOCK_GetOsc32KFreq();
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+ return freq / ((SYSCON->CLKOUTDIV & 0xffU) + 1U);
+}
+
+/* Get SPIFI Clk */
+/*! brief Return Frequency of Spifi Clock
+ * return Frequency of Spifi.
+ */
+uint32_t CLOCK_GetSpifiClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->SPIFICLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case 2U:
+ freq = CLOCK_GetUsbPllOutFreq();
+ break;
+ case 3U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+ case 4U:
+ freq = CLOCK_GetAudioPllOutFreq();
+ break;
+ case 7U:
+ freq = 0U;
+ break;
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq / ((SYSCON->SPIFICLKDIV & 0xffU) + 1U);
+}
+
+/* Get ADC Clk */
+/*! brief Return Frequency of Adc Clock
+ * return Frequency of Adc Clock.
+ */
+uint32_t CLOCK_GetAdcClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->ADCCLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case 2U:
+ freq = CLOCK_GetUsbPllOutFreq();
+ break;
+ case 3U:
+ freq = CLOCK_GetAudioPllOutFreq();
+ break;
+ case 7U:
+ freq = 0U;
+ break;
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq / ((SYSCON->ADCCLKDIV & 0xffU) + 1U);
+}
+
+/* Get USB0 Clk */
+/*! brief Return Frequency of Usb0 Clock
+ * return Frequency of Usb0 Clock.
+ */
+uint32_t CLOCK_GetUsb0ClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->USB0CLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case 2U:
+ freq = CLOCK_GetUsbPllOutFreq();
+ break;
+ case 7U:
+ freq = 0U;
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq / ((SYSCON->USB0CLKDIV & 0xffU) + 1U);
+}
+
+/* Get USB1 Clk */
+/*! brief Return Frequency of Usb1 Clock
+ * return Frequency of Usb1 Clock.
+ */
+uint32_t CLOCK_GetUsb1ClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->USB1CLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case 2U:
+ freq = CLOCK_GetUsbPllOutFreq();
+ break;
+ case 7U:
+ freq = 0U;
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq / ((SYSCON->USB1CLKDIV & 0xffU) + 1U);
+}
+
+/* Get MCLK Clk */
+/*! brief Return Frequency of MClk Clock
+ * return Frequency of MClk Clock.
+ */
+uint32_t CLOCK_GetMclkClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->MCLKCLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffu) + 1U);
+ break;
+ case 1U:
+ freq = CLOCK_GetAudioPllOutFreq();
+ break;
+ case 7U:
+ freq = 0U;
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq / ((SYSCON->MCLKDIV & 0xffU) + 1U);
+}
+
+/* Get SCTIMER Clk */
+/*! brief Return Frequency of SCTimer Clock
+ * return Frequency of SCTimer Clock.
+ */
+uint32_t CLOCK_GetSctClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->SCTCLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case 2U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+ case 3U:
+ freq = CLOCK_GetAudioPllOutFreq();
+ break;
+ case 7U:
+ freq = 0U;
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq / ((SYSCON->SCTCLKDIV & 0xffU) + 1U);
+}
+
+/* Get SDIO Clk */
+/*! brief Return Frequency of SDIO Clock
+ * return Frequency of SDIO Clock.
+ */
+uint32_t CLOCK_GetSdioClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->SDIOCLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case 2U:
+ freq = CLOCK_GetUsbPllOutFreq();
+ break;
+ case 3U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+ case 4U:
+ freq = CLOCK_GetAudioPllOutFreq();
+ break;
+ case 7U:
+ freq = 0U;
+ break;
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq / ((SYSCON->SDIOCLKDIV & 0xffU) + 1U);
+}
+
+/* Get LCD Clk */
+/*! brief Return Frequency of LCD Clock
+ * return Frequency of LCD Clock.
+ */
+uint32_t CLOCK_GetLcdClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->LCDCLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetLcdClkIn();
+ break;
+ case 2U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+ case 3U:
+ freq = 0U;
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq / ((SYSCON->LCDCLKDIV & 0xffU) + 1U);
+}
+
+/* Get LCD CLK IN Clk */
+/*! brief Return Frequency of LCD CLKIN Clock
+ * return Frequency of LCD CLKIN Clock.
+ */
+uint32_t CLOCK_GetLcdClkIn(void)
+{
+ return g_Lcd_Clk_In_Freq;
+}
+
+/* Get FRO 12M Clk */
+/*! brief Return Frequency of FRO 12MHz
+ * return Frequency of FRO 12MHz
+ */
+uint32_t CLOCK_GetFro12MFreq(void)
+{
+ return ((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK) != 0UL) ? 0U : 12000000U;
+}
+
+/* Get EXT OSC Clk */
+/*! brief Return Frequency of External Clock
+ * return Frequency of External Clock. If no external clock is used returns 0.
+ */
+uint32_t CLOCK_GetExtClkFreq(void)
+{
+ return g_Ext_Clk_Freq;
+}
+
+/* Get WATCH DOG Clk */
+/*! brief Return Frequency of Watchdog Oscillator
+ * return Frequency of Watchdog Oscillator
+ */
+uint32_t CLOCK_GetWdtOscFreq(void)
+{
+ uint8_t freq_sel, div_sel;
+ if ((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_WDT_OSC_MASK) != 0UL)
+ {
+ return 0U;
+ }
+ else
+ {
+ div_sel = (uint8_t)(((SYSCON->WDTOSCCTRL & 0x1fU) + 1U) << 1U);
+ freq_sel =
+ wdtFreqLookup[((SYSCON->WDTOSCCTRL & SYSCON_WDTOSCCTRL_FREQSEL_MASK) >> SYSCON_WDTOSCCTRL_FREQSEL_SHIFT)];
+ return ((uint32_t)freq_sel * 50000U) / ((uint32_t)div_sel);
+ }
+}
+
+/* Get HF FRO Clk */
+/*! brief Return Frequency of High-Freq output of FRO
+ * return Frequency of High-Freq output of FRO
+ */
+uint32_t CLOCK_GetFroHfFreq(void)
+{
+ if (((SYSCON->PDRUNCFG[0] & SYSCON_PDRUNCFG_PDEN_FRO_MASK) != 0UL) ||
+ (0UL == (SYSCON->FROCTRL & SYSCON_FROCTRL_HSPDCLK_MASK)))
+ {
+ return 0U;
+ }
+
+ if ((SYSCON->FROCTRL & SYSCON_FROCTRL_SEL_MASK) != 0UL)
+ {
+ return 96000000U;
+ }
+ else
+ {
+ return 48000000U;
+ }
+}
+
+/* Get SYSTEM PLL Clk */
+/*! brief Return Frequency of PLL
+ * return Frequency of PLL
+ */
+uint32_t CLOCK_GetPllOutFreq(void)
+{
+ return s_Pll_Freq;
+}
+
+/* Get AUDIO PLL Clk */
+/*! brief Return Frequency of AUDIO PLL
+ * return Frequency of PLL
+ */
+uint32_t CLOCK_GetAudioPllOutFreq(void)
+{
+ return s_Audio_Pll_Freq;
+}
+
+/* Get USB PLL Clk */
+/*! brief Return Frequency of USB PLL
+ * return Frequency of PLL
+ */
+uint32_t CLOCK_GetUsbPllOutFreq(void)
+{
+ return s_Usb_Pll_Freq;
+}
+
+/* Get RTC OSC Clk */
+/*! brief Return Frequency of 32kHz osc
+ * return Frequency of 32kHz osc
+ */
+uint32_t CLOCK_GetOsc32KFreq(void)
+{
+ return CLK_RTC_32K_CLK; /* Needs to be corrected to check that RTC Clock is enabled */
+}
+
+/* Get MAIN Clk */
+/*! brief Return Frequency of Core System
+ * return Frequency of Core System
+ */
+uint32_t CLOCK_GetCoreSysClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->MAINCLKSELB)
+ {
+ case 0U:
+ if (SYSCON->MAINCLKSELA == 0U)
+ {
+ freq = CLOCK_GetFro12MFreq();
+ }
+ else if (SYSCON->MAINCLKSELA == 1U)
+ {
+ freq = CLOCK_GetExtClkFreq();
+ }
+ else if (SYSCON->MAINCLKSELA == 2U)
+ {
+ freq = CLOCK_GetWdtOscFreq();
+ }
+ else if (SYSCON->MAINCLKSELA == 3U)
+ {
+ freq = CLOCK_GetFroHfFreq();
+ }
+ else
+ {
+ /* Add comment to prevent the case of rule 15.7. */
+ }
+ break;
+ case 2U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+
+ case 3U:
+ freq = CLOCK_GetOsc32KFreq();
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq;
+}
+
+/* Get I2S MCLK Clk */
+/*! brief Return Frequency of I2S MCLK Clock
+ * return Frequency of I2S MCLK Clock
+ */
+uint32_t CLOCK_GetI2SMClkFreq(void)
+{
+ return g_I2S_Mclk_Freq;
+}
+
+/* Get ASYNC APB Clk */
+/*! brief Return Frequency of Asynchronous APB Clock
+ * return Frequency of Asynchronous APB Clock Clock
+ */
+uint32_t CLOCK_GetAsyncApbClkFreq(void)
+{
+ async_clock_src_t clkSrc;
+ uint32_t clkRate;
+
+ clkSrc = CLOCK_GetAsyncApbClkSrc();
+
+ switch (clkSrc)
+ {
+ case kCLOCK_AsyncMainClk:
+ clkRate = CLOCK_GetCoreSysClkFreq();
+ break;
+ case kCLOCK_AsyncFro12Mhz:
+ clkRate = CLK_FRO_12MHZ;
+ break;
+ default:
+ clkRate = 0U;
+ break;
+ }
+
+ return clkRate;
+}
+
+/* Get MCAN Clk */
+/*! brief Return Frequency of MCAN Clock
+ * param MCanSel : 0U: MCAN0; 1U: MCAN1
+ * return Frequency of MCAN Clock
+ */
+uint32_t CLOCK_GetMCanClkFreq(uint32_t MCanSel)
+{
+ uint32_t freq = 0U;
+ switch (MCanSel)
+ {
+ case 0U:
+ freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->CAN0CLKDIV & 0xffU) + 1U);
+ break;
+ case 1U:
+ freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->CAN1CLKDIV & 0xffU) + 1U);
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq;
+}
+
+/* Get FLEXCOMM Clk */
+/*! brief Return Frequency of Flexcomm functional Clock
+ * return Frequency of Flexcomm functional Clock
+ */
+uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id)
+{
+ uint32_t freq = 0U;
+
+ if (id != 10U)
+ {
+ switch (SYSCON->FCLKSEL[id])
+ {
+ case 0U:
+ freq = CLOCK_GetFro12MFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetFroHfFreq() / ((SYSCON->FROHFDIV & 0xffu) + 1U);
+ break;
+ case 2U:
+ freq = CLOCK_GetAudioPllOutFreq();
+ break;
+ case 3U:
+ freq = CLOCK_GetI2SMClkFreq();
+ break;
+ case 4U:
+ freq = CLOCK_GetFrgClkFreq();
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+ }
+ else
+ {
+ switch (SYSCON->FCLKSEL10)
+ {
+ case 0U:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case 2U:
+ freq = CLOCK_GetUsbPllOutFreq();
+ break;
+ case 3U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+ case 4U:
+ freq = CLOCK_GetAudioPllOutFreq();
+ break;
+ default:
+ freq = 0U;
+ break;
+ }
+ }
+
+ return freq;
+}
+
+/* Get FRG Clk */
+uint32_t CLOCK_GetFRGInputClock(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->FRGCLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case 2U:
+ freq = CLOCK_GetFro12MFreq();
+ break;
+ case 3U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq;
+}
+
+/* Get FRG Clk */
+/*! brief Return Frequency of frg
+ * return Frequency of FRG
+ */
+uint32_t CLOCK_GetFrgClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ if ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_DIV_MASK) == SYSCON_FRGCTRL_DIV_MASK)
+ {
+ freq = (uint32_t)(((uint64_t)CLOCK_GetFRGInputClock() * (SYSCON_FRGCTRL_DIV_MASK + 1U)) /
+ ((SYSCON_FRGCTRL_DIV_MASK + 1U) +
+ ((SYSCON->FRGCTRL & SYSCON_FRGCTRL_MULT_MASK) >> SYSCON_FRGCTRL_MULT_SHIFT)));
+ }
+ else
+ {
+ freq = 0U;
+ }
+
+ return freq;
+}
+
+/* Get FRG Clk */
+/*! brief Return Frequency of dmic
+ * return Frequency of DMIC
+ */
+uint32_t CLOCK_GetDmicClkFreq(void)
+{
+ uint32_t freq = 0U;
+
+ switch (SYSCON->DMICCLKSEL)
+ {
+ case 0U:
+ freq = CLOCK_GetFro12MFreq();
+ break;
+ case 1U:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+ case 2U:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case 3U:
+ freq = CLOCK_GetI2SMClkFreq();
+ break;
+ case 4U:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+ case 5U:
+ freq = CLOCK_GetWdtOscFreq();
+ break;
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq / ((SYSCON->DMICCLKDIV & 0xffU) + 1U);
+ ;
+}
+
+/* Set FRG Clk */
+uint32_t CLOCK_SetFRGClock(uint32_t freq)
+{
+ assert(0UL != freq);
+
+ uint32_t input = CLOCK_GetFRGInputClock();
+ uint32_t mul;
+
+ if ((freq > 48000000U) || (freq > input) || (input / freq >= 2U))
+ {
+ /* FRG output frequency should be less than equal to 48MHz */
+ return 0U;
+ }
+ else
+ {
+ mul = (uint32_t)((((uint64_t)input - freq) * 256U) / ((uint64_t)freq));
+ SYSCON->FRGCTRL = (mul << SYSCON_FRGCTRL_MULT_SHIFT) | SYSCON_FRGCTRL_DIV_MASK;
+ return 1U;
+ }
+}
+
+/* Set IP Clk */
+/*! brief Return Frequency of selected clock
+ * return Frequency of selected clock
+ */
+uint32_t CLOCK_GetFreq(clock_name_t clockName)
+{
+ uint32_t freq;
+ switch (clockName)
+ {
+ case kCLOCK_CoreSysClk:
+ freq = CLOCK_GetCoreSysClkFreq();
+ break;
+ case kCLOCK_BusClk:
+ freq = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
+ break;
+ case kCLOCK_ClockOut:
+ freq = CLOCK_GetClockOutClkFreq();
+ break;
+ case kCLOCK_Mclk:
+ freq = CLOCK_GetMclkClkFreq();
+ break;
+ case kCLOCK_FroHf:
+ freq = CLOCK_GetFroHfFreq();
+ break;
+ case kCLOCK_Fro12M:
+ freq = CLOCK_GetFro12MFreq();
+ break;
+ case kCLOCK_ExtClk:
+ freq = CLOCK_GetExtClkFreq();
+ break;
+ case kCLOCK_PllOut:
+ freq = CLOCK_GetPllOutFreq();
+ break;
+ case kCLOCK_WdtOsc:
+ freq = CLOCK_GetWdtOscFreq();
+ break;
+ case kCLOCK_Frg:
+ freq = CLOCK_GetFrgClkFreq();
+ break;
+
+ case kCLOCK_AsyncApbClk:
+ freq = CLOCK_GetAsyncApbClkFreq();
+ break;
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq;
+}
+
+/* Find encoded NDEC value for raw N value, max N = NVALMAX */
+static uint32_t pllEncodeN(uint32_t N)
+{
+ uint32_t x, i;
+
+ /* Find NDec */
+ switch (N)
+ {
+ case 0U:
+ x = 0x3FFU;
+ break;
+
+ case 1U:
+ x = 0x302U;
+ break;
+
+ case 2U:
+ x = 0x202U;
+ break;
+
+ default:
+ x = 0x080U;
+ for (i = N; i <= NVALMAX; i++)
+ {
+ x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
+ }
+ break;
+ }
+
+ return x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P);
+}
+
+/* Find decoded N value for raw NDEC value */
+static uint32_t pllDecodeN(uint32_t NDEC)
+{
+ uint32_t n, x, i;
+
+ /* Find NDec */
+ switch (NDEC)
+ {
+ case 0x3FFU:
+ n = 0U;
+ break;
+
+ case 0x302U:
+ n = 1U;
+ break;
+
+ case 0x202U:
+ n = 2U;
+ break;
+
+ default:
+ x = 0x080U;
+ n = 0xFFFFFFFFU;
+ for (i = NVALMAX; i >= 3U; i--)
+ {
+ x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU);
+ if ((x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P)) == NDEC)
+ {
+ /* Decoded value of NDEC */
+ n = i;
+ break;
+ }
+ }
+ break;
+ }
+
+ return n;
+}
+
+/* Find encoded PDEC value for raw P value, max P = PVALMAX */
+static uint32_t pllEncodeP(uint32_t P)
+{
+ uint32_t x, i;
+
+ /* Find PDec */
+ switch (P)
+ {
+ case 0U:
+ x = 0x7FU;
+ break;
+
+ case 1U:
+ x = 0x62U;
+ break;
+
+ case 2U:
+ x = 0x42U;
+ break;
+
+ default:
+ x = 0x10U;
+ for (i = P; i <= PVALMAX; i++)
+ {
+ x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
+ }
+ break;
+ }
+
+ return x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P);
+}
+
+/* Find decoded P value for raw PDEC value */
+static uint32_t pllDecodeP(uint32_t PDEC)
+{
+ uint32_t p, x, i;
+
+ /* Find PDec */
+ switch (PDEC)
+ {
+ case 0x7FU:
+ p = 0U;
+ break;
+
+ case 0x62U:
+ p = 1U;
+ break;
+
+ case 0x42U:
+ p = 2U;
+ break;
+
+ default:
+ x = 0x10U;
+ p = 0xFFFFFFFFU;
+ for (i = PVALMAX; i >= 3U; i--)
+ {
+ x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU);
+ if ((x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P)) == PDEC)
+ {
+ /* Decoded value of PDEC */
+ p = i;
+ break;
+ }
+ }
+ break;
+ }
+
+ return p;
+}
+
+/* Find encoded MDEC value for raw M value, max M = MVALMAX */
+static uint32_t pllEncodeM(uint32_t M)
+{
+ uint32_t i, x;
+
+ /* Find MDec */
+ switch (M)
+ {
+ case 0U:
+ x = 0x1FFFFU;
+ break;
+
+ case 1U:
+ x = 0x18003U;
+ break;
+
+ case 2U:
+ x = 0x10003U;
+ break;
+
+ default:
+ x = 0x04000U;
+ for (i = M; i <= MVALMAX; i++)
+ {
+ x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
+ }
+ break;
+ }
+
+ return x & (PLL_MDEC_VAL_M >> PLL_MDEC_VAL_P);
+}
+
+/* Find decoded M value for raw MDEC value */
+static uint32_t pllDecodeM(uint32_t MDEC)
+{
+ uint32_t m, i, x;
+
+ /* Find MDec */
+ switch (MDEC)
+ {
+ case 0x1FFFFU:
+ m = 0U;
+ break;
+
+ case 0x18003U:
+ m = 1U;
+ break;
+
+ case 0x10003U:
+ m = 2U;
+ break;
+
+ default:
+ x = 0x04000U;
+ m = 0xFFFFFFFFU;
+ for (i = MVALMAX; i >= 3U; i--)
+ {
+ x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU);
+ if ((x & (PLL_MDEC_VAL_M >> PLL_MDEC_VAL_P)) == MDEC)
+ {
+ /* Decoded value of MDEC */
+ m = i;
+ break;
+ }
+ }
+ break;
+ }
+
+ return m;
+}
+
+/* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */
+static void pllFindSel(uint32_t M, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR)
+{
+ /* bandwidth: compute selP from Multiplier */
+ if (M < 60U)
+ {
+ *pSelP = (M >> 1U) + 1U;
+ }
+ else
+ {
+ *pSelP = PVALMAX - 1U;
+ }
+
+ /* bandwidth: compute selI from Multiplier */
+ if (M > 16384U)
+ {
+ *pSelI = 1U;
+ }
+ else if (M > 8192U)
+ {
+ *pSelI = 2U;
+ }
+ else if (M > 2048U)
+ {
+ *pSelI = 4U;
+ }
+ else if (M >= 501U)
+ {
+ *pSelI = 8U;
+ }
+ else if (M >= 60U)
+ {
+ *pSelI = 4U * (1024U / (M + 9U));
+ }
+ else
+ {
+ *pSelI = (M & 0x3CU) + 4U;
+ }
+
+ if (*pSelI > ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT))
+ {
+ *pSelI = ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT);
+ }
+
+ *pSelR = 0U;
+}
+
+/* Get predivider (N) from PLL NDEC setting */
+static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg)
+{
+ uint32_t preDiv = 1;
+
+ /* Direct input is not used? */
+ if ((ctrlReg & (1UL << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) == 0U)
+ {
+ /* Decode NDEC value to get (N) pre divider */
+ preDiv = pllDecodeN(nDecReg & 0x3FFU);
+ if (preDiv == 0U)
+ {
+ preDiv = 1U;
+ }
+ }
+
+ /* Adjusted by 1, directi is used to bypass */
+ return preDiv;
+}
+
+/* Get postdivider (P) from PLL PDEC setting */
+static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg)
+{
+ uint32_t postDiv = 1U;
+
+ /* Direct input is not used? */
+ if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTO_MASK) == 0U)
+ {
+ /* Decode PDEC value to get (P) post divider */
+ postDiv = 2U * pllDecodeP(pDecReg & 0x7FU);
+ if (postDiv == 0U)
+ {
+ postDiv = 2U;
+ }
+ }
+
+ /* Adjusted by 1, directo is used to bypass */
+ return postDiv;
+}
+
+/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */
+static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg)
+{
+ uint32_t mMult = 1U;
+
+ /* Decode MDEC value to get (M) multiplier */
+ mMult = pllDecodeM(mDecReg & 0x1FFFFU);
+
+ if (mMult == 0U)
+ {
+ mMult = 1U;
+ }
+
+ return mMult;
+}
+
+/* Calculate the powerTimes' power of 2 */
+static uint32_t power2Cal(uint32_t powerTimes)
+{
+ uint32_t ret = 1U;
+ uint32_t i;
+ for (i = 0; i < powerTimes; i++)
+ {
+ ret *= 2U;
+ }
+
+ return ret;
+}
+
+/* Convert the binary to fractional part */
+static double Binary2Fractional(uint32_t binaryPart)
+{
+ double fractional = 0.0;
+ for (uint32_t i = 0U; i <= 14U; i++)
+ {
+ fractional += (double)(uint32_t)((binaryPart >> i) & 0x1U) / (double)(uint32_t)power2Cal(15U - i);
+ }
+ return fractional;
+}
+
+/* Find greatest common divisor between m and n */
+static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n)
+{
+ uint32_t tmp;
+
+ while (n != 0U)
+ {
+ tmp = n;
+ n = m % n;
+ m = tmp;
+ }
+
+ return m;
+}
+
+/*
+ * Set PLL output based on desired output rate.
+ * In this function, the it calculates the PLL setting for output frequency from input clock
+ * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently.
+ * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function.
+ */
+static pll_error_t CLOCK_GetPllConfigInternal(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup)
+{
+ uint32_t nDivOutHz, fccoHz, multFccoDiv;
+ uint32_t pllPreDivider, pllMultiplier, pllPostDivider;
+ uint32_t pllDirectInput, pllDirectOutput;
+ uint32_t pllSelP, pllSelI, pllSelR, uplimoff;
+
+ /* Baseline parameters (no input or output dividers) */
+ pllPreDivider = 1U; /* 1 implies pre-divider will be disabled */
+ pllPostDivider = 0U; /* 0 implies post-divider will be disabled */
+ pllDirectOutput = 1U;
+ multFccoDiv = 2U;
+
+ /* Verify output rate parameter */
+ if (foutHz > PLL_MAX_CCO_FREQ_MHZ)
+ {
+ /* Maximum PLL output with post divider=1 cannot go above this frequency */
+ return kStatus_PLL_OutputTooHigh;
+ }
+ if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U)))
+ {
+ /* Minmum PLL output with maximum post divider cannot go below this frequency */
+ return kStatus_PLL_OutputTooLow;
+ }
+
+ /* Verify input rate parameter */
+ if (finHz < PLL_LOWER_IN_LIMIT)
+ {
+ /* Input clock into the PLL cannot be lower than this */
+ return kStatus_PLL_InputTooLow;
+ }
+
+ /* Find the optimal CCO frequency for the output and input that
+ will keep it inside the PLL CCO range. This may require
+ tweaking the post-divider for the PLL. */
+ fccoHz = foutHz;
+ while (fccoHz < PLL_MIN_CCO_FREQ_MHZ)
+ {
+ /* CCO output is less than minimum CCO range, so the CCO output
+ needs to be bumped up and the post-divider is used to bring
+ the PLL output back down. */
+ pllPostDivider++;
+ if (pllPostDivider > PVALMAX)
+ {
+ return kStatus_PLL_OutsideIntLimit;
+ }
+
+ /* Target CCO goes up, PLL output goes down */
+ fccoHz = foutHz * (pllPostDivider * 2U);
+ pllDirectOutput = 0U;
+ }
+
+ /* Determine if a pre-divider is needed to get the best frequency */
+ if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz))
+ {
+ uint32_t a = FindGreatestCommonDivisor(fccoHz, (multFccoDiv * finHz));
+
+ if (a > 20000U)
+ {
+ a = (multFccoDiv * finHz) / a;
+ if ((a != 0U) && (a < PLL_MAX_N_DIV))
+ {
+ pllPreDivider = a;
+ }
+ }
+ }
+
+ /* Bypass pre-divider hardware if pre-divider is 1 */
+ if (pllPreDivider > 1U)
+ {
+ pllDirectInput = 0U;
+ }
+ else
+ {
+ pllDirectInput = 1U;
+ }
+
+ /* Determine PLL multipler */
+ nDivOutHz = (finHz / pllPreDivider);
+ pllMultiplier = (fccoHz / nDivOutHz) / multFccoDiv;
+
+ /* Find optimal values for filter */
+ /* Will bumping up M by 1 get us closer to the desired CCO frequency? */
+ if ((nDivOutHz * ((multFccoDiv * pllMultiplier * 2U) + 1U)) < (fccoHz * 2U))
+ {
+ pllMultiplier++;
+ }
+
+ /* Setup filtering */
+ pllFindSel(pllMultiplier, &pllSelP, &pllSelI, &pllSelR);
+ uplimoff = 0U;
+
+ /* Get encoded value for M (mult) and use manual filter, disable SS mode */
+ pSetup->pllmdec = PLL_MDEC_VAL_SET(pllEncodeM(pllMultiplier));
+
+ /* Get encoded values for N (prediv) and P (postdiv) */
+ pSetup->pllndec = PLL_NDEC_VAL_SET(pllEncodeN(pllPreDivider));
+ pSetup->pllpdec = PLL_PDEC_VAL_SET(pllEncodeP(pllPostDivider));
+
+ /* PLL control */
+ pSetup->pllctrl = (pllSelR << SYSCON_SYSPLLCTRL_SELR_SHIFT) | /* Filter coefficient */
+ (pllSelI << SYSCON_SYSPLLCTRL_SELI_SHIFT) | /* Filter coefficient */
+ (pllSelP << SYSCON_SYSPLLCTRL_SELP_SHIFT) | /* Filter coefficient */
+ (0UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT) | /* PLL bypass mode disabled */
+ (uplimoff << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT) | /* SS/fractional mode disabled */
+ (pllDirectInput << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT) | /* Bypass pre-divider? */
+ (pllDirectOutput << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT); /* Bypass post-divider? */
+
+ return kStatus_PLL_Success;
+}
+
+#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
+/* Alloct the static buffer for cache. */
+static pll_setup_t gPllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT];
+static uint32_t gFinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
+static uint32_t gFoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0};
+static uint32_t gPllSetupCacheIdx = 0U;
+#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
+
+/*
+ * Calculate the PLL setting values from input clock freq to output freq.
+ */
+static pll_error_t CLOCK_GetPllConfig(uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup)
+{
+ pll_error_t retErr;
+#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
+ uint32_t i;
+
+ for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++)
+ {
+ if ((finHz == gFinHzCache[i]) && (foutHz == gFoutHzCache[i]))
+ {
+ /* Hit the target in cache buffer. */
+ pSetup->pllctrl = gPllSetupCacheStruct[i].pllctrl;
+ pSetup->pllndec = gPllSetupCacheStruct[i].pllndec;
+ pSetup->pllpdec = gPllSetupCacheStruct[i].pllpdec;
+ pSetup->pllmdec = gPllSetupCacheStruct[i].pllmdec;
+ retErr = kStatus_PLL_Success;
+ break;
+ }
+ }
+
+ if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
+ {
+ return retErr;
+ }
+#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
+
+ /* No cache or did not hit the cache. */
+ retErr = CLOCK_GetPllConfigInternal(finHz, foutHz, pSetup);
+
+#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT)
+ if (kStatus_PLL_Success == retErr)
+ {
+ /* Cache the most recent calulation result into buffer. */
+ gFinHzCache[gPllSetupCacheIdx] = finHz;
+ gFoutHzCache[gPllSetupCacheIdx] = foutHz;
+
+ gPllSetupCacheStruct[gPllSetupCacheIdx].pllctrl = pSetup->pllctrl;
+ gPllSetupCacheStruct[gPllSetupCacheIdx].pllndec = pSetup->pllndec;
+ gPllSetupCacheStruct[gPllSetupCacheIdx].pllpdec = pSetup->pllpdec;
+ gPllSetupCacheStruct[gPllSetupCacheIdx].pllmdec = pSetup->pllmdec;
+ /* Update the index for next available buffer. */
+ gPllSetupCacheIdx = (gPllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT;
+ }
+#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */
+
+ return retErr;
+}
+
+/* Update SYSTEM PLL rate variable */
+static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup)
+{
+ s_Pll_Freq = CLOCK_GetSystemPLLOutFromSetup(pSetup);
+}
+
+/* Update AUDIO PLL rate variable */
+static void CLOCK_GetAudioPLLOutFromSetupUpdate(pll_setup_t *pSetup)
+{
+ s_Audio_Pll_Freq = CLOCK_GetAudioPLLOutFromSetup(pSetup);
+}
+
+/* Update AUDIO Fractional PLL rate variable */
+static void CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pll_setup_t *pSetup)
+{
+ s_Audio_Pll_Freq = CLOCK_GetAudioPLLOutFromFractSetup(pSetup);
+}
+
+/* Update USB PLL rate variable */
+static void CLOCK_GetUsbPLLOutFromSetupUpdate(const usb_pll_setup_t *pSetup)
+{
+ s_Usb_Pll_Freq = CLOCK_GetUsbPLLOutFromSetup(pSetup);
+}
+
+/* Return System PLL input clock rate */
+/*! brief Return System PLL input clock rate
+ * return System PLL input clock rate
+ */
+uint32_t CLOCK_GetSystemPLLInClockRate(void)
+{
+ uint32_t clkRate = 0U;
+
+ switch ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK))
+ {
+ case 0x00U:
+ clkRate = CLK_FRO_12MHZ;
+ break;
+
+ case 0x01U:
+ clkRate = CLOCK_GetExtClkFreq();
+ break;
+
+ case 0x02U:
+ clkRate = CLOCK_GetWdtOscFreq();
+ break;
+
+ case 0x03U:
+ clkRate = CLOCK_GetOsc32KFreq();
+ break;
+
+ default:
+ clkRate = 0U;
+ break;
+ }
+
+ return clkRate;
+}
+
+/* Return Audio PLL input clock rate */
+/*! brief Return Audio PLL input clock rate
+ * return Audio PLL input clock rate
+ */
+uint32_t CLOCK_GetAudioPLLInClockRate(void)
+{
+ uint32_t clkRate = 0U;
+
+ switch ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK))
+ {
+ case 0x00U:
+ clkRate = CLK_FRO_12MHZ;
+ break;
+
+ case 0x01U:
+ clkRate = CLOCK_GetExtClkFreq();
+ break;
+
+ default:
+ clkRate = 0U;
+ break;
+ }
+
+ return clkRate;
+}
+
+/* Return System PLL output clock rate from setup structure */
+/*! brief Return System PLL output clock rate from setup structure
+ * param pSetup : Pointer to a PLL setup structure
+ * return System PLL output clock rate the setup structure will generate
+ */
+uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup)
+{
+ uint32_t prediv, postdiv, mMult, inPllRate;
+ uint64_t workRate;
+
+ inPllRate = CLOCK_GetSystemPLLInClockRate();
+ /* If the PLL is bypassed, PLL would not be used and the output of PLL module would just be the input clock*/
+ if ((pSetup->pllctrl & (SYSCON_SYSPLLCTRL_BYPASS_MASK)) == 0U)
+ {
+ /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
+ /*
+ * 1. Pre-divider
+ * Pre-divider is only available when the DIRECTI is disabled.
+ */
+ if (0U == (pSetup->pllctrl & SYSCON_SYSPLLCTRL_DIRECTI_MASK))
+ {
+ prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
+ }
+ else
+ {
+ prediv = 1U; /* The pre-divider is bypassed. */
+ }
+ /*
+ * 2. Post-divider
+ * Post-divider is only available when the DIRECTO is disabled.
+ */
+ if (0U == (pSetup->pllctrl & SYSCON_SYSPLLCTRL_DIRECTO_MASK))
+ {
+ postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
+ }
+ else
+ {
+ postdiv = 1U; /* The post-divider is bypassed. */
+ }
+ /* Adjust input clock */
+ inPllRate = inPllRate / prediv;
+
+ /* MDEC used for rate */
+ mMult = findPllMMult(pSetup->pllctrl, pSetup->pllmdec);
+ workRate = (uint64_t)inPllRate * (uint64_t)mMult;
+
+ workRate = workRate / ((uint64_t)postdiv);
+ workRate = workRate * 2U; /* SYS PLL hardware cco is divide by 2 before to M-DIVIDER*/
+ }
+ else
+ {
+ /* In bypass mode */
+ workRate = (uint64_t)inPllRate;
+ }
+
+ return (uint32_t)workRate;
+}
+
+/* Return Usb PLL output clock rate from setup structure */
+/*! brief Return System USB PLL output clock rate from setup structure
+ * param pSetup : Pointer to a PLL setup structure
+ * return System PLL output clock rate the setup structure will generate
+ */
+uint32_t CLOCK_GetUsbPLLOutFromSetup(const usb_pll_setup_t *pSetup)
+{
+ uint32_t nsel, psel, msel, inPllRate;
+ uint64_t workRate;
+ inPllRate = CLOCK_GetExtClkFreq();
+ msel = pSetup->msel;
+ psel = pSetup->psel;
+ nsel = pSetup->nsel;
+
+ /* Make sure the PSEL is correct. */
+ if (0U == SWITCH_USB_PSEL(psel))
+ {
+ return 0UL;
+ }
+
+ if (pSetup->fbsel)
+ {
+ /*integer_mode: Fout = M*(Fin/N), Fcco = 2*P*M*(Fin/N) */
+ workRate = ((uint64_t)inPllRate) * ((uint64_t)msel + 1U) / ((uint64_t)nsel + 1U);
+ }
+ else
+ {
+ /* non integer_mode: Fout = M*(Fin/N)/(2*P), Fcco = M * (Fin/N) */
+ workRate = ((uint64_t)inPllRate / ((uint64_t)nsel + 1U)) * (msel + 1U) / (2U * SWITCH_USB_PSEL(psel));
+ }
+
+ return (uint32_t)workRate;
+}
+
+/* Return Audio PLL output clock rate from setup structure */
+/*! brief Return System AUDIO PLL output clock rate from setup structure
+ * param pSetup : Pointer to a PLL setup structure
+ * return System PLL output clock rate the setup structure will generate
+ */
+uint32_t CLOCK_GetAudioPLLOutFromSetup(pll_setup_t *pSetup)
+{
+ uint32_t prediv, postdiv, mMult, inPllRate;
+ uint64_t workRate;
+
+ inPllRate = CLOCK_GetAudioPLLInClockRate();
+ if ((pSetup->pllctrl & (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) == 0U)
+ {
+ /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
+ /*
+ * 1. Pre-divider
+ * Pre-divider is only available when the DIRECTI is disabled.
+ */
+ if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTI_MASK))
+ {
+ prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
+ }
+ else
+ {
+ prediv = 1U; /* The pre-divider is bypassed. */
+ }
+ /*
+ * 2. Post-divider
+ * Post-divider is only available when the DIRECTO is disabled.
+ */
+ if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTO_MASK))
+ {
+ postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
+ }
+ else
+ {
+ postdiv = 1U; /* The post-divider is bypassed. */
+ }
+ /* Adjust input clock */
+ inPllRate = inPllRate / prediv;
+
+ /* MDEC used for rate */
+ mMult = findPllMMult(pSetup->pllctrl, pSetup->pllmdec);
+ workRate = (uint64_t)inPllRate * (uint64_t)mMult;
+
+ workRate = workRate / ((uint64_t)postdiv);
+ workRate = workRate * 2U; /* SYS PLL hardware cco is divide by 2 before to M-DIVIDER*/
+ }
+ else
+ {
+ /* In bypass mode */
+ workRate = (uint64_t)inPllRate;
+ }
+
+ return (uint32_t)workRate;
+}
+
+/* Return Audio PLL output clock rate from audio fractioanl setup structure */
+/*! brief Return System AUDIO PLL output clock rate from audio fractioanl setup structure
+ * param pSetup : Pointer to a PLL setup structure
+ * return System PLL output clock rate the setup structure will generate
+ */
+uint32_t CLOCK_GetAudioPLLOutFromFractSetup(pll_setup_t *pSetup)
+{
+ uint32_t prediv, postdiv, inPllRate;
+ double workRate, mMultFactional;
+
+ inPllRate = CLOCK_GetAudioPLLInClockRate();
+ if ((pSetup->pllctrl & (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) == 0U)
+ {
+ /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */
+ /*
+ * 1. Pre-divider
+ * Pre-divider is only available when the DIRECTI is disabled.
+ */
+ if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTI_MASK))
+ {
+ prediv = findPllPreDiv(pSetup->pllctrl, pSetup->pllndec);
+ }
+ else
+ {
+ prediv = 1U; /* The pre-divider is bypassed. */
+ }
+ /*
+ * 2. Post-divider
+ * Post-divider is only available when the DIRECTO is disabled.
+ */
+ if (0U == (pSetup->pllctrl & SYSCON_AUDPLLCTRL_DIRECTO_MASK))
+ {
+ postdiv = findPllPostDiv(pSetup->pllctrl, pSetup->pllpdec);
+ }
+ else
+ {
+ postdiv = 1U; /* The post-divider is bypassed. */
+ }
+ /* Adjust input clock */
+ inPllRate = inPllRate / prediv;
+
+ mMultFactional = (double)(uint32_t)(pSetup->audpllfrac >> 15) +
+ (double)(uint32_t)Binary2Fractional(pSetup->audpllfrac & 0x7FFFU);
+ workRate = (double)inPllRate * (double)mMultFactional;
+
+ workRate = workRate / ((double)postdiv);
+ workRate = workRate * 2.0; /* SYS PLL hardware cco is divide by 2 before to M-DIVIDER*/
+ }
+ else
+ {
+ /* In bypass mode */
+ workRate = (double)(uint64_t)inPllRate;
+ }
+
+ return (uint32_t)workRate;
+}
+
+/* Set the current PLL Rate */
+/*! brief Store the current PLL rate
+ * param rate: Current rate of the PLL
+ * return Nothing
+ **/
+void CLOCK_SetStoredPLLClockRate(uint32_t rate)
+{
+ s_Pll_Freq = rate;
+}
+
+/* Set the current Audio PLL Rate */
+/*! brief Store the current AUDIO PLL rate
+ * param rate: Current rate of the PLL
+ * return Nothing
+ **/
+void CLOCK_SetStoredAudioPLLClockRate(uint32_t rate)
+{
+ s_Audio_Pll_Freq = rate;
+}
+
+/* Set the current Usb PLL Rate */
+void CLOCK_SetStoredUsbPLLClockRate(uint32_t rate)
+{
+ s_Usb_Pll_Freq = rate;
+}
+
+/* Return System PLL output clock rate */
+/*! brief Return System PLL output clock rate
+ * param recompute : Forces a PLL rate recomputation if true
+ * return System PLL output clock rate
+ * note The PLL rate is cached in the driver in a variable as
+ * the rate computation function can take some time to perform. It
+ * is recommended to use 'false' with the 'recompute' parameter.
+ */
+uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute)
+{
+ pll_setup_t Setup;
+ uint32_t rate;
+
+ if ((recompute) || (s_Pll_Freq == 0U))
+ {
+ Setup.pllctrl = SYSCON->SYSPLLCTRL;
+ Setup.pllndec = SYSCON->SYSPLLNDEC;
+ Setup.pllpdec = SYSCON->SYSPLLPDEC;
+ Setup.pllmdec = SYSCON->SYSPLLMDEC;
+
+ CLOCK_GetSystemPLLOutFromSetupUpdate(&Setup);
+ }
+
+ rate = s_Pll_Freq;
+
+ return rate;
+}
+
+/* Return AUDIO PLL output clock rate */
+/*! brief Return System AUDIO PLL output clock rate
+ * param recompute : Forces a AUDIO PLL rate recomputation if true
+ * return System AUDIO PLL output clock rate
+ * note The AUDIO PLL rate is cached in the driver in a variable as
+ * the rate computation function can take some time to perform. It
+ * is recommended to use 'false' with the 'recompute' parameter.
+ */
+uint32_t CLOCK_GetAudioPLLOutClockRate(bool recompute)
+{
+ pll_setup_t Setup;
+ uint32_t rate;
+
+ if ((recompute) || (s_Audio_Pll_Freq == 0U))
+ {
+ Setup.pllctrl = SYSCON->AUDPLLCTRL;
+ Setup.pllndec = SYSCON->AUDPLLNDEC;
+ Setup.pllpdec = SYSCON->AUDPLLPDEC;
+ Setup.pllmdec = SYSCON->AUDPLLMDEC;
+
+ CLOCK_GetAudioPLLOutFromSetupUpdate(&Setup);
+ }
+
+ rate = s_Audio_Pll_Freq;
+ return rate;
+}
+
+/* Return USB PLL output clock rate */
+uint32_t CLOCK_GetUsbPLLOutClockRate(bool recompute)
+{
+ usb_pll_setup_t Setup;
+ uint32_t rate;
+
+ if ((recompute) || (s_Usb_Pll_Freq == 0U))
+ {
+ Setup.msel = (uint8_t)((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_MSEL_SHIFT) & SYSCON_USBPLLCTRL_MSEL_MASK);
+ Setup.psel = (uint8_t)((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_PSEL_SHIFT) & SYSCON_USBPLLCTRL_PSEL_MASK);
+ Setup.nsel = (uint8_t)((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_NSEL_SHIFT) & SYSCON_USBPLLCTRL_NSEL_MASK);
+ Setup.fbsel = (((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_FBSEL_SHIFT) & SYSCON_USBPLLCTRL_FBSEL_MASK) != 0UL);
+ Setup.bypass =
+ (((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_BYPASS_SHIFT) & SYSCON_USBPLLCTRL_BYPASS_MASK) != 0UL);
+ Setup.direct =
+ (((SYSCON->USBPLLCTRL >> SYSCON_USBPLLCTRL_DIRECT_SHIFT) & SYSCON_USBPLLCTRL_DIRECT_MASK) != 0UL);
+ CLOCK_GetUsbPLLOutFromSetupUpdate(&Setup);
+ }
+
+ rate = s_Usb_Pll_Freq;
+ return rate;
+}
+
+/* Set PLL output based on the passed PLL setup data */
+/*! brief Set PLL output based on the passed PLL setup data
+ * param pControl : Pointer to populated PLL control structure to generate setup with
+ * param pSetup : Pointer to PLL setup structure to be filled
+ * return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * note Actual frequency for setup may vary from the desired frequency based on the
+ * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
+ */
+pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
+{
+ uint32_t inRate;
+ pll_error_t pllError;
+
+ /* Determine input rate for the PLL */
+ if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
+ {
+ inRate = pControl->inputRate;
+ }
+ else
+ {
+ inRate = CLOCK_GetSystemPLLInClockRate();
+ }
+
+ /* PLL flag options */
+ pllError = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup);
+ pSetup->pllRate = pControl->desiredRate;
+ return pllError;
+}
+
+/* Set PLL output from PLL setup structure */
+/*! brief Set PLL output from PLL setup structure (precise frequency)
+ * param pSetup : Pointer to populated PLL setup structure
+ * param flagcfg : Flag configuration for PLL config structure
+ * return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * note This function will power off the PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the PLL, wait for PLL lock,
+ * and adjust system voltages to the new PLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg)
+{
+ if ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK) == 0x01U)
+ {
+ /* Turn on the ext clock if system pll input select clk_in */
+ CLOCK_Enable_SysOsc(true);
+ }
+ /* Enable power for PLLs */
+ POWER_SetPLL();
+ /* Power off PLL during setup changes */
+ POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
+
+ pSetup->flags = flagcfg;
+
+ /* Write PLL setup data */
+ SYSCON->SYSPLLCTRL = pSetup->pllctrl;
+ SYSCON->SYSPLLNDEC = pSetup->pllndec;
+ SYSCON->SYSPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
+ SYSCON->SYSPLLPDEC = pSetup->pllpdec;
+ SYSCON->SYSPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
+ SYSCON->SYSPLLMDEC = pSetup->pllmdec;
+ SYSCON->SYSPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
+
+ /* Flags for lock or power on */
+ if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
+ {
+ /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
+ uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
+ uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
+
+ /* Initialize and power up PLL */
+ SYSCON->SYSPLLMDEC = maxCCO;
+ POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
+
+ /* Set mreq to activate */
+ SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
+
+ /* Delay for 72 uSec @ 12Mhz */
+ SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+
+ /* clear mreq to prepare for restoring mreq */
+ SYSCON->SYSPLLMDEC = curSSCTRL;
+
+ /* set original value back and activate */
+ SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
+
+ /* Enable peripheral states by setting low */
+ POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
+ }
+ if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
+ {
+ while (CLOCK_IsSystemPLLLocked() == false)
+ {
+ }
+ }
+
+ /* Update current programmed PLL rate var */
+ CLOCK_GetSystemPLLOutFromSetupUpdate(pSetup);
+
+ /* System voltage adjustment, occurs prior to setting main system clock */
+ if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0U)
+ {
+ POWER_SetVoltageForFreq(s_Pll_Freq);
+ }
+
+ return kStatus_PLL_Success;
+}
+
+/* Set AUDIO PLL output from AUDIO PLL setup structure */
+/*! brief Set AUDIO PLL output from AUDIOPLL setup structure (precise frequency)
+ * param pSetup : Pointer to populated PLL setup structure
+ * param flagcfg : Flag configuration for PLL config structure
+ * return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * note This function will power off the PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
+ * and adjust system voltages to the new AUDIOPLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetupAudioPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg)
+{
+ if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
+ {
+ /* Turn on the ext clock if system pll input select clk_in */
+ CLOCK_Enable_SysOsc(true);
+ }
+ /* Enable power VD3 for PLLs */
+ POWER_SetPLL();
+ /* Power off PLL during setup changes */
+ POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
+
+ pSetup->flags = flagcfg;
+
+ /* Write PLL setup data */
+ SYSCON->AUDPLLCTRL = pSetup->pllctrl;
+ SYSCON->AUDPLLNDEC = pSetup->pllndec;
+ SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
+ SYSCON->AUDPLLPDEC = pSetup->pllpdec;
+ SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
+ SYSCON->AUDPLLMDEC = pSetup->pllmdec;
+ SYSCON->AUDPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
+ SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(1); /* disable fractional function */
+
+ /* Flags for lock or power on */
+ if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
+ {
+ /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
+ uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
+ uint32_t curSSCTRL = SYSCON->AUDPLLMDEC & ~(1UL << 17U);
+
+ /* Initialize and power up PLL */
+ SYSCON->AUDPLLMDEC = maxCCO;
+ POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
+
+ /* Set mreq to activate */
+ SYSCON->AUDPLLMDEC = maxCCO | (1UL << 17U);
+
+ /* Delay for 72 uSec @ 12Mhz */
+ SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+
+ /* clear mreq to prepare for restoring mreq */
+ SYSCON->AUDPLLMDEC = curSSCTRL;
+
+ /* set original value back and activate */
+ SYSCON->AUDPLLMDEC = curSSCTRL | (1UL << 17U);
+
+ /* Enable peripheral states by setting low */
+ POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
+ }
+ if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
+ {
+ while (CLOCK_IsAudioPLLLocked() == false)
+ {
+ }
+ }
+
+ /* Update current programmed PLL rate var */
+ CLOCK_GetAudioPLLOutFromSetupUpdate(pSetup);
+
+ return kStatus_PLL_Success;
+}
+
+/* Set AUDIO PLL output from AUDIO PLL fractional setup structure */
+/*! brief Set AUDIO PLL output from AUDIOPLL setup structure using the Audio Fractional divider register(precise
+ * frequency)
+ * param pSetup : Pointer to populated PLL setup structure
+ * param flagcfg : Flag configuration for PLL config structure
+ * return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * note This function will power off the PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
+ * and adjust system voltages to the new AUDIOPLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetupAudioPLLPrecFract(pll_setup_t *pSetup, uint32_t flagcfg)
+{
+ if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
+ {
+ /* Turn on the ext clock if system pll input select clk_in */
+ CLOCK_Enable_SysOsc(true);
+ }
+ /* Enable power VD3 for PLLs */
+ POWER_SetPLL();
+ /* Power off PLL during setup changes */
+ POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
+
+ pSetup->flags = flagcfg;
+
+ /* Write PLL setup data */
+ SYSCON->AUDPLLCTRL = pSetup->pllctrl;
+ SYSCON->AUDPLLNDEC = pSetup->pllndec;
+ SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
+ SYSCON->AUDPLLPDEC = pSetup->pllpdec;
+ SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
+ SYSCON->AUDPLLMDEC = pSetup->pllmdec;
+ SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(0); /* enable fractional function */
+ SYSCON->AUDPLLFRAC = pSetup->audpllfrac;
+ SYSCON->AUDPLLFRAC = pSetup->audpllfrac | (1UL << SYSCON_AUDPLLFRAC_REQ_SHIFT);
+
+ /* Enable peripheral states by setting low */
+ POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
+
+ if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
+ {
+ while (CLOCK_IsAudioPLLLocked() == false)
+ {
+ }
+ }
+
+ /* Update current programmed PLL rate var */
+ CLOCK_GetAudioPLLOutFromAudioFracSetupUpdate(pSetup);
+
+ return kStatus_PLL_Success;
+}
+
+/* Set Audio PLL output based on the passed Audio PLL setup data */
+/*! brief Set AUDIO PLL output based on the passed AUDIO PLL setup data
+ * param pControl : Pointer to populated PLL control structure to generate setup with
+ * param pSetup : Pointer to PLL setup structure to be filled
+ * return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * note Actual frequency for setup may vary from the desired frequency based on the
+ * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
+ */
+pll_error_t CLOCK_SetupAudioPLLData(pll_config_t *pControl, pll_setup_t *pSetup)
+{
+ uint32_t inRate;
+ pll_error_t pllError;
+
+ /* Determine input rate for the PLL */
+ if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U)
+ {
+ inRate = pControl->inputRate;
+ }
+ else
+ {
+ inRate = CLOCK_GetAudioPLLInClockRate();
+ }
+
+ /* PLL flag options */
+ pllError = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup);
+ pSetup->pllRate = pControl->desiredRate;
+ return pllError;
+}
+
+/* Setup PLL Frequency from pre-calculated value */
+/**
+ * brief Set PLL output from PLL setup structure (precise frequency)
+ * param pSetup : Pointer to populated PLL setup structure
+ * return kStatus_PLL_Success on success, or PLL setup error code
+ * note This function will power off the PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the PLL, wait for PLL lock,
+ * and adjust system voltages to the new PLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup)
+{
+ if ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK) == 0x01U)
+ {
+ /* Turn on the ext clock if system pll input select clk_in */
+ CLOCK_Enable_SysOsc(true);
+ }
+ /* Enable power VD3 for PLLs */
+ POWER_SetPLL();
+ /* Power off PLL during setup changes */
+ POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL0);
+
+ /* Write PLL setup data */
+ SYSCON->SYSPLLCTRL = pSetup->pllctrl;
+ SYSCON->SYSPLLNDEC = pSetup->pllndec;
+ SYSCON->SYSPLLNDEC = pSetup->pllndec | (1UL << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */
+ SYSCON->SYSPLLPDEC = pSetup->pllpdec;
+ SYSCON->SYSPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */
+ SYSCON->SYSPLLMDEC = pSetup->pllmdec;
+ SYSCON->SYSPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_SYSPLLMDEC_MREQ_SHIFT); /* latch */
+
+ /* Flags for lock or power on */
+ if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
+ {
+ /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
+ uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
+ uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
+
+ /* Initialize and power up PLL */
+ SYSCON->SYSPLLMDEC = maxCCO;
+ POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
+
+ /* Set mreq to activate */
+ SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
+
+ /* Delay for 72 uSec @ 12Mhz */
+ SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+
+ /* clear mreq to prepare for restoring mreq */
+ SYSCON->SYSPLLMDEC = curSSCTRL;
+
+ /* set original value back and activate */
+ SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
+
+ /* Enable peripheral states by setting low */
+ POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL0);
+ }
+ if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
+ {
+ while (CLOCK_IsSystemPLLLocked() == false)
+ {
+ }
+ }
+
+ /* Update current programmed PLL rate var */
+ s_Pll_Freq = pSetup->pllRate;
+
+ return kStatus_PLL_Success;
+}
+
+/* Setup Audio PLL Frequency from pre-calculated value */
+/**
+ * brief Set Audio PLL output from Audio PLL setup structure (precise frequency)
+ * param pSetup : Pointer to populated PLL setup structure
+ * return kStatus_PLL_Success on success, or Audio PLL setup error code
+ * note This function will power off the PLL, setup the Audio PLL with the
+ * new setup data, and then optionally powerup the PLL, wait for Audio PLL lock,
+ * and adjust system voltages to the new PLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the Audio PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetAudioPLLFreq(const pll_setup_t *pSetup)
+{
+ if ((SYSCON->AUDPLLCLKSEL & SYSCON_AUDPLLCLKSEL_SEL_MASK) == 0x01U)
+ {
+ /* Turn on the ext clock if system pll input select clk_in */
+ CLOCK_Enable_SysOsc(true);
+ }
+ /* Enable power VD3 for PLLs */
+ POWER_SetPLL();
+ /* Power off Audio PLL during setup changes */
+ POWER_EnablePD(kPDRUNCFG_PD_AUDIO_PLL);
+
+ /* Write Audio PLL setup data */
+ SYSCON->AUDPLLCTRL = pSetup->pllctrl;
+ SYSCON->AUDPLLFRAC = pSetup->audpllfrac;
+ SYSCON->AUDPLLFRAC = pSetup->audpllfrac | (1UL << SYSCON_AUDPLLFRAC_REQ_SHIFT); /* latch */
+ SYSCON->AUDPLLNDEC = pSetup->pllndec;
+ SYSCON->AUDPLLNDEC = pSetup->pllndec | (1UL << SYSCON_AUDPLLNDEC_NREQ_SHIFT); /* latch */
+ SYSCON->AUDPLLPDEC = pSetup->pllpdec;
+ SYSCON->AUDPLLPDEC = pSetup->pllpdec | (1UL << SYSCON_AUDPLLPDEC_PREQ_SHIFT); /* latch */
+ SYSCON->AUDPLLMDEC = pSetup->pllmdec;
+ SYSCON->AUDPLLMDEC = pSetup->pllmdec | (1UL << SYSCON_AUDPLLMDEC_MREQ_SHIFT); /* latch */
+ SYSCON->AUDPLLFRAC = SYSCON_AUDPLLFRAC_SEL_EXT(1); /* disable fractional function */
+
+ /* Flags for lock or power on */
+ if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U)
+ {
+ /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */
+ uint32_t maxCCO = (1UL << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/
+ uint32_t curSSCTRL = SYSCON->SYSPLLMDEC & ~(1UL << 17U);
+
+ /* Initialize and power up PLL */
+ SYSCON->SYSPLLMDEC = maxCCO;
+ POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
+
+ /* Set mreq to activate */
+ SYSCON->SYSPLLMDEC = maxCCO | (1UL << 17U);
+
+ /* Delay for 72 uSec @ 12Mhz */
+ SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+
+ /* clear mreq to prepare for restoring mreq */
+ SYSCON->SYSPLLMDEC = curSSCTRL;
+
+ /* set original value back and activate */
+ SYSCON->SYSPLLMDEC = curSSCTRL | (1UL << 17U);
+
+ /* Enable peripheral states by setting low */
+ POWER_DisablePD(kPDRUNCFG_PD_AUDIO_PLL);
+ }
+ if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U)
+ {
+ while (CLOCK_IsAudioPLLLocked() == false)
+ {
+ }
+ }
+
+ /* Update current programmed PLL rate var */
+ s_Audio_Pll_Freq = pSetup->pllRate;
+
+ return kStatus_PLL_Success;
+}
+
+/* Setup USB PLL Frequency from pre-calculated value */
+/**
+ * brief Set USB PLL output from USB PLL setup structure (precise frequency)
+ * param pSetup : Pointer to populated USB PLL setup structure
+ * return kStatus_PLL_Success on success, or USB PLL setup error code
+ * note This function will power off the USB PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the USB PLL, wait for USB PLL lock,
+ * and adjust system voltages to the new USB PLL rate. The function will not
+ * alter any source clocks (ie, usb pll clock) that may use the USB PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetUsbPLLFreq(const usb_pll_setup_t *pSetup)
+{
+ uint32_t usbpllctrl, fccoHz;
+ uint8_t msel, psel, nsel;
+ bool pllDirectInput, pllDirectOutput, pllfbsel;
+
+ msel = pSetup->msel;
+ psel = pSetup->psel;
+ nsel = pSetup->nsel;
+ pllDirectOutput = pSetup->direct;
+ pllDirectInput = pSetup->bypass;
+ pllfbsel = pSetup->fbsel;
+
+ /* Input clock into the PLL cannot be lower than this */
+ if (pSetup->inputRate < USB_PLL_LOWER_IN_LIMIT)
+ {
+ return kStatus_PLL_InputTooLow;
+ }
+
+ if (pllfbsel)
+ {
+ /*integer_mode: Fout = M*(Fin/N), Fcco = 2*P*M*(Fin/N) */
+ fccoHz = (pSetup->inputRate / ((uint32_t)nsel + 1U)) * 2U * (msel + 1U) * SWITCH_USB_PSEL(psel);
+
+ /* USB PLL CCO out rate cannot be lower than this */
+ if (fccoHz < USB_PLL_MIN_CCO_FREQ_MHZ)
+ {
+ return kStatus_PLL_CCOTooLow;
+ }
+ /* USB PLL CCO out rate cannot be Higher than this */
+ if (fccoHz > USB_PLL_MAX_CCO_FREQ_MHZ)
+ {
+ return kStatus_PLL_CCOTooHigh;
+ }
+ }
+ else
+ {
+ /* non integer_mode: Fout = M*(Fin/N)/(2*P), Fcco = M * (Fin/N) */
+ fccoHz = pSetup->inputRate / ((uint32_t)nsel + 1U) * (msel + 1U);
+
+ /* USB PLL CCO out rate cannot be lower than this */
+ if (fccoHz < USB_PLL_MIN_CCO_FREQ_MHZ)
+ {
+ return kStatus_PLL_CCOTooLow;
+ }
+ /* USB PLL CCO out rate cannot be Higher than this */
+ if (fccoHz > USB_PLL_MAX_CCO_FREQ_MHZ)
+ {
+ return kStatus_PLL_CCOTooHigh;
+ }
+ }
+
+ /* If configure the USB HOST clock, VD5 power for USB PHY should be enable
+ before the PLL is working */
+ /* Turn on the ext clock for usb pll input */
+ CLOCK_Enable_SysOsc(true);
+
+ /* Enable power VD3 for PLLs */
+ POWER_SetPLL();
+
+ /* Power on the VD5 for USB PHY */
+ POWER_SetUsbPhy();
+
+ /* Power off USB PLL during setup changes */
+ POWER_EnablePD(kPDRUNCFG_PD_USB_PLL);
+
+ /* Write USB PLL setup data */
+ usbpllctrl = USB_PLL_NSEL_VAL_SET(nsel) | /* NSEL VALUE */
+ USB_PLL_PSEL_VAL_SET(psel) | /* PSEL VALUE */
+ USB_PLL_MSEL_VAL_SET(msel) | /* MSEL VALUE */
+ (uint32_t)pllDirectInput << SYSCON_USBPLLCTRL_BYPASS_SHIFT | /* BYPASS DISABLE */
+ (uint32_t)pllDirectOutput << SYSCON_USBPLLCTRL_DIRECT_SHIFT | /* DIRECTO DISABLE */
+ (uint32_t)pllfbsel << SYSCON_USBPLLCTRL_FBSEL_SHIFT; /* FBSEL SELECT */
+
+ SYSCON->USBPLLCTRL = usbpllctrl;
+
+ POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
+
+ /* Delay for 72 uSec @ 12Mhz for the usb pll to lock */
+ SDK_DelayAtLeastUs(72U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+ if (false == pllDirectInput)
+ {
+ while (CLOCK_IsUsbPLLLocked() == false)
+ {
+ }
+ }
+ CLOCK_GetUsbPLLOutFromSetupUpdate(pSetup);
+ return kStatus_PLL_Success;
+}
+
+/* Set System PLL clock based on the input frequency and multiplier */
+/*! brief Set PLL output based on the multiplier and input frequency
+ * param multiply_by : multiplier
+ * param input_freq : Clock input frequency of the PLL
+ * return Nothing
+ * note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
+ * function does not disable or enable PLL power, wait for PLL lock,
+ * or adjust system voltages. These must be done in the application.
+ * The function will not alter any source clocks (ie, main systen clock)
+ * that may use the PLL, so these should be setup prior to and after
+ * exiting the function.
+ */
+void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq)
+{
+ uint32_t cco_freq = input_freq * multiply_by;
+ uint32_t pdec = 1U;
+ uint32_t selr;
+ uint32_t seli;
+ uint32_t selp;
+ uint32_t mdec, ndec;
+
+ uint32_t directo = SYSCON_SYSPLLCTRL_DIRECTO(1);
+
+ while (cco_freq < 275000000U)
+ {
+ multiply_by <<= 1U; /* double value in each iteration */
+ pdec <<= 1U; /* correspondingly double pdec to cancel effect of double msel */
+ cco_freq = input_freq * multiply_by;
+ }
+ selr = 0U;
+ if (multiply_by < 60U)
+ {
+ seli = (multiply_by & 0x3cU) + 4U;
+ selp = (multiply_by >> 1U) + 1U;
+ }
+ else
+ {
+ selp = 31U;
+ if (multiply_by > 16384U)
+ {
+ seli = 1U;
+ }
+ else if (multiply_by > 8192U)
+ {
+ seli = 2U;
+ }
+ else if (multiply_by > 2048U)
+ {
+ seli = 4U;
+ }
+ else if (multiply_by >= 501U)
+ {
+ seli = 8U;
+ }
+ else
+ {
+ seli = 4U * (1024U / (multiply_by + 9U));
+ }
+ }
+
+ if (pdec > 1U)
+ {
+ directo = 0U; /* use post divider */
+ pdec = pdec / 2U; /* Account for minus 1 encoding */
+ /* Translate P value */
+ switch (pdec)
+ {
+ case 1U:
+ pdec = 0x62U; /* 1 * 2 */
+ break;
+ case 2U:
+ pdec = 0x42U; /* 2 * 2 */
+ break;
+ case 4U:
+ pdec = 0x02U; /* 4 * 2 */
+ break;
+ case 8U:
+ pdec = 0x0bU; /* 8 * 2 */
+ break;
+ case 16U:
+ pdec = 0x11U; /* 16 * 2 */
+ break;
+ case 32U:
+ pdec = 0x08U; /* 32 * 2 */
+ break;
+ default:
+ pdec = 0x08U;
+ break;
+ }
+ }
+
+ mdec = PLL_MDEC_VAL_SET(pllEncodeM(multiply_by));
+ ndec = 0x302U; /* pre divide by 1 (hardcoded) */
+
+ SYSCON->SYSPLLCTRL = directo | (selr << SYSCON_SYSPLLCTRL_SELR_SHIFT) | (seli << SYSCON_SYSPLLCTRL_SELI_SHIFT) |
+ (selp << SYSCON_SYSPLLCTRL_SELP_SHIFT);
+ SYSCON->SYSPLLPDEC = pdec | (1U << 7U); /* set Pdec value and assert preq */
+ SYSCON->SYSPLLNDEC = ndec | (1UL << 10U); /* set Pdec value and assert preq */
+ SYSCON->SYSPLLMDEC = (1UL << 17U) | mdec; /* select non sscg MDEC value, assert mreq and select mdec value */
+}
+
+/* Enable USB DEVICE FULL SPEED clock */
+/*! brief Enable USB Device FS clock.
+ * param src : clock source
+ * param freq: clock frequency
+ * Enable USB Device Full Speed clock.
+ */
+bool CLOCK_EnableUsbfs0DeviceClock(clock_usb_src_t src, uint32_t freq)
+{
+ bool ret = true;
+
+ CLOCK_DisableClock(kCLOCK_Usbd0);
+
+ if (kCLOCK_UsbSrcFro == src)
+ {
+ switch (freq)
+ {
+ case 96000000U:
+ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2U, false); /*!< Div by 2 to get 48MHz, no divider reset */
+ break;
+
+ case 48000000U:
+ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false); /*!< Div by 1 to get 48MHz, no divider reset */
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+ /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
+ SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
+ SYSCON_FROCTRL_USBCLKADJ_MASK;
+ /* Select FRO 96 or 48 MHz */
+ CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
+ }
+ else
+ {
+ /*Set the USB PLL as the Usb0 CLK*/
+ POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
+
+ usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
+
+ (void)CLOCK_SetUsbPLLFreq(&pll_setup);
+ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
+ CLOCK_AttachClk(kUSB_PLL_to_USB0_CLK);
+ SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+ }
+ CLOCK_EnableClock(kCLOCK_Usbd0);
+ CLOCK_EnableClock(kCLOCK_UsbRam1);
+
+ return ret;
+}
+
+/* Enable USB HOST FULL SPEED clock */
+/*! brief Enable USB HOST FS clock.
+ * param src : clock source
+ * param freq: clock frequency
+ * Enable USB HOST Full Speed clock.
+ */
+bool CLOCK_EnableUsbfs0HostClock(clock_usb_src_t src, uint32_t freq)
+{
+ bool ret = true;
+
+ CLOCK_DisableClock(kCLOCK_Usbhmr0);
+ CLOCK_DisableClock(kCLOCK_Usbhsl0);
+
+ if (kCLOCK_UsbSrcFro == src)
+ {
+ switch (freq)
+ {
+ case 96000000U:
+ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 2U, false); /*!< Div by 2 to get 48MHz, no divider reset */
+ break;
+
+ case 48000000U:
+ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false); /*!< Div by 1 to get 48MHz, no divider reset */
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+ /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
+ SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
+ SYSCON_FROCTRL_USBCLKADJ_MASK;
+ /* Select FRO 96 or 48 MHz */
+ CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
+ }
+ else
+ {
+ /*Set the USB PLL as the Usb0 CLK*/
+ POWER_DisablePD(kPDRUNCFG_PD_USB_PLL);
+
+ usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
+
+ (void)CLOCK_SetUsbPLLFreq(&pll_setup);
+ CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1U, false);
+ CLOCK_AttachClk(kUSB_PLL_to_USB0_CLK);
+ SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+ }
+ CLOCK_EnableClock(kCLOCK_Usbhmr0);
+ CLOCK_EnableClock(kCLOCK_Usbhsl0);
+ CLOCK_EnableClock(kCLOCK_UsbRam1);
+
+ return ret;
+}
+
+/* Enable USB DEVICE HIGH SPEED clock */
+/*! brief Enable USB Device HS clock.
+ * param src : clock source
+ * param freq: clock frequency
+ * Enable USB Device High Speed clock.
+ */
+bool CLOCK_EnableUsbhs0DeviceClock(clock_usb_src_t src, uint32_t freq)
+{
+ bool ret = true;
+ CLOCK_DisableClock(kCLOCK_Usbd1);
+ /* Power on the VD5 for USB PHY */
+ POWER_SetUsbPhy();
+ if (kCLOCK_UsbSrcFro == src)
+ {
+ switch (freq)
+ {
+ case 96000000U:
+ CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 2U, false); /*!< Div by 2 to get 48MHz, no divider reset */
+ break;
+
+ case 48000000U:
+ CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false); /*!< Div by 1 to get 48MHz, no divider reset */
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+ /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
+ SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
+ SYSCON_FROCTRL_USBCLKADJ_MASK;
+ /* Select FRO 96 or 48 MHz */
+ CLOCK_AttachClk(kFRO_HF_to_USB1_CLK);
+ }
+ else
+ {
+ SDK_DelayAtLeastUs(50, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+ usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
+
+ (void)CLOCK_SetUsbPLLFreq(&pll_setup);
+
+ /* Select USB PLL output as USB clock src */
+ CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false);
+ CLOCK_AttachClk(kUSB_PLL_to_USB1_CLK);
+ }
+
+ SDK_DelayAtLeastUs(50, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+ /* Enable USB1D and USB1RAM */
+ CLOCK_EnableClock(kCLOCK_Usbd1);
+ CLOCK_EnableClock(kCLOCK_UsbRam1);
+ POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* Turn on power for USB PHY */
+ return ret;
+}
+
+/* Enable USB HOST HIGH SPEED clock */
+/*! brief Enable USB HOST HS clock.
+ * param src : clock source
+ * param freq: clock frequency
+ * Enable USB HOST High Speed clock.
+ */
+bool CLOCK_EnableUsbhs0HostClock(clock_usb_src_t src, uint32_t freq)
+{
+ bool ret = true;
+ CLOCK_DisableClock(kCLOCK_Usbh1);
+ /* Power on the VD5 for USB PHY */
+ POWER_SetUsbPhy();
+ if (kCLOCK_UsbSrcFro == src)
+ {
+ switch (freq)
+ {
+ case 96000000U:
+ CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 2U, false); /*!< Div by 2 to get 48MHz, no divider reset */
+ break;
+
+ case 48000000U:
+ CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false); /*!< Div by 1 to get 48MHz, no divider reset */
+ break;
+
+ default:
+ ret = false;
+ break;
+ }
+ /* Turn ON FRO HF and let it adjust TRIM value based on USB SOF */
+ SYSCON->FROCTRL = (SYSCON->FROCTRL & ~((0x01UL << 15U) | (0xFUL << 26U))) | SYSCON_FROCTRL_HSPDCLK_MASK |
+ SYSCON_FROCTRL_USBCLKADJ_MASK;
+ /* Select FRO 96 or 48 MHz */
+ CLOCK_AttachClk(kFRO_HF_to_USB1_CLK);
+ }
+ else
+ {
+ SDK_DelayAtLeastUs(50U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+ usb_pll_setup_t pll_setup = {0x3FU, 0x01U, 0x03U, false, false, false, 12000000U};
+
+ (void)CLOCK_SetUsbPLLFreq(&pll_setup);
+
+ /* Select USB PLL output as USB clock src */
+ CLOCK_SetClkDiv(kCLOCK_DivUsb1Clk, 1U, false);
+ CLOCK_AttachClk(kUSB_PLL_to_USB1_CLK);
+ }
+
+ SDK_DelayAtLeastUs(50, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+ /* Enable USBh1 and USB1RAM */
+ CLOCK_EnableClock(kCLOCK_Usbh1);
+ CLOCK_EnableClock(kCLOCK_UsbRam1);
+ POWER_DisablePD(kPDRUNCFG_PD_USB1_PHY); /* Turn on power for USB PHY */
+ return ret;
+}
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_clock.h b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_clock.h
new file mode 100644
index 000000000..f14a543dc
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_clock.h
@@ -0,0 +1,1293 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016 - 2019 , NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_CLOCK_H_
+#define _FSL_CLOCK_H_
+
+#include "fsl_common.h"
+
+/*! @addtogroup clock */
+/*! @{ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ *****************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief CLOCK driver version 2.3.1. */
+#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 3, 1))
+/*@}*/
+
+/*! @brief Configure whether driver controls clock
+ *
+ * When set to 0, peripheral drivers will enable clock in initialize function
+ * and disable clock in de-initialize function. When set to 1, peripheral
+ * driver will not control the clock, application could control the clock out of
+ * the driver.
+ *
+ * @note All drivers share this feature switcher. If it is set to 1, application
+ * should handle clock enable and disable for all drivers.
+ */
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL))
+#define FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL 0
+#endif
+
+/*!
+ * @brief User-defined the size of cache for CLOCK_PllGetConfig() function.
+ *
+ * Once define this MACRO to be non-zero value, CLOCK_PllGetConfig() function
+ * would cache the recent calulation and accelerate the execution to get the
+ * right settings.
+ */
+#ifndef CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT
+#define CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT 2U
+#endif
+
+/* Definition for delay API in clock driver, users can redefine it to the real application. */
+#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
+#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (180000000UL)
+#endif
+
+/*! @brief Clock ip name array for ADC. */
+#define ADC_CLOCKS \
+ { \
+ kCLOCK_Adc0 \
+ }
+/*! @brief Clock ip name array for ROM. */
+#define ROM_CLOCKS \
+ { \
+ kCLOCK_Rom \
+ }
+/*! @brief Clock ip name array for SRAM. */
+#define SRAM_CLOCKS \
+ { \
+ kCLOCK_Sram1, kCLOCK_Sram2, kCLOCK_Sram3 \
+ }
+/*! @brief Clock ip name array for FLASH. */
+#define FLASH_CLOCKS \
+ { \
+ kCLOCK_Flash \
+ }
+/*! @brief Clock ip name array for FMC. */
+#define FMC_CLOCKS \
+ { \
+ kCLOCK_Fmc \
+ }
+/*! @brief Clock ip name array for EEPROM. */
+#define EEPROM_CLOCKS \
+ { \
+ kCLOCK_Eeprom \
+ }
+/*! @brief Clock ip name array for SPIFI. */
+#define SPIFI_CLOCKS \
+ { \
+ kCLOCK_Spifi \
+ }
+/*! @brief Clock ip name array for INPUTMUX. */
+#define INPUTMUX_CLOCKS \
+ { \
+ kCLOCK_InputMux \
+ }
+/*! @brief Clock ip name array for IOCON. */
+#define IOCON_CLOCKS \
+ { \
+ kCLOCK_Iocon \
+ }
+/*! @brief Clock ip name array for GPIO. */
+#define GPIO_CLOCKS \
+ { \
+ kCLOCK_Gpio0, kCLOCK_Gpio1, kCLOCK_Gpio2, kCLOCK_Gpio3, kCLOCK_Gpio4, kCLOCK_Gpio5 \
+ }
+/*! @brief Clock ip name array for PINT. */
+#define PINT_CLOCKS \
+ { \
+ kCLOCK_Pint \
+ }
+/*! @brief Clock ip name array for GINT. */
+#define GINT_CLOCKS \
+ { \
+ kCLOCK_Gint, kCLOCK_Gint \
+ }
+/*! @brief Clock ip name array for DMA. */
+#define DMA_CLOCKS \
+ { \
+ kCLOCK_Dma \
+ }
+/*! @brief Clock ip name array for CRC. */
+#define CRC_CLOCKS \
+ { \
+ kCLOCK_Crc \
+ }
+/*! @brief Clock ip name array for WWDT. */
+#define WWDT_CLOCKS \
+ { \
+ kCLOCK_Wwdt \
+ }
+/*! @brief Clock ip name array for RTC. */
+#define RTC_CLOCKS \
+ { \
+ kCLOCK_Rtc \
+ }
+/*! @brief Clock ip name array for ADC0. */
+#define ADC0_CLOCKS \
+ { \
+ kCLOCK_Adc0 \
+ }
+/*! @brief Clock ip name array for MRT. */
+#define MRT_CLOCKS \
+ { \
+ kCLOCK_Mrt \
+ }
+/*! @brief Clock ip name array for RIT. */
+#define RIT_CLOCKS \
+ { \
+ kCLOCK_Rit \
+ }
+/*! @brief Clock ip name array for SCT0. */
+#define SCT_CLOCKS \
+ { \
+ kCLOCK_Sct0 \
+ }
+/*! @brief Clock ip name array for MCAN. */
+#define MCAN_CLOCKS \
+ { \
+ kCLOCK_Mcan0, kCLOCK_Mcan1 \
+ }
+/*! @brief Clock ip name array for UTICK. */
+#define UTICK_CLOCKS \
+ { \
+ kCLOCK_Utick \
+ }
+/*! @brief Clock ip name array for FLEXCOMM. */
+#define FLEXCOMM_CLOCKS \
+ { \
+ kCLOCK_FlexComm0, kCLOCK_FlexComm1, kCLOCK_FlexComm2, kCLOCK_FlexComm3, kCLOCK_FlexComm4, kCLOCK_FlexComm5, \
+ kCLOCK_FlexComm6, kCLOCK_FlexComm7, kCLOCK_FlexComm8, kCLOCK_FlexComm9, kCLOCK_FlexComm10 \
+ }
+/*! @brief Clock ip name array for LPUART. */
+#define LPUART_CLOCKS \
+ { \
+ kCLOCK_MinUart0, kCLOCK_MinUart1, kCLOCK_MinUart2, kCLOCK_MinUart3, kCLOCK_MinUart4, kCLOCK_MinUart5, \
+ kCLOCK_MinUart6, kCLOCK_MinUart7, kCLOCK_MinUart8, kCLOCK_MinUart9 \
+ }
+
+/*! @brief Clock ip name array for BI2C. */
+#define BI2C_CLOCKS \
+ { \
+ kCLOCK_BI2c0, kCLOCK_BI2c1, kCLOCK_BI2c2, kCLOCK_BI2c3, kCLOCK_BI2c4, kCLOCK_BI2c5, kCLOCK_BI2c6, \
+ kCLOCK_BI2c7, kCLOCK_BI2c8, kCLOCK_BI2c9 \
+ }
+/*! @brief Clock ip name array for LSPI. */
+#define LPSI_CLOCKS \
+ { \
+ kCLOCK_LSpi0, kCLOCK_LSpi1, kCLOCK_LSpi2, kCLOCK_LSpi3, kCLOCK_LSpi4, kCLOCK_LSpi5, kCLOCK_LSpi6, \
+ kCLOCK_LSpi7, kCLOCK_LSpi8, kCLOCK_LSpi9 \
+ }
+/*! @brief Clock ip name array for FLEXI2S. */
+#define FLEXI2S_CLOCKS \
+ { \
+ kCLOCK_FlexI2s0, kCLOCK_FlexI2s1, kCLOCK_FlexI2s2, kCLOCK_FlexI2s3, kCLOCK_FlexI2s4, kCLOCK_FlexI2s5, \
+ kCLOCK_FlexI2s6, kCLOCK_FlexI2s7, kCLOCK_FlexI2s8, kCLOCK_FlexI2s9 \
+ }
+/*! @brief Clock ip name array for DMIC. */
+#define DMIC_CLOCKS \
+ { \
+ kCLOCK_DMic \
+ }
+/*! @brief Clock ip name array for CT32B. */
+#define CTIMER_CLOCKS \
+ { \
+ kCLOCK_Ct32b0, kCLOCK_Ct32b1, kCLOCK_Ct32b2, kCLOCK_Ct32b3, kCLOCK_Ct32b4 \
+ }
+/*! @brief Clock ip name array for LCD. */
+#define LCD_CLOCKS \
+ { \
+ kCLOCK_Lcd \
+ }
+/*! @brief Clock ip name array for SDIO. */
+#define SDIO_CLOCKS \
+ { \
+ kCLOCK_Sdio \
+ }
+/*! @brief Clock ip name array for USBRAM. */
+#define USBRAM_CLOCKS \
+ { \
+ kCLOCK_UsbRam1 \
+ }
+/*! @brief Clock ip name array for EMC. */
+#define EMC_CLOCKS \
+ { \
+ kCLOCK_Emc \
+ }
+/*! @brief Clock ip name array for ETH. */
+#define ETH_CLOCKS \
+ { \
+ kCLOCK_Eth \
+ }
+/*! @brief Clock ip name array for AES. */
+#define AES_CLOCKS \
+ { \
+ kCLOCK_Aes \
+ }
+/*! @brief Clock ip name array for OTP. */
+#define OTP_CLOCKS \
+ { \
+ kCLOCK_Otp \
+ }
+/*! @brief Clock ip name array for RNG. */
+#define RNG_CLOCKS \
+ { \
+ kCLOCK_Rng \
+ }
+/*! @brief Clock ip name array for USBHMR0. */
+#define USBHMR0_CLOCKS \
+ { \
+ kCLOCK_Usbhmr0 \
+ }
+/*! @brief Clock ip name array for USBHSL0. */
+#define USBHSL0_CLOCKS \
+ { \
+ kCLOCK_Usbhsl0 \
+ }
+/*! @brief Clock ip name array for SHA0. */
+#define SHA0_CLOCKS \
+ { \
+ kCLOCK_Sha0 \
+ }
+/*! @brief Clock ip name array for SMARTCARD. */
+#define SMARTCARD_CLOCKS \
+ { \
+ kCLOCK_SmartCard0, kCLOCK_SmartCard1 \
+ }
+/*! @brief Clock ip name array for USBD. */
+#define USBD_CLOCKS \
+ { \
+ kCLOCK_Usbd0, kCLOCK_Usbh1, kCLOCK_Usbd1 \
+ }
+/*! @brief Clock ip name array for USBH. */
+#define USBH_CLOCKS \
+ { \
+ kCLOCK_Usbh1 \
+ }
+/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
+/*------------------------------------------------------------------------------
+ clock_ip_name_t definition:
+------------------------------------------------------------------------------*/
+
+#define CLK_GATE_REG_OFFSET_SHIFT 8U
+#define CLK_GATE_REG_OFFSET_MASK 0xFFFFFF00U
+#define CLK_GATE_BIT_SHIFT_SHIFT 0U
+#define CLK_GATE_BIT_SHIFT_MASK 0x000000FFU
+
+#define CLK_GATE_DEFINE(reg_offset, bit_shift) \
+ ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \
+ (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK))
+
+#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((uint32_t)(x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT)
+#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((uint32_t)(x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT)
+
+#define AHB_CLK_CTRL0 0
+#define AHB_CLK_CTRL1 1
+#define AHB_CLK_CTRL2 2
+#define ASYNC_CLK_CTRL0 3
+
+/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */
+typedef enum _clock_ip_name
+{
+ kCLOCK_IpInvalid = 0U,
+ kCLOCK_Rom = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 1),
+ kCLOCK_Sram1 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 3),
+ kCLOCK_Sram2 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 4),
+ kCLOCK_Sram3 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 5),
+ kCLOCK_Spifi = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 10),
+ kCLOCK_InputMux = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 11),
+ kCLOCK_Iocon = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 13),
+ kCLOCK_Gpio0 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 14),
+ kCLOCK_Gpio1 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 15),
+ kCLOCK_Gpio2 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 16),
+ kCLOCK_Gpio3 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 17),
+ kCLOCK_Pint = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 18),
+ kCLOCK_Gint = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 19),
+ kCLOCK_Dma = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 20),
+ kCLOCK_Crc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 21),
+ kCLOCK_Wwdt = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 22),
+ kCLOCK_Rtc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 23),
+ kCLOCK_Adc0 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 27),
+ kCLOCK_Mrt = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 0),
+ kCLOCK_Rit = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 1),
+ kCLOCK_Sct0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 2),
+ kCLOCK_Mcan0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 7),
+ kCLOCK_Mcan1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 8),
+ kCLOCK_Utick = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 10),
+ kCLOCK_FlexComm0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
+ kCLOCK_FlexComm1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
+ kCLOCK_FlexComm2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
+ kCLOCK_FlexComm3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
+ kCLOCK_FlexComm4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
+ kCLOCK_FlexComm5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
+ kCLOCK_FlexComm6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
+ kCLOCK_FlexComm7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
+ kCLOCK_MinUart0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
+ kCLOCK_MinUart1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
+ kCLOCK_MinUart2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
+ kCLOCK_MinUart3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
+ kCLOCK_MinUart4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
+ kCLOCK_MinUart5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
+ kCLOCK_MinUart6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
+ kCLOCK_MinUart7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
+ kCLOCK_LSpi0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
+ kCLOCK_LSpi1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
+ kCLOCK_LSpi2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
+ kCLOCK_LSpi3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
+ kCLOCK_LSpi4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
+ kCLOCK_LSpi5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
+ kCLOCK_LSpi6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
+ kCLOCK_LSpi7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
+ kCLOCK_BI2c0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
+ kCLOCK_BI2c1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
+ kCLOCK_BI2c2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
+ kCLOCK_BI2c3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
+ kCLOCK_BI2c4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
+ kCLOCK_BI2c5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
+ kCLOCK_BI2c6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
+ kCLOCK_BI2c7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
+ kCLOCK_FlexI2s0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 11),
+ kCLOCK_FlexI2s1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 12),
+ kCLOCK_FlexI2s2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 13),
+ kCLOCK_FlexI2s3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 14),
+ kCLOCK_FlexI2s4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 15),
+ kCLOCK_FlexI2s5 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 16),
+ kCLOCK_FlexI2s6 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 17),
+ kCLOCK_FlexI2s7 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 18),
+ kCLOCK_DMic = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 19),
+ kCLOCK_Ct32b2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 22),
+ kCLOCK_Usbd0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 25),
+ kCLOCK_Ct32b0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 26),
+ kCLOCK_Ct32b1 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 27),
+ kCLOCK_BodyBias0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 29),
+ kCLOCK_EzhArchB0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 31),
+ kCLOCK_Lcd = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 2),
+ kCLOCK_Sdio = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 3),
+ kCLOCK_Usbh1 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 4),
+ kCLOCK_Usbd1 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 5),
+ kCLOCK_UsbRam1 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 6),
+ kCLOCK_Emc = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 7),
+ kCLOCK_Eth = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 8),
+ kCLOCK_Gpio4 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 9),
+ kCLOCK_Gpio5 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 10),
+ kCLOCK_Aes = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 11),
+ kCLOCK_Otp = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 12),
+ kCLOCK_Rng = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 13),
+ kCLOCK_FlexComm8 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 14),
+ kCLOCK_FlexComm9 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 15),
+ kCLOCK_MinUart8 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 14),
+ kCLOCK_MinUart9 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 15),
+ kCLOCK_LSpi8 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 14),
+ kCLOCK_LSpi9 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 15),
+ kCLOCK_BI2c8 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 14),
+ kCLOCK_BI2c9 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 15),
+ kCLOCK_FlexI2s8 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 14),
+ kCLOCK_FlexI2s9 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 15),
+ kCLOCK_Usbhmr0 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 16),
+ kCLOCK_Usbhsl0 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 17),
+ kCLOCK_Sha0 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 18),
+ kCLOCK_SmartCard0 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 19),
+ kCLOCK_SmartCard1 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 20),
+ kCLOCK_FlexComm10 = CLK_GATE_DEFINE(AHB_CLK_CTRL2, 21),
+
+ kCLOCK_Ct32b3 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 13),
+ kCLOCK_Ct32b4 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 14)
+} clock_ip_name_t;
+
+/*! @brief Clock name used to get clock frequency. */
+typedef enum _clock_name
+{
+ kCLOCK_CoreSysClk, /*!< Core/system clock (aka MAIN_CLK) */
+ kCLOCK_BusClk, /*!< Bus clock (AHB clock) */
+ kCLOCK_ClockOut, /*!< CLOCKOUT */
+ kCLOCK_FroHf, /*!< FRO48/96 */
+ kCLOCK_UsbPll, /*!< USB1 PLL */
+ kCLOCK_Mclk, /*!< MCLK */
+ kCLOCK_Fro12M, /*!< FRO12M */
+ kCLOCK_ExtClk, /*!< External Clock */
+ kCLOCK_PllOut, /*!< PLL Output */
+ kCLOCK_UsbClk, /*!< USB input */
+ kCLOCK_WdtOsc, /*!< Watchdog Oscillator */
+ kCLOCK_Frg, /*!< Frg Clock */
+ kCLOCK_AsyncApbClk, /*!< Async APB clock */
+} clock_name_t;
+
+/**
+ * Clock source selections for the asynchronous APB clock
+ */
+typedef enum _async_clock_src
+{
+ kCLOCK_AsyncMainClk = 0, /*!< Main System clock */
+ kCLOCK_AsyncFro12Mhz, /*!< 12MHz FRO */
+ kCLOCK_AsyncAudioPllClk,
+ kCLOCK_AsyncI2cClkFc6,
+
+} async_clock_src_t;
+
+/*! @brief Clock Mux Switches
+ * The encoding is as follows each connection identified is 32bits wide while 24bits are valuable
+ * starting from LSB upwards
+ *
+ * [4 bits for choice, 0 means invalid choice] [8 bits mux ID]*
+ *
+ */
+
+#define CLK_ATTACH_ID(mux, sel, pos) ((((uint32_t)(mux) << 0U) | (((uint32_t)(sel) + 1U) & 0xFU) << 8U) << ((pos)*12U))
+#define MUX_A(mux, sel) CLK_ATTACH_ID((mux), (sel), 0U)
+#define MUX_B(mux, sel, selector) (CLK_ATTACH_ID((mux), (sel), 1U) | ((selector) << 24U))
+
+#define GET_ID_ITEM(connection) ((connection)&0xFFFU)
+#define GET_ID_NEXT_ITEM(connection) ((connection) >> 12U)
+#define GET_ID_ITEM_MUX(connection) ((uint8_t)((connection)&0xFFU))
+#define GET_ID_ITEM_SEL(connection) ((uint8_t)((((connection)&0xF00U) >> 8U) - 1U))
+#define GET_ID_SELECTOR(connection) ((connection)&0xF000000U)
+
+#define CM_STICKCLKSEL 0
+#define CM_MAINCLKSELA 1
+#define CM_MAINCLKSELB 2
+#define CM_CLKOUTCLKSELA 3
+#define CM_SYSPLLCLKSEL 5
+#define CM_AUDPLLCLKSEL 7
+#define CM_SPIFICLKSEL 9
+#define CM_ADCASYNCCLKSEL 10
+#define CM_USB0CLKSEL 11
+#define CM_USB1CLKSEL 12
+#define CM_FXCOMCLKSEL0 13
+#define CM_FXCOMCLKSEL1 14
+#define CM_FXCOMCLKSEL2 15
+#define CM_FXCOMCLKSEL3 16
+#define CM_FXCOMCLKSEL4 17
+#define CM_FXCOMCLKSEL5 18
+#define CM_FXCOMCLKSEL6 19
+#define CM_FXCOMCLKSEL7 20
+#define CM_FXCOMCLKSEL8 21
+#define CM_FXCOMCLKSEL9 22
+#define CM_FXCOMCLKSEL10 23
+#define CM_MCLKCLKSEL 25
+#define CM_FRGCLKSEL 27
+#define CM_DMICCLKSEL 28
+#define CM_SCTCLKSEL 29
+#define CM_LCDCLKSEL 30
+#define CM_SDIOCLKSEL 31
+
+#define CM_ASYNCAPB 32U
+
+typedef enum _clock_attach_id
+{
+
+ kSYSTICK_DIV_CLK_to_SYSTICKCLK = MUX_A(CM_STICKCLKSEL, 0),
+ kWDT_OSC_to_SYSTICKCLK = MUX_A(CM_STICKCLKSEL, 1),
+ kOSC32K_to_SYSTICKCLK = MUX_A(CM_STICKCLKSEL, 2),
+ kFRO12M_to_SYSTICKCLK = MUX_A(CM_STICKCLKSEL, 3),
+ kNONE_to_SYSTICKCLK = MUX_A(CM_STICKCLKSEL, 7),
+
+ kFRO12M_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 0, 0),
+ kEXT_CLK_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 1) | MUX_B(CM_MAINCLKSELB, 0, 0),
+ kWDT_OSC_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 2) | MUX_B(CM_MAINCLKSELB, 0, 0),
+ kFRO_HF_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 3) | MUX_B(CM_MAINCLKSELB, 0, 0),
+ kSYS_PLL_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 2, 0),
+ kOSC32K_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 3, 0),
+
+ kMAIN_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 0),
+ kEXT_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 1),
+ kWDT_OSC_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 2),
+ kFRO_HF_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 3),
+ kSYS_PLL_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 4),
+ kUSB_PLL_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 5),
+ kAUDIO_PLL_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 6),
+ kOSC32K_OSC_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 7),
+
+ kFRO12M_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 0),
+ kEXT_CLK_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 1),
+ kWDT_OSC_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 2),
+ kOSC32K_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 3),
+ kNONE_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 7),
+
+ kFRO12M_to_AUDIO_PLL = MUX_A(CM_AUDPLLCLKSEL, 0),
+ kEXT_CLK_to_AUDIO_PLL = MUX_A(CM_AUDPLLCLKSEL, 1),
+ kNONE_to_AUDIO_PLL = MUX_A(CM_AUDPLLCLKSEL, 7),
+
+ kMAIN_CLK_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 0),
+ kSYS_PLL_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 1),
+ kUSB_PLL_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 2),
+ kFRO_HF_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 3),
+ kAUDIO_PLL_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 4),
+ kNONE_to_SPIFI_CLK = MUX_A(CM_SPIFICLKSEL, 7),
+
+ kFRO_HF_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 0),
+ kSYS_PLL_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 1),
+ kUSB_PLL_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 2),
+ kAUDIO_PLL_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 3),
+ kNONE_to_ADC_CLK = MUX_A(CM_ADCASYNCCLKSEL, 7),
+
+ kFRO_HF_to_USB0_CLK = MUX_A(CM_USB0CLKSEL, 0),
+ kSYS_PLL_to_USB0_CLK = MUX_A(CM_USB0CLKSEL, 1),
+ kUSB_PLL_to_USB0_CLK = MUX_A(CM_USB0CLKSEL, 2),
+ kNONE_to_USB0_CLK = MUX_A(CM_USB0CLKSEL, 7),
+
+ kFRO_HF_to_USB1_CLK = MUX_A(CM_USB1CLKSEL, 0),
+ kSYS_PLL_to_USB1_CLK = MUX_A(CM_USB1CLKSEL, 1),
+ kUSB_PLL_to_USB1_CLK = MUX_A(CM_USB1CLKSEL, 2),
+ kNONE_to_USB1_CLK = MUX_A(CM_USB1CLKSEL, 7),
+
+ kFRO12M_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 0),
+ kFRO_HF_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 1),
+ kAUDIO_PLL_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 2),
+ kMCLK_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 3),
+ kFRG_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 4),
+ kNONE_to_FLEXCOMM0 = MUX_A(CM_FXCOMCLKSEL0, 7),
+
+ kFRO12M_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 0),
+ kFRO_HF_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 1),
+ kAUDIO_PLL_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 2),
+ kMCLK_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 3),
+ kFRG_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 4),
+ kNONE_to_FLEXCOMM1 = MUX_A(CM_FXCOMCLKSEL1, 7),
+
+ kFRO12M_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 0),
+ kFRO_HF_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 1),
+ kAUDIO_PLL_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 2),
+ kMCLK_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 3),
+ kFRG_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 4),
+ kNONE_to_FLEXCOMM2 = MUX_A(CM_FXCOMCLKSEL2, 7),
+
+ kFRO12M_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 0),
+ kFRO_HF_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 1),
+ kAUDIO_PLL_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 2),
+ kMCLK_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 3),
+ kFRG_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 4),
+ kNONE_to_FLEXCOMM3 = MUX_A(CM_FXCOMCLKSEL3, 7),
+
+ kFRO12M_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 0),
+ kFRO_HF_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 1),
+ kAUDIO_PLL_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 2),
+ kMCLK_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 3),
+ kFRG_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 4),
+ kNONE_to_FLEXCOMM4 = MUX_A(CM_FXCOMCLKSEL4, 7),
+
+ kFRO12M_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 0),
+ kFRO_HF_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 1),
+ kAUDIO_PLL_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 2),
+ kMCLK_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 3),
+ kFRG_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 4),
+ kNONE_to_FLEXCOMM5 = MUX_A(CM_FXCOMCLKSEL5, 7),
+
+ kFRO12M_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 0),
+ kFRO_HF_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 1),
+ kAUDIO_PLL_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 2),
+ kMCLK_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 3),
+ kFRG_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 4),
+ kNONE_to_FLEXCOMM6 = MUX_A(CM_FXCOMCLKSEL6, 7),
+
+ kFRO12M_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 0),
+ kFRO_HF_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 1),
+ kAUDIO_PLL_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 2),
+ kMCLK_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 3),
+ kFRG_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 4),
+ kNONE_to_FLEXCOMM7 = MUX_A(CM_FXCOMCLKSEL7, 7),
+
+ kFRO12M_to_FLEXCOMM8 = MUX_A(CM_FXCOMCLKSEL8, 0),
+ kFRO_HF_to_FLEXCOMM8 = MUX_A(CM_FXCOMCLKSEL8, 1),
+ kAUDIO_PLL_to_FLEXCOMM8 = MUX_A(CM_FXCOMCLKSEL8, 2),
+ kMCLK_to_FLEXCOMM8 = MUX_A(CM_FXCOMCLKSEL8, 3),
+ kFRG_to_FLEXCOMM8 = MUX_A(CM_FXCOMCLKSEL8, 4),
+ kNONE_to_FLEXCOMM8 = MUX_A(CM_FXCOMCLKSEL8, 7),
+
+ kFRO12M_to_FLEXCOMM9 = MUX_A(CM_FXCOMCLKSEL9, 0),
+ kFRO_HF_to_FLEXCOMM9 = MUX_A(CM_FXCOMCLKSEL9, 1),
+ kAUDIO_PLL_to_FLEXCOMM9 = MUX_A(CM_FXCOMCLKSEL9, 2),
+ kMCLK_to_FLEXCOMM9 = MUX_A(CM_FXCOMCLKSEL9, 3),
+ kFRG_to_FLEXCOMM9 = MUX_A(CM_FXCOMCLKSEL9, 4),
+ kNONE_to_FLEXCOMM9 = MUX_A(CM_FXCOMCLKSEL9, 7),
+
+ kMAIN_CLK_to_FLEXCOMM10 = MUX_A(CM_FXCOMCLKSEL10, 0),
+ kSYS_PLL_to_FLEXCOMM10 = MUX_A(CM_FXCOMCLKSEL10, 1),
+ kUSB_PLL_to_FLEXCOMM10 = MUX_A(CM_FXCOMCLKSEL10, 2),
+ kFRO_HF_to_FLEXCOMM10 = MUX_A(CM_FXCOMCLKSEL10, 3),
+ kAUDIO_PLL_to_FLEXCOMM10 = MUX_A(CM_FXCOMCLKSEL10, 4),
+ kNONE_to_FLEXCOMM10 = MUX_A(CM_FXCOMCLKSEL10, 7),
+
+ kFRO_HF_to_MCLK = MUX_A(CM_MCLKCLKSEL, 0),
+ kAUDIO_PLL_to_MCLK = MUX_A(CM_MCLKCLKSEL, 1),
+ kNONE_to_MCLK = MUX_A(CM_MCLKCLKSEL, 7),
+
+ kMAIN_CLK_to_FRG = MUX_A(CM_FRGCLKSEL, 0),
+ kSYS_PLL_to_FRG = MUX_A(CM_FRGCLKSEL, 1),
+ kFRO12M_to_FRG = MUX_A(CM_FRGCLKSEL, 2),
+ kFRO_HF_to_FRG = MUX_A(CM_FRGCLKSEL, 3),
+ kNONE_to_FRG = MUX_A(CM_FRGCLKSEL, 7),
+
+ kFRO12M_to_DMIC = MUX_A(CM_DMICCLKSEL, 0),
+ kFRO_HF_DIV_to_DMIC = MUX_A(CM_DMICCLKSEL, 1),
+ kAUDIO_PLL_to_DMIC = MUX_A(CM_DMICCLKSEL, 2),
+ kMCLK_to_DMIC = MUX_A(CM_DMICCLKSEL, 3),
+ kMAIN_CLK_to_DMIC = MUX_A(CM_DMICCLKSEL, 4),
+ kWDT_OSC_to_DMIC = MUX_A(CM_DMICCLKSEL, 5),
+ kNONE_to_DMIC = MUX_A(CM_DMICCLKSEL, 7),
+
+ kMAIN_CLK_to_SCT_CLK = MUX_A(CM_SCTCLKSEL, 0),
+ kSYS_PLL_to_SCT_CLK = MUX_A(CM_SCTCLKSEL, 1),
+ kFRO_HF_to_SCT_CLK = MUX_A(CM_SCTCLKSEL, 2),
+ kAUDIO_PLL_to_SCT_CLK = MUX_A(CM_SCTCLKSEL, 3),
+ kNONE_to_SCT_CLK = MUX_A(CM_SCTCLKSEL, 7),
+
+ kMAIN_CLK_to_LCD_CLK = MUX_A(CM_LCDCLKSEL, 0),
+ kLCDCLKIN_to_LCD_CLK = MUX_A(CM_LCDCLKSEL, 1),
+ kFRO_HF_to_LCD_CLK = MUX_A(CM_LCDCLKSEL, 2),
+ kNONE_to_LCD_CLK = MUX_A(CM_LCDCLKSEL, 3),
+
+ kMAIN_CLK_to_SDIO_CLK = MUX_A(CM_SDIOCLKSEL, 0),
+ kSYS_PLL_to_SDIO_CLK = MUX_A(CM_SDIOCLKSEL, 1),
+ kUSB_PLL_to_SDIO_CLK = MUX_A(CM_SDIOCLKSEL, 2),
+ kFRO_HF_to_SDIO_CLK = MUX_A(CM_SDIOCLKSEL, 3),
+ kAUDIO_PLL_to_SDIO_CLK = MUX_A(CM_SDIOCLKSEL, 4),
+ kNONE_to_SDIO_CLK = MUX_A(CM_SDIOCLKSEL, 7),
+
+ kMAIN_CLK_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 0),
+ kFRO12M_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 1),
+ kAUDIO_PLL_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 2),
+ kI2C_CLK_FC6_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 3),
+ kNONE_to_NONE = (int)0x80000000U,
+} clock_attach_id_t;
+
+/* Clock dividers */
+typedef enum _clock_div_name
+{
+ kCLOCK_DivSystickClk = 0,
+ kCLOCK_DivArmTrClkDiv = 1,
+ kCLOCK_DivCan0Clk = 2,
+ kCLOCK_DivCan1Clk = 3,
+ kCLOCK_DivSmartCard0Clk = 4,
+ kCLOCK_DivSmartCard1Clk = 5,
+ kCLOCK_DivAhbClk = 32,
+ kCLOCK_DivClkOut = 33,
+ kCLOCK_DivFrohfClk = 34,
+ kCLOCK_DivSpifiClk = 36,
+ kCLOCK_DivAdcAsyncClk = 37,
+ kCLOCK_DivUsb0Clk = 38,
+ kCLOCK_DivUsb1Clk = 39,
+ kCLOCK_DivFrg = 40,
+ kCLOCK_DivDmicClk = 42,
+ kCLOCK_DivMClk = 43,
+ kCLOCK_DivLcdClk = 44,
+ kCLOCK_DivSctClk = 45,
+ kCLOCK_DivEmcClk = 46,
+ kCLOCK_DivSdioClk = 47
+} clock_div_name_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+static inline void CLOCK_EnableClock(clock_ip_name_t clk)
+{
+ uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
+ if (index < 3UL)
+ {
+ SYSCON->AHBCLKCTRLSET[index] = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+ }
+ else
+ {
+ SYSCON->ASYNCAPBCTRL = SYSCON_ASYNCAPBCTRL_ENABLE(1);
+ ASYNC_SYSCON->ASYNCAPBCLKCTRLSET = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+ }
+}
+
+static inline void CLOCK_DisableClock(clock_ip_name_t clk)
+{
+ uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk);
+ if (index < 3UL)
+ {
+ SYSCON->AHBCLKCTRLCLR[index] = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+ }
+ else
+ {
+ ASYNC_SYSCON->ASYNCAPBCLKCTRLCLR = (1UL << CLK_GATE_ABSTRACT_BITS_SHIFT(clk));
+ SYSCON->ASYNCAPBCTRL = SYSCON_ASYNCAPBCTRL_ENABLE(0);
+ }
+}
+
+/**
+ * @brief
+ * Initialize the Core clock to given frequency (12, 48 or 96 MHz), this API is implememnt in ROM code.
+ * Turns on FRO and uses default CCO, if freq is 12000000, then high speed output is off, else high speed
+ * output is enabled.
+ * Usage: CLOCK_SetupFROClocking(frequency), (frequency must be one of 12, 48 or 96 MHz)
+ * Note: Need to make sure ROM and OTP has power(PDRUNCFG0[17,29]= 0U) before calling this API since this API is
+ * implemented in ROM code and the FROHF TRIM value is stored in OTP
+ *
+ * @param froFreq target fro frequency.
+ * @return Nothing
+ */
+
+void CLOCK_SetupFROClocking(uint32_t froFreq);
+
+/**
+ * @brief Configure the clock selection muxes.
+ * @param connection : Clock to be configured.
+ * @return Nothing
+ */
+void CLOCK_AttachClk(clock_attach_id_t connection);
+/**
+ * @brief Get the actual clock attach id.
+ * This fuction uses the offset in input attach id, then it reads the actual source value in
+ * the register and combine the offset to obtain an actual attach id.
+ * @param attachId : Clock attach id to get.
+ * @return Clock source value.
+ */
+clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId);
+/**
+ * @brief Setup peripheral clock dividers.
+ * @param div_name : Clock divider name
+ * @param divided_by_value: Value to be divided
+ * @param reset : Whether to reset the divider counter.
+ * @return Nothing
+ */
+void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset);
+
+/*! @brief Return Frequency of selected clock
+ * @return Frequency of selected clock
+ */
+uint32_t CLOCK_GetFreq(clock_name_t clockName);
+/*! @brief Return Frequency of FRO 12MHz
+ * @return Frequency of FRO 12MHz
+ */
+uint32_t CLOCK_GetFro12MFreq(void);
+/*! @brief Return Frequency of ClockOut
+ * @return Frequency of ClockOut
+ */
+uint32_t CLOCK_GetClockOutClkFreq(void);
+/*! @brief Return Frequency of Spifi Clock
+ * @return Frequency of Spifi.
+ */
+uint32_t CLOCK_GetSpifiClkFreq(void);
+/*! @brief Return Frequency of Adc Clock
+ * @return Frequency of Adc Clock.
+ */
+uint32_t CLOCK_GetAdcClkFreq(void);
+/*! brief Return Frequency of MCAN Clock
+ * param MCanSel : 0U: MCAN0; 1U: MCAN1
+ * return Frequency of MCAN Clock
+ */
+uint32_t CLOCK_GetMCanClkFreq(uint32_t MCanSel);
+/*! @brief Return Frequency of Usb0 Clock
+ * @return Frequency of Usb0 Clock.
+ */
+uint32_t CLOCK_GetUsb0ClkFreq(void);
+/*! @brief Return Frequency of Usb1 Clock
+ * @return Frequency of Usb1 Clock.
+ */
+uint32_t CLOCK_GetUsb1ClkFreq(void);
+/*! @brief Return Frequency of MClk Clock
+ * @return Frequency of MClk Clock.
+ */
+uint32_t CLOCK_GetMclkClkFreq(void);
+/*! @brief Return Frequency of SCTimer Clock
+ * @return Frequency of SCTimer Clock.
+ */
+uint32_t CLOCK_GetSctClkFreq(void);
+/*! @brief Return Frequency of SDIO Clock
+ * @return Frequency of SDIO Clock.
+ */
+uint32_t CLOCK_GetSdioClkFreq(void);
+/*! @brief Return Frequency of LCD Clock
+ * @return Frequency of LCD Clock.
+ */
+uint32_t CLOCK_GetLcdClkFreq(void);
+/*! @brief Return Frequency of LCD CLKIN Clock
+ * @return Frequency of LCD CLKIN Clock.
+ */
+uint32_t CLOCK_GetLcdClkIn(void);
+/*! @brief Return Frequency of External Clock
+ * @return Frequency of External Clock. If no external clock is used returns 0.
+ */
+uint32_t CLOCK_GetExtClkFreq(void);
+/*! @brief Return Frequency of Watchdog Oscillator
+ * @return Frequency of Watchdog Oscillator
+ */
+uint32_t CLOCK_GetWdtOscFreq(void);
+/*! @brief Return Frequency of High-Freq output of FRO
+ * @return Frequency of High-Freq output of FRO
+ */
+uint32_t CLOCK_GetFroHfFreq(void);
+/*! @brief Return Frequency of frg
+ * @return Frequency of FRG
+ */
+uint32_t CLOCK_GetFrgClkFreq(void);
+/*! @brief Return Frequency of dmic
+ * @return Frequency of DMIC
+ */
+uint32_t CLOCK_GetDmicClkFreq(void);
+
+/*!
+ * @brief Set FRG Clk
+ * @return
+ * 1: if set FRG CLK successfully.
+ * 0: if set FRG CLK fail.
+ */
+uint32_t CLOCK_SetFRGClock(uint32_t freq);
+
+/*! @brief Return Frequency of PLL
+ * @return Frequency of PLL
+ */
+uint32_t CLOCK_GetPllOutFreq(void);
+/*! @brief Return Frequency of USB PLL
+ * @return Frequency of PLL
+ */
+uint32_t CLOCK_GetUsbPllOutFreq(void);
+/*! @brief Return Frequency of AUDIO PLL
+ * @return Frequency of PLL
+ */
+uint32_t CLOCK_GetAudioPllOutFreq(void);
+/*! @brief Return Frequency of 32kHz osc
+ * @return Frequency of 32kHz osc
+ */
+uint32_t CLOCK_GetOsc32KFreq(void);
+/*! @brief Return Frequency of Core System
+ * @return Frequency of Core System
+ */
+uint32_t CLOCK_GetCoreSysClkFreq(void);
+/*! @brief Return Frequency of I2S MCLK Clock
+ * @return Frequency of I2S MCLK Clock
+ */
+uint32_t CLOCK_GetI2SMClkFreq(void);
+/*! @brief Return Frequency of Flexcomm functional Clock
+ * @return Frequency of Flexcomm functional Clock
+ */
+uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id);
+
+/*! @brief return FRG Clk
+ * @return Frequency of FRG CLK.
+ */
+uint32_t CLOCK_GetFRGInputClock(void);
+/*! @brief Return Asynchronous APB Clock source
+ * @return Asynchronous APB CLock source
+ */
+__STATIC_INLINE async_clock_src_t CLOCK_GetAsyncApbClkSrc(void)
+{
+ return (async_clock_src_t)(uint32_t)(ASYNC_SYSCON->ASYNCAPBCLKSELA & 0x3U);
+}
+/*! @brief Return Frequency of Asynchronous APB Clock
+ * @return Frequency of Asynchronous APB Clock Clock
+ */
+uint32_t CLOCK_GetAsyncApbClkFreq(void);
+/*! @brief Return EMC source
+ * @return EMC source
+ */
+__STATIC_INLINE uint32_t CLOCK_GetEmcClkFreq(void)
+{
+ uint32_t freqtmp;
+
+ freqtmp = CLOCK_GetCoreSysClkFreq() / ((SYSCON->AHBCLKDIV & 0xffU) + 1U);
+ return freqtmp / ((SYSCON->EMCCLKDIV & 0xffU) + 1U);
+}
+/*! @brief Return Audio PLL input clock rate
+ * @return Audio PLL input clock rate
+ */
+uint32_t CLOCK_GetAudioPLLInClockRate(void);
+/*! @brief Return System PLL input clock rate
+ * @return System PLL input clock rate
+ */
+uint32_t CLOCK_GetSystemPLLInClockRate(void);
+
+/*! @brief Return System PLL output clock rate
+ * @param recompute : Forces a PLL rate recomputation if true
+ * @return System PLL output clock rate
+ * @note The PLL rate is cached in the driver in a variable as
+ * the rate computation function can take some time to perform. It
+ * is recommended to use 'false' with the 'recompute' parameter.
+ */
+uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute);
+
+/*! @brief Return System AUDIO PLL output clock rate
+ * @param recompute : Forces a AUDIO PLL rate recomputation if true
+ * @return System AUDIO PLL output clock rate
+ * @note The AUDIO PLL rate is cached in the driver in a variable as
+ * the rate computation function can take some time to perform. It
+ * is recommended to use 'false' with the 'recompute' parameter.
+ */
+uint32_t CLOCK_GetAudioPLLOutClockRate(bool recompute);
+
+/*! @brief Return System USB PLL output clock rate
+ * @param recompute : Forces a USB PLL rate recomputation if true
+ * @return System USB PLL output clock rate
+ * @note The USB PLL rate is cached in the driver in a variable as
+ * the rate computation function can take some time to perform. It
+ * is recommended to use 'false' with the 'recompute' parameter.
+ */
+uint32_t CLOCK_GetUsbPLLOutClockRate(bool recompute);
+
+/*! @brief Enables and disables PLL bypass mode
+ * @brief bypass : true to bypass PLL (PLL output = PLL input, false to disable bypass
+ * @return System PLL output clock rate
+ */
+__STATIC_INLINE void CLOCK_SetBypassPLL(bool bypass)
+{
+ if (bypass)
+ {
+ SYSCON->SYSPLLCTRL |= (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT);
+ }
+ else
+ {
+ SYSCON->SYSPLLCTRL &= ~(1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT);
+ }
+}
+
+/*! @brief Check if PLL is locked or not
+ * @return true if the PLL is locked, false if not locked
+ */
+__STATIC_INLINE bool CLOCK_IsSystemPLLLocked(void)
+{
+ return (bool)((SYSCON->SYSPLLSTAT & SYSCON_SYSPLLSTAT_LOCK_MASK) != 0U);
+}
+
+/*! @brief Check if USB PLL is locked or not
+ * @return true if the USB PLL is locked, false if not locked
+ */
+__STATIC_INLINE bool CLOCK_IsUsbPLLLocked(void)
+{
+ return (bool)((SYSCON->USBPLLSTAT & SYSCON_USBPLLSTAT_LOCK_MASK) != 0U);
+}
+
+/*! @brief Check if AUDIO PLL is locked or not
+ * @return true if the AUDIO PLL is locked, false if not locked
+ */
+__STATIC_INLINE bool CLOCK_IsAudioPLLLocked(void)
+{
+ return (bool)((SYSCON->AUDPLLSTAT & SYSCON_AUDPLLSTAT_LOCK_MASK) != 0U);
+}
+
+/*! @brief Enables and disables SYS OSC
+ * @brief enable : true to enable SYS OSC, false to disable SYS OSC
+ */
+__STATIC_INLINE void CLOCK_Enable_SysOsc(bool enable)
+{
+ if (enable)
+ {
+ SYSCON->PDRUNCFGCLR[0] |= SYSCON_PDRUNCFG_PDEN_VD2_ANA_MASK;
+ SYSCON->PDRUNCFGCLR[1] |= SYSCON_PDRUNCFG_PDEN_SYSOSC_MASK;
+ }
+
+ else
+ {
+ SYSCON->PDRUNCFGSET[0] = SYSCON_PDRUNCFG_PDEN_VD2_ANA_MASK;
+ SYSCON->PDRUNCFGSET[1] = SYSCON_PDRUNCFG_PDEN_SYSOSC_MASK;
+ }
+}
+
+/*! @brief Store the current PLL rate
+ * @param rate: Current rate of the PLL
+ * @return Nothing
+ **/
+void CLOCK_SetStoredPLLClockRate(uint32_t rate);
+
+/*! @brief Store the current AUDIO PLL rate
+ * @param rate: Current rate of the PLL
+ * @return Nothing
+ **/
+void CLOCK_SetStoredAudioPLLClockRate(uint32_t rate);
+
+/*! @brief PLL configuration structure flags for 'flags' field
+ * These flags control how the PLL configuration function sets up the PLL setup structure.<br>
+ *
+ * When the PLL_CONFIGFLAG_USEINRATE flag is selected, the 'InputRate' field in the
+ * configuration structure must be assigned with the expected PLL frequency. If the
+ * PLL_CONFIGFLAG_USEINRATE is not used, 'InputRate' is ignored in the configuration
+ * function and the driver will determine the PLL rate from the currently selected
+ * PLL source. This flag might be used to configure the PLL input clock more accurately
+ * when using the WDT oscillator or a more dyanmic CLKIN source.<br>
+ *
+ * When the PLL_CONFIGFLAG_FORCENOFRACT flag is selected, the PLL hardware for the
+ * automatic bandwidth selection, Spread Spectrum (SS) support, and fractional M-divider
+ * are not used.<br>
+ */
+#define PLL_CONFIGFLAG_USEINRATE (1U << 0U) /*!< Flag to use InputRate in PLL configuration structure for setup */
+#define PLL_CONFIGFLAG_FORCENOFRACT \
+ (1U << 2U) /*!< Force non-fractional output mode, PLL output will not use the fractional, automatic bandwidth, or \
+ SS hardware */
+
+/*! @brief PLL configuration structure
+ *
+ * This structure can be used to configure the settings for a PLL
+ * setup structure. Fill in the desired configuration for the PLL
+ * and call the PLL setup function to fill in a PLL setup structure.
+ */
+typedef struct _pll_config
+{
+ uint32_t desiredRate; /*!< Desired PLL rate in Hz */
+ uint32_t inputRate; /*!< PLL input clock in Hz, only used if PLL_CONFIGFLAG_USEINRATE flag is set */
+ uint32_t flags; /*!< PLL configuration flags, Or'ed value of PLL_CONFIGFLAG_* definitions */
+} pll_config_t;
+
+/*! @brief PLL setup structure flags for 'flags' field
+ * These flags control how the PLL setup function sets up the PLL
+ */
+#define PLL_SETUPFLAG_POWERUP (1U << 0U) /*!< Setup will power on the PLL after setup */
+#define PLL_SETUPFLAG_WAITLOCK (1U << 1U) /*!< Setup will wait for PLL lock, implies the PLL will be pwoered on */
+#define PLL_SETUPFLAG_ADGVOLT (1U << 2U) /*!< Optimize system voltage for the new PLL rate */
+
+/*! @brief PLL setup structure
+ * This structure can be used to pre-build a PLL setup configuration
+ * at run-time and quickly set the PLL to the configuration. It can be
+ * populated with the PLL setup function. If powering up or waiting
+ * for PLL lock, the PLL input clock source should be configured prior
+ * to PLL setup.
+ */
+typedef struct _pll_setup
+{
+ uint32_t pllctrl; /*!< PLL control register SYSPLLCTRL */
+ uint32_t pllndec; /*!< PLL NDEC register SYSPLLNDEC */
+ uint32_t pllpdec; /*!< PLL PDEC register SYSPLLPDEC */
+ uint32_t pllmdec; /*!< PLL MDEC registers SYSPLLPDEC */
+ uint32_t pllRate; /*!< Acutal PLL rate */
+ uint32_t audpllfrac; /*!< only aduio PLL has this function*/
+ uint32_t flags; /*!< PLL setup flags, Or'ed value of PLL_SETUPFLAG_* definitions */
+} pll_setup_t;
+
+/*! @brief PLL status definitions
+ */
+typedef enum _pll_error
+{
+ kStatus_PLL_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< PLL operation was successful */
+ kStatus_PLL_OutputTooLow = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< PLL output rate request was too low */
+ kStatus_PLL_OutputTooHigh = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< PLL output rate request was too high */
+ kStatus_PLL_InputTooLow = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< PLL input rate is too low */
+ kStatus_PLL_InputTooHigh = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< PLL input rate is too high */
+ kStatus_PLL_OutsideIntLimit = MAKE_STATUS(kStatusGroup_Generic, 5), /*!< Requested output rate isn't possible */
+ kStatus_PLL_CCOTooLow = MAKE_STATUS(kStatusGroup_Generic, 6), /*!< Requested CCO rate isn't possible */
+ kStatus_PLL_CCOTooHigh = MAKE_STATUS(kStatusGroup_Generic, 7) /*!< Requested CCO rate isn't possible */
+} pll_error_t;
+
+/*! @brief USB clock source definition. */
+typedef enum _clock_usb_src
+{
+ kCLOCK_UsbSrcFro = (uint32_t)kCLOCK_FroHf, /*!< Use FRO 96 or 48 MHz. */
+ kCLOCK_UsbSrcSystemPll = (uint32_t)kCLOCK_PllOut, /*!< Use System PLL output. */
+ kCLOCK_UsbSrcMainClock = (uint32_t)kCLOCK_CoreSysClk, /*!< Use Main clock. */
+ kCLOCK_UsbSrcUsbPll = (uint32_t)kCLOCK_UsbPll, /*!< Use USB PLL clock. */
+
+ kCLOCK_UsbSrcNone = SYSCON_USB0CLKSEL_SEL(
+ 7U) /*!< Use None, this may be selected in order to reduce power when no output is needed.. */
+} clock_usb_src_t;
+
+/*! @brief USB PDEL Divider. */
+typedef enum _usb_pll_psel
+{
+ pSel_Divide_1 = 0U,
+ pSel_Divide_2,
+ pSel_Divide_4,
+ pSel_Divide_8
+} usb_pll_psel;
+
+/*! @brief PLL setup structure
+ * This structure can be used to pre-build a USB PLL setup configuration
+ * at run-time and quickly set the usb PLL to the configuration. It can be
+ * populated with the USB PLL setup function. If powering up or waiting
+ * for USB PLL lock, the PLL input clock source should be configured prior
+ * to USB PLL setup.
+ */
+typedef struct _usb_pll_setup
+{
+ uint8_t msel; /*!< USB PLL control register msel:1U-256U */
+ uint8_t psel; /*!< USB PLL control register psel:only support inter 1U 2U 4U 8U */
+ uint8_t nsel; /*!< USB PLL control register nsel:only suppoet inter 1U 2U 3U 4U */
+ bool direct; /*!< USB PLL CCO output control */
+ bool bypass; /*!< USB PLL inout clock bypass control */
+ bool fbsel; /*!< USB PLL ineter mode and non-integer mode control*/
+ uint32_t inputRate; /*!< USB PLL input rate */
+} usb_pll_setup_t;
+
+/*! @brief Return System PLL output clock rate from setup structure
+ * @param pSetup : Pointer to a PLL setup structure
+ * @return System PLL output clock rate the setup structure will generate
+ */
+uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup);
+
+/*! @brief Return System AUDIO PLL output clock rate from setup structure
+ * @param pSetup : Pointer to a PLL setup structure
+ * @return System PLL output clock rate the setup structure will generate
+ */
+uint32_t CLOCK_GetAudioPLLOutFromSetup(pll_setup_t *pSetup);
+
+/*! @brief Return System AUDIO PLL output clock rate from audio fractioanl setup structure
+ * @param pSetup : Pointer to a PLL setup structure
+ * @return System PLL output clock rate the setup structure will generate
+ */
+uint32_t CLOCK_GetAudioPLLOutFromFractSetup(pll_setup_t *pSetup);
+
+/*! @brief Return System USB PLL output clock rate from setup structure
+ * @param pSetup : Pointer to a PLL setup structure
+ * @return System PLL output clock rate the setup structure will generate
+ */
+uint32_t CLOCK_GetUsbPLLOutFromSetup(const usb_pll_setup_t *pSetup);
+
+/*! @brief Set PLL output based on the passed PLL setup data
+ * @param pControl : Pointer to populated PLL control structure to generate setup with
+ * @param pSetup : Pointer to PLL setup structure to be filled
+ * @return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * @note Actual frequency for setup may vary from the desired frequency based on the
+ * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
+ */
+pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup);
+
+/*! @brief Set AUDIO PLL output based on the passed AUDIO PLL setup data
+ * @param pControl : Pointer to populated PLL control structure to generate setup with
+ * @param pSetup : Pointer to PLL setup structure to be filled
+ * @return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * @note Actual frequency for setup may vary from the desired frequency based on the
+ * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
+ */
+pll_error_t CLOCK_SetupAudioPLLData(pll_config_t *pControl, pll_setup_t *pSetup);
+
+/*! @brief Set PLL output from PLL setup structure (precise frequency)
+ * @param pSetup : Pointer to populated PLL setup structure
+ * @param flagcfg : Flag configuration for PLL config structure
+ * @return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * @note This function will power off the PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the PLL, wait for PLL lock,
+ * and adjust system voltages to the new PLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg);
+
+/*! @brief Set AUDIO PLL output from AUDIOPLL setup structure (precise frequency)
+ * @param pSetup : Pointer to populated PLL setup structure
+ * @param flagcfg : Flag configuration for PLL config structure
+ * @return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * @note This function will power off the PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
+ * and adjust system voltages to the new AUDIOPLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetupAudioPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg);
+
+/*! @brief Set AUDIO PLL output from AUDIOPLL setup structure using the Audio Fractional divider register(precise
+ * frequency)
+ * @param pSetup : Pointer to populated PLL setup structure
+ * @param flagcfg : Flag configuration for PLL config structure
+ * @return PLL_ERROR_SUCCESS on success, or PLL setup error code
+ * @note This function will power off the PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the AUDIO PLL, wait for PLL lock,
+ * and adjust system voltages to the new AUDIOPLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the AUDIO PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetupAudioPLLPrecFract(pll_setup_t *pSetup, uint32_t flagcfg);
+
+/**
+ * @brief Set PLL output from PLL setup structure (precise frequency)
+ * @param pSetup : Pointer to populated PLL setup structure
+ * @return kStatus_PLL_Success on success, or PLL setup error code
+ * @note This function will power off the PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the PLL, wait for PLL lock,
+ * and adjust system voltages to the new PLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup);
+
+/**
+ * @brief Set Audio PLL output from Audio PLL setup structure (precise frequency)
+ * @param pSetup : Pointer to populated PLL setup structure
+ * @return kStatus_PLL_Success on success, or Audio PLL setup error code
+ * @note This function will power off the PLL, setup the Audio PLL with the
+ * new setup data, and then optionally powerup the PLL, wait for Audio PLL lock,
+ * and adjust system voltages to the new PLL rate. The function will not
+ * alter any source clocks (ie, main systen clock) that may use the Audio PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetAudioPLLFreq(const pll_setup_t *pSetup);
+
+/**
+ * @brief Set USB PLL output from USB PLL setup structure (precise frequency)
+ * @param pSetup : Pointer to populated USB PLL setup structure
+ * @return kStatus_PLL_Success on success, or USB PLL setup error code
+ * @note This function will power off the USB PLL, setup the PLL with the
+ * new setup data, and then optionally powerup the USB PLL, wait for USB PLL lock,
+ * and adjust system voltages to the new USB PLL rate. The function will not
+ * alter any source clocks (ie, usb pll clock) that may use the USB PLL,
+ * so these should be setup prior to and after exiting the function.
+ */
+pll_error_t CLOCK_SetUsbPLLFreq(const usb_pll_setup_t *pSetup);
+
+/*! @brief Set PLL output based on the multiplier and input frequency
+ * @param multiply_by : multiplier
+ * @param input_freq : Clock input frequency of the PLL
+ * @return Nothing
+ * @note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
+ * function does not disable or enable PLL power, wait for PLL lock,
+ * or adjust system voltages. These must be done in the application.
+ * The function will not alter any source clocks (ie, main systen clock)
+ * that may use the PLL, so these should be setup prior to and after
+ * exiting the function.
+ */
+void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq);
+
+/*! @brief Disable USB clock.
+ *
+ * Disable USB clock.
+ */
+static inline void CLOCK_DisableUsbDevicefs0Clock(clock_ip_name_t clk)
+{
+ CLOCK_DisableClock(clk);
+}
+
+/*! @brief Enable USB Device FS clock.
+ * @param src : clock source
+ * @param freq: clock frequency
+ * Enable USB Device Full Speed clock.
+ */
+bool CLOCK_EnableUsbfs0DeviceClock(clock_usb_src_t src, uint32_t freq);
+
+/*! @brief Enable USB HOST FS clock.
+ * @param src : clock source
+ * @param freq: clock frequency
+ * Enable USB HOST Full Speed clock.
+ */
+bool CLOCK_EnableUsbfs0HostClock(clock_usb_src_t src, uint32_t freq);
+
+/*! @brief Set the current Usb PLL Rate
+ */
+void CLOCK_SetStoredUsbPLLClockRate(uint32_t rate);
+
+/*! @brief Enable USB Device HS clock.
+ * @param src : clock source
+ * @param freq: clock frequency
+ * Enable USB Device High Speed clock.
+ */
+bool CLOCK_EnableUsbhs0DeviceClock(clock_usb_src_t src, uint32_t freq);
+
+/*! @brief Enable USB HOST HS clock.
+ * @param src : clock source
+ * @param freq: clock frequency
+ * Enable USB HOST High Speed clock.
+ */
+bool CLOCK_EnableUsbhs0HostClock(clock_usb_src_t src, uint32_t freq);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+
+/*! @} */
+
+#endif /* _FSL_CLOCK_H_ */
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_common.c b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_common.c
new file mode 100644
index 000000000..f6284379c
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_common.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#define SDK_MEM_MAGIC_NUMBER 12345U
+
+typedef struct _mem_align_control_block
+{
+ uint16_t identifier; /*!< Identifier for the memory control block. */
+ uint16_t offset; /*!< offset from aligned address to real address */
+} mem_align_cb_t;
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.common"
+#endif
+
+#ifndef __GIC_PRIO_BITS
+#if defined(ENABLE_RAM_VECTOR_TABLE)
+uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler)
+{
+/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */
+#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
+ extern uint32_t Image$$VECTOR_ROM$$Base[];
+ extern uint32_t Image$$VECTOR_RAM$$Base[];
+ extern uint32_t Image$$RW_m_data$$Base[];
+
+#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base
+#define __VECTOR_RAM Image$$VECTOR_RAM$$Base
+#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base))
+#elif defined(__ICCARM__)
+ extern uint32_t __RAM_VECTOR_TABLE_SIZE[];
+ extern uint32_t __VECTOR_TABLE[];
+ extern uint32_t __VECTOR_RAM[];
+#elif defined(__GNUC__)
+ extern uint32_t __VECTOR_TABLE[];
+ extern uint32_t __VECTOR_RAM[];
+ extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[];
+ uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES);
+#endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */
+ uint32_t n;
+ uint32_t ret;
+ uint32_t irqMaskValue;
+
+ irqMaskValue = DisableGlobalIRQ();
+ if (SCB->VTOR != (uint32_t)__VECTOR_RAM)
+ {
+ /* Copy the vector table from ROM to RAM */
+ for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++)
+ {
+ __VECTOR_RAM[n] = __VECTOR_TABLE[n];
+ }
+ /* Point the VTOR to the position of vector table */
+ SCB->VTOR = (uint32_t)__VECTOR_RAM;
+ }
+
+ ret = __VECTOR_RAM[irq + 16];
+ /* make sure the __VECTOR_RAM is noncachable */
+ __VECTOR_RAM[irq + 16] = irqHandler;
+
+ EnableGlobalIRQ(irqMaskValue);
+
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+
+ return ret;
+}
+#endif /* ENABLE_RAM_VECTOR_TABLE. */
+#endif /* __GIC_PRIO_BITS. */
+
+#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0))
+#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS)
+
+void EnableDeepSleepIRQ(IRQn_Type interrupt)
+{
+ uint32_t intNumber = (uint32_t)interrupt;
+
+ uint32_t index = 0;
+
+ while (intNumber >= 32u)
+ {
+ index++;
+ intNumber -= 32u;
+ }
+
+ SYSCON->STARTERSET[index] = 1u << intNumber;
+ EnableIRQ(interrupt); /* also enable interrupt at NVIC */
+}
+
+void DisableDeepSleepIRQ(IRQn_Type interrupt)
+{
+ uint32_t intNumber = (uint32_t)interrupt;
+
+ DisableIRQ(interrupt); /* also disable interrupt at NVIC */
+ uint32_t index = 0;
+
+ while (intNumber >= 32u)
+ {
+ index++;
+ intNumber -= 32u;
+ }
+
+ SYSCON->STARTERCLR[index] = 1u << intNumber;
+}
+#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */
+#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
+
+void *SDK_Malloc(size_t size, size_t alignbytes)
+{
+ mem_align_cb_t *p_cb = NULL;
+ uint32_t alignedsize = SDK_SIZEALIGN(size, alignbytes) + alignbytes + sizeof(mem_align_cb_t);
+ union
+ {
+ void *pointer_value;
+ uint32_t unsigned_value;
+ } p_align_addr, p_addr;
+
+ p_addr.pointer_value = malloc(alignedsize);
+
+ if (p_addr.pointer_value == NULL)
+ {
+ return NULL;
+ }
+
+ p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes);
+
+ p_cb = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U);
+ p_cb->identifier = SDK_MEM_MAGIC_NUMBER;
+ p_cb->offset = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value);
+
+ return p_align_addr.pointer_value;
+}
+
+void SDK_Free(void *ptr)
+{
+ union
+ {
+ void *pointer_value;
+ uint32_t unsigned_value;
+ } p_free;
+ p_free.pointer_value = ptr;
+ mem_align_cb_t *p_cb = (mem_align_cb_t *)(p_free.unsigned_value - 4U);
+
+ if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER)
+ {
+ return;
+ }
+
+ p_free.unsigned_value = p_free.unsigned_value - p_cb->offset;
+
+ free(p_free.pointer_value);
+}
+
+/*!
+ * @brief Delay function bases on while loop, every loop includes three instructions.
+ *
+ * @param count Counts of loop needed for dalay.
+ */
+#ifndef __XCC__
+#if defined(__CC_ARM) /* This macro is arm v5 specific */
+/* clang-format off */
+__ASM static void DelayLoop(uint32_t count)
+{
+loop
+ SUBS R0, R0, #1
+ CMP R0, #0
+ BNE loop
+ BX LR
+}
+/* clang-format on */
+#elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__)
+/* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler,
+ * use SUB and CMP here for compatibility */
+static void DelayLoop(uint32_t count)
+{
+ __ASM volatile(" MOV R0, %0" : : "r"(count));
+ __ASM volatile(
+ "loop: \n"
+#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
+ " SUB R0, R0, #1 \n"
+#else
+ " SUBS R0, R0, #1 \n"
+#endif
+ " CMP R0, #0 \n"
+
+ " BNE loop \n");
+}
+#endif /* defined(__CC_ARM) */
+
+/*!
+ * @brief Delay at least for some time.
+ * Please note that, this API uses while loop for delay, different run-time environments make the time not precise,
+ * if precise delay count was needed, please implement a new delay function with hardware timer.
+ *
+ * @param delay_us Delay time in unit of microsecond.
+ * @param coreClock_Hz Core clock frequency with Hz.
+ */
+void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz)
+{
+ assert(0U != delay_us);
+ uint64_t count = USEC_TO_COUNT(delay_us, coreClock_Hz);
+ assert(count <= UINT32_MAX);
+
+ /* Divide value may be different in various environment to ensure delay is precise.
+ * Every loop count includes three instructions, due to Cortex-M7 sometimes executes
+ * two instructions in one period, through test here set divide 2. Other M cores use
+ * divide 4. By the way, divide 2 or 4 could let odd count lost precision, but it does
+ * not matter because other instructions outside while loop is enough to fill the time.
+ */
+#if (__CORTEX_M == 7)
+ count = count / 2U;
+#else
+ count = count / 4U;
+#endif
+ DelayLoop((uint32_t)count);
+}
+#endif
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_common.h b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_common.h
new file mode 100644
index 000000000..b7be9c3f1
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_common.h
@@ -0,0 +1,648 @@
+/*
+ * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_COMMON_H_
+#define _FSL_COMMON_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if defined(__ICCARM__)
+#include <stddef.h>
+#endif
+
+/*
+ * For CMSIS pack RTE.
+ * CMSIS pack RTE generates "RTC_Components.h" which contains the statements
+ * of the related <RTE_Components_h> element for all selected software components.
+ */
+#ifdef _RTE_
+#include "RTE_Components.h"
+#endif
+
+#include "fsl_device_registers.h"
+
+/*!
+ * @addtogroup ksdk_common
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @brief Construct a status code value from a group and code number. */
+#define MAKE_STATUS(group, code) ((((group)*100) + (code)))
+
+/*! @brief Construct the version number for drivers. */
+#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief common driver version 2.2.2. */
+#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 2, 2))
+/*@}*/
+
+/* Debug console type definition. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console based on UART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console based on LPUART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console based on LPSCI. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console based on USBCDC. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console based on FLEXCOMM. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console based on i.MX UART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console based on LPC_VUSART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_MINI_USART 8U /*!< Debug console based on LPC_USART. */
+#define DEBUG_CONSOLE_DEVICE_TYPE_SWO 9U /*!< Debug console based on SWO. */
+
+/*! @brief Status group numbers. */
+enum _status_groups
+{
+ kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */
+ kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */
+ kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */
+ kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */
+ kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */
+ kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */
+ kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */
+ kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */
+ kStatusGroup_UART = 10, /*!< Group number for UART status codes. */
+ kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */
+ kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */
+ kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */
+ kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/
+ kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/
+ kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/
+ kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */
+ kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */
+ kStatusGroup_SAI = 19, /*!< Group number for SAI status code */
+ kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */
+ 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_CSI = 29, /*!< Group number for CSI status codes */
+ kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI 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. */
+ kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */
+ kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */
+ kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */
+ kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */
+ kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */
+ kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */
+ kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */
+ kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */
+ 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_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/
+ kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/
+ kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/
+ kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */
+ kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */
+ kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */
+ kStatusGroup_PDM = 72, /*!< Group number for MIC status codes. */
+ kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */
+ kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */
+ kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */
+ kStatusGroup_LPC_MINISPI = 76, /*!< Group number for LPC_MINISPI status codes. */
+ kStatusGroup_HASHCRYPT = 77, /*!< Group number for Hashcrypt status codes */
+ kStatusGroup_LPC_SPI_SSP = 78, /*!< Group number for LPC_SPI_SSP status codes. */
+ kStatusGroup_I3C = 79, /*!< Group number for I3C status codes */
+ kStatusGroup_LPC_I2C_1 = 97, /*!< Group number for LPC_I2C_1 status codes. */
+ kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */
+ kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */
+ kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */
+ kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */
+ kStatusGroup_IAP = 102, /*!< Group number for IAP status codes */
+
+ kStatusGroup_HAL_GPIO = 121, /*!< Group number for HAL GPIO status codes. */
+ kStatusGroup_HAL_UART = 122, /*!< Group number for HAL UART status codes. */
+ kStatusGroup_HAL_TIMER = 123, /*!< Group number for HAL TIMER status codes. */
+ kStatusGroup_HAL_SPI = 124, /*!< Group number for HAL SPI status codes. */
+ kStatusGroup_HAL_I2C = 125, /*!< Group number for HAL I2C status codes. */
+ kStatusGroup_HAL_FLASH = 126, /*!< Group number for HAL FLASH status codes. */
+ kStatusGroup_HAL_PWM = 127, /*!< Group number for HAL PWM status codes. */
+ kStatusGroup_HAL_RNG = 128, /*!< Group number for HAL RNG status codes. */
+ kStatusGroup_TIMERMANAGER = 135, /*!< Group number for TiMER MANAGER status codes. */
+ kStatusGroup_SERIALMANAGER = 136, /*!< Group number for SERIAL MANAGER status codes. */
+ kStatusGroup_LED = 137, /*!< Group number for LED status codes. */
+ kStatusGroup_BUTTON = 138, /*!< Group number for BUTTON status codes. */
+ kStatusGroup_EXTERN_EEPROM = 139, /*!< Group number for EXTERN EEPROM status codes. */
+ kStatusGroup_SHELL = 140, /*!< Group number for SHELL status codes. */
+ kStatusGroup_MEM_MANAGER = 141, /*!< Group number for MEM MANAGER status codes. */
+ kStatusGroup_LIST = 142, /*!< Group number for List status codes. */
+ kStatusGroup_OSA = 143, /*!< Group number for OSA status codes. */
+ kStatusGroup_COMMON_TASK = 144, /*!< Group number for Common task status codes. */
+ kStatusGroup_MSG = 145, /*!< Group number for messaging status codes. */
+ kStatusGroup_SDK_OCOTP = 146, /*!< Group number for OCOTP status codes. */
+ kStatusGroup_SDK_FLEXSPINOR = 147, /*!< Group number for FLEXSPINOR status codes.*/
+ kStatusGroup_CODEC = 148, /*!< Group number for codec status codes. */
+ kStatusGroup_ASRC = 149, /*!< Group number for codec status ASRC. */
+ kStatusGroup_OTFAD = 150, /*!< Group number for codec status codes. */
+};
+
+/*! @brief Generic status return codes. */
+enum
+{
+ kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0),
+ kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1),
+ kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2),
+ kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3),
+ kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4),
+ kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5),
+ kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6),
+};
+
+/*! @brief Type used for all status and error return values. */
+typedef int32_t status_t;
+
+/*
+ * Macro guard for whether to use default weak IRQ implementation in drivers
+ */
+#ifndef FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ
+#define FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ 1
+#endif
+
+/*! @name Min/max macros */
+/* @{ */
+#if !defined(MIN)
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#if !defined(MAX)
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+/* @} */
+
+/*! @brief Computes the number of elements in an array. */
+#if !defined(ARRAY_SIZE)
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#endif
+
+/*! @name UINT16_MAX/UINT32_MAX value */
+/* @{ */
+#if !defined(UINT16_MAX)
+#define UINT16_MAX ((uint16_t)-1)
+#endif
+
+#if !defined(UINT32_MAX)
+#define UINT32_MAX ((uint32_t)-1)
+#endif
+/* @} */
+
+/*! @name Timer utilities */
+/* @{ */
+/*! Macro to convert a microsecond period to raw count value */
+#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)(((uint64_t)(us) * (clockFreqInHz)) / 1000000U)
+/*! Macro to convert a raw count value to microsecond */
+#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz)
+
+/*! Macro to convert a millisecond period to raw count value */
+#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U)
+/*! Macro to convert a raw count value to millisecond */
+#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz)
+/* @} */
+
+/*! @name Alignment variable definition macros */
+/* @{ */
+#if (defined(__ICCARM__))
+/**
+ * Workaround to disable MISRA C message suppress warnings for IAR compiler.
+ * http:/ /supp.iar.com/Support/?note=24725
+ */
+_Pragma("diag_suppress=Pm120")
+#define SDK_PRAGMA(x) _Pragma(#x)
+ _Pragma("diag_error=Pm120")
+/*! Macro to define a variable with alignbytes alignment */
+#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
+/*! Macro to define a variable with L1 d-cache line size alignment */
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var
+#endif
+/*! Macro to define a variable with L2 cache line size alignment */
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var
+#endif
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+/*! Macro to define a variable with alignbytes alignment */
+#define SDK_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
+/*! Macro to define a variable with L1 d-cache line size alignment */
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) var
+#endif
+/*! Macro to define a variable with L2 cache line size alignment */
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) var
+#endif
+#elif defined(__GNUC__)
+/*! Macro to define a variable with alignbytes alignment */
+#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
+/*! Macro to define a variable with L1 d-cache line size alignment */
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)))
+#endif
+/*! Macro to define a variable with L2 cache line size alignment */
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)))
+#endif
+#else
+#error Toolchain not supported
+#define SDK_ALIGN(var, alignbytes) var
+#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE)
+#define SDK_L1DCACHE_ALIGN(var) var
+#endif
+#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE)
+#define SDK_L2CACHE_ALIGN(var) var
+#endif
+#endif
+
+/*! Macro to change a value to a given size aligned value */
+#define SDK_SIZEALIGN(var, alignbytes) \
+ ((unsigned int)((var) + ((alignbytes)-1U)) & (unsigned int)(~(unsigned int)((alignbytes)-1U)))
+/* @} */
+
+/*! @name Non-cacheable region definition macros */
+/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or
+ * "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables,
+ * please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables
+ * will be initialized to zero in system startup.
+ */
+/* @{ */
+#if (defined(__ICCARM__))
+#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
+#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable"
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable"
+#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init"
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init"
+#else
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var
+#endif
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
+#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
+ __attribute__((section("NonCacheable.init"))) __attribute__((aligned(alignbytes))) var
+#if(defined(__CC_ARM))
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+ __attribute__((section("NonCacheable"), zero_init)) __attribute__((aligned(alignbytes))) var
+#else
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section(".bss.NonCacheable"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+ __attribute__((section(".bss.NonCacheable"))) __attribute__((aligned(alignbytes))) var
+#endif
+#else
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __attribute__((aligned(alignbytes))) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) __attribute__((aligned(alignbytes))) var
+#endif
+#elif(defined(__XCC__))
+#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
+ __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+ __attribute__((section("NonCacheable"))) var __attribute__((aligned(alignbytes)))
+#elif(defined(__GNUC__))
+/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA"
+ * in your projects to make sure the non-cacheable section variables will be initialized in system startup.
+ */
+#if ((!(defined(FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION) && FSL_FEATURE_HAS_NO_NONCACHEABLE_SECTION)) && defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE))
+#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \
+ __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes)))
+#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \
+ __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes)))
+#else
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes)))
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var __attribute__((aligned(alignbytes)))
+#endif
+#else
+#error Toolchain not supported.
+#define AT_NONCACHEABLE_SECTION(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var
+#define AT_NONCACHEABLE_SECTION_INIT(var) var
+#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var
+#endif
+/* @} */
+
+/*! @name Time sensitive region */
+/* @{ */
+#if defined(FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE) && FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE
+#if (defined(__ICCARM__))
+#define AT_QUICKACCESS_SECTION_CODE(func) func @"CodeQuickAccess"
+#define AT_QUICKACCESS_SECTION_DATA(func) func @"DataQuickAccess"
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
+#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
+#elif(defined(__GNUC__))
+#define AT_QUICKACCESS_SECTION_CODE(func) __attribute__((section("CodeQuickAccess"), __noinline__)) func
+#define AT_QUICKACCESS_SECTION_DATA(func) __attribute__((section("DataQuickAccess"))) func
+#else
+#error Toolchain not supported.
+#endif /* defined(__ICCARM__) */
+#else
+#if (defined(__ICCARM__))
+#define AT_QUICKACCESS_SECTION_CODE(func) func
+#define AT_QUICKACCESS_SECTION_DATA(func) func
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#define AT_QUICKACCESS_SECTION_CODE(func) func
+#define AT_QUICKACCESS_SECTION_DATA(func) func
+#elif(defined(__GNUC__))
+#define AT_QUICKACCESS_SECTION_CODE(func) func
+#define AT_QUICKACCESS_SECTION_DATA(func) func
+#else
+#error Toolchain not supported.
+#endif
+#endif /* __FSL_SDK_DRIVER_QUICK_ACCESS_ENABLE */
+/* @} */
+
+/*! @name Ram Function */
+#if (defined(__ICCARM__))
+#define RAMFUNCTION_SECTION_CODE(func) func @"RamFunction"
+#elif(defined(__CC_ARM) || defined(__ARMCC_VERSION))
+#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
+#elif(defined(__GNUC__))
+#define RAMFUNCTION_SECTION_CODE(func) __attribute__((section("RamFunction"))) func
+#else
+#error Toolchain not supported.
+#endif /* defined(__ICCARM__) */
+/* @} */
+
+/*! @name Suppress fallthrough warning macro */
+/* For switch case code block, if case section ends without "break;" statement, there wil be
+ fallthrough warning with compiler flag -Wextra or -Wimplicit-fallthrough=n when using armgcc.
+ To suppress this warning, "SUPPRESS_FALL_THROUGH_WARNING();" need to be added at the end of each
+ case section which misses "break;"statement.
+ */
+/* @{ */
+#if defined(__GNUC__) && !defined(__ARMCC_VERSION)
+#define SUPPRESS_FALL_THROUGH_WARNING() __attribute__ ((fallthrough))
+#else
+#define SUPPRESS_FALL_THROUGH_WARNING()
+#endif
+/* @} */
+
+#if defined ( __ARMCC_VERSION ) && ( __ARMCC_VERSION >= 6010050 )
+void DefaultISR(void);
+#endif
+/*
+ * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t
+ * defined in previous of this file.
+ */
+#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
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+ extern "C"
+{
+#endif
+
+ /*!
+ * @brief Enable specific interrupt.
+ *
+ * Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt
+ * levels. For example, there are NVIC and intmux. Here the interrupts connected
+ * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
+ * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
+ * to NVIC first then routed to core.
+ *
+ * This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts
+ * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
+ *
+ * @param interrupt The IRQ number.
+ * @retval kStatus_Success Interrupt enabled successfully
+ * @retval kStatus_Fail Failed to enable the interrupt
+ */
+ static inline status_t EnableIRQ(IRQn_Type interrupt)
+ {
+ if (NotAvail_IRQn == interrupt)
+ {
+ return kStatus_Fail;
+ }
+
+#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
+ if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
+ {
+ return kStatus_Fail;
+ }
+#endif
+
+#if defined(__GIC_PRIO_BITS)
+ GIC_EnableIRQ(interrupt);
+#else
+ NVIC_EnableIRQ(interrupt);
+#endif
+ return kStatus_Success;
+ }
+
+ /*!
+ * @brief Disable specific interrupt.
+ *
+ * Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt
+ * levels. For example, there are NVIC and intmux. Here the interrupts connected
+ * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly.
+ * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed
+ * to NVIC first then routed to core.
+ *
+ * This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts
+ * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS.
+ *
+ * @param interrupt The IRQ number.
+ * @retval kStatus_Success Interrupt disabled successfully
+ * @retval kStatus_Fail Failed to disable the interrupt
+ */
+ static inline status_t DisableIRQ(IRQn_Type interrupt)
+ {
+ if (NotAvail_IRQn == interrupt)
+ {
+ return kStatus_Fail;
+ }
+
+#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0)
+ if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS)
+ {
+ return kStatus_Fail;
+ }
+#endif
+
+#if defined(__GIC_PRIO_BITS)
+ GIC_DisableIRQ(interrupt);
+#else
+ NVIC_DisableIRQ(interrupt);
+#endif
+ return kStatus_Success;
+ }
+
+ /*!
+ * @brief Disable the global IRQ
+ *
+ * Disable the global interrupt and return the current primask register. User is required to provided the primask
+ * register for the EnableGlobalIRQ().
+ *
+ * @return Current primask value.
+ */
+ static inline uint32_t DisableGlobalIRQ(void)
+ {
+#if defined (__XCC__)
+ return 0;
+#else
+#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
+#endif
+ }
+
+ /*!
+ * @brief Enable the global IRQ
+ *
+ * Set the primask register with the provided primask value but not just enable the primask. The idea is for the
+ * convenience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to
+ * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair.
+ *
+ * @param primask value of primask register to be restored. The primask value is supposed to be provided by the
+ * DisableGlobalIRQ().
+ */
+ static inline void EnableGlobalIRQ(uint32_t primask)
+ {
+#if defined (__XCC__)
+#else
+#if defined(CPSR_I_Msk)
+ __set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask);
+#else
+ __set_PRIMASK(primask);
+#endif
+#endif
+ }
+
+#if defined(ENABLE_RAM_VECTOR_TABLE)
+ /*!
+ * @brief install IRQ handler
+ *
+ * @param irq IRQ number
+ * @param irqHandler IRQ handler address
+ * @return The old IRQ handler address
+ */
+ uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
+#endif /* ENABLE_RAM_VECTOR_TABLE. */
+
+#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 internaly).
+ *
+ * @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 internaly).
+ *
+ * @param interrupt The IRQ number.
+ */
+ void DisableDeepSleepIRQ(IRQn_Type interrupt);
+#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */
+
+ /*!
+ * @brief Allocate memory with given alignment and aligned size.
+ *
+ * This is provided to support the dynamically allocated memory
+ * used in cache-able region.
+ * @param size The length required to malloc.
+ * @param alignbytes The alignment size.
+ * @retval The allocated memory.
+ */
+ void *SDK_Malloc(size_t size, size_t alignbytes);
+
+ /*!
+ * @brief Free memory.
+ *
+ * @param ptr The memory to be release.
+ */
+ void SDK_Free(void *ptr);
+
+ /*!
+ * @brief Delay at least for some time.
+ * Please note that, this API uses while loop for delay, different run-time environments make the time not precise,
+ * if precise delay count was needed, please implement a new delay function with hardware timer.
+ *
+ * @param delay_us Delay time in unit of microsecond.
+ * @param coreClock_Hz Core clock frequency with Hz.
+ */
+ void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @} */
+
+#endif /* _FSL_COMMON_H_ */
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_emc.c b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_emc.c
new file mode 100644
index 000000000..57e9d4b7c
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_emc.c
@@ -0,0 +1,445 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_emc.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.emc"
+#endif
+
+/*! @brief Define macros for EMC driver. */
+#define EMC_REFRESH_CLOCK_PARAM (16U)
+#define EMC_SDRAM_WAIT_CYCLES (2000U)
+#define EMC_DYNCTL_COLUMNBASE_OFFSET (0U)
+#define EMC_DYNCTL_COLUMNBASE_MASK (0x3U)
+#define EMC_DYNCTL_COLUMNPLUS_OFFSET (3U)
+#define EMC_DYNCTL_COLUMNPLUS_MASK (0x18U)
+#define EMC_DYNCTL_BUSWIDTH_MASK (0x80U)
+#define EMC_DYNCTL_BUSADDRMAP_MASK (0x20U)
+#define EMC_DYNCTL_DEVBANKS_BITS_MASK (0x1cU)
+#define EMC_SDRAM_BANKCS_BA0_MASK (uint32_t)(0x2000)
+#define EMC_SDRAM_BANKCS_BA1_MASK (uint32_t)(0x4000)
+#define EMC_SDRAM_BANKCS_BA_MASK (EMC_SDRAM_BANKCS_BA0_MASK | EMC_SDRAM_BANKCS_BA1_MASK)
+#define EMC_DIV_ROUND_UP(n, m) (((n) + (m)-1U) / (m))
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Get instance number for EMC module.
+ *
+ * @param base EMC peripheral base address
+ */
+static uint32_t EMC_GetInstance(EMC_Type *base);
+
+/*!
+ * @brief Get the clock cycles of EMC clock.
+ * The function is used to calculate the multiple of the
+ * 16 EMCCLKs between the timer_Ns period.
+ *
+ * @param base EMC peripheral base address
+ * @param timer_Ns The timer/period in unit of nanosecond
+ * @param plus The plus added to the register settings to reach the calculated cycles.
+ * @return The calculated cycles.
+ */
+static uint32_t EMC_CalculateTimerCycles(EMC_Type *base, uint32_t timer_Ns, uint32_t plus);
+
+/*!
+ * @brief Get the shift value to shift the mode register content by.
+ *
+ * @param addrMap EMC address map for the dynamic memory configuration.
+ * It is the bit 14 ~ bit 7 of the EMC_DYNAMICCONFIG.
+ * @return The offset value to shift the mode register content by.
+ */
+static uint32_t EMC_ModeOffset(uint32_t addrMap);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to EMC clocks for each instance. */
+static const clock_ip_name_t s_EMCClock[FSL_FEATURE_SOC_EMC_COUNT] = EMC_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_EMC_HAS_NO_RESET) && FSL_FEATURE_EMC_HAS_NO_RESET)
+/*! @brief Pointers to EMC resets for each instance. */
+static const reset_ip_name_t s_emcResets[] = EMC_RSTS;
+#endif
+
+/*! @brief Pointers to EMC bases for each instance. */
+static const EMC_Type *const s_EMCBases[] = EMC_BASE_PTRS;
+
+/*! @brief Define the start address for each chip controlled by EMC. */
+static const uint32_t s_EMCDYCSBases[] = EMC_DYCS_ADDRESS;
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static uint32_t EMC_GetInstance(EMC_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_EMCBases); instance++)
+ {
+ if (s_EMCBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_EMCBases));
+
+ return instance;
+}
+
+static uint32_t EMC_CalculateTimerCycles(EMC_Type *base, uint32_t timer_Ns, uint32_t plus)
+{
+ uint32_t cycles;
+
+ cycles = CLOCK_GetEmcClkFreq() / EMC_HZ_ONEMHZ * timer_Ns;
+ cycles = EMC_DIV_ROUND_UP(cycles, EMC_MILLISECS_ONESEC); /* Round up. */
+
+ /* Decrese according to the plus. */
+ if (cycles >= plus)
+ {
+ cycles = cycles - plus;
+ }
+ else
+ {
+ cycles = 0;
+ }
+
+ return cycles;
+}
+
+static uint32_t EMC_ModeOffset(uint32_t addrMap)
+{
+ uint8_t offset = 0;
+ uint32_t columbase = addrMap & EMC_DYNCTL_COLUMNBASE_MASK;
+
+ /* First calculate the column length. */
+ if (columbase == 2U)
+ {
+ offset = 8;
+ }
+ else
+ {
+ if (0U == columbase)
+ {
+ offset = 9;
+ }
+ else
+ {
+ offset = 8;
+ }
+
+ /* Add column length increase check. */
+ offset += (uint8_t)((addrMap & EMC_DYNCTL_COLUMNPLUS_MASK) >> EMC_DYNCTL_COLUMNPLUS_OFFSET);
+ }
+
+ /* Add Buswidth/16. */
+ if (0U != (addrMap & EMC_DYNCTL_BUSWIDTH_MASK))
+ {
+ offset += 2U;
+ }
+ else
+ {
+ offset += 1U;
+ }
+
+ /* Add bank select bit if the sdram address map mode is RBC(row-bank-column) mode. */
+ if (0U == (addrMap & EMC_DYNCTL_BUSADDRMAP_MASK))
+ {
+ if (0U == (addrMap & EMC_DYNCTL_DEVBANKS_BITS_MASK))
+ {
+ offset += 1U;
+ }
+ else
+ {
+ offset += 2U;
+ }
+ }
+
+ return offset;
+}
+
+/*!
+ * brief Initializes the basic for EMC.
+ * This function ungates the EMC clock, initializes the emc system configure
+ * and enable the EMC module. This function must be called in the first step to initialize
+ * the external memory.
+ *
+ * param base EMC peripheral base address.
+ * param config The EMC basic configuration.
+ */
+void EMC_Init(EMC_Type *base, emc_basic_config_t *config)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Enable the clock. */
+ CLOCK_EnableClock((s_EMCClock[EMC_GetInstance(base)]));
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_EMC_HAS_NO_RESET) && FSL_FEATURE_EMC_HAS_NO_RESET)
+ /* Reset the EMC module */
+ RESET_PeripheralReset(s_emcResets[EMC_GetInstance(base)]);
+#endif
+
+ /* Reset the EMC. */
+ SYSCON->PRESETCTRL[2] |= SYSCON_PRESETCTRL_EMC_RESET_MASK;
+ SYSCON->PRESETCTRL[2] &= ~SYSCON_PRESETCTRL_EMC_RESET_MASK;
+
+ /* Set the EMC sytem configure. */
+ SYSCON->EMCCLKDIV = SYSCON_EMCCLKDIV_DIV(config->emcClkDiv);
+
+ SYSCON->EMCSYSCTRL = SYSCON_EMCSYSCTRL_EMCFBCLKINSEL(config->fbClkSrc);
+
+ /* Set the endian mode. */
+ base->CONFIG = (uint32_t)config->endian;
+ /* Enable the EMC module with normal memory map mode and normal work mode. */
+ base->CONTROL = EMC_CONTROL_E_MASK;
+}
+
+/*!
+ * brief Initializes the dynamic memory controller.
+ * This function initializes the dynamic memory controller in external memory controller.
+ * This function must be called after EMC_Init and before accessing the external dynamic memory.
+ *
+ * param base EMC peripheral base address.
+ * param timing The timing and latency for dynamica memory controller setting. It shall
+ * be used for all dynamica memory chips, threfore the worst timing value for all
+ * used chips must be given.
+ * param configure The EMC dynamic memory controller chip independent configuration pointer.
+ * This configuration pointer is actually pointer to a configration array. the array number
+ * depends on the "totalChips".
+ * param totalChips The total dynamic memory chip numbers been used or the length of the
+ * "emc_dynamic_chip_config_t" type memory.
+ */
+void EMC_DynamicMemInit(EMC_Type *base,
+ emc_dynamic_timing_config_t *timing,
+ emc_dynamic_chip_config_t *config,
+ uint32_t totalChips)
+{
+ assert(NULL != config);
+ assert(NULL != timing);
+ assert(totalChips <= EMC_DYNAMIC_MEMDEV_NUM);
+
+ uint32_t count;
+ uint32_t casLatency;
+ uint32_t addr;
+ uint32_t offset;
+ uint32_t data;
+ emc_dynamic_chip_config_t *dynamicConfig = config;
+
+ /* Setting for dynamic memory controller chip independent configuration. */
+ for (count = 0; (count < totalChips); count++)
+ {
+ if (NULL == dynamicConfig)
+ {
+ break;
+ }
+ else
+ {
+ base->DYNAMIC[dynamicConfig->chipIndex].DYNAMICCONFIG =
+ EMC_DYNAMIC_DYNAMICCONFIG_MD(dynamicConfig->dynamicDevice) | EMC_ADDRMAP(dynamicConfig->devAddrMap);
+ /* Abstract CAS latency from the sdram mode reigster setting values. */
+ casLatency = ((uint32_t)dynamicConfig->sdramModeReg & EMC_SDRAM_MODE_CL_MASK) >> EMC_SDRAM_MODE_CL_SHIFT;
+ base->DYNAMIC[dynamicConfig->chipIndex].DYNAMICRASCAS =
+ EMC_DYNAMIC_DYNAMICRASCAS_RAS(dynamicConfig->rAS_Nclk) | EMC_DYNAMIC_DYNAMICRASCAS_CAS(casLatency);
+
+ dynamicConfig++;
+ }
+ }
+
+ /* Configure the Dynamic Memory controller timing/latency for all chips. */
+ base->DYNAMICREADCONFIG = EMC_DYNAMICREADCONFIG_RD(timing->readConfig);
+ base->DYNAMICRP = EMC_CalculateTimerCycles(base, timing->tRp_Ns, 1) & EMC_DYNAMICRP_TRP_MASK;
+ base->DYNAMICRAS = EMC_CalculateTimerCycles(base, timing->tRas_Ns, 1) & EMC_DYNAMICRAS_TRAS_MASK;
+ base->DYNAMICSREX = EMC_CalculateTimerCycles(base, timing->tSrex_Ns, 1) & EMC_DYNAMICSREX_TSREX_MASK;
+ base->DYNAMICAPR = EMC_CalculateTimerCycles(base, timing->tApr_Ns, 1) & EMC_DYNAMICAPR_TAPR_MASK;
+ base->DYNAMICDAL = EMC_CalculateTimerCycles(base, timing->tDal_Ns, 0) & EMC_DYNAMICDAL_TDAL_MASK;
+ base->DYNAMICWR = EMC_CalculateTimerCycles(base, timing->tWr_Ns, 1) & EMC_DYNAMICWR_TWR_MASK;
+ base->DYNAMICRC = EMC_CalculateTimerCycles(base, timing->tRc_Ns, 1) & EMC_DYNAMICRC_TRC_MASK;
+ base->DYNAMICRFC = EMC_CalculateTimerCycles(base, timing->tRfc_Ns, 1) & EMC_DYNAMICRFC_TRFC_MASK;
+ base->DYNAMICXSR = EMC_CalculateTimerCycles(base, timing->tXsr_Ns, 1) & EMC_DYNAMICXSR_TXSR_MASK;
+ base->DYNAMICRRD = EMC_CalculateTimerCycles(base, timing->tRrd_Ns, 1) & EMC_DYNAMICRRD_TRRD_MASK;
+ base->DYNAMICMRD = EMC_DYNAMICMRD_TMRD((timing->tMrd_Nclk > 0U) ? timing->tMrd_Nclk - 1UL : 0UL);
+
+ SDK_DelayAtLeastUs(EMC_SDRAM_NOP_DELAY_US, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+ /* Step 2. issue nop command. */
+ base->DYNAMICCONTROL = 0x00000183;
+
+ SDK_DelayAtLeastUs(EMC_SDRAM_PRECHARGE_DELAY_US, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+ /* Step 3. issue precharge all command. */
+ base->DYNAMICCONTROL = 0x00000103;
+
+ /* Step 4. issue two auto-refresh command. */
+ base->DYNAMICREFRESH = 2;
+ SDK_DelayAtLeastUs(EMC_SDRAM_AUTO_REFRESH_DELAY_US, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
+
+ base->DYNAMICREFRESH = EMC_CalculateTimerCycles(base, timing->refreshPeriod_Nanosec, 0) / EMC_REFRESH_CLOCK_PARAM;
+
+ /* Step 5. issue a mode command and set the mode value. */
+ base->DYNAMICCONTROL = 0x00000083;
+
+ /* Calculate the mode settings here and to reach the 8 auto-refresh time requirement. */
+ dynamicConfig = config;
+ for (count = 0; (count < totalChips); count++)
+ {
+ if (NULL == dynamicConfig)
+ {
+ break;
+ }
+ else
+ {
+ /* Get the shift value first. */
+ offset = EMC_ModeOffset(dynamicConfig->devAddrMap);
+ addr = (s_EMCDYCSBases[dynamicConfig->chipIndex] |
+ ((uint32_t)(dynamicConfig->sdramModeReg & ~EMC_SDRAM_BANKCS_BA_MASK) << offset));
+ /* Set the right mode setting value. */
+ data = *(volatile uint32_t *)addr;
+ data = data;
+ dynamicConfig++;
+ }
+ }
+
+ if (kEMC_Sdram != config->dynamicDevice)
+ {
+ /* Add extended mode register if the low-power sdram is used. */
+ base->DYNAMICCONTROL = 0x00000083;
+ /* Calculate the mode settings for extended mode register. */
+ dynamicConfig = config;
+ for (count = 0; (count < totalChips); count++)
+ {
+ if (NULL == dynamicConfig)
+ {
+ break;
+ }
+ else
+ {
+ /* Get the shift value first. */
+ offset = EMC_ModeOffset(dynamicConfig->devAddrMap);
+ addr = (s_EMCDYCSBases[dynamicConfig->chipIndex] |
+ (((uint32_t)(dynamicConfig->sdramExtModeReg & ~EMC_SDRAM_BANKCS_BA_MASK) |
+ EMC_SDRAM_BANKCS_BA1_MASK)
+ << offset));
+ /* Set the right mode setting value. */
+ data = *(volatile uint32_t *)addr;
+ data = data;
+ dynamicConfig++;
+ }
+ }
+ }
+
+ /* Step 6. issue normal operation command. */
+ base->DYNAMICCONTROL = 0x00000000; /* Issue NORMAL command */
+
+ /* The buffer shall be disabled when do the sdram initialization and
+ * enabled after the initialization during normal opeation.
+ */
+ dynamicConfig = config;
+ for (count = 0; (count < totalChips); count++)
+ {
+ if (NULL == dynamicConfig)
+ {
+ break;
+ }
+ else
+ {
+ base->DYNAMIC[dynamicConfig->chipIndex].DYNAMICCONFIG |= EMC_DYNAMIC_DYNAMICCONFIG_B_MASK;
+ dynamicConfig++;
+ }
+ }
+}
+
+/*!
+ * brief Initializes the static memory controller.
+ * This function initializes the static memory controller in external memory controller.
+ * This function must be called after EMC_Init and before accessing the external static memory.
+ *
+ * param base EMC peripheral base address.
+ * param extWait_Ns The extended wait timeout or the read/write transfer time.
+ * This is common for all static memory chips and set with NULL if not required.
+ * param configure The EMC static memory controller chip independent configuration pointer.
+ * This configuration pointer is actually pointer to a configration array. the array number
+ * depends on the "totalChips".
+ * param totalChips The total static memory chip numbers been used or the length of the
+ * "emc_static_chip_config_t" type memory.
+ */
+void EMC_StaticMemInit(EMC_Type *base, uint32_t *extWait_Ns, emc_static_chip_config_t *config, uint32_t totalChips)
+{
+ assert(NULL != config);
+
+ uint32_t count;
+ emc_static_chip_config_t *staticConfig = config;
+
+ /* Initialize extended wait. */
+ if (NULL != extWait_Ns)
+ {
+ for (count = 0; (count < totalChips) && (staticConfig != NULL); count++)
+ {
+ assert(0U != (staticConfig->specailConfig & (uint32_t)kEMC_AsynchronosPageEnable));
+ }
+
+ base->STATICEXTENDEDWAIT = EMC_CalculateTimerCycles(base, *extWait_Ns, 1);
+ staticConfig++;
+ }
+
+ /* Initialize the static memory chip specific configure. */
+ staticConfig = config;
+ for (count = 0; (count < totalChips); count++)
+ {
+ if (NULL == staticConfig)
+ {
+ break;
+ }
+ else
+ {
+ base->STATIC[staticConfig->chipIndex].STATICCONFIG =
+ (staticConfig->specailConfig | (uint32_t)staticConfig->memWidth);
+ base->STATIC[staticConfig->chipIndex].STATICWAITWEN =
+ EMC_CalculateTimerCycles(base, staticConfig->tWaitWriteEn_Ns, 1);
+ base->STATIC[staticConfig->chipIndex].STATICWAITOEN =
+ EMC_CalculateTimerCycles(base, staticConfig->tWaitOutEn_Ns, 0);
+ base->STATIC[staticConfig->chipIndex].STATICWAITRD =
+ EMC_CalculateTimerCycles(base, staticConfig->tWaitReadNoPage_Ns, 1);
+ base->STATIC[staticConfig->chipIndex].STATICWAITPAGE =
+ EMC_CalculateTimerCycles(base, staticConfig->tWaitReadPage_Ns, 1);
+ base->STATIC[staticConfig->chipIndex].STATICWAITWR =
+ EMC_CalculateTimerCycles(base, staticConfig->tWaitWrite_Ns, 2);
+ base->STATIC[staticConfig->chipIndex].STATICWAITTURN =
+ EMC_CalculateTimerCycles(base, staticConfig->tWaitTurn_Ns, 1);
+
+ staticConfig++;
+ }
+ }
+}
+
+/*!
+ * brief Deinitializes the EMC module and gates the clock.
+ * This function gates the EMC controller clock. As a result, the EMC
+ * module doesn't work after calling this function.
+ *
+ * param base EMC peripheral base address.
+ */
+void EMC_Deinit(EMC_Type *base)
+{
+ /* Deinit the EMC. */
+ base->CONTROL &= ~EMC_CONTROL_E_MASK;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Disable the clock. */
+ CLOCK_DisableClock(s_EMCClock[EMC_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_emc.h b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_emc.h
new file mode 100644
index 000000000..082ac508e
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_emc.h
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_EMC_H_
+#define _FSL_EMC_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup emc
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief EMC driver version. */
+#define FSL_EMC_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
+/*@}*/
+
+/*! @brief Define the chip numbers for dynamic and static memory devices. */
+#define EMC_STATIC_MEMDEV_NUM (4U)
+#define EMC_DYNAMIC_MEMDEV_NUM (4U)
+#define EMC_ADDRMAP_SHIFT EMC_DYNAMIC_DYNAMICCONFIG_AM0_SHIFT
+#define EMC_ADDRMAP_MASK (EMC_DYNAMIC_DYNAMICCONFIG_AM0_MASK | EMC_DYNAMIC_DYNAMICCONFIG_AM1_MASK)
+#define EMC_ADDRMAP(x) (((uint32_t)(((uint32_t)(x)) << EMC_ADDRMAP_SHIFT)) & EMC_ADDRMAP_MASK)
+#define EMC_HZ_ONEMHZ (1000000U)
+#define EMC_MILLISECS_ONESEC (1000U)
+#define EMC_SDRAM_MODE_CL_SHIFT (4U)
+#define EMC_SDRAM_MODE_CL_MASK (0x70U)
+/*! @brief EDMA_SDRAM NOP command wait us */
+#ifndef EMC_SDRAM_NOP_DELAY_US
+#define EMC_SDRAM_NOP_DELAY_US (100U)
+#endif
+/*! @brief EDMA_SDRAM precharge command wait us */
+#ifndef EMC_SDRAM_PRECHARGE_DELAY_US
+#define EMC_SDRAM_PRECHARGE_DELAY_US (100U)
+#endif
+/*! @brief EDMA_SDRAM auto refresh wait us */
+#ifndef EMC_SDRAM_AUTO_REFRESH_DELAY_US
+#define EMC_SDRAM_AUTO_REFRESH_DELAY_US (50U)
+#endif
+/*!
+ * @brief Define EMC memory width for static memory device.
+ */
+typedef enum _emc_static_memwidth
+{
+ kEMC_8BitWidth = 0x0U, /*!< 8 bit memory width. */
+ kEMC_16BitWidth, /*!< 16 bit memory width. */
+ kEMC_32BitWidth /*!< 32 bit memory width. */
+} emc_static_memwidth_t;
+
+/*!
+ * @brief Define EMC static configuration.
+ */
+typedef enum _emc_static_special_config
+{
+ kEMC_AsynchronosPageEnable = 0x0008U, /*!< Enable the asynchronous page mode. page length four. */
+ kEMC_ActiveHighChipSelect = 0x0040U, /*!< Chip select active high. */
+ kEMC_ByteLaneStateAllLow = 0x0080U, /*!< Reads/writes the respective valuie bits in BLS3:0 are low. */
+ kEMC_ExtWaitEnable = 0x0100U, /*!< Extended wait enable. */
+ kEMC_BufferEnable = 0x80000U /*!< Buffer enable. */
+} emc_static_special_config_t;
+
+/*! @brief EMC dynamic memory device. */
+typedef enum _emc_dynamic_device
+{
+ kEMC_Sdram = 0x0U, /*!< Dynamic memory device: SDRAM. */
+ kEMC_Lpsdram, /*!< Dynamic memory device: Low-power SDRAM. */
+} emc_dynamic_device_t;
+
+/*! @brief EMC dynamic read strategy. */
+typedef enum _emc_dynamic_read
+{
+ kEMC_NoDelay = 0x0U, /*!< No delay. */
+ kEMC_Cmddelay, /*!< Command delayed strategy, using EMCCLKDELAY. */
+ kEMC_CmdDelayPulseOneclk, /*!< Command delayed strategy pluse one clock cycle using EMCCLKDELAY. */
+ kEMC_CmddelayPulsetwoclk, /*!< Command delayed strategy pulse two clock cycle using EMCCLKDELAY. */
+} emc_dynamic_read_t;
+
+/*! @brief EMC endian mode. */
+typedef enum _emc_endian_mode
+{
+ kEMC_LittleEndian = 0x0U, /*!< Little endian mode. */
+ kEMC_BigEndian, /*!< Big endian mode. */
+} emc_endian_mode_t;
+
+/*! @brief EMC Feedback clock input source select. */
+typedef enum _emc_fbclk_src
+{
+ kEMC_IntloopbackEmcclk = 0U, /*!< Use the internal loop back from EMC_CLK output. */
+ kEMC_EMCFbclkInput /*!< Use the external EMC_FBCLK input. */
+} emc_fbclk_src_t;
+
+/*! @brief EMC dynamic timing/delay configure structure. */
+typedef struct _emc_dynamic_timing_config
+{
+ emc_dynamic_read_t readConfig; /* Dynamic read strategy. */
+ uint32_t refreshPeriod_Nanosec; /*!< The refresh period in unit of nanosecond. */
+ uint32_t tRp_Ns; /*!< Precharge command period in unit of nanosecond. */
+ uint32_t tRas_Ns; /*!< Active to precharge command period in unit of nanosecond. */
+ uint32_t tSrex_Ns; /*!< Self-refresh exit time in unit of nanosecond. */
+ uint32_t tApr_Ns; /*!< Last data out to active command time in unit of nanosecond. */
+ uint32_t tDal_Ns; /*!< Data-in to active command in unit of nanosecond. */
+ uint32_t tWr_Ns; /*!< Write recovery time in unit of nanosecond. */
+ uint32_t tRc_Ns; /*!< Active to active command period in unit of nanosecond. */
+ uint32_t tRfc_Ns; /*!< Auto-refresh period and auto-refresh to active command period in unit of nanosecond. */
+ uint32_t tXsr_Ns; /*!< Exit self-refresh to active command time in unit of nanosecond. */
+ uint32_t tRrd_Ns; /*!< Active bank A to active bank B latency in unit of nanosecond. */
+ uint8_t tMrd_Nclk; /*!< Load mode register to active command time in unit of EMCCLK cycles.*/
+} emc_dynamic_timing_config_t;
+
+/*!
+ * @brief EMC dynamic memory controller independent chip configuration structure.
+ * Please take refer to the address mapping table in the RM in EMC chapter when you
+ * set the "devAddrMap". Choose the right Bit 14 Bit12 ~ Bit 7 group in the table
+ * according to the bus width/banks/row/colum length for you device.
+ * Set devAddrMap with the value make up with the seven bits (bit14 bit12 ~ bit 7)
+ * and inset the bit 13 with 0.
+ * for example, if the bit 14 and bit12 ~ bit7 is 1000001 is choosen according to the
+ * 32bit high-performance bus width with 2 banks, 11 row lwngth, 8 column length.
+ * Set devAddrMap with 0x81.
+ */
+typedef struct _emc_dynamic_chip_config
+{
+ uint8_t chipIndex; /*!< Chip Index, range from 0 ~ EMC_DYNAMIC_MEMDEV_NUM - 1. */
+ emc_dynamic_device_t
+ dynamicDevice; /*!< All chips shall use the same device setting. mixed use are not supported. */
+ uint8_t rAS_Nclk; /*!< Active to read/write delay tRCD. */
+ uint16_t sdramModeReg; /*!< Sdram mode register setting. */
+ uint16_t sdramExtModeReg; /*!< Used for low-power sdram device. The extended mode register. */
+ uint8_t devAddrMap; /*!< dynamic device address mapping, choose the address mapping for your specific device. */
+} emc_dynamic_chip_config_t;
+
+/*!
+ * @brief EMC static memory controller independent chip configuration structure.
+ */
+typedef struct _emc_static_chip_config
+{
+ uint8_t chipIndex;
+ emc_static_memwidth_t memWidth; /*!< Memory width. */
+ uint32_t specailConfig; /*!< Static configuration,a logical OR of "emc_static_special_config_t". */
+ uint32_t tWaitWriteEn_Ns; /*!< The delay form chip select to write enable in unit of nanosecond. */
+ uint32_t tWaitOutEn_Ns; /*!< The delay from chip selcet to output enable in unit of nanosecond. */
+ uint32_t
+ tWaitReadNoPage_Ns; /*!< In No-page mode, the delay from chip select to read access in unit of nanosecond. */
+ uint32_t tWaitReadPage_Ns; /*!< In page mode, the read after the first read wait states in unit of nanosecond. */
+ uint32_t tWaitWrite_Ns; /*!< The delay from chip select to write access in unit of nanosecond. */
+ uint32_t tWaitTurn_Ns; /*!< The Bus turn-around time in unit of nanosecond. */
+} emc_static_chip_config_t;
+
+/*!
+ * @brief EMC module basic configuration structure.
+ *
+ * Defines the static memory controller configure structure and
+ * uses the EMC_Init() function to make necessary initializations.
+ *
+ */
+typedef struct _emc_basic_config
+{
+ emc_endian_mode_t endian; /*!< Endian mode . */
+ emc_fbclk_src_t fbClkSrc; /*!< The feedback clock source. */
+ uint8_t emcClkDiv; /*!< EMC_CLK = AHB_CLK / (emc_clkDiv + 1). */
+} emc_basic_config_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @name EMC Initialize and de-initialize opeartion
+ * @{
+ */
+/*!
+ * @brief Initializes the basic for EMC.
+ * This function ungates the EMC clock, initializes the emc system configure
+ * and enable the EMC module. This function must be called in the first step to initialize
+ * the external memory.
+ *
+ * @param base EMC peripheral base address.
+ * @param config The EMC basic configuration.
+ */
+void EMC_Init(EMC_Type *base, emc_basic_config_t *config);
+
+/*!
+ * @brief Initializes the dynamic memory controller.
+ * This function initializes the dynamic memory controller in external memory controller.
+ * This function must be called after EMC_Init and before accessing the external dynamic memory.
+ *
+ * @param base EMC peripheral base address.
+ * @param timing The timing and latency for dynamica memory controller setting. It shall
+ * be used for all dynamica memory chips, threfore the worst timing value for all
+ * used chips must be given.
+ * @param configure The EMC dynamic memory controller chip independent configuration pointer.
+ * This configuration pointer is actually pointer to a configration array. the array number
+ * depends on the "totalChips".
+ * @param totalChips The total dynamic memory chip numbers been used or the length of the
+ * "emc_dynamic_chip_config_t" type memory.
+ */
+void EMC_DynamicMemInit(EMC_Type *base,
+ emc_dynamic_timing_config_t *timing,
+ emc_dynamic_chip_config_t *config,
+ uint32_t totalChips);
+
+/*!
+ * @brief Initializes the static memory controller.
+ * This function initializes the static memory controller in external memory controller.
+ * This function must be called after EMC_Init and before accessing the external static memory.
+ *
+ * @param base EMC peripheral base address.
+ * @param extWait_Ns The extended wait timeout or the read/write transfer time.
+ * This is common for all static memory chips and set with NULL if not required.
+ * @param configure The EMC static memory controller chip independent configuration pointer.
+ * This configuration pointer is actually pointer to a configration array. the array number
+ * depends on the "totalChips".
+ * @param totalChips The total static memory chip numbers been used or the length of the
+ * "emc_static_chip_config_t" type memory.
+ */
+void EMC_StaticMemInit(EMC_Type *base, uint32_t *extWait_Ns, emc_static_chip_config_t *config, uint32_t totalChips);
+
+/*!
+ * @brief Deinitializes the EMC module and gates the clock.
+ * This function gates the EMC controller clock. As a result, the EMC
+ * module doesn't work after calling this function.
+ *
+ * @param base EMC peripheral base address.
+ */
+void EMC_Deinit(EMC_Type *base);
+
+/* @} */
+
+/*!
+ * @name EMC Basic Operation
+ * @{
+ */
+
+/*!
+ * @brief Enables/disables the EMC module.
+ *
+ * @param base EMC peripheral base address.
+ * @param enable True enable EMC module, false disable.
+ */
+static inline void EMC_Enable(EMC_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->CONTROL |= EMC_CONTROL_E_MASK;
+ }
+ else
+ {
+ base->CONTROL &= ~EMC_CONTROL_E_MASK;
+ }
+}
+
+/*!
+ * @brief Enables/disables the EMC Dynaimc memory controller.
+ *
+ * @param base EMC peripheral base address.
+ * @param enable True enable EMC dynamic memory controller, false disable.
+ */
+static inline void EMC_EnableDynamicMemControl(EMC_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->DYNAMICCONTROL |= (EMC_DYNAMICCONTROL_CE_MASK | EMC_DYNAMICCONTROL_CS_MASK);
+ }
+ else
+ {
+ base->DYNAMICCONTROL &= ~(EMC_DYNAMICCONTROL_CE_MASK | EMC_DYNAMICCONTROL_CS_MASK);
+ }
+}
+
+/*!
+ * @brief Enables/disables the EMC address mirror.
+ * Enable the address mirror the EMC_CS1is mirrored to both EMC_CS0
+ * and EMC_DYCS0 memory areas. Disable the address mirror enables
+ * EMC_cS0 and EMC_DYCS0 memory to be accessed.
+ *
+ * @param base EMC peripheral base address.
+ * @param enable True enable the address mirror, false disable the address mirror.
+ */
+static inline void EMC_MirrorChipAddr(EMC_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->CONTROL |= EMC_CONTROL_M_MASK;
+ }
+ else
+ {
+ base->CONTROL &= ~EMC_CONTROL_M_MASK;
+ }
+}
+
+/*!
+ * @brief Enter the self-refresh mode for dynamic memory controller.
+ * This function provided self-refresh mode enter or exit for application.
+ *
+ * @param base EMC peripheral base address.
+ * @param enable True enter the self-refresh mode, false to exit self-refresh
+ * and enter the normal mode.
+ */
+static inline void EMC_EnterSelfRefreshCommand(EMC_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->DYNAMICCONTROL |= EMC_DYNAMICCONTROL_SR_MASK;
+ }
+ else
+ {
+ base->DYNAMICCONTROL &= ~EMC_DYNAMICCONTROL_SR_MASK;
+ }
+}
+
+/*!
+ * @brief Get the operating mode of the EMC.
+ * This function can be used to get the operating mode of the EMC.
+ *
+ * @param base EMC peripheral base address.
+ * @return The EMC in self-refresh mode if true, else in normal mode.
+ */
+static inline bool EMC_IsInSelfrefreshMode(EMC_Type *base)
+{
+ return (0U != (base->STATUS & EMC_STATUS_SA_MASK));
+}
+
+/*!
+ * @brief Enter/exit the low-power mode.
+ *
+ * @param base EMC peripheral base address.
+ * @param enable True Enter the low-power mode, false exit low-power mode
+ * and return to normal mode.
+ */
+static inline void EMC_EnterLowPowerMode(EMC_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->CONTROL |= EMC_CONTROL_L_MASK;
+ }
+ else
+ {
+ base->CONTROL &= ~EMC_CONTROL_L_MASK;
+ }
+}
+
+/* @} */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_EMC_H_*/
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c
new file mode 100644
index 000000000..28cfb38bd
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_flexcomm.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.flexcomm"
+#endif
+
+/*!
+ * @brief Used for conversion between `void*` and `uint32_t`.
+ */
+typedef union pvoid_to_u32
+{
+ void *pvoid;
+ uint32_t u32;
+} pvoid_to_u32_t;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*! @brief Set the FLEXCOMM mode . */
+static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock);
+
+/*! @brief check whether flexcomm supports peripheral type */
+static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */
+static flexcomm_irq_handler_t s_flexcommIrqHandler[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
+
+/*! @brief Pointers to handles for each instance to provide context to interrupt routines */
+static void *s_flexcommHandle[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
+
+/*! @brief Array to map FLEXCOMM instance number to IRQ number. */
+IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;
+
+/*! @brief Array to map FLEXCOMM instance number to base address. */
+static const uint32_t s_flexcommBaseAddrs[FSL_FEATURE_SOC_FLEXCOMM_COUNT] = FLEXCOMM_BASE_ADDRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief IDs of clock for each FLEXCOMM module */
+static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
+/*! @brief Pointers to FLEXCOMM resets for each instance. */
+static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS;
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/* check whether flexcomm supports peripheral type */
+static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph)
+{
+ if (periph == FLEXCOMM_PERIPH_NONE)
+ {
+ return true;
+ }
+ else if (periph <= FLEXCOMM_PERIPH_I2S_TX)
+ {
+ return (base->PSELID & (1UL << ((uint32_t)periph + 3U))) > 0UL ? true : false;
+ }
+ else if (periph == FLEXCOMM_PERIPH_I2S_RX)
+ {
+ return (base->PSELID & (1U << 7U)) > (uint32_t)0U ? true : false;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/* Get the index corresponding to the FLEXCOMM */
+/*! brief Returns instance number for FLEXCOMM module with given base address. */
+uint32_t FLEXCOMM_GetInstance(void *base)
+{
+ uint32_t i;
+ pvoid_to_u32_t BaseAddr;
+ BaseAddr.pvoid = base;
+
+ for (i = 0U; i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++)
+ {
+ if (BaseAddr.u32 == s_flexcommBaseAddrs[i])
+ {
+ break;
+ }
+ }
+
+ assert(i < FSL_FEATURE_SOC_FLEXCOMM_COUNT);
+ return i;
+}
+
+/* Changes FLEXCOMM mode */
+static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock)
+{
+ /* Check whether peripheral type is present */
+ if (!FLEXCOMM_PeripheralIsPresent(base, periph))
+ {
+ return kStatus_OutOfRange;
+ }
+
+ /* Flexcomm is locked to different peripheral type than expected */
+ if (((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) != 0U) &&
+ ((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != (uint32_t)periph))
+ {
+ return kStatus_Fail;
+ }
+
+ /* Check if we are asked to lock */
+ if (lock != 0)
+ {
+ base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK;
+ }
+ else
+ {
+ base->PSELID = (uint32_t)periph;
+ }
+
+ return kStatus_Success;
+}
+
+/*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
+status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph)
+{
+ uint32_t idx = FLEXCOMM_GetInstance(base);
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Enable the peripheral clock */
+ CLOCK_EnableClock(s_flexcommClocks[idx]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET)
+ /* Reset the FLEXCOMM module */
+ RESET_PeripheralReset(s_flexcommResets[idx]);
+#endif
+
+ /* Set the FLEXCOMM to given peripheral */
+ return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0);
+}
+
+/*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
+ * mode */
+void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle)
+{
+ uint32_t instance;
+
+ /* Look up instance number */
+ instance = FLEXCOMM_GetInstance(base);
+
+ /* Clear handler first to avoid execution of the handler with wrong handle */
+ s_flexcommIrqHandler[instance] = NULL;
+ s_flexcommHandle[instance] = handle;
+ s_flexcommIrqHandler[instance] = handler;
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+
+/* IRQ handler functions overloading weak symbols in the startup */
+#if defined(FLEXCOMM0)
+void FLEXCOMM0_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[0]);
+ s_flexcommIrqHandler[0]((uint32_t *)s_flexcommBaseAddrs[0], s_flexcommHandle[0]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM1)
+void FLEXCOMM1_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[1]);
+ s_flexcommIrqHandler[1]((uint32_t *)s_flexcommBaseAddrs[1], s_flexcommHandle[1]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM2)
+void FLEXCOMM2_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[2]);
+ s_flexcommIrqHandler[2]((uint32_t *)s_flexcommBaseAddrs[2], s_flexcommHandle[2]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM3)
+void FLEXCOMM3_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[3]);
+ s_flexcommIrqHandler[3]((uint32_t *)s_flexcommBaseAddrs[3], s_flexcommHandle[3]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM4)
+void FLEXCOMM4_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[4]);
+ s_flexcommIrqHandler[4]((uint32_t *)s_flexcommBaseAddrs[4], s_flexcommHandle[4]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+
+#endif
+
+#if defined(FLEXCOMM5)
+void FLEXCOMM5_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[5]);
+ s_flexcommIrqHandler[5]((uint32_t *)s_flexcommBaseAddrs[5], s_flexcommHandle[5]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM6)
+void FLEXCOMM6_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[6]);
+ s_flexcommIrqHandler[6]((uint32_t *)s_flexcommBaseAddrs[6], s_flexcommHandle[6]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM7)
+void FLEXCOMM7_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[7]);
+ s_flexcommIrqHandler[7]((uint32_t *)s_flexcommBaseAddrs[7], s_flexcommHandle[7]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM8)
+void FLEXCOMM8_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[8]);
+ s_flexcommIrqHandler[8]((uint32_t *)s_flexcommBaseAddrs[8], s_flexcommHandle[8]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM9)
+void FLEXCOMM9_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[9]);
+ s_flexcommIrqHandler[9]((uint32_t *)s_flexcommBaseAddrs[9], s_flexcommHandle[9]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM10)
+void FLEXCOMM10_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[10]);
+ s_flexcommIrqHandler[10]((uint32_t *)s_flexcommBaseAddrs[10], s_flexcommHandle[10]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM11)
+void FLEXCOMM11_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[11]);
+ s_flexcommIrqHandler[11]((uint32_t *)s_flexcommBaseAddrs[11], s_flexcommHandle[11]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM12)
+void FLEXCOMM12_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[12]);
+ s_flexcommIrqHandler[12]((uint32_t *)s_flexcommBaseAddrs[12], s_flexcommHandle[12]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM13)
+void FLEXCOMM13_DriverIRQHandler(void)
+{
+ assert(s_flexcommIrqHandler[13]);
+ s_flexcommIrqHandler[13]((uint32_t *)s_flexcommBaseAddrs[13], s_flexcommHandle[13]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM14)
+void FLEXCOMM14_DriverIRQHandler(void)
+{
+ uint32_t instance;
+
+ /* Look up instance number */
+ instance = FLEXCOMM_GetInstance(FLEXCOMM14);
+ assert(s_flexcommIrqHandler[instance]);
+ s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM15)
+void FLEXCOMM15_DriverIRQHandler(void)
+{
+ uint32_t instance;
+
+ /* Look up instance number */
+ instance = FLEXCOMM_GetInstance(FLEXCOMM15);
+ assert(s_flexcommIrqHandler[instance]);
+ s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+
+#if defined(FLEXCOMM16)
+void FLEXCOMM16_DriverIRQHandler(void)
+{
+ uint32_t instance;
+
+ /* Look up instance number */
+ instance = FLEXCOMM_GetInstance(FLEXCOMM16);
+ assert(s_flexcommIrqHandler[instance]);
+ s_flexcommIrqHandler[instance]((void *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
+/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
+ exception return operation might vector to incorrect interrupt */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.h b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.h
new file mode 100644
index 000000000..6fa82b415
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_FLEXCOMM_H_
+#define _FSL_FLEXCOMM_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup flexcomm_driver
+ * @{
+ */
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief FlexCOMM driver version 2.0.2. */
+#define FSL_FLEXCOMM_DRIVER_VERSION (MAKE_VERSION(2, 0, 2))
+/*@}*/
+
+/*! @brief FLEXCOMM peripheral modes. */
+typedef enum
+{
+ FLEXCOMM_PERIPH_NONE, /*!< No peripheral */
+ FLEXCOMM_PERIPH_USART, /*!< USART peripheral */
+ FLEXCOMM_PERIPH_SPI, /*!< SPI Peripheral */
+ FLEXCOMM_PERIPH_I2C, /*!< I2C Peripheral */
+ FLEXCOMM_PERIPH_I2S_TX, /*!< I2S TX Peripheral */
+ FLEXCOMM_PERIPH_I2S_RX, /*!< I2S RX Peripheral */
+} FLEXCOMM_PERIPH_T;
+
+/*! @brief Typedef for interrupt handler. */
+typedef void (*flexcomm_irq_handler_t)(void *base, void *handle);
+
+/*! @brief Array with IRQ number for each FLEXCOMM module. */
+extern IRQn_Type const kFlexcommIrqs[];
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*! @brief Returns instance number for FLEXCOMM module with given base address. */
+uint32_t FLEXCOMM_GetInstance(void *base);
+
+/*! @brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */
+status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph);
+
+/*! @brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM
+ * mode */
+void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *handle);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*@}*/
+
+#endif /* _FSL_FLEXCOMM_H_*/
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_gpio.c b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_gpio.c
new file mode 100644
index 000000000..ed74b465e
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_gpio.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_gpio.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.lpc_gpio"
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Array to map FGPIO instance number to clock name. */
+static const clock_ip_name_t s_gpioClockName[] = GPIO_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
+/*! @brief Pointers to GPIO resets for each instance. */
+static const reset_ip_name_t s_gpioResets[] = GPIO_RSTS_N;
+#endif
+/*******************************************************************************
+ * Prototypes
+ ************ ******************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+/*!
+ * brief Initializes the GPIO peripheral.
+ *
+ * This function ungates the GPIO clock.
+ *
+ * param base GPIO peripheral base pointer.
+ * param port GPIO port number.
+ */
+void GPIO_PortInit(GPIO_Type *base, uint32_t port)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ assert(port < ARRAY_SIZE(s_gpioClockName));
+
+ /* Upgate the GPIO clock */
+ CLOCK_EnableClock(s_gpioClockName[port]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+#if !(defined(FSL_FEATURE_GPIO_HAS_NO_RESET) && FSL_FEATURE_GPIO_HAS_NO_RESET)
+ /* Reset the GPIO module */
+ RESET_PeripheralReset(s_gpioResets[port]);
+#endif
+}
+
+/*!
+ * 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.
+ * Then, call the GPIO_PinInit() function.
+ *
+ * This is an example to define an input pin or output pin configuration:
+ * code
+ * Define a digital input pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ * kGPIO_DigitalInput,
+ * 0,
+ * }
+ * Define a digital output pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ * kGPIO_DigitalOutput,
+ * 0,
+ * }
+ * endcode
+ *
+ * param base GPIO peripheral base pointer(Typically GPIO)
+ * param port GPIO port number
+ * param pin GPIO pin number
+ * param config GPIO pin configuration pointer
+ */
+void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config)
+{
+ if (config->pinDirection == kGPIO_DigitalInput)
+ {
+#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
+ base->DIRCLR[port] = 1UL << pin;
+#else
+ base->DIR[port] &= ~(1UL << pin);
+#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
+ }
+ else
+ {
+ /* Set default output value */
+ if (config->outputLogic == 0U)
+ {
+ base->CLR[port] = (1UL << pin);
+ }
+ else
+ {
+ base->SET[port] = (1UL << pin);
+ }
+/* Set pin direction */
+#if defined(FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR) && (FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR)
+ base->DIRSET[port] = 1UL << pin;
+#else
+ base->DIR[port] |= 1UL << pin;
+#endif /*FSL_FEATURE_GPIO_DIRSET_AND_DIRCLR*/
+ }
+}
+
+#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
+/*!
+ * @brief Configures the gpio pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param pin GPIO pin number.
+ * @param config GPIO pin interrupt configuration..
+ */
+void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config)
+{
+ base->INTEDG[port] = base->INTEDG[port] | ((uint32_t)config->mode << pin);
+
+ base->INTPOL[port] = base->INTPOL[port] | ((uint32_t)config->polarity << pin);
+}
+
+/*!
+ * @brief Enables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
+{
+ if ((uint32_t)kGPIO_InterruptA == index)
+ {
+ base->INTENA[port] = base->INTENA[port] | mask;
+ }
+ else if ((uint32_t)kGPIO_InterruptB == index)
+ {
+ base->INTENB[port] = base->INTENB[port] | mask;
+ }
+ else
+ {
+ /*Should not enter here*/
+ }
+}
+
+/*!
+ * @brief Disables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
+{
+ if ((uint32_t)kGPIO_InterruptA == index)
+ {
+ base->INTENA[port] = base->INTENA[port] & ~mask;
+ }
+ else if ((uint32_t)kGPIO_InterruptB == index)
+ {
+ base->INTENB[port] = base->INTENB[port] & ~mask;
+ }
+ else
+ {
+ /*Should not enter here*/
+ }
+}
+
+/*!
+ * @brief Clears multiple pins interrupt flag. Status flags are cleared by
+ * writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask)
+{
+ if ((uint32_t)kGPIO_InterruptA == index)
+ {
+ base->INTSTATA[port] = mask;
+ }
+ else if ((uint32_t)kGPIO_InterruptB == index)
+ {
+ base->INTSTATB[port] = mask;
+ }
+ else
+ {
+ /*Should not enter here*/
+ }
+}
+
+/*!
+ * @ Read port interrupt status.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param index GPIO interrupt number.
+ * @retval masked GPIO status value
+ */
+uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index)
+{
+ uint32_t status = 0U;
+
+ if ((uint32_t)kGPIO_InterruptA == index)
+ {
+ status = base->INTSTATA[port];
+ }
+ else if ((uint32_t)kGPIO_InterruptB == index)
+ {
+ status = base->INTSTATB[port];
+ }
+ else
+ {
+ /*Should not enter here*/
+ }
+ return status;
+}
+
+/*!
+ * @brief Enables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
+{
+ if ((uint32_t)kGPIO_InterruptA == index)
+ {
+ base->INTENA[port] = base->INTENA[port] | (1UL << pin);
+ }
+ else if ((uint32_t)kGPIO_InterruptB == index)
+ {
+ base->INTENB[port] = base->INTENB[port] | (1UL << pin);
+ }
+ else
+ {
+ /*Should not enter here*/
+ }
+}
+
+/*!
+ * @brief Disables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
+{
+ if ((uint32_t)kGPIO_InterruptA == index)
+ {
+ base->INTENA[port] = base->INTENA[port] & ~(1UL << pin);
+ }
+ else if ((uint32_t)kGPIO_InterruptB == index)
+ {
+ base->INTENB[port] = base->INTENB[port] & ~(1UL << pin);
+ }
+ else
+ {
+ /*Should not enter here*/
+ }
+}
+
+/*!
+ * @brief Clears the specific pin interrupt flag. Status flags are cleared by
+ * writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index)
+{
+ if ((uint32_t)kGPIO_InterruptA == index)
+ {
+ base->INTSTATA[port] = 1UL << pin;
+ }
+ else if ((uint32_t)kGPIO_InterruptB == index)
+ {
+ base->INTSTATB[port] = 1UL << pin;
+ }
+ else
+ {
+ /*Should not enter here*/
+ }
+}
+#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_gpio.h b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_gpio.h
new file mode 100644
index 000000000..39dd2f488
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_gpio.h
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _LPC_GPIO_H_
+#define _LPC_GPIO_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup lpc_gpio
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief LPC GPIO driver version. */
+#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 5))
+/*@}*/
+
+/*! @brief LPC GPIO direction definition */
+typedef enum _gpio_pin_direction
+{
+ kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/
+ kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/
+} gpio_pin_direction_t;
+
+/*!
+ * @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.
+ */
+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_config_t;
+
+#if (defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT)
+#define GPIO_PIN_INT_LEVEL 0x00U
+#define GPIO_PIN_INT_EDGE 0x01U
+
+#define PINT_PIN_INT_HIGH_OR_RISE_TRIGGER 0x00U
+#define PINT_PIN_INT_LOW_OR_FALL_TRIGGER 0x01U
+
+/*! @brief GPIO Pin Interrupt enable mode */
+typedef enum _gpio_pin_enable_mode
+{
+ kGPIO_PinIntEnableLevel = GPIO_PIN_INT_LEVEL, /*!< Generate Pin Interrupt on level mode */
+ kGPIO_PinIntEnableEdge = GPIO_PIN_INT_EDGE /*!< Generate Pin Interrupt on edge mode */
+} gpio_pin_enable_mode_t;
+
+/*! @brief GPIO Pin Interrupt enable polarity */
+typedef enum _gpio_pin_enable_polarity
+{
+ kGPIO_PinIntEnableHighOrRise =
+ PINT_PIN_INT_HIGH_OR_RISE_TRIGGER, /*!< Generate Pin Interrupt on high level or rising edge */
+ kGPIO_PinIntEnableLowOrFall =
+ PINT_PIN_INT_LOW_OR_FALL_TRIGGER /*!< Generate Pin Interrupt on low level or falling edge */
+} gpio_pin_enable_polarity_t;
+
+/*! @brief LPC GPIO interrupt index definition */
+typedef enum _gpio_interrupt_index
+{
+ kGPIO_InterruptA = 0U, /*!< Set current pin as interrupt A*/
+ kGPIO_InterruptB = 1U, /*!< Set current pin as interrupt B*/
+} gpio_interrupt_index_t;
+
+/*! @brief Configures the interrupt generation condition. */
+typedef struct _gpio_interrupt_config
+{
+ uint8_t mode; /* The trigger mode of GPIO interrupts */
+ uint8_t polarity; /* The polarity of GPIO interrupts */
+} gpio_interrupt_config_t;
+#endif
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*! @name GPIO Configuration */
+/*@{*/
+
+/*!
+ * @brief Initializes the GPIO peripheral.
+ *
+ * This function ungates the GPIO clock.
+ *
+ * @param base GPIO peripheral base pointer.
+ * @param port GPIO port number.
+ */
+void GPIO_PortInit(GPIO_Type *base, uint32_t port);
+
+/*!
+ * @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.
+ * Then, call the GPIO_PinInit() function.
+ *
+ * This is an example to define an input pin or output pin configuration:
+ * @code
+ * Define a digital input pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ * kGPIO_DigitalInput,
+ * 0,
+ * }
+ * Define a digital output pin configuration,
+ * gpio_pin_config_t config =
+ * {
+ * kGPIO_DigitalOutput,
+ * 0,
+ * }
+ * @endcode
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param pin GPIO pin number
+ * @param config GPIO pin configuration pointer
+ */
+void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config);
+
+/*@}*/
+
+/*! @name GPIO Output Operations */
+/*@{*/
+
+/*!
+ * @brief Sets the output level of the one GPIO pin to the logic 1 or 0.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port 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.
+ */
+static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t port, uint32_t pin, uint8_t output)
+{
+ base->B[port][pin] = output;
+}
+
+/*@}*/
+/*! @name GPIO Input Operations */
+/*@{*/
+
+/*!
+ * @brief Reads the current input value of the GPIO PIN.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port 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.
+ */
+static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t port, uint32_t pin)
+{
+ return (uint32_t)base->B[port][pin];
+}
+
+/*@}*/
+
+/*!
+ * @brief Sets the output level of the multiple GPIO pins to the logic 1.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortSet(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+ base->SET[port] = mask;
+}
+
+/*!
+ * @brief Sets the output level of the multiple GPIO pins to the logic 0.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortClear(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+ base->CLR[port] = mask;
+}
+
+/*!
+ * @brief Reverses current output logic of the multiple GPIO pins.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+ base->NOT[port] = mask;
+}
+
+/*@}*/
+
+/*!
+ * @brief Reads the current input value of the whole GPIO port.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ */
+static inline uint32_t GPIO_PortRead(GPIO_Type *base, uint32_t port)
+{
+ return (uint32_t)base->PIN[port];
+}
+
+/*@}*/
+/*! @name GPIO Mask Operations */
+/*@{*/
+
+/*!
+ * @brief Sets port mask, 0 - enable pin, 1 - disable pin.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param mask GPIO pin number macro
+ */
+static inline void GPIO_PortMaskedSet(GPIO_Type *base, uint32_t port, uint32_t mask)
+{
+ base->MASK[port] = mask;
+}
+
+/*!
+ * @brief Sets the output level of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be affected.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @param output GPIO port output value.
+ */
+static inline void GPIO_PortMaskedWrite(GPIO_Type *base, uint32_t port, uint32_t output)
+{
+ base->MPIN[port] = output;
+}
+
+/*!
+ * @brief Reads the current input value of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be
+ * affected.
+ *
+ * @param base GPIO peripheral base pointer(Typically GPIO)
+ * @param port GPIO port number
+ * @retval masked GPIO port value
+ */
+static inline uint32_t GPIO_PortMaskedRead(GPIO_Type *base, uint32_t port)
+{
+ return (uint32_t)base->MPIN[port];
+}
+
+#if defined(FSL_FEATURE_GPIO_HAS_INTERRUPT) && FSL_FEATURE_GPIO_HAS_INTERRUPT
+/*!
+ * @brief Configures the gpio pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param pin GPIO pin number.
+ * @param config GPIO pin interrupt configuration..
+ */
+void GPIO_SetPinInterruptConfig(GPIO_Type *base, uint32_t port, uint32_t pin, gpio_interrupt_config_t *config);
+
+/*!
+ * @brief Enables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortEnableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
+
+/*!
+ * @brief Disables multiple pins interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortDisableInterrupts(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
+
+/*!
+ * @brief Clears pin interrupt flag. Status flags are cleared by
+ * writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param index GPIO interrupt number.
+ * @param mask GPIO pin number macro.
+ */
+void GPIO_PortClearInterruptFlags(GPIO_Type *base, uint32_t port, uint32_t index, uint32_t mask);
+
+/*!
+ * @ Read port interrupt status.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number
+ * @param index GPIO interrupt number.
+ * @retval masked GPIO status value
+ */
+uint32_t GPIO_PortGetInterruptStatus(GPIO_Type *base, uint32_t port, uint32_t index);
+
+/*!
+ * @brief Enables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinEnableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
+
+/*!
+ * @brief Disables the specific pin interrupt.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinDisableInterrupt(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
+
+/*!
+ * @brief Clears the specific pin interrupt flag. Status flags are cleared by
+ * writing a 1 to the corresponding bit position.
+ *
+ * @param base GPIO base pointer.
+ * @param port GPIO port number.
+ * @param pin GPIO pin number.
+ * @param index GPIO interrupt number.
+ */
+void GPIO_PinClearInterruptFlag(GPIO_Type *base, uint32_t port, uint32_t pin, uint32_t index);
+
+#endif /* FSL_FEATURE_GPIO_HAS_INTERRUPT */
+
+/*@}*/
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*!
+ * @}
+ */
+
+#endif /* _LPC_GPIO_H_*/
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_iocon.h b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_iocon.h
new file mode 100644
index 000000000..0386ecb4f
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_iocon.h
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_IOCON_H_
+#define _FSL_IOCON_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup lpc_iocon
+ * @{
+ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.lpc_iocon"
+#endif
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief IOCON driver version 2.1.1. */
+#define FSL_IOCON_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
+/*@}*/
+
+/**
+ * @brief Array of IOCON pin definitions passed to IOCON_SetPinMuxing() must be in this format
+ */
+typedef struct _iocon_group
+{
+ uint32_t port : 8; /* Pin port */
+ uint32_t pin : 8; /* Pin number */
+ uint32_t ionumber : 8; /* IO number */
+ uint32_t modefunc : 16; /* Function and mode */
+} iocon_group_t;
+
+/**
+ * @brief IOCON function and mode selection definitions
+ * @note See the User Manual for specific modes and functions supported by the various pins.
+ */
+#if defined(FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH) && (FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH == 4)
+#define IOCON_FUNC0 0x0 /*!< Selects pin function 0 */
+#define IOCON_FUNC1 0x1 /*!< Selects pin function 1 */
+#define IOCON_FUNC2 0x2 /*!< Selects pin function 2 */
+#define IOCON_FUNC3 0x3 /*!< Selects pin function 3 */
+#define IOCON_FUNC4 0x4 /*!< Selects pin function 4 */
+#define IOCON_FUNC5 0x5 /*!< Selects pin function 5 */
+#define IOCON_FUNC6 0x6 /*!< Selects pin function 6 */
+#define IOCON_FUNC7 0x7 /*!< Selects pin function 7 */
+#define IOCON_FUNC8 0x8 /*!< Selects pin function 8 */
+#define IOCON_FUNC9 0x9 /*!< Selects pin function 9 */
+#define IOCON_FUNC10 0xA /*!< Selects pin function 10 */
+#define IOCON_FUNC11 0xB /*!< Selects pin function 11 */
+#define IOCON_FUNC12 0xC /*!< Selects pin function 12 */
+#define IOCON_FUNC13 0xD /*!< Selects pin function 13 */
+#define IOCON_FUNC14 0xE /*!< Selects pin function 14 */
+#define IOCON_FUNC15 0xF /*!< Selects pin function 15 */
+#if defined(IOCON_PIO_MODE_SHIFT)
+#define IOCON_MODE_INACT (0x0 << IOCON_PIO_MODE_SHIFT) /*!< No addition pin function */
+#define IOCON_MODE_PULLDOWN (0x1 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-down function */
+#define IOCON_MODE_PULLUP (0x2 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-up function */
+#define IOCON_MODE_REPEATER (0x3 << IOCON_PIO_MODE_SHIFT) /*!< Selects pin repeater function */
+#endif
+
+#if defined(IOCON_PIO_I2CSLEW_SHIFT)
+#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_I2CSLEW_SHIFT) /*!< GPIO Mode */
+#define IOCON_I2C_SLEW (0x0 << IOCON_PIO_I2CSLEW_SHIFT) /*!< I2C Slew Rate Control */
+#endif
+
+#if defined(IOCON_PIO_EGP_SHIFT)
+#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_EGP_SHIFT) /*!< GPIO Mode */
+#define IOCON_I2C_SLEW (0x0 << IOCON_PIO_EGP_SHIFT) /*!< I2C Slew Rate Control */
+#endif
+
+#if defined(IOCON_PIO_SLEW_SHIFT)
+#define IOCON_SLEW_STANDARD (0x0 << IOCON_PIO_SLEW_SHIFT) /*!< Driver Slew Rate Control */
+#define IOCON_SLEW_FAST (0x1 << IOCON_PIO_SLEW_SHIFT) /*!< Driver Slew Rate Control */
+#endif
+
+#if defined(IOCON_PIO_INVERT_SHIFT)
+#define IOCON_INV_EN (0x1 << IOCON_PIO_INVERT_SHIFT) /*!< Enables invert function on input */
+#endif
+
+#if defined(IOCON_PIO_DIGIMODE_SHIFT)
+#define IOCON_ANALOG_EN (0x0 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables analog function by setting 0 to bit 7 */
+#define IOCON_DIGITAL_EN \
+ (0x1 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables digital function by setting 1 to bit 7(default) */
+#endif
+
+#if defined(IOCON_PIO_FILTEROFF_SHIFT)
+#define IOCON_INPFILT_OFF (0x1 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter Off for GPIO pins */
+#define IOCON_INPFILT_ON (0x0 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter On for GPIO pins */
+#endif
+
+#if defined(IOCON_PIO_I2CDRIVE_SHIFT)
+#define IOCON_I2C_LOWDRIVER (0x0 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< Low drive, Output drive sink is 4 mA */
+#define IOCON_I2C_HIGHDRIVER (0x1 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< High drive, Output drive sink is 20 mA */
+#endif
+
+#if defined(IOCON_PIO_OD_SHIFT)
+#define IOCON_OPENDRAIN_EN (0x1 << IOCON_PIO_OD_SHIFT) /*!< Enables open-drain function */
+#endif
+
+#if defined(IOCON_PIO_I2CFILTER_SHIFT)
+#define IOCON_I2CFILTER_OFF (0x1 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter enabled */
+#define IOCON_I2CFILTER_ON (0x0 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter not enabled, */
+#endif
+
+#if defined(IOCON_PIO_ASW_SHIFT)
+#define IOCON_AWS_EN (0x1 << IOCON_PIO_ASW_SHIFT) /*!< Enables analog switch function */
+#endif
+
+#if defined(IOCON_PIO_SSEL_SHIFT)
+#define IOCON_SSEL_3V3 (0x0 << IOCON_PIO_SSEL_SHIFT) /*!< 3V3 signaling in I2C mode */
+#define IOCON_SSEL_1V8 (0x1 << IOCON_PIO_SSEL_SHIFT) /*!< 1V8 signaling in I2C mode */
+#endif
+
+#if defined(IOCON_PIO_ECS_SHIFT)
+#define IOCON_ECS_OFF (0x0 << IOCON_PIO_ECS_SHIFT) /*!< IO is an open drain cell */
+#define IOCON_ECS_ON (0x1 << IOCON_PIO_ECS_SHIFT) /*!< Pull-up resistor is connected */
+#endif
+
+#if defined(IOCON_PIO_S_MODE_SHIFT)
+#define IOCON_S_MODE_0CLK (0x0 << IOCON_PIO_S_MODE_SHIFT) /*!< Bypass input filter */
+#define IOCON_S_MODE_1CLK \
+ (0x1 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 1 filter clock are rejected \ \ \ \ \
+ */
+#define IOCON_S_MODE_2CLK \
+ (0x2 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 2 filter clock2 are rejected \ \ \ \ \
+ */
+#define IOCON_S_MODE_3CLK \
+ (0x3 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 3 filter clock2 are rejected \ \ \ \ \
+ */
+#define IOCON_S_MODE(clks) ((clks) << IOCON_PIO_S_MODE_SHIFT) /*!< Select clocks for digital input filter mode */
+#endif
+
+#if defined(IOCON_PIO_CLK_DIV_SHIFT)
+#define IOCON_CLKDIV(div) \
+ ((div) \
+ << IOCON_PIO_CLK_DIV_SHIFT) /*!< Select peripheral clock divider for input filter sampling clock, 2^n, n=0-6 */
+#endif
+
+#else
+#define IOCON_FUNC0 0x0 /*!< Selects pin function 0 */
+#define IOCON_FUNC1 0x1 /*!< Selects pin function 1 */
+#define IOCON_FUNC2 0x2 /*!< Selects pin function 2 */
+#define IOCON_FUNC3 0x3 /*!< Selects pin function 3 */
+#define IOCON_FUNC4 0x4 /*!< Selects pin function 4 */
+#define IOCON_FUNC5 0x5 /*!< Selects pin function 5 */
+#define IOCON_FUNC6 0x6 /*!< Selects pin function 6 */
+#define IOCON_FUNC7 0x7 /*!< Selects pin function 7 */
+
+#if defined(IOCON_PIO_MODE_SHIFT)
+#define IOCON_MODE_INACT (0x0 << IOCON_PIO_MODE_SHIFT) /*!< No addition pin function */
+#define IOCON_MODE_PULLDOWN (0x1 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-down function */
+#define IOCON_MODE_PULLUP (0x2 << IOCON_PIO_MODE_SHIFT) /*!< Selects pull-up function */
+#define IOCON_MODE_REPEATER (0x3 << IOCON_PIO_MODE_SHIFT) /*!< Selects pin repeater function */
+#endif
+
+#if defined(IOCON_PIO_I2CSLEW_SHIFT)
+#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_I2CSLEW_SHIFT) /*!< GPIO Mode */
+#define IOCON_I2C_SLEW (0x0 << IOCON_PIO_I2CSLEW_SHIFT) /*!< I2C Slew Rate Control */
+#endif
+
+#if defined(IOCON_PIO_EGP_SHIFT)
+#define IOCON_GPIO_MODE (0x1 << IOCON_PIO_EGP_SHIFT) /*!< GPIO Mode */
+#define IOCON_I2C_SLEW (0x0 << IOCON_PIO_EGP_SHIFT) /*!< I2C Slew Rate Control */
+#endif
+
+#if defined(IOCON_PIO_INVERT_SHIFT)
+#define IOCON_INV_EN (0x1 << IOCON_PIO_INVERT_SHIFT) /*!< Enables invert function on input */
+#endif
+
+#if defined(IOCON_PIO_DIGIMODE_SHIFT)
+#define IOCON_ANALOG_EN (0x0 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables analog function by setting 0 to bit 7 */
+#define IOCON_DIGITAL_EN \
+ (0x1 << IOCON_PIO_DIGIMODE_SHIFT) /*!< Enables digital function by setting 1 to bit 7(default) */
+#endif
+
+#if defined(IOCON_PIO_FILTEROFF_SHIFT)
+#define IOCON_INPFILT_OFF (0x1 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter Off for GPIO pins */
+#define IOCON_INPFILT_ON (0x0 << IOCON_PIO_FILTEROFF_SHIFT) /*!< Input filter On for GPIO pins */
+#endif
+
+#if defined(IOCON_PIO_I2CDRIVE_SHIFT)
+#define IOCON_I2C_LOWDRIVER (0x0 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< Low drive, Output drive sink is 4 mA */
+#define IOCON_I2C_HIGHDRIVER (0x1 << IOCON_PIO_I2CDRIVE_SHIFT) /*!< High drive, Output drive sink is 20 mA */
+#endif
+
+#if defined(IOCON_PIO_OD_SHIFT)
+#define IOCON_OPENDRAIN_EN (0x1 << IOCON_PIO_OD_SHIFT) /*!< Enables open-drain function */
+#endif
+
+#if defined(IOCON_PIO_I2CFILTER_SHIFT)
+#define IOCON_I2CFILTER_OFF (0x1 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter enabled */
+#define IOCON_I2CFILTER_ON (0x0 << IOCON_PIO_I2CFILTER_SHIFT) /*!< I2C 50 ns glitch filter not enabled */
+#endif
+
+#if defined(IOCON_PIO_S_MODE_SHIFT)
+#define IOCON_S_MODE_0CLK (0x0 << IOCON_PIO_S_MODE_SHIFT) /*!< Bypass input filter */
+#define IOCON_S_MODE_1CLK \
+ (0x1 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 1 filter clock are rejected \ \ \ \ \
+ */
+#define IOCON_S_MODE_2CLK \
+ (0x2 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 2 filter clock2 are rejected \ \ \ \ \
+ */
+#define IOCON_S_MODE_3CLK \
+ (0x3 << IOCON_PIO_S_MODE_SHIFT) /*!< Input pulses shorter than 3 filter clock2 are rejected \ \ \ \ \
+ */
+#define IOCON_S_MODE(clks) ((clks) << IOCON_PIO_S_MODE_SHIFT) /*!< Select clocks for digital input filter mode */
+#endif
+
+#if defined(IOCON_PIO_CLK_DIV_SHIFT)
+#define IOCON_CLKDIV(div) \
+ ((div) \
+ << IOCON_PIO_CLK_DIV_SHIFT) /*!< Select peripheral clock divider for input filter sampling clock, 2^n, n=0-6 */
+#endif
+
+#endif
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if (defined(FSL_FEATURE_IOCON_ONE_DIMENSION) && (FSL_FEATURE_IOCON_ONE_DIMENSION == 1))
+/**
+ * @brief Sets I/O Control pin mux
+ * @param base : The base of IOCON peripheral on the chip
+ * @param ionumber : GPIO number to mux
+ * @param modefunc : OR'ed values of type IOCON_*
+ * @return Nothing
+ */
+__STATIC_INLINE void IOCON_PinMuxSet(IOCON_Type *base, uint8_t ionumber, uint32_t modefunc)
+{
+ base->PIO[ionumber] = modefunc;
+}
+#else
+/**
+ * @brief Sets I/O Control pin mux
+ * @param base : The base of IOCON peripheral on the chip
+ * @param port : GPIO port to mux
+ * @param pin : GPIO pin to mux
+ * @param modefunc : OR'ed values of type IOCON_*
+ * @return Nothing
+ */
+__STATIC_INLINE void IOCON_PinMuxSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint32_t modefunc)
+{
+ base->PIO[port][pin] = modefunc;
+}
+#endif
+
+/**
+ * @brief Set all I/O Control pin muxing
+ * @param base : The base of IOCON peripheral on the chip
+ * @param pinArray : Pointer to array of pin mux selections
+ * @param arrayLength : Number of entries in pinArray
+ * @return Nothing
+ */
+__STATIC_INLINE void IOCON_SetPinMuxing(IOCON_Type *base, const iocon_group_t *pinArray, uint32_t arrayLength)
+{
+ uint32_t i;
+
+ for (i = 0; i < arrayLength; i++)
+ {
+#if (defined(FSL_FEATURE_IOCON_ONE_DIMENSION) && (FSL_FEATURE_IOCON_ONE_DIMENSION == 1))
+ IOCON_PinMuxSet(base, pinArray[i].ionumber, pinArray[i].modefunc);
+#else
+ IOCON_PinMuxSet(base, pinArray[i].port, pinArray[i].pin, pinArray[i].modefunc);
+#endif /* FSL_FEATURE_IOCON_ONE_DIMENSION */
+ }
+}
+
+/* @} */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _FSL_IOCON_H_ */
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_power.c b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_power.c
new file mode 100644
index 000000000..92ca474e9
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_power.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016, NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "fsl_common.h"
+#include "fsl_power.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.power"
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/* Empty file since implementation is in header file and power library */
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_power.h b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_power.h
new file mode 100644
index 000000000..6e19262a6
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_power.h
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016, NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_POWER_H_
+#define _FSL_POWER_H_
+
+#include "fsl_common.h"
+
+/*! @addtogroup power */
+/*! @{ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief power driver version 2.0.0. */
+#define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
+/*@}*/
+
+#define MAKE_PD_BITS(reg, slot) (((reg) << 8) | (slot))
+#define PDRCFG0 0x0U
+#define PDRCFG1 0x1U
+
+typedef enum pd_bits
+{
+ kPDRUNCFG_LP_REG = MAKE_PD_BITS(PDRCFG0, 2U),
+ kPDRUNCFG_PD_FRO_EN = MAKE_PD_BITS(PDRCFG0, 4U),
+ kPDRUNCFG_PD_TS = MAKE_PD_BITS(PDRCFG0, 6U),
+ kPDRUNCFG_PD_BOD_RESET = MAKE_PD_BITS(PDRCFG0, 7U),
+ kPDRUNCFG_PD_BOD_INTR = MAKE_PD_BITS(PDRCFG0, 8U),
+ kPDRUNCFG_PD_VD2_ANA = MAKE_PD_BITS(PDRCFG0, 9U),
+ kPDRUNCFG_PD_ADC0 = MAKE_PD_BITS(PDRCFG0, 10U),
+ kPDRUNCFG_PD_RAM0 = MAKE_PD_BITS(PDRCFG0, 13U),
+ kPDRUNCFG_PD_RAM1 = MAKE_PD_BITS(PDRCFG0, 14U),
+ kPDRUNCFG_PD_RAM2 = MAKE_PD_BITS(PDRCFG0, 15U),
+ kPDRUNCFG_PD_RAM3 = MAKE_PD_BITS(PDRCFG0, 16U),
+ kPDRUNCFG_PD_ROM = MAKE_PD_BITS(PDRCFG0, 17U),
+ kPDRUNCFG_PD_VDDA = MAKE_PD_BITS(PDRCFG0, 19U),
+ kPDRUNCFG_PD_WDT_OSC = MAKE_PD_BITS(PDRCFG0, 20U),
+ kPDRUNCFG_PD_USB0_PHY = MAKE_PD_BITS(PDRCFG0, 21U),
+ kPDRUNCFG_PD_SYS_PLL0 = MAKE_PD_BITS(PDRCFG0, 22U),
+ kPDRUNCFG_PD_VREFP = MAKE_PD_BITS(PDRCFG0, 23U),
+ kPDRUNCFG_PD_FLASH_BG = MAKE_PD_BITS(PDRCFG0, 25U),
+ kPDRUNCFG_PD_VD3 = MAKE_PD_BITS(PDRCFG0, 26U),
+ kPDRUNCFG_PD_VD4 = MAKE_PD_BITS(PDRCFG0, 27U),
+ kPDRUNCFG_PD_VD5 = MAKE_PD_BITS(PDRCFG0, 28U),
+ kPDRUNCFG_PD_VD6 = MAKE_PD_BITS(PDRCFG0, 29U),
+ kPDRUNCFG_REQ_DELAY = MAKE_PD_BITS(PDRCFG0, 30U),
+ kPDRUNCFG_FORCE_RBB = MAKE_PD_BITS(PDRCFG0, 31U),
+
+ kPDRUNCFG_PD_USB1_PHY = MAKE_PD_BITS(PDRCFG1, 0U),
+ kPDRUNCFG_PD_USB_PLL = MAKE_PD_BITS(PDRCFG1, 1U),
+ kPDRUNCFG_PD_AUDIO_PLL = MAKE_PD_BITS(PDRCFG1, 2U),
+ kPDRUNCFG_PD_SYS_OSC = MAKE_PD_BITS(PDRCFG1, 3U),
+ kPDRUNCFG_PD_EEPROM = MAKE_PD_BITS(PDRCFG1, 5U),
+ kPDRUNCFG_PD_rng = MAKE_PD_BITS(PDRCFG1, 6U),
+
+ /*
+ This enum member has no practical meaning,it is used to avoid MISRA issue,
+ user should not trying to use it.
+ */
+ kPDRUNCFG_ForceUnsigned = (int)0x80000000U,
+} pd_bit_t;
+
+/* Power mode configuration API parameter */
+typedef enum _power_mode_config
+{
+ kPmu_Sleep = 0U,
+ kPmu_Deep_Sleep = 1U,
+ kPmu_Deep_PowerDown = 2U,
+} power_mode_cfg_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+* @name Power Configuration
+* @{
+*/
+
+/*!
+ * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral
+ *
+ * @param en peripheral for which to enable the PDRUNCFG bit
+ * @return none
+ */
+static inline void POWER_EnablePD(pd_bit_t en)
+{
+ /* PDRUNCFGSET */
+ SYSCON->PDRUNCFGSET[((uint32_t)en >> 8UL)] = (1UL << ((uint32_t)en & 0xffU));
+}
+
+/*!
+ * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral
+ *
+ * @param en peripheral for which to disable the PDRUNCFG bit
+ * @return none
+ */
+static inline void POWER_DisablePD(pd_bit_t en)
+{
+ /* PDRUNCFGCLR */
+ SYSCON->PDRUNCFGCLR[((uint32_t)en >> 8UL)] = (1UL << ((uint32_t)en & 0xffU));
+}
+
+/*!
+ * @brief API to enable deep sleep bit in the ARM Core.
+ *
+ * @param none
+ * @return none
+ */
+static inline void POWER_EnableDeepSleep(void)
+{
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+}
+
+/*!
+ * @brief API to disable deep sleep bit in the ARM Core.
+ *
+ * @param none
+ * @return none
+ */
+static inline void POWER_DisableDeepSleep(void)
+{
+ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
+}
+
+/*!
+ * @brief Power Library API to reload OTP.
+ * This API must be called if VD6 is power down
+ * and power back again since FROHF TRIM value
+ * is store in OTP. If not, when calling FROHF settng
+ * API in clock driver then the FROHF clock out put
+ * will be inaccurate.
+ * @return none
+ */
+void POWER_OtpReload(void);
+
+/*!
+ * @brief Power Library API to power the PLLs.
+ *
+ * @param none
+ * @return none
+ */
+void POWER_SetPLL(void);
+
+/*!
+ * @brief Power Library API to power the USB PHY.
+ *
+ * @param none
+ * @return none
+ */
+void POWER_SetUsbPhy(void);
+
+/*!
+ * @brief Power Library API to enter different power mode.
+ *
+ * @param exclude_from_pd Bit mask of the PDRUNCFG0(low 32bits) and PDRUNCFG1(high 32bits) that needs to be powered on
+ * during power mode selected.
+ * @return none
+ */
+void POWER_EnterPowerMode(power_mode_cfg_t mode, uint64_t exclude_from_pd);
+
+/*!
+ * @brief Power Library API to enter sleep mode.
+ *
+ * @return none
+ */
+void POWER_EnterSleep(void);
+
+/*!
+ * @brief Power Library API to enter deep sleep mode.
+ *
+ * @param exclude_from_pd Bit mask of the PDRUNCFG0(low 32bits) and PDRUNCFG1(high 32bits) bits that needs to be
+ * powered on during deep sleep
+ * @return none
+ */
+void POWER_EnterDeepSleep(uint64_t exclude_from_pd);
+
+/*!
+ * @brief Power Library API to enter deep power down mode.
+ *
+ * @param exclude_from_pd Bit mask of the PDRUNCFG0(low 32bits) and PDRUNCFG1(high 32bits) that needs to be powered on
+ during deep power
+ * down mode, but this is has no effect as the voltages are cut off.
+
+ * @return none
+ */
+void POWER_EnterDeepPowerDown(uint64_t exclude_from_pd);
+
+/*!
+ * @brief Power Library API to choose normal regulation and set the voltage for the desired operating frequency.
+ *
+ * @param freq - The desired frequency at which the part would like to operate,
+ * note that the voltage and flash wait states should be set before changing frequency
+ * @return none
+ */
+void POWER_SetVoltageForFreq(uint32_t freq);
+
+/*!
+ * @brief Power Library API to return the library version.
+ *
+ * @param none
+ * @return version number of the power library
+ */
+uint32_t POWER_GetLibVersion(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FSL_POWER_H_ */
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_reset.c b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_reset.c
new file mode 100644
index 000000000..6c000500e
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_reset.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016, NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_common.h"
+#include "fsl_reset.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.reset"
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+#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)))
+
+/*!
+ * brief Assert reset to peripheral.
+ *
+ * Asserts reset signal to specified peripheral module.
+ *
+ * param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
+ * and reset bit position in the reset register.
+ */
+void RESET_SetPeripheralReset(reset_ip_name_t peripheral)
+{
+ const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
+ const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu);
+ const uint32_t bitMask = 1UL << bitPos;
+
+ assert(bitPos < 32UL);
+
+ /* ASYNC_SYSCON registers have offset 1024 */
+ if (regIndex >= SYSCON_PRESETCTRL_COUNT)
+ {
+ /* reset register is in ASYNC_SYSCON */
+
+ /* set bit */
+ ASYNC_SYSCON->ASYNCPRESETCTRLSET = bitMask;
+ /* wait until it reads 0b1 */
+ while (0u == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
+ {
+ }
+ }
+ else
+ {
+ /* reset register is in SYSCON */
+
+ /* set bit */
+ SYSCON->PRESETCTRLSET[regIndex] = bitMask;
+ /* wait until it reads 0b1 */
+ while (0u == (SYSCON->PRESETCTRL[regIndex] & bitMask))
+ {
+ }
+ }
+}
+
+/*!
+ * brief Clear reset to peripheral.
+ *
+ * Clears reset signal to specified peripheral module, allows it to operate.
+ *
+ * param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
+ * and reset bit position in the reset register.
+ */
+void RESET_ClearPeripheralReset(reset_ip_name_t peripheral)
+{
+ const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16;
+ const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu);
+ const uint32_t bitMask = 1UL << bitPos;
+
+ assert(bitPos < 32UL);
+
+ /* ASYNC_SYSCON registers have offset 1024 */
+ if (regIndex >= SYSCON_PRESETCTRL_COUNT)
+ {
+ /* reset register is in ASYNC_SYSCON */
+
+ /* clear bit */
+ ASYNC_SYSCON->ASYNCPRESETCTRLCLR = bitMask;
+ /* wait until it reads 0b0 */
+ while (bitMask == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask))
+ {
+ }
+ }
+ else
+ {
+ /* reset register is in SYSCON */
+
+ /* clear bit */
+ SYSCON->PRESETCTRLCLR[regIndex] = bitMask;
+ /* wait until it reads 0b0 */
+ while (bitMask == (SYSCON->PRESETCTRL[regIndex] & bitMask))
+ {
+ }
+ }
+}
+
+/*!
+ * brief Reset peripheral module.
+ *
+ * Reset peripheral module.
+ *
+ * param peripheral Peripheral to reset. The enum argument contains encoding of reset register
+ * and reset bit position in the reset register.
+ */
+void RESET_PeripheralReset(reset_ip_name_t peripheral)
+{
+ RESET_SetPeripheralReset(peripheral);
+ RESET_ClearPeripheralReset(peripheral);
+}
+
+#endif /* FSL_FEATURE_SOC_SYSCON_COUNT || FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT */
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_reset.h b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_reset.h
new file mode 100644
index 000000000..75dc0a582
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_reset.h
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016, NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _FSL_RESET_H_
+#define _FSL_RESET_H_
+
+#include <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "fsl_device_registers.h"
+
+/*! @addtogroup reset */
+/*! @{ */
+
+/*! @file */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief reset driver version 2.0.1. */
+#define FSL_RESET_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
+/*@}*/
+
+/*!
+ * @brief Enumeration for peripheral reset control bits
+ *
+ * Defines the enumeration for peripheral reset control bits in PRESETCTRL/ASYNCPRESETCTRL registers
+ */
+typedef enum _SYSCON_RSTn
+{
+ kSPIFI_RST_SHIFT_RSTn = 0 | 10U, /**< SPIFI reset control */
+ kMUX_RST_SHIFT_RSTn = 0 | 11U, /**< Input mux reset control */
+ kIOCON_RST_SHIFT_RSTn = 0 | 13U, /**< IOCON reset control */
+ kGPIO0_RST_SHIFT_RSTn = 0 | 14U, /**< GPIO0 reset control */
+ kGPIO1_RST_SHIFT_RSTn = 0 | 15U, /**< GPIO1 reset control */
+ kGPIO2_RST_SHIFT_RSTn = 0 | 16U, /**< GPIO2 reset control */
+ kGPIO3_RST_SHIFT_RSTn = 0 | 17U, /**< GPIO3 reset control */
+ kPINT_RST_SHIFT_RSTn = 0 | 18U, /**< Pin interrupt (PINT) reset control */
+ kGINT_RST_SHIFT_RSTn = 0 | 19U, /**< Grouped interrupt (PINT) reset control. */
+ kDMA_RST_SHIFT_RSTn = 0 | 20U, /**< DMA reset control */
+ kCRC_RST_SHIFT_RSTn = 0 | 21U, /**< CRC reset control */
+ kWWDT_RST_SHIFT_RSTn = 0 | 22U, /**< Watchdog timer reset control */
+ kADC0_RST_SHIFT_RSTn = 0 | 27U, /**< ADC0 reset control */
+
+ kMRT_RST_SHIFT_RSTn = 65536 | 0U, /**< Multi-rate timer (MRT) reset control */
+ kSCT0_RST_SHIFT_RSTn = 65536 | 2U, /**< SCTimer/PWM 0 (SCT0) reset control */
+ kMCAN0_RST_SHIFT_RSTn = 65536 | 7U, /**< MCAN0 reset control */
+ kMCAN1_RST_SHIFT_RSTn = 65536 | 8U, /**< MCAN1 reset control */
+ kUTICK_RST_SHIFT_RSTn = 65536 | 10U, /**< Micro-tick timer reset control */
+ kFC0_RST_SHIFT_RSTn = 65536 | 11U, /**< Flexcomm Interface 0 reset control */
+ kFC1_RST_SHIFT_RSTn = 65536 | 12U, /**< Flexcomm Interface 1 reset control */
+ kFC2_RST_SHIFT_RSTn = 65536 | 13U, /**< Flexcomm Interface 2 reset control */
+ kFC3_RST_SHIFT_RSTn = 65536 | 14U, /**< Flexcomm Interface 3 reset control */
+ kFC4_RST_SHIFT_RSTn = 65536 | 15U, /**< Flexcomm Interface 4 reset control */
+ kFC5_RST_SHIFT_RSTn = 65536 | 16U, /**< Flexcomm Interface 5 reset control */
+ kFC6_RST_SHIFT_RSTn = 65536 | 17U, /**< Flexcomm Interface 6 reset control */
+ kFC7_RST_SHIFT_RSTn = 65536 | 18U, /**< Flexcomm Interface 7 reset control */
+ kDMIC_RST_SHIFT_RSTn = 65536 | 19U, /**< Digital microphone interface reset control */
+ kCT32B2_RST_SHIFT_RSTn = 65536 | 22U, /**< CT32B2 reset control */
+ kUSB0D_RST_SHIFT_RSTn = 65536 | 25U, /**< USB0D reset control */
+ kCT32B0_RST_SHIFT_RSTn = 65536 | 26U, /**< CT32B0 reset control */
+ kCT32B1_RST_SHIFT_RSTn = 65536 | 27U, /**< CT32B1 reset control */
+
+ kLCD_RST_SHIFT_RSTn = 131072 | 2U, /**< LCD reset control */
+ kSDIO_RST_SHIFT_RSTn = 131072 | 3U, /**< SDIO reset control */
+ kUSB1H_RST_SHIFT_RSTn = 131072 | 4U, /**< USB1H reset control */
+ kUSB1D_RST_SHIFT_RSTn = 131072 | 5U, /**< USB1D reset control */
+ kUSB1RAM_RST_SHIFT_RSTn = 131072 | 6U, /**< USB1RAM reset control */
+ kEMC_RST_SHIFT_RSTn = 131072 | 7U, /**< EMC reset control */
+ kETH_RST_SHIFT_RSTn = 131072 | 8U, /**< ETH reset control */
+ kGPIO4_RST_SHIFT_RSTn = 131072 | 9U, /**< GPIO4 reset control */
+ kGPIO5_RST_SHIFT_RSTn = 131072 | 10U, /**< GPIO5 reset control */
+ kAES_RST_SHIFT_RSTn = 131072 | 11U, /**< AES reset control */
+ kOTP_RST_SHIFT_RSTn = 131072 | 12U, /**< OTP reset control */
+ kRNG_RST_SHIFT_RSTn = 131072 | 13U, /**< RNG reset control */
+ kFC8_RST_SHIFT_RSTn = 131072 | 14U, /**< Flexcomm Interface 8 reset control */
+ kFC9_RST_SHIFT_RSTn = 131072 | 15U, /**< Flexcomm Interface 9 reset control */
+ kUSB0HMR_RST_SHIFT_RSTn = 131072 | 16U, /**< USB0HMR reset control */
+ kUSB0HSL_RST_SHIFT_RSTn = 131072 | 17U, /**< USB0HSL reset control */
+ kSHA_RST_SHIFT_RSTn = 131072 | 18U, /**< SHA reset control */
+ kSC0_RST_SHIFT_RSTn = 131072 | 19U, /**< SC0 reset control */
+ kSC1_RST_SHIFT_RSTn = 131072 | 20U, /**< SC1 reset control */
+ kFC10_RST_SHIFT_RSTn = 131072 | 21U, /**< Flexcomm Interface 10 reset control */
+
+ kCT32B3_RST_SHIFT_RSTn = 67108864 | 13U, /**< CT32B3 reset control */
+ kCT32B4_RST_SHIFT_RSTn = 67108864 | 14U, /**< CT32B4 reset control */
+} SYSCON_RSTn_t;
+
+/** Array initializers with peripheral reset bits **/
+#define ADC_RSTS \
+ { \
+ kADC0_RST_SHIFT_RSTn \
+ } /* Reset bits for ADC peripheral */
+#define AES_RSTS \
+ { \
+ kAES_RST_SHIFT_RSTn \
+ } /* Reset bits for AES peripheral */
+#define CRC_RSTS \
+ { \
+ kCRC_RST_SHIFT_RSTn \
+ } /* Reset bits for CRC peripheral */
+#define CTIMER_RSTS \
+ { \
+ kCT32B0_RST_SHIFT_RSTn, kCT32B1_RST_SHIFT_RSTn, kCT32B2_RST_SHIFT_RSTn, kCT32B3_RST_SHIFT_RSTn, \
+ kCT32B4_RST_SHIFT_RSTn \
+ } /* Reset bits for CTIMER peripheral */
+#define DMA_RSTS_N \
+ { \
+ kDMA_RST_SHIFT_RSTn \
+ } /* Reset bits for DMA peripheral */
+#define DMIC_RSTS \
+ { \
+ kDMIC_RST_SHIFT_RSTn \
+ } /* Reset bits for DMIC peripheral */
+#define EMC_RSTS \
+ { \
+ kEMC_RST_SHIFT_RSTn \
+ } /* Reset bits for EMC peripheral */
+#define ETH_RST \
+ { \
+ kETH_RST_SHIFT_RSTn \
+ } /* Reset bits for EMC peripheral */
+#define FLEXCOMM_RSTS \
+ { \
+ kFC0_RST_SHIFT_RSTn, kFC1_RST_SHIFT_RSTn, kFC2_RST_SHIFT_RSTn, kFC3_RST_SHIFT_RSTn, kFC4_RST_SHIFT_RSTn, \
+ kFC5_RST_SHIFT_RSTn, kFC6_RST_SHIFT_RSTn, kFC7_RST_SHIFT_RSTn, kFC8_RST_SHIFT_RSTn, kFC9_RST_SHIFT_RSTn, kFC9_RST_SHIFT_RSTn \
+ } /* Reset bits for FLEXCOMM peripheral */
+#define GINT_RSTS \
+ { \
+ kGINT_RST_SHIFT_RSTn, kGINT_RST_SHIFT_RSTn \
+ } /* Reset bits for GINT peripheral. GINT0 & GINT1 share same slot */
+#define GPIO_RSTS_N \
+ { \
+ kGPIO0_RST_SHIFT_RSTn, kGPIO1_RST_SHIFT_RSTn, kGPIO2_RST_SHIFT_RSTn, kGPIO3_RST_SHIFT_RSTn, \
+ kGPIO4_RST_SHIFT_RSTn, kGPIO5_RST_SHIFT_RSTn \
+ } /* Reset bits for GPIO peripheral */
+#define INPUTMUX_RSTS \
+ { \
+ kMUX_RST_SHIFT_RSTn \
+ } /* Reset bits for INPUTMUX peripheral */
+#define IOCON_RSTS \
+ { \
+ kIOCON_RST_SHIFT_RSTn \
+ } /* Reset bits for IOCON peripheral */
+#define FLASH_RSTS \
+ { \
+ kFLASH_RST_SHIFT_RSTn, kFMC_RST_SHIFT_RSTn \
+ } /* Reset bits for Flash peripheral */
+#define LCD_RSTS \
+ { \
+ kLCD_RST_SHIFT_RSTn \
+ } /* Reset bits for LCD peripheral */
+#define MRT_RSTS \
+ { \
+ kMRT_RST_SHIFT_RSTn \
+ } /* Reset bits for MRT peripheral */
+#define MCAN_RSTS \
+ { \
+ kMCAN0_RST_SHIFT_RSTn,kMCAN1_RST_SHIFT_RSTn \
+ } /* Reset bits for MCAN0&MACN1 peripheral */
+#define OTP_RSTS \
+ { \
+ kOTP_RST_SHIFT_RSTn \
+ } /* Reset bits for OTP peripheral */
+#define PINT_RSTS \
+ { \
+ kPINT_RST_SHIFT_RSTn \
+ } /* Reset bits for PINT peripheral */
+#define RNG_RSTS \
+ { \
+ kRNG_RST_SHIFT_RSTn \
+ } /* Reset bits for RNG peripheral */
+#define SDIO_RST \
+ { \
+ kSDIO_RST_SHIFT_RSTn \
+ } /* Reset bits for SDIO peripheral */
+#define SCT_RSTS \
+ { \
+ kSCT0_RST_SHIFT_RSTn \
+ } /* Reset bits for SCT peripheral */
+#define SHA_RST \
+ { \
+ kSHA_RST_SHIFT_RSTn \
+ } /* Reset bits for SHA peripheral */
+#define SPIFI_RSTS \
+ { \
+ kSPIFI_RST_SHIFT_RSTn \
+ } /* Reset bits for SPIFI peripheral */
+#define USB0D_RST \
+ { \
+ kUSB0D_RST_SHIFT_RSTn \
+ } /* Reset bits for USB0D peripheral */
+#define USB0HMR_RST \
+ { \
+ kUSB0HMR_RST_SHIFT_RSTn \
+ } /* Reset bits for USB0HMR peripheral */
+#define USB0HSL_RST \
+ { \
+ kUSB0HSL_RST_SHIFT_RSTn \
+ } /* Reset bits for USB0HSL peripheral */
+#define USB1H_RST \
+ { \
+ kUSB1H_RST_SHIFT_RSTn \
+ } /* Reset bits for USB1H peripheral */
+#define USB1D_RST \
+ { \
+ kUSB1D_RST_SHIFT_RSTn \
+ } /* Reset bits for USB1D peripheral */
+#define USB1RAM_RST \
+ { \
+ kUSB1RAM_RST_SHIFT_RSTn \
+ } /* Reset bits for USB1RAM peripheral */
+#define UTICK_RSTS \
+ { \
+ kUTICK_RST_SHIFT_RSTn \
+ } /* Reset bits for UTICK peripheral */
+#define WWDT_RSTS \
+ { \
+ kWWDT_RST_SHIFT_RSTn \
+ } /* Reset bits for WWDT peripheral */
+
+typedef SYSCON_RSTn_t reset_ip_name_t;
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @brief Assert reset to peripheral.
+ *
+ * Asserts reset signal to specified peripheral module.
+ *
+ * @param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register
+ * and reset bit position in the reset register.
+ */
+void RESET_SetPeripheralReset(reset_ip_name_t peripheral);
+
+/*!
+ * @brief Clear reset to peripheral.
+ *
+ * Clears reset signal to specified peripheral module, allows it to operate.
+ *
+ * @param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register
+ * and reset bit position in the reset register.
+ */
+void RESET_ClearPeripheralReset(reset_ip_name_t peripheral);
+
+/*!
+ * @brief Reset peripheral module.
+ *
+ * Reset peripheral module.
+ *
+ * @param peripheral Peripheral to reset. The enum argument contains encoding of reset register
+ * and reset bit position in the reset register.
+ */
+void RESET_PeripheralReset(reset_ip_name_t peripheral);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @} */
+
+#endif /* _FSL_RESET_H_ */
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_usart.c b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_usart.c
new file mode 100644
index 000000000..dd35da6b4
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_usart.c
@@ -0,0 +1,981 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_usart.h"
+#include "fsl_device_registers.h"
+#include "fsl_flexcomm.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.flexcomm_usart"
+#endif
+
+/*!
+ * @brief Used for conversion from `flexcomm_usart_irq_handler_t` to `flexcomm_irq_handler_t`
+ */
+typedef union usart_to_flexcomm
+{
+ flexcomm_usart_irq_handler_t usart_master_handler;
+ flexcomm_irq_handler_t flexcomm_handler;
+} usart_to_flexcomm_t;
+
+enum
+{
+ kUSART_TxIdle, /* TX idle. */
+ kUSART_TxBusy, /* TX busy. */
+ kUSART_RxIdle, /* RX idle. */
+ kUSART_RxBusy /* RX busy. */
+};
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief IRQ name array */
+static const IRQn_Type s_usartIRQ[] = USART_IRQS;
+
+/*! @brief Array to map USART instance number to base address. */
+static const uint32_t s_usartBaseAddrs[FSL_FEATURE_SOC_USART_COUNT] = USART_BASE_ADDRS;
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/* Get the index corresponding to the USART */
+/*! brief Returns instance number for USART peripheral base address. */
+uint32_t USART_GetInstance(USART_Type *base)
+{
+ uint32_t i;
+
+ for (i = 0; i < (uint32_t)FSL_FEATURE_SOC_USART_COUNT; i++)
+ {
+ if ((uint32_t)base == s_usartBaseAddrs[i])
+ {
+ break;
+ }
+ }
+
+ assert(i < FSL_FEATURE_SOC_USART_COUNT);
+ return i;
+}
+
+/*!
+ * brief Get the length of received data in RX ring buffer.
+ *
+ * param handle USART handle pointer.
+ * return Length of received data in RX ring buffer.
+ */
+size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle)
+{
+ size_t size;
+
+ /* Check arguments */
+ assert(NULL != handle);
+ uint16_t rxRingBufferHead = handle->rxRingBufferHead;
+ uint16_t rxRingBufferTail = handle->rxRingBufferTail;
+
+ if (rxRingBufferTail > rxRingBufferHead)
+ {
+ size = (size_t)rxRingBufferHead + handle->rxRingBufferSize - (size_t)rxRingBufferTail;
+ }
+ else
+ {
+ size = (size_t)rxRingBufferHead - (size_t)rxRingBufferTail;
+ }
+ return size;
+}
+
+static bool USART_TransferIsRxRingBufferFull(usart_handle_t *handle)
+{
+ bool full;
+
+ /* Check arguments */
+ assert(NULL != handle);
+
+ if (USART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U))
+ {
+ full = true;
+ }
+ else
+ {
+ full = false;
+ }
+ return full;
+}
+
+/*!
+ * brief Sets up the RX ring buffer.
+ *
+ * This function sets up the RX ring buffer to a specific USART handle.
+ *
+ * When the RX ring buffer is used, data received are stored into the ring buffer even when the
+ * user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received
+ * in the ring buffer, the user can get the received data from the ring buffer directly.
+ *
+ * note When using the RX ring buffer, one byte is reserved for internal use. In other
+ * words, if p ringBufferSize is 32, then only 31 bytes are used for saving data.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
+ * param ringBufferSize size of the ring buffer.
+ */
+void USART_TransferStartRingBuffer(USART_Type *base, usart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize)
+{
+ /* Check arguments */
+ assert(NULL != base);
+ assert(NULL != handle);
+ assert(NULL != ringBuffer);
+
+ /* Setup the ringbuffer address */
+ handle->rxRingBuffer = ringBuffer;
+ handle->rxRingBufferSize = ringBufferSize;
+ handle->rxRingBufferHead = 0U;
+ handle->rxRingBufferTail = 0U;
+ /* ring buffer is ready we can start receiving data */
+ base->FIFOINTENSET |= USART_FIFOINTENSET_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK;
+}
+
+/*!
+ * brief Aborts the background transfer and uninstalls the ring buffer.
+ *
+ * This function aborts the background transfer and uninstalls the ring buffer.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle)
+{
+ /* Check arguments */
+ assert(NULL != base);
+ assert(NULL != handle);
+
+ if (handle->rxState == (uint8_t)kUSART_RxIdle)
+ {
+ base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENCLR_RXERR_MASK;
+ }
+ handle->rxRingBuffer = NULL;
+ handle->rxRingBufferSize = 0U;
+ handle->rxRingBufferHead = 0U;
+ handle->rxRingBufferTail = 0U;
+}
+
+/*!
+ * brief Initializes a USART instance with user configuration structure and peripheral clock.
+ *
+ * This function configures the USART module with the user-defined settings. The user can configure the configuration
+ * structure and also get the default configuration by using the USART_GetDefaultConfig() function.
+ * Example below shows how to use this API to configure USART.
+ * code
+ * usart_config_t usartConfig;
+ * usartConfig.baudRate_Bps = 115200U;
+ * usartConfig.parityMode = kUSART_ParityDisabled;
+ * usartConfig.stopBitCount = kUSART_OneStopBit;
+ * USART_Init(USART1, &usartConfig, 20000000U);
+ * endcode
+ *
+ * param base USART peripheral base address.
+ * param config Pointer to user-defined configuration structure.
+ * param srcClock_Hz USART clock source frequency in HZ.
+ * retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * retval kStatus_InvalidArgument USART base address is not valid
+ * retval kStatus_Success Status USART initialize succeed
+ */
+status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz)
+{
+ int result;
+
+ /* check arguments */
+ assert(!((NULL == base) || (NULL == config) || (0U == srcClock_Hz)));
+ if ((NULL == base) || (NULL == config) || (0U == srcClock_Hz))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* initialize flexcomm to USART mode */
+ result = FLEXCOMM_Init(base, FLEXCOMM_PERIPH_USART);
+ if (kStatus_Success != result)
+ {
+ return result;
+ }
+
+ if (config->enableTx)
+ {
+ /* empty and enable txFIFO */
+ base->FIFOCFG |= USART_FIFOCFG_EMPTYTX_MASK | USART_FIFOCFG_ENABLETX_MASK;
+ /* setup trigger level */
+ base->FIFOTRIG &= ~(USART_FIFOTRIG_TXLVL_MASK);
+ base->FIFOTRIG |= USART_FIFOTRIG_TXLVL(config->txWatermark);
+ /* enable trigger interrupt */
+ base->FIFOTRIG |= USART_FIFOTRIG_TXLVLENA_MASK;
+ }
+
+ /* empty and enable rxFIFO */
+ if (config->enableRx)
+ {
+ base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK | USART_FIFOCFG_ENABLERX_MASK;
+ /* setup trigger level */
+ base->FIFOTRIG &= ~(USART_FIFOTRIG_RXLVL_MASK);
+ base->FIFOTRIG |= USART_FIFOTRIG_RXLVL(config->rxWatermark);
+ /* enable trigger interrupt */
+ base->FIFOTRIG |= USART_FIFOTRIG_RXLVLENA_MASK;
+ }
+ /* setup configuration and enable USART */
+ base->CFG = USART_CFG_PARITYSEL(config->parityMode) | USART_CFG_STOPLEN(config->stopBitCount) |
+ USART_CFG_DATALEN(config->bitCountPerChar) | USART_CFG_LOOP(config->loopback) |
+ USART_CFG_SYNCEN((uint32_t)config->syncMode >> 1) | USART_CFG_SYNCMST((uint8_t)config->syncMode) |
+ USART_CFG_CLKPOL(config->clockPolarity) | USART_CFG_ENABLE_MASK;
+
+ /* Setup baudrate */
+ result = USART_SetBaudRate(base, config->baudRate_Bps, srcClock_Hz);
+ if (kStatus_Success != result)
+ {
+ return result;
+ }
+ /* Setting continuous Clock configuration. used for synchronous mode. */
+ USART_EnableContinuousSCLK(base, config->enableContinuousSCLK);
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Deinitializes a USART instance.
+ *
+ * This function waits for TX complete, disables TX and RX, and disables the USART clock.
+ *
+ * param base USART peripheral base address.
+ */
+void USART_Deinit(USART_Type *base)
+{
+ /* Check arguments */
+ assert(NULL != base);
+ while (0U == (base->STAT & USART_STAT_TXIDLE_MASK))
+ {
+ }
+ /* Disable interrupts, disable dma requests, disable peripheral */
+ base->FIFOINTENCLR = USART_FIFOINTENCLR_TXERR_MASK | USART_FIFOINTENCLR_RXERR_MASK | USART_FIFOINTENCLR_TXLVL_MASK |
+ USART_FIFOINTENCLR_RXLVL_MASK;
+ base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK | USART_FIFOCFG_DMARX_MASK);
+ base->CFG &= ~(USART_CFG_ENABLE_MASK);
+}
+
+/*!
+ * brief Gets the default configuration structure.
+ *
+ * This function initializes the USART configuration structure to a default value. The default
+ * values are:
+ * usartConfig->baudRate_Bps = 115200U;
+ * usartConfig->parityMode = kUSART_ParityDisabled;
+ * usartConfig->stopBitCount = kUSART_OneStopBit;
+ * usartConfig->bitCountPerChar = kUSART_8BitsPerChar;
+ * usartConfig->loopback = false;
+ * usartConfig->enableTx = false;
+ * usartConfig->enableRx = false;
+ *
+ * param config Pointer to configuration structure.
+ */
+void USART_GetDefaultConfig(usart_config_t *config)
+{
+ /* Check arguments */
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ /* Set always all members ! */
+ config->baudRate_Bps = 115200U;
+ config->parityMode = kUSART_ParityDisabled;
+ config->stopBitCount = kUSART_OneStopBit;
+ config->bitCountPerChar = kUSART_8BitsPerChar;
+ config->loopback = false;
+ config->enableRx = false;
+ config->enableTx = false;
+ config->txWatermark = kUSART_TxFifo0;
+ config->rxWatermark = kUSART_RxFifo1;
+ config->syncMode = kUSART_SyncModeDisabled;
+ config->enableContinuousSCLK = false;
+ config->clockPolarity = kUSART_RxSampleOnFallingEdge;
+}
+
+/*!
+ * brief Sets the USART instance baud rate.
+ *
+ * This function configures the USART module baud rate. This function is used to update
+ * the USART module baud rate after the USART module is initialized by the USART_Init.
+ * code
+ * USART_SetBaudRate(USART1, 115200U, 20000000U);
+ * endcode
+ *
+ * param base USART peripheral base address.
+ * param baudrate_Bps USART baudrate to be set.
+ * param srcClock_Hz USART clock source frequency in HZ.
+ * retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * retval kStatus_Success Set baudrate succeed.
+ * retval kStatus_InvalidArgument One or more arguments are invalid.
+ */
+status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz)
+{
+ uint32_t best_diff = (uint32_t)-1, best_osrval = 0xf, best_brgval = (uint32_t)-1;
+ uint32_t osrval, brgval, diff, baudrate;
+
+ /* check arguments */
+ assert(!((NULL == base) || (0 == baudrate_Bps) || (0 == srcClock_Hz)));
+ if ((NULL == base) || (0U == baudrate_Bps) || (0U == srcClock_Hz))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* If synchronous master mode is enabled, only configure the BRG value. */
+ if ((base->CFG & USART_CFG_SYNCEN_MASK) != 0U)
+ {
+ if ((base->CFG & USART_CFG_SYNCMST_MASK) != 0U)
+ {
+ brgval = srcClock_Hz / baudrate_Bps;
+ base->BRG = brgval - 1U;
+ }
+ }
+ else
+ {
+ /*
+ * Smaller values of OSR can make the sampling position within a data bit less accurate and may
+ * potentially cause more noise errors or incorrect data.
+ */
+ for (osrval = best_osrval; osrval >= 8U; osrval--)
+ {
+ brgval = (((srcClock_Hz * 10U) / ((osrval + 1U) * baudrate_Bps)) - 5U) / 10U;
+ if (brgval > 0xFFFFU)
+ {
+ continue;
+ }
+ baudrate = srcClock_Hz / ((osrval + 1U) * (brgval + 1U));
+ diff = baudrate_Bps < baudrate ? baudrate - baudrate_Bps : baudrate_Bps - baudrate;
+ if (diff < best_diff)
+ {
+ best_diff = diff;
+ best_osrval = osrval;
+ best_brgval = brgval;
+ }
+ }
+
+ /* value over range */
+ if (best_brgval > 0xFFFFU)
+ {
+ return kStatus_USART_BaudrateNotSupport;
+ }
+
+ base->OSR = best_osrval;
+ base->BRG = best_brgval;
+ }
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Writes to the TX register using a blocking method.
+ *
+ * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
+ * to have room and writes data to the TX buffer.
+ *
+ * param base USART peripheral base address.
+ * param data Start address of the data to write.
+ * param length Size of the data to write.
+ */
+void USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length)
+{
+ /* Check arguments */
+ assert(!((NULL == base) || (NULL == data)));
+ if ((NULL == base) || (NULL == data))
+ {
+ return;
+ }
+ /* Check whether txFIFO is enabled */
+ if (0U == (base->FIFOCFG & USART_FIFOCFG_ENABLETX_MASK))
+ {
+ return;
+ }
+ for (; length > 0U; length--)
+ {
+ /* Loop until txFIFO get some space for new data */
+ while (0U == (base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK))
+ {
+ }
+ base->FIFOWR = *data;
+ data++;
+ }
+ /* Wait to finish transfer */
+ while (0U == (base->STAT & USART_STAT_TXIDLE_MASK))
+ {
+ }
+}
+
+/*!
+ * brief Read RX data register using a blocking method.
+ *
+ * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
+ * have data and read data from the TX register.
+ *
+ * param base USART peripheral base address.
+ * param data Start address of the buffer to store the received data.
+ * param length Size of the buffer.
+ * retval kStatus_USART_FramingError Receiver overrun happened while receiving data.
+ * retval kStatus_USART_ParityError Noise error happened while receiving data.
+ * retval kStatus_USART_NoiseError Framing error happened while receiving data.
+ * retval kStatus_USART_RxError Overflow or underflow rxFIFO happened.
+ * retval kStatus_Success Successfully received all data.
+ */
+status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length)
+{
+ uint32_t statusFlag;
+ status_t status = kStatus_Success;
+
+ /* check arguments */
+ assert(!((NULL == base) || (NULL == data)));
+ if ((NULL == base) || (NULL == data))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* Check whether rxFIFO is enabled */
+ if ((base->FIFOCFG & USART_FIFOCFG_ENABLERX_MASK) == 0U)
+ {
+ return kStatus_Fail;
+ }
+ for (; length > 0U; length--)
+ {
+ /* loop until rxFIFO have some data to read */
+ while ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) == 0U)
+ {
+ }
+ /* check rxFIFO statusFlag */
+ if ((base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK) != 0U)
+ {
+ base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+ base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK;
+ status = kStatus_USART_RxError;
+ break;
+ }
+ /* check receive statusFlag */
+ statusFlag = base->STAT;
+ /* Clear all status flags */
+ base->STAT |= statusFlag;
+ if ((statusFlag & USART_STAT_PARITYERRINT_MASK) != 0U)
+ {
+ status = kStatus_USART_ParityError;
+ }
+ if ((statusFlag & USART_STAT_FRAMERRINT_MASK) != 0U)
+ {
+ status = kStatus_USART_FramingError;
+ }
+ if ((statusFlag & USART_STAT_RXNOISEINT_MASK) != 0U)
+ {
+ status = kStatus_USART_NoiseError;
+ }
+
+ if (kStatus_Success == status)
+ {
+ *data = (uint8_t)base->FIFORD;
+ data++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return status;
+}
+
+/*!
+ * brief Initializes the USART handle.
+ *
+ * This function initializes the USART handle which can be used for other USART
+ * transactional APIs. Usually, for a specified USART instance,
+ * call this API once to get the initialized handle.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param callback The callback function.
+ * param userData The parameter of the callback function.
+ */
+status_t USART_TransferCreateHandle(USART_Type *base,
+ usart_handle_t *handle,
+ usart_transfer_callback_t callback,
+ void *userData)
+{
+ /* Check 'base' */
+ assert(!((NULL == base) || (NULL == handle)));
+
+ uint32_t instance = 0;
+ usart_to_flexcomm_t handler;
+ handler.usart_master_handler = USART_TransferHandleIRQ;
+
+ if ((NULL == base) || (NULL == handle))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ instance = USART_GetInstance(base);
+
+ (void)memset(handle, 0, sizeof(*handle));
+ /* Set the TX/RX state. */
+ handle->rxState = (uint8_t)kUSART_RxIdle;
+ handle->txState = (uint8_t)kUSART_TxIdle;
+ /* Set the callback and user data. */
+ handle->callback = callback;
+ handle->userData = userData;
+ handle->rxWatermark = (uint8_t)USART_FIFOTRIG_RXLVL_GET(base);
+ handle->txWatermark = (uint8_t)USART_FIFOTRIG_TXLVL_GET(base);
+
+ FLEXCOMM_SetIRQHandler(base, handler.flexcomm_handler, handle);
+
+ /* Enable interrupt in NVIC. */
+ (void)EnableIRQ(s_usartIRQ[instance]);
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the IRQ handler, the USART driver calls the callback
+ * function and passes the ref kStatus_USART_TxIdle as status parameter.
+ *
+ * note The kStatus_USART_TxIdle is passed to the upper layer when all data is written
+ * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX,
+ * check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param xfer USART transfer structure. See #usart_transfer_t.
+ * retval kStatus_Success Successfully start the data transmission.
+ * retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet.
+ * retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer)
+{
+ /* Check arguments */
+ assert(!((NULL == base) || (NULL == handle) || (NULL == xfer)));
+ if ((NULL == base) || (NULL == handle) || (NULL == xfer))
+ {
+ return kStatus_InvalidArgument;
+ }
+ /* Check xfer members */
+ assert(!((0 == xfer->dataSize) || (NULL == xfer->data)));
+ if ((0U == xfer->dataSize) || (NULL == xfer->data))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* Return error if current TX busy. */
+ if ((uint8_t)kUSART_TxBusy == handle->txState)
+ {
+ return kStatus_USART_TxBusy;
+ }
+ else
+ {
+ handle->txData = xfer->data;
+ handle->txDataSize = xfer->dataSize;
+ handle->txDataSizeAll = xfer->dataSize;
+ handle->txState = (uint8_t)kUSART_TxBusy;
+ /* Enable transmiter interrupt. */
+ base->FIFOINTENSET |= USART_FIFOINTENSET_TXLVL_MASK;
+ }
+ return kStatus_Success;
+}
+
+/*!
+ * 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.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle)
+{
+ assert(NULL != handle);
+
+ /* Disable interrupts */
+ USART_DisableInterrupts(base, (uint32_t)kUSART_TxLevelInterruptEnable);
+ /* Empty txFIFO */
+ base->FIFOCFG |= USART_FIFOCFG_EMPTYTX_MASK;
+
+ handle->txDataSize = 0U;
+ handle->txState = (uint8_t)kUSART_TxIdle;
+}
+
+/*!
+ * brief Get the number of bytes that have been written to USART TX register.
+ *
+ * This function gets the number of bytes that have been written to USART TX
+ * register by interrupt method.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param count Send bytes count.
+ * retval kStatus_NoTransferInProgress No send in progress.
+ * retval kStatus_InvalidArgument Parameter is invalid.
+ * retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count)
+{
+ assert(NULL != handle);
+ assert(NULL != count);
+
+ if ((uint8_t)kUSART_TxIdle == handle->txState)
+ {
+ return kStatus_NoTransferInProgress;
+ }
+
+ *count = handle->txDataSizeAll - handle->txDataSize;
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ * returns without waiting for all data to be received.
+ * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
+ * the parameter p receivedBytes shows how many bytes are copied from the ring buffer.
+ * After copying, if the data in the ring buffer is not enough to read, the receive
+ * request is saved by the USART driver. When the new data arrives, the receive request
+ * is serviced first. When all data is received, the USART driver notifies the upper layer
+ * through a callback function and passes the status parameter ref kStatus_USART_RxIdle.
+ * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
+ * The 5 bytes are copied to the xfer->data and this function returns with the
+ * parameter p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
+ * saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer.
+ * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
+ * to receive data to the xfer->data. When all data is received, the upper layer is notified.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param xfer USART transfer structure, see #usart_transfer_t.
+ * param receivedBytes Bytes received from the ring buffer directly.
+ * retval kStatus_Success Successfully queue the transfer into transmit queue.
+ * retval kStatus_USART_RxBusy Previous receive request is not finished.
+ * retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferReceiveNonBlocking(USART_Type *base,
+ usart_handle_t *handle,
+ usart_transfer_t *xfer,
+ size_t *receivedBytes)
+{
+ uint32_t i;
+ /* How many bytes to copy from ring buffer to user memory. */
+ size_t bytesToCopy = 0U;
+ /* How many bytes to receive. */
+ size_t bytesToReceive;
+ /* How many bytes currently have received. */
+ size_t bytesCurrentReceived;
+ uint32_t regPrimask = 0U;
+
+ /* Check arguments */
+ assert(!((NULL == base) || (NULL == handle) || (NULL == xfer)));
+ if ((NULL == base) || (NULL == handle) || (NULL == xfer))
+ {
+ return kStatus_InvalidArgument;
+ }
+ /* Check xfer members */
+ assert(!((0 == xfer->dataSize) || (NULL == xfer->data)));
+ 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
+ to uart handle, enable interrupt to store received data to xfer->data. When
+ all data received, trigger callback.
+ 2. If RX ring buffer is enabled and not empty, get data from ring buffer first.
+ If there are enough data in ring buffer, copy them to xfer->data and return.
+ If there are not enough data in ring buffer, copy all of them to xfer->data,
+ save the xfer->data remained empty space to uart handle, receive data
+ to this empty space and trigger callback when finished. */
+ if ((uint8_t)kUSART_RxBusy == handle->rxState)
+ {
+ return kStatus_USART_RxBusy;
+ }
+ else
+ {
+ bytesToReceive = xfer->dataSize;
+ bytesCurrentReceived = 0U;
+ /* If RX ring buffer is used. */
+ if (handle->rxRingBuffer != NULL)
+ {
+ /* Disable IRQ, protect ring buffer. */
+ regPrimask = DisableGlobalIRQ();
+ /* How many bytes in RX ring buffer currently. */
+ bytesToCopy = USART_TransferGetRxRingBufferLength(handle);
+ if (bytesToCopy != 0U)
+ {
+ bytesToCopy = MIN(bytesToReceive, bytesToCopy);
+ bytesToReceive -= bytesToCopy;
+ /* Copy data from ring buffer to user memory. */
+ for (i = 0U; i < bytesToCopy; i++)
+ {
+ xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail];
+ /* Wrap to 0. Not use modulo (%) because it might be large and slow. */
+ if ((size_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
+ {
+ handle->rxRingBufferTail = 0U;
+ }
+ else
+ {
+ handle->rxRingBufferTail++;
+ }
+ }
+ }
+ /* If ring buffer does not have enough data, still need to read more data. */
+ if (bytesToReceive != 0U)
+ {
+ /* No data in ring buffer, save the request to UART handle. */
+ handle->rxData = xfer->data + bytesCurrentReceived;
+ handle->rxDataSize = bytesToReceive;
+ handle->rxDataSizeAll = bytesToReceive;
+ handle->rxState = (uint8_t)kUSART_RxBusy;
+ }
+ /* Enable IRQ if previously enabled. */
+ EnableGlobalIRQ(regPrimask);
+ /* Call user callback since all data are received. */
+ if (0U == bytesToReceive)
+ {
+ if (handle->callback != NULL)
+ {
+ handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData);
+ }
+ }
+ }
+ /* Ring buffer not used. */
+ else
+ {
+ handle->rxData = xfer->data + bytesCurrentReceived;
+ handle->rxDataSize = bytesToReceive;
+ handle->rxDataSizeAll = bytesToReceive;
+ handle->rxState = (uint8_t)kUSART_RxBusy;
+
+ /* Enable RX interrupt. */
+ base->FIFOINTENSET |= USART_FIFOINTENSET_RXLVL_MASK;
+ }
+ /* Return the how many bytes have read. */
+ if (receivedBytes != NULL)
+ {
+ *receivedBytes = bytesCurrentReceived;
+ }
+ }
+ return kStatus_Success;
+}
+
+/*!
+ * brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
+ * how many bytes not received yet.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle)
+{
+ assert(NULL != handle);
+
+ /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */
+ if (NULL == handle->rxRingBuffer)
+ {
+ /* Disable interrupts */
+ USART_DisableInterrupts(base, (uint32_t)kUSART_RxLevelInterruptEnable);
+ /* Empty rxFIFO */
+ base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+ }
+
+ handle->rxDataSize = 0U;
+ handle->rxState = (uint8_t)kUSART_RxIdle;
+}
+
+/*!
+ * brief Get the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ * param count Receive bytes count.
+ * retval kStatus_NoTransferInProgress No receive in progress.
+ * retval kStatus_InvalidArgument Parameter is invalid.
+ * retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count)
+{
+ assert(NULL != handle);
+ assert(NULL != count);
+
+ if ((uint8_t)kUSART_RxIdle == handle->rxState)
+ {
+ return kStatus_NoTransferInProgress;
+ }
+
+ *count = handle->rxDataSizeAll - handle->rxDataSize;
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief USART IRQ handle function.
+ *
+ * This function handles the USART transmit and receive IRQ request.
+ *
+ * param base USART peripheral base address.
+ * param handle USART handle pointer.
+ */
+void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle)
+{
+ /* Check arguments */
+ assert((NULL != base) && (NULL != handle));
+
+ bool receiveEnabled = ((handle->rxDataSize != 0U) || (handle->rxRingBuffer != NULL));
+ bool sendEnabled = (handle->txDataSize != 0U);
+ uint8_t rxdata;
+ size_t tmpsize;
+
+ /* If RX overrun. */
+ if ((base->FIFOSTAT & USART_FIFOSTAT_RXERR_MASK) != 0U)
+ {
+ /* Clear rx error state. */
+ base->FIFOSTAT |= USART_FIFOSTAT_RXERR_MASK;
+ /* clear rxFIFO */
+ base->FIFOCFG |= USART_FIFOCFG_EMPTYRX_MASK;
+ /* Trigger callback. */
+ if (handle->callback != NULL)
+ {
+ handle->callback(base, handle, kStatus_USART_RxError, handle->userData);
+ }
+ }
+ while ((receiveEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) != 0U)) ||
+ (sendEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK) != 0U)))
+ {
+ /* Receive data */
+ if (receiveEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_RXNOTEMPTY_MASK) != 0U))
+ {
+ /* Receive to app bufffer if app buffer is present */
+ if (handle->rxDataSize != 0U)
+ {
+ rxdata = (uint8_t)base->FIFORD;
+ *handle->rxData = rxdata;
+ handle->rxDataSize--;
+ handle->rxData++;
+ receiveEnabled = ((handle->rxDataSize != 0U) || (handle->rxRingBuffer != NULL));
+ if (0U == handle->rxDataSize)
+ {
+ if (NULL == handle->rxRingBuffer)
+ {
+ base->FIFOINTENCLR = USART_FIFOINTENCLR_RXLVL_MASK | USART_FIFOINTENSET_RXERR_MASK;
+ }
+ handle->rxState = (uint8_t)kUSART_RxIdle;
+ if (handle->callback != NULL)
+ {
+ handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData);
+ }
+ }
+ }
+ /* Otherwise receive to ring buffer if ring buffer is present */
+ else
+ {
+ if (handle->rxRingBuffer != NULL)
+ {
+ /* If RX ring buffer is full, trigger callback to notify over run. */
+ if (USART_TransferIsRxRingBufferFull(handle))
+ {
+ if (handle->callback != NULL)
+ {
+ handle->callback(base, handle, kStatus_USART_RxRingBufferOverrun, handle->userData);
+ }
+ }
+ /* If ring buffer is still full after callback function, the oldest data is overridden. */
+ if (USART_TransferIsRxRingBufferFull(handle))
+ {
+ /* Increase handle->rxRingBufferTail to make room for new data. */
+ if ((size_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize)
+ {
+ handle->rxRingBufferTail = 0U;
+ }
+ else
+ {
+ handle->rxRingBufferTail++;
+ }
+ }
+ /* Read data. */
+ rxdata = (uint8_t)base->FIFORD;
+ handle->rxRingBuffer[handle->rxRingBufferHead] = rxdata;
+ /* Increase handle->rxRingBufferHead. */
+ if ((size_t)handle->rxRingBufferHead + 1U == handle->rxRingBufferSize)
+ {
+ handle->rxRingBufferHead = 0U;
+ }
+ else
+ {
+ handle->rxRingBufferHead++;
+ }
+ }
+ }
+ }
+ /* Send data */
+ if (sendEnabled && ((base->FIFOSTAT & USART_FIFOSTAT_TXNOTFULL_MASK) != 0U))
+ {
+ base->FIFOWR = *handle->txData;
+ handle->txDataSize--;
+ handle->txData++;
+ sendEnabled = handle->txDataSize != 0U;
+ if (!sendEnabled)
+ {
+ base->FIFOINTENCLR = USART_FIFOINTENCLR_TXLVL_MASK;
+ handle->txState = (uint8_t)kUSART_TxIdle;
+
+ base->INTENSET |= USART_INTENSET_TXIDLEEN_MASK;
+ }
+ }
+ }
+
+ /* Tx idle and the interrupt is enabled. */
+ if ((0U != (base->INTENSET & USART_INTENSET_TXIDLEEN_MASK)) &&
+ (0U != (base->INTSTAT & USART_INTSTAT_TXIDLE_MASK)) && (handle->txState == (uint8_t)kUSART_TxIdle))
+ {
+ /* Disable tx idle interrupt */
+ base->INTENCLR |= USART_INTENCLR_TXIDLECLR_MASK;
+ /* Trigger callback. */
+ if (handle->callback != NULL)
+ {
+ handle->callback(base, handle, kStatus_USART_TxIdle, handle->userData);
+ }
+ }
+
+ /* ring buffer is not used */
+ if (NULL == handle->rxRingBuffer)
+ {
+ tmpsize = handle->rxDataSize;
+
+ /* restore if rx transfer ends and rxLevel is different from default value */
+ if ((tmpsize == 0U) && (USART_FIFOTRIG_RXLVL_GET(base) != handle->rxWatermark))
+ {
+ base->FIFOTRIG =
+ (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | USART_FIFOTRIG_RXLVL(handle->rxWatermark);
+ }
+ /* decrease level if rx transfer is bellow */
+ if ((tmpsize != 0U) && (tmpsize < (USART_FIFOTRIG_RXLVL_GET(base) + 1U)))
+ {
+ base->FIFOTRIG = (base->FIFOTRIG & (~USART_FIFOTRIG_RXLVL_MASK)) | (USART_FIFOTRIG_RXLVL(tmpsize - 1U));
+ }
+ }
+}
diff --git a/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_usart.h b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_usart.h
new file mode 100644
index 000000000..b97ae487b
--- /dev/null
+++ b/FreeRTOS/Demo/CORTEX_MPU_LPC54018_MCUXpresso/NXP_Code/drivers/fsl_usart.h
@@ -0,0 +1,721 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _FSL_USART_H_
+#define _FSL_USART_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup usart_driver
+ * @{
+ */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief USART driver version 2.1.1. */
+#define FSL_USART_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
+/*@}*/
+
+#define USART_FIFOTRIG_TXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_TXLVL_MASK) >> USART_FIFOTRIG_TXLVL_SHIFT)
+#define USART_FIFOTRIG_RXLVL_GET(base) (((base)->FIFOTRIG & USART_FIFOTRIG_RXLVL_MASK) >> USART_FIFOTRIG_RXLVL_SHIFT)
+
+/*! @brief Error codes for the USART driver. */
+enum
+{
+ kStatus_USART_TxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 0), /*!< Transmitter is busy. */
+ kStatus_USART_RxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 1), /*!< Receiver is busy. */
+ kStatus_USART_TxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 2), /*!< USART transmitter is idle. */
+ kStatus_USART_RxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 3), /*!< USART receiver is idle. */
+ kStatus_USART_TxError = MAKE_STATUS(kStatusGroup_LPC_USART, 7), /*!< Error happens on txFIFO. */
+ kStatus_USART_RxError = MAKE_STATUS(kStatusGroup_LPC_USART, 9), /*!< Error happens on rxFIFO. */
+ kStatus_USART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_LPC_USART, 8), /*!< Error happens on rx ring buffer */
+ kStatus_USART_NoiseError = MAKE_STATUS(kStatusGroup_LPC_USART, 10), /*!< USART noise error. */
+ kStatus_USART_FramingError = MAKE_STATUS(kStatusGroup_LPC_USART, 11), /*!< USART framing error. */
+ kStatus_USART_ParityError = MAKE_STATUS(kStatusGroup_LPC_USART, 12), /*!< USART parity error. */
+ kStatus_USART_BaudrateNotSupport =
+ MAKE_STATUS(kStatusGroup_LPC_USART, 13), /*!< Baudrate is not support in current clock source */
+};
+
+/*! @brief USART synchronous mode. */
+typedef enum _usart_sync_mode
+{
+ kUSART_SyncModeDisabled = 0x0U, /*!< Asynchronous mode. */
+ kUSART_SyncModeSlave = 0x2U, /*!< Synchronous slave mode. */
+ kUSART_SyncModeMaster = 0x3U, /*!< Synchronous master mode. */
+} usart_sync_mode_t;
+
+/*! @brief USART parity mode. */
+typedef enum _usart_parity_mode
+{
+ kUSART_ParityDisabled = 0x0U, /*!< Parity disabled */
+ kUSART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */
+ kUSART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */
+} usart_parity_mode_t;
+
+/*! @brief USART stop bit count. */
+typedef enum _usart_stop_bit_count
+{
+ kUSART_OneStopBit = 0U, /*!< One stop bit */
+ kUSART_TwoStopBit = 1U, /*!< Two stop bits */
+} usart_stop_bit_count_t;
+
+/*! @brief USART data size. */
+typedef enum _usart_data_len
+{
+ kUSART_7BitsPerChar = 0U, /*!< Seven bit mode */
+ kUSART_8BitsPerChar = 1U, /*!< Eight bit mode */
+} usart_data_len_t;
+
+/*! @brief USART clock polarity configuration, used in sync mode.*/
+typedef enum _usart_clock_polarity
+{
+ kUSART_RxSampleOnFallingEdge = 0x0U, /*!< Un_RXD is sampled on the falling edge of SCLK. */
+ kUSART_RxSampleOnRisingEdge = 0x1U, /*!< Un_RXD is sampled on the rising edge of SCLK. */
+} usart_clock_polarity_t;
+
+/*! @brief txFIFO watermark values */
+typedef enum _usart_txfifo_watermark
+{
+ kUSART_TxFifo0 = 0, /*!< USART tx watermark is empty */
+ kUSART_TxFifo1 = 1, /*!< USART tx watermark at 1 item */
+ kUSART_TxFifo2 = 2, /*!< USART tx watermark at 2 items */
+ kUSART_TxFifo3 = 3, /*!< USART tx watermark at 3 items */
+ kUSART_TxFifo4 = 4, /*!< USART tx watermark at 4 items */
+ kUSART_TxFifo5 = 5, /*!< USART tx watermark at 5 items */
+ kUSART_TxFifo6 = 6, /*!< USART tx watermark at 6 items */
+ kUSART_TxFifo7 = 7, /*!< USART tx watermark at 7 items */
+} usart_txfifo_watermark_t;
+
+/*! @brief rxFIFO watermark values */
+typedef enum _usart_rxfifo_watermark
+{
+ kUSART_RxFifo1 = 0, /*!< USART rx watermark at 1 item */
+ kUSART_RxFifo2 = 1, /*!< USART rx watermark at 2 items */
+ kUSART_RxFifo3 = 2, /*!< USART rx watermark at 3 items */
+ kUSART_RxFifo4 = 3, /*!< USART rx watermark at 4 items */
+ kUSART_RxFifo5 = 4, /*!< USART rx watermark at 5 items */
+ kUSART_RxFifo6 = 5, /*!< USART rx watermark at 6 items */
+ kUSART_RxFifo7 = 6, /*!< USART rx watermark at 7 items */
+ kUSART_RxFifo8 = 7, /*!< USART rx watermark at 8 items */
+} usart_rxfifo_watermark_t;
+
+/*!
+ * @brief USART interrupt configuration structure, default settings all disabled.
+ */
+enum _usart_interrupt_enable
+{
+ kUSART_TxErrorInterruptEnable = (USART_FIFOINTENSET_TXERR_MASK),
+ kUSART_RxErrorInterruptEnable = (USART_FIFOINTENSET_RXERR_MASK),
+ kUSART_TxLevelInterruptEnable = (USART_FIFOINTENSET_TXLVL_MASK),
+ kUSART_RxLevelInterruptEnable = (USART_FIFOINTENSET_RXLVL_MASK),
+};
+
+/*!
+ * @brief USART status flags.
+ *
+ * This provides constants for the USART status flags for use in the USART functions.
+ */
+enum _usart_flags
+{
+ kUSART_TxError = (USART_FIFOSTAT_TXERR_MASK), /*!< TEERR bit, sets if TX buffer is error */
+ kUSART_RxError = (USART_FIFOSTAT_RXERR_MASK), /*!< RXERR bit, sets if RX buffer is error */
+ kUSART_TxFifoEmptyFlag = (USART_FIFOSTAT_TXEMPTY_MASK), /*!< TXEMPTY bit, sets if TX buffer is empty */
+ kUSART_TxFifoNotFullFlag = (USART_FIFOSTAT_TXNOTFULL_MASK), /*!< TXNOTFULL bit, sets if TX buffer is not full */
+ kUSART_RxFifoNotEmptyFlag = (USART_FIFOSTAT_RXNOTEMPTY_MASK), /*!< RXNOEMPTY bit, sets if RX buffer is not empty */
+ kUSART_RxFifoFullFlag = (USART_FIFOSTAT_RXFULL_MASK), /*!< RXFULL bit, sets if RX buffer is full */
+};
+
+/*! @brief USART configuration structure. */
+typedef struct _usart_config
+{
+ uint32_t baudRate_Bps; /*!< USART baud rate */
+ usart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
+ usart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
+ usart_data_len_t bitCountPerChar; /*!< Data length - 7 bit, 8 bit */
+ bool loopback; /*!< Enable peripheral loopback */
+ bool enableRx; /*!< Enable RX */
+ bool enableTx; /*!< Enable TX */
+ bool enableContinuousSCLK; /*!< USART continuous Clock generation enable in synchronous master mode. */
+ usart_txfifo_watermark_t txWatermark; /*!< txFIFO watermark */
+ usart_rxfifo_watermark_t rxWatermark; /*!< rxFIFO watermark */
+ usart_sync_mode_t syncMode; /*!< Transfer mode select - asynchronous, synchronous master, synchronous slave. */
+ usart_clock_polarity_t clockPolarity; /*!< Selects the clock polarity and sampling edge in synchronous mode. */
+} usart_config_t;
+
+/*! @brief USART transfer structure. */
+typedef struct _usart_transfer
+{
+ uint8_t *data; /*!< The buffer of data to be transfer.*/
+ size_t dataSize; /*!< The byte count to be transfer. */
+} usart_transfer_t;
+
+/* Forward declaration of the handle typedef. */
+typedef struct _usart_handle usart_handle_t;
+
+/*! @brief USART transfer callback function. */
+typedef void (*usart_transfer_callback_t)(USART_Type *base, usart_handle_t *handle, status_t status, void *userData);
+
+/*! @brief USART handle structure. */
+struct _usart_handle
+{
+ uint8_t *volatile txData; /*!< Address of remaining data to send. */
+ volatile size_t txDataSize; /*!< Size of the remaining data to send. */
+ size_t txDataSizeAll; /*!< Size of the data to send out. */
+ uint8_t *volatile rxData; /*!< Address of remaining data to receive. */
+ volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */
+ size_t rxDataSizeAll; /*!< Size of the data to receive. */
+
+ uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */
+ size_t rxRingBufferSize; /*!< Size of the ring buffer. */
+ volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */
+ volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */
+
+ usart_transfer_callback_t callback; /*!< Callback function. */
+ void *userData; /*!< USART callback function parameter.*/
+
+ volatile uint8_t txState; /*!< TX transfer state. */
+ volatile uint8_t rxState; /*!< RX transfer state */
+
+ uint8_t txWatermark; /*!< txFIFO watermark */
+ uint8_t rxWatermark; /*!< rxFIFO watermark */
+};
+
+/*! @brief Typedef for usart interrupt handler. */
+typedef void (*flexcomm_usart_irq_handler_t)(USART_Type *base, usart_handle_t *handle);
+
+/*******************************************************************************
+ * API
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* _cplusplus */
+
+/*! @brief Returns instance number for USART peripheral base address. */
+uint32_t USART_GetInstance(USART_Type *base);
+
+/*!
+ * @name Initialization and deinitialization
+ * @{
+ */
+
+/*!
+ * @brief Initializes a USART instance with user configuration structure and peripheral clock.
+ *
+ * This function configures the USART module with the user-defined settings. The user can configure the configuration
+ * structure and also get the default configuration by using the USART_GetDefaultConfig() function.
+ * Example below shows how to use this API to configure USART.
+ * @code
+ * usart_config_t usartConfig;
+ * usartConfig.baudRate_Bps = 115200U;
+ * usartConfig.parityMode = kUSART_ParityDisabled;
+ * usartConfig.stopBitCount = kUSART_OneStopBit;
+ * USART_Init(USART1, &usartConfig, 20000000U);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param config Pointer to user-defined configuration structure.
+ * @param srcClock_Hz USART clock source frequency in HZ.
+ * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * @retval kStatus_InvalidArgument USART base address is not valid
+ * @retval kStatus_Success Status USART initialize succeed
+ */
+status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz);
+
+/*!
+ * @brief Deinitializes a USART instance.
+ *
+ * This function waits for TX complete, disables TX and RX, and disables the USART clock.
+ *
+ * @param base USART peripheral base address.
+ */
+void USART_Deinit(USART_Type *base);
+
+/*!
+ * @brief Gets the default configuration structure.
+ *
+ * This function initializes the USART configuration structure to a default value. The default
+ * values are:
+ * usartConfig->baudRate_Bps = 115200U;
+ * usartConfig->parityMode = kUSART_ParityDisabled;
+ * usartConfig->stopBitCount = kUSART_OneStopBit;
+ * usartConfig->bitCountPerChar = kUSART_8BitsPerChar;
+ * usartConfig->loopback = false;
+ * usartConfig->enableTx = false;
+ * usartConfig->enableRx = false;
+ *
+ * @param config Pointer to configuration structure.
+ */
+void USART_GetDefaultConfig(usart_config_t *config);
+
+/*!
+ * @brief Sets the USART instance baud rate.
+ *
+ * This function configures the USART module baud rate. This function is used to update
+ * the USART module baud rate after the USART module is initialized by the USART_Init.
+ * @code
+ * USART_SetBaudRate(USART1, 115200U, 20000000U);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param baudrate_Bps USART baudrate to be set.
+ * @param srcClock_Hz USART clock source frequency in HZ.
+ * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source.
+ * @retval kStatus_Success Set baudrate succeed.
+ * @retval kStatus_InvalidArgument One or more arguments are invalid.
+ */
+status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz);
+
+/* @} */
+
+/*!
+ * @name Status
+ * @{
+ */
+
+/*!
+ * @brief Get USART status flags.
+ *
+ * This function get all USART status flags, the flags are returned as the logical
+ * OR value of the enumerators @ref _usart_flags. To check a specific status,
+ * compare the return value with enumerators in @ref _usart_flags.
+ * For example, to check whether the TX is empty:
+ * @code
+ * if (kUSART_TxFifoNotFullFlag & USART_GetStatusFlags(USART1))
+ * {
+ * ...
+ * }
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @return USART status flags which are ORed by the enumerators in the _usart_flags.
+ */
+static inline uint32_t USART_GetStatusFlags(USART_Type *base)
+{
+ return base->FIFOSTAT;
+}
+
+/*!
+ * @brief Clear USART status flags.
+ *
+ * This function clear supported USART status flags
+ * Flags that can be cleared or set are:
+ * kUSART_TxError
+ * kUSART_RxError
+ * For example:
+ * @code
+ * USART_ClearStatusFlags(USART1, kUSART_TxError | kUSART_RxError)
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param mask status flags to be cleared.
+ */
+static inline void USART_ClearStatusFlags(USART_Type *base, uint32_t mask)
+{
+ /* Only TXERR, RXERR fields support write. Remaining fields should be set to zero */
+ base->FIFOSTAT = mask & (USART_FIFOSTAT_TXERR_MASK | USART_FIFOSTAT_RXERR_MASK);
+}
+
+/* @} */
+
+/*!
+ * @name Interrupts
+ * @{
+ */
+
+/*!
+ * @brief Enables USART interrupts according to the provided mask.
+ *
+ * This function enables the USART interrupts according to the provided mask. The mask
+ * is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
+ * For example, to enable TX empty interrupt and RX full interrupt:
+ * @code
+ * USART_EnableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param mask The interrupts to enable. Logical OR of @ref _usart_interrupt_enable.
+ */
+static inline void USART_EnableInterrupts(USART_Type *base, uint32_t mask)
+{
+ base->FIFOINTENSET = mask & 0xFUL;
+}
+
+/*!
+ * @brief Disables USART interrupts according to a provided mask.
+ *
+ * This function disables the USART interrupts according to a provided mask. The mask
+ * is a logical OR of enumeration members. See @ref _usart_interrupt_enable.
+ * This example shows how to disable the TX empty interrupt and RX full interrupt:
+ * @code
+ * USART_DisableInterrupts(USART1, kUSART_TxLevelInterruptEnable | kUSART_RxLevelInterruptEnable);
+ * @endcode
+ *
+ * @param base USART peripheral base address.
+ * @param mask The interrupts to disable. Logical OR of @ref _usart_interrupt_enable.
+ */
+static inline void USART_DisableInterrupts(USART_Type *base, uint32_t mask)
+{
+ base->FIFOINTENCLR = mask & 0xFUL;
+}
+
+/*!
+ * @brief Returns enabled USART interrupts.
+ *
+ * This function returns the enabled USART interrupts.
+ *
+ * @param base USART peripheral base address.
+ */
+static inline uint32_t USART_GetEnabledInterrupts(USART_Type *base)
+{
+ return base->FIFOINTENSET;
+}
+
+/*!
+ * @brief Enable DMA for Tx
+ */
+static inline void USART_EnableTxDMA(USART_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->FIFOCFG |= USART_FIFOCFG_DMATX_MASK;
+ }
+ else
+ {
+ base->FIFOCFG &= ~(USART_FIFOCFG_DMATX_MASK);
+ }
+}
+
+/*!
+ * @brief Enable DMA for Rx
+ */
+static inline void USART_EnableRxDMA(USART_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->FIFOCFG |= USART_FIFOCFG_DMARX_MASK;
+ }
+ else
+ {
+ base->FIFOCFG &= ~(USART_FIFOCFG_DMARX_MASK);
+ }
+}
+
+/*!
+ * @brief Enable CTS.
+ * This function will determine whether CTS is used for flow control.
+ *
+ * @param base USART peripheral base address.
+ * @param enable Enable CTS or not, true for enable and false for disable.
+ */
+static inline void USART_EnableCTS(USART_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->CFG |= USART_CFG_CTSEN_MASK;
+ }
+ else
+ {
+ base->CFG &= ~USART_CFG_CTSEN_MASK;
+ }
+}
+
+/*!
+ * @brief Continuous Clock generation.
+ * By default, SCLK is only output while data is being transmitted in synchronous mode.
+ * Enable this funciton, SCLK will run continuously in synchronous mode, allowing
+ * characters to be received on Un_RxD independently from transmission on Un_TXD).
+ *
+ * @param base USART peripheral base address.
+ * @param enable Enable Continuous Clock generation mode or not, true for enable and false for disable.
+ */
+static inline void USART_EnableContinuousSCLK(USART_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->CTL |= USART_CTL_CC_MASK;
+ }
+ else
+ {
+ base->CTL &= ~USART_CTL_CC_MASK;
+ }
+}
+
+/*!
+ * @brief Enable Continuous Clock generation bit auto clear.
+ * While enable this cuntion, the Continuous Clock bit is automatically cleared when a complete
+ * character has been received. This bit is cleared at the same time.
+ *
+ * @param base USART peripheral base address.
+ * @param enable Enable auto clear or not, true for enable and false for disable.
+ */
+static inline void USART_EnableAutoClearSCLK(USART_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->CTL |= USART_CTL_CLRCCONRX_MASK;
+ }
+ else
+ {
+ base->CTL &= ~USART_CTL_CLRCCONRX_MASK;
+ }
+}
+/* @} */
+
+/*!
+ * @name Bus Operations
+ * @{
+ */
+
+/*!
+ * @brief Writes to the FIFOWR register.
+ *
+ * This function writes data to the txFIFO directly. The upper layer must ensure
+ * that txFIFO has space for data to write before calling this function.
+ *
+ * @param base USART peripheral base address.
+ * @param data The byte to write.
+ */
+static inline void USART_WriteByte(USART_Type *base, uint8_t data)
+{
+ base->FIFOWR = data;
+}
+
+/*!
+ * @brief Reads the FIFORD register directly.
+ *
+ * This function reads data from the rxFIFO directly. The upper layer must
+ * ensure that the rxFIFO is not empty before calling this function.
+ *
+ * @param base USART peripheral base address.
+ * @return The byte read from USART data register.
+ */
+static inline uint8_t USART_ReadByte(USART_Type *base)
+{
+ return (uint8_t)base->FIFORD;
+}
+
+/*!
+ * @brief Writes to the TX register using a blocking method.
+ *
+ * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO
+ * to have room and writes data to the TX buffer.
+ *
+ * @param base USART peripheral base address.
+ * @param data Start address of the data to write.
+ * @param length Size of the data to write.
+ */
+void USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length);
+
+/*!
+ * @brief Read RX data register using a blocking method.
+ *
+ * This function polls the RX register, waits for the RX register to be full or for RX FIFO to
+ * have data and read data from the TX register.
+ *
+ * @param base USART peripheral base address.
+ * @param data Start address of the buffer to store the received data.
+ * @param length Size of the buffer.
+ * @retval kStatus_USART_FramingError Receiver overrun happened while receiving data.
+ * @retval kStatus_USART_ParityError Noise error happened while receiving data.
+ * @retval kStatus_USART_NoiseError Framing error happened while receiving data.
+ * @retval kStatus_USART_RxError Overflow or underflow rxFIFO happened.
+ * @retval kStatus_Success Successfully received all data.
+ */
+status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length);
+
+/* @} */
+
+/*!
+ * @name Transactional
+ * @{
+ */
+
+/*!
+ * @brief Initializes the USART handle.
+ *
+ * This function initializes the USART handle which can be used for other USART
+ * transactional APIs. Usually, for a specified USART instance,
+ * call this API once to get the initialized handle.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param callback The callback function.
+ * @param userData The parameter of the callback function.
+ */
+status_t USART_TransferCreateHandle(USART_Type *base,
+ usart_handle_t *handle,
+ usart_transfer_callback_t callback,
+ void *userData);
+
+/*!
+ * @brief Transmits a buffer of data using the interrupt method.
+ *
+ * This function sends data using an interrupt method. This is a non-blocking function, which
+ * returns directly without waiting for all data to be written to the TX register. When
+ * all data is written to the TX register in the IRQ handler, the USART driver calls the callback
+ * function and passes the @ref kStatus_USART_TxIdle as status parameter.
+ *
+ * @note The kStatus_USART_TxIdle is passed to the upper layer when all data is written
+ * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX,
+ * check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param xfer USART transfer structure. See #usart_transfer_t.
+ * @retval kStatus_Success Successfully start the data transmission.
+ * @retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet.
+ * @retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer);
+
+/*!
+ * @brief Sets up the RX ring buffer.
+ *
+ * This function sets up the RX ring buffer to a specific USART handle.
+ *
+ * When the RX ring buffer is used, data received are stored into the ring buffer even when the
+ * user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received
+ * in the ring buffer, the user can get the received data from the ring buffer directly.
+ *
+ * @note When using the RX ring buffer, one byte is reserved for internal use. In other
+ * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer.
+ * @param ringBufferSize size of the ring buffer.
+ */
+void USART_TransferStartRingBuffer(USART_Type *base,
+ usart_handle_t *handle,
+ uint8_t *ringBuffer,
+ size_t ringBufferSize);
+
+/*!
+ * @brief Aborts the background transfer and uninstalls the ring buffer.
+ *
+ * This function aborts the background transfer and uninstalls the ring buffer.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle);
+
+/*!
+ * @brief Get the length of received data in RX ring buffer.
+ *
+ * @param handle USART handle pointer.
+ * @return Length of received data in RX ring buffer.
+ */
+size_t USART_TransferGetRxRingBufferLength(usart_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.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle);
+
+/*!
+ * @brief Get the number of bytes that have been written to USART TX register.
+ *
+ * This function gets the number of bytes that have been written to USART TX
+ * register by interrupt method.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param count Send bytes count.
+ * @retval kStatus_NoTransferInProgress No send in progress.
+ * @retval kStatus_InvalidArgument Parameter is invalid.
+ * @retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
+
+/*!
+ * @brief Receives a buffer of data using an interrupt method.
+ *
+ * This function receives data using an interrupt method. This is a non-blocking function, which
+ * returns without waiting for all data to be received.
+ * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and
+ * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer.
+ * After copying, if the data in the ring buffer is not enough to read, the receive
+ * request is saved by the USART driver. When the new data arrives, the receive request
+ * is serviced first. When all data is received, the USART driver notifies the upper layer
+ * through a callback function and passes the status parameter @ref kStatus_USART_RxIdle.
+ * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer.
+ * The 5 bytes are copied to the xfer->data and this function returns with the
+ * parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is
+ * saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer.
+ * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt
+ * to receive data to the xfer->data. When all data is received, the upper layer is notified.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param xfer USART transfer structure, see #usart_transfer_t.
+ * @param receivedBytes Bytes received from the ring buffer directly.
+ * @retval kStatus_Success Successfully queue the transfer into transmit queue.
+ * @retval kStatus_USART_RxBusy Previous receive request is not finished.
+ * @retval kStatus_InvalidArgument Invalid argument.
+ */
+status_t USART_TransferReceiveNonBlocking(USART_Type *base,
+ usart_handle_t *handle,
+ usart_transfer_t *xfer,
+ size_t *receivedBytes);
+
+/*!
+ * @brief Aborts the interrupt-driven data receiving.
+ *
+ * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out
+ * how many bytes not received yet.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle);
+
+/*!
+ * @brief Get the number of bytes that have been received.
+ *
+ * This function gets the number of bytes that have been received.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ * @param count Receive bytes count.
+ * @retval kStatus_NoTransferInProgress No receive in progress.
+ * @retval kStatus_InvalidArgument Parameter is invalid.
+ * @retval kStatus_Success Get successfully through the parameter \p count;
+ */
+status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count);
+
+/*!
+ * @brief USART IRQ handle function.
+ *
+ * This function handles the USART transmit and receive IRQ request.
+ *
+ * @param base USART peripheral base address.
+ * @param handle USART handle pointer.
+ */
+void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle);
+
+/* @} */
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*! @}*/
+
+#endif /* _FSL_USART_H_ */