summaryrefslogtreecommitdiffstats
path: root/bsps/arm/imxrt/nxp
diff options
context:
space:
mode:
authorChristian Mauderer <christian.mauderer@embedded-brains.de>2020-10-12 13:40:30 +0200
committerChristian Mauderer <christian.mauderer@embedded-brains.de>2020-11-20 08:53:18 +0100
commit48f6a6c302a3e1a3f8915e2503d0fe618d1af285 (patch)
treeb5d570ddd5e432519c5a9d42b4cf6725d8161551 /bsps/arm/imxrt/nxp
parentb169095c7dfd106a9c0c3d47e9f1c640ac3377d2 (diff)
downloadrtems-48f6a6c302a3e1a3f8915e2503d0fe618d1af285.tar.bz2
bsp/imxrt: Import files from MCUXpresso SDK V2.8.5
The following files have been imported: cp ${SDK}/boards/evkbimxrt1050/project_template/clock_config.c nxp/boards/evkbimxrt1050 cp ${SDK}/boards/evkbimxrt1050/project_template/clock_config.h include/fsl_clock_config.h cp ${SDK}/boards/evkbimxrt1050/project_template/dcd.c start/flash-dcd.c cp ${SDK}/boards/evkbimxrt1050/project_template/pin_mux.c nxp/boards/evkbimxrt1050 cp ${SDK}/boards/evkbimxrt1050/project_template/pin_mux.h include/fsl_pin_mux.h cp ${SDK}/boards/evkbimxrt1050/xip/evkbimxrt1050_flexspi_nor_config.h include/fsl_flexspi_nor_config.h cp ${SDK}/devices/MIMXRT1052/MIMXRT1052.h include cp ${SDK}/devices/MIMXRT1052/MIMXRT1052_features.h include cp ${SDK}/devices/MIMXRT1052/drivers/fsl_*.c nxp/devices/MIMXRT1052/drivers cp ${SDK}/devices/MIMXRT1052/drivers/fsl_*.h include cp ${SDK}/devices/MIMXRT1052/fsl_device_registers.h include cp ${SDK}/devices/MIMXRT1052/system_MIMXRT1052.h include/ cp ${SDK}/devices/MIMXRT1052/xip/fsl_flexspi_nor_boot.c nxp/devices/MIMXRT1052/xip/fsl_flexspi_nor_boot.c cp ${SDK}/devices/MIMXRT1052/xip/fsl_flexspi_nor_boot.h include Update #4180
Diffstat (limited to 'bsps/arm/imxrt/nxp')
-rw-r--r--bsps/arm/imxrt/nxp/boards/evkbimxrt1050/clock_config.c471
-rw-r--r--bsps/arm/imxrt/nxp/boards/evkbimxrt1050/pin_mux.c1094
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc.c395
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc_etc.c433
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aipstz.c51
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aoi.c214
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c303
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cache.c602
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_clock.c1250
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cmp.c371
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_common.c280
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_csi.c1395
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcdc.c534
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcp.c1461
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dmamux.c91
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_edma.c2849
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_elcdif.c386
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enc.c593
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enet.c3389
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ewm.c140
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexcan.c3564
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio.c424
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_camera.c215
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_camera_edma.c248
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2c_master.c1258
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2s.c903
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2s_edma.c447
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_mculcd.c1293
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_mculcd_edma.c564
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_spi.c1326
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_spi_edma.c474
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_uart.c991
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_uart_edma.c407
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexram.c94
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexram_allocate.c157
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexspi.c1105
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpc.c103
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpio.c171
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpt.c127
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_kpp.c203
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpi2c.c2315
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpi2c_edma.c518
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpspi.c2221
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpspi_edma.c1154
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpuart.c2051
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpuart_edma.c444
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ocotp.c263
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pit.c146
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pmu.c55
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pwm.c935
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pxp.c1050
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_qtmr.c612
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_rtwdog.c148
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_sai.c3764
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_sai_edma.c707
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_semc.c1148
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_snvs_hp.c573
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_snvs_lp.c809
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_spdif.c828
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_spdif_edma.c598
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_src.c49
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_tempmon.c195
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_trng.c1935
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_tsc.c260
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_usdhc.c2126
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_wdog.c214
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_xbara.c229
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_xbarb.c126
-rw-r--r--bsps/arm/imxrt/nxp/devices/MIMXRT1052/xip/fsl_flexspi_nor_boot.c51
69 files changed, 55900 insertions, 0 deletions
diff --git a/bsps/arm/imxrt/nxp/boards/evkbimxrt1050/clock_config.c b/bsps/arm/imxrt/nxp/boards/evkbimxrt1050/clock_config.c
new file mode 100644
index 0000000000..2ed6638cbe
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/boards/evkbimxrt1050/clock_config.c
@@ -0,0 +1,471 @@
+/*
+ * Copyright 2017-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * How to setup clock using clock driver functions:
+ *
+ * 1. Call CLOCK_InitXXXPLL() to configure corresponding PLL clock.
+ *
+ * 2. Call CLOCK_InitXXXpfd() to configure corresponding PLL pfd clock.
+ *
+ * 3. Call CLOCK_SetMux() to configure corresponding clock source for target clock out.
+ *
+ * 4. Call CLOCK_SetDiv() to configure corresponding clock divider for target clock out.
+ *
+ * 5. Call CLOCK_SetXtalFreq() to set XTAL frequency based on board settings.
+ *
+ */
+
+/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+!!GlobalInfo
+product: Clocks v5.0
+processor: MIMXRT1052xxxxB
+package_id: MIMXRT1052DVL6B
+mcu_data: ksdk2_0
+processor_version: 0.0.0
+board: IMXRT1050-EVKB
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
+
+#include "clock_config.h"
+#include "fsl_iomuxc.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/* System clock frequency. */
+extern uint32_t SystemCoreClock;
+
+/*******************************************************************************
+ ************************ BOARD_InitBootClocks function ************************
+ ******************************************************************************/
+void BOARD_InitBootClocks(void)
+{
+ BOARD_BootClockRUN();
+}
+
+/*******************************************************************************
+ ********************** Configuration BOARD_BootClockRUN ***********************
+ ******************************************************************************/
+/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+!!Configuration
+name: BOARD_BootClockRUN
+called_from_default_init: true
+outputs:
+- {id: AHB_CLK_ROOT.outFreq, value: 600 MHz}
+- {id: CAN_CLK_ROOT.outFreq, value: 40 MHz}
+- {id: CKIL_SYNC_CLK_ROOT.outFreq, value: 32.768 kHz}
+- {id: CLK_1M.outFreq, value: 1 MHz}
+- {id: CLK_24M.outFreq, value: 24 MHz}
+- {id: CSI_CLK_ROOT.outFreq, value: 12 MHz}
+- {id: ENET1_TX_CLK.outFreq, value: 2.4 MHz}
+- {id: ENET_125M_CLK.outFreq, value: 2.4 MHz}
+- {id: ENET_25M_REF_CLK.outFreq, value: 1.2 MHz}
+- {id: FLEXIO1_CLK_ROOT.outFreq, value: 30 MHz}
+- {id: FLEXIO2_CLK_ROOT.outFreq, value: 30 MHz}
+- {id: FLEXSPI_CLK_ROOT.outFreq, value: 160 MHz}
+- {id: GPT1_ipg_clk_highfreq.outFreq, value: 75 MHz}
+- {id: GPT2_ipg_clk_highfreq.outFreq, value: 75 MHz}
+- {id: IPG_CLK_ROOT.outFreq, value: 150 MHz}
+- {id: LCDIF_CLK_ROOT.outFreq, value: 67.5 MHz}
+- {id: LPI2C_CLK_ROOT.outFreq, value: 60 MHz}
+- {id: LPSPI_CLK_ROOT.outFreq, value: 105.6 MHz}
+- {id: LVDS1_CLK.outFreq, value: 1.2 GHz}
+- {id: MQS_MCLK.outFreq, value: 1080/17 MHz}
+- {id: PERCLK_CLK_ROOT.outFreq, value: 75 MHz}
+- {id: PLL7_MAIN_CLK.outFreq, value: 24 MHz}
+- {id: SAI1_CLK_ROOT.outFreq, value: 1080/17 MHz}
+- {id: SAI1_MCLK1.outFreq, value: 1080/17 MHz}
+- {id: SAI1_MCLK2.outFreq, value: 1080/17 MHz}
+- {id: SAI1_MCLK3.outFreq, value: 30 MHz}
+- {id: SAI2_CLK_ROOT.outFreq, value: 1080/17 MHz}
+- {id: SAI2_MCLK1.outFreq, value: 1080/17 MHz}
+- {id: SAI2_MCLK3.outFreq, value: 30 MHz}
+- {id: SAI3_CLK_ROOT.outFreq, value: 1080/17 MHz}
+- {id: SAI3_MCLK1.outFreq, value: 1080/17 MHz}
+- {id: SAI3_MCLK3.outFreq, value: 30 MHz}
+- {id: SEMC_CLK_ROOT.outFreq, value: 75 MHz}
+- {id: SPDIF0_CLK_ROOT.outFreq, value: 30 MHz}
+- {id: TRACE_CLK_ROOT.outFreq, value: 352/3 MHz}
+- {id: UART_CLK_ROOT.outFreq, value: 80 MHz}
+- {id: USDHC1_CLK_ROOT.outFreq, value: 198 MHz}
+- {id: USDHC2_CLK_ROOT.outFreq, value: 198 MHz}
+settings:
+- {id: CCM.AHB_PODF.scale, value: '1', locked: true}
+- {id: CCM.ARM_PODF.scale, value: '2', locked: true}
+- {id: CCM.FLEXSPI_PODF.scale, value: '3', locked: true}
+- {id: CCM.FLEXSPI_SEL.sel, value: CCM.PLL3_SW_CLK_SEL}
+- {id: CCM.LPSPI_PODF.scale, value: '5', locked: true}
+- {id: CCM.PERCLK_PODF.scale, value: '2', locked: true}
+- {id: CCM.SEMC_PODF.scale, value: '8'}
+- {id: CCM.TRACE_PODF.scale, value: '3', locked: true}
+- {id: CCM_ANALOG.PLL1_BYPASS.sel, value: CCM_ANALOG.PLL1}
+- {id: CCM_ANALOG.PLL1_PREDIV.scale, value: '1', locked: true}
+- {id: CCM_ANALOG.PLL1_VDIV.scale, value: '50', locked: true}
+- {id: CCM_ANALOG.PLL2.denom, value: '1', locked: true}
+- {id: CCM_ANALOG.PLL2.num, value: '0', locked: true}
+- {id: CCM_ANALOG.PLL2_BYPASS.sel, value: CCM_ANALOG.PLL2_OUT_CLK}
+- {id: CCM_ANALOG.PLL2_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD0}
+- {id: CCM_ANALOG.PLL2_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD1}
+- {id: CCM_ANALOG.PLL2_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD2}
+- {id: CCM_ANALOG.PLL2_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL2_PFD3}
+- {id: CCM_ANALOG.PLL3_BYPASS.sel, value: CCM_ANALOG.PLL3}
+- {id: CCM_ANALOG.PLL3_PFD0_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD0}
+- {id: CCM_ANALOG.PLL3_PFD0_DIV.scale, value: '33', locked: true}
+- {id: CCM_ANALOG.PLL3_PFD0_MUL.scale, value: '18', locked: true}
+- {id: CCM_ANALOG.PLL3_PFD1_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD1}
+- {id: CCM_ANALOG.PLL3_PFD2_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD2}
+- {id: CCM_ANALOG.PLL3_PFD3_BYPASS.sel, value: CCM_ANALOG.PLL3_PFD3}
+- {id: CCM_ANALOG.PLL4.denom, value: '50'}
+- {id: CCM_ANALOG.PLL4.div, value: '47'}
+- {id: CCM_ANALOG.PLL5.denom, value: '1'}
+- {id: CCM_ANALOG.PLL5.div, value: '40'}
+- {id: CCM_ANALOG.PLL5.num, value: '0'}
+- {id: CCM_ANALOG_PLL_ENET_POWERDOWN_CFG, value: 'Yes'}
+- {id: CCM_ANALOG_PLL_USB1_POWER_CFG, value: 'Yes'}
+sources:
+- {id: XTALOSC24M.OSC.outFreq, value: 24 MHz, enabled: true}
+- {id: XTALOSC24M.RTC_OSC.outFreq, value: 32.768 kHz, enabled: true}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
+
+/*******************************************************************************
+ * Variables for BOARD_BootClockRUN configuration
+ ******************************************************************************/
+const clock_arm_pll_config_t armPllConfig_BOARD_BootClockRUN = {
+ .loopDivider = 100, /* PLL loop divider, Fout = Fin * 50 */
+ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
+};
+const clock_sys_pll_config_t sysPllConfig_BOARD_BootClockRUN = {
+ .loopDivider = 1, /* PLL loop divider, Fout = Fin * ( 20 + loopDivider*2 + numerator / denominator ) */
+ .numerator = 0, /* 30 bit numerator of fractional loop divider */
+ .denominator = 1, /* 30 bit denominator of fractional loop divider */
+ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
+};
+const clock_usb_pll_config_t usb1PllConfig_BOARD_BootClockRUN = {
+ .loopDivider = 0, /* PLL loop divider, Fout = Fin * 20 */
+ .src = 0, /* Bypass clock source, 0 - OSC 24M, 1 - CLK1_P and CLK1_N */
+};
+/*******************************************************************************
+ * Code for BOARD_BootClockRUN configuration
+ ******************************************************************************/
+void BOARD_BootClockRUN(void)
+{
+ /* Init RTC OSC clock frequency. */
+ CLOCK_SetRtcXtalFreq(32768U);
+ /* Enable 1MHz clock output. */
+ XTALOSC24M->OSC_CONFIG2 |= XTALOSC24M_OSC_CONFIG2_ENABLE_1M_MASK;
+ /* Use free 1MHz clock output. */
+ XTALOSC24M->OSC_CONFIG2 &= ~XTALOSC24M_OSC_CONFIG2_MUX_1M_MASK;
+ /* Set XTAL 24MHz clock frequency. */
+ CLOCK_SetXtalFreq(24000000U);
+ /* Enable XTAL 24MHz clock source. */
+ CLOCK_InitExternalClk(0);
+ /* Enable internal RC. */
+ CLOCK_InitRcOsc24M();
+ /* Switch clock source to external OSC. */
+ CLOCK_SwitchOsc(kCLOCK_XtalOsc);
+ /* Set Oscillator ready counter value. */
+ CCM->CCR = (CCM->CCR & (~CCM_CCR_OSCNT_MASK)) | CCM_CCR_OSCNT(127);
+ /* Setting PeriphClk2Mux and PeriphMux to provide stable clock before PLLs are initialed */
+ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 1); /* Set PERIPH_CLK2 MUX to OSC */
+ CLOCK_SetMux(kCLOCK_PeriphMux, 1); /* Set PERIPH_CLK MUX to PERIPH_CLK2 */
+ /* Setting the VDD_SOC to 1.275V. It is necessary to config AHB to 600Mhz. */
+ DCDC->REG3 = (DCDC->REG3 & (~DCDC_REG3_TRG_MASK)) | DCDC_REG3_TRG(0x13);
+ /* Waiting for DCDC_STS_DC_OK bit is asserted */
+ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & DCDC->REG0))
+ {
+ }
+ /* Set AHB_PODF. */
+ CLOCK_SetDiv(kCLOCK_AhbDiv, 0);
+ /* Disable IPG clock gate. */
+ CLOCK_DisableClock(kCLOCK_Adc1);
+ CLOCK_DisableClock(kCLOCK_Adc2);
+ CLOCK_DisableClock(kCLOCK_Xbar1);
+ CLOCK_DisableClock(kCLOCK_Xbar2);
+ CLOCK_DisableClock(kCLOCK_Xbar3);
+ /* Set IPG_PODF. */
+ CLOCK_SetDiv(kCLOCK_IpgDiv, 3);
+ /* Set ARM_PODF. */
+ CLOCK_SetDiv(kCLOCK_ArmDiv, 1);
+ /* Set PERIPH_CLK2_PODF. */
+ CLOCK_SetDiv(kCLOCK_PeriphClk2Div, 0);
+ /* Disable PERCLK clock gate. */
+ CLOCK_DisableClock(kCLOCK_Gpt1);
+ CLOCK_DisableClock(kCLOCK_Gpt1S);
+ CLOCK_DisableClock(kCLOCK_Gpt2);
+ CLOCK_DisableClock(kCLOCK_Gpt2S);
+ CLOCK_DisableClock(kCLOCK_Pit);
+ /* Set PERCLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_PerclkDiv, 1);
+ /* Disable USDHC1 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Usdhc1);
+ /* Set USDHC1_PODF. */
+ CLOCK_SetDiv(kCLOCK_Usdhc1Div, 1);
+ /* Set Usdhc1 clock source. */
+ CLOCK_SetMux(kCLOCK_Usdhc1Mux, 0);
+ /* Disable USDHC2 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Usdhc2);
+ /* Set USDHC2_PODF. */
+ CLOCK_SetDiv(kCLOCK_Usdhc2Div, 1);
+ /* Set Usdhc2 clock source. */
+ CLOCK_SetMux(kCLOCK_Usdhc2Mux, 0);
+/* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd.
+ * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left
+ * unchanged.
+ * Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as well.*/
+#ifndef SKIP_SYSCLK_INIT
+ /* Disable Semc clock gate. */
+ CLOCK_DisableClock(kCLOCK_Semc);
+ /* Set SEMC_PODF. */
+ CLOCK_SetDiv(kCLOCK_SemcDiv, 7);
+ /* Set Semc alt clock source. */
+ CLOCK_SetMux(kCLOCK_SemcAltMux, 0);
+ /* Set Semc clock source. */
+ CLOCK_SetMux(kCLOCK_SemcMux, 0);
+#endif
+/* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
+ * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left
+ * unchanged.
+ * Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as well.*/
+#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
+ /* Disable Flexspi clock gate. */
+ CLOCK_DisableClock(kCLOCK_FlexSpi);
+ /* Set FLEXSPI_PODF. */
+ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2);
+ /* Set Flexspi clock source. */
+ CLOCK_SetMux(kCLOCK_FlexspiMux, 1);
+#endif
+ /* Disable CSI clock gate. */
+ CLOCK_DisableClock(kCLOCK_Csi);
+ /* Set CSI_PODF. */
+ CLOCK_SetDiv(kCLOCK_CsiDiv, 1);
+ /* Set Csi clock source. */
+ CLOCK_SetMux(kCLOCK_CsiMux, 0);
+ /* Disable LPSPI clock gate. */
+ CLOCK_DisableClock(kCLOCK_Lpspi1);
+ CLOCK_DisableClock(kCLOCK_Lpspi2);
+ CLOCK_DisableClock(kCLOCK_Lpspi3);
+ CLOCK_DisableClock(kCLOCK_Lpspi4);
+ /* Set LPSPI_PODF. */
+ CLOCK_SetDiv(kCLOCK_LpspiDiv, 4);
+ /* Set Lpspi clock source. */
+ CLOCK_SetMux(kCLOCK_LpspiMux, 2);
+ /* Disable TRACE clock gate. */
+ CLOCK_DisableClock(kCLOCK_Trace);
+ /* Set TRACE_PODF. */
+ CLOCK_SetDiv(kCLOCK_TraceDiv, 2);
+ /* Set Trace clock source. */
+ CLOCK_SetMux(kCLOCK_TraceMux, 2);
+ /* Disable SAI1 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Sai1);
+ /* Set SAI1_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Sai1PreDiv, 3);
+ /* Set SAI1_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Sai1Div, 1);
+ /* Set Sai1 clock source. */
+ CLOCK_SetMux(kCLOCK_Sai1Mux, 0);
+ /* Disable SAI2 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Sai2);
+ /* Set SAI2_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Sai2PreDiv, 3);
+ /* Set SAI2_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Sai2Div, 1);
+ /* Set Sai2 clock source. */
+ CLOCK_SetMux(kCLOCK_Sai2Mux, 0);
+ /* Disable SAI3 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Sai3);
+ /* Set SAI3_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Sai3PreDiv, 3);
+ /* Set SAI3_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Sai3Div, 1);
+ /* Set Sai3 clock source. */
+ CLOCK_SetMux(kCLOCK_Sai3Mux, 0);
+ /* Disable Lpi2c clock gate. */
+ CLOCK_DisableClock(kCLOCK_Lpi2c1);
+ CLOCK_DisableClock(kCLOCK_Lpi2c2);
+ CLOCK_DisableClock(kCLOCK_Lpi2c3);
+ /* Set LPI2C_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Lpi2cDiv, 0);
+ /* Set Lpi2c clock source. */
+ CLOCK_SetMux(kCLOCK_Lpi2cMux, 0);
+ /* Disable CAN clock gate. */
+ CLOCK_DisableClock(kCLOCK_Can1);
+ CLOCK_DisableClock(kCLOCK_Can2);
+ CLOCK_DisableClock(kCLOCK_Can1S);
+ CLOCK_DisableClock(kCLOCK_Can2S);
+ /* Set CAN_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_CanDiv, 1);
+ /* Set Can clock source. */
+ CLOCK_SetMux(kCLOCK_CanMux, 2);
+ /* Disable UART clock gate. */
+ CLOCK_DisableClock(kCLOCK_Lpuart1);
+ CLOCK_DisableClock(kCLOCK_Lpuart2);
+ CLOCK_DisableClock(kCLOCK_Lpuart3);
+ CLOCK_DisableClock(kCLOCK_Lpuart4);
+ CLOCK_DisableClock(kCLOCK_Lpuart5);
+ CLOCK_DisableClock(kCLOCK_Lpuart6);
+ CLOCK_DisableClock(kCLOCK_Lpuart7);
+ CLOCK_DisableClock(kCLOCK_Lpuart8);
+ /* Set UART_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_UartDiv, 0);
+ /* Set Uart clock source. */
+ CLOCK_SetMux(kCLOCK_UartMux, 0);
+ /* Disable LCDIF clock gate. */
+ CLOCK_DisableClock(kCLOCK_LcdPixel);
+ /* Set LCDIF_PRED. */
+ CLOCK_SetDiv(kCLOCK_LcdifPreDiv, 1);
+ /* Set LCDIF_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_LcdifDiv, 3);
+ /* Set Lcdif pre clock source. */
+ CLOCK_SetMux(kCLOCK_LcdifPreMux, 5);
+ /* Disable SPDIF clock gate. */
+ CLOCK_DisableClock(kCLOCK_Spdif);
+ /* Set SPDIF0_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Spdif0PreDiv, 1);
+ /* Set SPDIF0_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Spdif0Div, 7);
+ /* Set Spdif clock source. */
+ CLOCK_SetMux(kCLOCK_SpdifMux, 3);
+ /* Disable Flexio1 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Flexio1);
+ /* Set FLEXIO1_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Flexio1PreDiv, 1);
+ /* Set FLEXIO1_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Flexio1Div, 7);
+ /* Set Flexio1 clock source. */
+ CLOCK_SetMux(kCLOCK_Flexio1Mux, 3);
+ /* Disable Flexio2 clock gate. */
+ CLOCK_DisableClock(kCLOCK_Flexio2);
+ /* Set FLEXIO2_CLK_PRED. */
+ CLOCK_SetDiv(kCLOCK_Flexio2PreDiv, 1);
+ /* Set FLEXIO2_CLK_PODF. */
+ CLOCK_SetDiv(kCLOCK_Flexio2Div, 7);
+ /* Set Flexio2 clock source. */
+ CLOCK_SetMux(kCLOCK_Flexio2Mux, 3);
+ /* Set Pll3 sw clock source. */
+ CLOCK_SetMux(kCLOCK_Pll3SwMux, 0);
+ /* Init ARM PLL. */
+ CLOCK_InitArmPll(&armPllConfig_BOARD_BootClockRUN);
+ /* In SDK projects, SDRAM (configured by SEMC) will be initialized in either debug script or dcd.
+ * With this macro SKIP_SYSCLK_INIT, system pll (selected to be SEMC source clock in SDK projects) will be left
+ * unchanged. Note: If another clock source is selected for SEMC, user may want to avoid changing that clock as
+ * well.*/
+#ifndef SKIP_SYSCLK_INIT
+ /* Init System PLL. */
+ CLOCK_InitSysPll(&sysPllConfig_BOARD_BootClockRUN);
+ /* Init System pfd0. */
+ CLOCK_InitSysPfd(kCLOCK_Pfd0, 27);
+ /* Init System pfd1. */
+ CLOCK_InitSysPfd(kCLOCK_Pfd1, 16);
+ /* Init System pfd2. */
+ CLOCK_InitSysPfd(kCLOCK_Pfd2, 24);
+ /* Init System pfd3. */
+ CLOCK_InitSysPfd(kCLOCK_Pfd3, 16);
+ /* Disable pfd offset. */
+ CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_PFD_OFFSET_EN_MASK;
+#endif
+ /* In SDK projects, external flash (configured by FLEXSPI) will be initialized by dcd.
+ * With this macro XIP_EXTERNAL_FLASH, usb1 pll (selected to be FLEXSPI clock source in SDK projects) will be left
+ * unchanged. Note: If another clock source is selected for FLEXSPI, user may want to avoid changing that clock as
+ * well.*/
+#if !(defined(XIP_EXTERNAL_FLASH) && (XIP_EXTERNAL_FLASH == 1))
+ /* Init Usb1 PLL. */
+ CLOCK_InitUsb1Pll(&usb1PllConfig_BOARD_BootClockRUN);
+ /* Init Usb1 pfd0. */
+ CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 33);
+ /* Init Usb1 pfd1. */
+ CLOCK_InitUsb1Pfd(kCLOCK_Pfd1, 16);
+ /* Init Usb1 pfd2. */
+ CLOCK_InitUsb1Pfd(kCLOCK_Pfd2, 17);
+ /* Init Usb1 pfd3. */
+ CLOCK_InitUsb1Pfd(kCLOCK_Pfd3, 19);
+ /* Disable Usb1 PLL output for USBPHY1. */
+ CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
+#endif
+ /* DeInit Audio PLL. */
+ CLOCK_DeinitAudioPll();
+ /* Bypass Audio PLL. */
+ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllAudio, 1);
+ /* Set divider for Audio PLL. */
+ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
+ CCM_ANALOG->MISC2 &= ~CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK;
+ /* Enable Audio PLL output. */
+ CCM_ANALOG->PLL_AUDIO |= CCM_ANALOG_PLL_AUDIO_ENABLE_MASK;
+ /* DeInit Video PLL. */
+ CLOCK_DeinitVideoPll();
+ /* Bypass Video PLL. */
+ CCM_ANALOG->PLL_VIDEO |= CCM_ANALOG_PLL_VIDEO_BYPASS_MASK;
+ /* Set divider for Video PLL. */
+ CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & (~CCM_ANALOG_MISC2_VIDEO_DIV_MASK)) | CCM_ANALOG_MISC2_VIDEO_DIV(0);
+ /* Enable Video PLL output. */
+ CCM_ANALOG->PLL_VIDEO |= CCM_ANALOG_PLL_VIDEO_ENABLE_MASK;
+ /* DeInit Enet PLL. */
+ CLOCK_DeinitEnetPll();
+ /* Bypass Enet PLL. */
+ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllEnet, 1);
+ /* Set Enet output divider. */
+ CCM_ANALOG->PLL_ENET =
+ (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK)) | CCM_ANALOG_PLL_ENET_DIV_SELECT(1);
+ /* Enable Enet output. */
+ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENABLE_MASK;
+ /* Enable Enet25M output. */
+ CCM_ANALOG->PLL_ENET |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK;
+ /* DeInit Usb2 PLL. */
+ CLOCK_DeinitUsb2Pll();
+ /* Bypass Usb2 PLL. */
+ CLOCK_SetPllBypass(CCM_ANALOG, kCLOCK_PllUsb2, 1);
+ /* Enable Usb2 PLL output. */
+ CCM_ANALOG->PLL_USB2 |= CCM_ANALOG_PLL_USB2_ENABLE_MASK;
+ /* Set preperiph clock source. */
+ CLOCK_SetMux(kCLOCK_PrePeriphMux, 3);
+ /* Set periph clock source. */
+ CLOCK_SetMux(kCLOCK_PeriphMux, 0);
+ /* Set periph clock2 clock source. */
+ CLOCK_SetMux(kCLOCK_PeriphClk2Mux, 0);
+ /* Set per clock source. */
+ CLOCK_SetMux(kCLOCK_PerclkMux, 0);
+ /* Set lvds1 clock source. */
+ CCM_ANALOG->MISC1 =
+ (CCM_ANALOG->MISC1 & (~CCM_ANALOG_MISC1_LVDS1_CLK_SEL_MASK)) | CCM_ANALOG_MISC1_LVDS1_CLK_SEL(0);
+ /* Set clock out1 divider. */
+ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_DIV_MASK)) | CCM_CCOSR_CLKO1_DIV(0);
+ /* Set clock out1 source. */
+ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO1_SEL_MASK)) | CCM_CCOSR_CLKO1_SEL(1);
+ /* Set clock out2 divider. */
+ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_DIV_MASK)) | CCM_CCOSR_CLKO2_DIV(0);
+ /* Set clock out2 source. */
+ CCM->CCOSR = (CCM->CCOSR & (~CCM_CCOSR_CLKO2_SEL_MASK)) | CCM_CCOSR_CLKO2_SEL(18);
+ /* Set clock out1 drives clock out1. */
+ CCM->CCOSR &= ~CCM_CCOSR_CLK_OUT_SEL_MASK;
+ /* Disable clock out1. */
+ CCM->CCOSR &= ~CCM_CCOSR_CLKO1_EN_MASK;
+ /* Disable clock out2. */
+ CCM->CCOSR &= ~CCM_CCOSR_CLKO2_EN_MASK;
+ /* Set SAI1 MCLK1 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk1Sel, 0);
+ /* Set SAI1 MCLK2 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk2Sel, 0);
+ /* Set SAI1 MCLK3 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI1MClk3Sel, 0);
+ /* Set SAI2 MCLK3 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI2MClk3Sel, 0);
+ /* Set SAI3 MCLK3 clock source. */
+ IOMUXC_SetSaiMClkClockSource(IOMUXC_GPR, kIOMUXC_GPR_SAI3MClk3Sel, 0);
+ /* Set MQS configuration. */
+ IOMUXC_MQSConfig(IOMUXC_GPR, kIOMUXC_MqsPwmOverSampleRate32, 0);
+ /* Set ENET Tx clock source. */
+ IOMUXC_EnableMode(IOMUXC_GPR, kIOMUXC_GPR_ENET1RefClkMode, false);
+ /* Set GPT1 High frequency reference clock source. */
+ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT1_MASK;
+ /* Set GPT2 High frequency reference clock source. */
+ IOMUXC_GPR->GPR5 &= ~IOMUXC_GPR_GPR5_VREF_1M_CLK_GPT2_MASK;
+ /* Set SystemCoreClock variable. */
+ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
+}
diff --git a/bsps/arm/imxrt/nxp/boards/evkbimxrt1050/pin_mux.c b/bsps/arm/imxrt/nxp/boards/evkbimxrt1050/pin_mux.c
new file mode 100644
index 0000000000..8e3021afcb
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/boards/evkbimxrt1050/pin_mux.c
@@ -0,0 +1,1094 @@
+/*
+ * Copyright 2018 NXP.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/***********************************************************************************************************************
+ * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file
+ * will be overwritten if the respective MCUXpresso Config Tools is used to update this file.
+ **********************************************************************************************************************/
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+!!GlobalInfo
+product: Pins v4.1
+processor: MIMXRT1052xxxxB
+package_id: MIMXRT1052DVL6B
+mcu_data: ksdk2_0
+processor_version: 4.0.0
+board: IMXRT1050-EVKB
+pin_labels:
+- {pin_num: E3, pin_signal: GPIO_EMC_00, label: SEMC_D0, identifier: SEMC_D0}
+- {pin_num: F3, pin_signal: GPIO_EMC_01, label: SEMC_D1, identifier: SEMC_D1}
+- {pin_num: F4, pin_signal: GPIO_EMC_02, label: SEMC_D2, identifier: SEMC_D2}
+- {pin_num: F2, pin_signal: GPIO_EMC_04, label: SEMC_D4, identifier: SEMC_D4}
+- {pin_num: G4, pin_signal: GPIO_EMC_03, label: SEMC_D3, identifier: SEMC_D3}
+- {pin_num: G5, pin_signal: GPIO_EMC_05, label: SEMC_D5, identifier: SEMC_D5}
+- {pin_num: H5, pin_signal: GPIO_EMC_06, label: SEMC_D6, identifier: SEMC_D6}
+- {pin_num: H4, pin_signal: GPIO_EMC_07, label: SEMC_D7, identifier: SEMC_D7}
+- {pin_num: H3, pin_signal: GPIO_EMC_08, label: SEMC_DM0, identifier: SEMC_DM0}
+- {pin_num: C2, pin_signal: GPIO_EMC_09, label: SEMC_A0, identifier: SEMC_A0}
+- {pin_num: G1, pin_signal: GPIO_EMC_10, label: SEMC_A1, identifier: SEMC_A1}
+- {pin_num: G3, pin_signal: GPIO_EMC_11, label: SEMC_A2, identifier: SEMC_A2}
+- {pin_num: H1, pin_signal: GPIO_EMC_12, label: SEMC_A3, identifier: SEMC_A3}
+- {pin_num: A6, pin_signal: GPIO_EMC_13, label: SEMC_A4, identifier: SEMC_A4}
+- {pin_num: B6, pin_signal: GPIO_EMC_14, label: SEMC_A5, identifier: SEMC_A5}
+- {pin_num: B1, pin_signal: GPIO_EMC_15, label: SEMC_A6, identifier: SEMC_A6}
+- {pin_num: A5, pin_signal: GPIO_EMC_16, label: SEMC_A7, identifier: SEMC_A7}
+- {pin_num: A4, pin_signal: GPIO_EMC_17, label: SEMC_A8, identifier: SEMC_A8}
+- {pin_num: B2, pin_signal: GPIO_EMC_18, label: SEMC_A9, identifier: SEMC_A9}
+- {pin_num: B4, pin_signal: GPIO_EMC_19, label: SEMC_A11, identifier: SEMC_A11}
+- {pin_num: G2, pin_signal: GPIO_EMC_23, label: SEMC_A10, identifier: SEMC_A10}
+- {pin_num: A3, pin_signal: GPIO_EMC_20, label: SEMC_A12, identifier: SEMC_A12}
+- {pin_num: C1, pin_signal: GPIO_EMC_21, label: SEMC_BA0, identifier: SEMC_BA0}
+- {pin_num: F1, pin_signal: GPIO_EMC_22, label: SEMC_BA1, identifier: SEMC_BA1}
+- {pin_num: D3, pin_signal: GPIO_EMC_24, label: SEMC_CAS, identifier: SEMC_CAS}
+- {pin_num: D2, pin_signal: GPIO_EMC_25, label: SEMC_RAS, identifier: SEMC_RAS}
+- {pin_num: B3, pin_signal: GPIO_EMC_26, label: SEMC_CLK, identifier: SEMC_CLK}
+- {pin_num: A2, pin_signal: GPIO_EMC_27, label: SEMC_CKE, identifier: SEMC_CKE}
+- {pin_num: D1, pin_signal: GPIO_EMC_28, label: SEMC_WE, identifier: SEMC_WE}
+- {pin_num: E1, pin_signal: GPIO_EMC_29, label: SEMC_CS0, identifier: SEMC_CS0}
+- {pin_num: C6, pin_signal: GPIO_EMC_30, label: SEMC_D8, identifier: SEMC_D8}
+- {pin_num: C5, pin_signal: GPIO_EMC_31, label: SEMC_D9, identifier: SEMC_D9}
+- {pin_num: D5, pin_signal: GPIO_EMC_32, label: SEMC_D10, identifier: SEMC_D10}
+- {pin_num: C4, pin_signal: GPIO_EMC_33, label: SEMC_D11, identifier: SEMC_D11}
+- {pin_num: D4, pin_signal: GPIO_EMC_34, label: SEMC_D12, identifier: SEMC_D12}
+- {pin_num: E5, pin_signal: GPIO_EMC_35, label: SEMC_D13, identifier: SEMC_D13}
+- {pin_num: C3, pin_signal: GPIO_EMC_36, label: SEMC_D14, identifier: SEMC_D14}
+- {pin_num: E4, pin_signal: GPIO_EMC_37, label: SEMC_D15, identifier: SEMC_D15}
+- {pin_num: D6, pin_signal: GPIO_EMC_38, label: SEMC_DM1, identifier: SEMC_DM1}
+- {pin_num: B7, pin_signal: GPIO_EMC_39, label: SEMC_DQS, identifier: SEMC_DQS}
+- {pin_num: A7, pin_signal: GPIO_EMC_40, label: ENET_MDC, identifier: ENET_MDC}
+- {pin_num: C7, pin_signal: GPIO_EMC_41, label: ENET_MDIO, identifier: ENET_MDIO}
+- {pin_num: D7, pin_signal: GPIO_B0_00, label: LCDIF_CLK, identifier: LCDIF_CLK}
+- {pin_num: E7, pin_signal: GPIO_B0_01, label: LCDIF_ENABLE, identifier: LCDIF_ENABLE}
+- {pin_num: E8, pin_signal: GPIO_B0_02, label: LCDIF_HSYNC, identifier: LCDIF_HSYNC}
+- {pin_num: D8, pin_signal: GPIO_B0_03, label: LCDIF_VSYNC, identifier: LCDIF_VSYNC}
+- {pin_num: C8, pin_signal: GPIO_B0_04, label: 'LCDIF_D0/BT_CFG[0]', identifier: LCDIF_D0}
+- {pin_num: B8, pin_signal: GPIO_B0_05, label: 'LCDIF_D1/BT_CFG[1]', identifier: LCDIF_D1}
+- {pin_num: A8, pin_signal: GPIO_B0_06, label: 'LCDIF_D2/BT_CFG[2]', identifier: LCDIF_D2}
+- {pin_num: A9, pin_signal: GPIO_B0_07, label: 'LCDIF_D3/BT_CFG[3]', identifier: LCDIF_D3}
+- {pin_num: B9, pin_signal: GPIO_B0_08, label: 'LCDIF_D4/BT_CFG[4]', identifier: LCDIF_D4}
+- {pin_num: C9, pin_signal: GPIO_B0_09, label: 'LCDIF_D5/BT_CFG[5]', identifier: LCDIF_D5}
+- {pin_num: D9, pin_signal: GPIO_B0_10, label: 'LCDIF_D6/BT_CFG[6]', identifier: LCDIF_D6}
+- {pin_num: A10, pin_signal: GPIO_B0_11, label: 'LCDIF_D7/BT_CFG[7]', identifier: LCDIF_D7}
+- {pin_num: C10, pin_signal: GPIO_B0_12, label: 'LCDIF_D8/BT_CFG[8]', identifier: LCDIF_D8}
+- {pin_num: D10, pin_signal: GPIO_B0_13, label: 'LCDIF_D9/BT_CFG[9]', identifier: LCDIF_D9}
+- {pin_num: E10, pin_signal: GPIO_B0_14, label: 'LCDIF_D10/BT_CFG[10]', identifier: LCDIF_D10}
+- {pin_num: E11, pin_signal: GPIO_B0_15, label: 'LCDIF_D11/BT_CFG[11]', identifier: LCDIF_D11}
+- {pin_num: A11, pin_signal: GPIO_B1_00, label: LCDIF_D12, identifier: LCDIF_D12}
+- {pin_num: B11, pin_signal: GPIO_B1_01, label: LCDIF_D13, identifier: LCDIF_D13}
+- {pin_num: C11, pin_signal: GPIO_B1_02, label: LCDIF_D14, identifier: LCDIF_D14}
+- {pin_num: D11, pin_signal: GPIO_B1_03, label: LCDIF_D15, identifier: LCDIF_D15}
+- {pin_num: E12, pin_signal: GPIO_B1_04, label: ENET_RXD0, identifier: ENET_RXD0}
+- {pin_num: D12, pin_signal: GPIO_B1_05, label: ENET_RXD1, identifier: ENET_RXD1}
+- {pin_num: C12, pin_signal: GPIO_B1_06, label: ENET_CRS_DV, identifier: ENET_CRS_DV}
+- {pin_num: B12, pin_signal: GPIO_B1_07, label: ENET_TXD0, identifier: ENET_TXD0}
+- {pin_num: A12, pin_signal: GPIO_B1_08, label: ENET_TXD1, identifier: ENET_TXD1}
+- {pin_num: A13, pin_signal: GPIO_B1_09, label: ENET_TXEN, identifier: ENET_TXEN}
+- {pin_num: B13, pin_signal: GPIO_B1_10, label: ENET_TX_CLK, identifier: ENET_TX_CLK}
+- {pin_num: C13, pin_signal: GPIO_B1_11, label: ENET_RXER, identifier: ENET_RXER}
+- {pin_num: D13, pin_signal: GPIO_B1_12, label: SD_CD_SW, identifier: SD_CD_SW}
+- {pin_num: D14, pin_signal: GPIO_B1_13, label: WDOG_B, identifier: WDOG_B}
+- {pin_num: C14, pin_signal: GPIO_B1_14, label: SD0_VSELECT, identifier: SD0_VSELECT}
+- {pin_num: B14, pin_signal: GPIO_B1_15, label: USB_HOST_PWR/BACKLIGHT_CTL, identifier: BACKLIGHT_CTL}
+- {pin_num: E9, pin_signal: NVCC_GPIO0, label: DCDC_3V3/NVCC_GPIO_3V3}
+- {pin_num: F10, pin_signal: NVCC_GPIO1, label: DCDC_3V3/NVCC_GPIO_3V3}
+- {pin_num: J10, pin_signal: NVCC_GPIO2, label: DCDC_3V3/NVCC_GPIO_3V3}
+- {pin_num: M14, pin_signal: GPIO_AD_B0_00, label: 'USB_HOST_OC/J24[10]'}
+- {pin_num: H10, pin_signal: GPIO_AD_B0_01, label: 'USB_OTG1_ID/J24[9]'}
+- {pin_num: M11, pin_signal: GPIO_AD_B0_02, label: 'USB_OTG1_PWR/J24[2]'}
+- {pin_num: G11, pin_signal: GPIO_AD_B0_03, label: 'USB_OTG1_OC/J24[1]'}
+- {pin_num: F11, pin_signal: GPIO_AD_B0_04, label: 'CSI_PWDN/J35[17]/BOOT_MODE[0]', identifier: CSI_PWDN}
+- {pin_num: G14, pin_signal: GPIO_AD_B0_05, label: 'CAN_STBY/BOOT_MODE[1]/Flash_RST/U12[8]', identifier: CAN_STBY}
+- {pin_num: E14, pin_signal: GPIO_AD_B0_06, label: 'JTAG_TMS/J21[7]/SWD_DIO'}
+- {pin_num: F12, pin_signal: GPIO_AD_B0_07, label: 'JTAG_TCK/J21[9]/SWD_CLK'}
+- {pin_num: F13, pin_signal: GPIO_AD_B0_08, label: JTAG_MOD}
+- {pin_num: F14, pin_signal: GPIO_AD_B0_09, label: 'JTAG_TDI/J21[5]/ENET_RST/J22[5]'}
+- {pin_num: G13, pin_signal: GPIO_AD_B0_10, label: 'JTAG_TDO/J21[13]/INT1_COMBO/ENET_INT/J22[6]/U32[11]', identifier: INT1_COMBO}
+- {pin_num: G10, pin_signal: GPIO_AD_B0_11, label: 'JTAG_nTRST/J21[3]/INT2_COMBO/LCD_TOUCH_INT/J22[3]/U32[9]', identifier: INT2_COMBO}
+- {pin_num: K14, pin_signal: GPIO_AD_B0_12, label: UART1_TXD, identifier: UART1_TXD}
+- {pin_num: L14, pin_signal: GPIO_AD_B0_13, label: UART1_RXD, identifier: UART1_RXD}
+- {pin_num: H14, pin_signal: GPIO_AD_B0_14, label: 'CAN2_TX/U12[1]', identifier: CAN2_TX}
+- {pin_num: L10, pin_signal: GPIO_AD_B0_15, label: 'CAN2_RX/U12[4]', identifier: CAN2_RX}
+- {pin_num: J11, pin_signal: GPIO_AD_B1_00, label: 'I2C1_SCL/CSI_I2C_SCL/J35[20]/J23[6]/U13[17]/U32[4]', identifier: I2C_SCL_FXOS8700CQ;CSI_I2C_SCL}
+- {pin_num: K11, pin_signal: GPIO_AD_B1_01, label: 'I2C1_SDA/CSI_I2C_SDA/J35[22]/J23[5]/U13[18]/U32[6]', identifier: I2C_SDA_FXOS8700CQ;CSI_I2C_SDA}
+- {pin_num: L11, pin_signal: GPIO_AD_B1_02, label: 'SPDIF_OUT/J22[7]', identifier: SPDIF_OUT}
+- {pin_num: M12, pin_signal: GPIO_AD_B1_03, label: 'SPDIF_IN/J22[8]', identifier: SPDIF_IN}
+- {pin_num: H13, pin_signal: GPIO_AD_B1_08, label: 'AUD_INT/CSI_D9//J35[13]/J22[4]', identifier: CSI_D9}
+- {pin_num: M13, pin_signal: GPIO_AD_B1_09, label: 'SAI1_MCLK/CSI_D8/J35[11]', identifier: CSI_D8}
+- {pin_num: L13, pin_signal: GPIO_AD_B1_10, label: 'SAI1_RX_SYNC/CSI_D7/J35[9]/J23[1]', identifier: CSI_D7}
+- {pin_num: J13, pin_signal: GPIO_AD_B1_11, label: 'SAI1_RX_BCLK/CSI_D6/J35[7]/J23[2]', identifier: CSI_D6}
+- {pin_num: H12, pin_signal: GPIO_AD_B1_12, label: 'SAI1_RXD/CSI_D5/J35[5]/U13[16]', identifier: CSI_D5}
+- {pin_num: H11, pin_signal: GPIO_AD_B1_13, label: 'SAI1_TXD/CSI_D4/J35[3]/U13[14]', identifier: CSI_D4}
+- {pin_num: G12, pin_signal: GPIO_AD_B1_14, label: 'SAI1_TX_BCLK/CSI_D3/J35[4]/U13[12]', identifier: CSI_D3}
+- {pin_num: J14, pin_signal: GPIO_AD_B1_15, label: 'SAI1_TX_SYNC/CSI_D2/J35[6]/U13[13]', identifier: CSI_D2}
+- {pin_num: J4, pin_signal: GPIO_SD_B0_00, label: 'SD1_CMD/J24[6]', identifier: SD1_CMD}
+- {pin_num: J3, pin_signal: GPIO_SD_B0_01, label: 'SD1_CLK/J24[3]', identifier: SD1_CLK}
+- {pin_num: J1, pin_signal: GPIO_SD_B0_02, label: 'SD1_D0/J24[4]/SPI_MOSI/PWM', identifier: SD1_D0}
+- {pin_num: K1, pin_signal: GPIO_SD_B0_03, label: 'SD1_D1/J24[5]/SPI_MISO', identifier: SD1_D1}
+- {pin_num: H2, pin_signal: GPIO_SD_B0_04, label: SD1_D2, identifier: SD1_D2}
+- {pin_num: J2, pin_signal: GPIO_SD_B0_05, label: SD1_D3, identifier: SD1_D3}
+- {pin_num: L5, pin_signal: GPIO_SD_B1_00, label: FlexSPI_D3_B, identifier: FlexSPI_D3_B}
+- {pin_num: M5, pin_signal: GPIO_SD_B1_01, label: FlexSPI_D2_B, identifier: FlexSPI_D2_B}
+- {pin_num: M3, pin_signal: GPIO_SD_B1_02, label: FlexSPI_D1_B, identifier: FlexSPI_D1_B}
+- {pin_num: M4, pin_signal: GPIO_SD_B1_03, label: FlexSPI_D0_B, identifier: FlexSPI_D0_B}
+- {pin_num: P2, pin_signal: GPIO_SD_B1_04, label: FlexSPI_CLK_B, identifier: FlexSPI_CLK_B}
+- {pin_num: N3, pin_signal: GPIO_SD_B1_05, label: FlexSPI_DQS, identifier: FlexSPI_DQS}
+- {pin_num: L3, pin_signal: GPIO_SD_B1_06, label: FlexSPI_SS0, identifier: FlexSPI_SS0}
+- {pin_num: L4, pin_signal: GPIO_SD_B1_07, label: FlexSPI_CLK, identifier: FlexSPI_CLK}
+- {pin_num: P3, pin_signal: GPIO_SD_B1_08, label: FlexSPI_D0_A, identifier: FlexSPI_D0_A}
+- {pin_num: N4, pin_signal: GPIO_SD_B1_09, label: FlexSPI_D1_A, identifier: FlexSPI_D1_A}
+- {pin_num: P4, pin_signal: GPIO_SD_B1_10, label: FlexSPI_D2_A, identifier: FlexSPI_D2_A}
+- {pin_num: P5, pin_signal: GPIO_SD_B1_11, label: FlexSPI_D3_A, identifier: FlexSPI_D3_A}
+- {pin_num: M8, pin_signal: USB_OTG1_DN, label: OTG1_DN, identifier: OTG1_DN}
+- {pin_num: L8, pin_signal: USB_OTG1_DP, label: OTG1_DP, identifier: OTG1_DP}
+- {pin_num: N7, pin_signal: USB_OTG2_DN, label: OTG2_DN, identifier: OTG2_DN}
+- {pin_num: P7, pin_signal: USB_OTG2_DP, label: OTG2_DP, identifier: OTG2_DP}
+- {pin_num: K8, pin_signal: VDD_USB_CAP, label: VDD_USB_3V}
+- {pin_num: N6, pin_signal: USB_OTG1_VBUS, label: 5V_USB_OTG}
+- {pin_num: P6, pin_signal: USB_OTG2_VBUS, label: 5V_USB_HS}
+- {pin_num: L12, pin_signal: GPIO_AD_B1_04, label: 'CSI_PIXCLK/J35[8]/J23[3]', identifier: CSI_PIXCLK}
+- {pin_num: K12, pin_signal: GPIO_AD_B1_05, label: 'CSI_MCLK/J35[12]/J23[4]', identifier: CSI_MCLK}
+- {pin_num: J12, pin_signal: GPIO_AD_B1_06, label: 'CSI_VSYNC/J35[18]/J22[2]/UART_TX', identifier: CSI_VSYNC}
+- {pin_num: K10, pin_signal: GPIO_AD_B1_07, label: 'CSI_HSYNC/J35[16]/J22[1]/UART_RX', identifier: CSI_HSYNC}
+- {pin_num: M7, pin_signal: POR_B, label: 'RST_TGTMCU_B/POR_B/J21[15]', identifier: RST_TGTMCU_B;POR_B}
+- {pin_num: N14, pin_signal: VDDA_ADC_3P3, label: VDDA_ADC_3P3_MCU}
+- {pin_num: P12, pin_signal: VDD_HIGH_IN, label: VDD_HIGH_IN_MCU}
+- {pin_num: M9, pin_signal: VDD_SNVS_IN, label: VDD_SNVS_IN}
+- {pin_num: F6, pin_signal: VDD_SOC_IN0, label: VDD_SOC_IN}
+- {pin_num: H6, pin_signal: VDD_SOC_IN2, label: VDD_SOC_IN}
+- {pin_num: G6, pin_signal: VDD_SOC_IN1, label: VDD_SOC_IN}
+- {pin_num: F7, pin_signal: VDD_SOC_IN3, label: VDD_SOC_IN}
+- {pin_num: F8, pin_signal: VDD_SOC_IN4, label: VDD_SOC_IN}
+- {pin_num: F9, pin_signal: VDD_SOC_IN5, label: VDD_SOC_IN}
+- {pin_num: G9, pin_signal: VDD_SOC_IN6, label: VDD_SOC_IN}
+- {pin_num: H9, pin_signal: VDD_SOC_IN7, label: VDD_SOC_IN}
+- {pin_num: J9, pin_signal: VDD_SOC_IN8, label: VDD_SOC_IN}
+- {pin_num: P1, pin_signal: VSS1, label: GND}
+- {pin_num: E2, pin_signal: VSS2, label: GND}
+- {pin_num: K2, pin_signal: VSS3, label: GND}
+- {pin_num: B5, pin_signal: VSS4, label: GND}
+- {pin_num: N5, pin_signal: VSS5, label: GND}
+- {pin_num: G7, pin_signal: VSS6, label: GND}
+- {pin_num: H7, pin_signal: VSS7, label: GND}
+- {pin_num: J7, pin_signal: VSS8, label: GND}
+- {pin_num: G8, pin_signal: VSS9, label: GND}
+- {pin_num: H8, pin_signal: VSS10, label: GND}
+- {pin_num: J8, pin_signal: VSS11, label: GND}
+- {pin_num: N8, pin_signal: VSS12, label: GND}
+- {pin_num: L9, pin_signal: VSS13, label: GND}
+- {pin_num: B10, pin_signal: VSS14, label: GND}
+- {pin_num: E13, pin_signal: VSS15, label: GND}
+- {pin_num: K13, pin_signal: VSS16, label: GND}
+- {pin_num: A14, pin_signal: VSS17, label: GND}
+- {pin_num: P14, pin_signal: VSS18, label: GND}
+- {pin_num: A1, pin_signal: VSS0, label: GND}
+- {pin_num: J6, pin_signal: NVCC_SD0, label: NVCC_SD, identifier: NVCC_SD}
+- {pin_num: K5, pin_signal: NVCC_SD1, label: FLASH_VCC, identifier: FLASH_VCC}
+- {pin_num: F5, pin_signal: NVCC_EMC0, label: DCDC_3V3}
+- {pin_num: E6, pin_signal: NVCC_EMC1, label: DCDC_3V3}
+- {pin_num: L6, pin_signal: WAKEUP, label: SD_PWREN, identifier: SD_PWREN}
+- {pin_num: L1, pin_signal: DCDC_IN0, label: MCU_DCDC_IN_3V3}
+- {pin_num: L2, pin_signal: DCDC_IN1, label: MCU_DCDC_IN_3V3}
+- {pin_num: K4, pin_signal: DCDC_IN_Q, label: MCU_DCDC_IN_3V3}
+- {pin_num: M1, pin_signal: DCDC_LP0, label: VDD_SOC_IN}
+- {pin_num: M2, pin_signal: DCDC_LP1, label: VDD_SOC_IN}
+- {pin_num: P11, pin_signal: XTALI, label: XTALI, identifier: XTALI}
+- {pin_num: N11, pin_signal: XTALO, label: XTALO, identifier: XTALO}
+- {pin_num: N9, pin_signal: RTC_XTALI, label: RTC_XTALI, identifier: RTC_XTALI}
+- {pin_num: P9, pin_signal: RTC_XTALO, label: RTC_XTALO, identifier: RTC_XTALO}
+- {pin_num: N1, pin_signal: DCDC_GND0, label: GND}
+- {pin_num: N2, pin_signal: DCDC_GND1, label: GND}
+- {pin_num: J5, pin_signal: DCDC_SENSE, label: VDD_SOC_IN}
+- {pin_num: K3, pin_signal: DCDC_PSWITCH, label: MCU_DCDC_IN_3V3}
+- {pin_num: K7, pin_signal: PMIC_ON_REQ, label: PMIC_ON_REQ, identifier: PMIC_ON_REQ}
+- {pin_num: L7, pin_signal: PMIC_STBY_REQ, label: PERI_PWREN, identifier: PERI_PWREN}
+- {pin_num: M6, pin_signal: ONOFF, label: ONOFF, identifier: ONOFF}
+- {pin_num: K6, pin_signal: TEST_MODE, label: GND}
+- {pin_num: P10, pin_signal: NVCC_PLL, label: VDDA_1P1_CAP}
+- {pin_num: P8, pin_signal: VDD_HIGH_CAP, label: VDDA_2P5_CAP}
+- {pin_num: K9, pin_signal: NGND_KEL0, label: GND}
+- {pin_num: M10, pin_signal: VDD_SNVS_CAP, label: GND}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+#include "fsl_common.h"
+#include "fsl_iomuxc.h"
+#include "pin_mux.h"
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitBootPins
+ * Description : Calls initialization functions.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitBootPins(void) {
+ BOARD_InitPins();
+ BOARD_InitDEBUG_UARTPins();
+}
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitPins:
+- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'}
+- pin_list: []
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitPins(void) {
+}
+
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitDEBUG_UARTPins:
+- options: {callFromInitBoot: 'true', coreID: core0, enableClock: 'true'}
+- pin_list:
+ - {pin_num: K14, peripheral: LPUART1, signal: TX, pin_signal: GPIO_AD_B0_12, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm,
+ pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow}
+ - {pin_num: L14, peripheral: LPUART1, signal: RX, pin_signal: GPIO_AD_B0_13, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Down_100K_Ohm,
+ pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Disable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitDEBUG_UARTPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitDEBUG_UARTPins(void) {
+ CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
+
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 is configured as LPUART1_TX */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 is configured as LPUART1_RX */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 PAD functional properties : */
+ 0x10B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Keeper
+ Pull Up / Down Config. Field: 100K Ohm Pull Down
+ Hyst. Enable Field: Hysteresis Disabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 PAD functional properties : */
+ 0x10B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Keeper
+ Pull Up / Down Config. Field: 100K Ohm Pull Down
+ Hyst. Enable Field: Hysteresis Disabled */
+}
+
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitSDRAMPins:
+- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'}
+- pin_list:
+ - {pin_num: C2, peripheral: SEMC, signal: 'ADDR, 00', pin_signal: GPIO_EMC_09}
+ - {pin_num: G1, peripheral: SEMC, signal: 'ADDR, 01', pin_signal: GPIO_EMC_10}
+ - {pin_num: G3, peripheral: SEMC, signal: 'ADDR, 02', pin_signal: GPIO_EMC_11}
+ - {pin_num: H1, peripheral: SEMC, signal: 'ADDR, 03', pin_signal: GPIO_EMC_12}
+ - {pin_num: A6, peripheral: SEMC, signal: 'ADDR, 04', pin_signal: GPIO_EMC_13}
+ - {pin_num: B6, peripheral: SEMC, signal: 'ADDR, 05', pin_signal: GPIO_EMC_14}
+ - {pin_num: B1, peripheral: SEMC, signal: 'ADDR, 06', pin_signal: GPIO_EMC_15}
+ - {pin_num: A5, peripheral: SEMC, signal: 'ADDR, 07', pin_signal: GPIO_EMC_16}
+ - {pin_num: A4, peripheral: SEMC, signal: 'ADDR, 08', pin_signal: GPIO_EMC_17}
+ - {pin_num: B2, peripheral: SEMC, signal: 'ADDR, 09', pin_signal: GPIO_EMC_18}
+ - {pin_num: G2, peripheral: SEMC, signal: 'ADDR, 10', pin_signal: GPIO_EMC_23}
+ - {pin_num: B4, peripheral: SEMC, signal: 'ADDR, 11', pin_signal: GPIO_EMC_19}
+ - {pin_num: A3, peripheral: SEMC, signal: 'ADDR, 12', pin_signal: GPIO_EMC_20}
+ - {pin_num: C1, peripheral: SEMC, signal: 'BA, 0', pin_signal: GPIO_EMC_21}
+ - {pin_num: F1, peripheral: SEMC, signal: 'BA, 1', pin_signal: GPIO_EMC_22}
+ - {pin_num: D3, peripheral: SEMC, signal: semc_cas, pin_signal: GPIO_EMC_24}
+ - {pin_num: A2, peripheral: SEMC, signal: semc_cke, pin_signal: GPIO_EMC_27}
+ - {pin_num: B3, peripheral: SEMC, signal: semc_clk, pin_signal: GPIO_EMC_26}
+ - {pin_num: E3, peripheral: SEMC, signal: 'DATA, 00', pin_signal: GPIO_EMC_00}
+ - {pin_num: F3, peripheral: SEMC, signal: 'DATA, 01', pin_signal: GPIO_EMC_01}
+ - {pin_num: F4, peripheral: SEMC, signal: 'DATA, 02', pin_signal: GPIO_EMC_02}
+ - {pin_num: G4, peripheral: SEMC, signal: 'DATA, 03', pin_signal: GPIO_EMC_03}
+ - {pin_num: F2, peripheral: SEMC, signal: 'DATA, 04', pin_signal: GPIO_EMC_04}
+ - {pin_num: G5, peripheral: SEMC, signal: 'DATA, 05', pin_signal: GPIO_EMC_05}
+ - {pin_num: H5, peripheral: SEMC, signal: 'DATA, 06', pin_signal: GPIO_EMC_06}
+ - {pin_num: H4, peripheral: SEMC, signal: 'DATA, 07', pin_signal: GPIO_EMC_07}
+ - {pin_num: C6, peripheral: SEMC, signal: 'DATA, 08', pin_signal: GPIO_EMC_30}
+ - {pin_num: C5, peripheral: SEMC, signal: 'DATA, 09', pin_signal: GPIO_EMC_31}
+ - {pin_num: D5, peripheral: SEMC, signal: 'DATA, 10', pin_signal: GPIO_EMC_32}
+ - {pin_num: C4, peripheral: SEMC, signal: 'DATA, 11', pin_signal: GPIO_EMC_33}
+ - {pin_num: D4, peripheral: SEMC, signal: 'DATA, 12', pin_signal: GPIO_EMC_34}
+ - {pin_num: E5, peripheral: SEMC, signal: 'DATA, 13', pin_signal: GPIO_EMC_35}
+ - {pin_num: C3, peripheral: SEMC, signal: 'DATA, 14', pin_signal: GPIO_EMC_36}
+ - {pin_num: E4, peripheral: SEMC, signal: 'DATA, 15', pin_signal: GPIO_EMC_37}
+ - {pin_num: H3, peripheral: SEMC, signal: 'DM, 0', pin_signal: GPIO_EMC_08}
+ - {pin_num: D6, peripheral: SEMC, signal: 'DM, 1', pin_signal: GPIO_EMC_38}
+ - {pin_num: D2, peripheral: SEMC, signal: semc_ras, pin_signal: GPIO_EMC_25}
+ - {pin_num: D1, peripheral: SEMC, signal: semc_we, pin_signal: GPIO_EMC_28}
+ - {pin_num: C7, peripheral: SEMC, signal: 'CSX, 0', pin_signal: GPIO_EMC_41}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitSDRAMPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitSDRAMPins(void) {
+ CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
+
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_00_SEMC_DATA00, /* GPIO_EMC_00 is configured as SEMC_DATA00 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_01_SEMC_DATA01, /* GPIO_EMC_01 is configured as SEMC_DATA01 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_02_SEMC_DATA02, /* GPIO_EMC_02 is configured as SEMC_DATA02 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_03_SEMC_DATA03, /* GPIO_EMC_03 is configured as SEMC_DATA03 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_04_SEMC_DATA04, /* GPIO_EMC_04 is configured as SEMC_DATA04 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_05_SEMC_DATA05, /* GPIO_EMC_05 is configured as SEMC_DATA05 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_06_SEMC_DATA06, /* GPIO_EMC_06 is configured as SEMC_DATA06 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_07_SEMC_DATA07, /* GPIO_EMC_07 is configured as SEMC_DATA07 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_08_SEMC_DM00, /* GPIO_EMC_08 is configured as SEMC_DM00 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_09_SEMC_ADDR00, /* GPIO_EMC_09 is configured as SEMC_ADDR00 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_10_SEMC_ADDR01, /* GPIO_EMC_10 is configured as SEMC_ADDR01 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_11_SEMC_ADDR02, /* GPIO_EMC_11 is configured as SEMC_ADDR02 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_12_SEMC_ADDR03, /* GPIO_EMC_12 is configured as SEMC_ADDR03 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_13_SEMC_ADDR04, /* GPIO_EMC_13 is configured as SEMC_ADDR04 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_14_SEMC_ADDR05, /* GPIO_EMC_14 is configured as SEMC_ADDR05 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_15_SEMC_ADDR06, /* GPIO_EMC_15 is configured as SEMC_ADDR06 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_16_SEMC_ADDR07, /* GPIO_EMC_16 is configured as SEMC_ADDR07 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_17_SEMC_ADDR08, /* GPIO_EMC_17 is configured as SEMC_ADDR08 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_18_SEMC_ADDR09, /* GPIO_EMC_18 is configured as SEMC_ADDR09 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_19_SEMC_ADDR11, /* GPIO_EMC_19 is configured as SEMC_ADDR11 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_20_SEMC_ADDR12, /* GPIO_EMC_20 is configured as SEMC_ADDR12 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_21_SEMC_BA0, /* GPIO_EMC_21 is configured as SEMC_BA0 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_22_SEMC_BA1, /* GPIO_EMC_22 is configured as SEMC_BA1 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_23_SEMC_ADDR10, /* GPIO_EMC_23 is configured as SEMC_ADDR10 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_24_SEMC_CAS, /* GPIO_EMC_24 is configured as SEMC_CAS */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_25_SEMC_RAS, /* GPIO_EMC_25 is configured as SEMC_RAS */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_26_SEMC_CLK, /* GPIO_EMC_26 is configured as SEMC_CLK */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_27_SEMC_CKE, /* GPIO_EMC_27 is configured as SEMC_CKE */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_28_SEMC_WE, /* GPIO_EMC_28 is configured as SEMC_WE */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_30_SEMC_DATA08, /* GPIO_EMC_30 is configured as SEMC_DATA08 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_31_SEMC_DATA09, /* GPIO_EMC_31 is configured as SEMC_DATA09 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_32_SEMC_DATA10, /* GPIO_EMC_32 is configured as SEMC_DATA10 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_33_SEMC_DATA11, /* GPIO_EMC_33 is configured as SEMC_DATA11 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_34_SEMC_DATA12, /* GPIO_EMC_34 is configured as SEMC_DATA12 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_35_SEMC_DATA13, /* GPIO_EMC_35 is configured as SEMC_DATA13 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_36_SEMC_DATA14, /* GPIO_EMC_36 is configured as SEMC_DATA14 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_37_SEMC_DATA15, /* GPIO_EMC_37 is configured as SEMC_DATA15 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_38_SEMC_DM01, /* GPIO_EMC_38 is configured as SEMC_DM01 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_41_SEMC_CSX00, /* GPIO_EMC_41 is configured as SEMC_CSX00 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+}
+
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitCSIPins:
+- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'}
+- pin_list:
+ - {pin_num: H13, peripheral: CSI, signal: 'csi_data, 09', pin_signal: GPIO_AD_B1_08}
+ - {pin_num: M13, peripheral: CSI, signal: 'csi_data, 08', pin_signal: GPIO_AD_B1_09}
+ - {pin_num: L13, peripheral: CSI, signal: 'csi_data, 07', pin_signal: GPIO_AD_B1_10}
+ - {pin_num: J13, peripheral: CSI, signal: 'csi_data, 06', pin_signal: GPIO_AD_B1_11}
+ - {pin_num: H12, peripheral: CSI, signal: 'csi_data, 05', pin_signal: GPIO_AD_B1_12}
+ - {pin_num: H11, peripheral: CSI, signal: 'csi_data, 04', pin_signal: GPIO_AD_B1_13}
+ - {pin_num: J14, peripheral: CSI, signal: 'csi_data, 02', pin_signal: GPIO_AD_B1_15}
+ - {pin_num: G12, peripheral: CSI, signal: 'csi_data, 03', pin_signal: GPIO_AD_B1_14}
+ - {pin_num: L12, peripheral: CSI, signal: csi_pixclk, pin_signal: GPIO_AD_B1_04}
+ - {pin_num: K12, peripheral: CSI, signal: csi_mclk, pin_signal: GPIO_AD_B1_05}
+ - {pin_num: J12, peripheral: CSI, signal: csi_vsync, pin_signal: GPIO_AD_B1_06}
+ - {pin_num: K10, peripheral: CSI, signal: csi_hsync, pin_signal: GPIO_AD_B1_07}
+ - {pin_num: J11, peripheral: LPI2C1, signal: SCL, pin_signal: GPIO_AD_B1_00, identifier: CSI_I2C_SCL, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm,
+ pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow}
+ - {pin_num: K11, peripheral: LPI2C1, signal: SDA, pin_signal: GPIO_AD_B1_01, identifier: CSI_I2C_SDA, software_input_on: Disable, hysteresis_enable: Disable, pull_up_down_config: Pull_Up_22K_Ohm,
+ pull_keeper_select: Keeper, pull_keeper_enable: Enable, open_drain: Enable, speed: MHZ_100, drive_strength: R0_6, slew_rate: Slow}
+ - {pin_num: F11, peripheral: GPIO1, signal: 'gpio_io, 04', pin_signal: GPIO_AD_B0_04}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitCSIPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitCSIPins(void) {
+ CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
+
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B0_04_GPIO1_IO04, /* GPIO_AD_B0_04 is configured as GPIO1_IO04 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, /* GPIO_AD_B1_00 is configured as LPI2C1_SCL */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, /* GPIO_AD_B1_01 is configured as LPI2C1_SDA */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_04_CSI_PIXCLK, /* GPIO_AD_B1_04 is configured as CSI_PIXCLK */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_05_CSI_MCLK, /* GPIO_AD_B1_05 is configured as CSI_MCLK */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_06_CSI_VSYNC, /* GPIO_AD_B1_06 is configured as CSI_VSYNC */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_07_CSI_HSYNC, /* GPIO_AD_B1_07 is configured as CSI_HSYNC */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_08_CSI_DATA09, /* GPIO_AD_B1_08 is configured as CSI_DATA09 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_09_CSI_DATA08, /* GPIO_AD_B1_09 is configured as CSI_DATA08 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_10_CSI_DATA07, /* GPIO_AD_B1_10 is configured as CSI_DATA07 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_11_CSI_DATA06, /* GPIO_AD_B1_11 is configured as CSI_DATA06 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_12_CSI_DATA05, /* GPIO_AD_B1_12 is configured as CSI_DATA05 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_13_CSI_DATA04, /* GPIO_AD_B1_13 is configured as CSI_DATA04 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_14_CSI_DATA03, /* GPIO_AD_B1_14 is configured as CSI_DATA03 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B1_15_CSI_DATA02, /* GPIO_AD_B1_15 is configured as CSI_DATA02 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, /* GPIO_AD_B1_00 PAD functional properties : */
+ 0xD8B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Enabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Keeper
+ Pull Up / Down Config. Field: 22K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Disabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, /* GPIO_AD_B1_01 PAD functional properties : */
+ 0xD8B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Enabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Keeper
+ Pull Up / Down Config. Field: 22K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Disabled */
+}
+
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitLCDPins:
+- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'}
+- pin_list:
+ - {pin_num: C8, peripheral: LCDIF, signal: 'lcdif_data, 00', pin_signal: GPIO_B0_04, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: B8, peripheral: LCDIF, signal: 'lcdif_data, 01', pin_signal: GPIO_B0_05, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: A8, peripheral: LCDIF, signal: 'lcdif_data, 02', pin_signal: GPIO_B0_06, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: D7, peripheral: LCDIF, signal: lcdif_clk, pin_signal: GPIO_B0_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: A9, peripheral: LCDIF, signal: 'lcdif_data, 03', pin_signal: GPIO_B0_07, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: B9, peripheral: LCDIF, signal: 'lcdif_data, 04', pin_signal: GPIO_B0_08, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: C9, peripheral: LCDIF, signal: 'lcdif_data, 05', pin_signal: GPIO_B0_09, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: D9, peripheral: LCDIF, signal: 'lcdif_data, 06', pin_signal: GPIO_B0_10, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: A10, peripheral: LCDIF, signal: 'lcdif_data, 07', pin_signal: GPIO_B0_11, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: C10, peripheral: LCDIF, signal: 'lcdif_data, 08', pin_signal: GPIO_B0_12, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: D10, peripheral: LCDIF, signal: 'lcdif_data, 09', pin_signal: GPIO_B0_13, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: E10, peripheral: LCDIF, signal: 'lcdif_data, 10', pin_signal: GPIO_B0_14, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: E11, peripheral: LCDIF, signal: 'lcdif_data, 11', pin_signal: GPIO_B0_15, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: A11, peripheral: LCDIF, signal: 'lcdif_data, 12', pin_signal: GPIO_B1_00, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: B11, peripheral: LCDIF, signal: 'lcdif_data, 13', pin_signal: GPIO_B1_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: C11, peripheral: LCDIF, signal: 'lcdif_data, 14', pin_signal: GPIO_B1_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: D11, peripheral: LCDIF, signal: 'lcdif_data, 15', pin_signal: GPIO_B1_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: E7, peripheral: LCDIF, signal: lcdif_enable, pin_signal: GPIO_B0_01, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: E8, peripheral: LCDIF, signal: lcdif_hsync, pin_signal: GPIO_B0_02, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: D8, peripheral: LCDIF, signal: lcdif_vsync, pin_signal: GPIO_B0_03, hysteresis_enable: Enable, pull_up_down_config: Pull_Up_100K_Ohm, pull_keeper_select: Pull}
+ - {pin_num: B14, peripheral: GPIO2, signal: 'gpio_io, 31', pin_signal: GPIO_B1_15, slew_rate: Slow}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitLCDPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitLCDPins(void) {
+ CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
+
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_00_LCD_CLK, /* GPIO_B0_00 is configured as LCD_CLK */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_01_LCD_ENABLE, /* GPIO_B0_01 is configured as LCD_ENABLE */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_02_LCD_HSYNC, /* GPIO_B0_02 is configured as LCD_HSYNC */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_03_LCD_VSYNC, /* GPIO_B0_03 is configured as LCD_VSYNC */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_04_LCD_DATA00, /* GPIO_B0_04 is configured as LCD_DATA00 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_05_LCD_DATA01, /* GPIO_B0_05 is configured as LCD_DATA01 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_06_LCD_DATA02, /* GPIO_B0_06 is configured as LCD_DATA02 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_07_LCD_DATA03, /* GPIO_B0_07 is configured as LCD_DATA03 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_08_LCD_DATA04, /* GPIO_B0_08 is configured as LCD_DATA04 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_09_LCD_DATA05, /* GPIO_B0_09 is configured as LCD_DATA05 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_10_LCD_DATA06, /* GPIO_B0_10 is configured as LCD_DATA06 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_11_LCD_DATA07, /* GPIO_B0_11 is configured as LCD_DATA07 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_12_LCD_DATA08, /* GPIO_B0_12 is configured as LCD_DATA08 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_13_LCD_DATA09, /* GPIO_B0_13 is configured as LCD_DATA09 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_14_LCD_DATA10, /* GPIO_B0_14 is configured as LCD_DATA10 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B0_15_LCD_DATA11, /* GPIO_B0_15 is configured as LCD_DATA11 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_00_LCD_DATA12, /* GPIO_B1_00 is configured as LCD_DATA12 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_01_LCD_DATA13, /* GPIO_B1_01 is configured as LCD_DATA13 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_02_LCD_DATA14, /* GPIO_B1_02 is configured as LCD_DATA14 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_03_LCD_DATA15, /* GPIO_B1_03 is configured as LCD_DATA15 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_15_GPIO2_IO31, /* GPIO_B1_15 is configured as GPIO2_IO31 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_00_LCD_CLK, /* GPIO_B0_00 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_01_LCD_ENABLE, /* GPIO_B0_01 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_02_LCD_HSYNC, /* GPIO_B0_02 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_03_LCD_VSYNC, /* GPIO_B0_03 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_04_LCD_DATA00, /* GPIO_B0_04 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_05_LCD_DATA01, /* GPIO_B0_05 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_06_LCD_DATA02, /* GPIO_B0_06 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_07_LCD_DATA03, /* GPIO_B0_07 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_08_LCD_DATA04, /* GPIO_B0_08 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_09_LCD_DATA05, /* GPIO_B0_09 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_10_LCD_DATA06, /* GPIO_B0_10 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_11_LCD_DATA07, /* GPIO_B0_11 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_12_LCD_DATA08, /* GPIO_B0_12 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_13_LCD_DATA09, /* GPIO_B0_13 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_14_LCD_DATA10, /* GPIO_B0_14 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B0_15_LCD_DATA11, /* GPIO_B0_15 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B1_00_LCD_DATA12, /* GPIO_B1_00 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B1_01_LCD_DATA13, /* GPIO_B1_01 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B1_02_LCD_DATA14, /* GPIO_B1_02 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B1_03_LCD_DATA15, /* GPIO_B1_03 PAD functional properties : */
+ 0x01B0B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Pull
+ Pull Up / Down Config. Field: 100K Ohm Pull Up
+ Hyst. Enable Field: Hysteresis Enabled */
+ IOMUXC_SetPinConfig(
+ IOMUXC_GPIO_B1_15_GPIO2_IO31, /* GPIO_B1_15 PAD functional properties : */
+ 0x10B0u); /* Slew Rate Field: Slow Slew Rate
+ Drive Strength Field: R0/6
+ Speed Field: medium(100MHz)
+ Open Drain Enable Field: Open Drain Disabled
+ Pull / Keep Enable Field: Pull/Keeper Enabled
+ Pull / Keep Select Field: Keeper
+ Pull Up / Down Config. Field: 100K Ohm Pull Down
+ Hyst. Enable Field: Hysteresis Disabled */
+}
+
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitCANPins:
+- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'}
+- pin_list:
+ - {pin_num: H14, peripheral: CAN2, signal: TX, pin_signal: GPIO_AD_B0_14}
+ - {pin_num: L10, peripheral: CAN2, signal: RX, pin_signal: GPIO_AD_B0_15}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitCANPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitCANPins(void) {
+ CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
+
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B0_14_FLEXCAN2_TX, /* GPIO_AD_B0_14 is configured as FLEXCAN2_TX */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_AD_B0_15_FLEXCAN2_RX, /* GPIO_AD_B0_15 is configured as FLEXCAN2_RX */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+}
+
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitENETPins:
+- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'}
+- pin_list:
+ - {pin_num: A7, peripheral: ENET, signal: enet_mdc, pin_signal: GPIO_EMC_40}
+ - {pin_num: C7, peripheral: ENET, signal: enet_mdio, pin_signal: GPIO_EMC_41}
+ - {pin_num: B13, peripheral: ENET, signal: enet_ref_clk, pin_signal: GPIO_B1_10}
+ - {pin_num: E12, peripheral: ENET, signal: 'enet_rx_data, 0', pin_signal: GPIO_B1_04}
+ - {pin_num: D12, peripheral: ENET, signal: 'enet_rx_data, 1', pin_signal: GPIO_B1_05}
+ - {pin_num: C12, peripheral: ENET, signal: enet_rx_en, pin_signal: GPIO_B1_06}
+ - {pin_num: C13, peripheral: ENET, signal: enet_rx_er, pin_signal: GPIO_B1_11}
+ - {pin_num: B12, peripheral: ENET, signal: 'enet_tx_data, 0', pin_signal: GPIO_B1_07}
+ - {pin_num: A12, peripheral: ENET, signal: 'enet_tx_data, 1', pin_signal: GPIO_B1_08}
+ - {pin_num: A13, peripheral: ENET, signal: enet_tx_en, pin_signal: GPIO_B1_09}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitENETPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitENETPins(void) {
+ CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
+
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_04_ENET_RX_DATA00, /* GPIO_B1_04 is configured as ENET_RX_DATA00 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_05_ENET_RX_DATA01, /* GPIO_B1_05 is configured as ENET_RX_DATA01 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_06_ENET_RX_EN, /* GPIO_B1_06 is configured as ENET_RX_EN */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_07_ENET_TX_DATA00, /* GPIO_B1_07 is configured as ENET_TX_DATA00 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_08_ENET_TX_DATA01, /* GPIO_B1_08 is configured as ENET_TX_DATA01 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_09_ENET_TX_EN, /* GPIO_B1_09 is configured as ENET_TX_EN */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_10_ENET_REF_CLK, /* GPIO_B1_10 is configured as ENET_REF_CLK */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_B1_11_ENET_RX_ER, /* GPIO_B1_11 is configured as ENET_RX_ER */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_40_ENET_MDC, /* GPIO_EMC_40 is configured as ENET_MDC */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_EMC_41_ENET_MDIO, /* GPIO_EMC_41 is configured as ENET_MDIO */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+}
+
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitUSDHCPins:
+- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'}
+- pin_list:
+ - {pin_num: J2, peripheral: USDHC1, signal: 'usdhc_data, 3', pin_signal: GPIO_SD_B0_05}
+ - {pin_num: H2, peripheral: USDHC1, signal: 'usdhc_data, 2', pin_signal: GPIO_SD_B0_04}
+ - {pin_num: K1, peripheral: USDHC1, signal: 'usdhc_data, 1', pin_signal: GPIO_SD_B0_03}
+ - {pin_num: J1, peripheral: USDHC1, signal: 'usdhc_data, 0', pin_signal: GPIO_SD_B0_02}
+ - {pin_num: J4, peripheral: USDHC1, signal: usdhc_cmd, pin_signal: GPIO_SD_B0_00}
+ - {pin_num: J3, peripheral: USDHC1, signal: usdhc_clk, pin_signal: GPIO_SD_B0_01}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitUSDHCPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitUSDHCPins(void) {
+ CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
+
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, /* GPIO_SD_B0_00 is configured as USDHC1_CMD */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B0_01_USDHC1_CLK, /* GPIO_SD_B0_01 is configured as USDHC1_CLK */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B0_02_USDHC1_DATA0, /* GPIO_SD_B0_02 is configured as USDHC1_DATA0 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B0_03_USDHC1_DATA1, /* GPIO_SD_B0_03 is configured as USDHC1_DATA1 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B0_04_USDHC1_DATA2, /* GPIO_SD_B0_04 is configured as USDHC1_DATA2 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B0_05_USDHC1_DATA3, /* GPIO_SD_B0_05 is configured as USDHC1_DATA3 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+}
+
+
+/*
+ * TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
+BOARD_InitHyperFlashPins:
+- options: {callFromInitBoot: 'false', coreID: core0, enableClock: 'true'}
+- pin_list:
+ - {pin_num: L4, peripheral: FLEXSPI, signal: FLEXSPI_A_SCLK, pin_signal: GPIO_SD_B1_07}
+ - {pin_num: P4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA2, pin_signal: GPIO_SD_B1_10}
+ - {pin_num: P3, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA0, pin_signal: GPIO_SD_B1_08}
+ - {pin_num: N4, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA1, pin_signal: GPIO_SD_B1_09}
+ - {pin_num: L5, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA3, pin_signal: GPIO_SD_B1_00}
+ - {pin_num: M5, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA2, pin_signal: GPIO_SD_B1_01}
+ - {pin_num: M3, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA1, pin_signal: GPIO_SD_B1_02}
+ - {pin_num: M4, peripheral: FLEXSPI, signal: FLEXSPI_B_DATA0, pin_signal: GPIO_SD_B1_03}
+ - {pin_num: P2, peripheral: FLEXSPI, signal: FLEXSPI_B_SCLK, pin_signal: GPIO_SD_B1_04}
+ - {pin_num: L3, peripheral: FLEXSPI, signal: FLEXSPI_A_SS0_B, pin_signal: GPIO_SD_B1_06}
+ - {pin_num: P5, peripheral: FLEXSPI, signal: FLEXSPI_A_DATA3, pin_signal: GPIO_SD_B1_11}
+ - {pin_num: N3, peripheral: FLEXSPI, signal: FLEXSPI_A_DQS, pin_signal: GPIO_SD_B1_05}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
+ */
+
+/* FUNCTION ************************************************************************************************************
+ *
+ * Function Name : BOARD_InitHyperFlashPins
+ * Description : Configures pin routing and optionally pin electrical features.
+ *
+ * END ****************************************************************************************************************/
+void BOARD_InitHyperFlashPins(void) {
+ CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
+
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_00_FLEXSPIB_DATA03, /* GPIO_SD_B1_00 is configured as FLEXSPIB_DATA03 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_01_FLEXSPIB_DATA02, /* GPIO_SD_B1_01 is configured as FLEXSPIB_DATA02 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_02_FLEXSPIB_DATA01, /* GPIO_SD_B1_02 is configured as FLEXSPIB_DATA01 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_03_FLEXSPIB_DATA00, /* GPIO_SD_B1_03 is configured as FLEXSPIB_DATA00 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_04_FLEXSPIB_SCLK, /* GPIO_SD_B1_04 is configured as FLEXSPIB_SCLK */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, /* GPIO_SD_B1_05 is configured as FLEXSPIA_DQS */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, /* GPIO_SD_B1_06 is configured as FLEXSPIA_SS0_B */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, /* GPIO_SD_B1_07 is configured as FLEXSPIA_SCLK */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, /* GPIO_SD_B1_08 is configured as FLEXSPIA_DATA00 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, /* GPIO_SD_B1_09 is configured as FLEXSPIA_DATA01 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, /* GPIO_SD_B1_10 is configured as FLEXSPIA_DATA02 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(
+ IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, /* GPIO_SD_B1_11 is configured as FLEXSPIA_DATA03 */
+ 0U); /* Software Input On Field: Input Path is determined by functionality */
+}
+
+/***********************************************************************************************************************
+ * EOF
+ **********************************************************************************************************************/
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc.c
new file mode 100644
index 0000000000..d93de620c0
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_adc.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.adc_12b1msps_sar"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Get instance number for ADC module.
+ *
+ * @param base ADC peripheral base address
+ */
+static uint32_t ADC_GetInstance(ADC_Type *base);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief Pointers to ADC bases for each instance. */
+static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to ADC clocks for each instance. */
+static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static uint32_t ADC_GetInstance(ADC_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++)
+ {
+ if (s_adcBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_adcBases));
+
+ return instance;
+}
+
+/*!
+ * brief Initialize the ADC module.
+ *
+ * param base ADC peripheral base address.
+ * param config Pointer to "adc_config_t" structure.
+ */
+void ADC_Init(ADC_Type *base, const adc_config_t *config)
+{
+ assert(NULL != config);
+
+ uint32_t tmp32;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Enable the clock. */
+ CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+ /* ADCx_CFG */
+ tmp32 = base->CFG & (ADC_CFG_AVGS_MASK | ADC_CFG_ADTRG_MASK); /* Reserve AVGS and ADTRG bits. */
+ tmp32 |= ADC_CFG_REFSEL(config->referenceVoltageSource) | ADC_CFG_ADSTS(config->samplePeriodMode) |
+ ADC_CFG_ADICLK(config->clockSource) | ADC_CFG_ADIV(config->clockDriver) | ADC_CFG_MODE(config->resolution);
+ if (config->enableOverWrite)
+ {
+ tmp32 |= ADC_CFG_OVWREN_MASK;
+ }
+ if (config->enableLongSample)
+ {
+ tmp32 |= ADC_CFG_ADLSMP_MASK;
+ }
+ if (config->enableLowPower)
+ {
+ tmp32 |= ADC_CFG_ADLPC_MASK;
+ }
+ if (config->enableHighSpeed)
+ {
+ tmp32 |= ADC_CFG_ADHSC_MASK;
+ }
+ base->CFG = tmp32;
+
+ /* ADCx_GC */
+ tmp32 = base->GC & ~(ADC_GC_ADCO_MASK | ADC_GC_ADACKEN_MASK);
+ if (config->enableContinuousConversion)
+ {
+ tmp32 |= ADC_GC_ADCO_MASK;
+ }
+ if (config->enableAsynchronousClockOutput)
+ {
+ tmp32 |= ADC_GC_ADACKEN_MASK;
+ }
+ base->GC = tmp32;
+}
+
+/*!
+ * brief De-initializes the ADC module.
+ *
+ * param base ADC peripheral base address.
+ */
+void ADC_Deinit(ADC_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Disable the clock. */
+ CLOCK_DisableClock(s_adcClocks[ADC_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Gets an available pre-defined settings for the converter's configuration.
+ *
+ * This function initializes the converter configuration structure with available settings. The default values are:
+ * code
+ * config->enableAsynchronousClockOutput = true;
+ * config->enableOverWrite = false;
+ * config->enableContinuousConversion = false;
+ * config->enableHighSpeed = false;
+ * config->enableLowPower = false;
+ * config->enableLongSample = false;
+ * config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
+ * config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
+ * config->clockSource = kADC_ClockSourceAD;
+ * config->clockDriver = kADC_ClockDriver1;
+ * config->resolution = kADC_Resolution12Bit;
+ * endcode
+ * param base ADC peripheral base address.
+ * param config Pointer to the configuration structure.
+ */
+void ADC_GetDefaultConfig(adc_config_t *config)
+{
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->enableAsynchronousClockOutput = true;
+ config->enableOverWrite = false;
+ config->enableContinuousConversion = false;
+ config->enableHighSpeed = false;
+ config->enableLowPower = false;
+ config->enableLongSample = false;
+ config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
+ config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
+ config->clockSource = kADC_ClockSourceAD;
+ config->clockDriver = kADC_ClockDriver1;
+ config->resolution = kADC_Resolution12Bit;
+}
+
+/*!
+ * brief Configures the conversion channel.
+ *
+ * This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API
+ * configures the channel while the external trigger source helps to trigger the conversion.
+ *
+ * Note that the "Channel Group" has a detailed description.
+ * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one
+ * group of status and control registers, one for each conversion. The channel group parameter indicates which group of
+ * registers are used, for example channel group 0 is for Group A registers and channel group 1 is for Group B
+ * registers. The
+ * channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of
+ * the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and
+ * hardware
+ * trigger modes. Channel groups 1 and greater indicate potentially multiple channel group registers for
+ * use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual
+ * about the
+ * number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used
+ * for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion.
+ * Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and
+ * vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a
+ * conversion aborts the current conversion.
+ *
+ * param base ADC peripheral base address.
+ * param channelGroup Channel group index.
+ * param config Pointer to the "adc_channel_config_t" structure for the conversion channel.
+ */
+void ADC_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc_channel_config_t *config)
+{
+ assert(NULL != config);
+ assert(channelGroup < FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT);
+
+ uint32_t tmp32;
+
+ tmp32 = ADC_HC_ADCH(config->channelNumber);
+ if (config->enableInterruptOnConversionCompleted)
+ {
+ tmp32 |= ADC_HC_AIEN_MASK;
+ }
+ base->HC[channelGroup] = tmp32;
+}
+
+/*
+ *To complete calibration, the user must follow the below procedure:
+ * 1. Configure ADC_CFG with actual operating values for maximum accuracy.
+ * 2. Configure the ADC_GC values along with CAL bit.
+ * 3. Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC.
+ * 4. When CAL bit becomes '0' then check the CALF status and COCO[0] bit status.
+ */
+/*!
+ * brief Automates the hardware calibration.
+ *
+ * This auto calibration helps to adjust the plus/minus side gain automatically.
+ * Execute the calibration before using the converter. Note that the software trigger should be used
+ * during calibration.
+ *
+ * param base ADC peripheral base address.
+ *
+ * return Execution status.
+ * retval kStatus_Success Calibration is done successfully.
+ * retval kStatus_Fail Calibration has failed.
+ */
+status_t ADC_DoAutoCalibration(ADC_Type *base)
+{
+ status_t status = kStatus_Success;
+#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
+ bool bHWTrigger = false;
+
+ /* The calibration would be failed when in hardwar mode.
+ * Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/
+ if (0U != (ADC_CFG_ADTRG_MASK & base->CFG))
+ {
+ bHWTrigger = true;
+ ADC_EnableHardwareTrigger(base, false);
+ }
+#endif
+
+ /* Clear the CALF and launch the calibration. */
+ base->GS = ADC_GS_CALF_MASK; /* Clear the CALF. */
+ base->GC |= ADC_GC_CAL_MASK; /* Launch the calibration. */
+
+ /* Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC. */
+ while (0U != (base->GC & ADC_GC_CAL_MASK))
+ {
+ /* Check the CALF when the calibration is active. */
+ if (0U != (ADC_GetStatusFlags(base) & (uint32_t)kADC_CalibrationFailedFlag))
+ {
+ status = kStatus_Fail;
+ break;
+ }
+ }
+
+ /* When CAL bit becomes '0' then check the CALF status and COCO[0] bit status. */
+ if (0U == ADC_GetChannelStatusFlags(base, 0U)) /* Check the COCO[0] bit status. */
+ {
+ status = kStatus_Fail;
+ }
+ if (0U != (ADC_GetStatusFlags(base) & (uint32_t)kADC_CalibrationFailedFlag)) /* Check the CALF status. */
+ {
+ status = kStatus_Fail;
+ }
+
+ /* Clear conversion done flag. */
+ (void)ADC_GetChannelConversionValue(base, 0U);
+
+#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
+ /* Restore original trigger mode. */
+ if (true == bHWTrigger)
+ {
+ ADC_EnableHardwareTrigger(base, true);
+ }
+#endif
+
+ return status;
+}
+
+/*!
+ * brief Set user defined offset.
+ *
+ * param base ADC peripheral base address.
+ * param config Pointer to "adc_offest_config_t" structure.
+ */
+void ADC_SetOffsetConfig(ADC_Type *base, const adc_offest_config_t *config)
+{
+ assert(NULL != config);
+
+ uint32_t tmp32;
+
+ tmp32 = ADC_OFS_OFS(config->offsetValue);
+ if (config->enableSigned)
+ {
+ tmp32 |= ADC_OFS_SIGN_MASK;
+ }
+ base->OFS = tmp32;
+}
+
+/*!
+ * brief Configures the hardware compare mode.
+ *
+ * The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the
+ * result
+ * in the compare range is available. To compare the range, see "adc_hardware_compare_mode_t" or the appopriate
+ * reference
+ * manual for more information.
+ *
+ * param base ADC peripheral base address.
+ * param Pointer to "adc_hardware_compare_config_t" structure.
+ *
+ */
+void ADC_SetHardwareCompareConfig(ADC_Type *base, const adc_hardware_compare_config_t *config)
+{
+ uint32_t tmp32;
+
+ tmp32 = base->GC & ~(ADC_GC_ACFE_MASK | ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK);
+ if (NULL == config) /* Pass "NULL" to disable the feature. */
+ {
+ base->GC = tmp32;
+ return;
+ }
+ /* Enable the feature. */
+ tmp32 |= ADC_GC_ACFE_MASK;
+
+ /* Select the hardware compare working mode. */
+ switch (config->hardwareCompareMode)
+ {
+ case kADC_HardwareCompareMode0:
+ break;
+ case kADC_HardwareCompareMode1:
+ tmp32 |= ADC_GC_ACFGT_MASK;
+ break;
+ case kADC_HardwareCompareMode2:
+ tmp32 |= ADC_GC_ACREN_MASK;
+ break;
+ case kADC_HardwareCompareMode3:
+ tmp32 |= ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK;
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ base->GC = tmp32;
+
+ /* Load the compare values. */
+ tmp32 = ADC_CV_CV1(config->value1) | ADC_CV_CV2(config->value2);
+ base->CV = tmp32;
+}
+
+/*!
+ * brief Configures the hardware average mode.
+ *
+ * The hardware average mode provides a way to process the conversion result automatically by using hardware. The
+ * multiple
+ * conversion results are accumulated and averaged internally making them easier to read.
+ *
+ * param base ADC peripheral base address.
+ * param mode Setting the hardware average mode. See "adc_hardware_average_mode_t".
+ */
+void ADC_SetHardwareAverageConfig(ADC_Type *base, adc_hardware_average_mode_t mode)
+{
+ uint32_t tmp32;
+
+ if (mode == kADC_HardwareAverageDiasable)
+ {
+ base->GC &= ~ADC_GC_AVGE_MASK;
+ }
+ else
+ {
+ tmp32 = base->CFG & ~ADC_CFG_AVGS_MASK;
+ tmp32 |= ADC_CFG_AVGS(mode);
+ base->CFG = tmp32;
+ base->GC |= ADC_GC_AVGE_MASK; /* Enable the hardware compare. */
+ }
+}
+
+/*!
+ * brief Clears the converter's status falgs.
+ *
+ * param base ADC peripheral base address.
+ * param mask Mask value for the cleared flags. See "adc_status_flags_t".
+ */
+void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask)
+{
+ uint32_t tmp32 = 0;
+
+ if (0U != (mask & (uint32_t)kADC_CalibrationFailedFlag))
+ {
+ tmp32 |= ADC_GS_CALF_MASK;
+ }
+ if (0U != (mask & (uint32_t)kADC_ConversionActiveFlag))
+ {
+ tmp32 |= ADC_GS_ADACT_MASK;
+ }
+ base->GS = tmp32;
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc_etc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc_etc.c
new file mode 100644
index 0000000000..d912b7045c
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc_etc.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_adc_etc.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.adc_etc"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+#if defined(ADC_ETC_CLOCKS)
+/*!
+ * @brief Get instance number for ADC_ETC module.
+ *
+ * @param base ADC_ETC peripheral base address
+ */
+static uint32_t ADC_ETC_GetInstance(ADC_ETC_Type *base);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief Pointers to ADC_ETC bases for each instance. */
+static ADC_ETC_Type *const s_adcetcBases[] = ADC_ETC_BASE_PTRS;
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to ADC_ETC clocks for each instance. */
+static const clock_ip_name_t s_adcetcClocks[] = ADC_ETC_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static uint32_t ADC_ETC_GetInstance(ADC_ETC_Type *base)
+{
+ uint32_t instance = 0U;
+ uint32_t adcetcArrayCount = (sizeof(s_adcetcBases) / sizeof(s_adcetcBases[0]));
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < adcetcArrayCount; instance++)
+ {
+ if (s_adcetcBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ return instance;
+}
+#endif /* ADC_ETC_CLOCKS */
+
+/*!
+ * brief Initialize the ADC_ETC module.
+ *
+ * param base ADC_ETC peripheral base address.
+ * param config Pointer to "adc_etc_config_t" structure.
+ */
+void ADC_ETC_Init(ADC_ETC_Type *base, const adc_etc_config_t *config)
+{
+ assert(NULL != config);
+
+ uint32_t tmp32 = 0U;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+#if defined(ADC_ETC_CLOCKS)
+ /* Open clock gate. */
+ CLOCK_EnableClock(s_adcetcClocks[ADC_ETC_GetInstance(base)]);
+#endif /* ADC_ETC_CLOCKS */
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+ /* Disable software reset. */
+ ADC_ETC_DoSoftwareReset(base, false);
+
+ /* Set ADC_ETC_CTRL register. */
+ tmp32 = ADC_ETC_CTRL_EXT0_TRIG_PRIORITY(config->TSC0triggerPriority) |
+ ADC_ETC_CTRL_EXT1_TRIG_PRIORITY(config->TSC1triggerPriority) |
+ ADC_ETC_CTRL_PRE_DIVIDER(config->clockPreDivider) | ADC_ETC_CTRL_TRIG_ENABLE(config->XBARtriggerMask)
+#if defined(FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL) && FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL
+ | ADC_ETC_CTRL_DMA_MODE_SEL(config->dmaMode)
+#endif /*FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL*/
+ ;
+ if (config->enableTSCBypass)
+ {
+ tmp32 |= ADC_ETC_CTRL_TSC_BYPASS_MASK;
+ }
+ if (config->enableTSC0Trigger)
+ {
+ tmp32 |= ADC_ETC_CTRL_EXT0_TRIG_ENABLE_MASK;
+ }
+ if (config->enableTSC1Trigger)
+ {
+ tmp32 |= ADC_ETC_CTRL_EXT1_TRIG_ENABLE_MASK;
+ }
+ base->CTRL = tmp32;
+}
+
+/*!
+ * brief De-Initialize the ADC_ETC module.
+ *
+ * param base ADC_ETC peripheral base address.
+ */
+void ADC_ETC_Deinit(ADC_ETC_Type *base)
+{
+ /* Do software reset to clear all logical. */
+ ADC_ETC_DoSoftwareReset(base, true);
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+#if defined(ADC_ETC_CLOCKS)
+ /* Close clock gate. */
+ CLOCK_DisableClock(s_adcetcClocks[ADC_ETC_GetInstance(base)]);
+#endif /* ADC_ETC_CLOCKS */
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Gets an available pre-defined settings for the ADC_ETC's configuration.
+ * This function initializes the ADC_ETC's configuration structure with available settings. The default values are:
+ * code
+ * config->enableTSCBypass = true;
+ * config->enableTSC0Trigger = false;
+ * config->enableTSC1Trigger = false;
+ * config->TSC0triggerPriority = 0U;
+ * config->TSC1triggerPriority = 0U;
+ * config->clockPreDivider = 0U;
+ * config->XBARtriggerMask = 0U;
+ * endCode
+ *
+ * param config Pointer to "adc_etc_config_t" structure.
+ */
+void ADC_ETC_GetDefaultConfig(adc_etc_config_t *config)
+{
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->enableTSCBypass = true;
+ config->enableTSC0Trigger = false;
+ config->enableTSC1Trigger = false;
+#if defined(FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL) && FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL
+ config->dmaMode = kADC_ETC_TrigDMAWithLatchedSignal;
+#endif /*FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL*/
+ config->TSC0triggerPriority = 0U;
+ config->TSC1triggerPriority = 0U;
+ config->clockPreDivider = 0U;
+ config->XBARtriggerMask = 0U;
+}
+
+/*!
+ * brief Set the external XBAR trigger configuration.
+ *
+ * param base ADC_ETC peripheral base address.
+ * param triggerGroup Trigger group index.
+ * param config Pointer to "adc_etc_trigger_config_t" structure.
+ */
+void ADC_ETC_SetTriggerConfig(ADC_ETC_Type *base, uint32_t triggerGroup, const adc_etc_trigger_config_t *config)
+{
+ assert(triggerGroup < ADC_ETC_TRIGn_CTRL_COUNT);
+ assert(ADC_ETC_TRIGn_COUNTER_COUNT > triggerGroup);
+
+ uint32_t tmp32 = 0U;
+
+ /* Set ADC_ETC_TRGn_CTRL register. */
+ tmp32 = ADC_ETC_TRIGn_CTRL_TRIG_CHAIN(config->triggerChainLength) |
+ ADC_ETC_TRIGn_CTRL_TRIG_PRIORITY(config->triggerPriority);
+ if (config->enableSyncMode)
+ {
+ tmp32 |= ADC_ETC_TRIGn_CTRL_SYNC_MODE_MASK;
+ }
+ if (config->enableSWTriggerMode)
+ {
+ tmp32 |= ADC_ETC_TRIGn_CTRL_TRIG_MODE_MASK;
+ }
+ base->TRIG[triggerGroup].TRIGn_CTRL = tmp32;
+
+ /* Set ADC_ETC_TRGn_COUNTER register. */
+ tmp32 = ADC_ETC_TRIGn_COUNTER_INIT_DELAY(config->initialDelay) |
+ ADC_ETC_TRIGn_COUNTER_SAMPLE_INTERVAL(config->sampleIntervalDelay);
+ base->TRIG[triggerGroup].TRIGn_COUNTER = tmp32;
+}
+
+/*!
+ * brief Set the external XBAR trigger chain configuration.
+ * For example, if triggerGroup is set to 0U and chainGroup is set to 1U, which means Trigger0 source's chain1 would be
+ * configurated.
+ *
+ * param base ADC_ETC peripheral base address.
+ * param triggerGroup Trigger group index. Available number is 0~7.
+ * param chainGroup Trigger chain group index. Available number is 0~7.
+ * param config Pointer to "adc_etc_trigger_chain_config_t" structure.
+ */
+void ADC_ETC_SetTriggerChainConfig(ADC_ETC_Type *base,
+ uint32_t triggerGroup,
+ uint32_t chainGroup,
+ const adc_etc_trigger_chain_config_t *config)
+{
+ assert(triggerGroup < ADC_ETC_TRIGn_CTRL_COUNT);
+
+ uint32_t tmp32 = 0U;
+ uint32_t tmpReg = 0U;
+ uint8_t mRemainder = (uint8_t)(chainGroup % 2U);
+
+ /* Set ADC_ETC_TRIGn_CHAINm register. */
+ tmp32 = ADC_ETC_TRIGn_CHAIN_1_0_HWTS0(config->ADCHCRegisterSelect) |
+ ADC_ETC_TRIGn_CHAIN_1_0_CSEL0(config->ADCChannelSelect) |
+ ADC_ETC_TRIGn_CHAIN_1_0_IE0(config->InterruptEnable);
+ if (true == config->enableB2BMode)
+ {
+ tmp32 |= ADC_ETC_TRIGn_CHAIN_1_0_B2B0_MASK;
+ }
+#if defined(FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN) && FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN
+ if (true == config->enableIrq)
+ {
+ tmp32 |= ADC_ETC_TRIGn_CHAIN_1_0_IE0_EN_MASK;
+ }
+#endif /* FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN */
+ switch (chainGroup / 2U)
+ {
+ case 0U: /* Configurate trigger chain0 and chain 1. */
+ tmpReg = base->TRIG[triggerGroup].TRIGn_CHAIN_1_0;
+ if (mRemainder == 0U) /* Chain 0. */
+ {
+ tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_1_0_CSEL0_MASK | ADC_ETC_TRIGn_CHAIN_1_0_HWTS0_MASK |
+ ADC_ETC_TRIGn_CHAIN_1_0_B2B0_MASK | ADC_ETC_TRIGn_CHAIN_1_0_IE0_MASK);
+ tmpReg |= tmp32;
+ }
+ else /* Chain 1. */
+ {
+ tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_1_0_CSEL1_MASK | ADC_ETC_TRIGn_CHAIN_1_0_HWTS1_MASK |
+ ADC_ETC_TRIGn_CHAIN_1_0_B2B1_MASK | ADC_ETC_TRIGn_CHAIN_1_0_IE1_MASK);
+ tmpReg |= (tmp32 << ADC_ETC_TRIGn_CHAIN_1_0_CSEL1_SHIFT);
+ }
+ base->TRIG[triggerGroup].TRIGn_CHAIN_1_0 = tmpReg;
+ break;
+ case 1U: /* Configurate trigger chain2 and chain 3. */
+ tmpReg = base->TRIG[triggerGroup].TRIGn_CHAIN_3_2;
+ if (mRemainder == 0U) /* Chain 2. */
+ {
+ tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_3_2_CSEL2_MASK | ADC_ETC_TRIGn_CHAIN_3_2_HWTS2_MASK |
+ ADC_ETC_TRIGn_CHAIN_3_2_B2B2_MASK | ADC_ETC_TRIGn_CHAIN_3_2_IE2_MASK);
+ tmpReg |= tmp32;
+ }
+ else /* Chain 3. */
+ {
+ tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_3_2_CSEL3_MASK | ADC_ETC_TRIGn_CHAIN_3_2_HWTS3_MASK |
+ ADC_ETC_TRIGn_CHAIN_3_2_B2B3_MASK | ADC_ETC_TRIGn_CHAIN_3_2_IE3_MASK);
+ tmpReg |= (tmp32 << ADC_ETC_TRIGn_CHAIN_3_2_CSEL3_SHIFT);
+ }
+ base->TRIG[triggerGroup].TRIGn_CHAIN_3_2 = tmpReg;
+ break;
+ case 2U: /* Configurate trigger chain4 and chain 5. */
+ tmpReg = base->TRIG[triggerGroup].TRIGn_CHAIN_5_4;
+ if (mRemainder == 0U) /* Chain 4. */
+ {
+ tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_5_4_CSEL4_MASK | ADC_ETC_TRIGn_CHAIN_5_4_HWTS4_MASK |
+ ADC_ETC_TRIGn_CHAIN_5_4_B2B4_MASK | ADC_ETC_TRIGn_CHAIN_5_4_IE4_MASK);
+ tmpReg |= tmp32;
+ }
+ else /* Chain 5. */
+ {
+ tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_5_4_CSEL5_MASK | ADC_ETC_TRIGn_CHAIN_5_4_HWTS5_MASK |
+ ADC_ETC_TRIGn_CHAIN_5_4_B2B5_MASK | ADC_ETC_TRIGn_CHAIN_5_4_IE5_MASK);
+ tmpReg |= (tmp32 << ADC_ETC_TRIGn_CHAIN_5_4_CSEL5_SHIFT);
+ }
+ base->TRIG[triggerGroup].TRIGn_CHAIN_5_4 = tmpReg;
+ break;
+ case 3U: /* Configurate trigger chain6 and chain 7. */
+ tmpReg = base->TRIG[triggerGroup].TRIGn_CHAIN_7_6;
+ if (mRemainder == 0U) /* Chain 6. */
+ {
+ tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_7_6_CSEL6_MASK | ADC_ETC_TRIGn_CHAIN_7_6_HWTS6_MASK |
+ ADC_ETC_TRIGn_CHAIN_7_6_B2B6_MASK | ADC_ETC_TRIGn_CHAIN_7_6_IE6_MASK);
+ tmpReg |= tmp32;
+ }
+ else /* Chain 7. */
+ {
+ tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_7_6_CSEL7_MASK | ADC_ETC_TRIGn_CHAIN_7_6_HWTS7_MASK |
+ ADC_ETC_TRIGn_CHAIN_7_6_B2B7_MASK | ADC_ETC_TRIGn_CHAIN_7_6_IE7_MASK);
+ tmpReg |= (tmp32 << ADC_ETC_TRIGn_CHAIN_7_6_CSEL7_SHIFT);
+ }
+ base->TRIG[triggerGroup].TRIGn_CHAIN_7_6 = tmpReg;
+ break;
+ default:
+ assert(false);
+ break;
+ }
+}
+
+/*!
+ * brief Gets the interrupt status flags of external XBAR and TSC triggers.
+ *
+ * param base ADC_ETC peripheral base address.
+ * param sourceIndex trigger source index.
+ *
+ * return Status flags mask of trigger. Refer to "_adc_etc_status_flag_mask".
+ */
+uint32_t ADC_ETC_GetInterruptStatusFlags(ADC_ETC_Type *base, adc_etc_external_trigger_source_t sourceIndex)
+{
+ uint32_t tmp32 = 0U;
+
+ if (((base->DONE0_1_IRQ) & ((uint32_t)ADC_ETC_DONE0_1_IRQ_TRIG0_DONE0_MASK << (uint32_t)sourceIndex)) != 0U)
+ {
+ tmp32 |= (uint32_t)kADC_ETC_Done0StatusFlagMask; /* Customized DONE0 status flags mask, which is defined in
+ fsl_adc_etc.h file. */
+ }
+ if (((base->DONE0_1_IRQ) & ((uint32_t)ADC_ETC_DONE0_1_IRQ_TRIG0_DONE1_MASK << (uint32_t)sourceIndex)) != 0U)
+ {
+ tmp32 |= (uint32_t)kADC_ETC_Done1StatusFlagMask; /* Customized DONE1 status flags mask, which is defined in
+ fsl_adc_etc.h file. */
+ }
+ if (((base->DONE2_ERR_IRQ) & ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE2_MASK << (uint32_t)sourceIndex)) != 0U)
+ {
+ tmp32 |= (uint32_t)kADC_ETC_Done2StatusFlagMask; /* Customized DONE2 status flags mask, which is defined in
+ fsl_adc_etc.h file. */
+ }
+#if defined(FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN) && FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN
+ if (((base->DONE2_ERR_IRQ) & ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE3_MASK << (uint32_t)sourceIndex)) != 0U)
+ {
+ tmp32 |= (uint32_t)kADC_ETC_Done3StatusFlagMask; /* Customized DONE3 status flags mask, which is defined in
+ fsl_adc_etc.h file. */
+ }
+#endif /* FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN */
+ if (((base->DONE2_ERR_IRQ) & ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_ERR_MASK << (uint32_t)sourceIndex)) != 0U)
+ {
+ tmp32 |= (uint32_t)kADC_ETC_ErrorStatusFlagMask; /* Customized ERROR status flags mask, which is defined in
+ fsl_adc_etc.h file. */
+ }
+ return tmp32;
+}
+
+/*!
+ * brief Clears the ADC_ETC's interrupt status falgs.
+ *
+ * param base ADC_ETC peripheral base address.
+ * param sourceIndex trigger source index.
+ * param mask Status flags mask of trigger. Refer to "_adc_etc_status_flag_mask".
+ */
+void ADC_ETC_ClearInterruptStatusFlags(ADC_ETC_Type *base, adc_etc_external_trigger_source_t sourceIndex, uint32_t mask)
+{
+ if (0U != (mask & (uint32_t)kADC_ETC_Done0StatusFlagMask)) /* Write 1 to clear DONE0 status flags. */
+ {
+ base->DONE0_1_IRQ = ((uint32_t)ADC_ETC_DONE0_1_IRQ_TRIG0_DONE0_MASK << (uint32_t)sourceIndex);
+ }
+ if (0U != (mask & (uint32_t)kADC_ETC_Done1StatusFlagMask)) /* Write 1 to clear DONE1 status flags. */
+ {
+ base->DONE0_1_IRQ = ((uint32_t)ADC_ETC_DONE0_1_IRQ_TRIG0_DONE1_MASK << (uint32_t)sourceIndex);
+ }
+ if (0U != (mask & (uint32_t)kADC_ETC_Done2StatusFlagMask)) /* Write 1 to clear DONE2 status flags. */
+ {
+ base->DONE2_ERR_IRQ = ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE2_MASK << (uint32_t)sourceIndex);
+ }
+#if defined(FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN) && FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN
+ if (0U != (mask & (uint32_t)kADC_ETC_Done3StatusFlagMask)) /* Write 1 to clear DONE3 status flags. */
+ {
+ base->DONE2_ERR_IRQ = ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE3_MASK << (uint32_t)sourceIndex);
+ }
+#endif /* FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN */
+ if (0U != (mask & (uint32_t)kADC_ETC_ErrorStatusFlagMask)) /* Write 1 to clear ERROR status flags. */
+ {
+ base->DONE2_ERR_IRQ = ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_ERR_MASK << (uint32_t)sourceIndex);
+ }
+}
+
+/*!
+ * brief Get ADC conversion result from external XBAR sources.
+ * For example, if triggerGroup is set to 0U and chainGroup is set to 1U, which means the API would
+ * return Trigger0 source's chain1 conversion result.
+ *
+ * param base ADC_ETC peripheral base address.
+ * param triggerGroup Trigger group index. Available number is 0~7.
+ * param chainGroup Trigger chain group index. Available number is 0~7.
+ * return ADC conversion result value.
+ */
+uint32_t ADC_ETC_GetADCConversionValue(ADC_ETC_Type *base, uint32_t triggerGroup, uint32_t chainGroup)
+{
+ assert(triggerGroup < ADC_ETC_TRIGn_RESULT_1_0_COUNT);
+
+ uint32_t mADCResult;
+ uint8_t mRemainder = (uint8_t)(chainGroup % 2U);
+
+ switch (chainGroup / 2U)
+ {
+ case 0U:
+ if (0U == mRemainder)
+ {
+ mADCResult = ADC_ETC_TRIGn_RESULT_1_0_DATA0_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_1_0);
+ }
+ else
+ {
+ mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_1_0) >> ADC_ETC_TRIGn_RESULT_1_0_DATA1_SHIFT;
+ }
+ break;
+ case 1U:
+ if (0U == mRemainder)
+ {
+ mADCResult = ADC_ETC_TRIGn_RESULT_3_2_DATA2_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_3_2);
+ }
+ else
+ {
+ mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_3_2) >> ADC_ETC_TRIGn_RESULT_3_2_DATA3_SHIFT;
+ }
+ break;
+ case 2U:
+ if (0U == mRemainder)
+ {
+ mADCResult = ADC_ETC_TRIGn_RESULT_5_4_DATA4_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_5_4);
+ }
+ else
+ {
+ mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_5_4) >> ADC_ETC_TRIGn_RESULT_5_4_DATA5_SHIFT;
+ }
+ break;
+ case 3U:
+ if (0U == mRemainder)
+ {
+ mADCResult = ADC_ETC_TRIGn_RESULT_7_6_DATA6_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_7_6);
+ }
+ else
+ {
+ mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_7_6) >> ADC_ETC_TRIGn_RESULT_7_6_DATA7_SHIFT;
+ }
+ break;
+ default:
+ mADCResult = 0U;
+ assert(false);
+ break;
+ }
+ return mADCResult;
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aipstz.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aipstz.c
new file mode 100644
index 0000000000..077b4e01e2
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aipstz.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_aipstz.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.aipstz"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * brief Configure the privilege level for master.
+ *
+ * param base AIPSTZ peripheral base pointer
+ * param master Masters for AIPSTZ.
+ * param privilegeConfig Configuration is ORed from aipstz_master_privilege_level_t.
+ */
+void AIPSTZ_SetMasterPriviledgeLevel(AIPSTZ_Type *base, aipstz_master_t master, uint32_t privilegeConfig)
+{
+ uint32_t mask = ((uint32_t)master >> 8U) - 1U;
+ uint32_t shift = (uint32_t)master & 0xFFU;
+ base->MPR = (base->MPR & (~(mask << shift))) | (privilegeConfig << shift);
+}
+
+/*!
+ * brief Configure the access for peripheral.
+ *
+ * param base AIPSTZ peripheral base pointer
+ * param master Peripheral for AIPSTZ.
+ * param accessControl Configuration is ORed from aipstz_peripheral_access_control_t.
+ */
+void AIPSTZ_SetPeripheralAccessControl(AIPSTZ_Type *base, aipstz_peripheral_t peripheral, uint32_t accessControl)
+{
+ volatile uint32_t *reg = (uint32_t *)((uint32_t)base + ((uint32_t)peripheral >> 16U));
+ uint32_t mask = (((uint32_t)peripheral & 0xFF00U) >> 8U) - 1U;
+ uint32_t shift = (uint32_t)peripheral & 0xFFU;
+
+ *reg = (*reg & (~(mask << shift))) | ((accessControl & mask) << shift);
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aoi.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aoi.c
new file mode 100644
index 0000000000..a8f1f29ddb
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aoi.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "fsl_aoi.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.aoi"
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief Pointers to aoi bases for each instance. */
+static AOI_Type *const s_aoiBases[] = AOI_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to aoi clocks for each instance. */
+static const clock_ip_name_t s_aoiClocks[] = AOI_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+ /*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Get instance number for AOI module.
+ *
+ * @param base AOI peripheral base address
+ *
+ * @return The AOI instance
+ */
+static uint32_t AOI_GetInstance(AOI_Type *base);
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static uint32_t AOI_GetInstance(AOI_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_aoiBases); instance++)
+ {
+ if (s_aoiBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_aoiBases));
+
+ return instance;
+}
+
+/*!
+ * brief Initializes an AOI instance for operation.
+ *
+ * This function un-gates the AOI clock.
+ *
+ * param base AOI peripheral address.
+ */
+void AOI_Init(AOI_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Enable the clock gate from clock manager. */
+ CLOCK_EnableClock(s_aoiClocks[AOI_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Deinitializes an AOI instance for operation.
+ *
+ * This function shutdowns AOI module.
+ *
+ * param base AOI peripheral address.
+ */
+void AOI_Deinit(AOI_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Disable the clock gate from clock manager */
+ CLOCK_DisableClock(s_aoiClocks[AOI_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Gets the Boolean evaluation associated.
+ *
+ * This function returns the Boolean evaluation associated.
+ *
+ * Example:
+ code
+ aoi_event_config_t demoEventLogicStruct;
+
+ AOI_GetEventLogicConfig(AOI, kAOI_Event0, &demoEventLogicStruct);
+ endcode
+ *
+ * param base AOI peripheral address.
+ * param event Index of the event which will be set of type aoi_event_t.
+ * param config Selected input configuration .
+ */
+void AOI_GetEventLogicConfig(AOI_Type *base, aoi_event_t event, aoi_event_config_t *config)
+{
+ assert((uint32_t)event < (uint32_t)FSL_FEATURE_AOI_EVENT_COUNT);
+ assert(config != NULL);
+
+ uint16_t value;
+ uint16_t temp;
+ /* Read BFCRT01 register at event index. */
+ value = base->BFCRT[event].BFCRT01;
+
+ temp = (value & AOI_BFCRT01_PT0_AC_MASK) >> AOI_BFCRT01_PT0_AC_SHIFT;
+ config->PT0AC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT01_PT0_BC_MASK) >> AOI_BFCRT01_PT0_BC_SHIFT;
+ config->PT0BC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT01_PT0_CC_MASK) >> AOI_BFCRT01_PT0_CC_SHIFT;
+ config->PT0CC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT01_PT0_DC_MASK) >> AOI_BFCRT01_PT0_DC_SHIFT;
+ config->PT0DC = (aoi_input_config_t)temp;
+
+ temp = (value & AOI_BFCRT01_PT1_AC_MASK) >> AOI_BFCRT01_PT1_AC_SHIFT;
+ config->PT1AC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT01_PT1_BC_MASK) >> AOI_BFCRT01_PT1_BC_SHIFT;
+ config->PT1BC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT01_PT1_CC_MASK) >> AOI_BFCRT01_PT1_CC_SHIFT;
+ config->PT1CC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT01_PT1_DC_MASK) >> AOI_BFCRT01_PT1_DC_SHIFT;
+ config->PT1DC = (aoi_input_config_t)temp;
+
+ /* Read BFCRT23 register at event index. */
+ value = base->BFCRT[event].BFCRT23;
+
+ temp = (value & AOI_BFCRT23_PT2_AC_MASK) >> AOI_BFCRT23_PT2_AC_SHIFT;
+ config->PT2AC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT23_PT2_BC_MASK) >> AOI_BFCRT23_PT2_BC_SHIFT;
+ config->PT2BC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT23_PT2_CC_MASK) >> AOI_BFCRT23_PT2_CC_SHIFT;
+ config->PT2CC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT23_PT2_DC_MASK) >> AOI_BFCRT23_PT2_DC_SHIFT;
+ config->PT2DC = (aoi_input_config_t)temp;
+
+ temp = (value & AOI_BFCRT23_PT3_AC_MASK) >> AOI_BFCRT23_PT3_AC_SHIFT;
+ config->PT3AC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT23_PT3_BC_MASK) >> AOI_BFCRT23_PT3_BC_SHIFT;
+ config->PT3BC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT23_PT3_CC_MASK) >> AOI_BFCRT23_PT3_CC_SHIFT;
+ config->PT3CC = (aoi_input_config_t)temp;
+ temp = (value & AOI_BFCRT23_PT3_DC_MASK) >> AOI_BFCRT23_PT3_DC_SHIFT;
+ config->PT3DC = (aoi_input_config_t)temp;
+}
+
+/*!
+ * brief Configures an AOI event.
+ *
+ * This function configures an AOI event according
+ * to the aoiEventConfig structure. This function configures all inputs (A, B, C, and D)
+ * of all product terms (0, 1, 2, and 3) of a desired event.
+ *
+ * Example:
+ code
+ aoi_event_config_t demoEventLogicStruct;
+
+ demoEventLogicStruct.PT0AC = kAOI_InvInputSignal;
+ demoEventLogicStruct.PT0BC = kAOI_InputSignal;
+ demoEventLogicStruct.PT0CC = kAOI_LogicOne;
+ demoEventLogicStruct.PT0DC = kAOI_LogicOne;
+
+ demoEventLogicStruct.PT1AC = kAOI_LogicZero;
+ demoEventLogicStruct.PT1BC = kAOI_LogicOne;
+ demoEventLogicStruct.PT1CC = kAOI_LogicOne;
+ demoEventLogicStruct.PT1DC = kAOI_LogicOne;
+
+ demoEventLogicStruct.PT2AC = kAOI_LogicZero;
+ demoEventLogicStruct.PT2BC = kAOI_LogicOne;
+ demoEventLogicStruct.PT2CC = kAOI_LogicOne;
+ demoEventLogicStruct.PT2DC = kAOI_LogicOne;
+
+ demoEventLogicStruct.PT3AC = kAOI_LogicZero;
+ demoEventLogicStruct.PT3BC = kAOI_LogicOne;
+ demoEventLogicStruct.PT3CC = kAOI_LogicOne;
+ demoEventLogicStruct.PT3DC = kAOI_LogicOne;
+
+ AOI_SetEventLogicConfig(AOI, kAOI_Event0, demoEventLogicStruct);
+ endcode
+ *
+ * param base AOI peripheral address.
+ * param event Event which will be configured of type aoi_event_t.
+ * param eventConfig Pointer to type aoi_event_config_t structure. The user is responsible for
+ * filling out the members of this structure and passing the pointer to this function.
+ */
+void AOI_SetEventLogicConfig(AOI_Type *base, aoi_event_t event, const aoi_event_config_t *eventConfig)
+{
+ assert(eventConfig != NULL);
+ assert((uint32_t)event < (uint32_t)FSL_FEATURE_AOI_EVENT_COUNT);
+
+ uint16_t value;
+ /* Calculate value to configure product term 0, 1 */
+ value = AOI_BFCRT01_PT0_AC(eventConfig->PT0AC) | AOI_BFCRT01_PT0_BC(eventConfig->PT0BC) |
+ AOI_BFCRT01_PT0_CC(eventConfig->PT0CC) | AOI_BFCRT01_PT0_DC(eventConfig->PT0DC) |
+ AOI_BFCRT01_PT1_AC(eventConfig->PT1AC) | AOI_BFCRT01_PT1_BC(eventConfig->PT1BC) |
+ AOI_BFCRT01_PT1_CC(eventConfig->PT1CC) | AOI_BFCRT01_PT1_DC(eventConfig->PT1DC);
+ /* Write value to register */
+ base->BFCRT[event].BFCRT01 = value;
+
+ /* Reset and calculate value to configure product term 2, 3 */
+ value = AOI_BFCRT23_PT2_AC(eventConfig->PT2AC) | AOI_BFCRT23_PT2_BC(eventConfig->PT2BC) |
+ AOI_BFCRT23_PT2_CC(eventConfig->PT2CC) | AOI_BFCRT23_PT2_DC(eventConfig->PT2DC) |
+ AOI_BFCRT23_PT3_AC(eventConfig->PT3AC) | AOI_BFCRT23_PT3_BC(eventConfig->PT3BC) |
+ AOI_BFCRT23_PT3_CC(eventConfig->PT3CC) | AOI_BFCRT23_PT3_DC(eventConfig->PT3DC);
+ /* Write value to register */
+ base->BFCRT[event].BFCRT23 = value;
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c
new file mode 100644
index 0000000000..d4ffdacfb9
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2017, 2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_bee.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.bee"
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static void aligned_memcpy(void *dst, const void *src, size_t size)
+{
+ register uint32_t *to32 = (uint32_t *)(uint32_t *)dst;
+ register const uint32_t *from32 = (const uint32_t *)(const uint32_t *)src;
+
+ while (size >= sizeof(uint32_t))
+ {
+ *to32 = *from32;
+ size -= sizeof(uint32_t);
+ to32++;
+ from32++;
+ }
+}
+
+/*!
+ * brief Resets BEE module to factory default values.
+ *
+ * This function performs hardware reset of BEE module. Attributes and keys from software for both regions are cleared.
+ *
+ * param base BEE peripheral address.
+ */
+void BEE_Init(BEE_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ CLOCK_EnableClock(kCLOCK_Bee);
+#endif
+
+ base->CTRL = BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK;
+}
+
+/*!
+ * brief Resets BEE module, clears keys for both regions and disables clock to the BEE.
+ *
+ * This function performs hardware reset of BEE module and disables clocks. Attributes and keys from software for both
+ * regions are cleared.
+ *
+ * param base BEE peripheral address.
+ */
+void BEE_Deinit(BEE_Type *base)
+{
+ base->CTRL &=
+ ~(BEE_CTRL_BEE_ENABLE_MASK | BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK | BEE_CTRL_KEY_VALID_MASK);
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ CLOCK_DisableClock(kCLOCK_Bee);
+#endif
+}
+
+/*!
+ * brief Loads default values to the BEE region configuration structure.
+ *
+ * Loads default values to the BEE region configuration structure. The default values are as follows:
+ * code
+ * config->region0Mode = kBEE_AesCtrMode;
+ * config->region1Mode = kBEE_AesCtrMode;
+ * config->region0AddrOffset = 0U;
+ * config->region1AddrOffset = 0U;
+ * config->region0SecLevel = kBEE_SecurityLevel3;
+ * config->region1SecLevel = kBEE_SecurityLevel3;
+ * config->region1Bot = 0U;
+ * config->region1Top = 0U;
+ * config->accessPermission = kBEE_AccessProtDisabled;
+ * config->endianSwapEn = kBEE_EndianSwapEnabled;
+ * endcode
+ *
+ * param config Configuration structure for BEE peripheral.
+ */
+void BEE_GetDefaultConfig(bee_region_config_t *config)
+{
+ assert(config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->region0Mode = kBEE_AesCtrMode;
+ config->region1Mode = kBEE_AesCtrMode;
+ config->region0AddrOffset = 0U;
+ config->region1AddrOffset = 0U;
+ config->region0SecLevel = kBEE_SecurityLevel3;
+ config->region1SecLevel = kBEE_SecurityLevel3;
+ config->region1Bot = 0U;
+ config->region1Top = 0U;
+ config->accessPermission = kBEE_AccessProtDisabled;
+ config->endianSwapEn = kBEE_EndianSwapEnabled;
+}
+
+/*!
+ * brief Sets BEE configuration.
+ *
+ * This function sets BEE peripheral and BEE region settings accorging to given configuration structure.
+ *
+ * param base BEE peripheral address.
+ * param config Configuration structure for BEE.
+ */
+void BEE_SetConfig(BEE_Type *base, const bee_region_config_t *config)
+{
+ uint32_t beeCtrlVal;
+ bool reenable = false;
+
+ /* Wait until BEE is in idle state */
+ while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
+ {
+ }
+
+ /* Disable BEE before region configuration in case it is enabled. */
+ if ((base->CTRL & BEE_CTRL_BEE_ENABLE_MASK) != 0U)
+ {
+ BEE_Disable(base);
+ reenable = true;
+ }
+
+ /* Preserve CTRL bit values that are not set by this function */
+ beeCtrlVal = base->CTRL & 0xFFFF0037U;
+
+ /* Set variable according to configuration */
+ beeCtrlVal |= BEE_CTRL_AC_PROT_EN(config->accessPermission) | BEE_CTRL_LITTLE_ENDIAN(config->endianSwapEn) |
+ BEE_CTRL_SECURITY_LEVEL_R0(config->region0SecLevel) | BEE_CTRL_CTRL_AES_MODE_R0(config->region0Mode) |
+ BEE_CTRL_SECURITY_LEVEL_R1(config->region1SecLevel) | BEE_CTRL_CTRL_AES_MODE_R1(config->region1Mode);
+
+ /* Load values to registers */
+ base->CTRL = beeCtrlVal;
+ base->ADDR_OFFSET0 = config->region0AddrOffset;
+ base->ADDR_OFFSET1 = config->region1AddrOffset;
+ base->REGION1_BOT = config->region1Bot;
+ base->REGION1_TOP = config->region1Top;
+
+ /* Reenable BEE if it was enabled before. */
+ if (reenable)
+ {
+ BEE_Enable(base);
+ }
+}
+
+/*!
+ * brief Loads the AES key for selected region into BEE key registers.
+ *
+ * This function loads given AES key to BEE register for the given region.
+ * The key must be 32-bit aligned and stored in little-endian format.
+ *
+ * Please note, that eFuse BEE_KEYx_SEL must be set accordingly to be able to load and use key loaded in BEE registers.
+ * Otherwise, key cannot loaded and BEE will use key from OTPMK or SW_GP2.
+ *
+ * param base BEE peripheral address.
+ * param region Selection of the BEE region to be configured.
+ * param key AES key (in little-endian format).
+ * param keySize Size of AES key.
+ */
+status_t BEE_SetRegionKey(BEE_Type *base, bee_region_t region, const uint8_t *key, size_t keySize)
+{
+ bool redisable = false;
+
+ /* Key must be 32-bit aligned */
+ if ((0U != ((uintptr_t)key & 0x3u)) || (keySize != 16U))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* Wait until BEE is in idle state */
+ while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
+ {
+ }
+
+ /* Clear KEY_VALID bit before new key is loaded */
+ base->CTRL &= ~BEE_CTRL_KEY_VALID_MASK;
+
+ /* Write key registers, key is stored in little-endian format in memory */
+ aligned_memcpy((uint32_t *)(uint32_t)&base->AES_KEY0_W0, key, keySize);
+
+ /* Enable BEE before key configuration. */
+ if (0U == (base->CTRL & BEE_CTRL_BEE_ENABLE_MASK))
+ {
+ BEE_Enable(base);
+ redisable = true;
+ }
+
+ if (region == kBEE_Region0)
+ {
+ base->CTRL &= ~BEE_CTRL_KEY_REGION_SEL_MASK;
+ }
+
+ else if (region == kBEE_Region1)
+ {
+ base->CTRL |= BEE_CTRL_KEY_REGION_SEL_MASK;
+ }
+
+ else
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* Set KEY_VALID bit to trigger key loading */
+ base->CTRL |= BEE_CTRL_KEY_VALID_MASK;
+ /* Wait until key is ready */
+ while (0U == (base->CTRL & BEE_CTRL_KEY_VALID_MASK))
+ {
+ }
+
+ /* Redisable BEE if it was disabled before this function call. */
+ if (redisable)
+ {
+ BEE_Disable(base);
+ }
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Loads the nonce for selected region into BEE nonce registers.
+ *
+ * This function loads given nonce(only AES CTR mode) to BEE register for the given region.
+ * The nonce must be 32-bit aligned and stored in little-endian format.
+ *
+ * param base BEE peripheral address.
+ * param region Selection of the BEE region to be configured.
+ * param nonce AES nonce (in little-endian format).
+ * param nonceSize Size of AES nonce.
+ */
+status_t BEE_SetRegionNonce(BEE_Type *base, bee_region_t region, const uint8_t *nonce, size_t nonceSize)
+{
+ /* Nonce must be 32-bit aligned */
+ if ((0U != ((uintptr_t)nonce & 0x3u)) || (nonceSize != 16U))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* Wait until BEE is in idle state */
+ while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag))
+ {
+ }
+
+ /* Write nonce registers, nonce is stored in little-endian format in memory */
+ if (region == kBEE_Region0)
+ {
+ aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE0_W0, nonce, nonceSize);
+ }
+
+ else if (region == kBEE_Region1)
+ {
+ aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE1_W0, nonce, nonceSize);
+ }
+
+ else
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Gets the BEE status flags.
+ *
+ * This function returns status of BEE peripheral.
+ *
+ * param base BEE peripheral address.
+ *
+ * return The status flags. This is the logical OR of members of the
+ * enumeration ::bee_status_flags_t
+ */
+uint32_t BEE_GetStatusFlags(BEE_Type *base)
+{
+ return base->STATUS;
+}
+
+/*!
+ * brief Clears the BEE status flags.
+ *
+ * param base BEE peripheral base address.
+ * param mask The status flags to clear. This is a logical OR of members of the
+ * enumeration ::bee_status_flags_t
+ */
+void BEE_ClearStatusFlags(BEE_Type *base, uint32_t mask)
+{
+ /* w1c */
+ base->STATUS |= mask;
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cache.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cache.c
new file mode 100644
index 0000000000..31d6a2479c
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cache.c
@@ -0,0 +1,602 @@
+/*
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_cache.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.cache_armv7_m7"
+#endif
+
+#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
+#define L2CACHE_OPERATION_TIMEOUT 0xFFFFFU
+#define L2CACHE_8WAYS_MASK 0xFFU
+#define L2CACHE_16WAYS_MASK 0xFFFFU
+#define L2CACHE_SMALLWAYS_NUM 8U
+#define L2CACHE_1KBCOVERTOB 1024U
+#define L2CACHE_SAMLLWAYS_SIZE 16U
+#define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/
+ /*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Set for all ways and waiting for the operation finished.
+ * This is provided for all the background operations.
+ *
+ * @param auxCtlReg The auxiliary control register.
+ * @param regAddr The register address to be operated.
+ */
+static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr);
+
+/*!
+ * @brief Invalidates the Level 2 cache line by physical address.
+ * This function invalidates a cache line by physcial address.
+ *
+ * @param address The physical addderss of the cache.
+ * The format of the address shall be :
+ * bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
+ * Tag | index | 0
+ * Note: the physical address shall be aligned to the line size - 32B (256 bit).
+ * so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
+ * If the input address is not aligned, it will be changed to 32-byte aligned address.
+ * The n is varies according to the index width.
+ * @return The actual 32-byte aligned physical address be operated.
+ */
+static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address);
+
+/*!
+ * @brief Cleans the Level 2 cache line based on the physical address.
+ * This function cleans a cache line based on a physcial address.
+ *
+ * @param address The physical addderss of the cache.
+ * The format of the address shall be :
+ * bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
+ * Tag | index | 0
+ * Note: the physical address shall be aligned to the line size - 32B (256 bit).
+ * so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
+ * If the input address is not aligned, it will be changed to 32-byte aligned address.
+ * The n is varies according to the index width.
+ * @return The actual 32-byte aligned physical address be operated.
+ */
+static uint32_t L2CACHE_CleanLineByAddr(uint32_t address);
+
+/*!
+ * @brief Cleans and invalidates the Level 2 cache line based on the physical address.
+ * This function cleans and invalidates a cache line based on a physcial address.
+ *
+ * @param address The physical addderss of the cache.
+ * The format of the address shall be :
+ * bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0
+ * Tag | index | 0
+ * Note: the physical address shall be aligned to the line size - 32B (256 bit).
+ * so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero.
+ * If the input address is not aligned, it will be changed to 32-byte aligned address.
+ * The n is varies according to the index width.
+ * @return The actual 32-byte aligned physical address be operated.
+ */
+static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address);
+
+/*!
+ * @brief Gets the number of the Level 2 cache and the way size.
+ * This function cleans and invalidates a cache line based on a physcial address.
+ *
+ * @param num_ways The number of the cache way.
+ * @param size_way The way size.
+ */
+static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way);
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr)
+{
+ uint16_t mask = L2CACHE_8WAYS_MASK;
+ uint32_t timeout = L2CACHE_OPERATION_TIMEOUT;
+
+ /* Check the ways used at first. */
+ if (auxCtlReg & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
+ {
+ mask = L2CACHE_16WAYS_MASK;
+ }
+
+ /* Set the opeartion for all ways/entries of the cache. */
+ *(uint32_t *)regAddr = mask;
+ /* Waiting for until the operation is complete. */
+ while ((*(volatile uint32_t *)regAddr & mask) && timeout)
+ {
+ __ASM("nop");
+ timeout--;
+ }
+}
+
+static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address)
+{
+ /* Align the address first. */
+ address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
+ /* Invalidate the cache line by physical address. */
+ L2CACHEC->REG7_INV_PA = address;
+
+ return address;
+}
+
+static uint32_t L2CACHE_CleanLineByAddr(uint32_t address)
+{
+ /* Align the address first. */
+ address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
+ /* Invalidate the cache line by physical address. */
+ L2CACHEC->REG7_CLEAN_PA = address;
+
+ return address;
+}
+
+static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address)
+{
+ /* Align the address first. */
+ address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1);
+ /* Clean and invalidate the cache line by physical address. */
+ L2CACHEC->REG7_CLEAN_INV_PA = address;
+
+ return address;
+}
+
+static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way)
+{
+ assert(num_ways);
+ assert(size_way);
+
+ uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
+ L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
+ uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
+ L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
+
+ *num_ways = (number + 1) * L2CACHE_SMALLWAYS_NUM;
+ if (!size)
+ {
+ /* 0 internally mapped to the same size as 1 - 16KB.*/
+ size += 1;
+ }
+ *size_way = (1 << (size - 1)) * L2CACHE_SAMLLWAYS_SIZE * L2CACHE_1KBCOVERTOB;
+}
+
+/*!
+ * brief Initializes the level 2 cache controller module.
+ *
+ * param config Pointer to configuration structure. See "l2cache_config_t".
+ */
+void L2CACHE_Init(l2cache_config_t *config)
+{
+ assert(config);
+
+ uint16_t waysNum = 0xFFU; /* Default use the 8-way mask. */
+ uint8_t count;
+ uint32_t auxReg = 0;
+
+ /*The aux register must be configured when the cachec is disabled
+ * So disable first if the cache controller is enabled.
+ */
+ if (L2CACHEC->REG1_CONTROL & L2CACHEC_REG1_CONTROL_CE_MASK)
+ {
+ L2CACHE_Disable();
+ }
+
+ /* Unlock all entries. */
+ if (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK)
+ {
+ waysNum = 0xFFFFU;
+ }
+
+ for (count = 0; count < L2CACHE_LOCKDOWN_REGNUM; count++)
+ {
+ L2CACHE_LockdownByWayEnable(count, waysNum, false);
+ }
+
+ /* Set the ways and way-size etc. */
+ auxReg = L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY(config->wayNum) |
+ L2CACHEC_REG1_AUX_CONTROL_WAYSIZE(config->waySize) | L2CACHEC_REG1_AUX_CONTROL_CRP(config->repacePolicy) |
+ L2CACHEC_REG1_AUX_CONTROL_IPE(config->istrPrefetchEnable) |
+ L2CACHEC_REG1_AUX_CONTROL_DPE(config->dataPrefetchEnable) |
+ L2CACHEC_REG1_AUX_CONTROL_NLE(config->nsLockdownEnable) |
+ L2CACHEC_REG1_AUX_CONTROL_FWA(config->writeAlloc) | L2CACHEC_REG1_AUX_CONTROL_HPSDRE(config->writeAlloc);
+ L2CACHEC->REG1_AUX_CONTROL = auxReg;
+
+ /* Set the tag/data ram latency. */
+ if (config->lateConfig)
+ {
+ uint32_t data = 0;
+ /* Tag latency. */
+ data = L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
+ L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) |
+ L2CACHEC_REG1_TAG_RAM_CONTROL_RAL(config->lateConfig->tagReadLate) |
+ L2CACHEC_REG1_TAG_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
+ L2CACHEC->REG1_TAG_RAM_CONTROL = data;
+ /* Data latency. */
+ data = L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
+ L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) |
+ L2CACHEC_REG1_DATA_RAM_CONTROL_RAL(config->lateConfig->dataReadLate) |
+ L2CACHEC_REG1_DATA_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate);
+ L2CACHEC->REG1_DATA_RAM_CONTROL = data;
+ }
+}
+
+/*!
+ * brief Gets an available default settings for the cache controller.
+ *
+ * This function initializes the cache controller configuration structure with default settings.
+ * The default values are:
+ * code
+ * config->waysNum = kL2CACHE_8ways;
+ * config->waySize = kL2CACHE_32KbSize;
+ * config->repacePolicy = kL2CACHE_Roundrobin;
+ * config->lateConfig = NULL;
+ * config->istrPrefetchEnable = false;
+ * config->dataPrefetchEnable = false;
+ * config->nsLockdownEnable = false;
+ * config->writeAlloc = kL2CACHE_UseAwcache;
+ * endcode
+ * param config Pointer to the configuration structure.
+ */
+void L2CACHE_GetDefaultConfig(l2cache_config_t *config)
+{
+ assert(config);
+
+ /* Initializes the configure structure to zero. */
+ memset(config, 0, sizeof(*config));
+
+ uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
+ L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
+ uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >>
+ L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT;
+
+ /* Get the default value */
+ config->wayNum = (l2cache_way_num_t)number;
+ config->waySize = (l2cache_way_size)size;
+ config->repacePolicy = kL2CACHE_Roundrobin;
+ config->lateConfig = NULL;
+ config->istrPrefetchEnable = false;
+ config->dataPrefetchEnable = false;
+ config->nsLockdownEnable = false;
+ config->writeAlloc = kL2CACHE_UseAwcache;
+}
+
+/*!
+ * brief Enables the level 2 cache controller.
+ * This function enables the cache controller. Must be written using a secure access.
+ * If write with a Non-secure access will cause a DECERR response.
+ *
+ */
+void L2CACHE_Enable(void)
+{
+ /* Invalidate first. */
+ L2CACHE_Invalidate();
+ /* Enable the level 2 cache controller. */
+ L2CACHEC->REG1_CONTROL = L2CACHEC_REG1_CONTROL_CE_MASK;
+}
+
+/*!
+ * brief Disables the level 2 cache controller.
+ * This function disables the cache controller. Must be written using a secure access.
+ * If write with a Non-secure access will cause a DECERR response.
+ *
+ */
+void L2CACHE_Disable(void)
+{
+ /* First CleanInvalidate all enties in the cache. */
+ L2CACHE_CleanInvalidate();
+ /* Disable the level 2 cache controller. */
+ L2CACHEC->REG1_CONTROL &= ~L2CACHEC_REG1_CONTROL_CE_MASK;
+ /* DSB - data sync barrier.*/
+ __DSB();
+}
+
+/*!
+ * brief Invalidates the Level 2 cache.
+ * This function invalidates all entries in cache.
+ *
+ */
+void L2CACHE_Invalidate(void)
+{
+ /* Invalidate all entries in cache. */
+ L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_INV_WAY);
+ /* Cache sync. */
+ L2CACHEC->REG7_CACHE_SYNC = 0;
+}
+
+/*!
+ * brief Cleans the level 2 cache controller.
+ * This function cleans all entries in the level 2 cache controller.
+ *
+ */
+void L2CACHE_Clean(void)
+{
+ /* Clean all entries of the cache. */
+ L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_WAY);
+ /* Cache sync. */
+ L2CACHEC->REG7_CACHE_SYNC = 0;
+}
+
+/*!
+ * brief Cleans and invalidates the level 2 cache controller.
+ * This function cleans and invalidates all entries in the level 2 cache controller.
+ *
+ */
+void L2CACHE_CleanInvalidate(void)
+{
+ /* Clean all entries of the cache. */
+ L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_INV_WAY);
+ /* Cache sync. */
+ L2CACHEC->REG7_CACHE_SYNC = 0;
+}
+
+/*!
+ * brief Invalidates the Level 2 cache lines in the range of two physical addresses.
+ * This function invalidates all cache lines between two physical addresses.
+ *
+ * param address The start address of the memory to be invalidated.
+ * param size_byte The memory size.
+ * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
+ * The startAddr here will be forced to align to L2 line size if startAddr
+ * is not aligned. For the size_byte, application should make sure the
+ * alignment or make sure the right operation order if the size_byte is not aligned.
+ */
+void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
+{
+ uint32_t endAddr = address + size_byte;
+
+ /* Invalidate addresses in the range. */
+ while (address < endAddr)
+ {
+ address = L2CACHE_InvalidateLineByAddr(address);
+ /* Update the size. */
+ address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
+ }
+
+ /* Cache sync. */
+ L2CACHEC->REG7_CACHE_SYNC = 0;
+}
+
+/*!
+ * brief Cleans the Level 2 cache lines in the range of two physical addresses.
+ * This function cleans all cache lines between two physical addresses.
+ *
+ * param address The start address of the memory to be cleaned.
+ * param size_byte The memory size.
+ * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
+ * The startAddr here will be forced to align to L2 line size if startAddr
+ * is not aligned. For the size_byte, application should make sure the
+ * alignment or make sure the right operation order if the size_byte is not aligned.
+ */
+void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte)
+{
+ uint32_t num_ways = 0;
+ uint32_t size_way = 0;
+ uint32_t endAddr = address + size_byte;
+
+ /* Get the number and size of the cache way. */
+ L2CACHE_GetWayNumSize(&num_ways, &size_way);
+
+ /* Check if the clean size is over the cache size. */
+ if ((endAddr - address) > num_ways * size_way)
+ {
+ L2CACHE_Clean();
+ return;
+ }
+
+ /* Clean addresses in the range. */
+ while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
+ {
+ /* Clean the address in the range. */
+ address = L2CACHE_CleanLineByAddr(address);
+ address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
+ }
+
+ L2CACHEC->REG7_CACHE_SYNC = 0;
+}
+
+/*!
+ * brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses.
+ * This function cleans and invalidates all cache lines between two physical addresses.
+ *
+ * param address The start address of the memory to be cleaned and invalidated.
+ * param size_byte The memory size.
+ * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned.
+ * The startAddr here will be forced to align to L2 line size if startAddr
+ * is not aligned. For the size_byte, application should make sure the
+ * alignment or make sure the right operation order if the size_byte is not aligned.
+ */
+void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
+{
+ uint32_t num_ways = 0;
+ uint32_t size_way = 0;
+ uint32_t endAddr = address + size_byte;
+
+ /* Get the number and size of the cache way. */
+ L2CACHE_GetWayNumSize(&num_ways, &size_way);
+
+ /* Check if the clean size is over the cache size. */
+ if ((endAddr - address) > num_ways * size_way)
+ {
+ L2CACHE_CleanInvalidate();
+ return;
+ }
+
+ /* Clean addresses in the range. */
+ while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr)
+ {
+ /* Clean the address in the range. */
+ address = L2CACHE_CleanInvalidateLineByAddr(address);
+ address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE;
+ }
+
+ L2CACHEC->REG7_CACHE_SYNC = 0;
+}
+
+/*!
+ * brief Enables or disables to lock down the data and instruction by way.
+ * This function locks down the cached instruction/data by way and prevent the adresses from
+ * being allocated and prevent dara from being evicted out of the level 2 cache.
+ * But the normal cache maintenance operations that invalidate, clean or clean
+ * and validate cache contents affect the locked-down cache lines as normal.
+ *
+ * param masterId The master id, range from 0 ~ 7.
+ * param mask The ways to be enabled or disabled to lockdown.
+ * each bit in value is related to each way of the cache. for example:
+ * value: bit 0 ------ way 0.
+ * value: bit 1 ------ way 1.
+ * --------------------------
+ * value: bit 15 ------ way 15.
+ * Note: please make sure the value setting is align with your supported ways.
+ * param enable True enable the lockdown, false to disable the lockdown.
+ */
+void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable)
+{
+ uint8_t num_ways = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >>
+ L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT;
+ num_ways = (num_ways + 1) * L2CACHE_SMALLWAYS_NUM;
+
+ assert(mask < (1U << num_ways));
+ assert(masterId < L2CACHE_LOCKDOWN_REGNUM);
+
+ uint32_t dataReg = L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN;
+ uint32_t istrReg = L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN;
+
+ if (enable)
+ {
+ /* Data lockdown. */
+ L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg | mask;
+ /* Instruction lockdown. */
+ L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg | mask;
+ }
+ else
+ {
+ /* Data lockdown. */
+ L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg & ~mask;
+ /* Instruction lockdown. */
+ L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg & ~mask;
+ }
+}
+#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
+
+/*!
+ * brief Invalidate cortex-m7 L1 instruction cache by range.
+ *
+ * param address The start address of the memory to be invalidated.
+ * param size_byte The memory size.
+ * note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned.
+ * The startAddr here will be forced to align to L1 I-cache line size if
+ * startAddr is not aligned. For the size_byte, application should make sure the
+ * alignment or make sure the right operation order if the size_byte is not aligned.
+ */
+void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte)
+{
+#if (__DCACHE_PRESENT == 1U)
+ uint32_t addr = address & ~((uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE - 1U);
+ uint32_t align_len = address - addr;
+ int32_t size = (int32_t)size_byte + (int32_t)align_len;
+
+ __DSB();
+ while (size > 0)
+ {
+ SCB->ICIMVAU = addr;
+ addr += (uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE;
+ size -= (int32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE;
+ }
+ __DSB();
+ __ISB();
+#endif
+}
+
+/*!
+ * brief Invalidates all instruction caches by range.
+ *
+ * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
+ *
+ * param address The physical address.
+ * param size_byte size of the memory to be invalidated.
+ * note address and size should be aligned to cache line size
+ * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
+ * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
+ * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
+ */
+void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
+{
+#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
+#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
+ L2CACHE_InvalidateByRange(address, size_byte);
+#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
+#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
+
+ L1CACHE_InvalidateICacheByRange(address, size_byte);
+}
+
+/*!
+ * brief Invalidates all data caches by range.
+ *
+ * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
+ *
+ * param address The physical address.
+ * param size_byte size of the memory to be invalidated.
+ * note address and size should be aligned to cache line size
+ * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
+ * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
+ * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
+ */
+void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte)
+{
+#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
+#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
+ L2CACHE_InvalidateByRange(address, size_byte);
+#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
+#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
+ L1CACHE_InvalidateDCacheByRange(address, size_byte);
+}
+
+/*!
+ * brief Cleans all data caches by range.
+ *
+ * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
+ *
+ * param address The physical address.
+ * param size_byte size of the memory to be cleaned.
+ * note address and size should be aligned to cache line size
+ * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
+ * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
+ * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
+ */
+void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte)
+{
+ L1CACHE_CleanDCacheByRange(address, size_byte);
+#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
+#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
+ L2CACHE_CleanByRange(address, size_byte);
+#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
+#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
+}
+
+/*!
+ * brief Cleans and Invalidates all data caches by range.
+ *
+ * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte.
+ *
+ * param address The physical address.
+ * param size_byte size of the memory to be cleaned and invalidated.
+ * note address and size should be aligned to cache line size
+ * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced
+ * to align to the cache line size if startAddr is not aligned. For the size_byte, application should
+ * make sure the alignment or make sure the right operation order if the size_byte is not aligned.
+ */
+void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte)
+{
+ L1CACHE_CleanInvalidateDCacheByRange(address, size_byte);
+#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT
+#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT
+ L2CACHE_CleanInvalidateByRange(address, size_byte);
+#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */
+#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_clock.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_clock.c
new file mode 100644
index 0000000000..cb5ca96dab
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_clock.c
@@ -0,0 +1,1250 @@
+/*
+ * Copyright 2017 - 2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_clock.h"
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.clock"
+#endif
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+/* To make full use of CM7 hardware FPU, use double instead of uint64_t in clock driver to
+achieve better performance, it is depend on the IDE Floating point settings, if double precision is selected
+in IDE, clock_64b_t will switch to double type automatically. only support IAR and MDK here */
+#if __FPU_USED
+
+#if (defined(__ICCARM__))
+
+#if (__ARMVFP__ >= __ARMFPV5__) && \
+ (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/
+typedef double clock_64b_t;
+#else
+typedef uint64_t clock_64b_t;
+#endif
+
+#elif (defined(__GNUC__))
+
+#if (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/
+typedef double clock_64b_t;
+#else
+typedef uint64_t clock_64b_t;
+#endif
+
+#elif defined(__CC_ARM) || defined(__ARMCC_VERSION)
+
+#if defined __TARGET_FPU_FPV5_D16
+typedef double clock_64b_t;
+#else
+typedef uint64_t clock_64b_t;
+#endif
+
+#else
+typedef uint64_t clock_64b_t;
+#endif
+
+#else
+typedef uint64_t clock_64b_t;
+#endif
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/* External XTAL (OSC) clock frequency. */
+volatile uint32_t g_xtalFreq;
+/* External RTC XTAL clock frequency. */
+volatile uint32_t g_rtcXtalFreq;
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief Get the periph clock frequency.
+ *
+ * @return Periph clock frequency in Hz.
+ */
+static uint32_t CLOCK_GetPeriphClkFreq(void);
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static uint32_t CLOCK_GetPeriphClkFreq(void)
+{
+ uint32_t freq;
+
+ /* Periph_clk2_clk ---> Periph_clk */
+ if ((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK_SEL_MASK) != 0U)
+ {
+ switch (CCM->CBCMR & CCM_CBCMR_PERIPH_CLK2_SEL_MASK)
+ {
+ /* Pll3_sw_clk ---> Periph_clk2_clk ---> Periph_clk */
+ case CCM_CBCMR_PERIPH_CLK2_SEL(0U):
+ freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
+ break;
+
+ /* Osc_clk ---> Periph_clk2_clk ---> Periph_clk */
+ case CCM_CBCMR_PERIPH_CLK2_SEL(1U):
+ freq = CLOCK_GetOscFreq();
+ break;
+
+ case CCM_CBCMR_PERIPH_CLK2_SEL(2U):
+ freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
+ break;
+
+ case CCM_CBCMR_PERIPH_CLK2_SEL(3U):
+ default:
+ freq = 0U;
+ break;
+ }
+
+ freq /= (((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >> CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT) + 1U);
+ }
+ /* Pre_Periph_clk ---> Periph_clk */
+ else
+ {
+ switch (CCM->CBCMR & CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK)
+ {
+ /* PLL2 ---> Pre_Periph_clk ---> Periph_clk */
+ case CCM_CBCMR_PRE_PERIPH_CLK_SEL(0U):
+ freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
+ break;
+
+ /* PLL2 PFD2 ---> Pre_Periph_clk ---> Periph_clk */
+ case CCM_CBCMR_PRE_PERIPH_CLK_SEL(1U):
+ freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2);
+ break;
+
+ /* PLL2 PFD0 ---> Pre_Periph_clk ---> Periph_clk */
+ case CCM_CBCMR_PRE_PERIPH_CLK_SEL(2U):
+ freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0);
+ break;
+
+ /* PLL1 divided(/2) ---> Pre_Periph_clk ---> Periph_clk */
+ case CCM_CBCMR_PRE_PERIPH_CLK_SEL(3U):
+ freq = CLOCK_GetPllFreq(kCLOCK_PllArm) /
+ (((CCM->CACRR & CCM_CACRR_ARM_PODF_MASK) >> CCM_CACRR_ARM_PODF_SHIFT) + 1U);
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+ }
+
+ return freq;
+}
+
+/*!
+ * brief Initialize the external 24MHz clock.
+ *
+ * This function supports two modes:
+ * 1. Use external crystal oscillator.
+ * 2. Bypass the external crystal oscillator, using input source clock directly.
+ *
+ * After this function, please call ref CLOCK_SetXtal0Freq to inform clock driver
+ * the external clock frequency.
+ *
+ * param bypassXtalOsc Pass in true to bypass the external crystal oscillator.
+ * note This device does not support bypass external crystal oscillator, so
+ * the input parameter should always be false.
+ */
+void CLOCK_InitExternalClk(bool bypassXtalOsc)
+{
+ /* This device does not support bypass XTAL OSC. */
+ assert(!bypassXtalOsc);
+
+ CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power up */
+ while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0U)
+ {
+ }
+ CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; /* detect freq */
+ while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0UL)
+ {
+ }
+ CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK;
+}
+
+/*!
+ * brief Deinitialize the external 24MHz clock.
+ *
+ * This function disables the external 24MHz clock.
+ *
+ * After this function, please call ref CLOCK_SetXtal0Freq to set external clock
+ * frequency to 0.
+ */
+void CLOCK_DeinitExternalClk(void)
+{
+ CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power down */
+}
+
+/*!
+ * brief Switch the OSC.
+ *
+ * This function switches the OSC source for SoC.
+ *
+ * param osc OSC source to switch to.
+ */
+void CLOCK_SwitchOsc(clock_osc_t osc)
+{
+ if (osc == kCLOCK_RcOsc)
+ {
+ XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK;
+ }
+ else
+ {
+ XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_CLR_OSC_SEL_MASK;
+ }
+}
+
+/*!
+ * brief Initialize the RC oscillator 24MHz clock.
+ */
+void CLOCK_InitRcOsc24M(void)
+{
+ XTALOSC24M->LOWPWR_CTRL |= XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK;
+}
+
+/*!
+ * brief Power down the RCOSC 24M clock.
+ */
+void CLOCK_DeinitRcOsc24M(void)
+{
+ XTALOSC24M->LOWPWR_CTRL &= ~XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK;
+}
+
+/*!
+ * brief Gets the AHB clock frequency.
+ *
+ * return The AHB clock frequency value in hertz.
+ */
+uint32_t CLOCK_GetAhbFreq(void)
+{
+ return CLOCK_GetPeriphClkFreq() / (((CCM->CBCDR & CCM_CBCDR_AHB_PODF_MASK) >> CCM_CBCDR_AHB_PODF_SHIFT) + 1U);
+}
+
+/*!
+ * brief Gets the SEMC clock frequency.
+ *
+ * return The SEMC clock frequency value in hertz.
+ */
+uint32_t CLOCK_GetSemcFreq(void)
+{
+ uint32_t freq;
+
+ /* SEMC alternative clock ---> SEMC Clock */
+ if ((CCM->CBCDR & CCM_CBCDR_SEMC_CLK_SEL_MASK) != 0U)
+ {
+ /* PLL3 PFD1 ---> SEMC alternative clock ---> SEMC Clock */
+ if ((CCM->CBCDR & CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK) != 0U)
+ {
+ freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1);
+ }
+ /* PLL2 PFD2 ---> SEMC alternative clock ---> SEMC Clock */
+ else
+ {
+ freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2);
+ }
+ }
+ /* Periph_clk ---> SEMC Clock */
+ else
+ {
+ freq = CLOCK_GetPeriphClkFreq();
+ }
+
+ freq /= (((CCM->CBCDR & CCM_CBCDR_SEMC_PODF_MASK) >> CCM_CBCDR_SEMC_PODF_SHIFT) + 1U);
+
+ return freq;
+}
+
+/*!
+ * brief Gets the IPG clock frequency.
+ *
+ * return The IPG clock frequency value in hertz.
+ */
+uint32_t CLOCK_GetIpgFreq(void)
+{
+ return CLOCK_GetAhbFreq() / (((CCM->CBCDR & CCM_CBCDR_IPG_PODF_MASK) >> CCM_CBCDR_IPG_PODF_SHIFT) + 1U);
+}
+
+/*!
+ * brief Gets the PER clock frequency.
+ *
+ * return The PER clock frequency value in hertz.
+ */
+uint32_t CLOCK_GetPerClkFreq(void)
+{
+ uint32_t freq;
+
+ /* Osc_clk ---> PER Clock*/
+ if ((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL_MASK) != 0U)
+ {
+ freq = CLOCK_GetOscFreq();
+ }
+ /* Periph_clk ---> AHB Clock ---> IPG Clock ---> PER Clock */
+ else
+ {
+ freq = CLOCK_GetIpgFreq();
+ }
+
+ freq /= (((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_PODF_MASK) >> CCM_CSCMR1_PERCLK_PODF_SHIFT) + 1U);
+
+ return freq;
+}
+
+/*!
+ * brief Gets the clock frequency for a specific clock name.
+ *
+ * This function checks the current clock configurations and then calculates
+ * the clock frequency for a specific clock name defined in clock_name_t.
+ *
+ * param clockName Clock names defined in clock_name_t
+ * return Clock frequency value in hertz
+ */
+uint32_t CLOCK_GetFreq(clock_name_t name)
+{
+ uint32_t freq;
+
+ switch (name)
+ {
+ case kCLOCK_CpuClk:
+ case kCLOCK_AhbClk:
+ freq = CLOCK_GetAhbFreq();
+ break;
+
+ case kCLOCK_SemcClk:
+ freq = CLOCK_GetSemcFreq();
+ break;
+
+ case kCLOCK_IpgClk:
+ freq = CLOCK_GetIpgFreq();
+ break;
+
+ case kCLOCK_PerClk:
+ freq = CLOCK_GetPerClkFreq();
+ break;
+
+ case kCLOCK_OscClk:
+ freq = CLOCK_GetOscFreq();
+ break;
+ case kCLOCK_RtcClk:
+ freq = CLOCK_GetRtcFreq();
+ break;
+ case kCLOCK_ArmPllClk:
+ freq = CLOCK_GetPllFreq(kCLOCK_PllArm);
+ break;
+ case kCLOCK_Usb1PllClk:
+ freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
+ break;
+ case kCLOCK_Usb1PllPfd0Clk:
+ freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd0);
+ break;
+ case kCLOCK_Usb1PllPfd1Clk:
+ freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1);
+ break;
+ case kCLOCK_Usb1PllPfd2Clk:
+ freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd2);
+ break;
+ case kCLOCK_Usb1PllPfd3Clk:
+ freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd3);
+ break;
+ case kCLOCK_Usb2PllClk:
+ freq = CLOCK_GetPllFreq(kCLOCK_PllUsb2);
+ break;
+ case kCLOCK_SysPllClk:
+ freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
+ break;
+ case kCLOCK_SysPllPfd0Clk:
+ freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0);
+ break;
+ case kCLOCK_SysPllPfd1Clk:
+ freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd1);
+ break;
+ case kCLOCK_SysPllPfd2Clk:
+ freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2);
+ break;
+ case kCLOCK_SysPllPfd3Clk:
+ freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd3);
+ break;
+ case kCLOCK_EnetPll0Clk:
+ freq = CLOCK_GetPllFreq(kCLOCK_PllEnet);
+ break;
+ case kCLOCK_EnetPll1Clk:
+ freq = CLOCK_GetPllFreq(kCLOCK_PllEnet25M);
+ break;
+ case kCLOCK_AudioPllClk:
+ freq = CLOCK_GetPllFreq(kCLOCK_PllAudio);
+ break;
+ case kCLOCK_VideoPllClk:
+ freq = CLOCK_GetPllFreq(kCLOCK_PllVideo);
+ break;
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq;
+}
+
+/*! brief Enable USB HS clock.
+ *
+ * This function only enables the access to USB HS prepheral, upper layer
+ * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY
+ * clock to use USB HS.
+ *
+ * param src USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused.
+ * param freq USB HS does not care about the clock source, so this parameter is ignored.
+ * retval true The clock is set successfully.
+ * retval false The clock source is invalid to get proper USB HS clock.
+ */
+bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq)
+{
+ uint32_t i;
+ CCM->CCGR6 |= CCM_CCGR6_CG0_MASK;
+ USB1->USBCMD |= USBHS_USBCMD_RST_MASK;
+
+ /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/
+ for (i = 0; i < 400000U; i++)
+ {
+ __ASM("nop");
+ }
+ PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) |
+ (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK);
+ return true;
+}
+
+/*! brief Enable USB HS clock.
+ *
+ * This function only enables the access to USB HS prepheral, upper layer
+ * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY
+ * clock to use USB HS.
+ *
+ * param src USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused.
+ * param freq USB HS does not care about the clock source, so this parameter is ignored.
+ * retval true The clock is set successfully.
+ * retval false The clock source is invalid to get proper USB HS clock.
+ */
+bool CLOCK_EnableUsbhs1Clock(clock_usb_src_t src, uint32_t freq)
+{
+ uint32_t i = 0;
+ CCM->CCGR6 |= CCM_CCGR6_CG0_MASK;
+ USB2->USBCMD |= USBHS_USBCMD_RST_MASK;
+
+ /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/
+ for (i = 0; i < 400000U; i++)
+ {
+ __ASM("nop");
+ }
+ PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) |
+ (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK);
+ return true;
+}
+
+/*! brief Enable USB HS PHY PLL clock.
+ *
+ * This function enables the internal 480MHz USB PHY PLL clock.
+ *
+ * param src USB HS PHY PLL clock source.
+ * param freq The frequency specified by src.
+ * retval true The clock is set successfully.
+ * retval false The clock source is invalid to get proper USB HS clock.
+ */
+bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
+{
+ const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
+ if ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_ENABLE_MASK) != 0U)
+ {
+ CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
+ }
+ else
+ {
+ CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
+ }
+ USBPHY1->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */
+ USBPHY1->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK;
+
+ USBPHY1->PWD = 0;
+ USBPHY1->CTRL |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK | USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK |
+ USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK;
+ return true;
+}
+
+/*! brief Disable USB HS PHY PLL clock.
+ *
+ * This function disables USB HS PHY PLL clock.
+ */
+void CLOCK_DisableUsbhs0PhyPllClock(void)
+{
+ CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK;
+ USBPHY1->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */
+}
+
+/*!
+ * brief Initialize the ARM PLL.
+ *
+ * This function initialize the ARM PLL with specific settings
+ *
+ * param config configuration to set to PLL.
+ */
+void CLOCK_InitArmPll(const clock_arm_pll_config_t *config)
+{
+ /* Bypass PLL first */
+ CCM_ANALOG->PLL_ARM = (CCM_ANALOG->PLL_ARM & (~CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC_MASK)) |
+ CCM_ANALOG_PLL_ARM_BYPASS_MASK | CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC(config->src);
+
+ CCM_ANALOG->PLL_ARM =
+ (CCM_ANALOG->PLL_ARM & (~(CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK | CCM_ANALOG_PLL_ARM_POWERDOWN_MASK))) |
+ CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_DIV_SELECT(config->loopDivider);
+
+ while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0UL)
+ {
+ }
+
+ /* Disable Bypass */
+ CCM_ANALOG->PLL_ARM &= ~CCM_ANALOG_PLL_ARM_BYPASS_MASK;
+}
+
+/*!
+ * brief De-initialize the ARM PLL.
+ */
+void CLOCK_DeinitArmPll(void)
+{
+ CCM_ANALOG->PLL_ARM = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK;
+}
+
+/*!
+ * brief Initialize the System PLL.
+ *
+ * This function initializes the System PLL with specific settings
+ *
+ * param config Configuration to set to PLL.
+ */
+void CLOCK_InitSysPll(const clock_sys_pll_config_t *config)
+{
+ /* Bypass PLL first */
+ CCM_ANALOG->PLL_SYS = (CCM_ANALOG->PLL_SYS & (~CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_MASK)) |
+ CCM_ANALOG_PLL_SYS_BYPASS_MASK | CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC(config->src);
+
+ CCM_ANALOG->PLL_SYS =
+ (CCM_ANALOG->PLL_SYS & (~(CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK | CCM_ANALOG_PLL_SYS_POWERDOWN_MASK))) |
+ CCM_ANALOG_PLL_SYS_ENABLE_MASK | CCM_ANALOG_PLL_SYS_DIV_SELECT(config->loopDivider);
+
+ /* Initialize the fractional mode */
+ CCM_ANALOG->PLL_SYS_NUM = CCM_ANALOG_PLL_SYS_NUM_A(config->numerator);
+ CCM_ANALOG->PLL_SYS_DENOM = CCM_ANALOG_PLL_SYS_DENOM_B(config->denominator);
+
+ /* Initialize the spread spectrum mode */
+ CCM_ANALOG->PLL_SYS_SS = CCM_ANALOG_PLL_SYS_SS_STEP(config->ss_step) |
+ CCM_ANALOG_PLL_SYS_SS_ENABLE(config->ss_enable) |
+ CCM_ANALOG_PLL_SYS_SS_STOP(config->ss_stop);
+
+ while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0UL)
+ {
+ }
+
+ /* Disable Bypass */
+ CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_BYPASS_MASK;
+}
+
+/*!
+ * brief De-initialize the System PLL.
+ */
+void CLOCK_DeinitSysPll(void)
+{
+ CCM_ANALOG->PLL_SYS = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK;
+}
+
+/*!
+ * brief Initialize the USB1 PLL.
+ *
+ * This function initializes the USB1 PLL with specific settings
+ *
+ * param config Configuration to set to PLL.
+ */
+void CLOCK_InitUsb1Pll(const clock_usb_pll_config_t *config)
+{
+ /* Bypass PLL first */
+ CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK)) |
+ CCM_ANALOG_PLL_USB1_BYPASS_MASK | CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC(config->src);
+
+ CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK)) |
+ CCM_ANALOG_PLL_USB1_ENABLE_MASK | CCM_ANALOG_PLL_USB1_POWER_MASK |
+ CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB1_DIV_SELECT(config->loopDivider);
+
+ while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0UL)
+ {
+ }
+
+ /* Disable Bypass */
+ CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_BYPASS_MASK;
+}
+
+/*!
+ * brief Deinitialize the USB1 PLL.
+ */
+void CLOCK_DeinitUsb1Pll(void)
+{
+ CCM_ANALOG->PLL_USB1 = 0U;
+}
+
+/*!
+ * brief Initialize the USB2 PLL.
+ *
+ * This function initializes the USB2 PLL with specific settings
+ *
+ * param config Configuration to set to PLL.
+ */
+void CLOCK_InitUsb2Pll(const clock_usb_pll_config_t *config)
+{
+ /* Bypass PLL first */
+ CCM_ANALOG->PLL_USB2 = (CCM_ANALOG->PLL_USB2 & (~CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC_MASK)) |
+ CCM_ANALOG_PLL_USB2_BYPASS_MASK | CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC(config->src);
+
+ CCM_ANALOG->PLL_USB2 = (CCM_ANALOG->PLL_USB2 & (~CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK)) |
+ CCM_ANALOG_PLL_USB2_ENABLE_MASK | CCM_ANALOG_PLL_USB2_POWER_MASK |
+ CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB2_DIV_SELECT(config->loopDivider);
+
+ while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0UL)
+ {
+ }
+
+ /* Disable Bypass */
+ CCM_ANALOG->PLL_USB2 &= ~CCM_ANALOG_PLL_USB2_BYPASS_MASK;
+}
+
+/*!
+ * brief Deinitialize the USB2 PLL.
+ */
+void CLOCK_DeinitUsb2Pll(void)
+{
+ CCM_ANALOG->PLL_USB2 = 0U;
+}
+
+/*!
+ * brief Initializes the Audio PLL.
+ *
+ * This function initializes the Audio PLL with specific settings
+ *
+ * param config Configuration to set to PLL.
+ */
+void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config)
+{
+ uint32_t pllAudio;
+ uint32_t misc2 = 0;
+
+ /* Bypass PLL first */
+ CCM_ANALOG->PLL_AUDIO = (CCM_ANALOG->PLL_AUDIO & (~CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC_MASK)) |
+ CCM_ANALOG_PLL_AUDIO_BYPASS_MASK | CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC(config->src);
+
+ CCM_ANALOG->PLL_AUDIO_NUM = CCM_ANALOG_PLL_AUDIO_NUM_A(config->numerator);
+ CCM_ANALOG->PLL_AUDIO_DENOM = CCM_ANALOG_PLL_AUDIO_DENOM_B(config->denominator);
+
+ /*
+ * Set post divider:
+ *
+ * ------------------------------------------------------------------------
+ * | config->postDivider | PLL_AUDIO[POST_DIV_SELECT] | MISC2[AUDIO_DIV] |
+ * ------------------------------------------------------------------------
+ * | 1 | 2 | 0 |
+ * ------------------------------------------------------------------------
+ * | 2 | 1 | 0 |
+ * ------------------------------------------------------------------------
+ * | 4 | 2 | 3 |
+ * ------------------------------------------------------------------------
+ * | 8 | 1 | 3 |
+ * ------------------------------------------------------------------------
+ * | 16 | 0 | 3 |
+ * ------------------------------------------------------------------------
+ */
+ pllAudio =
+ (CCM_ANALOG->PLL_AUDIO & (~(CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK | CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK))) |
+ CCM_ANALOG_PLL_AUDIO_ENABLE_MASK | CCM_ANALOG_PLL_AUDIO_DIV_SELECT(config->loopDivider);
+
+ switch (config->postDivider)
+ {
+ case 16:
+ pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0);
+ misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
+ break;
+
+ case 8:
+ pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1);
+ misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
+ break;
+
+ case 4:
+ pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2);
+ misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK;
+ break;
+
+ case 2:
+ pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1);
+ break;
+
+ default:
+ pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2);
+ break;
+ }
+
+ CCM_ANALOG->MISC2 =
+ (CCM_ANALOG->MISC2 & ~(CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK)) | misc2;
+
+ CCM_ANALOG->PLL_AUDIO = pllAudio;
+
+ while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0UL)
+ {
+ }
+
+ /* Disable Bypass */
+ CCM_ANALOG->PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_BYPASS_MASK;
+}
+
+/*!
+ * brief De-initialize the Audio PLL.
+ */
+void CLOCK_DeinitAudioPll(void)
+{
+ CCM_ANALOG->PLL_AUDIO = (uint32_t)CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK;
+}
+
+/*!
+ * brief Initialize the video PLL.
+ *
+ * This function configures the Video PLL with specific settings
+ *
+ * param config configuration to set to PLL.
+ */
+void CLOCK_InitVideoPll(const clock_video_pll_config_t *config)
+{
+ uint32_t pllVideo;
+ uint32_t misc2 = 0;
+
+ /* Bypass PLL first */
+ CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) |
+ CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(config->src);
+
+ CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(config->numerator);
+ CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(config->denominator);
+
+ /*
+ * Set post divider:
+ *
+ * ------------------------------------------------------------------------
+ * | config->postDivider | PLL_VIDEO[POST_DIV_SELECT] | MISC2[VIDEO_DIV] |
+ * ------------------------------------------------------------------------
+ * | 1 | 2 | 0 |
+ * ------------------------------------------------------------------------
+ * | 2 | 1 | 0 |
+ * ------------------------------------------------------------------------
+ * | 4 | 2 | 3 |
+ * ------------------------------------------------------------------------
+ * | 8 | 1 | 3 |
+ * ------------------------------------------------------------------------
+ * | 16 | 0 | 3 |
+ * ------------------------------------------------------------------------
+ */
+ pllVideo =
+ (CCM_ANALOG->PLL_VIDEO & (~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK))) |
+ CCM_ANALOG_PLL_VIDEO_ENABLE_MASK | CCM_ANALOG_PLL_VIDEO_DIV_SELECT(config->loopDivider);
+
+ switch (config->postDivider)
+ {
+ case 16:
+ pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0);
+ misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3);
+ break;
+
+ case 8:
+ pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1);
+ misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3);
+ break;
+
+ case 4:
+ pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2);
+ misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3);
+ break;
+
+ case 2:
+ pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1);
+ break;
+
+ default:
+ pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2);
+ break;
+ }
+
+ CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & ~CCM_ANALOG_MISC2_VIDEO_DIV_MASK) | misc2;
+
+ CCM_ANALOG->PLL_VIDEO = pllVideo;
+
+ while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0UL)
+ {
+ }
+
+ /* Disable Bypass */
+ CCM_ANALOG->PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_BYPASS_MASK;
+}
+
+/*!
+ * brief De-initialize the Video PLL.
+ */
+void CLOCK_DeinitVideoPll(void)
+{
+ CCM_ANALOG->PLL_VIDEO = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK;
+}
+
+/*!
+ * brief Initialize the ENET PLL.
+ *
+ * This function initializes the ENET PLL with specific settings.
+ *
+ * param config Configuration to set to PLL.
+ */
+void CLOCK_InitEnetPll(const clock_enet_pll_config_t *config)
+{
+ uint32_t enet_pll = CCM_ANALOG_PLL_ENET_DIV_SELECT(config->loopDivider);
+
+ CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC_MASK)) |
+ CCM_ANALOG_PLL_ENET_BYPASS_MASK | CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC(config->src);
+
+ if (config->enableClkOutput)
+ {
+ enet_pll |= CCM_ANALOG_PLL_ENET_ENABLE_MASK;
+ }
+
+ if (config->enableClkOutput25M)
+ {
+ enet_pll |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK;
+ }
+
+ CCM_ANALOG->PLL_ENET =
+ (CCM_ANALOG->PLL_ENET & (~(CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK | CCM_ANALOG_PLL_ENET_POWERDOWN_MASK))) |
+ enet_pll;
+
+ /* Wait for stable */
+ while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0UL)
+ {
+ }
+
+ /* Disable Bypass */
+ CCM_ANALOG->PLL_ENET &= ~CCM_ANALOG_PLL_ENET_BYPASS_MASK;
+}
+
+/*!
+ * brief Deinitialize the ENET PLL.
+ *
+ * This function disables the ENET PLL.
+ */
+void CLOCK_DeinitEnetPll(void)
+{
+ CCM_ANALOG->PLL_ENET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK;
+}
+
+/*!
+ * brief Get current PLL output frequency.
+ *
+ * This function get current output frequency of specific PLL
+ *
+ * param pll pll name to get frequency.
+ * return The PLL output frequency in hertz.
+ */
+uint32_t CLOCK_GetPllFreq(clock_pll_t pll)
+{
+ uint32_t freq;
+ uint32_t divSelect;
+ clock_64b_t freqTmp;
+
+ const uint32_t enetRefClkFreq[] = {
+ 25000000U, /* 25M */
+ 50000000U, /* 50M */
+ 100000000U, /* 100M */
+ 125000000U /* 125M */
+ };
+
+ /* check if PLL is enabled */
+ if (!CLOCK_IsPllEnabled(CCM_ANALOG, pll))
+ {
+ return 0U;
+ }
+
+ /* get pll reference clock */
+ freq = CLOCK_GetPllBypassRefClk(CCM_ANALOG, pll);
+
+ /* check if pll is bypassed */
+ if (CLOCK_IsPllBypassed(CCM_ANALOG, pll))
+ {
+ return freq;
+ }
+
+ switch (pll)
+ {
+ case kCLOCK_PllArm:
+ freq = ((freq * ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >>
+ CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT)) >>
+ 1U);
+ break;
+ case kCLOCK_PllSys:
+ /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
+ freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_SYS_NUM)));
+ freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_SYS_DENOM));
+
+ if ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK) != 0U)
+ {
+ freq *= 22U;
+ }
+ else
+ {
+ freq *= 20U;
+ }
+
+ freq += (uint32_t)freqTmp;
+ break;
+
+ case kCLOCK_PllUsb1:
+ freq = (freq * (((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) != 0UL) ? 22U : 20U));
+ break;
+
+ case kCLOCK_PllAudio:
+ /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
+ divSelect =
+ (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_AUDIO_DIV_SELECT_SHIFT;
+
+ freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_NUM)));
+ freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_DENOM));
+
+ freq = freq * divSelect + (uint32_t)freqTmp;
+
+ /* AUDIO PLL output = PLL output frequency / POSTDIV. */
+
+ /*
+ * Post divider:
+ *
+ * PLL_AUDIO[POST_DIV_SELECT]:
+ * 0x00: 4
+ * 0x01: 2
+ * 0x02: 1
+ *
+ * MISC2[AUDO_DIV]:
+ * 0x00: 1
+ * 0x01: 2
+ * 0x02: 1
+ * 0x03: 4
+ */
+ switch (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT_MASK)
+ {
+ case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0U):
+ freq = freq >> 2U;
+ break;
+
+ case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1U):
+ freq = freq >> 1U;
+ break;
+
+ case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2U):
+ freq = freq >> 0U;
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+
+ switch (CCM_ANALOG->MISC2 & (CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK))
+ {
+ case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1):
+ freq >>= 2U;
+ break;
+
+ case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1):
+ freq >>= 1U;
+ break;
+
+ case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0):
+ case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0):
+ freq >>= 0U;
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+ break;
+
+ case kCLOCK_PllVideo:
+ /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */
+ divSelect =
+ (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_VIDEO_DIV_SELECT_SHIFT;
+
+ freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_NUM)));
+ freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_DENOM));
+ freq = freq * divSelect + (uint32_t)freqTmp;
+
+ /* VIDEO PLL output = PLL output frequency / POSTDIV. */
+
+ /*
+ * Post divider:
+ *
+ * PLL_VIDEO[POST_DIV_SELECT]:
+ * 0x00: 4
+ * 0x01: 2
+ * 0x02: 1
+ *
+ * MISC2[VIDEO_DIV]:
+ * 0x00: 1
+ * 0x01: 2
+ * 0x02: 1
+ * 0x03: 4
+ */
+ switch (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT_MASK)
+ {
+ case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0U):
+ freq = freq >> 2U;
+ break;
+
+ case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1U):
+ freq = freq >> 1U;
+ break;
+
+ case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2U):
+ freq = freq >> 0U;
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+
+ switch (CCM_ANALOG->MISC2 & CCM_ANALOG_MISC2_VIDEO_DIV_MASK)
+ {
+ case CCM_ANALOG_MISC2_VIDEO_DIV(3U):
+ freq >>= 2U;
+ break;
+
+ case CCM_ANALOG_MISC2_VIDEO_DIV(1U):
+ freq >>= 1U;
+ break;
+
+ case CCM_ANALOG_MISC2_VIDEO_DIV(0U):
+ case CCM_ANALOG_MISC2_VIDEO_DIV(2U):
+ freq >>= 0U;
+ break;
+
+ default:
+ assert(false);
+ break;
+ }
+ break;
+ case kCLOCK_PllEnet:
+ divSelect =
+ (CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_ENET_DIV_SELECT_SHIFT;
+ freq = enetRefClkFreq[divSelect];
+ break;
+
+ case kCLOCK_PllEnet25M:
+ /* ref_enetpll1 if fixed at 25MHz. */
+ freq = 25000000UL;
+ break;
+
+ case kCLOCK_PllUsb2:
+ freq = (freq * (((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) != 0U) ? 22U : 20U));
+ break;
+ default:
+ freq = 0U;
+ break;
+ }
+
+ return freq;
+}
+
+/*!
+ * brief Initialize the System PLL PFD.
+ *
+ * This function initializes the System PLL PFD. During new value setting,
+ * the clock output is disabled to prevent glitch.
+ *
+ * param pfd Which PFD clock to enable.
+ * param pfdFrac The PFD FRAC value.
+ * note It is recommended that PFD settings are kept between 12-35.
+ */
+void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t pfdFrac)
+{
+ uint32_t pfdIndex = (uint32_t)pfd;
+ uint32_t pfd528;
+
+ pfd528 = CCM_ANALOG->PFD_528 &
+ ~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_528_PFD0_FRAC_MASK)
+ << (8UL * pfdIndex)));
+
+ /* Disable the clock output first. */
+ CCM_ANALOG->PFD_528 = pfd528 | ((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
+
+ /* Set the new value and enable output. */
+ CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex));
+}
+
+/*!
+ * brief De-initialize the System PLL PFD.
+ *
+ * This function disables the System PLL PFD.
+ *
+ * param pfd Which PFD clock to disable.
+ */
+void CLOCK_DeinitSysPfd(clock_pfd_t pfd)
+{
+ CCM_ANALOG->PFD_528 |= (uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8U * (uint8_t)pfd);
+}
+
+/*!
+ * brief Initialize the USB1 PLL PFD.
+ *
+ * This function initializes the USB1 PLL PFD. During new value setting,
+ * the clock output is disabled to prevent glitch.
+ *
+ * param pfd Which PFD clock to enable.
+ * param pfdFrac The PFD FRAC value.
+ * note It is recommended that PFD settings are kept between 12-35.
+ */
+void CLOCK_InitUsb1Pfd(clock_pfd_t pfd, uint8_t pfdFrac)
+{
+ uint32_t pfdIndex = (uint32_t)pfd;
+ uint32_t pfd480;
+
+ pfd480 = CCM_ANALOG->PFD_480 &
+ ~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_480_PFD0_FRAC_MASK)
+ << (8UL * pfdIndex)));
+
+ /* Disable the clock output first. */
+ CCM_ANALOG->PFD_480 = pfd480 | ((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * pfdIndex));
+
+ /* Set the new value and enable output. */
+ CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex));
+}
+
+/*!
+ * brief De-initialize the USB1 PLL PFD.
+ *
+ * This function disables the USB1 PLL PFD.
+ *
+ * param pfd Which PFD clock to disable.
+ */
+void CLOCK_DeinitUsb1Pfd(clock_pfd_t pfd)
+{
+ CCM_ANALOG->PFD_480 |= (uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * (uint8_t)pfd);
+}
+
+/*!
+ * brief Get current System PLL PFD output frequency.
+ *
+ * This function get current output frequency of specific System PLL PFD
+ *
+ * param pfd pfd name to get frequency.
+ * return The PFD output frequency in hertz.
+ */
+uint32_t CLOCK_GetSysPfdFreq(clock_pfd_t pfd)
+{
+ uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllSys);
+
+ switch (pfd)
+ {
+ case kCLOCK_Pfd0:
+ freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD0_FRAC_SHIFT);
+ break;
+
+ case kCLOCK_Pfd1:
+ freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD1_FRAC_SHIFT);
+ break;
+
+ case kCLOCK_Pfd2:
+ freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD2_FRAC_SHIFT);
+ break;
+
+ case kCLOCK_Pfd3:
+ freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD3_FRAC_SHIFT);
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+ freq *= 18U;
+
+ return freq;
+}
+
+/*!
+ * brief Get current USB1 PLL PFD output frequency.
+ *
+ * This function get current output frequency of specific USB1 PLL PFD
+ *
+ * param pfd pfd name to get frequency.
+ * return The PFD output frequency in hertz.
+ */
+uint32_t CLOCK_GetUsb1PfdFreq(clock_pfd_t pfd)
+{
+ uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1);
+
+ switch (pfd)
+ {
+ case kCLOCK_Pfd0:
+ freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT);
+ break;
+
+ case kCLOCK_Pfd1:
+ freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD1_FRAC_SHIFT);
+ break;
+
+ case kCLOCK_Pfd2:
+ freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD2_FRAC_SHIFT);
+ break;
+
+ case kCLOCK_Pfd3:
+ freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD3_FRAC_SHIFT);
+ break;
+
+ default:
+ freq = 0U;
+ break;
+ }
+ freq *= 18U;
+
+ return freq;
+}
+
+/*! brief Enable USB HS PHY PLL clock.
+ *
+ * This function enables the internal 480MHz USB PHY PLL clock.
+ *
+ * param src USB HS PHY PLL clock source.
+ * param freq The frequency specified by src.
+ * retval true The clock is set successfully.
+ * retval false The clock source is invalid to get proper USB HS clock.
+ */
+bool CLOCK_EnableUsbhs1PhyPllClock(clock_usb_phy_src_t src, uint32_t freq)
+{
+ const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
+ CLOCK_InitUsb2Pll(&g_ccmConfigUsbPll);
+ USBPHY2->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */
+ USBPHY2->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK;
+
+ USBPHY2->PWD = 0;
+ USBPHY2->CTRL |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK | USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK |
+ USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK;
+
+ return true;
+}
+
+/*! brief Disable USB HS PHY PLL clock.
+ *
+ * This function disables USB HS PHY PLL clock.
+ */
+void CLOCK_DisableUsbhs1PhyPllClock(void)
+{
+ CCM_ANALOG->PLL_USB2 &= ~CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK;
+ USBPHY2->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cmp.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cmp.c
new file mode 100644
index 0000000000..8f6bed69b4
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cmp.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_cmp.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.cmp"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Get instance number for CMP module.
+ *
+ * @param base CMP peripheral base address
+ */
+static uint32_t CMP_GetInstance(CMP_Type *base);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief Pointers to CMP bases for each instance. */
+static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS;
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to CMP clocks for each instance. */
+static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*******************************************************************************
+ * Codes
+ ******************************************************************************/
+static uint32_t CMP_GetInstance(CMP_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_cmpBases); instance++)
+ {
+ if (s_cmpBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_cmpBases));
+
+ return instance;
+}
+
+/*!
+ * brief Initializes the CMP.
+ *
+ * This function initializes the CMP module. The operations included are as follows.
+ * - Enabling the clock for CMP module.
+ * - Configuring the comparator.
+ * - Enabling the CMP module.
+ * Note that for some devices, multiple CMP instances share the same clock gate. In this case, to enable the clock for
+ * any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP.
+ *
+ * param base CMP peripheral base address.
+ * param config Pointer to the configuration structure.
+ */
+void CMP_Init(CMP_Type *base, const cmp_config_t *config)
+{
+ assert(NULL != config);
+
+ uint8_t tmp8;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Enable the clock. */
+ CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+ /* Configure. */
+ CMP_Enable(base, false); /* Disable the CMP module during configuring. */
+ /* CMPx_CR1. */
+ tmp8 = (uint8_t)(base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK));
+ if (true == config->enableHighSpeed)
+ {
+ tmp8 |= CMP_CR1_PMODE_MASK;
+ }
+ if (true == config->enableInvertOutput)
+ {
+ tmp8 |= CMP_CR1_INV_MASK;
+ }
+ if (true == config->useUnfilteredOutput)
+ {
+ tmp8 |= CMP_CR1_COS_MASK;
+ }
+ if (true == config->enablePinOut)
+ {
+ tmp8 |= CMP_CR1_OPE_MASK;
+ }
+#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
+ if (true == config->enableTriggerMode)
+ {
+ tmp8 |= CMP_CR1_TRIGM_MASK;
+ }
+ else
+ {
+ tmp8 &= ~(uint8_t)CMP_CR1_TRIGM_MASK;
+ }
+#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
+ base->CR1 = tmp8;
+
+ /* CMPx_CR0. */
+ tmp8 = base->CR0 & ~(uint8_t)CMP_CR0_HYSTCTR_MASK;
+ tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode);
+ base->CR0 = tmp8;
+
+ CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */
+}
+
+/*!
+ * brief De-initializes the CMP module.
+ *
+ * This function de-initializes the CMP module. The operations included are as follows.
+ * - Disabling the CMP module.
+ * - Disabling the clock for CMP module.
+ *
+ * This function disables the clock for the CMP.
+ * Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the
+ * clock for the CMP, ensure that all the CMP instances are not used.
+ *
+ * param base CMP peripheral base address.
+ */
+void CMP_Deinit(CMP_Type *base)
+{
+ /* Disable the CMP module. */
+ CMP_Enable(base, false);
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Disable the clock. */
+ CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Initializes the CMP user configuration structure.
+ *
+ * This function initializes the user configuration structure to these default values.
+ * code
+ * config->enableCmp = true;
+ * config->hysteresisMode = kCMP_HysteresisLevel0;
+ * config->enableHighSpeed = false;
+ * config->enableInvertOutput = false;
+ * config->useUnfilteredOutput = false;
+ * config->enablePinOut = false;
+ * config->enableTriggerMode = false;
+ * endcode
+ * param config Pointer to the configuration structure.
+ */
+void CMP_GetDefaultConfig(cmp_config_t *config)
+{
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->enableCmp = true; /* Enable the CMP module after initialization. */
+ config->hysteresisMode = kCMP_HysteresisLevel0;
+ config->enableHighSpeed = false;
+ config->enableInvertOutput = false;
+ config->useUnfilteredOutput = false;
+ config->enablePinOut = false;
+#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE
+ config->enableTriggerMode = false;
+#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */
+}
+
+/*!
+ * brief Sets the input channels for the comparator.
+ *
+ * This function sets the input channels for the comparator.
+ * Note that two input channels cannot be set the same way in the application. When the user selects the same input
+ * from the analog mux to the positive and negative port, the comparator is disabled automatically.
+ *
+ * param base CMP peripheral base address.
+ * param positiveChannel Positive side input channel number. Available range is 0-7.
+ * param negativeChannel Negative side input channel number. Available range is 0-7.
+ */
+void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel)
+{
+ uint8_t tmp8 = base->MUXCR;
+
+ tmp8 &= ~(uint8_t)(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK);
+ tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel);
+ base->MUXCR = tmp8;
+}
+
+#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA
+/*!
+ * brief Enables/disables the DMA request for rising/falling events.
+ *
+ * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of
+ * the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from
+ * the CMP
+ * if the DMA is disabled.
+ *
+ * param base CMP peripheral base address.
+ * param enable Enables or disables the feature.
+ */
+void CMP_EnableDMA(CMP_Type *base, bool enable)
+{
+ uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
+
+ if (enable)
+ {
+ tmp8 |= CMP_SCR_DMAEN_MASK;
+ }
+ else
+ {
+ tmp8 &= ~(uint8_t)CMP_SCR_DMAEN_MASK;
+ }
+ base->SCR = tmp8;
+}
+#endif /* FSL_FEATURE_CMP_HAS_DMA */
+
+/*!
+ * brief Configures the filter.
+ *
+ * param base CMP peripheral base address.
+ * param config Pointer to the configuration structure.
+ */
+void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config)
+{
+ assert(NULL != config);
+
+ uint8_t tmp8;
+
+#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT
+ /* Choose the clock source for sampling. */
+ if (config->enableSample)
+ {
+ base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */
+ }
+ else
+ {
+ base->CR1 &= (uint8_t)(~CMP_CR1_SE_MASK); /* Choose the internal divided bus clock. */
+ }
+#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */
+ /* Set the filter count. */
+ tmp8 = (uint8_t)(base->CR0 & ~CMP_CR0_FILTER_CNT_MASK);
+ tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount);
+ base->CR0 = tmp8;
+ /* Set the filter period. It is used as the divider to bus clock. */
+ base->FPR = CMP_FPR_FILT_PER(config->filterPeriod);
+}
+
+/*!
+ * brief Configures the internal DAC.
+ *
+ * param base CMP peripheral base address.
+ * param config Pointer to the configuration structure. "NULL" disables the feature.
+ */
+void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config)
+{
+ uint8_t tmp8 = 0U;
+
+ if (NULL == config)
+ {
+ /* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/
+ base->DACCR = 0U;
+ return;
+ }
+ /* CMPx_DACCR. */
+ tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */
+ if (kCMP_VrefSourceVin2 == config->referenceVoltageSource)
+ {
+ tmp8 |= CMP_DACCR_VRSEL_MASK;
+ }
+ tmp8 |= CMP_DACCR_VOSEL(config->DACValue);
+
+ base->DACCR = tmp8;
+}
+
+/*!
+ * brief Enables the interrupts.
+ *
+ * param base CMP peripheral base address.
+ * param mask Mask value for interrupts. See "_cmp_interrupt_enable".
+ */
+void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask)
+{
+ uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
+
+ if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask))
+ {
+ tmp8 |= CMP_SCR_IER_MASK;
+ }
+ if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask))
+ {
+ tmp8 |= CMP_SCR_IEF_MASK;
+ }
+ base->SCR = tmp8;
+}
+
+/*!
+ * brief Disables the interrupts.
+ *
+ * param base CMP peripheral base address.
+ * param mask Mask value for interrupts. See "_cmp_interrupt_enable".
+ */
+void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask)
+{
+ uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
+
+ if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask))
+ {
+ tmp8 &= ~(uint8_t)CMP_SCR_IER_MASK;
+ }
+ if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask))
+ {
+ tmp8 &= ~(uint8_t)CMP_SCR_IEF_MASK;
+ }
+ base->SCR = tmp8;
+}
+
+/*!
+ * brief Gets the status flags.
+ *
+ * param base CMP peripheral base address.
+ *
+ * return Mask value for the asserted flags. See "_cmp_status_flags".
+ */
+uint32_t CMP_GetStatusFlags(CMP_Type *base)
+{
+ uint32_t ret32 = 0U;
+
+ if (0U != (CMP_SCR_CFR_MASK & base->SCR))
+ {
+ ret32 |= (uint32_t)kCMP_OutputRisingEventFlag;
+ }
+ if (0U != (CMP_SCR_CFF_MASK & base->SCR))
+ {
+ ret32 |= (uint32_t)kCMP_OutputFallingEventFlag;
+ }
+ if (0U != (CMP_SCR_COUT_MASK & base->SCR))
+ {
+ ret32 |= (uint32_t)kCMP_OutputAssertEventFlag;
+ }
+ return ret32;
+}
+
+/*!
+ * brief Clears the status flags.
+ *
+ * param base CMP peripheral base address.
+ * param mask Mask value for the flags. See "_cmp_status_flags".
+ */
+void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask)
+{
+ uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */
+
+ if (0U != ((uint32_t)kCMP_OutputRisingEventFlag & mask))
+ {
+ tmp8 |= CMP_SCR_CFR_MASK;
+ }
+ if (0U != ((uint32_t)kCMP_OutputFallingEventFlag & mask))
+ {
+ tmp8 |= CMP_SCR_CFF_MASK;
+ }
+ base->SCR = tmp8;
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_common.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_common.c
new file mode 100644
index 0000000000..fd96a955c3
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_common.c
@@ -0,0 +1,280 @@
+/*
+ * 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);
+ SDK_ISR_EXIT_BARRIER;
+
+ 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.
+ */
+#if defined(SDK_DELAY_USE_DWT) && defined(DWT)
+void enableCpuCycleCounter(void)
+{
+ /* Make sure the DWT trace fucntion is enabled. */
+ if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & CoreDebug->DEMCR))
+ {
+ CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
+ }
+
+ /* CYCCNT not supported on this device. */
+ assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk));
+
+ /* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */
+ if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT->CTRL))
+ {
+ DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
+ }
+}
+
+uint32_t getCpuCycleCount(void)
+{
+ return DWT->CYCCNT;
+}
+#elif defined __XCC__
+extern uint32_t xthal_get_ccount(void);
+void enableCpuCycleCounter(void)
+{
+ /* do nothing */
+}
+
+uint32_t getCpuCycleCount(void)
+{
+ return xthal_get_ccount();
+}
+#endif
+
+#ifndef __XCC__
+#if (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT))
+#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) */
+#endif /* (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT)) */
+#endif /* __XCC__ */
+/*!
+ * @brief Delay at least for some time.
+ * Please note that, if not uses DWT, this API will use while loop for delay, different run-time environments have
+ * effect on the delay time. If precise delay is needed, please enable DWT delay. The two parmeters delay_us and
+ * coreClock_Hz have limitation. For example, in the platform with 1GHz coreClock_Hz, the delay_us only supports
+ * up to 4294967 in current code. If long time delay is needed, please implement a new delay function.
+ *
+ * @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);
+
+#if defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) /* Use DWT for better accuracy */
+
+ enableCpuCycleCounter();
+ /* Calculate the count ticks. */
+ count += getCpuCycleCount();
+
+ if (count > UINT32_MAX)
+ {
+ count -= UINT32_MAX;
+ /* Wait for cyccnt overflow. */
+ while (count < getCpuCycleCount())
+ {
+ }
+ }
+
+ /* Wait for cyccnt reach count value. */
+ while (count > getCpuCycleCount())
+ {
+ }
+#else
+ /* 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 1.5. Other M cores use
+ * divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does
+ * not matter because other instructions outside while loop is enough to fill the time.
+ */
+#if (__CORTEX_M == 7)
+ count = count / 3U * 2U;
+#else
+ count = count / 4U;
+#endif
+ DelayLoop((uint32_t)count);
+#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) */
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_csi.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_csi.c
new file mode 100644
index 0000000000..2eea263e5f
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_csi.c
@@ -0,0 +1,1395 @@
+/*
+ * Copyright 2017-2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_csi.h"
+#if CSI_DRIVER_FRAG_MODE
+#include "fsl_cache.h"
+#endif
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.csi"
+#endif
+
+/* Two frame buffer loaded to CSI register at most. */
+#define CSI_MAX_ACTIVE_FRAME_NUM 2U
+
+/* CSI driver only support RGB565 and YUV422 in fragment mode, 2 bytes per pixel. */
+#define CSI_FRAG_INPUT_BYTES_PER_PIXEL 2U
+
+/*!
+ * @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 Get the instance from the base address
+ *
+ * @param base CSI peripheral base address
+ *
+ * @return The CSI module instance
+ */
+static uint32_t CSI_GetInstance(CSI_Type *base);
+
+#if !CSI_DRIVER_FRAG_MODE
+/*!
+ * @brief Get the delta value of two index in queue.
+ *
+ * @param startIdx Start index.
+ * @param endIdx End index.
+ *
+ * @return The delta between startIdx and endIdx in queue.
+ */
+static uint8_t CSI_TransferGetQueueDelta(uint8_t startIdx, uint8_t endIdx);
+
+/*!
+ * @brief Increase a index value in queue.
+ *
+ * This function increases the index value in the queue, if the index is out of
+ * the queue range, it is reset to 0.
+ *
+ * @param idx The index value to increase.
+ *
+ * @return The index value after increase.
+ */
+static uint8_t CSI_TransferIncreaseQueueIdx(uint8_t idx);
+
+/*!
+ * @brief Get the empty frame buffer count in queue.
+ *
+ * @param base CSI peripheral base address
+ * @param handle Pointer to CSI driver handle.
+ *
+ * @return Number of the empty frame buffer count in queue.
+ */
+static uint32_t CSI_TransferGetEmptyBufferCount(csi_handle_t *handle);
+
+/*!
+ * @brief Get the empty frame buffer.
+ *
+ * This function should only be called when frame buffer count larger than 0.
+ *
+ * @param handle Pointer to CSI driver handle.
+ *
+ * @return Empty buffer
+ */
+static uint32_t CSI_TransferGetEmptyBuffer(csi_handle_t *handle);
+
+/*!
+ * @brief Put the empty frame buffer.
+ *
+ * @param handle Pointer to CSI driver handle.
+ * @param buffer The empty buffer to put.
+ */
+static void CSI_TransferPutEmptyBuffer(csi_handle_t *handle, uint32_t buffer);
+
+/*!
+ * @brief Get the RX frame buffer address.
+ *
+ * @param base CSI peripheral base address.
+ * @param index Buffer index.
+ * @return Frame buffer address.
+ */
+static uint32_t CSI_GetRxBufferAddr(CSI_Type *base, uint8_t index);
+
+/* Typedef for interrupt handler. */
+typedef void (*csi_isr_t)(CSI_Type *base, csi_handle_t *handle);
+
+#else
+
+/* Typedef for interrupt handler to work in fragment mode. */
+typedef void (*csi_isr_t)(CSI_Type *base, csi_frag_handle_t *handle);
+#endif /* CSI_DRIVER_FRAG_MODE */
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief Pointers to CSI bases for each instance. */
+static CSI_Type *const s_csiBases[] = CSI_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to CSI clocks for each CSI submodule. */
+static const clock_ip_name_t s_csiClocks[] = CSI_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/* Array for the CSI driver handle. */
+#if !CSI_DRIVER_FRAG_MODE
+static csi_handle_t *s_csiHandle[ARRAY_SIZE(s_csiBases)];
+#else
+static csi_frag_handle_t *s_csiHandle[ARRAY_SIZE(s_csiBases)];
+#endif
+
+/* Array of CSI IRQ number. */
+static const IRQn_Type s_csiIRQ[] = CSI_IRQS;
+
+/* CSI ISR for transactional APIs. */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+static csi_isr_t s_csiIsr = (csi_isr_t)DefaultISR;
+#else
+static csi_isr_t s_csiIsr;
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static uint32_t CSI_GetInstance(CSI_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_csiBases); instance++)
+ {
+ if (s_csiBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_csiBases));
+
+ return instance;
+}
+
+#if !CSI_DRIVER_FRAG_MODE
+static uint8_t CSI_TransferGetQueueDelta(uint8_t startIdx, uint8_t endIdx)
+{
+ uint8_t ret;
+
+ if (endIdx >= startIdx)
+ {
+ ret = endIdx - startIdx;
+ }
+ else
+ {
+ ret = (uint8_t)(endIdx + CSI_DRIVER_ACTUAL_QUEUE_SIZE - startIdx);
+ }
+
+ return ret;
+}
+
+static uint8_t CSI_TransferIncreaseQueueIdx(uint8_t idx)
+{
+ uint8_t ret;
+
+ /*
+ * Here not use the method:
+ * ret = (idx+1) % CSI_DRIVER_ACTUAL_QUEUE_SIZE;
+ *
+ * Because the mod function might be slow.
+ */
+
+ ret = idx + 1U;
+
+ if (ret >= CSI_DRIVER_ACTUAL_QUEUE_SIZE)
+ {
+ ret = 0U;
+ }
+
+ return ret;
+}
+
+static uint32_t CSI_TransferGetEmptyBufferCount(csi_handle_t *handle)
+{
+ return handle->emptyBufferCnt;
+}
+
+static uint32_t CSI_TransferGetEmptyBuffer(csi_handle_t *handle)
+{
+ pvoid_to_u32_t buf;
+
+ buf.pvoid = handle->emptyBuffer;
+ handle->emptyBufferCnt--;
+ handle->emptyBuffer = *(void **)(buf.pvoid);
+
+ return buf.u32;
+}
+
+static void CSI_TransferPutEmptyBuffer(csi_handle_t *handle, uint32_t buffer)
+{
+ pvoid_to_u32_t buf;
+ buf.u32 = buffer;
+
+ *(void **)(buf.pvoid) = handle->emptyBuffer;
+ handle->emptyBuffer = buf.pvoid;
+ handle->emptyBufferCnt++;
+}
+
+static uint32_t CSI_GetRxBufferAddr(CSI_Type *base, uint8_t index)
+{
+ uint32_t addr;
+
+ if (index != 0U)
+ {
+ addr = base->CSIDMASA_FB2;
+ }
+ else
+ {
+ addr = base->CSIDMASA_FB1;
+ }
+
+ return addr;
+}
+
+#endif /* CSI_DRIVER_FRAG_MODE */
+
+/*!
+ * brief Initialize the CSI.
+ *
+ * This function enables the CSI peripheral clock, and resets the CSI registers.
+ *
+ * param base CSI peripheral base address.
+ * param config Pointer to the configuration structure.
+ *
+ * retval kStatus_Success Initialize successfully.
+ * retval kStatus_InvalidArgument Initialize failed because of invalid argument.
+ */
+status_t CSI_Init(CSI_Type *base, const csi_config_t *config)
+{
+ assert(NULL != config);
+ uint32_t reg;
+ uint32_t imgWidth_Bytes;
+ uint8_t busCyclePerPixel;
+
+ imgWidth_Bytes = (uint32_t)config->width * (uint32_t)config->bytesPerPixel;
+
+ /* The image width and frame buffer pitch should be multiple of 8-bytes. */
+ if ((0U != (imgWidth_Bytes & 0x07U)) || (0U != ((uint32_t)config->linePitch_Bytes & 0x07U)))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ uint32_t instance = CSI_GetInstance(base);
+ CLOCK_EnableClock(s_csiClocks[instance]);
+#endif
+
+ CSI_Reset(base);
+
+ /* Configure CSICR1. CSICR1 has been reset to the default value, so could write it directly. */
+ reg = ((uint32_t)config->workMode) | config->polarityFlags | CSI_CSICR1_FCC_MASK;
+
+ if (config->useExtVsync)
+ {
+ reg |= CSI_CSICR1_EXT_VSYNC_MASK;
+ }
+
+ base->CSICR1 = reg;
+
+ /*
+ * Generally, CSIIMAG_PARA[IMAGE_WIDTH] indicates how many data bus cycles per line.
+ * One special case is when receiving 24-bit pixels through 8-bit data bus.
+ * In this case, the CSIIMAG_PARA[IMAGE_WIDTH] should be set to the pixel number per line.
+ */
+ if ((kCSI_DataBus8Bit == config->dataBus) && (2U == config->bytesPerPixel))
+ {
+ busCyclePerPixel = 2U;
+ }
+ else
+ {
+ busCyclePerPixel = 1U;
+ }
+
+ if (4U == config->bytesPerPixel)
+ {
+ base->CSICR18 |= CSI_CSICR18_PARALLEL24_EN_MASK;
+ }
+
+ if (kCSI_DataBus16Bit == config->dataBus)
+ {
+ base->CSICR3 |= CSI_CSICR3_TWO_8BIT_SENSOR_MASK;
+ }
+
+ /* Image parameter. */
+ base->CSIIMAG_PARA =
+ (((uint32_t)config->width * (uint32_t)busCyclePerPixel) << CSI_CSIIMAG_PARA_IMAGE_WIDTH_SHIFT) |
+ ((uint32_t)(config->height) << CSI_CSIIMAG_PARA_IMAGE_HEIGHT_SHIFT);
+
+ /* The CSI frame buffer bus is 8-byte width. */
+ base->CSIFBUF_PARA = (uint32_t)((config->linePitch_Bytes - imgWidth_Bytes) / 8U)
+ << CSI_CSIFBUF_PARA_FBUF_STRIDE_SHIFT;
+
+ /* Enable auto ECC. */
+ base->CSICR3 |= CSI_CSICR3_ECC_AUTO_EN_MASK;
+
+ /*
+ * For better performance.
+ * The DMA burst size could be set to 16 * 8 byte, 8 * 8 byte, or 4 * 8 byte,
+ * choose the best burst size based on bytes per line.
+ */
+ if (0U == (imgWidth_Bytes % (8U * 16U)))
+ {
+ base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(3U);
+ base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((2U << CSI_CSICR3_RxFF_LEVEL_SHIFT));
+ }
+ else if (0U == (imgWidth_Bytes % (8U * 8U)))
+ {
+ base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(2U);
+ base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((1U << CSI_CSICR3_RxFF_LEVEL_SHIFT));
+ }
+ else
+ {
+ base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(1U);
+ base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((0U << CSI_CSICR3_RxFF_LEVEL_SHIFT));
+ }
+
+ CSI_ReflashFifoDma(base, kCSI_RxFifo);
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief De-initialize the CSI.
+ *
+ * This function disables the CSI peripheral clock.
+ *
+ * param base CSI peripheral base address.
+ */
+void CSI_Deinit(CSI_Type *base)
+{
+ /* Disable transfer first. */
+ CSI_Stop(base);
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ uint32_t instance = CSI_GetInstance(base);
+ CLOCK_DisableClock(s_csiClocks[instance]);
+#endif
+}
+
+/*!
+ * brief Reset the CSI.
+ *
+ * This function resets the CSI peripheral registers to default status.
+ *
+ * param base CSI peripheral base address.
+ */
+void CSI_Reset(CSI_Type *base)
+{
+ uint32_t csisr;
+
+ /* Disable transfer first. */
+ CSI_Stop(base);
+
+ /* Disable DMA request. */
+ base->CSICR3 = 0U;
+
+ /* Reset the fame count. */
+ base->CSICR3 |= CSI_CSICR3_FRMCNT_RST_MASK;
+ while (0U != (base->CSICR3 & CSI_CSICR3_FRMCNT_RST_MASK))
+ {
+ }
+
+ /* Clear the RX FIFO. */
+ CSI_ClearFifo(base, kCSI_AllFifo);
+
+ /* Reflash DMA. */
+ CSI_ReflashFifoDma(base, kCSI_AllFifo);
+
+ /* Clear the status. */
+ csisr = base->CSISR;
+ base->CSISR = csisr;
+
+ /* Set the control registers to default value. */
+ base->CSICR1 = CSI_CSICR1_HSYNC_POL_MASK | CSI_CSICR1_EXT_VSYNC_MASK;
+ base->CSICR2 = 0U;
+ base->CSICR3 = 0U;
+#if defined(CSI_CSICR18_CSI_LCDIF_BUFFER_LINES)
+ base->CSICR18 = CSI_CSICR18_AHB_HPROT(0x0DU) | CSI_CSICR18_CSI_LCDIF_BUFFER_LINES(0x02U);
+#else
+ base->CSICR18 = CSI_CSICR18_AHB_HPROT(0x0DU);
+#endif
+ base->CSIFBUF_PARA = 0U;
+ base->CSIIMAG_PARA = 0U;
+}
+
+/*!
+ * brief Get the default configuration for to initialize the CSI.
+ *
+ * The default configuration value is:
+ *
+ * code
+ config->width = 320U;
+ config->height = 240U;
+ config->polarityFlags = kCSI_HsyncActiveHigh | kCSI_DataLatchOnRisingEdge;
+ config->bytesPerPixel = 2U;
+ config->linePitch_Bytes = 320U * 2U;
+ config->workMode = kCSI_GatedClockMode;
+ config->dataBus = kCSI_DataBus8Bit;
+ config->useExtVsync = true;
+ endcode
+ *
+ * param config Pointer to the CSI configuration.
+ */
+void CSI_GetDefaultConfig(csi_config_t *config)
+{
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->width = 320U;
+ config->height = 240U;
+ config->polarityFlags = (uint32_t)kCSI_HsyncActiveHigh | (uint32_t)kCSI_DataLatchOnRisingEdge;
+ config->bytesPerPixel = 2U;
+ config->linePitch_Bytes = 320U * 2U;
+ config->workMode = kCSI_GatedClockMode;
+ config->dataBus = kCSI_DataBus8Bit;
+ config->useExtVsync = true;
+}
+
+/*!
+ * brief Set the RX frame buffer address.
+ *
+ * param base CSI peripheral base address.
+ * param index Buffer index.
+ * param addr Frame buffer address to set.
+ */
+void CSI_SetRxBufferAddr(CSI_Type *base, uint8_t index, uint32_t addr)
+{
+ if (0U != index)
+ {
+ base->CSIDMASA_FB2 = addr;
+ }
+ else
+ {
+ base->CSIDMASA_FB1 = addr;
+ }
+}
+
+/*!
+ * brief Clear the CSI FIFO.
+ *
+ * This function clears the CSI FIFO.
+ *
+ * param base CSI peripheral base address.
+ * param fifo The FIFO to clear.
+ */
+void CSI_ClearFifo(CSI_Type *base, csi_fifo_t fifo)
+{
+ uint32_t cr1;
+ uint32_t mask = 0U;
+
+ /* The FIFO could only be cleared when CSICR1[FCC] = 0, so first clear the FCC. */
+ cr1 = base->CSICR1;
+ base->CSICR1 = (cr1 & ~CSI_CSICR1_FCC_MASK);
+
+ if (0U != ((uint32_t)fifo & (uint32_t)kCSI_RxFifo))
+ {
+ mask |= CSI_CSICR1_CLR_RXFIFO_MASK;
+ }
+
+ if (0U != ((uint32_t)fifo & (uint32_t)kCSI_StatFifo))
+ {
+ mask |= CSI_CSICR1_CLR_STATFIFO_MASK;
+ }
+
+ base->CSICR1 = (cr1 & ~CSI_CSICR1_FCC_MASK) | mask;
+
+ /* Wait clear completed. */
+ while (0U != (base->CSICR1 & mask))
+ {
+ }
+
+ /* Recover the FCC. */
+ base->CSICR1 = cr1;
+}
+
+/*!
+ * brief Reflash the CSI FIFO DMA.
+ *
+ * This function reflashes the CSI FIFO DMA.
+ *
+ * For RXFIFO, there are two frame buffers. When the CSI module started, it saves
+ * the frames to frame buffer 0 then frame buffer 1, the two buffers will be
+ * written by turns. After reflash DMA using this function, the CSI is reset to
+ * save frame to buffer 0.
+ *
+ * param base CSI peripheral base address.
+ * param fifo The FIFO DMA to reflash.
+ */
+void CSI_ReflashFifoDma(CSI_Type *base, csi_fifo_t fifo)
+{
+ uint32_t cr3 = 0U;
+
+ if (0U != ((uint32_t)fifo & (uint32_t)kCSI_RxFifo))
+ {
+ cr3 |= CSI_CSICR3_DMA_REFLASH_RFF_MASK;
+ }
+
+ if (0U != ((uint32_t)fifo & (uint32_t)kCSI_StatFifo))
+ {
+ cr3 |= CSI_CSICR3_DMA_REFLASH_SFF_MASK;
+ }
+
+ base->CSICR3 |= cr3;
+
+ /* Wait clear completed. */
+ while (0U != (base->CSICR3 & cr3))
+ {
+ }
+}
+
+/*!
+ * brief Enable or disable the CSI FIFO DMA request.
+ *
+ * param base CSI peripheral base address.
+ * param fifo The FIFO DMA reques to enable or disable.
+ * param enable True to enable, false to disable.
+ */
+void CSI_EnableFifoDmaRequest(CSI_Type *base, csi_fifo_t fifo, bool enable)
+{
+ uint32_t cr3 = 0U;
+
+ if (0U != ((uint32_t)fifo & (uint32_t)kCSI_RxFifo))
+ {
+ cr3 |= CSI_CSICR3_DMA_REQ_EN_RFF_MASK;
+ }
+
+ if (0U != ((uint32_t)fifo & (uint32_t)kCSI_StatFifo))
+ {
+ cr3 |= CSI_CSICR3_DMA_REQ_EN_SFF_MASK;
+ }
+
+ if (enable)
+ {
+ base->CSICR3 |= cr3;
+ }
+ else
+ {
+ base->CSICR3 &= ~cr3;
+ }
+}
+
+/*!
+ * brief Enables CSI interrupt requests.
+ *
+ * param base CSI peripheral base address.
+ * param mask The interrupts to enable, pass in as OR'ed value of ref _csi_interrupt_enable.
+ */
+void CSI_EnableInterrupts(CSI_Type *base, uint32_t mask)
+{
+ base->CSICR1 |= (mask & CSI_CSICR1_INT_EN_MASK);
+ base->CSICR3 |= (mask & CSI_CSICR3_INT_EN_MASK);
+ base->CSICR18 |= ((mask & CSI_CSICR18_INT_EN_MASK) >> 6U);
+}
+
+/*!
+ * brief Disable CSI interrupt requests.
+ *
+ * param base CSI peripheral base address.
+ * param mask The interrupts to disable, pass in as OR'ed value of ref _csi_interrupt_enable.
+ */
+void CSI_DisableInterrupts(CSI_Type *base, uint32_t mask)
+{
+ base->CSICR1 &= ~(mask & CSI_CSICR1_INT_EN_MASK);
+ base->CSICR3 &= ~(mask & CSI_CSICR3_INT_EN_MASK);
+ base->CSICR18 &= ~((mask & CSI_CSICR18_INT_EN_MASK) >> 6U);
+}
+
+#if !CSI_DRIVER_FRAG_MODE
+/*!
+ * brief Initializes the CSI handle.
+ *
+ * This function initializes CSI handle, it should be called before any other
+ * CSI transactional functions.
+ *
+ * param base CSI peripheral base address.
+ * param handle Pointer to the handle structure.
+ * param callback Callback function for CSI transfer.
+ * param userData Callback function parameter.
+ *
+ * retval kStatus_Success Handle created successfully.
+ */
+status_t CSI_TransferCreateHandle(CSI_Type *base,
+ csi_handle_t *handle,
+ csi_transfer_callback_t callback,
+ void *userData)
+{
+ assert(NULL != handle);
+ uint32_t instance;
+
+ (void)memset(handle, 0, sizeof(*handle));
+
+ /* Set the callback and user data. */
+ handle->callback = callback;
+ handle->userData = userData;
+
+ /* Get instance from peripheral base address. */
+ instance = CSI_GetInstance(base);
+
+ /* Save the handle in global variables to support the double weak mechanism. */
+ s_csiHandle[instance] = handle;
+
+ s_csiIsr = CSI_TransferHandleIRQ;
+
+ /* Enable interrupt. */
+ (void)EnableIRQ(s_csiIRQ[instance]);
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Start the transfer using transactional functions.
+ *
+ * When the empty frame buffers have been submit to CSI driver using function
+ * ref CSI_TransferSubmitEmptyBuffer, user could call this function to start
+ * the transfer. The incoming frame will be saved to the empty frame buffer,
+ * and user could be optionally notified through callback function.
+ *
+ * param base CSI peripheral base address.
+ * param handle Pointer to the handle structure.
+ *
+ * retval kStatus_Success Started successfully.
+ * retval kStatus_CSI_NoEmptyBuffer Could not start because no empty frame buffer in queue.
+ */
+status_t CSI_TransferStart(CSI_Type *base, csi_handle_t *handle)
+{
+ assert(NULL != handle);
+
+ uint32_t emptyBufferCount;
+
+ emptyBufferCount = CSI_TransferGetEmptyBufferCount(handle);
+
+ if (emptyBufferCount < 2U)
+ {
+ return kStatus_CSI_NoEmptyBuffer;
+ }
+
+ /*
+ * Write to memory from first completed frame.
+ * DMA base addr switch at the edge of the first data of each frame, thus
+ * if one frame is broken, it could be reset at the next frame.
+ */
+ base->CSICR18 = (base->CSICR18 & ~CSI_CSICR18_MASK_OPTION_MASK) | CSI_CSICR18_MASK_OPTION(0) |
+ CSI_CSICR18_BASEADDR_SWITCH_SEL_MASK | CSI_CSICR18_BASEADDR_SWITCH_EN_MASK;
+
+ /* Load the frame buffer to CSI register, there are at least two empty buffers. */
+ base->CSIDMASA_FB1 = CSI_TransferGetEmptyBuffer(handle);
+ base->CSIDMASA_FB2 = CSI_TransferGetEmptyBuffer(handle);
+
+ handle->activeBufferNum = CSI_MAX_ACTIVE_FRAME_NUM;
+
+ /* After reflash DMA, the CSI saves frame to frame buffer 0. */
+ CSI_ReflashFifoDma(base, kCSI_RxFifo);
+
+ handle->transferStarted = true;
+
+ CSI_EnableInterrupts(
+ base, (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable | (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable);
+
+ CSI_Start(base);
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Stop the transfer using transactional functions.
+ *
+ * The driver does not clean the full frame buffers in queue. In other words, after
+ * calling this function, user still could get the full frame buffers in queue
+ * using function ref CSI_TransferGetFullBuffer.
+ *
+ * param base CSI peripheral base address.
+ * param handle Pointer to the handle structure.
+ *
+ * retval kStatus_Success Stoped successfully.
+ */
+status_t CSI_TransferStop(CSI_Type *base, csi_handle_t *handle)
+{
+ assert(NULL != handle);
+ uint8_t activeBufferNum;
+ uint8_t bufIdx;
+
+ CSI_Stop(base);
+ CSI_DisableInterrupts(
+ base, (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable | (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable);
+
+ activeBufferNum = handle->activeBufferNum;
+
+ handle->transferStarted = false;
+ handle->activeBufferNum = 0;
+
+ /*
+ * Put active buffers to empty queue.
+ *
+ * If there is only one active frame buffers, then FB0 and FB1 use the same address,
+ * put FB0 to empty buffer queue is OK.
+ */
+ for (bufIdx = 0; bufIdx < activeBufferNum; bufIdx++)
+ {
+ CSI_TransferPutEmptyBuffer(handle, CSI_GetRxBufferAddr(base, bufIdx));
+ }
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Submit empty frame buffer to queue.
+ *
+ * This function could be called before ref CSI_TransferStart or after ref
+ * CSI_TransferStart. If there is no room in queue to store the empty frame
+ * buffer, this function returns error.
+ *
+ * param base CSI peripheral base address.
+ * param handle Pointer to the handle structure.
+ * param frameBuffer Empty frame buffer to submit.
+ *
+ * retval kStatus_Success Started successfully.
+ * retval kStatus_CSI_QueueFull Could not submit because there is no room in queue.
+ */
+status_t CSI_TransferSubmitEmptyBuffer(CSI_Type *base, csi_handle_t *handle, uint32_t frameBuffer)
+{
+ uint32_t csicr1;
+
+ /* Disable the interrupt to protect the index information in handle. */
+ csicr1 = base->CSICR1;
+
+ base->CSICR1 = (csicr1 & ~(CSI_CSICR1_FB2_DMA_DONE_INTEN_MASK | CSI_CSICR1_FB1_DMA_DONE_INTEN_MASK));
+
+ /* Save the empty frame buffer address to queue. */
+ CSI_TransferPutEmptyBuffer(handle, frameBuffer);
+
+ base->CSICR1 = csicr1;
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Get one full frame buffer from queue.
+ *
+ * After the transfer started using function ref CSI_TransferStart, the incoming
+ * frames will be saved to the empty frame buffers in queue. This function gets
+ * the full-filled frame buffer from the queue. If there is no full frame buffer
+ * in queue, this function returns error.
+ *
+ * param base CSI peripheral base address.
+ * param handle Pointer to the handle structure.
+ * param frameBuffer Full frame buffer.
+ *
+ * retval kStatus_Success Started successfully.
+ * retval kStatus_CSI_NoFullBuffer There is no full frame buffer in queue.
+ */
+status_t CSI_TransferGetFullBuffer(CSI_Type *base, csi_handle_t *handle, uint32_t *frameBuffer)
+{
+ uint32_t csicr1;
+ status_t status;
+ uint8_t queueReadIdx;
+ uint8_t queueWriteIdx;
+
+ queueReadIdx = handle->queueReadIdx;
+ queueWriteIdx = handle->queueWriteIdx;
+
+ /* No full frame buffer. */
+ if (queueReadIdx == queueWriteIdx)
+ {
+ status = kStatus_CSI_NoFullBuffer;
+ }
+ else
+ {
+ /* Disable the interrupt to protect the index information in handle. */
+ csicr1 = base->CSICR1;
+
+ base->CSICR1 = (csicr1 & ~(CSI_CSICR1_FB2_DMA_DONE_INTEN_MASK | CSI_CSICR1_FB1_DMA_DONE_INTEN_MASK));
+
+ *frameBuffer = handle->frameBufferQueue[handle->queueReadIdx];
+
+ handle->queueReadIdx = CSI_TransferIncreaseQueueIdx(handle->queueReadIdx);
+
+ base->CSICR1 = csicr1;
+
+ status = kStatus_Success;
+ }
+
+ return status;
+}
+
+/*!
+ * brief CSI IRQ handle function.
+ *
+ * This function handles the CSI IRQ request to work with CSI driver transactional
+ * APIs.
+ *
+ * param base CSI peripheral base address.
+ * param handle CSI handle pointer.
+ */
+void CSI_TransferHandleIRQ(CSI_Type *base, csi_handle_t *handle)
+{
+ uint8_t queueWriteIdx;
+ uint8_t queueReadIdx;
+ uint8_t dmaDoneBufferIdx;
+ uint32_t frameBuffer;
+ uint32_t csisr = base->CSISR;
+
+ /* Clear the error flags. */
+ base->CSISR = csisr;
+
+ /*
+ * If both frame buffer 0 and frame buffer 1 flags assert, driver does not
+ * know which frame buffer ready just now, so skip them.
+ */
+ if ((csisr & (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK)) ==
+ (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK))
+ {
+ ; /* Skip the frames. */
+ }
+ else if (0U != (csisr & (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK)))
+ {
+ if (0U != (csisr & CSI_CSISR_DMA_TSF_DONE_FB2_MASK))
+ {
+ dmaDoneBufferIdx = 1;
+ }
+ else
+ {
+ dmaDoneBufferIdx = 0;
+ }
+
+ if (handle->activeBufferNum == CSI_MAX_ACTIVE_FRAME_NUM)
+ {
+ queueWriteIdx = handle->queueWriteIdx;
+ queueReadIdx = handle->queueReadIdx;
+
+ if (CSI_TransferGetQueueDelta(queueReadIdx, queueWriteIdx) < CSI_DRIVER_QUEUE_SIZE)
+ {
+ /* Put the full frame buffer to full buffer queue. */
+ frameBuffer = CSI_GetRxBufferAddr(base, dmaDoneBufferIdx);
+ handle->frameBufferQueue[queueWriteIdx] = frameBuffer;
+
+ handle->queueWriteIdx = CSI_TransferIncreaseQueueIdx(queueWriteIdx);
+
+ handle->activeBufferNum--;
+
+ if (NULL != handle->callback)
+ {
+ handle->callback(base, handle, kStatus_CSI_FrameDone, handle->userData);
+ }
+ }
+ else
+ {
+ }
+ }
+
+ /*
+ * User may submit new frame buffer in callback, so recheck activeBufferNum here,
+ * if there is only one active buffer in CSI device, the two buffer registers
+ * are both set to the frame buffer address.
+ */
+ if (handle->activeBufferNum < CSI_MAX_ACTIVE_FRAME_NUM)
+ {
+ if (CSI_TransferGetEmptyBufferCount(handle) > 0U)
+ {
+ /* Get the empty frameBuffer, and submit to CSI device. */
+ CSI_SetRxBufferAddr(base, dmaDoneBufferIdx, CSI_TransferGetEmptyBuffer(handle));
+ handle->activeBufferNum++;
+ }
+ else
+ {
+ /* If there is only one active frame buffer, then the two CSI
+ * output buffer address are all set to this frame buffer.
+ */
+ frameBuffer = CSI_GetRxBufferAddr(base, dmaDoneBufferIdx ^ 1U);
+ CSI_SetRxBufferAddr(base, dmaDoneBufferIdx, frameBuffer);
+ }
+ }
+ }
+ else
+ {
+ }
+}
+
+#else /* CSI_DRIVER_FRAG_MODE */
+
+#if defined(__CC_ARM)
+__asm void CSI_ExtractYFromYUYV(void *datBase, const void *dmaBase, size_t count)
+{
+ /* clang-format off */
+ push {r4-r7, lr}
+10
+ LDMIA R1!, {r3-r6}
+ bfi r7, r3, #0, #8 /* Y0 */
+ bfi ip, r5, #0, #8 /* Y4 */
+ lsr r3, r3, #16
+ lsr r5, r5, #16
+ bfi r7, r3, #8, #8 /* Y1 */
+ bfi ip, r5, #8, #8 /* Y5 */
+ bfi r7, r4, #16, #8 /* Y2 */
+ bfi ip, r6, #16, #8 /* Y6 */
+ lsr r4, r4, #16
+ lsr r6, r6, #16
+ bfi r7, r4, #24, #8 /* Y3 */
+ bfi ip, r6, #24, #8 /* Y7 */
+ STMIA r0!, {r7, ip}
+ subs r2, #8
+ bne %b10
+ pop {r4-r7, pc}
+ /* clang-format on */
+}
+
+__asm void CSI_ExtractYFromUYVY(void *datBase, const void *dmaBase, size_t count)
+{
+ /* clang-format off */
+ push {r4-r7, lr}
+10
+ LDMIA R1!, {r3-r6}
+ lsr r3, r3, #8
+ lsr r5, r5, #8
+ bfi r7, r3, #0, #8 /* Y0 */
+ bfi ip, r5, #0, #8 /* Y4 */
+ lsr r3, r3, #16
+ lsr r5, r5, #16
+ bfi r7, r3, #8, #8 /* Y1 */
+ bfi ip, r5, #8, #8 /* Y5 */
+ lsr r4, r4, #8
+ lsr r6, r6, #8
+ bfi r7, r4, #16, #8 /* Y2 */
+ bfi ip, r6, #16, #8 /* Y6 */
+ lsr r4, r4, #16
+ lsr r6, r6, #16
+ bfi r7, r4, #24, #8 /* Y3 */
+ bfi ip, r6, #24, #8 /* Y7 */
+ STMIA r0!, {r7, ip}
+ subs r2, #8
+ bne %b10
+ pop {r4-r7, pc}
+ /* clang-format on */
+}
+
+#elif (defined(__GNUC__) || defined(__ICCARM__)) || defined(__ARMCC_VERSION)
+#if defined(__ICCARM__)
+#pragma diag_suppress = Pe940
+#endif
+__attribute__((naked)) void CSI_ExtractYFromYUYV(void *datBase, const void *dmaBase, size_t count);
+void CSI_ExtractYFromYUYV(void *datBase, const void *dmaBase, size_t count)
+{
+ /* clang-format off */
+ __asm volatile(
+ " push {r1-r7, r12, lr} \n"
+ "loop0: \n"
+ " ldmia r1!, {r3-r6} \n"
+ " bfi r7, r3, #0, #8 \n" /* Y0 */
+ " bfi r12, r5, #0, #8 \n" /* Y4 */
+ " lsr r3, r3, #16 \n"
+ " lsr r5, r5, #16 \n"
+ " bfi r7, r3, #8, #8 \n" /* Y1 */
+ " bfi r12, r5, #8, #8 \n" /* Y5 */
+ " bfi r7, r4, #16, #8 \n" /* Y2 */
+ " bfi r12, r6, #16, #8 \n" /* Y6 */
+ " lsr r4, r4, #16 \n"
+ " lsr r6, r6, #16 \n"
+ " bfi r7, r4, #24, #8 \n" /* Y3 */
+ " bfi r12, r6, #24, #8 \n" /* Y7 */
+ " stmia r0!, {r7, r12} \n"
+ " subs r2, #8 \n"
+ " bne loop0 \n"
+ " pop {r1-r7, r12, pc} \n");
+ /* clang-format on */
+}
+
+__attribute__((naked)) void CSI_ExtractYFromUYVY(void *datBase, const void *dmaBase, size_t count);
+void CSI_ExtractYFromUYVY(void *datBase, const void *dmaBase, size_t count)
+{
+ /* clang-format off */
+ __asm volatile(
+ " push {r1-r7, r12, lr} \n"
+ "loop1: \n"
+ " ldmia r1!, {r3-r6} \n"
+ " lsr r3, r3, #8 \n"
+ " lsr r5, r5, #8 \n"
+ " bfi r7, r3, #0, #8 \n" /* Y0 */
+ " bfi r12, r5, #0, #8 \n" /* Y4 */
+ " lsr r3, r3, #16 \n"
+ " lsr r5, r5, #16 \n"
+ " bfi r7, r3, #8, #8 \n" /* Y1 */
+ " bfi r12, r5, #8, #8 \n" /* Y5 */
+ " lsr r4, r4, #8 \n"
+ " lsr r6, r6, #8 \n"
+ " bfi r7, r4, #16, #8 \n" /* Y2 */
+ " bfi r12, r6, #16, #8 \n" /* Y6 */
+ " lsr r4, r4, #16 \n"
+ " lsr r6, r6, #16 \n"
+ " bfi r7, r4, #24, #8 \n" /* Y3 */
+ " bfi r12, r6, #24, #8 \n" /* Y7 */
+ " stmia r0!, {r7, r12} \n"
+ " subs r2, #8 \n"
+ " bne loop1 \n"
+ " pop {r1-r7, r12, pc} \n");
+ /* clang-format on */
+}
+#if defined(__ICCARM__)
+#pragma diag_default = Pe940
+#endif
+#else
+#error Toolchain not supported.
+#endif
+
+static void CSI_MemCopy(void *pDest, const void *pSrc, size_t cnt)
+{
+ (void)memcpy(pDest, pSrc, cnt);
+}
+
+/*!
+ * brief Initialize the CSI to work in fragment mode.
+ *
+ * This function enables the CSI peripheral clock, and resets the CSI registers.
+ *
+ * param base CSI peripheral base address.
+ */
+void CSI_FragModeInit(CSI_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ uint32_t instance = CSI_GetInstance(base);
+ CLOCK_EnableClock(s_csiClocks[instance]);
+#endif
+
+ CSI_Reset(base);
+}
+
+/*!
+ * brief De-initialize the CSI.
+ *
+ * This function disables the CSI peripheral clock.
+ *
+ * param base CSI peripheral base address.
+ */
+void CSI_FragModeDeinit(CSI_Type *base)
+{
+ CSI_Deinit(base);
+}
+
+/*!
+ * brief Create handle for CSI work in fragment mode.
+ *
+ * param base CSI peripheral base address.
+ * param handle Pointer to the transactional handle.
+ * param config Pointer to the configuration structure.
+ * param callback Callback function for CSI transfer.
+ * param userData Callback function parameter.
+ *
+ * retval kStatus_Success Initialize successfully.
+ * retval kStatus_InvalidArgument Initialize failed because of invalid argument.
+ */
+status_t CSI_FragModeCreateHandle(CSI_Type *base,
+ csi_frag_handle_t *handle,
+ const csi_frag_config_t *config,
+ csi_frag_transfer_callback_t callback,
+ void *userData)
+{
+ assert(NULL != config);
+ uint32_t reg;
+ uint32_t instance;
+ uint32_t imgWidth_Bytes;
+
+ if (config->dataBus != kCSI_DataBus8Bit)
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ imgWidth_Bytes = (uint32_t)config->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL;
+
+ /* The image buffer line width should be multiple of 8-bytes. */
+ if ((imgWidth_Bytes & 0x07U) != 0U)
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* Camera frame height must be dividable by DMA buffer line. */
+ if (config->height % config->dmaBufferLine != 0U)
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ (void)memset(handle, 0, sizeof(*handle));
+ handle->callback = callback;
+ handle->userData = userData;
+ handle->height = config->height;
+ handle->width = config->width;
+ handle->maxLinePerFrag = config->dmaBufferLine;
+ handle->dmaBytePerLine = config->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL;
+ handle->isDmaBufferCachable = config->isDmaBufferCachable;
+
+ /* Get instance from peripheral base address. */
+ instance = CSI_GetInstance(base);
+ /* Save the handle in global variables to support the double weak mechanism. */
+ s_csiHandle[instance] = handle;
+
+ s_csiIsr = CSI_FragModeTransferHandleIRQ;
+
+ EnableIRQ(s_csiIRQ[instance]);
+
+ /* Configure CSICR1. CSICR1 has been reset to the default value, so could write it directly. */
+ reg = ((uint32_t)config->workMode) | config->polarityFlags | CSI_CSICR1_FCC_MASK;
+
+ if (config->useExtVsync)
+ {
+ reg |= CSI_CSICR1_EXT_VSYNC_MASK;
+ }
+
+ base->CSICR1 = reg;
+
+ /* No stride. */
+ base->CSIFBUF_PARA = 0;
+
+ /* Enable auto ECC. */
+ base->CSICR3 |= CSI_CSICR3_ECC_AUTO_EN_MASK;
+
+ /*
+ * For better performance.
+ * The DMA burst size could be set to 16 * 8 byte, 8 * 8 byte, or 4 * 8 byte,
+ * choose the best burst size based on bytes per line.
+ */
+ if (0U == (imgWidth_Bytes % (8U * 16U)))
+ {
+ base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(3U);
+ base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((2U << CSI_CSICR3_RxFF_LEVEL_SHIFT));
+ }
+ else if (0U == (imgWidth_Bytes % (8U * 8U)))
+ {
+ base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(2U);
+ base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((1U << CSI_CSICR3_RxFF_LEVEL_SHIFT));
+ }
+ else
+ {
+ base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(1U);
+ base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((0U << CSI_CSICR3_RxFF_LEVEL_SHIFT));
+ }
+
+ base->CSIDMASA_FB1 = config->dmaBufferAddr0;
+ base->CSIDMASA_FB2 = config->dmaBufferAddr1;
+
+ if (handle->isDmaBufferCachable)
+ {
+ DCACHE_CleanInvalidateByRange(
+ config->dmaBufferAddr0,
+ (uint32_t)config->dmaBufferLine * (uint32_t)config->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL);
+ DCACHE_CleanInvalidateByRange(
+ config->dmaBufferAddr1,
+ (uint32_t)config->dmaBufferLine * (uint32_t)config->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL);
+ }
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Start to capture a image.
+ *
+ * param base CSI peripheral base address.
+ * param handle Pointer to the transactional handle.
+ * param config Pointer to the capture configuration.
+ *
+ * retval kStatus_Success Initialize successfully.
+ * retval kStatus_InvalidArgument Initialize failed because of invalid argument.
+ */
+status_t CSI_FragModeTransferCaptureImage(CSI_Type *base,
+ csi_frag_handle_t *handle,
+ const csi_frag_capture_config_t *config)
+{
+ assert(NULL != config);
+
+ uint16_t windowWidth;
+
+ /*
+ * If no special window setting, capture full frame.
+ * If capture window, then capture 1 one each fragment.
+ */
+ if (config->window != NULL)
+ {
+ handle->windowULX = config->window->windowULX;
+ handle->windowULY = config->window->windowULY;
+ handle->windowLRX = config->window->windowLRX;
+ handle->windowLRY = config->window->windowLRY;
+ handle->linePerFrag = 1;
+ }
+ else
+ {
+ handle->windowULX = 0;
+ handle->windowULY = 0;
+ handle->windowLRX = handle->width - 1U;
+ handle->windowLRY = handle->height - 1U;
+ handle->linePerFrag = handle->maxLinePerFrag;
+ }
+
+ windowWidth = handle->windowLRX - handle->windowULX + 1U;
+
+ if (config->outputGrayScale)
+ {
+ /* When output format is gray, the window width must be multiple value of 8. */
+ if (windowWidth % 8U != 0U)
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ handle->datBytePerLine = windowWidth;
+ if (handle->inputFormat == kCSI_FragInputYUYV)
+ {
+ handle->copyFunc = CSI_ExtractYFromYUYV;
+ }
+ else
+ {
+ handle->copyFunc = CSI_ExtractYFromUYVY;
+ }
+ }
+ else
+ {
+ handle->datBytePerLine = windowWidth * CSI_FRAG_INPUT_BYTES_PER_PIXEL;
+ handle->copyFunc = CSI_MemCopy;
+ }
+
+ handle->dmaCurLine = 0;
+ handle->outputBuffer = (uint32_t)config->buffer;
+ handle->datCurWriteAddr = (uint32_t)config->buffer;
+
+ /* Image parameter. */
+ base->CSIIMAG_PARA =
+ (((uint32_t)handle->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL) << CSI_CSIIMAG_PARA_IMAGE_WIDTH_SHIFT) |
+ ((uint32_t)(handle->linePerFrag) << CSI_CSIIMAG_PARA_IMAGE_HEIGHT_SHIFT);
+
+ /*
+ * Write to memory from first completed frame.
+ * DMA base addr switch at dma transfer done.
+ */
+ base->CSICR18 = (base->CSICR18 & ~CSI_CSICR18_MASK_OPTION_MASK) | CSI_CSICR18_MASK_OPTION(0);
+
+ CSI_EnableInterrupts(base, (uint32_t)kCSI_StartOfFrameInterruptEnable |
+ (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable |
+ (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable);
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Abort image capture.
+ *
+ * Abort image capture initialized by ref CSI_FragModeTransferCaptureImage.
+ *
+ * param base CSI peripheral base address.
+ * param handle Pointer to the transactional handle.
+ */
+void CSI_FragModeTransferAbortCaptureImage(CSI_Type *base, csi_frag_handle_t *handle)
+{
+ CSI_Stop(base);
+ CSI_DisableInterrupts(base, (uint32_t)kCSI_StartOfFrameInterruptEnable |
+ (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable |
+ (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable);
+}
+
+/*!
+ * brief CSI IRQ handle function.
+ *
+ * This function handles the CSI IRQ request to work with CSI driver fragment mode
+ * APIs.
+ *
+ * param base CSI peripheral base address.
+ * param handle CSI handle pointer.
+ */
+void CSI_FragModeTransferHandleIRQ(CSI_Type *base, csi_frag_handle_t *handle)
+{
+ uint32_t csisr = base->CSISR;
+ uint32_t dmaBufAddr;
+ uint16_t line;
+ pvoid_to_u32_t memSrc;
+ pvoid_to_u32_t memDest;
+
+ /* Clear the error flags. */
+ base->CSISR = csisr;
+
+ /* Start of frame, clear the FIFO and start receiving. */
+ if (0U != (csisr & (uint32_t)kCSI_StartOfFrameFlag))
+ {
+ /* Reflash the DMA and enable RX DMA request. */
+ base->CSICR3 |= (CSI_CSICR3_DMA_REFLASH_RFF_MASK | CSI_CSICR3_DMA_REQ_EN_RFF_MASK);
+ CSI_Start(base);
+ handle->dmaCurLine = 0;
+ handle->datCurWriteAddr = handle->outputBuffer;
+ }
+ else if ((csisr & (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK)) != 0U)
+ {
+ if ((csisr & CSI_CSISR_DMA_TSF_DONE_FB1_MASK) == CSI_CSISR_DMA_TSF_DONE_FB1_MASK)
+ {
+ dmaBufAddr = base->CSIDMASA_FB1;
+ }
+ else
+ {
+ dmaBufAddr = base->CSIDMASA_FB2;
+ }
+
+ if (handle->isDmaBufferCachable)
+ {
+ DCACHE_InvalidateByRange(dmaBufAddr, (uint32_t)handle->dmaBytePerLine * (uint32_t)handle->linePerFrag);
+ }
+
+ /* Copy from DMA buffer to user data buffer. */
+ dmaBufAddr += ((uint32_t)handle->windowULX * CSI_FRAG_INPUT_BYTES_PER_PIXEL);
+
+ for (line = 0; line < handle->linePerFrag; line++)
+ {
+ if (handle->dmaCurLine + line > handle->windowLRY)
+ {
+ /* out of window range */
+ break;
+ }
+ else if (handle->dmaCurLine + line >= handle->windowULY)
+ {
+ memDest.u32 = handle->datCurWriteAddr;
+ memSrc.u32 = dmaBufAddr;
+
+ handle->copyFunc(memDest.pvoid, memSrc.pvoid, handle->datBytePerLine);
+ handle->datCurWriteAddr += handle->datBytePerLine;
+ dmaBufAddr += handle->dmaBytePerLine;
+ }
+ else
+ {
+ ; /* For MISRA C-2012 Rule 15.7 */
+ }
+ }
+
+ handle->dmaCurLine += handle->linePerFrag;
+
+ if (handle->dmaCurLine >= handle->height)
+ {
+ CSI_Stop(base);
+ CSI_DisableInterrupts(base, (uint32_t)kCSI_StartOfFrameInterruptEnable |
+ (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable |
+ (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable);
+
+ /* Image captured. Stop the CSI. */
+ if (NULL != handle->callback)
+ {
+ handle->callback(base, handle, kStatus_CSI_FrameDone, handle->userData);
+ }
+ }
+ }
+ else
+ {
+ }
+}
+#endif /* CSI_DRIVER_FRAG_MODE */
+
+#if defined(CSI)
+void CSI_DriverIRQHandler(void)
+{
+ s_csiIsr(CSI, s_csiHandle[0]);
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif
+
+#if defined(CSI0)
+void CSI0_DriverIRQHandler(void)
+{
+ s_csiIsr(CSI, s_csiHandle[0]);
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcdc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcdc.c
new file mode 100644
index 0000000000..fa290939bd
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcdc.c
@@ -0,0 +1,534 @@
+/*
+ * Copyright 2017-2019, NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_dcdc.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.dcdc_1"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Get instance number for DCDC module.
+ *
+ * @param base DCDC peripheral base address
+ */
+static uint32_t DCDC_GetInstance(DCDC_Type *base);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief Pointers to DCDC bases for each instance. */
+static DCDC_Type *const s_dcdcBases[] = DCDC_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to DCDC clocks for each instance. */
+static const clock_ip_name_t s_dcdcClocks[] = DCDC_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static uint32_t DCDC_GetInstance(DCDC_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_dcdcBases); instance++)
+ {
+ if (s_dcdcBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_dcdcBases));
+
+ return instance;
+}
+
+/*!
+ * brief Enable the access to DCDC registers.
+ *
+ * param base DCDC peripheral base address.
+ */
+void DCDC_Init(DCDC_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Enable the clock. */
+ CLOCK_EnableClock(s_dcdcClocks[DCDC_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Disable the access to DCDC registers.
+ *
+ * param base DCDC peripheral base address.
+ */
+void DCDC_Deinit(DCDC_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Disable the clock. */
+ CLOCK_DisableClock(s_dcdcClocks[DCDC_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Configure the DCDC clock source.
+ *
+ * param base DCDC peripheral base address.
+ * param clockSource Clock source for DCDC. See to "dcdc_clock_source_t".
+ */
+void DCDC_SetClockSource(DCDC_Type *base, dcdc_clock_source_t clockSource)
+{
+ uint32_t tmp32;
+
+ /* Configure the DCDC_REG0 register. */
+ tmp32 = base->REG0 & ~(DCDC_REG0_XTAL_24M_OK_MASK | DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK |
+ DCDC_REG0_SEL_CLK_MASK | DCDC_REG0_PWD_OSC_INT_MASK);
+ switch (clockSource)
+ {
+ case kDCDC_ClockInternalOsc:
+ tmp32 |= DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK;
+ break;
+ case kDCDC_ClockExternalOsc:
+ /* Choose the external clock and disable the internal clock. */
+ tmp32 |= DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK | DCDC_REG0_SEL_CLK_MASK | DCDC_REG0_PWD_OSC_INT_MASK;
+ break;
+ case kDCDC_ClockAutoSwitch:
+ /* Set to switch from internal ring osc to xtal 24M if auto mode is enabled. */
+ tmp32 |= DCDC_REG0_XTAL_24M_OK_MASK;
+ break;
+ default:
+ assert(false);
+ break;
+ }
+ base->REG0 = tmp32;
+}
+
+/*!
+ * brief Get the default setting for detection configuration.
+ *
+ * The default configuration are set according to responding registers' setting when powered on.
+ * They are:
+ * code
+ * config->enableXtalokDetection = false;
+ * config->powerDownOverVoltageDetection = true;
+ * config->powerDownLowVlotageDetection = false;
+ * config->powerDownOverCurrentDetection = true;
+ * config->powerDownPeakCurrentDetection = true;
+ * config->powerDownZeroCrossDetection = true;
+ * config->OverCurrentThreshold = kDCDC_OverCurrentThresholdAlt0;
+ * config->PeakCurrentThreshold = kDCDC_PeakCurrentThresholdAlt0;
+ * endcode
+ *
+ * param config Pointer to configuration structure. See to "dcdc_detection_config_t"
+ */
+void DCDC_GetDefaultDetectionConfig(dcdc_detection_config_t *config)
+{
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->enableXtalokDetection = false;
+ config->powerDownOverVoltageDetection = true;
+ config->powerDownLowVlotageDetection = false;
+ config->powerDownOverCurrentDetection = true;
+ config->powerDownPeakCurrentDetection = true;
+ config->powerDownZeroCrossDetection = true;
+ config->OverCurrentThreshold = kDCDC_OverCurrentThresholdAlt0;
+ config->PeakCurrentThreshold = kDCDC_PeakCurrentThresholdAlt0;
+}
+
+/*!
+ * breif Configure the DCDC detection.
+ *
+ * param base DCDC peripheral base address.
+ * param config Pointer to configuration structure. See to "dcdc_detection_config_t"
+ */
+void DCDC_SetDetectionConfig(DCDC_Type *base, const dcdc_detection_config_t *config)
+{
+ assert(NULL != config);
+
+ uint32_t tmp32;
+ /* Configure the DCDC_REG0 register. */
+ tmp32 = base->REG0 &
+ ~(DCDC_REG0_XTALOK_DISABLE_MASK | DCDC_REG0_PWD_HIGH_VOLT_DET_MASK | DCDC_REG0_PWD_CMP_BATT_DET_MASK |
+ DCDC_REG0_PWD_OVERCUR_DET_MASK | DCDC_REG0_PWD_CUR_SNS_CMP_MASK | DCDC_REG0_PWD_ZCD_MASK |
+ DCDC_REG0_CUR_SNS_THRSH_MASK | DCDC_REG0_OVERCUR_TRIG_ADJ_MASK);
+
+ tmp32 |= DCDC_REG0_CUR_SNS_THRSH(config->PeakCurrentThreshold) |
+ DCDC_REG0_OVERCUR_TRIG_ADJ(config->OverCurrentThreshold);
+ if (false == config->enableXtalokDetection)
+ {
+ tmp32 |= DCDC_REG0_XTALOK_DISABLE_MASK;
+ }
+ if (config->powerDownOverVoltageDetection)
+ {
+ tmp32 |= DCDC_REG0_PWD_HIGH_VOLT_DET_MASK;
+ }
+ if (config->powerDownLowVlotageDetection)
+ {
+ tmp32 |= DCDC_REG0_PWD_CMP_BATT_DET_MASK;
+ }
+ if (config->powerDownOverCurrentDetection)
+ {
+ tmp32 |= DCDC_REG0_PWD_OVERCUR_DET_MASK;
+ }
+ if (config->powerDownPeakCurrentDetection)
+ {
+ tmp32 |= DCDC_REG0_PWD_CUR_SNS_CMP_MASK;
+ }
+ if (config->powerDownZeroCrossDetection)
+ {
+ tmp32 |= DCDC_REG0_PWD_ZCD_MASK;
+ }
+ base->REG0 = tmp32;
+}
+
+/*!
+ * brief Get the default setting for low power configuration.
+ *
+ * The default configuration are set according to responding registers' setting when powered on.
+ * They are:
+ * code
+ * config->enableOverloadDetection = true;
+ * config->enableAdjustHystereticValue = false;
+ * config->countChargingTimePeriod = kDCDC_CountChargingTimePeriod8Cycle;
+ * config->countChargingTimeThreshold = kDCDC_CountChargingTimeThreshold32;
+ * endcode
+ *
+ * param config Pointer to configuration structure. See to "dcdc_low_power_config_t"
+ */
+void DCDC_GetDefaultLowPowerConfig(dcdc_low_power_config_t *config)
+{
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->enableOverloadDetection = true;
+ config->enableAdjustHystereticValue = false;
+ config->countChargingTimePeriod = kDCDC_CountChargingTimePeriod8Cycle;
+ config->countChargingTimeThreshold = kDCDC_CountChargingTimeThreshold32;
+}
+
+/*!
+ * brief Configure the DCDC low power.
+ *
+ * param base DCDC peripheral base address.
+ * param config Pointer to configuration structure. See to "dcdc_low_power_config_t".
+ */
+void DCDC_SetLowPowerConfig(DCDC_Type *base, const dcdc_low_power_config_t *config)
+{
+ assert(NULL != config);
+
+ uint32_t tmp32;
+ /* Configure the DCDC_REG0 register. */
+ tmp32 = base->REG0 & ~(DCDC_REG0_EN_LP_OVERLOAD_SNS_MASK | DCDC_REG0_LP_HIGH_HYS_MASK |
+ DCDC_REG0_LP_OVERLOAD_FREQ_SEL_MASK | DCDC_REG0_LP_OVERLOAD_THRSH_MASK);
+ tmp32 |= DCDC_REG0_LP_OVERLOAD_FREQ_SEL(config->countChargingTimePeriod) |
+ DCDC_REG0_LP_OVERLOAD_THRSH(config->countChargingTimeThreshold);
+ if (config->enableOverloadDetection)
+ {
+ tmp32 |= DCDC_REG0_EN_LP_OVERLOAD_SNS_MASK;
+ }
+ if (config->enableAdjustHystereticValue)
+ {
+ tmp32 |= DCDC_REG0_LP_HIGH_HYS_MASK;
+ }
+ base->REG0 = tmp32;
+}
+
+/*!
+ * brief Get DCDC status flags.
+ *
+ * param base peripheral base address.
+ * return Mask of asserted status flags. See to "_dcdc_status_flags_t".
+ */
+uint32_t DCDC_GetstatusFlags(DCDC_Type *base)
+{
+ uint32_t tmp32 = 0U;
+
+ if (DCDC_REG0_STS_DC_OK_MASK == (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
+ {
+ tmp32 |= (uint32_t)kDCDC_LockedOKStatus;
+ }
+
+ return tmp32;
+}
+
+/*!
+ * brief Reset current alert signal. Alert signal is generate by peak current detection.
+ *
+ * param base DCDC peripheral base address.
+ * param enable Switcher to reset signal. True means reset signal. False means don't reset signal.
+ */
+void DCDC_ResetCurrentAlertSignal(DCDC_Type *base, bool enable)
+{
+ if (enable)
+ {
+ base->REG0 |= DCDC_REG0_CURRENT_ALERT_RESET_MASK;
+ }
+ else
+ {
+ base->REG0 &= ~DCDC_REG0_CURRENT_ALERT_RESET_MASK;
+ }
+}
+
+/*!
+ * brief Get the default setting for loop control configuration.
+ *
+ * The default configuration are set according to responding registers' setting when powered on.
+ * They are:
+ * code
+ * config->enableCommonHysteresis = false;
+ * config->enableCommonThresholdDetection = false;
+ * config->enableInvertHysteresisSign = false;
+ * config->enableRCThresholdDetection = false;
+ * config->enableRCScaleCircuit = 0U;
+ * config->complementFeedForwardStep = 0U;
+ * config->controlParameterMagnitude = 2U;
+ * config->integralProportionalRatio = 2U;
+ * endcode
+ *
+ * param config Pointer to configuration structure. See to "dcdc_loop_control_config_t"
+ */
+void DCDC_GetDefaultLoopControlConfig(dcdc_loop_control_config_t *config)
+{
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->enableCommonHysteresis = false;
+ config->enableCommonThresholdDetection = false;
+ config->enableInvertHysteresisSign = false;
+ config->enableRCThresholdDetection = false;
+ config->enableRCScaleCircuit = 0U;
+ config->complementFeedForwardStep = 0U;
+ config->controlParameterMagnitude = 2U;
+ config->integralProportionalRatio = 2U;
+}
+
+/*!
+ * brief Configure the DCDC loop control.
+ *
+ * param base DCDC peripheral base address.
+ * param config Pointer to configuration structure. See to "dcdc_loop_control_config_t".
+ */
+void DCDC_SetLoopControlConfig(DCDC_Type *base, const dcdc_loop_control_config_t *config)
+{
+ assert(NULL != config);
+
+ uint32_t tmp32;
+
+ /* Configure the DCDC_REG1 register. */
+ tmp32 = base->REG1 & ~(DCDC_REG1_LOOPCTRL_EN_HYST_MASK | DCDC_REG1_LOOPCTRL_HST_THRESH_MASK);
+ if (config->enableCommonHysteresis)
+ {
+ tmp32 |= DCDC_REG1_LOOPCTRL_EN_HYST_MASK;
+ }
+ if (config->enableCommonThresholdDetection)
+ {
+ tmp32 |= DCDC_REG1_LOOPCTRL_HST_THRESH_MASK;
+ }
+ base->REG1 = tmp32;
+
+ /* configure the DCDC_REG2 register. */
+ tmp32 = base->REG2 & ~(DCDC_REG2_LOOPCTRL_HYST_SIGN_MASK | DCDC_REG2_LOOPCTRL_RCSCALE_THRSH_MASK |
+ DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK | DCDC_REG2_LOOPCTRL_DC_FF_MASK |
+ DCDC_REG2_LOOPCTRL_DC_R_MASK | DCDC_REG2_LOOPCTRL_DC_C_MASK);
+ tmp32 |= DCDC_REG2_LOOPCTRL_DC_FF(config->complementFeedForwardStep) |
+ DCDC_REG2_LOOPCTRL_DC_R(config->controlParameterMagnitude) |
+ DCDC_REG2_LOOPCTRL_DC_C(config->integralProportionalRatio) |
+ DCDC_REG2_LOOPCTRL_EN_RCSCALE(config->enableRCScaleCircuit);
+ if (config->enableInvertHysteresisSign)
+ {
+ tmp32 |= DCDC_REG2_LOOPCTRL_HYST_SIGN_MASK;
+ }
+ if (config->enableRCThresholdDetection)
+ {
+ tmp32 |= DCDC_REG2_LOOPCTRL_RCSCALE_THRSH_MASK;
+ }
+ base->REG2 = tmp32;
+}
+
+/*!
+ * brief Configure for the min power.
+ *
+ * param base DCDC peripheral base address.
+ * param config Pointer to configuration structure. See to "dcdc_min_power_config_t".
+ */
+void DCDC_SetMinPowerConfig(DCDC_Type *base, const dcdc_min_power_config_t *config)
+{
+ assert(NULL != config);
+
+ uint32_t tmp32;
+
+ tmp32 = base->REG3 & ~DCDC_REG3_MINPWR_DC_HALFCLK_MASK;
+ if (config->enableUseHalfFreqForContinuous)
+ {
+ tmp32 |= DCDC_REG3_MINPWR_DC_HALFCLK_MASK;
+ }
+ base->REG3 = tmp32;
+}
+
+/*!
+ * brief Adjust the target voltage of VDD_SOC in run mode and low power mode.
+ * @deprecated Do not use this function. It has been superceded by @ref DCDC_AdjustRunTargetVoltage
+ * and @ref DCDC_AdjustLowPowerTargetVoltage
+ *
+ * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
+ * stabled.
+ * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
+ * back to run mode if it detects the current loading is larger than about 50 mA(typical value).
+ *
+ * param base DCDC peripheral base address.
+ * param VDDRun Target value in run mode. 25 mV each step from 0x00 to 0x1F. 00 is for 0.8V, 0x1F is for 1.575V.
+ * param VDDStandby Target value in low power mode. 25 mV each step from 0x00 to 0x4. 00 is for 0.9V, 0x4 is for 1.0V.
+ */
+void DCDC_AdjustTargetVoltage(DCDC_Type *base, uint32_t VDDRun, uint32_t VDDStandby)
+{
+ uint32_t tmp32;
+
+ /* Unlock the step for the output. */
+ base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK;
+
+ /* Configure the DCDC_REG3 register. */
+ tmp32 = base->REG3 & ~(DCDC_REG3_TARGET_LP_MASK | DCDC_REG3_TRG_MASK);
+
+ tmp32 |= DCDC_REG3_TARGET_LP(VDDStandby) | DCDC_REG3_TRG(VDDRun);
+ base->REG3 = tmp32;
+
+ /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage settling to new
+ * target value, DCDC_STS_DC_OK will be asserted. */
+ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
+ {
+ }
+}
+
+/*!
+ * brief Adjust the target voltage of VDD_SOC in run mode.
+ *
+ * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
+ * stabled.
+ * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
+ * back to run mode if it detects the current loading is larger than about 50 mA(typical value).
+ *
+ * param base DCDC peripheral base address.
+ * param VDDRun Target value in run mode. 25 mV each step from 0x00 to 0x1F. 00 is for 0.8V, 0x1F is for 1.575V.
+ */
+void DCDC_AdjustRunTargetVoltage(DCDC_Type *base, uint32_t VDDRun)
+{
+ uint32_t tmp32;
+
+ /* Unlock the step for the output. */
+ base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK;
+
+ /* Configure the DCDC_REG3 register. */
+ tmp32 = base->REG3 & ~DCDC_REG3_TRG_MASK;
+
+ tmp32 |= DCDC_REG3_TRG(VDDRun);
+ base->REG3 = tmp32;
+
+ /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage settling to new
+ * target value, DCDC_STS_DC_OK will be asserted. */
+ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
+ {
+ }
+}
+
+/*!
+ * brief Adjust the target voltage of VDD_SOC in low power mode.
+ *
+ * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is
+ * stabled.
+ * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch
+ * back to run mode if it detects the current loading is larger than about 50 mA(typical value).
+ *
+ * param base DCDC peripheral base address.
+ * param VDDStandby Target value in low power mode. 25 mV each step from 0x00 to 0x4. 00 is for 0.9V, 0x4 is for 1.0V.
+ */
+void DCDC_AdjustLowPowerTargetVoltage(DCDC_Type *base, uint32_t VDDStandby)
+{
+ uint32_t tmp32;
+
+ /* Unlock the step for the output. */
+ base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK;
+
+ /* Configure the DCDC_REG3 register. */
+ tmp32 = base->REG3 & ~DCDC_REG3_TARGET_LP_MASK;
+
+ tmp32 |= DCDC_REG3_TARGET_LP(VDDStandby);
+ base->REG3 = tmp32;
+
+ /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage settling to new
+ * target value, DCDC_STS_DC_OK will be asserted. */
+ while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0))
+ {
+ }
+}
+
+/*!
+ * brief Configure the DCDC internal regulator.
+ *
+ * param base DCDC peripheral base address.
+ * param config Pointer to configuration structure. See to "dcdc_internal_regulator_config_t".
+ */
+void DCDC_SetInternalRegulatorConfig(DCDC_Type *base, const dcdc_internal_regulator_config_t *config)
+{
+ assert(NULL != config);
+
+ uint32_t tmp32;
+
+ /* Configure the DCDC_REG1 register. */
+ tmp32 = base->REG1 & ~(DCDC_REG1_REG_FBK_SEL_MASK | DCDC_REG1_REG_RLOAD_SW_MASK);
+ tmp32 |= DCDC_REG1_REG_FBK_SEL(config->feedbackPoint);
+ if (config->enableLoadResistor)
+ {
+ tmp32 |= DCDC_REG1_REG_RLOAD_SW_MASK;
+ }
+ base->REG1 = tmp32;
+}
+
+/*!
+ * brief Boot DCDC into DCM(discontinous conduction mode).
+ *
+ * pwd_zcd=0x0;
+ * pwd_cmp_offset=0x0;
+ * dcdc_loopctrl_en_rcscale=0x3 or 0x5;
+ * DCM_set_ctrl=1'b1;
+ *
+ * param base DCDC peripheral base address.
+ */
+void DCDC_BootIntoDCM(DCDC_Type *base)
+{
+ base->REG0 &= ~(DCDC_REG0_PWD_ZCD_MASK | DCDC_REG0_PWD_CMP_OFFSET_MASK);
+ base->REG2 = (~DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK & base->REG2) | DCDC_REG2_LOOPCTRL_EN_RCSCALE(0x4U) |
+ DCDC_REG2_DCM_SET_CTRL_MASK;
+}
+
+/*!
+ * brief Boot DCDC into CCM(continous conduction mode).
+ *
+ * pwd_zcd=0x1;
+ * pwd_cmp_offset=0x0;
+ * dcdc_loopctrl_en_rcscale=0x3;
+ *
+ * param base DCDC peripheral base address.
+ */
+void DCDC_BootIntoCCM(DCDC_Type *base)
+{
+ base->REG0 = (~DCDC_REG0_PWD_CMP_OFFSET_MASK & base->REG0) | DCDC_REG0_PWD_ZCD_MASK;
+ base->REG2 = (~DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK & base->REG2) | DCDC_REG2_LOOPCTRL_EN_RCSCALE(0x3U);
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcp.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcp.c
new file mode 100644
index 0000000000..4477406a73
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcp.c
@@ -0,0 +1,1461 @@
+/*
+ * Copyright 2017-2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_dcp.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.dcp"
+#endif
+
+#ifndef DCP_USE_DCACHE
+#define DCP_USE_DCACHE 0
+#endif
+/* 1 - driver supports DCACHE, 0 - drivers does not support DCACHE */
+/* When enable (DCP_USE_DCACHE = 1) Input/output buffers and hash ctx should be in */
+/* non-cached memory or handled properly (Clean & Invalidate DCACHE) */
+
+/*! Compile time sizeof() check */
+#define BUILD_ASSURE(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
+
+#define dcp_memcpy memcpy
+
+/*! Internal states of the HASH creation process */
+typedef enum _dcp_hash_algo_state
+{
+ kDCP_StateHashInit = 1u, /*!< Init state. */
+ kDCP_StateHashUpdate, /*!< Update state. */
+} dcp_hash_algo_state_t;
+
+/*! multiple of 64-byte block represented as byte array of 32-bit words */
+typedef union _dcp_hash_block
+{
+ uint32_t w[DCP_HASH_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
+ uint8_t b[DCP_HASH_BLOCK_SIZE]; /*!< byte array */
+} dcp_hash_block_t;
+
+/*! internal dcp_hash context structure */
+typedef struct _dcp_hash_ctx_internal
+{
+ dcp_hash_block_t blk; /*!< memory buffer. only full blocks are written to DCP during hash updates */
+ size_t blksz; /*!< number of valid bytes in memory buffer */
+ dcp_hash_algo_t algo; /*!< selected algorithm from the set of supported algorithms */
+ dcp_hash_algo_state_t state; /*!< finite machine state of the hash software process */
+ uint32_t fullMessageSize; /*!< track message size */
+ uint32_t ctrl0; /*!< HASH_INIT and HASH_TERM flags */
+ uint32_t runningHash[9]; /*!< running hash. up to SHA-256 plus size, that is 36 bytes. */
+ dcp_handle_t *handle;
+} dcp_hash_ctx_internal_t;
+
+/*!< SHA-1/SHA-2 digest length in bytes */
+enum _dcp_hash_digest_len
+{
+ kDCP_OutLenSha1 = 20u,
+ kDCP_OutLenSha256 = 32u,
+ kDCP_OutLenCrc32 = 4u,
+};
+
+enum _dcp_work_packet_bit_definitions
+{
+ kDCP_CONTROL0_DECR_SEMAPHOR = 1u << 1, /* DECR_SEMAPHOR */
+ kDCP_CONTROL0_ENABLE_HASH = 1u << 6, /* ENABLE_HASH */
+ kDCP_CONTROL0_HASH_INIT = 1u << 12, /* HASH_INIT */
+ kDCP_CONTROL0_HASH_TERM = 1u << 13, /* HASH_TERM */
+ kDCP_CONTROL1_HASH_SELECT_SHA256 = 2u << 16,
+ kDCP_CONTROL1_HASH_SELECT_SHA1 = 0u << 16,
+ kDCP_CONTROL1_HASH_SELECT_CRC32 = 1u << 16,
+};
+
+/*! 64-byte block represented as byte array of 16 32-bit words */
+typedef union _dcp_sha_block
+{
+ uint32_t w[64 / 4]; /*!< array of 32-bit words */
+ uint8_t b[64]; /*!< byte array */
+} dcp_sha_block_t;
+
+#if defined(DCP_HASH_CAVP_COMPATIBLE)
+/* result of sha1 hash for message with zero size */
+static uint8_t s_nullSha1[] = {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
+ 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09};
+/* result of sha256 hash for message with zero size */
+static uint8_t s_nullSha256[] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4,
+ 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b,
+ 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};
+#endif /* DCP_HASH_CAVP_COMPATIBLE */
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+AT_NONCACHEABLE_SECTION_INIT(static dcp_context_t s_dcpContextSwitchingBuffer);
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static void dcp_reverse_and_copy(uint8_t *src, uint8_t *dest, size_t src_len)
+{
+ for (uint32_t i = 0; i < src_len; i++)
+ {
+ dest[i] = src[src_len - 1U - i];
+ }
+}
+
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+static uint32_t *DCP_FindCacheLine(uint8_t *dcpWorkExt)
+{
+ while ((uint32_t)dcpWorkExt & (FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1))
+ dcpWorkExt++;
+ return (uint32_t *)dcpWorkExt;
+}
+#endif
+
+static status_t dcp_get_channel_status(DCP_Type *base, dcp_channel_t channel)
+{
+ uint32_t statReg = 0;
+ uint32_t semaReg = 0;
+ status_t status = kStatus_Fail;
+
+ switch (channel)
+ {
+ case kDCP_Channel0:
+ statReg = base->CH0STAT;
+ semaReg = base->CH0SEMA;
+ break;
+
+ case kDCP_Channel1:
+ statReg = base->CH1STAT;
+ semaReg = base->CH1SEMA;
+ break;
+
+ case kDCP_Channel2:
+ statReg = base->CH2STAT;
+ semaReg = base->CH2SEMA;
+ break;
+
+ case kDCP_Channel3:
+ statReg = base->CH3STAT;
+ semaReg = base->CH3SEMA;
+ break;
+
+ default:
+ /* All the cases have been listed above, the default clause should not be reached. */
+ break;
+ }
+
+ if (!((0U != (semaReg & DCP_CH0SEMA_VALUE_MASK)) || (0U != (statReg & DCP_CH0STAT_ERROR_CODE_MASK))))
+ {
+ status = kStatus_Success;
+ }
+
+ return status;
+}
+
+static void dcp_clear_status(DCP_Type *base)
+{
+ volatile uint32_t *dcpStatClrPtr = (volatile uint32_t *)&base->STAT + 2u;
+ *dcpStatClrPtr = 0xFFu;
+
+ while ((base->STAT & 0xffu) != 0U)
+ {
+ }
+}
+
+static void dcp_clear_channel_status(DCP_Type *base, uint32_t mask)
+{
+ volatile uint32_t *chStatClrPtr;
+
+ if (0U != (mask & (uint32_t)kDCP_Channel0))
+ {
+ chStatClrPtr = &base->CH0STAT_CLR;
+ *chStatClrPtr = 0xFFu;
+ }
+ if (0U != (mask & (uint32_t)kDCP_Channel1))
+ {
+ chStatClrPtr = &base->CH1STAT_CLR;
+ *chStatClrPtr = 0xFFu;
+ }
+ if (0U != (mask & (uint32_t)kDCP_Channel2))
+ {
+ chStatClrPtr = &base->CH2STAT_CLR;
+ *chStatClrPtr = 0xFFu;
+ }
+ if (0U != (mask & (uint32_t)kDCP_Channel3))
+ {
+ chStatClrPtr = &base->CH3STAT_CLR;
+ *chStatClrPtr = 0xFFu;
+ }
+}
+
+static status_t dcp_aes_set_sram_based_key(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key)
+{
+ base->KEY = DCP_KEY_INDEX(handle->keySlot) | DCP_KEY_SUBWORD(0);
+ /* move the key by 32-bit words */
+ int i = 0;
+ size_t keySize = 16u;
+ while (keySize != 0U)
+ {
+ keySize -= sizeof(uint32_t);
+ base->KEYDATA = ((uint32_t *)(uintptr_t)key)[i];
+ i++;
+ }
+ return kStatus_Success;
+}
+
+/* Disable optimizations for GCC to prevent instruction reordering */
+#if defined(__GNUC__)
+#pragma GCC push_options
+#pragma GCC optimize("O0")
+#endif
+static status_t dcp_schedule_work(DCP_Type *base, dcp_handle_t *handle, dcp_work_packet_t *dcpPacket)
+{
+ status_t status;
+
+ /* check if our channel is active */
+ if ((base->STAT & (uint32_t)handle->channel) != (uint32_t)handle->channel)
+ {
+ /* disable global interrupt */
+ uint32_t currPriMask = DisableGlobalIRQ();
+
+ /* re-check if our channel is still available */
+ if ((base->STAT & (uint32_t)handle->channel) == 0U)
+ {
+ volatile uint32_t *cmdptr = NULL;
+ volatile uint32_t *chsema = NULL;
+
+ switch (handle->channel)
+ {
+ case kDCP_Channel0:
+ cmdptr = &base->CH0CMDPTR;
+ chsema = &base->CH0SEMA;
+ break;
+
+ case kDCP_Channel1:
+ cmdptr = &base->CH1CMDPTR;
+ chsema = &base->CH1SEMA;
+ break;
+
+ case kDCP_Channel2:
+ cmdptr = &base->CH2CMDPTR;
+ chsema = &base->CH2SEMA;
+ break;
+
+ case kDCP_Channel3:
+ cmdptr = &base->CH3CMDPTR;
+ chsema = &base->CH3SEMA;
+ break;
+
+ default:
+ /* All the cases have been listed above, the default clause should not be reached. */
+ break;
+ }
+
+ if ((NULL != cmdptr) && (NULL != chsema))
+ {
+ /* set out packet to DCP CMDPTR */
+ *cmdptr = (uint32_t)dcpPacket;
+
+#if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ /* Clean DCACHE before sending DCP packet to engine */
+ SCB_CleanDCache_by_Addr((uint32_t *)dcpPacket, sizeof(dcp_work_packet_t));
+#endif
+ /* Make sure that all data memory accesses are completed before starting of the job */
+ __DSB();
+ __ISB();
+
+ /* set the channel semaphore to start the job */
+ *chsema = 1u;
+ }
+
+ status = kStatus_Success;
+ }
+
+ else
+ {
+ status = (int32_t)kStatus_DCP_Again;
+ }
+ /* global interrupt enable */
+ EnableGlobalIRQ(currPriMask);
+ }
+
+ else
+ {
+ return (int32_t)kStatus_DCP_Again;
+ }
+
+ return status;
+}
+#if defined(__GNUC__)
+#pragma GCC pop_options
+#endif
+
+/*!
+ * brief Set AES key to dcp_handle_t struct and optionally to DCP.
+ *
+ * Sets the AES key for encryption/decryption with the dcp_handle_t structure.
+ * The dcp_handle_t input argument specifies keySlot.
+ * If the keySlot is kDCP_OtpKey, the function will check the OTP_KEY_READY bit and will return it's ready to use
+ * status.
+ * For other keySlot selections, the function will copy and hold the key in dcp_handle_t struct.
+ * If the keySlot is one of the four DCP SRAM-based keys (one of kDCP_KeySlot0, kDCP_KeySlot1, kDCP_KeySlot2,
+ * kDCP_KeySlot3),
+ * this function will also load the supplied key to the specified keySlot in DCP.
+ *
+ * param base DCP peripheral base address.
+ * param handle Handle used for the request.
+ * param key 0-mod-4 aligned pointer to AES key.
+ * param keySize AES key size in bytes. Shall equal 16.
+ * return status from set key operation
+ */
+status_t DCP_AES_SetKey(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key, size_t keySize)
+{
+ status_t status = kStatus_Fail;
+
+ if ((kDCP_OtpKey == handle->keySlot) || (kDCP_OtpUniqueKey == handle->keySlot))
+ {
+ /* for AES OTP and unique key, check and return read from fuses status */
+ if ((base->STAT & DCP_STAT_OTP_KEY_READY_MASK) == DCP_STAT_OTP_KEY_READY_MASK)
+ {
+ status = kStatus_Success;
+ }
+ }
+ else
+ {
+ /* only work with aligned key[] */
+ if ((0x3U & (uintptr_t)key) != 0U)
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* keySize must be 16. */
+ if (keySize != 16U)
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ /* move the key by 32-bit words */
+ int i = 0;
+ while (keySize != 0U)
+ {
+ keySize -= sizeof(uint32_t);
+ handle->keyWord[i] = ((uint32_t *)(uintptr_t)key)[i];
+ i++;
+ }
+
+ if (kDCP_PayloadKey != handle->keySlot)
+ {
+ /* move the key by 32-bit words to DCP SRAM-based key storage */
+ status = dcp_aes_set_sram_based_key(base, handle, key);
+ }
+ else
+ {
+ /* for PAYLOAD_KEY, just return Ok status now */
+ status = kStatus_Success;
+ }
+ }
+
+ return status;
+}
+
+/*!
+ * brief Encrypts AES on one or multiple 128-bit block(s).
+ *
+ * Encrypts AES.
+ * The source plaintext and destination ciphertext can overlap in system memory.
+ *
+ * param base DCP peripheral base address
+ * param handle Handle used for this request.
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * return Status from encrypt operation
+ */
+status_t DCP_AES_EncryptEcb(
+ DCP_Type *base, dcp_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size)
+{
+ status_t completionStatus = kStatus_Fail;
+
+ /* Use extended DCACHE line size aligned structure */
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ dcp_work_packet_t *dcpWork;
+ uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
+ dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt);
+#else
+ dcp_work_packet_t dcpWorkPacket = {0};
+ dcp_work_packet_t *dcpWork = &dcpWorkPacket;
+#endif
+
+ do
+ {
+ completionStatus = DCP_AES_EncryptEcbNonBlocking(base, handle, dcpWork, plaintext, ciphertext, size);
+ } while (completionStatus == (int32_t)kStatus_DCP_Again);
+
+ if (completionStatus != kStatus_Success)
+ {
+ return completionStatus;
+ }
+
+ return DCP_WaitForChannelComplete(base, handle);
+}
+
+/*!
+ * brief Encrypts AES using the ECB block mode.
+ *
+ * Puts AES ECB encrypt work packet to DCP channel.
+ *
+ * param base DCP peripheral base address
+ * param handle Handle used for this request.
+ * param[out] dcpPacket Memory for the DCP work packet.
+ * param plaintext Input plain text to encrypt.
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * return kStatus_Success The work packet has been scheduled at DCP channel.
+ * return kStatus_DCP_Again The DCP channel is busy processing previous request.
+ */
+status_t DCP_AES_EncryptEcbNonBlocking(DCP_Type *base,
+ dcp_handle_t *handle,
+ dcp_work_packet_t *dcpPacket,
+ const uint8_t *plaintext,
+ uint8_t *ciphertext,
+ size_t size)
+{
+ /* Size must be 16-byte multiple */
+ if ((size < 16u) || (0U != (size % 16u)))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ dcpPacket->control0 =
+ 0x122u | (handle->swapConfig & 0xFC0000u); /* CIPHER_ENCRYPT | ENABLE_CIPHER | DECR_SEMAPHORE */
+ dcpPacket->sourceBufferAddress = (uint32_t)plaintext;
+ dcpPacket->destinationBufferAddress = (uint32_t)ciphertext;
+ dcpPacket->bufferSize = (uint32_t)size;
+
+ if (handle->keySlot == kDCP_OtpKey)
+ {
+ dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */
+ dcpPacket->control1 = ((uint32_t)0xFFu << 8); /* KEY_SELECT = OTP_KEY */
+ }
+ else if (handle->keySlot == kDCP_OtpUniqueKey)
+ {
+ dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */
+ dcpPacket->control1 = ((uint32_t)0xFEu << 8); /* KEY_SELECT = UNIQUE_KEY */
+ }
+ else if (handle->keySlot == kDCP_PayloadKey)
+ {
+ /* ECB does not have IV, so we can point payload directly to keyWord[] stored in handle. */
+ dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0];
+ dcpPacket->control0 |= ((uint32_t)1u << 11); /* PAYLOAD_KEY */
+ }
+ else
+ {
+ dcpPacket->control1 = ((uint32_t)handle->keySlot << 8); /* KEY_SELECT = keySlot */
+ }
+
+ return dcp_schedule_work(base, handle, dcpPacket);
+}
+
+/*!
+ * brief Decrypts AES on one or multiple 128-bit block(s).
+ *
+ * Decrypts AES.
+ * The source ciphertext and destination plaintext can overlap in system memory.
+ *
+ * param base DCP peripheral base address
+ * param handle Handle used for this request.
+ * param ciphertext Input plain text to encrypt
+ * param[out] plaintext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * return Status from decrypt operation
+ */
+status_t DCP_AES_DecryptEcb(
+ DCP_Type *base, dcp_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size)
+{
+ status_t completionStatus = kStatus_Fail;
+
+ /* Use extended DCACHE line size aligned structure */
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ dcp_work_packet_t *dcpWork;
+ uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
+ dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt);
+#else
+ dcp_work_packet_t dcpWorkPacket = {0};
+ dcp_work_packet_t *dcpWork = &dcpWorkPacket;
+#endif
+
+ do
+ {
+ completionStatus = DCP_AES_DecryptEcbNonBlocking(base, handle, dcpWork, ciphertext, plaintext, size);
+ } while (completionStatus == (int32_t)(kStatus_DCP_Again));
+
+ if (completionStatus != kStatus_Success)
+ {
+ return completionStatus;
+ }
+
+ return DCP_WaitForChannelComplete(base, handle);
+}
+
+/*!
+ * brief Decrypts AES using ECB block mode.
+ *
+ * Puts AES ECB decrypt dcpPacket to DCP input job ring.
+ *
+ * param base DCP peripheral base address
+ * param handle Handle used for this request.
+ * param[out] dcpPacket Memory for the DCP work packet.
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * return kStatus_Success The work packet has been scheduled at DCP channel.
+ * return kStatus_DCP_Again The DCP channel is busy processing previous request.
+ */
+status_t DCP_AES_DecryptEcbNonBlocking(DCP_Type *base,
+ dcp_handle_t *handle,
+ dcp_work_packet_t *dcpPacket,
+ const uint8_t *ciphertext,
+ uint8_t *plaintext,
+ size_t size)
+{
+ /* Size must be 16-byte multiple */
+ if ((size < 16u) || (0U != (size % 16u)))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ dcpPacket->control0 = 0x22u | (handle->swapConfig & 0xFC0000u); /* ENABLE_CIPHER | DECR_SEMAPHORE */
+ dcpPacket->sourceBufferAddress = (uint32_t)ciphertext;
+ dcpPacket->destinationBufferAddress = (uint32_t)plaintext;
+ dcpPacket->bufferSize = (uint32_t)size;
+
+ if (handle->keySlot == kDCP_OtpKey)
+ {
+ dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */
+ dcpPacket->control1 = ((uint32_t)0xFFu << 8); /* KEY_SELECT = OTP_KEY */
+ }
+ else if (handle->keySlot == kDCP_OtpUniqueKey)
+ {
+ dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */
+ dcpPacket->control1 = ((uint32_t)0xFEu << 8); /* KEY_SELECT = UNIQUE_KEY */
+ }
+ else if (handle->keySlot == kDCP_PayloadKey)
+ {
+ /* ECB does not have IV, so we can point payload directly to keyWord[] stored in handle. */
+ dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0];
+ dcpPacket->control0 |= ((uint32_t)1u << 11); /* PAYLOAD_KEY */
+ }
+ else
+ {
+ dcpPacket->control1 = ((uint32_t)handle->keySlot << 8); /* KEY_SELECT = keySlot */
+ }
+
+ return dcp_schedule_work(base, handle, dcpPacket);
+}
+
+/*!
+ * brief Encrypts AES using CBC block mode.
+ *
+ * Encrypts AES using CBC block mode.
+ * The source plaintext and destination ciphertext can overlap in system memory.
+ *
+ * param base DCP peripheral base address
+ * param handle Handle used for this request.
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input initial vector to combine with the first input block.
+ * return Status from encrypt operation
+ */
+status_t DCP_AES_EncryptCbc(DCP_Type *base,
+ dcp_handle_t *handle,
+ const uint8_t *plaintext,
+ uint8_t *ciphertext,
+ size_t size,
+ const uint8_t iv[16])
+{
+ status_t completionStatus = kStatus_Fail;
+
+ /* Use extended DCACHE line size aligned structure */
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ dcp_work_packet_t *dcpWork;
+ uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
+ dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt);
+#else
+ dcp_work_packet_t dcpWorkPacket = {0};
+ dcp_work_packet_t *dcpWork = &dcpWorkPacket;
+#endif
+
+ do
+ {
+ completionStatus = DCP_AES_EncryptCbcNonBlocking(base, handle, dcpWork, plaintext, ciphertext, size, iv);
+ } while (completionStatus == (int32_t)kStatus_DCP_Again);
+
+ if (completionStatus != kStatus_Success)
+ {
+ return completionStatus;
+ }
+
+ return DCP_WaitForChannelComplete(base, handle);
+}
+
+/*!
+ * brief Encrypts AES using CBC block mode.
+ *
+ * Puts AES CBC encrypt dcpPacket to DCP input job ring.
+ *
+ * param base DCP peripheral base address
+ * param handle Handle used for this request. Specifies jobRing.
+ * param[out] dcpPacket Memory for the DCP work packet.
+ * param plaintext Input plain text to encrypt
+ * param[out] ciphertext Output cipher text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input initial vector to combine with the first input block.
+ * return kStatus_Success The work packet has been scheduled at DCP channel.
+ * return kStatus_DCP_Again The DCP channel is busy processing previous request.
+ */
+status_t DCP_AES_EncryptCbcNonBlocking(DCP_Type *base,
+ dcp_handle_t *handle,
+ dcp_work_packet_t *dcpPacket,
+ const uint8_t *plaintext,
+ uint8_t *ciphertext,
+ size_t size,
+ const uint8_t *iv)
+{
+ /* Size must be 16-byte multiple */
+ if ((size < 16u) || (0U != (size % 16u)))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ dcpPacket->control0 =
+ 0x322u | (handle->swapConfig & 0xFC0000u); /* CIPHER_INIT | CIPHER_ENCRYPT | ENABLE_CIPHER | DECR_SEMAPHORE */
+ dcpPacket->control1 = 0x10u; /* CBC */
+ dcpPacket->sourceBufferAddress = (uint32_t)plaintext;
+ dcpPacket->destinationBufferAddress = (uint32_t)ciphertext;
+ dcpPacket->bufferSize = (uint32_t)size;
+
+ if (handle->keySlot == kDCP_OtpKey)
+ {
+ dcpPacket->payloadPointer = (uint32_t)iv;
+ dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */
+ dcpPacket->control1 |= ((uint32_t)0xFFu << 8); /* KEY_SELECT = OTP_KEY */
+ }
+ else if (handle->keySlot == kDCP_OtpUniqueKey)
+ {
+ dcpPacket->payloadPointer = (uint32_t)iv;
+ dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */
+ dcpPacket->control1 |= ((uint32_t)0xFEu << 8); /* KEY_SELECT = UNIQUE_KEY */
+ }
+ else if (handle->keySlot == kDCP_PayloadKey)
+ {
+ /* In this case payload must contain key & iv in one array. */
+ /* Copy iv into handle right behind the keyWord[] so we can point payload to keyWord[]. */
+ (void)dcp_memcpy(handle->iv, (const uint32_t *)(uintptr_t)iv, 16);
+ dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0];
+ dcpPacket->control0 |= ((uint32_t)1u << 11); /* PAYLOAD_KEY */
+ }
+ else
+ {
+ dcpPacket->payloadPointer = (uint32_t)iv;
+ dcpPacket->control1 |= ((uint32_t)handle->keySlot << 8); /* KEY_SELECT = keySlot */
+ }
+
+ return dcp_schedule_work(base, handle, dcpPacket);
+}
+
+/*!
+ * brief Decrypts AES using CBC block mode.
+ *
+ * Decrypts AES using CBC block mode.
+ * The source ciphertext and destination plaintext can overlap in system memory.
+ *
+ * param base DCP peripheral base address
+ * param handle Handle used for this request.
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input initial vector to combine with the first input block.
+ * return Status from decrypt operation
+ */
+status_t DCP_AES_DecryptCbc(DCP_Type *base,
+ dcp_handle_t *handle,
+ const uint8_t *ciphertext,
+ uint8_t *plaintext,
+ size_t size,
+ const uint8_t iv[16])
+{
+ status_t completionStatus = kStatus_Fail;
+
+ /* Use extended DCACHE line size aligned structure */
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ dcp_work_packet_t *dcpWork;
+ uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
+ dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt);
+#else
+ dcp_work_packet_t dcpWorkPacket = {0};
+ dcp_work_packet_t *dcpWork = &dcpWorkPacket;
+#endif
+
+ do
+ {
+ completionStatus = DCP_AES_DecryptCbcNonBlocking(base, handle, dcpWork, ciphertext, plaintext, size, iv);
+ } while (completionStatus == (int32_t)kStatus_DCP_Again);
+
+ if (completionStatus != (int32_t)kStatus_Success)
+ {
+ return completionStatus;
+ }
+
+ return DCP_WaitForChannelComplete(base, handle);
+}
+
+/*!
+ * brief Decrypts AES using CBC block mode.
+ *
+ * Puts AES CBC decrypt dcpPacket to DCP input job ring.
+ *
+ * param base DCP peripheral base address
+ * param handle Handle used for this request. Specifies jobRing.
+ * param[out] dcpPacket Memory for the DCP work packet.
+ * param ciphertext Input cipher text to decrypt
+ * param[out] plaintext Output plain text
+ * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
+ * param iv Input initial vector to combine with the first input block.
+ * return kStatus_Success The work packet has been scheduled at DCP channel.
+ * return kStatus_DCP_Again The DCP channel is busy processing previous request.
+ */
+status_t DCP_AES_DecryptCbcNonBlocking(DCP_Type *base,
+ dcp_handle_t *handle,
+ dcp_work_packet_t *dcpPacket,
+ const uint8_t *ciphertext,
+ uint8_t *plaintext,
+ size_t size,
+ const uint8_t *iv)
+{
+ /* Size must be 16-byte multiple */
+ if ((size < 16u) || (0U != (size % 16u)))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ dcpPacket->control0 = 0x222u | (handle->swapConfig & 0xFC0000u); /* CIPHER_INIT | ENABLE_CIPHER | DECR_SEMAPHORE */
+ dcpPacket->control1 = 0x10u; /* CBC */
+ dcpPacket->sourceBufferAddress = (uint32_t)ciphertext;
+ dcpPacket->destinationBufferAddress = (uint32_t)plaintext;
+ dcpPacket->bufferSize = (uint32_t)size;
+
+ if (handle->keySlot == kDCP_OtpKey)
+ {
+ dcpPacket->payloadPointer = (uint32_t)iv;
+ dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */
+ dcpPacket->control1 |= ((uint32_t)0xFFu << 8); /* OTP_KEY */
+ }
+ else if (handle->keySlot == kDCP_OtpUniqueKey)
+ {
+ dcpPacket->payloadPointer = (uint32_t)iv;
+ dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */
+ dcpPacket->control1 |= ((uint32_t)0xFEu << 8); /* UNIQUE_KEY */
+ }
+ else if (handle->keySlot == kDCP_PayloadKey)
+ {
+ /* in this case payload must contain KEY + IV together */
+ /* copy iv into handle struct so we can point payload directly to keyWord[]. */
+ (void)dcp_memcpy(handle->iv, (const uint32_t *)(uintptr_t)iv, 16);
+ dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0];
+ dcpPacket->control0 |= ((uint32_t)1u << 11); /* PAYLOAD_KEY */
+ }
+ else
+ {
+ dcpPacket->payloadPointer = (uint32_t)iv;
+ dcpPacket->control1 |= ((uint32_t)handle->keySlot << 8); /* KEY_SELECT */
+ }
+
+ return dcp_schedule_work(base, handle, dcpPacket);
+}
+
+/*!
+ * brief Gets the default configuration structure.
+ *
+ * This function initializes the DCP configuration structure to a default value. The default
+ * values are as follows.
+ * dcpConfig->gatherResidualWrites = true;
+ * dcpConfig->enableContextCaching = true;
+ * dcpConfig->enableContextSwitching = true;
+ * dcpConfig->enableChannnel = kDCP_chEnableAll;
+ * dcpConfig->enableChannelInterrupt = kDCP_chIntDisable;
+ *
+ * param[out] config Pointer to configuration structure.
+ */
+void DCP_GetDefaultConfig(dcp_config_t *config)
+{
+ /* ENABLE_CONTEXT_CACHING is disabled by default as the DCP Hash driver uses
+ * dcp_hash_save_running_hash() and dcp_hash_restore_running_hash() to support
+ * Hash context switch (different messages interleaved) on the same channel.
+ */
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ dcp_config_t userConfig = {
+ true, false, true, (uint8_t)kDCP_chEnableAll, (uint8_t)kDCP_chIntDisable,
+ };
+
+ *config = userConfig;
+}
+
+/*!
+ * brief Enables clock to and enables DCP
+ *
+ * Enable DCP clock and configure DCP.
+ *
+ * param base DCP base address
+ * param config Pointer to configuration structure.
+ */
+void DCP_Init(DCP_Type *base, const dcp_config_t *config)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ CLOCK_EnableClock(kCLOCK_Dcp);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+ base->CTRL = 0xF0800000u; /* reset value */
+ base->CTRL = 0x30800000u; /* default value */
+
+ dcp_clear_status(base);
+ dcp_clear_channel_status(
+ base, (uint32_t)kDCP_Channel0 | (uint32_t)kDCP_Channel1 | (uint32_t)kDCP_Channel2 | (uint32_t)kDCP_Channel3);
+
+ base->CTRL = DCP_CTRL_GATHER_RESIDUAL_WRITES(config->gatherResidualWrites) |
+ DCP_CTRL_ENABLE_CONTEXT_CACHING(config->enableContextCaching) |
+ DCP_CTRL_ENABLE_CONTEXT_SWITCHING(config->enableContextSwitching) |
+ DCP_CTRL_CHANNEL_INTERRUPT_ENABLE(config->enableChannelInterrupt);
+
+ /* enable DCP channels */
+ base->CHANNELCTRL = DCP_CHANNELCTRL_ENABLE_CHANNEL(config->enableChannel);
+
+ /* use context switching buffer */
+ base->CONTEXT = (uint32_t)&s_dcpContextSwitchingBuffer;
+}
+
+/*!
+ * brief Disable DCP clock
+ *
+ * Reset DCP and Disable DCP clock.
+ *
+ * param base DCP base address
+ */
+void DCP_Deinit(DCP_Type *base)
+{
+ base->CTRL = 0xF0800000u; /* reset value */
+ (void)memset(&s_dcpContextSwitchingBuffer, 0, sizeof(s_dcpContextSwitchingBuffer));
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ CLOCK_DisableClock(kCLOCK_Dcp);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Poll and wait on DCP channel.
+ *
+ * Polls the specified DCP channel until current it completes activity.
+ *
+ * param base DCP peripheral base address.
+ * param handle Specifies DCP channel.
+ * return kStatus_Success When data processing completes without error.
+ * return kStatus_Fail When error occurs.
+ */
+status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle)
+{
+ /* wait if our channel is still active */
+ while ((base->STAT & (uint32_t)handle->channel) == (uint32_t)handle->channel)
+ {
+ }
+
+ if (dcp_get_channel_status(base, handle->channel) != kStatus_Success)
+ {
+ dcp_clear_status(base);
+ dcp_clear_channel_status(base, (uint32_t)handle->channel);
+ return kStatus_Fail;
+ }
+
+ dcp_clear_status(base);
+ return kStatus_Success;
+}
+
+/*!
+ * @brief Check validity of algoritm.
+ *
+ * This function checks the validity of input argument.
+ *
+ * @param algo Tested algorithm value.
+ * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
+ */
+static status_t dcp_hash_check_input_alg(dcp_hash_algo_t algo)
+{
+ if ((algo != kDCP_Sha256) && (algo != kDCP_Sha1) && (algo != kDCP_Crc32))
+ {
+ return kStatus_InvalidArgument;
+ }
+ return kStatus_Success;
+}
+
+/*!
+ * @brief Check validity of input arguments.
+ *
+ * This function checks the validity of input arguments.
+ *
+ * @param base DCP peripheral base address.
+ * @param ctx Memory buffer given by user application where the DCP_HASH_Init/DCP_HASH_Update/DCP_HASH_Finish store
+ * context.
+ * @param algo Tested algorithm value.
+ * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
+ */
+static status_t dcp_hash_check_input_args(DCP_Type *base, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo)
+{
+ /* Check validity of input algorithm */
+ if (kStatus_Success != dcp_hash_check_input_alg(algo))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ if ((NULL == ctx) || (NULL == base))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+ return kStatus_Success;
+}
+
+/*!
+ * @brief Check validity of internal software context.
+ *
+ * This function checks if the internal context structure looks correct.
+ *
+ * @param ctxInternal Internal context.
+ * @param message Input message address.
+ * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
+ */
+static status_t dcp_hash_check_context(dcp_hash_ctx_internal_t *ctxInternal, const uint8_t *message)
+{
+ if ((NULL == message) || (NULL == ctxInternal) || (kStatus_Success != dcp_hash_check_input_alg(ctxInternal->algo)))
+ {
+ return kStatus_InvalidArgument;
+ }
+
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ else if ((uint32_t)ctxInternal & (FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1))
+ {
+ /* ctx must be cache line aligned when using DCACHE */
+ return kStatus_InvalidArgument;
+ }
+#endif
+
+ return kStatus_Success;
+}
+
+/*!
+ * @brief Initialize the SHA engine for new hash.
+ *
+ * This function sets kDCP_CONTROL0_HASH_INIT for control0 in work packet to start a new hash.
+ *
+ * @param base SHA peripheral base address.
+ * @param ctxInternal Internal context.
+ */
+static status_t dcp_hash_engine_init(DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal)
+{
+ status_t status;
+
+ status = kStatus_InvalidArgument;
+
+ if ((kDCP_Sha256 == ctxInternal->algo) || (kDCP_Sha1 == ctxInternal->algo) || (kDCP_Crc32 == ctxInternal->algo))
+ {
+ ctxInternal->ctrl0 = (uint32_t)kDCP_CONTROL0_HASH_INIT;
+ status = kStatus_Success;
+ }
+
+ return status;
+}
+
+static status_t dcp_hash_update_non_blocking(
+ DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal, dcp_work_packet_t *dcpPacket, const uint8_t *msg, size_t size)
+{
+ dcpPacket->control0 = ctxInternal->ctrl0 | (ctxInternal->handle->swapConfig & 0xFC0000u) |
+ (uint32_t)kDCP_CONTROL0_ENABLE_HASH | (uint32_t)kDCP_CONTROL0_DECR_SEMAPHOR;
+ if (ctxInternal->algo == kDCP_Sha256)
+ {
+ dcpPacket->control1 = (uint32_t)kDCP_CONTROL1_HASH_SELECT_SHA256;
+ }
+ else if (ctxInternal->algo == kDCP_Sha1)
+ {
+ dcpPacket->control1 = (uint32_t)kDCP_CONTROL1_HASH_SELECT_SHA1;
+ }
+ else if (ctxInternal->algo == kDCP_Crc32)
+ {
+ /* In CRC-32 case if size is zero, do not schedule other computing */
+ if (size == 0U)
+ {
+#if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ /* Clear DCACHE memory before starting the engine */
+ SCB_CleanDCache_by_Addr((uint32_t *)ctxInternal, sizeof(dcp_hash_ctx_internal_t));
+#endif
+ /* Make sure that all data memory accesses are completed before starting of the job */
+ __DSB();
+ __ISB();
+ return kStatus_Success;
+ }
+ dcpPacket->control1 = (uint32_t)kDCP_CONTROL1_HASH_SELECT_CRC32;
+ }
+ else
+ {
+ return kStatus_Fail;
+ }
+ dcpPacket->sourceBufferAddress = (uint32_t)msg;
+ dcpPacket->destinationBufferAddress = 0;
+ dcpPacket->bufferSize = size;
+ dcpPacket->payloadPointer = (uint32_t)ctxInternal->runningHash;
+
+#if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ /* Clear DCACHE memory before starting the engine */
+ SCB_CleanDCache_by_Addr((uint32_t *)ctxInternal, sizeof(dcp_hash_ctx_internal_t));
+#endif
+ /* Make sure that all data memory accesses are completed before starting of the job */
+ __DSB();
+ __ISB();
+
+ return dcp_schedule_work(base, ctxInternal->handle, dcpPacket);
+}
+
+static status_t dcp_hash_update(DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal, const uint8_t *msg, size_t size)
+{
+ status_t completionStatus = kStatus_Fail;
+
+ /* Use extended DCACHE line size aligned structure */
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ dcp_work_packet_t *dcpWork;
+ uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
+ dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt);
+#else
+ dcp_work_packet_t dcpWorkPacket = {0};
+ dcp_work_packet_t *dcpWork = &dcpWorkPacket;
+#endif
+
+ do
+ {
+ completionStatus = dcp_hash_update_non_blocking(base, ctxInternal, dcpWork, msg, size);
+ } while (completionStatus == (int32_t)kStatus_DCP_Again);
+
+ completionStatus = DCP_WaitForChannelComplete(base, ctxInternal->handle);
+
+ ctxInternal->ctrl0 = 0; /* clear kDCP_CONTROL0_HASH_INIT and kDCP_CONTROL0_HASH_TERM flags */
+ return (completionStatus);
+}
+
+/*!
+ * @brief Adds message to current hash.
+ *
+ * This function merges the message to fill the internal buffer, empties the internal buffer if
+ * it becomes full, then process all remaining message data.
+ *
+ *
+ * @param base DCP peripheral base address.
+ * @param ctxInternal Internal context.
+ * @param message Input message.
+ * @param messageSize Size of input message in bytes.
+ * @return kStatus_Success.
+ */
+static status_t dcp_hash_process_message_data(DCP_Type *base,
+ dcp_hash_ctx_internal_t *ctxInternal,
+ const uint8_t *message,
+ size_t messageSize)
+{
+ status_t status = kStatus_Fail;
+
+ /* if there is partially filled internal buffer, fill it to full block */
+ if (ctxInternal->blksz > 0U)
+ {
+ size_t toCopy = DCP_HASH_BLOCK_SIZE - ctxInternal->blksz;
+ (void)dcp_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy);
+ message += toCopy;
+ messageSize -= toCopy;
+
+ /* process full internal block */
+ status = dcp_hash_update(base, ctxInternal, &ctxInternal->blk.b[0], DCP_HASH_BLOCK_SIZE);
+ if (kStatus_Success != status)
+ {
+ return status;
+ }
+ }
+
+ /* process all full blocks in message[] */
+ uint32_t fullBlocksSize = ((messageSize >> 6) << 6); /* (X / 64) * 64 */
+ if (fullBlocksSize > 0U)
+ {
+ status = dcp_hash_update(base, ctxInternal, message, fullBlocksSize);
+ if (kStatus_Success != status)
+ {
+ return status;
+ }
+ message += fullBlocksSize;
+ messageSize -= fullBlocksSize;
+ }
+
+ /* copy last incomplete message bytes into internal block */
+ (void)dcp_memcpy(&ctxInternal->blk.b[0], message, messageSize);
+ ctxInternal->blksz = messageSize;
+
+ return status;
+}
+
+/*!
+ * @brief Finalize the running hash to make digest.
+ *
+ * This function empties the internal buffer, adds padding bits, and generates final digest.
+ *
+ * @param base SHA peripheral base address.
+ * @param ctxInternal Internal context.
+ * @return kStatus_Success.
+ */
+static status_t dcp_hash_finalize(DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal)
+{
+ status_t status;
+
+ ctxInternal->ctrl0 |= (uint32_t)kDCP_CONTROL0_HASH_TERM;
+ status = dcp_hash_update(base, ctxInternal, &ctxInternal->blk.b[0], ctxInternal->blksz);
+
+ return status;
+}
+
+static void dcp_hash_save_running_hash(dcp_hash_ctx_internal_t *ctxInternal)
+{
+ uint32_t *srcAddr = NULL;
+
+ switch (ctxInternal->handle->channel)
+ {
+ case kDCP_Channel0:
+ srcAddr = &s_dcpContextSwitchingBuffer.x[43];
+ break;
+
+ case kDCP_Channel1:
+ srcAddr = &s_dcpContextSwitchingBuffer.x[30];
+ break;
+
+ case kDCP_Channel2:
+ srcAddr = &s_dcpContextSwitchingBuffer.x[17];
+ break;
+
+ case kDCP_Channel3:
+ srcAddr = &s_dcpContextSwitchingBuffer.x[4];
+ break;
+
+ default:
+ /* All the cases have been listed above, the default clause should not be reached. */
+ break;
+ }
+ if (srcAddr != NULL)
+ {
+ (void)dcp_memcpy(ctxInternal->runningHash, srcAddr, sizeof(ctxInternal->runningHash));
+ }
+}
+
+static void dcp_hash_restore_running_hash(dcp_hash_ctx_internal_t *ctxInternal)
+{
+ uint32_t *destAddr = NULL;
+
+ switch (ctxInternal->handle->channel)
+ {
+ case kDCP_Channel0:
+ destAddr = &s_dcpContextSwitchingBuffer.x[43];
+ break;
+
+ case kDCP_Channel1:
+ destAddr = &s_dcpContextSwitchingBuffer.x[30];
+ break;
+
+ case kDCP_Channel2:
+ destAddr = &s_dcpContextSwitchingBuffer.x[17];
+ break;
+
+ case kDCP_Channel3:
+ destAddr = &s_dcpContextSwitchingBuffer.x[4];
+ break;
+
+ default:
+ /* No valid channel */
+ break;
+ }
+ if (destAddr != NULL)
+ {
+ (void)dcp_memcpy(destAddr, ctxInternal->runningHash, sizeof(ctxInternal->runningHash));
+ }
+}
+
+/*!
+ * brief Initialize HASH context
+ *
+ * This function initializes the HASH.
+ *
+ * param base DCP peripheral base address
+ * param handle Specifies the DCP channel used for hashing.
+ * param[out] ctx Output hash context
+ * param algo Underlaying algorithm to use for hash computation.
+ * return Status of initialization
+ */
+status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo)
+{
+ status_t status;
+
+ dcp_hash_ctx_internal_t *ctxInternal;
+ /* compile time check for the correct structure size */
+ BUILD_ASSURE(sizeof(dcp_hash_ctx_t) >= sizeof(dcp_hash_ctx_internal_t), dcp_hash_ctx_t_size);
+ uint32_t i;
+
+ status = dcp_hash_check_input_args(base, ctx, algo);
+ if (status != kStatus_Success)
+ {
+ return status;
+ }
+
+ /* set algorithm in context struct for later use */
+ ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)ctx;
+ ctxInternal->algo = algo;
+ ctxInternal->blksz = 0u;
+
+ const uint32_t j = sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]);
+ for (i = 0; i < j; i++)
+ {
+ ctxInternal->blk.w[i] = 0u;
+ }
+ ctxInternal->state = kDCP_StateHashInit;
+ ctxInternal->fullMessageSize = 0;
+ ctxInternal->handle = handle;
+ return status;
+}
+
+/*!
+ * brief Add data to current HASH
+ *
+ * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
+ * hashed. The functions blocks. If it returns kStatus_Success, the running hash
+ * has been updated (DCP has processed the input data), so the memory at ref input pointer
+ * can be released back to system. The DCP context buffer is updated with the running hash
+ * and with all necessary information to support possible context switch.
+ *
+ * param base DCP peripheral base address
+ * param[in,out] ctx HASH context
+ * param input Input data
+ * param inputSize Size of input data in bytes
+ * return Status of the hash update operation
+ */
+status_t DCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
+{
+ bool isUpdateState;
+ status_t status;
+ dcp_hash_ctx_internal_t *ctxInternal;
+ size_t blockSize;
+
+ if (inputSize == 0U)
+ {
+ return kStatus_Success;
+ }
+
+ ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)ctx;
+ status = dcp_hash_check_context(ctxInternal, input);
+ if (kStatus_Success != status)
+ {
+ return status;
+ }
+
+ ctxInternal->fullMessageSize += inputSize;
+ blockSize = DCP_HASH_BLOCK_SIZE;
+ /* if we are still less than DCP_HASH_BLOCK_SIZE bytes, keep only in context */
+ if ((ctxInternal->blksz + inputSize) <= blockSize)
+ {
+ (void)dcp_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
+ ctxInternal->blksz += inputSize;
+ return status;
+ }
+ else
+ {
+ isUpdateState = ctxInternal->state == kDCP_StateHashUpdate;
+ if (!isUpdateState)
+ {
+ /* start NEW hash */
+ status = dcp_hash_engine_init(base, ctxInternal);
+ if (status != kStatus_Success)
+ {
+ return status;
+ }
+ ctxInternal->state = kDCP_StateHashUpdate;
+ }
+ else
+ {
+ dcp_hash_restore_running_hash(ctxInternal);
+ }
+ }
+
+ /* process input data */
+ status = dcp_hash_process_message_data(base, ctxInternal, input, inputSize);
+ dcp_hash_save_running_hash(ctxInternal);
+ return status;
+}
+
+/*!
+ * brief Finalize hashing
+ *
+ * Outputs the final hash (computed by DCP_HASH_Update()) and erases the context.
+ *
+ * param[in,out] ctx Input hash context
+ * param[out] output Output hash data
+ * param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of
+ * output[] buffer. On function return, it stores the number of updated output bytes.
+ * return Status of the hash finish operation
+ */
+status_t DCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize)
+{
+ size_t algOutSize = 0;
+ status_t status;
+ dcp_hash_ctx_internal_t *ctxInternal;
+
+ ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)ctx;
+ status = dcp_hash_check_context(ctxInternal, output);
+
+ if (kStatus_Success != status)
+ {
+ return status;
+ }
+
+ if (ctxInternal->state == kDCP_StateHashInit)
+ {
+ status = dcp_hash_engine_init(base, ctxInternal);
+ if (status != kStatus_Success)
+ {
+ return status;
+ }
+ }
+ else
+ {
+ dcp_hash_restore_running_hash(ctxInternal);
+ }
+
+ size_t outSize = 0u;
+
+ /* compute algorithm output length */
+ switch (ctxInternal->algo)
+ {
+ case kDCP_Sha256:
+ outSize = (uint32_t)kDCP_OutLenSha256;
+ break;
+ case kDCP_Sha1:
+ outSize = (uint32_t)kDCP_OutLenSha1;
+ break;
+ case kDCP_Crc32:
+ outSize = (uint32_t)kDCP_OutLenCrc32;
+ break;
+ default:
+ /* All the cases have been listed above, the default clause should not be reached. */
+ break;
+ }
+ algOutSize = outSize;
+
+#if defined(DCP_HASH_CAVP_COMPATIBLE)
+ if (ctxInternal->fullMessageSize == 0U)
+ {
+ switch (ctxInternal->algo)
+ {
+ case kDCP_Sha256:
+ (void)dcp_memcpy(&output[0], &s_nullSha256, 32);
+ break;
+ case kDCP_Sha1:
+ (void)dcp_memcpy(&output[0], &s_nullSha1, 20);
+ break;
+ default:
+ /* All the cases have been listed above, the default clause should not be reached. */
+ break;
+ }
+
+ return kStatus_Success;
+ }
+#endif /* DCP_HASH_CAVP_COMPATIBLE */
+
+ /* flush message last incomplete block, if there is any, and add padding bits */
+ status = dcp_hash_finalize(base, ctxInternal);
+
+ if (outputSize != NULL)
+ {
+ if (algOutSize < *outputSize)
+ {
+ *outputSize = algOutSize;
+ }
+ else
+ {
+ algOutSize = *outputSize;
+ }
+ }
+
+#if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ SCB_InvalidateDCache_by_Addr(ctx, sizeof(dcp_hash_ctx_t));
+#endif
+ /* Reverse and copy result to output[] */
+ dcp_reverse_and_copy((uint8_t *)ctxInternal->runningHash, &output[0], algOutSize);
+
+ (void)memset(ctx, 0, sizeof(dcp_hash_ctx_t));
+ return status;
+}
+
+/*!
+ * brief Create HASH on given data
+ *
+ * Perform the full SHA or CRC32 in one function call. The function is blocking.
+ *
+ * param base DCP peripheral base address
+ * param handle Handle used for the request.
+ * param algo Underlaying algorithm to use for hash computation.
+ * param input Input data
+ * param inputSize Size of input data in bytes
+ * param[out] output Output hash data
+ * param[out] outputSize Output parameter storing the size of the output hash in bytes
+ * return Status of the one call hash operation.
+ */
+status_t DCP_HASH(DCP_Type *base,
+ dcp_handle_t *handle,
+ dcp_hash_algo_t algo,
+ const uint8_t *input,
+ size_t inputSize,
+ uint8_t *output,
+ size_t *outputSize)
+{
+ /* Use extended DCACHE line size aligned structure */
+#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U)
+ dcp_hash_ctx_t *hashCtx;
+ uint8_t hashCtxExt[sizeof(dcp_hash_ctx_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U};
+ hashCtx = (dcp_hash_ctx_t *)DCP_FindCacheLine(hashCtxExt);
+#else
+ dcp_hash_ctx_t hashCtxStruct = {0};
+ dcp_hash_ctx_t *hashCtx = &hashCtxStruct;
+#endif
+
+ status_t status;
+
+ status = DCP_HASH_Init(base, handle, hashCtx, algo);
+ if (status != kStatus_Success)
+ {
+ return status;
+ }
+
+ status = DCP_HASH_Update(base, hashCtx, input, inputSize);
+ if (status != kStatus_Success)
+ {
+ return status;
+ }
+
+ status = DCP_HASH_Finish(base, hashCtx, output, outputSize);
+
+ return status;
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dmamux.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dmamux.c
new file mode 100644
index 0000000000..8bfbe6c367
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dmamux.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_dmamux.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.dmamux"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief Get instance number for DMAMUX.
+ *
+ * @param base DMAMUX peripheral base address.
+ */
+static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Array to map DMAMUX instance number to base pointer. */
+static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Array to map DMAMUX instance number to clock name. */
+static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_dmamuxBases); instance++)
+ {
+ if (s_dmamuxBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_dmamuxBases));
+
+ return instance;
+}
+
+/*!
+ * brief Initializes the DMAMUX peripheral.
+ *
+ * This function ungates the DMAMUX clock.
+ *
+ * param base DMAMUX peripheral base address.
+ *
+ */
+void DMAMUX_Init(DMAMUX_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Deinitializes the DMAMUX peripheral.
+ *
+ * This function gates the DMAMUX clock.
+ *
+ * param base DMAMUX peripheral base address.
+ */
+void DMAMUX_Deinit(DMAMUX_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_edma.c
new file mode 100644
index 0000000000..e74334bc5a
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_edma.c
@@ -0,0 +1,2849 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_edma.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.edma"
+#endif
+
+#define EDMA_TRANSFER_ENABLED_MASK 0x80U
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief Get instance offset.
+ *
+ * @param instance EDMA peripheral instance number.
+ */
+static uint32_t EDMA_GetInstanceOffset(uint32_t instance);
+
+/*!
+ * @brief Map transfer width.
+ *
+ * @param width transfer width.
+ */
+static edma_transfer_size_t EDMA_TransferWidthMapping(uint32_t width);
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Array to map EDMA instance number to base pointer. */
+static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Array to map EDMA instance number to clock name. */
+static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*! @brief Array to map EDMA instance number to IRQ number. */
+static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS;
+
+/*! @brief Pointers to transfer handle for each EDMA channel. */
+static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT];
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+static uint32_t EDMA_GetInstance(DMA_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_edmaBases); instance++)
+ {
+ if (s_edmaBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_edmaBases));
+
+ return instance;
+}
+
+/*!
+ * brief Push content of TCD structure into hardware TCD register.
+ *
+ * param base EDMA peripheral base address.
+ * param channel EDMA channel number.
+ * param tcd Point to TCD structure.
+ */
+void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+ assert(tcd != NULL);
+ assert(((uint32_t)tcd & 0x1FU) == 0U);
+
+ /* Push tcd into hardware TCD register */
+ base->TCD[channel].SADDR = tcd->SADDR;
+ base->TCD[channel].SOFF = tcd->SOFF;
+ base->TCD[channel].ATTR = tcd->ATTR;
+ base->TCD[channel].NBYTES_MLNO = tcd->NBYTES;
+ base->TCD[channel].SLAST = tcd->SLAST;
+ base->TCD[channel].DADDR = tcd->DADDR;
+ base->TCD[channel].DOFF = tcd->DOFF;
+ base->TCD[channel].CITER_ELINKNO = tcd->CITER;
+ base->TCD[channel].DLAST_SGA = tcd->DLAST_SGA;
+ /* Clear DONE bit first, otherwise ESG cannot be set */
+ base->TCD[channel].CSR = 0;
+ base->TCD[channel].CSR = tcd->CSR;
+ base->TCD[channel].BITER_ELINKNO = tcd->BITER;
+}
+
+/*!
+ * brief Initializes the eDMA peripheral.
+ *
+ * This function ungates the eDMA clock and configures the eDMA peripheral according
+ * to the configuration structure.
+ *
+ * param base eDMA peripheral base address.
+ * param config A pointer to the configuration structure, see "edma_config_t".
+ * note This function enables the minor loop map feature.
+ */
+void EDMA_Init(DMA_Type *base, const edma_config_t *config)
+{
+ assert(config != NULL);
+
+ uint32_t tmpreg;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Ungate EDMA peripheral clock */
+ CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+ /* clear all the enabled request, status to make sure EDMA status is in normal condition */
+ base->ERQ = 0U;
+ base->INT = 0xFFFFFFFFU;
+ base->ERR = 0xFFFFFFFFU;
+ /* Configure EDMA peripheral according to the configuration structure. */
+ tmpreg = base->CR;
+ tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK);
+ tmpreg |= (DMA_CR_ERCA(config->enableRoundRobinArbitration) | DMA_CR_HOE(config->enableHaltOnError) |
+ DMA_CR_CLM(config->enableContinuousLinkMode) | DMA_CR_EDBG(config->enableDebugMode) | DMA_CR_EMLM(1U));
+ base->CR = tmpreg;
+}
+
+/*!
+ * brief Deinitializes the eDMA peripheral.
+ *
+ * This function gates the eDMA clock.
+ *
+ * param base eDMA peripheral base address.
+ */
+void EDMA_Deinit(DMA_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Gate EDMA peripheral clock */
+ CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Gets the eDMA default configuration structure.
+ *
+ * This function sets the configuration structure to default values.
+ * The default configuration is set to the following values.
+ * code
+ * config.enableContinuousLinkMode = false;
+ * config.enableHaltOnError = true;
+ * config.enableRoundRobinArbitration = false;
+ * config.enableDebugMode = false;
+ * endcode
+ *
+ * param config A pointer to the eDMA configuration structure.
+ */
+void EDMA_GetDefaultConfig(edma_config_t *config)
+{
+ assert(config != NULL);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->enableRoundRobinArbitration = false;
+ config->enableHaltOnError = true;
+ config->enableContinuousLinkMode = false;
+ config->enableDebugMode = false;
+}
+
+/*!
+ * brief Sets all TCD registers to default values.
+ *
+ * This function sets TCD registers for this channel to default values.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * note This function must not be called while the channel transfer is ongoing
+ * or it causes unpredictable results.
+ * note This function enables the auto stop request feature.
+ */
+void EDMA_ResetChannel(DMA_Type *base, uint32_t channel)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ EDMA_TcdReset((edma_tcd_t *)(uint32_t)&base->TCD[channel]);
+}
+
+/*!
+ * brief Configures the eDMA transfer attribute.
+ *
+ * This function configures the transfer attribute, including source address, destination address,
+ * transfer size, address offset, and so on. It also configures the scatter gather feature if the
+ * user supplies the TCD address.
+ * Example:
+ * code
+ * edma_transfer_t config;
+ * edma_tcd_t tcd;
+ * config.srcAddr = ..;
+ * config.destAddr = ..;
+ * ...
+ * EDMA_SetTransferConfig(DMA0, channel, &config, &stcd);
+ * endcode
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * param config Pointer to eDMA transfer configuration structure.
+ * param nextTcd Point to TCD structure. It can be NULL if users
+ * do not want to enable scatter/gather feature.
+ * note If nextTcd is not NULL, it means scatter gather feature is enabled
+ * and DREQ bit is cleared in the previous transfer configuration, which
+ * is set in the eDMA_ResetChannel.
+ */
+void EDMA_SetTransferConfig(DMA_Type *base, uint32_t channel, const edma_transfer_config_t *config, edma_tcd_t *nextTcd)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+ assert(config != NULL);
+ assert(((uint32_t)nextTcd & 0x1FU) == 0U);
+
+ EDMA_TcdSetTransferConfig((edma_tcd_t *)(uint32_t)&base->TCD[channel], config, nextTcd);
+}
+
+/*!
+ * brief Configures the eDMA minor offset feature.
+ *
+ * The minor offset means that the signed-extended value is added to the source address or destination
+ * address after each minor loop.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * param config A pointer to the minor offset configuration structure.
+ */
+void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+ assert(config != NULL);
+
+ uint32_t tmpreg;
+
+ tmpreg = base->TCD[channel].NBYTES_MLOFFYES;
+ tmpreg &= ~(DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK | DMA_NBYTES_MLOFFYES_MLOFF_MASK);
+ tmpreg |=
+ (DMA_NBYTES_MLOFFYES_SMLOE(config->enableSrcMinorOffset) |
+ DMA_NBYTES_MLOFFYES_DMLOE(config->enableDestMinorOffset) | DMA_NBYTES_MLOFFYES_MLOFF(config->minorOffset));
+ base->TCD[channel].NBYTES_MLOFFYES = tmpreg;
+}
+
+/*!
+ * brief Configures the eDMA channel preemption feature.
+ *
+ * This function configures the channel preemption attribute and the priority of the channel.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number
+ * param config A pointer to the channel preemption configuration structure.
+ */
+void EDMA_SetChannelPreemptionConfig(DMA_Type *base, uint32_t channel, const edma_channel_Preemption_config_t *config)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+ assert(config != NULL);
+
+ bool tmpEnablePreemptAbility = config->enablePreemptAbility;
+ bool tmpEnableChannelPreemption = config->enableChannelPreemption;
+ uint8_t tmpChannelPriority = config->channelPriority;
+ volatile uint8_t *tmpReg = &base->DCHPRI3;
+
+ ((volatile uint8_t *)tmpReg)[DMA_DCHPRI_INDEX(channel)] =
+ (DMA_DCHPRI0_DPA((true == tmpEnablePreemptAbility ? 0U : 1U)) |
+ DMA_DCHPRI0_ECP((true == tmpEnableChannelPreemption ? 1U : 0U)) | DMA_DCHPRI0_CHPRI(tmpChannelPriority));
+}
+
+/*!
+ * brief Sets the channel link for the eDMA transfer.
+ *
+ * This function configures either the minor link or the major link mode. The minor link means that the channel link is
+ * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
+ * exhausted.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * param type A channel link type, which can be one of the following:
+ * arg kEDMA_LinkNone
+ * arg kEDMA_MinorLink
+ * arg kEDMA_MajorLink
+ * param linkedChannel The linked channel number.
+ * note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid.
+ */
+void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+ assert(linkedChannel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ EDMA_TcdSetChannelLink((edma_tcd_t *)(uint32_t)&base->TCD[channel], type, linkedChannel);
+}
+
+/*!
+ * brief Sets the bandwidth for the eDMA transfer.
+ *
+ * Because the eDMA processes the minor loop, it continuously generates read/write sequences
+ * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of
+ * each read/write access to control the bus request bandwidth seen by the crossbar switch.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * param bandWidth A bandwidth setting, which can be one of the following:
+ * arg kEDMABandwidthStallNone
+ * arg kEDMABandwidthStall4Cycle
+ * arg kEDMABandwidthStall8Cycle
+ */
+void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ base->TCD[channel].CSR = (uint16_t)((base->TCD[channel].CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth));
+}
+
+/*!
+ * brief Sets the source modulo and the destination modulo for the eDMA transfer.
+ *
+ * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF)
+ * calculation is performed or the original register value. It provides the ability to implement a circular data
+ * queue easily.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * param srcModulo A source modulo value.
+ * param destModulo A destination modulo value.
+ */
+void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ uint16_t tmpreg;
+
+ tmpreg = base->TCD[channel].ATTR & (~(uint16_t)(DMA_ATTR_SMOD_MASK | DMA_ATTR_DMOD_MASK));
+ base->TCD[channel].ATTR = tmpreg | DMA_ATTR_DMOD(destModulo) | DMA_ATTR_SMOD(srcModulo);
+}
+
+/*!
+ * brief Enables the interrupt source for the eDMA transfer.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * param mask The mask of interrupt source to be set. Users need to use
+ * the defined edma_interrupt_enable_t type.
+ */
+void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ /* Enable error interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_ErrorInterruptEnable))
+ {
+ base->EEI |= ((uint32_t)0x1U << channel);
+ }
+
+ /* Enable Major interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_MajorInterruptEnable))
+ {
+ base->TCD[channel].CSR |= DMA_CSR_INTMAJOR_MASK;
+ }
+
+ /* Enable Half major interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_HalfInterruptEnable))
+ {
+ base->TCD[channel].CSR |= DMA_CSR_INTHALF_MASK;
+ }
+}
+
+/*!
+ * brief Disables the interrupt source for the eDMA transfer.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * param mask The mask of the interrupt source to be set. Use
+ * the defined edma_interrupt_enable_t type.
+ */
+void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ /* Disable error interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_ErrorInterruptEnable))
+ {
+ base->EEI &= (~((uint32_t)0x1U << channel));
+ }
+
+ /* Disable Major interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_MajorInterruptEnable))
+ {
+ base->TCD[channel].CSR &= ~(uint16_t)DMA_CSR_INTMAJOR_MASK;
+ }
+
+ /* Disable Half major interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_HalfInterruptEnable))
+ {
+ base->TCD[channel].CSR &= ~(uint16_t)DMA_CSR_INTHALF_MASK;
+ }
+}
+
+/*!
+ * brief Sets all fields to default values for the TCD structure.
+ *
+ * This function sets all fields for this TCD structure to default value.
+ *
+ * param tcd Pointer to the TCD structure.
+ * note This function enables the auto stop request feature.
+ */
+void EDMA_TcdReset(edma_tcd_t *tcd)
+{
+ assert(tcd != NULL);
+ assert(((uint32_t)tcd & 0x1FU) == 0U);
+
+ /* Reset channel TCD */
+ tcd->SADDR = 0U;
+ tcd->SOFF = 0U;
+ tcd->ATTR = 0U;
+ tcd->NBYTES = 0U;
+ tcd->SLAST = 0U;
+ tcd->DADDR = 0U;
+ tcd->DOFF = 0U;
+ tcd->CITER = 0U;
+ tcd->DLAST_SGA = 0U;
+ /* Enable auto disable request feature */
+ tcd->CSR = DMA_CSR_DREQ(true);
+ tcd->BITER = 0U;
+}
+
+/*!
+ * brief Configures the eDMA TCD transfer attribute.
+ *
+ * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers.
+ * The STCD is used in the scatter-gather mode.
+ * This function configures the TCD transfer attribute, including source address, destination address,
+ * transfer size, address offset, and so on. It also configures the scatter gather feature if the
+ * user supplies the next TCD address.
+ * Example:
+ * code
+ * edma_transfer_t config = {
+ * ...
+ * }
+ * edma_tcd_t tcd __aligned(32);
+ * edma_tcd_t nextTcd __aligned(32);
+ * EDMA_TcdSetTransferConfig(&tcd, &config, &nextTcd);
+ * endcode
+ *
+ * param tcd Pointer to the TCD structure.
+ * param config Pointer to eDMA transfer configuration structure.
+ * param nextTcd Pointer to the next TCD structure. It can be NULL if users
+ * do not want to enable scatter/gather feature.
+ * note TCD address should be 32 bytes aligned or it causes an eDMA error.
+ * note If the nextTcd is not NULL, the scatter gather feature is enabled
+ * and DREQ bit is cleared in the previous transfer configuration, which
+ * is set in the EDMA_TcdReset.
+ */
+void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd)
+{
+ assert(tcd != NULL);
+ assert(((uint32_t)tcd & 0x1FU) == 0U);
+ assert(config != NULL);
+ assert(((uint32_t)nextTcd & 0x1FU) == 0U);
+ assert((config->srcAddr % (1UL << (uint32_t)config->srcTransferSize)) == 0U);
+ assert((config->destAddr % (1UL << (uint32_t)config->destTransferSize)) == 0U);
+
+ /* source address */
+ tcd->SADDR = config->srcAddr;
+ /* destination address */
+ tcd->DADDR = config->destAddr;
+ /* Source data and destination data transfer size */
+ tcd->ATTR = DMA_ATTR_SSIZE(config->srcTransferSize) | DMA_ATTR_DSIZE(config->destTransferSize);
+ /* Source address signed offset */
+ tcd->SOFF = (uint16_t)config->srcOffset;
+ /* Destination address signed offset */
+ tcd->DOFF = (uint16_t)config->destOffset;
+ /* Minor byte transfer count */
+ tcd->NBYTES = config->minorLoopBytes;
+ /* Current major iteration count */
+ tcd->CITER = (uint16_t)config->majorLoopCounts;
+ /* Starting major iteration count */
+ tcd->BITER = (uint16_t)config->majorLoopCounts;
+ /* Enable scatter/gather processing */
+ if (nextTcd != NULL)
+ {
+ tcd->DLAST_SGA = (uint32_t)nextTcd;
+ /*
+ Before call EDMA_TcdSetTransferConfig or EDMA_SetTransferConfig,
+ user must call EDMA_TcdReset or EDMA_ResetChannel which will set
+ DREQ, so must use "|" or "&" rather than "=".
+
+ Clear the DREQ bit because scatter gather has been enabled, so the
+ previous transfer is not the last transfer, and channel request should
+ be enabled at the next transfer(the next TCD).
+ */
+ tcd->CSR = (tcd->CSR | (uint16_t)DMA_CSR_ESG_MASK) & ~(uint16_t)DMA_CSR_DREQ_MASK;
+ }
+}
+
+/*!
+ * brief Configures the eDMA TCD minor offset feature.
+ *
+ * A minor offset is a signed-extended value added to the source address or a destination
+ * address after each minor loop.
+ *
+ * param tcd A point to the TCD structure.
+ * param config A pointer to the minor offset configuration structure.
+ */
+void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config)
+{
+ assert(tcd != NULL);
+ assert(((uint32_t)tcd & 0x1FU) == 0U);
+
+ uint32_t tmpreg;
+
+ tmpreg = tcd->NBYTES &
+ ~(DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK | DMA_NBYTES_MLOFFYES_MLOFF_MASK);
+ tmpreg |=
+ (DMA_NBYTES_MLOFFYES_SMLOE(config->enableSrcMinorOffset) |
+ DMA_NBYTES_MLOFFYES_DMLOE(config->enableDestMinorOffset) | DMA_NBYTES_MLOFFYES_MLOFF(config->minorOffset));
+ tcd->NBYTES = tmpreg;
+}
+
+/*!
+ * brief Sets the channel link for the eDMA TCD.
+ *
+ * This function configures either a minor link or a major link. The minor link means the channel link is
+ * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is
+ * exhausted.
+ *
+ * note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid.
+ * param tcd Point to the TCD structure.
+ * param type Channel link type, it can be one of:
+ * arg kEDMA_LinkNone
+ * arg kEDMA_MinorLink
+ * arg kEDMA_MajorLink
+ * param linkedChannel The linked channel number.
+ */
+void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel)
+{
+ assert(tcd != NULL);
+ assert(((uint32_t)tcd & 0x1FU) == 0U);
+ assert(linkedChannel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ if (type == kEDMA_MinorLink) /* Minor link config */
+ {
+ uint16_t tmpreg;
+
+ /* Enable minor link */
+ tcd->CITER |= DMA_CITER_ELINKYES_ELINK_MASK;
+ tcd->BITER |= DMA_BITER_ELINKYES_ELINK_MASK;
+ /* Set linked channel */
+ tmpreg = tcd->CITER & (~(uint16_t)DMA_CITER_ELINKYES_LINKCH_MASK);
+ tmpreg |= DMA_CITER_ELINKYES_LINKCH(linkedChannel);
+ tcd->CITER = tmpreg;
+ tmpreg = tcd->BITER & (~(uint16_t)DMA_BITER_ELINKYES_LINKCH_MASK);
+ tmpreg |= DMA_BITER_ELINKYES_LINKCH(linkedChannel);
+ tcd->BITER = tmpreg;
+ }
+ else if (type == kEDMA_MajorLink) /* Major link config */
+ {
+ uint16_t tmpreg;
+
+ /* Enable major link */
+ tcd->CSR |= DMA_CSR_MAJORELINK_MASK;
+ /* Set major linked channel */
+ tmpreg = tcd->CSR & (~(uint16_t)DMA_CSR_MAJORLINKCH_MASK);
+ tcd->CSR = tmpreg | DMA_CSR_MAJORLINKCH(linkedChannel);
+ }
+ else /* Link none */
+ {
+ tcd->CITER &= ~(uint16_t)DMA_CITER_ELINKYES_ELINK_MASK;
+ tcd->BITER &= ~(uint16_t)DMA_BITER_ELINKYES_ELINK_MASK;
+ tcd->CSR &= ~(uint16_t)DMA_CSR_MAJORELINK_MASK;
+ }
+}
+
+/*!
+ * brief Sets the source modulo and the destination modulo for the eDMA TCD.
+ *
+ * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF)
+ * calculation is performed or the original register value. It provides the ability to implement a circular data
+ * queue easily.
+ *
+ * param tcd A pointer to the TCD structure.
+ * param srcModulo A source modulo value.
+ * param destModulo A destination modulo value.
+ */
+void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo)
+{
+ assert(tcd != NULL);
+ assert(((uint32_t)tcd & 0x1FU) == 0U);
+
+ uint16_t tmpreg;
+
+ tmpreg = tcd->ATTR & (~(uint16_t)(DMA_ATTR_SMOD_MASK | DMA_ATTR_DMOD_MASK));
+ tcd->ATTR = tmpreg | DMA_ATTR_DMOD(destModulo) | DMA_ATTR_SMOD(srcModulo);
+}
+
+/*!
+ * brief Enables the interrupt source for the eDMA TCD.
+ *
+ * param tcd Point to the TCD structure.
+ * param mask The mask of interrupt source to be set. Users need to use
+ * the defined edma_interrupt_enable_t type.
+ */
+void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask)
+{
+ assert(tcd != NULL);
+
+ /* Enable Major interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_MajorInterruptEnable))
+ {
+ tcd->CSR |= DMA_CSR_INTMAJOR_MASK;
+ }
+
+ /* Enable Half major interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_HalfInterruptEnable))
+ {
+ tcd->CSR |= DMA_CSR_INTHALF_MASK;
+ }
+}
+
+/*!
+ * brief Disables the interrupt source for the eDMA TCD.
+ *
+ * param tcd Point to the TCD structure.
+ * param mask The mask of interrupt source to be set. Users need to use
+ * the defined edma_interrupt_enable_t type.
+ */
+void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask)
+{
+ assert(tcd != NULL);
+
+ /* Disable Major interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_MajorInterruptEnable))
+ {
+ tcd->CSR &= ~(uint16_t)DMA_CSR_INTMAJOR_MASK;
+ }
+
+ /* Disable Half major interrupt */
+ if (0U != (mask & (uint32_t)kEDMA_HalfInterruptEnable))
+ {
+ tcd->CSR &= ~(uint16_t)DMA_CSR_INTHALF_MASK;
+ }
+}
+
+/*!
+ * brief Gets the remaining major loop count from the eDMA current channel TCD.
+ *
+ * This function checks the TCD (Task Control Descriptor) status for a specified
+ * eDMA channel and returns the number of major loop count that has not finished.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * return Major loop count which has not been transferred yet for the current TCD.
+ * note 1. This function can only be used to get unfinished major loop count of transfer without
+ * the next TCD, or it might be inaccuracy.
+ * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while
+ * the channel is running.
+ * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO
+ * register is needed while the eDMA IP does not support getting it while a channel is active.
+ * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine
+ * is working with while a channel is running.
+ * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example
+ * copied before enabling the channel) is needed. The formula to calculate it is shown below:
+ * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured)
+ */
+uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ uint32_t remainingCount = 0;
+
+ if (0U != (DMA_CSR_DONE_MASK & base->TCD[channel].CSR))
+ {
+ remainingCount = 0;
+ }
+ else
+ {
+ /* Calculate the unfinished bytes */
+ if (0U != (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK))
+ {
+ remainingCount = (((uint32_t)base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >>
+ DMA_CITER_ELINKYES_CITER_SHIFT);
+ }
+ else
+ {
+ remainingCount = (((uint32_t)base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >>
+ DMA_CITER_ELINKNO_CITER_SHIFT);
+ }
+ }
+
+ return remainingCount;
+}
+
+/*!
+ * brief Gets the eDMA channel status flags.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * return The mask of channel status flags. Users need to use the
+ * _edma_channel_status_flags type to decode the return variables.
+ */
+uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ uint32_t retval = 0;
+
+ /* Get DONE bit flag */
+ retval |= (((uint32_t)base->TCD[channel].CSR & DMA_CSR_DONE_MASK) >> DMA_CSR_DONE_SHIFT);
+ /* Get ERROR bit flag */
+ retval |= ((((uint32_t)base->ERR >> channel) & 0x1U) << 1U);
+ /* Get INT bit flag */
+ retval |= ((((uint32_t)base->INT >> channel) & 0x1U) << 2U);
+
+ return retval;
+}
+
+/*!
+ * brief Clears the eDMA channel status flags.
+ *
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ * param mask The mask of channel status to be cleared. Users need to use
+ * the defined _edma_channel_status_flags type.
+ */
+void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask)
+{
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ /* Clear DONE bit flag */
+ if (0U != (mask & (uint32_t)kEDMA_DoneFlag))
+ {
+ base->CDNE = (uint8_t)channel;
+ }
+ /* Clear ERROR bit flag */
+ if (0U != (mask & (uint32_t)kEDMA_ErrorFlag))
+ {
+ base->CERR = (uint8_t)channel;
+ }
+ /* Clear INT bit flag */
+ if (0U != (mask & (uint32_t)kEDMA_InterruptFlag))
+ {
+ base->CINT = (uint8_t)channel;
+ }
+}
+
+static uint32_t EDMA_GetInstanceOffset(uint32_t instance)
+{
+ static uint8_t startInstanceNum;
+
+#if defined(DMA0)
+ startInstanceNum = (uint8_t)EDMA_GetInstance(DMA0);
+#elif defined(DMA1)
+ startInstanceNum = (uint8_t)EDMA_GetInstance(DMA1);
+#elif defined(DMA2)
+ startInstanceNum = (uint8_t)EDMA_GetInstance(DMA2);
+#elif defined(DMA3)
+ startInstanceNum = (uint8_t)EDMA_GetInstance(DMA3);
+#endif
+
+ assert(startInstanceNum <= instance);
+
+ return instance - startInstanceNum;
+}
+
+/*!
+ * brief Creates the eDMA handle.
+ *
+ * This function is called if using the transactional API for eDMA. This function
+ * initializes the internal state of the eDMA handle.
+ *
+ * param handle eDMA handle pointer. The eDMA handle stores callback function and
+ * parameters.
+ * param base eDMA peripheral base address.
+ * param channel eDMA channel number.
+ */
+void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel)
+{
+ assert(handle != NULL);
+ assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL);
+
+ uint32_t edmaInstance;
+ uint32_t channelIndex;
+ edma_tcd_t *tcdRegs;
+
+ /* Zero the handle */
+ (void)memset(handle, 0, sizeof(*handle));
+
+ handle->base = base;
+ handle->channel = (uint8_t)channel;
+ /* Get the DMA instance number */
+ edmaInstance = EDMA_GetInstance(base);
+ channelIndex = (EDMA_GetInstanceOffset(edmaInstance) * (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel;
+ s_EDMAHandle[channelIndex] = handle;
+
+ /* Enable NVIC interrupt */
+ (void)EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]);
+
+ /*
+ Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set),
+ CSR will be 0. Because in order to suit EDMA busy check mechanism in
+ EDMA_SubmitTransfer, CSR must be set 0.
+ */
+ tcdRegs = (edma_tcd_t *)(uint32_t)&handle->base->TCD[handle->channel];
+ tcdRegs->SADDR = 0;
+ tcdRegs->SOFF = 0;
+ tcdRegs->ATTR = 0;
+ tcdRegs->NBYTES = 0;
+ tcdRegs->SLAST = 0;
+ tcdRegs->DADDR = 0;
+ tcdRegs->DOFF = 0;
+ tcdRegs->CITER = 0;
+ tcdRegs->DLAST_SGA = 0;
+ tcdRegs->CSR = 0;
+ tcdRegs->BITER = 0;
+}
+
+/*!
+ * brief Installs the TCDs memory pool into the eDMA handle.
+ *
+ * This function is called after the EDMA_CreateHandle to use scatter/gather feature. This function shall only be used
+ * while users need to use scatter gather mode. Scatter gather mode enables EDMA to load a new transfer control block
+ * (tcd) in hardware, and automatically reconfigure that DMA channel for a new transfer.
+ * Users need to prepare tcd memory and also configure tcds using interface EDMA_SubmitTransfer.
+ *
+ * param handle eDMA handle pointer.
+ * param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned.
+ * param tcdSize The number of TCD slots.
+ */
+void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize)
+{
+ assert(handle != NULL);
+ assert(((uint32_t)tcdPool & 0x1FU) == 0U);
+
+ /* Initialize tcd queue attribute. */
+ handle->header = 0;
+ handle->tail = 0;
+ handle->tcdUsed = 0;
+ handle->tcdSize = (int8_t)tcdSize;
+ handle->flags = 0;
+ handle->tcdPool = tcdPool;
+}
+
+/*!
+ * brief Installs a callback function for the eDMA transfer.
+ *
+ * This callback is called in the eDMA IRQ handler. Use the callback to do something after
+ * the current major loop transfer completes. This function will be called every time one tcd finished transfer.
+ *
+ * param handle eDMA handle pointer.
+ * param callback eDMA callback function pointer.
+ * param userData A parameter for the callback function.
+ */
+void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData)
+{
+ assert(handle != NULL);
+
+ handle->callback = callback;
+ handle->userData = userData;
+}
+
+static edma_transfer_size_t EDMA_TransferWidthMapping(uint32_t width)
+{
+ edma_transfer_size_t transferSize = kEDMA_TransferSize1Bytes;
+
+ /* map width to register value */
+ switch (width)
+ {
+ /* width 8bit */
+ case 1U:
+ transferSize = kEDMA_TransferSize1Bytes;
+ break;
+ /* width 16bit */
+ case 2U:
+ transferSize = kEDMA_TransferSize2Bytes;
+ break;
+ /* width 32bit */
+ case 4U:
+ transferSize = kEDMA_TransferSize4Bytes;
+ break;
+#if (defined(FSL_FEATURE_EDMA_SUPPORT_8_BYTES_TRANSFER) && FSL_FEATURE_EDMA_SUPPORT_8_BYTES_TRANSFER)
+ /* width 64bit */
+ case 8U:
+ transferSize = kEDMA_TransferSize8Bytes;
+ break;
+#endif
+#if (defined(FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER) && FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER)
+ /* width 128bit */
+ case 16U:
+ transferSize = kEDMA_TransferSize16Bytes;
+ break;
+#endif
+ /* width 256bit */
+ case 32U:
+ transferSize = kEDMA_TransferSize32Bytes;
+ break;
+ default:
+ /* All the cases have been listed above, the default clause should not be reached. */
+ assert(false);
+ break;
+ }
+
+ return transferSize;
+}
+
+/*!
+ * brief Prepares the eDMA transfer structure configurations.
+ *
+ * This function prepares the transfer configuration structure according to the user input.
+ *
+ * param config The user configuration structure of type edma_transfer_t.
+ * param srcAddr eDMA transfer source address.
+ * param srcWidth eDMA transfer source address width(bytes).
+ * param srcOffset source address offset.
+ * param destAddr eDMA transfer destination address.
+ * param destWidth eDMA transfer destination address width(bytes).
+ * param destOffset destination address offset.
+ * param bytesEachRequest eDMA transfer bytes per channel request.
+ * param transferBytes eDMA transfer bytes to be transferred.
+ * note The data address and the data width must be consistent. For example, if the SRC
+ * is 4 bytes, the source address must be 4 bytes aligned, or it results in
+ * source address error (SAE).
+ */
+void EDMA_PrepareTransferConfig(edma_transfer_config_t *config,
+ void *srcAddr,
+ uint32_t srcWidth,
+ int16_t srcOffset,
+ void *destAddr,
+ uint32_t destWidth,
+ int16_t destOffset,
+ uint32_t bytesEachRequest,
+ uint32_t transferBytes)
+{
+ assert(config != NULL);
+ assert(srcAddr != NULL);
+ assert(destAddr != NULL);
+ assert((srcWidth != 0U) && (srcWidth <= 32U) && ((srcWidth & (srcWidth - 1U)) == 0U));
+ assert((destWidth != 0U) && (destWidth <= 32U) && ((destWidth & (destWidth - 1U)) == 0U));
+ assert((transferBytes % bytesEachRequest) == 0U);
+ assert((((uint32_t)(uint32_t *)srcAddr) % srcWidth) == 0U);
+ assert((((uint32_t)(uint32_t *)destAddr) % destWidth) == 0U);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->destAddr = (uint32_t)(uint32_t *)destAddr;
+ config->srcAddr = (uint32_t)(uint32_t *)srcAddr;
+ config->minorLoopBytes = bytesEachRequest;
+ config->majorLoopCounts = transferBytes / bytesEachRequest;
+ config->srcTransferSize = EDMA_TransferWidthMapping(srcWidth);
+ config->destTransferSize = EDMA_TransferWidthMapping(destWidth);
+ config->destOffset = destOffset;
+ config->srcOffset = srcOffset;
+}
+
+/*!
+ * brief Prepares the eDMA transfer structure.
+ *
+ * This function prepares the transfer configuration structure according to the user input.
+ *
+ * param config The user configuration structure of type edma_transfer_t.
+ * param srcAddr eDMA transfer source address.
+ * param srcWidth eDMA transfer source address width(bytes).
+ * param destAddr eDMA transfer destination address.
+ * param destWidth eDMA transfer destination address width(bytes).
+ * param bytesEachRequest eDMA transfer bytes per channel request.
+ * param transferBytes eDMA transfer bytes to be transferred.
+ * param type eDMA transfer type.
+ * note The data address and the data width must be consistent. For example, if the SRC
+ * is 4 bytes, the source address must be 4 bytes aligned, or it results in
+ * source address error (SAE).
+ */
+void EDMA_PrepareTransfer(edma_transfer_config_t *config,
+ void *srcAddr,
+ uint32_t srcWidth,
+ void *destAddr,
+ uint32_t destWidth,
+ uint32_t bytesEachRequest,
+ uint32_t transferBytes,
+ edma_transfer_type_t type)
+{
+ assert(config != NULL);
+
+ int16_t srcOffset = 0, destOffset = 0;
+
+ switch (type)
+ {
+ case kEDMA_MemoryToMemory:
+ destOffset = (int16_t)destWidth;
+ srcOffset = (int16_t)srcWidth;
+ break;
+ case kEDMA_MemoryToPeripheral:
+ destOffset = 0;
+ srcOffset = (int16_t)srcWidth;
+ break;
+ case kEDMA_PeripheralToMemory:
+ destOffset = (int16_t)destWidth;
+ srcOffset = 0;
+ break;
+ case kEDMA_PeripheralToPeripheral:
+ destOffset = 0;
+ srcOffset = 0;
+ break;
+ default:
+ /* All the cases have been listed above, the default clause should not be reached. */
+ assert(false);
+ break;
+ }
+
+ EDMA_PrepareTransferConfig(config, srcAddr, srcWidth, srcOffset, destAddr, destWidth, destOffset, bytesEachRequest,
+ transferBytes);
+}
+
+/*!
+ * brief Submits the eDMA transfer request.
+ *
+ * This function submits the eDMA transfer request according to the transfer configuration structure.
+ * In scatter gather mode, call this function will add a configured tcd to the circular list of tcd pool.
+ * The tcd pools is setup by call function EDMA_InstallTCDMemory before.
+ *
+ * param handle eDMA handle pointer.
+ * param config Pointer to eDMA transfer configuration structure.
+ * retval kStatus_EDMA_Success It means submit transfer request succeed.
+ * retval kStatus_EDMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed.
+ * retval kStatus_EDMA_Busy It means the given channel is busy, need to submit request later.
+ */
+status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config)
+{
+ assert(handle != NULL);
+ assert(config != NULL);
+
+ edma_tcd_t *tcdRegs = (edma_tcd_t *)(uint32_t)&handle->base->TCD[handle->channel];
+
+ if (handle->tcdPool == NULL)
+ {
+ /*
+ * Check if EDMA channel is busy:
+ * 1. if channel active bit is set, it implies that minor loop is executing, then channel is busy
+ * 2. if channel active bit is not set and BITER not equal to CITER, it implies that major loop is executing,
+ * then channel is busy
+ *
+ * There is one case can not be covered in below condition:
+ * When transfer request is submitted, but no request from peripheral, that is to say channel sevice doesn't
+ * begin, if application would like to submit another transfer , then the TCD will be overwritten, since the
+ * ACTIVE is 0 and BITER = CITER, for such case, it is a scatter gather(link TCD) case actually, so
+ * application should enabled TCD pool for dynamic scatter gather mode by calling EDMA_InstallTCDMemory.
+ */
+ if (((handle->base->TCD[handle->channel].CSR & DMA_CSR_ACTIVE_MASK) != 0U) ||
+ (((handle->base->TCD[handle->channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) !=
+ (handle->base->TCD[handle->channel].BITER_ELINKNO & DMA_BITER_ELINKNO_BITER_MASK))))
+ {
+ return kStatus_EDMA_Busy;
+ }
+ else
+ {
+ EDMA_SetTransferConfig(handle->base, handle->channel, config, NULL);
+ /* Enable auto disable request feature */
+ handle->base->TCD[handle->channel].CSR |= DMA_CSR_DREQ_MASK;
+ /* Enable major interrupt */
+ handle->base->TCD[handle->channel].CSR |= DMA_CSR_INTMAJOR_MASK;
+
+ return kStatus_Success;
+ }
+ }
+ else /* Use the TCD queue. */
+ {
+ uint32_t primask;
+ uint16_t csr;
+ int8_t currentTcd;
+ int8_t previousTcd;
+ int8_t nextTcd;
+ int8_t tmpTcdUsed;
+ int8_t tmpTcdSize;
+
+ /* Check if tcd pool is full. */
+ primask = DisableGlobalIRQ();
+ tmpTcdUsed = handle->tcdUsed;
+ tmpTcdSize = handle->tcdSize;
+ if (tmpTcdUsed >= tmpTcdSize)
+ {
+ EnableGlobalIRQ(primask);
+
+ return kStatus_EDMA_QueueFull;
+ }
+ currentTcd = handle->tail;
+ handle->tcdUsed++;
+ /* Calculate index of next TCD */
+ nextTcd = currentTcd + 1;
+ if (nextTcd == handle->tcdSize)
+ {
+ nextTcd = 0;
+ }
+ /* Advance queue tail index */
+ handle->tail = nextTcd;
+ EnableGlobalIRQ(primask);
+ /* Calculate index of previous TCD */
+ previousTcd = currentTcd != 0 ? currentTcd - 1 : (handle->tcdSize - 1);
+ /* Configure current TCD block. */
+ EDMA_TcdReset(&handle->tcdPool[currentTcd]);
+ EDMA_TcdSetTransferConfig(&handle->tcdPool[currentTcd], config, NULL);
+ /* Enable major interrupt */
+ handle->tcdPool[currentTcd].CSR |= DMA_CSR_INTMAJOR_MASK;
+ /* Link current TCD with next TCD for identification of current TCD */
+ handle->tcdPool[currentTcd].DLAST_SGA = (uint32_t)&handle->tcdPool[nextTcd];
+ /* Chain from previous descriptor unless tcd pool size is 1(this descriptor is its own predecessor). */
+ if (currentTcd != previousTcd)
+ {
+ /* Enable scatter/gather feature in the previous TCD block. */
+ csr = handle->tcdPool[previousTcd].CSR | ((uint16_t)DMA_CSR_ESG_MASK);
+ csr &= ~((uint16_t)DMA_CSR_DREQ_MASK);
+ handle->tcdPool[previousTcd].CSR = csr;
+ /*
+ Check if the TCD block in the registers is the previous one (points to current TCD block). It
+ is used to check if the previous TCD linked has been loaded in TCD register. If so, it need to
+ link the TCD register in case link the current TCD with the dead chain when TCD loading occurs
+ before link the previous TCD block.
+ */
+ if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[currentTcd])
+ {
+ /* Clear the DREQ bits for the dynamic scatter gather */
+ tcdRegs->CSR |= DMA_CSR_DREQ_MASK;
+ /* Enable scatter/gather also in the TCD registers. */
+ csr = tcdRegs->CSR | DMA_CSR_ESG_MASK;
+ /* Must write the CSR register one-time, because the transfer maybe finished anytime. */
+ tcdRegs->CSR = csr;
+ /*
+ It is very important to check the ESG bit!
+ Because this hardware design: if DONE bit is set, the ESG bit can not be set. So it can
+ be used to check if the dynamic TCD link operation is successful. If ESG bit is not set
+ and the DLAST_SGA is not the next TCD address(it means the dynamic TCD link succeed and
+ the current TCD block has been loaded into TCD registers), it means transfer finished
+ and TCD link operation fail, so must install TCD content into TCD registers and enable
+ transfer again. And if ESG is set, it means transfer has not finished, so TCD dynamic
+ link succeed.
+ */
+ if (0U != (tcdRegs->CSR & DMA_CSR_ESG_MASK))
+ {
+ tcdRegs->CSR &= ~(uint16_t)DMA_CSR_DREQ_MASK;
+ return kStatus_Success;
+ }
+ /*
+ Check whether the current TCD block is already loaded in the TCD registers. It is another
+ condition when ESG bit is not set: it means the dynamic TCD link succeed and the current
+ TCD block has been loaded into TCD registers.
+ */
+ if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[nextTcd])
+ {
+ return kStatus_Success;
+ }
+ /*
+ If go to this, means the previous transfer finished, and the DONE bit is set.
+ So shall configure TCD registers.
+ */
+ }
+ else if (tcdRegs->DLAST_SGA != 0UL)
+ {
+ /* The current TCD block has been linked successfully. */
+ return kStatus_Success;
+ }
+ else
+ {
+ /*
+ DLAST_SGA is 0 and it means the first submit transfer, so shall configure
+ TCD registers.
+ */
+ }
+ }
+ /* There is no live chain, TCD block need to be installed in TCD registers. */
+ EDMA_InstallTCD(handle->base, handle->channel, &handle->tcdPool[currentTcd]);
+ /* Enable channel request again. */
+ if (0U != (handle->flags & EDMA_TRANSFER_ENABLED_MASK))
+ {
+ handle->base->SERQ = DMA_SERQ_SERQ(handle->channel);
+ }
+
+ return kStatus_Success;
+ }
+}
+
+/*!
+ * brief eDMA starts transfer.
+ *
+ * This function enables the channel request. Users can call this function after submitting the transfer request
+ * or before submitting the transfer request.
+ *
+ * param handle eDMA handle pointer.
+ */
+void EDMA_StartTransfer(edma_handle_t *handle)
+{
+ assert(handle != NULL);
+ uint32_t tmpCSR = 0;
+
+ if (handle->tcdPool == NULL)
+ {
+ handle->base->SERQ = DMA_SERQ_SERQ(handle->channel);
+ }
+ else /* Use the TCD queue. */
+ {
+ uint32_t primask;
+ edma_tcd_t *tcdRegs = (edma_tcd_t *)(uint32_t)&handle->base->TCD[handle->channel];
+
+ handle->flags |= EDMA_TRANSFER_ENABLED_MASK;
+
+ /* Check if there was at least one descriptor submitted since reset (TCD in registers is valid) */
+ if (tcdRegs->DLAST_SGA != 0U)
+ {
+ primask = DisableGlobalIRQ();
+ /* Check if channel request is actually disable. */
+ if ((handle->base->ERQ & ((uint32_t)1U << handle->channel)) == 0U)
+ {
+ /* Check if transfer is paused. */
+ tmpCSR = tcdRegs->CSR;
+ if ((0U == (tmpCSR & DMA_CSR_DONE_MASK)) || (0U != (tmpCSR & DMA_CSR_ESG_MASK)))
+ {
+ /*
+ Re-enable channel request must be as soon as possible, so must put it into
+ critical section to avoid task switching or interrupt service routine.
+ */
+ handle->base->SERQ = DMA_SERQ_SERQ(handle->channel);
+ }
+ }
+ EnableGlobalIRQ(primask);
+ }
+ }
+}
+
+/*!
+ * brief eDMA stops transfer.
+ *
+ * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer()
+ * again to resume the transfer.
+ *
+ * param handle eDMA handle pointer.
+ */
+void EDMA_StopTransfer(edma_handle_t *handle)
+{
+ assert(handle != NULL);
+
+ handle->flags &= (~(uint8_t)EDMA_TRANSFER_ENABLED_MASK);
+ handle->base->CERQ = DMA_CERQ_CERQ(handle->channel);
+}
+
+/*!
+ * brief eDMA aborts transfer.
+ *
+ * This function disables the channel request and clear transfer status bits.
+ * Users can submit another transfer after calling this API.
+ *
+ * param handle DMA handle pointer.
+ */
+void EDMA_AbortTransfer(edma_handle_t *handle)
+{
+ handle->base->CERQ = DMA_CERQ_CERQ(handle->channel);
+ /*
+ Clear CSR to release channel. Because if the given channel started transfer,
+ CSR will be not zero. Because if it is the last transfer, DREQ will be set.
+ If not, ESG will be set.
+ */
+ handle->base->TCD[handle->channel].CSR = 0;
+ /* Cancel all next TCD transfer. */
+ handle->base->TCD[handle->channel].DLAST_SGA = 0;
+
+ /* Handle the tcd */
+ if (handle->tcdPool != NULL)
+ {
+ handle->header = 0;
+ handle->tail = 0;
+ handle->tcdUsed = 0;
+ }
+}
+
+/*!
+ * brief eDMA IRQ handler for the current major loop transfer completion.
+ *
+ * This function clears the channel major interrupt flag and calls
+ * the callback function if it is not NULL.
+ *
+ * Note:
+ * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed.
+ * These include the final address adjustments and reloading of the BITER field into the CITER.
+ * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from
+ * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled).
+ *
+ * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine.
+ * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index
+ * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be
+ * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have
+ * been loaded into the eDMA engine at this point already.).
+ *
+ * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not
+ * load a new TCD) from the memory pool to the eDMA engine when major loop completes.
+ * Therefore, ensure that the header and tcdUsed updated are identical for them.
+ * tcdUsed are both 0 in this case as no TCD to be loaded.
+ *
+ * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for
+ * further details.
+ *
+ * param handle eDMA handle pointer.
+ */
+void EDMA_HandleIRQ(edma_handle_t *handle)
+{
+ assert(handle != NULL);
+
+ bool transfer_done;
+
+ /* Clear EDMA interrupt flag */
+ handle->base->CINT = handle->channel;
+ /* Check if transfer is already finished. */
+ transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0U);
+
+ if (handle->tcdPool == NULL)
+ {
+ if (handle->callback != NULL)
+ {
+ (handle->callback)(handle, handle->userData, transfer_done, 0);
+ }
+ }
+ else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */
+ {
+ uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA;
+ uint32_t sga_index;
+ int32_t tcds_done;
+ uint8_t new_header;
+
+ /* Get the offset of the next transfer TCD blocks to be loaded into the eDMA engine. */
+ sga -= (uint32_t)handle->tcdPool;
+ /* Get the index of the next transfer TCD blocks to be loaded into the eDMA engine. */
+ sga_index = sga / sizeof(edma_tcd_t);
+ /* Adjust header positions. */
+ if (transfer_done)
+ {
+ /* New header shall point to the next TCD to be loaded (current one is already finished) */
+ new_header = (uint8_t)sga_index;
+ }
+ else
+ {
+ /* New header shall point to this descriptor currently loaded (not finished yet) */
+ new_header = sga_index != 0U ? (uint8_t)sga_index - 1U : (uint8_t)handle->tcdSize - 1U;
+ }
+ /* Calculate the number of finished TCDs */
+ if (new_header == (uint8_t)handle->header)
+ {
+ int8_t tmpTcdUsed = handle->tcdUsed;
+ int8_t tmpTcdSize = handle->tcdSize;
+
+ if (tmpTcdUsed == tmpTcdSize)
+ {
+ tcds_done = handle->tcdUsed;
+ }
+ else
+ {
+ /* No TCD in the memory are going to be loaded or internal error occurs. */
+ tcds_done = 0;
+ }
+ }
+ else
+ {
+ tcds_done = (int32_t)new_header - (int32_t)handle->header;
+ if (tcds_done < 0)
+ {
+ tcds_done += handle->tcdSize;
+ }
+ }
+ /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */
+ handle->header = (int8_t)new_header;
+ /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */
+ handle->tcdUsed -= (int8_t)tcds_done;
+ /* Invoke callback function. */
+ if (NULL != handle->callback)
+ {
+ (handle->callback)(handle, handle->userData, transfer_done, tcds_done);
+ }
+
+ /* clear the DONE bit here is meaningful for below cases:
+ *1.A new TCD has been loaded to EDMA already:
+ * need to clear the DONE bit in the IRQ handler to avoid TCD in EDMA been overwritten
+ * if peripheral request isn't coming before next transfer request.
+ *2.A new TCD has not been loaded to EDMA:
+ * for the case that transfer request occur in the privious edma callback, this is a case that doesn't
+ * need scatter gather, so keep DONE bit during the next transfer request will re-install the TCD.
+ */
+ if (transfer_done)
+ {
+ handle->base->CDNE = handle->channel;
+ }
+ }
+}
+
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \
+ (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 4)
+/* 8 channels (Shared): kl28 */
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL == 8U)
+
+#if defined(DMA0)
+void DMA0_04_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[0]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[4]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_15_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[1]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[5]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_26_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[2]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[6]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_37_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[3]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[7]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif
+
+#if defined(DMA1)
+
+#if defined(DMA0)
+void DMA1_04_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[8]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[12]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_15_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[9]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[13]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_26_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[10]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[14]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_37_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[11]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[15]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+#else
+void DMA1_04_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[0]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[4]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_15_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[1]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[5]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_26_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[2]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[6]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_37_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[3]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[7]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif
+#endif
+#endif /* 8 channels (Shared) */
+#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */
+
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \
+ (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 8)
+/* 16 channels (Shared): K32H844P */
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U)
+
+void DMA0_08_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[0]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[8]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_19_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[1]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[9]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_210_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[2]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[10]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_311_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[3]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[11]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_412_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[4]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[12]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_513_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[5]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[13]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_614_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[6]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[14]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_715_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[7]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[15]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+#if defined(DMA1)
+void DMA1_08_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[16]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[24]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_19_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[17]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[25]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_210_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[18]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[26]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_311_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[19]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[27]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_412_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[20]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[28]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_513_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[21]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[29]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_614_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[22]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[30]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_715_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[23]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[31]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif
+#endif /* 16 channels (Shared) */
+#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */
+
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \
+ (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 16)
+/* 32 channels (Shared): k80 */
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U
+#if defined(DMA0) && !(defined(DMA1))
+void DMA0_DMA16_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[0]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[16]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_DMA17_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[1]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[17]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA2_DMA18_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[2]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[18]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA3_DMA19_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[3]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[19]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA4_DMA20_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[4]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[20]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA5_DMA21_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[5]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[21]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA6_DMA22_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[6]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[22]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA7_DMA23_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[7]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[23]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA8_DMA24_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[8]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[24]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA9_DMA25_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[9]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[25]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA10_DMA26_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[10]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[26]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA11_DMA27_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[11]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[27]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA12_DMA28_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[12]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[28]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA13_DMA29_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[13]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[29]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA14_DMA30_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[14]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[30]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA15_DMA31_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[15]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[31]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+#else
+void DMA0_0_16_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[0]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[16]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_1_17_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[1]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[17]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_2_18_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[2]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[18]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_3_19_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[3]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[19]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_4_20_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[4]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[20]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_5_21_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[5]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[21]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_6_22_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[6]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[22]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_7_23_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[7]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[23]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_8_24_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[8]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[24]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_9_25_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[9]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[25]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_10_26_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[10]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[26]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_11_27_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[11]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[27]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_12_28_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[12]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[28]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_13_29_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[13]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[29]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_14_30_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[14]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[30]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_15_31_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[15]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[31]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_0_16_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[32]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 16U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[48]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_1_17_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[33]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 17U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[49]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_2_18_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[34]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 18U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[50]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_3_19_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[35]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 19U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[51]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_4_20_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[36]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 20U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[52]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_5_21_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[37]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 21U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[53]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_6_22_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[38]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 22U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[54]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_7_23_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[39]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 23U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[55]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_8_24_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[40]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 24U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[56]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_9_25_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[41]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 25U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[57]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_10_26_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[42]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 26U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[58]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_11_27_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[43]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 27U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[59]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_12_28_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[44]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 28U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[60]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_13_29_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[45]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 29U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[61]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_14_30_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[46]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 30U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[62]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_15_31_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[47]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA1, 31U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[63]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+#endif
+#endif /* 32 channels (Shared) */
+#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */
+
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \
+ (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 4)
+/* 32 channels (Shared): MCIMX7U5_M4 */
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U)
+
+void DMA0_0_4_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[0]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[4]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_1_5_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[1]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[5]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_2_6_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[2]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[6]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_3_7_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[3]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[7]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_8_12_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[8]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[12]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_9_13_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[9]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[13]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_10_14_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[10]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[14]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_11_15_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[11]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[15]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_16_20_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[16]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[20]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_17_21_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[17]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[21]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_18_22_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[18]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[22]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_19_23_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[19]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[23]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_24_28_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[24]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[28]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_25_29_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[25]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[29]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_26_30_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[26]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[30]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA0_27_31_DriverIRQHandler(void)
+{
+ if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[27]);
+ }
+ if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & (uint32_t)kEDMA_InterruptFlag) != 0U)
+ {
+ EDMA_HandleIRQ(s_EDMAHandle[31]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif /* 32 channels (Shared): MCIMX7U5 */
+#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */
+
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \
+ (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 0)
+/* 4 channels (No Shared): kv10 */
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL > 0)
+
+void DMA0_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[0]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA1_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[1]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA2_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[2]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA3_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[3]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+/* 8 channels (No Shared) */
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL > 4U)
+
+void DMA4_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[4]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA5_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[5]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA6_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[6]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA7_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[7]);
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 8 */
+
+/* 16 channels (No Shared) */
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL > 8U)
+
+void DMA8_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[8]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA9_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[9]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA10_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[10]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA11_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[11]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA12_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[12]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA13_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[13]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA14_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[14]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA15_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[15]);
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 16 */
+
+/* 32 channels (No Shared) */
+#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL > 16U)
+
+void DMA16_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[16]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA17_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[17]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA18_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[18]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA19_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[19]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA20_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[20]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA21_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[21]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA22_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[22]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA23_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[23]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA24_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[24]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA25_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[25]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA26_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[26]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA27_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[27]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA28_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[28]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA29_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[29]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA30_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[30]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void DMA31_DriverIRQHandler(void)
+{
+ EDMA_HandleIRQ(s_EDMAHandle[31]);
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 32 */
+
+#endif /* 4/8/16/32 channels (No Shared) */
+#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_elcdif.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_elcdif.c
new file mode 100644
index 0000000000..ab9f63f912
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_elcdif.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2017-2019 NXP
+ * All rights reserved.
+ *
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_elcdif.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.elcdif"
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief Get instance number for ELCDIF module.
+ *
+ * @param base ELCDIF peripheral base address
+ */
+static uint32_t ELCDIF_GetInstance(LCDIF_Type *base);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Pointers to ELCDIF bases for each instance. */
+static LCDIF_Type *const s_elcdifBases[] = LCDIF_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to eLCDIF apb_clk for each instance. */
+static const clock_ip_name_t s_elcdifApbClocks[] = LCDIF_CLOCKS;
+#if defined(LCDIF_PERIPH_CLOCKS)
+/*! @brief Pointers to eLCDIF pix_clk for each instance. */
+static const clock_ip_name_t s_elcdifPixClocks[] = LCDIF_PERIPH_CLOCKS;
+#endif
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*! @brief The control register value to select different pixel format. */
+static const elcdif_pixel_format_reg_t s_pixelFormatReg[] = {
+ /* kELCDIF_PixelFormatRAW8 */
+ {/* Register CTRL. */
+ LCDIF_CTRL_WORD_LENGTH(1U),
+ /* Register CTRL1. */
+ LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
+ /* kELCDIF_PixelFormatRGB565 */
+ {/* Register CTRL. */
+ LCDIF_CTRL_WORD_LENGTH(0U),
+ /* Register CTRL1. */
+ LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
+ /* kELCDIF_PixelFormatRGB666 */
+ {/* Register CTRL. */
+ LCDIF_CTRL_WORD_LENGTH(3U) | LCDIF_CTRL_DATA_FORMAT_24_BIT(1U),
+ /* Register CTRL1. */
+ LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)},
+ /* kELCDIF_PixelFormatXRGB8888 */
+ {/* Register CTRL. 24-bit. */
+ LCDIF_CTRL_WORD_LENGTH(3U),
+ /* Register CTRL1. */
+ LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)},
+ /* kELCDIF_PixelFormatRGB888 */
+ {/* Register CTRL. 24-bit. */
+ LCDIF_CTRL_WORD_LENGTH(3U),
+ /* Register CTRL1. */
+ LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)},
+};
+
+/*******************************************************************************
+ * Codes
+ ******************************************************************************/
+static uint32_t ELCDIF_GetInstance(LCDIF_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_elcdifBases); instance++)
+ {
+ if (s_elcdifBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_elcdifBases));
+
+ return instance;
+}
+
+/*!
+ * brief Initializes the eLCDIF to work in RGB mode (DOTCLK mode).
+ *
+ * This function ungates the eLCDIF clock and configures the eLCDIF peripheral according
+ * to the configuration structure.
+ *
+ * param base eLCDIF peripheral base address.
+ * param config Pointer to the configuration structure.
+ */
+void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config)
+{
+ assert(NULL != config);
+ assert((uint32_t)config->pixelFormat < ARRAY_SIZE(s_pixelFormatReg));
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ uint32_t instance = ELCDIF_GetInstance(base);
+ /* Enable the clock. */
+ CLOCK_EnableClock(s_elcdifApbClocks[instance]);
+#if defined(LCDIF_PERIPH_CLOCKS)
+ CLOCK_EnableClock(s_elcdifPixClocks[instance]);
+#endif
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+ /* Reset. */
+ ELCDIF_Reset(base);
+
+ base->CTRL = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl | (uint32_t)(config->dataBus) |
+ LCDIF_CTRL_DOTCLK_MODE_MASK | /* RGB mode. */
+ LCDIF_CTRL_BYPASS_COUNT_MASK | /* Keep RUN bit set. */
+ LCDIF_CTRL_MASTER_MASK;
+
+ base->CTRL1 = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl1;
+
+ base->TRANSFER_COUNT = ((uint32_t)config->panelHeight << LCDIF_TRANSFER_COUNT_V_COUNT_SHIFT) |
+ ((uint32_t)config->panelWidth << LCDIF_TRANSFER_COUNT_H_COUNT_SHIFT);
+
+ base->VDCTRL0 = LCDIF_VDCTRL0_ENABLE_PRESENT_MASK | /* Data enable signal. */
+ LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT_MASK | /* VSYNC period in the unit of display clock. */
+ LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT_MASK | /* VSYNC pulse width in the unit of display clock. */
+ (uint32_t)config->polarityFlags | (uint32_t)config->vsw;
+
+ base->VDCTRL1 =
+ (uint32_t)config->vsw + (uint32_t)config->panelHeight + (uint32_t)config->vfp + (uint32_t)config->vbp;
+ base->VDCTRL2 =
+ ((uint32_t)config->hsw << LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_SHIFT) |
+ (((uint32_t)config->hfp + (uint32_t)config->hbp + (uint32_t)config->panelWidth + (uint32_t)config->hsw))
+ << LCDIF_VDCTRL2_HSYNC_PERIOD_SHIFT;
+
+ base->VDCTRL3 = (((uint32_t)config->hbp + config->hsw) << LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_SHIFT) |
+ (((uint32_t)config->vbp + config->vsw) << LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_SHIFT);
+
+ base->VDCTRL4 = LCDIF_VDCTRL4_SYNC_SIGNALS_ON_MASK |
+ ((uint32_t)config->panelWidth << LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_SHIFT);
+
+ base->CUR_BUF = config->bufferAddr;
+ base->NEXT_BUF = config->bufferAddr;
+}
+
+/*!
+ * brief Gets the eLCDIF default configuration structure for RGB (DOTCLK) mode.
+ *
+ * This function sets the configuration structure to default values.
+ * The default configuration is set to the following values.
+ * code
+ config->panelWidth = 480U;
+ config->panelHeight = 272U;
+ config->hsw = 41;
+ config->hfp = 4;
+ config->hbp = 8;
+ config->vsw = 10;
+ config->vfp = 4;
+ config->vbp = 2;
+ config->polarityFlags = kELCDIF_VsyncActiveLow |
+ kELCDIF_HsyncActiveLow |
+ kELCDIF_DataEnableActiveLow |
+ kELCDIF_DriveDataOnFallingClkEdge;
+ config->bufferAddr = 0U;
+ config->pixelFormat = kELCDIF_PixelFormatRGB888;
+ config->dataBus = kELCDIF_DataBus24Bit;
+ code
+ *
+ * param config Pointer to the eLCDIF configuration structure.
+ */
+void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config)
+{
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->panelWidth = 480U;
+ config->panelHeight = 272U;
+ config->hsw = 41;
+ config->hfp = 4;
+ config->hbp = 8;
+ config->vsw = 10;
+ config->vfp = 4;
+ config->vbp = 2;
+ config->polarityFlags = (uint32_t)kELCDIF_VsyncActiveLow | (uint32_t)kELCDIF_HsyncActiveLow |
+ (uint32_t)kELCDIF_DataEnableActiveLow | (uint32_t)kELCDIF_DriveDataOnFallingClkEdge;
+ config->bufferAddr = 0U;
+ config->pixelFormat = kELCDIF_PixelFormatRGB888;
+ config->dataBus = kELCDIF_DataBus24Bit;
+}
+
+/*!
+ * brief Set the pixel format in RGB (DOTCLK) mode.
+ *
+ * param base eLCDIF peripheral base address.
+ * param pixelFormat The pixel format.
+ */
+void ELCDIF_RgbModeSetPixelFormat(LCDIF_Type *base, elcdif_pixel_format_t pixelFormat)
+{
+ assert((uint32_t)pixelFormat < ARRAY_SIZE(s_pixelFormatReg));
+
+ base->CTRL = (base->CTRL & ~(LCDIF_CTRL_WORD_LENGTH_MASK | LCDIF_CTRL_DATA_FORMAT_24_BIT_MASK |
+ LCDIF_CTRL_DATA_FORMAT_18_BIT_MASK | LCDIF_CTRL_DATA_FORMAT_16_BIT_MASK)) |
+ s_pixelFormatReg[(uint32_t)pixelFormat].regCtrl;
+
+ base->CTRL1 = s_pixelFormatReg[(uint32_t)pixelFormat].regCtrl1;
+}
+
+/*!
+ * brief Deinitializes the eLCDIF peripheral.
+ *
+ * param base eLCDIF peripheral base address.
+ */
+void ELCDIF_Deinit(LCDIF_Type *base)
+{
+ ELCDIF_Reset(base);
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ uint32_t instance = ELCDIF_GetInstance(base);
+/* Disable the clock. */
+#if defined(LCDIF_PERIPH_CLOCKS)
+ CLOCK_DisableClock(s_elcdifPixClocks[instance]);
+#endif
+ CLOCK_DisableClock(s_elcdifApbClocks[instance]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Stop display in RGB (DOTCLK) mode and wait until finished.
+ *
+ * param base eLCDIF peripheral base address.
+ */
+void ELCDIF_RgbModeStop(LCDIF_Type *base)
+{
+ base->CTRL_CLR = LCDIF_CTRL_DOTCLK_MODE_MASK;
+
+ /* Wait for data transfer finished. */
+ while (0U != (base->CTRL & LCDIF_CTRL_DOTCLK_MODE_MASK))
+ {
+ }
+}
+
+/*!
+ * brief Reset the eLCDIF peripheral.
+ *
+ * param base eLCDIF peripheral base address.
+ */
+void ELCDIF_Reset(LCDIF_Type *base)
+{
+ /*
+ * ELCDIF reset workflow:
+ *
+ * 1. Ungate clock.
+ * 2. Trigger the software reset.
+ * 3. The software reset finished when clk_gate bit is set.
+ * 4. Ungate the clock.
+ * 5. Release the reset.
+ */
+
+ /* Ungate clock. */
+ base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK;
+
+ /*
+ * If already in reset state, release the reset.
+ * If not, trigger reset.
+ */
+ if (0U == (base->CTRL & LCDIF_CTRL_SFTRST_MASK))
+ {
+ /* Trigger reset. */
+ base->CTRL_SET = LCDIF_CTRL_SFTRST_MASK;
+
+ /* Reset is not finished until CLK_GATE is set. */
+ while (0U == (base->CTRL & LCDIF_CTRL_CLKGATE_MASK))
+ {
+ }
+
+ /* Ungate the clock. */
+ base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK;
+ }
+
+ /* Release the reset. */
+ base->CTRL_CLR = LCDIF_CTRL_SFTRST_MASK;
+}
+
+#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS)
+/*!
+ * brief Set the configuration for alpha surface buffer.
+ *
+ * param base eLCDIF peripheral base address.
+ * param config Pointer to the configuration structure.
+ */
+void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config)
+{
+ assert(NULL != config);
+
+ base->AS_CTRL = (base->AS_CTRL & ~LCDIF_AS_CTRL_FORMAT_MASK) | LCDIF_AS_CTRL_FORMAT(config->pixelFormat);
+ base->AS_BUF = config->bufferAddr;
+ base->AS_NEXT_BUF = config->bufferAddr;
+}
+
+/*!
+ * brief Set the alpha surface blending configuration.
+ *
+ * param base eLCDIF peripheral base address.
+ * param config Pointer to the configuration structure.
+ */
+void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config)
+{
+ assert(NULL != config);
+ uint32_t reg;
+
+ reg = base->AS_CTRL;
+ reg &= ~(LCDIF_AS_CTRL_ALPHA_INVERT_MASK | LCDIF_AS_CTRL_ROP_MASK | LCDIF_AS_CTRL_ALPHA_MASK |
+ LCDIF_AS_CTRL_ALPHA_CTRL_MASK);
+ reg |= (LCDIF_AS_CTRL_ROP(config->ropMode) | LCDIF_AS_CTRL_ALPHA(config->alpha) |
+ LCDIF_AS_CTRL_ALPHA_CTRL(config->alphaMode));
+
+ if (config->invertAlpha)
+ {
+ reg |= LCDIF_AS_CTRL_ALPHA_INVERT_MASK;
+ }
+
+ base->AS_CTRL = reg;
+}
+#endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */
+
+#if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && FSL_FEATURE_LCDIF_HAS_LUT)
+/*!
+ * brief Load the LUT value.
+ *
+ * This function loads the LUT value to the specific LUT memory, user can
+ * specify the start entry index.
+ *
+ * param base eLCDIF peripheral base address.
+ * param lut Which LUT to load.
+ * param startIndex The start index of the LUT entry to update.
+ * param lutData The LUT data to load.
+ * param count Count of p lutData.
+ * retval kStatus_Success Initialization success.
+ * retval kStatus_InvalidArgument Wrong argument.
+ */
+status_t ELCDIF_UpdateLut(
+ LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count)
+{
+ volatile uint32_t *regLutAddr;
+ volatile uint32_t *regLutData;
+ uint32_t i;
+ status_t status;
+
+ /* Only has 256 entries. */
+ if (startIndex + count > ELCDIF_LUT_ENTRY_NUM)
+ {
+ status = kStatus_InvalidArgument;
+ }
+ else
+ {
+ if (kELCDIF_Lut0 == lut)
+ {
+ regLutAddr = &(base->LUT0_ADDR);
+ regLutData = &(base->LUT0_DATA);
+ }
+ else
+ {
+ regLutAddr = &(base->LUT1_ADDR);
+ regLutData = &(base->LUT1_DATA);
+ }
+
+ *regLutAddr = startIndex;
+
+ for (i = 0; i < count; i++)
+ {
+ *regLutData = lutData[i];
+ }
+
+ status = kStatus_Success;
+ }
+
+ return status;
+}
+#endif /* FSL_FEATURE_LCDIF_HAS_LUT */
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enc.c
new file mode 100644
index 0000000000..8117df1332
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enc.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2019 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_enc.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.enc"
+#endif
+
+#define ENC_CTRL_W1C_FLAGS (ENC_CTRL_HIRQ_MASK | ENC_CTRL_XIRQ_MASK | ENC_CTRL_DIRQ_MASK | ENC_CTRL_CMPIRQ_MASK)
+#define ENC_CTRL2_W1C_FLAGS (ENC_CTRL2_SABIRQ_MASK | ENC_CTRL2_ROIRQ_MASK | ENC_CTRL2_RUIRQ_MASK)
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+/*!
+ * @brief Get instance number for ENC module.
+ *
+ * @param base ENC peripheral base address
+ */
+static uint32_t ENC_GetInstance(ENC_Type *base);
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+/*! @brief Pointers to ENC bases for each instance. */
+static ENC_Type *const s_encBases[] = ENC_BASE_PTRS;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+/*! @brief Pointers to ENC clocks for each instance. */
+static const clock_ip_name_t s_encClocks[] = ENC_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+static uint32_t ENC_GetInstance(ENC_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_encBases); instance++)
+ {
+ if (s_encBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_encBases));
+
+ return instance;
+}
+
+/*!
+ * brief Initialization for the ENC module.
+ *
+ * This function is to make the initialization for the ENC module. It should be called firstly before any operation to
+ * the ENC with the operations like:
+ * - Enable the clock for ENC module.
+ * - Configure the ENC's working attributes.
+ *
+ * param base ENC peripheral base address.
+ * param config Pointer to configuration structure. See to "enc_config_t".
+ */
+void ENC_Init(ENC_Type *base, const enc_config_t *config)
+{
+ assert(NULL != config);
+
+ uint16_t tmp16;
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Enable the clock. */
+ CLOCK_EnableClock(s_encClocks[ENC_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+ /* ENC_CTRL. */
+ tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_HIP_MASK | ENC_CTRL_HNE_MASK | ENC_CTRL_REV_MASK |
+ ENC_CTRL_PH1_MASK | ENC_CTRL_XIP_MASK | ENC_CTRL_XNE_MASK | ENC_CTRL_WDE_MASK));
+ /* For HOME trigger. */
+ if (kENC_HOMETriggerDisabled != config->HOMETriggerMode)
+ {
+ tmp16 |= ENC_CTRL_HIP_MASK;
+ if (kENC_HOMETriggerOnFallingEdge == config->HOMETriggerMode)
+ {
+ tmp16 |= ENC_CTRL_HNE_MASK;
+ }
+ }
+ /* For encoder work mode. */
+ if (config->enableReverseDirection)
+ {
+ tmp16 |= ENC_CTRL_REV_MASK;
+ }
+ if (kENC_DecoderWorkAsSignalPhaseCountMode == config->decoderWorkMode)
+ {
+ tmp16 |= ENC_CTRL_PH1_MASK;
+ }
+ /* For INDEX trigger. */
+ if (kENC_INDEXTriggerDisabled != config->INDEXTriggerMode)
+ {
+ tmp16 |= ENC_CTRL_XIP_MASK;
+ if (kENC_INDEXTriggerOnFallingEdge == config->INDEXTriggerMode)
+ {
+ tmp16 |= ENC_CTRL_XNE_MASK;
+ }
+ }
+ /* Watchdog. */
+ if (config->enableWatchdog)
+ {
+ tmp16 |= ENC_CTRL_WDE_MASK;
+ base->WTR = config->watchdogTimeoutValue; /* WDOG can be only available when the feature is enabled. */
+ }
+ base->CTRL = tmp16;
+
+ /* ENC_FILT. */
+ base->FILT = ENC_FILT_FILT_CNT(config->filterCount) | ENC_FILT_FILT_PER(config->filterSamplePeriod);
+
+ /* ENC_CTRL2. */
+ tmp16 = base->CTRL2 & (uint16_t)(~(ENC_CTRL2_W1C_FLAGS | ENC_CTRL2_OUTCTL_MASK | ENC_CTRL2_REVMOD_MASK |
+ ENC_CTRL2_MOD_MASK | ENC_CTRL2_UPDPOS_MASK | ENC_CTRL2_UPDHLD_MASK));
+ if (kENC_POSMATCHOnReadingAnyPositionCounter == config->positionMatchMode)
+ {
+ tmp16 |= ENC_CTRL2_OUTCTL_MASK;
+ }
+ if (kENC_RevolutionCountOnRollOverModulus == config->revolutionCountCondition)
+ {
+ tmp16 |= ENC_CTRL2_REVMOD_MASK;
+ }
+ if (config->enableModuloCountMode)
+ {
+ tmp16 |= ENC_CTRL2_MOD_MASK;
+ /* Set modulus value. */
+ base->UMOD = (uint16_t)(config->positionModulusValue >> 16U); /* Upper 16 bits. */
+ base->LMOD = (uint16_t)(config->positionModulusValue); /* Lower 16 bits. */
+ }
+ if (config->enableTRIGGERClearPositionCounter)
+ {
+ tmp16 |= ENC_CTRL2_UPDPOS_MASK;
+ }
+ if (config->enableTRIGGERClearHoldPositionCounter)
+ {
+ tmp16 |= ENC_CTRL2_UPDHLD_MASK;
+ }
+ base->CTRL2 = tmp16;
+
+ /* ENC_UCOMP & ENC_LCOMP. */
+ base->UCOMP = (uint16_t)(config->positionCompareValue >> 16U); /* Upper 16 bits. */
+ base->LCOMP = (uint16_t)(config->positionCompareValue); /* Lower 16 bits. */
+
+ /* ENC_UINIT & ENC_LINIT. */
+ base->UINIT = (uint16_t)(config->positionInitialValue >> 16U); /* Upper 16 bits. */
+ base->LINIT = (uint16_t)(config->positionInitialValue); /* Lower 16 bits. */
+}
+
+/*!
+ * brief De-initialization for the ENC module.
+ *
+ * This function is to make the de-initialization for the ENC module. It could be called when ENC is no longer used with
+ * the operations like:
+ * - Disable the clock for ENC module.
+ *
+ * param base ENC peripheral base address.
+ */
+void ENC_Deinit(ENC_Type *base)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Disable the clock. */
+ CLOCK_DisableClock(s_encClocks[ENC_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Get an available pre-defined settings for ENC's configuration.
+ *
+ * This function initializes the ENC configuration structure with an available settings, the default value are:
+ * code
+ * config->enableReverseDirection = false;
+ * config->decoderWorkMode = kENC_DecoderWorkAsNormalMode;
+ * config->HOMETriggerMode = kENC_HOMETriggerDisabled;
+ * config->INDEXTriggerMode = kENC_INDEXTriggerDisabled;
+ * config->enableTRIGGERClearPositionCounter = false;
+ * config->enableTRIGGERClearHoldPositionCounter = false;
+ * config->enableWatchdog = false;
+ * config->watchdogTimeoutValue = 0U;
+ * config->filterCount = 0U;
+ * config->filterSamplePeriod = 0U;
+ * config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue;
+ * config->positionCompareValue = 0xFFFFFFFFU;
+ * config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse;
+ * config->enableModuloCountMode = false;
+ * config->positionModulusValue = 0U;
+ * config->positionInitialValue = 0U;
+ * endcode
+ * param config Pointer to a variable of configuration structure. See to "enc_config_t".
+ */
+void ENC_GetDefaultConfig(enc_config_t *config)
+{
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->enableReverseDirection = false;
+ config->decoderWorkMode = kENC_DecoderWorkAsNormalMode;
+ config->HOMETriggerMode = kENC_HOMETriggerDisabled;
+ config->INDEXTriggerMode = kENC_INDEXTriggerDisabled;
+ config->enableTRIGGERClearPositionCounter = false;
+ config->enableTRIGGERClearHoldPositionCounter = false;
+ config->enableWatchdog = false;
+ config->watchdogTimeoutValue = 0U;
+ config->filterCount = 0U;
+ config->filterSamplePeriod = 0U;
+ config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue;
+ config->positionCompareValue = 0xFFFFFFFFU;
+ config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse;
+ config->enableModuloCountMode = false;
+ config->positionModulusValue = 0U;
+ config->positionInitialValue = 0U;
+}
+
+/*!
+ * brief Load the initial position value to position counter.
+ *
+ * This function is to transfer the initial position value (UINIT and LINIT) contents to position counter (UPOS and
+ * LPOS), so that to provide the consistent operation the position counter registers.
+ *
+ * param base ENC peripheral base address.
+ */
+void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base)
+{
+ uint16_t tmp16 = base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS);
+
+ tmp16 |= ENC_CTRL_SWIP_MASK; /* Write 1 to trigger the command for loading initial position value. */
+ base->CTRL = tmp16;
+}
+
+/*!
+ * brief Enable and configure the self test function.
+ *
+ * This function is to enable and configuration the self test function. It controls and sets the frequency of a
+ * quadrature signal generator. It provides a quadrature test signal to the inputs of the quadrature decoder module.
+ * It is a factory test feature; however, it may be useful to customers' software development and testing.
+ *
+ * param base ENC peripheral base address.
+ * param config Pointer to configuration structure. See to "enc_self_test_config_t". Pass "NULL" to disable.
+ */
+void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config)
+{
+ uint16_t tmp16 = 0U;
+
+ if (NULL == config) /* Pass "NULL" to disable the feature. */
+ {
+ tmp16 = 0U;
+ }
+ else
+ {
+ tmp16 = ENC_TST_TEN_MASK | ENC_TST_TCE_MASK | ENC_TST_TEST_PERIOD(config->signalPeriod) |
+ ENC_TST_TEST_COUNT(config->signalCount);
+ if (kENC_SelfTestDirectionNegative == config->signalDirection)
+ {
+ tmp16 |= ENC_TST_QDN_MASK;
+ }
+ }
+
+ base->TST = tmp16;
+}
+
+/*!
+ * brief Enable watchdog for ENC module.
+ *
+ * param base ENC peripheral base address
+ * param enable Enables or disables the watchdog
+ */
+void ENC_EnableWatchdog(ENC_Type *base, bool enable)
+{
+ uint16_t tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_WDE_MASK));
+
+ if (enable)
+ {
+ tmp16 |= ENC_CTRL_WDE_MASK;
+ }
+ base->CTRL = tmp16;
+}
+
+/*!
+ * brief Get the status flags.
+ *
+ * param base ENC peripheral base address.
+ *
+ * return Mask value of status flags. For available mask, see to "_enc_status_flags".
+ */
+uint32_t ENC_GetStatusFlags(ENC_Type *base)
+{
+ uint32_t ret32 = 0U;
+
+ /* ENC_CTRL. */
+ if (0U != (ENC_CTRL_HIRQ_MASK & base->CTRL))
+ {
+ ret32 |= (uint32_t)kENC_HOMETransitionFlag;
+ }
+ if (0U != (ENC_CTRL_XIRQ_MASK & base->CTRL))
+ {
+ ret32 |= (uint32_t)kENC_INDEXPulseFlag;
+ }
+ if (0U != (ENC_CTRL_DIRQ_MASK & base->CTRL))
+ {
+ ret32 |= (uint32_t)kENC_WatchdogTimeoutFlag;
+ }
+ if (0U != (ENC_CTRL_CMPIRQ_MASK & base->CTRL))
+ {
+ ret32 |= (uint32_t)kENC_PositionCompareFlag;
+ }
+
+ /* ENC_CTRL2. */
+ if (0U != (ENC_CTRL2_SABIRQ_MASK & base->CTRL2))
+ {
+ ret32 |= (uint32_t)kENC_SimultBothPhaseChangeFlag;
+ }
+ if (0U != (ENC_CTRL2_ROIRQ_MASK & base->CTRL2))
+ {
+ ret32 |= (uint32_t)kENC_PositionRollOverFlag;
+ }
+ if (0U != (ENC_CTRL2_RUIRQ_MASK & base->CTRL2))
+ {
+ ret32 |= (uint32_t)kENC_PositionRollUnderFlag;
+ }
+ if (0U != (ENC_CTRL2_DIR_MASK & base->CTRL2))
+ {
+ ret32 |= (uint32_t)kENC_LastCountDirectionFlag;
+ }
+
+ return ret32;
+}
+
+/*!
+ * brief Clear the status flags.
+ *
+ * param base ENC peripheral base address.
+ * param mask Mask value of status flags to be cleared. For available mask, see to "_enc_status_flags".
+ */
+void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask)
+{
+ uint32_t tmp16 = 0U;
+
+ /* ENC_CTRL. */
+ if (0U != ((uint32_t)kENC_HOMETransitionFlag & mask))
+ {
+ tmp16 |= ENC_CTRL_HIRQ_MASK;
+ }
+ if (0U != ((uint32_t)kENC_INDEXPulseFlag & mask))
+ {
+ tmp16 |= ENC_CTRL_XIRQ_MASK;
+ }
+ if (0U != ((uint32_t)kENC_WatchdogTimeoutFlag & mask))
+ {
+ tmp16 |= ENC_CTRL_DIRQ_MASK;
+ }
+ if (0U != ((uint32_t)kENC_PositionCompareFlag & mask))
+ {
+ tmp16 |= ENC_CTRL_CMPIRQ_MASK;
+ }
+ if (0U != tmp16)
+ {
+ base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16);
+ }
+
+ /* ENC_CTRL2. */
+ tmp16 = 0U;
+ if (0U != ((uint32_t)kENC_SimultBothPhaseChangeFlag & mask))
+ {
+ tmp16 |= ENC_CTRL2_SABIRQ_MASK;
+ }
+ if (0U != ((uint32_t)kENC_PositionRollOverFlag & mask))
+ {
+ tmp16 |= ENC_CTRL2_ROIRQ_MASK;
+ }
+ if (0U != ((uint32_t)kENC_PositionRollUnderFlag & mask))
+ {
+ tmp16 |= ENC_CTRL2_RUIRQ_MASK;
+ }
+ if (0U != tmp16)
+ {
+ base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16);
+ }
+}
+
+/*!
+ * brief Enable the interrupts.
+ *
+ * param base ENC peripheral base address.
+ * param mask Mask value of interrupts to be enabled. For available mask, see to "_enc_interrupt_enable".
+ */
+void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask)
+{
+ uint32_t tmp16 = 0U;
+
+ /* ENC_CTRL. */
+ if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL_HIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL_XIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL_DIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL_CMPIE_MASK;
+ }
+ if (tmp16 != 0U)
+ {
+ base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16);
+ }
+ /* ENC_CTRL2. */
+ tmp16 = 0U;
+ if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL2_SABIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL2_ROIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL2_RUIE_MASK;
+ }
+ if (tmp16 != 0U)
+ {
+ base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16);
+ }
+}
+
+/*!
+ * brief Disable the interrupts.
+ *
+ * param base ENC peripheral base address.
+ * param mask Mask value of interrupts to be disabled. For available mask, see to "_enc_interrupt_enable".
+ */
+void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask)
+{
+ uint16_t tmp16 = 0U;
+
+ /* ENC_CTRL. */
+ if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL_HIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL_XIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL_DIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL_CMPIE_MASK;
+ }
+ if (0U != tmp16)
+ {
+ base->CTRL = (uint16_t)(base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS)) & (uint16_t)(~tmp16);
+ }
+ /* ENC_CTRL2. */
+ tmp16 = 0U;
+ if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL2_SABIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL2_ROIE_MASK;
+ }
+ if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask))
+ {
+ tmp16 |= ENC_CTRL2_RUIE_MASK;
+ }
+ if (tmp16 != 0U)
+ {
+ base->CTRL2 = (uint16_t)(base->CTRL2 & (uint16_t)(~ENC_CTRL2_W1C_FLAGS)) & (uint16_t)(~tmp16);
+ }
+}
+
+/*!
+ * brief Get the enabled interrupts' flags.
+ *
+ * param base ENC peripheral base address.
+ *
+ * return Mask value of enabled interrupts.
+ */
+uint32_t ENC_GetEnabledInterrupts(ENC_Type *base)
+{
+ uint32_t ret32 = 0U;
+
+ /* ENC_CTRL. */
+ if (0U != (ENC_CTRL_HIE_MASK & base->CTRL))
+ {
+ ret32 |= (uint32_t)kENC_HOMETransitionInterruptEnable;
+ }
+ if (0U != (ENC_CTRL_XIE_MASK & base->CTRL))
+ {
+ ret32 |= (uint32_t)kENC_INDEXPulseInterruptEnable;
+ }
+ if (0U != (ENC_CTRL_DIE_MASK & base->CTRL))
+ {
+ ret32 |= (uint32_t)kENC_WatchdogTimeoutInterruptEnable;
+ }
+ if (0U != (ENC_CTRL_CMPIE_MASK & base->CTRL))
+ {
+ ret32 |= (uint32_t)kENC_PositionCompareInerruptEnable;
+ }
+ /* ENC_CTRL2. */
+ if (0U != (ENC_CTRL2_SABIE_MASK & base->CTRL2))
+ {
+ ret32 |= (uint32_t)kENC_SimultBothPhaseChangeInterruptEnable;
+ }
+ if (0U != (ENC_CTRL2_ROIE_MASK & base->CTRL2))
+ {
+ ret32 |= (uint32_t)kENC_PositionRollOverInterruptEnable;
+ }
+ if (0U != (ENC_CTRL2_RUIE_MASK & base->CTRL2))
+ {
+ ret32 |= (uint32_t)kENC_PositionRollUnderInterruptEnable;
+ }
+ return ret32;
+}
+
+/*!
+ * brief Set initial position value for ENC module.
+ *
+ * param base ENC peripheral base address
+ * param value Positive initial value
+ */
+void ENC_SetInitialPositionValue(ENC_Type *base, uint32_t value)
+{
+ base->UINIT = (uint16_t)(value >> 16U); /* Set upper 16 bits. */
+ base->LINIT = (uint16_t)(value); /* Set lower 16 bits. */
+}
+
+/*!
+ * brief Get the current position counter's value.
+ *
+ * param base ENC peripheral base address.
+ *
+ * return Current position counter's value.
+ */
+uint32_t ENC_GetPositionValue(ENC_Type *base)
+{
+ uint32_t ret32;
+
+ ret32 = base->UPOS; /* Get upper 16 bits and make a snapshot. */
+ ret32 <<= 16U;
+ ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */
+
+ return ret32;
+}
+
+/*!
+ * brief Get the hold position counter's value.
+ *
+ * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold
+ * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to
+ * be attained.
+ *
+ * param base ENC peripheral base address.
+ *
+ * return Hold position counter's value.
+ */
+uint32_t ENC_GetHoldPositionValue(ENC_Type *base)
+{
+ uint32_t ret32;
+
+ ret32 = base->UPOSH; /* Get upper 16 bits and make a snapshot. */
+ ret32 <<= 16U;
+ ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */
+
+ return ret32;
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enet.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enet.c
new file mode 100644
index 0000000000..2e9d229a18
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enet.c
@@ -0,0 +1,3389 @@
+/*
+ * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2020 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_enet.h"
+#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
+#include "fsl_cache.h"
+#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.enet"
+#endif
+
+/*! @brief Ethernet mac address length. */
+#define ENET_FRAME_MACLEN 6U
+/*! @brief Ethernet VLAN header length. */
+#define ENET_FRAME_VLAN_TAGLEN 4U
+/*! @brief MDC frequency. */
+#define ENET_MDC_FREQUENCY 2500000U
+/*! @brief NanoSecond in one second. */
+#define ENET_NANOSECOND_ONE_SECOND 1000000000U
+/*! @brief Define a common clock cycle delays used for time stamp capture. */
+#ifndef ENET_1588TIME_DELAY_COUNT
+#define ENET_1588TIME_DELAY_COUNT 10U
+#endif
+
+/*! @brief Define the ENET ring/class bumber . */
+enum
+{
+ kENET_Ring0 = 0U, /*!< ENET ring/class 0. */
+#if FSL_FEATURE_ENET_QUEUE > 1
+ kENET_Ring1 = 1U, /*!< ENET ring/class 1. */
+ kENET_Ring2 = 2U /*!< ENET ring/class 2. */
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+};
+
+/*******************************************************************************
+ * Variables
+ ******************************************************************************/
+
+/*! @brief Pointers to enet clocks for each instance. */
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+const clock_ip_name_t s_enetClock[] = ENET_CLOCKS;
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*! @brief Pointers to enet transmit IRQ number for each instance. */
+static const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS;
+/*! @brief Pointers to enet receive IRQ number for each instance. */
+static const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS;
+#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+/*! @brief Pointers to enet timestamp IRQ number for each instance. */
+static const IRQn_Type s_enetTsIrqId[] = ENET_1588_Timer_IRQS;
+#if (FSL_FEATURE_ENET_QUEUE > 1) && defined(ENET_1G)
+/*! @brief Pointers to enet 1588 timestamp IRQ number for each instance. */
+static const IRQn_Type s_enet1588TimerIrqId[] = ENET_1588_Timer_IRQS;
+#endif
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+/*! @brief Pointers to enet error IRQ number for each instance. */
+static const IRQn_Type s_enetErrIrqId[] = ENET_Error_IRQS;
+
+/*! @brief Pointers to enet bases for each instance. */
+static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS;
+
+/*! @brief Pointers to enet handles for each instance. */
+static enet_handle_t *s_ENETHandle[ARRAY_SIZE(s_enetBases)];
+
+/* ENET ISR for transactional APIs. */
+#if FSL_FEATURE_ENET_QUEUE > 1
+static enet_isr_ring_t s_enetTxIsr[ARRAY_SIZE(s_enetBases)];
+static enet_isr_ring_t s_enetRxIsr[ARRAY_SIZE(s_enetBases)];
+#else
+static enet_isr_t s_enetTxIsr[ARRAY_SIZE(s_enetBases)];
+static enet_isr_t s_enetRxIsr[ARRAY_SIZE(s_enetBases)];
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+static enet_isr_t s_enetErrIsr[ARRAY_SIZE(s_enetBases)];
+static enet_isr_t s_enetTsIsr[ARRAY_SIZE(s_enetBases)];
+#if (FSL_FEATURE_ENET_QUEUE > 1) && defined(ENET_1G)
+static enet_isr_t s_enet1588TimerIsr[ARRAY_SIZE(s_enetBases)];
+#endif
+
+/*******************************************************************************
+ * Prototypes
+ ******************************************************************************/
+
+/*!
+ * @brief Set ENET MAC controller with the configuration.
+ *
+ * @param base ENET peripheral base address.
+ * @param handle The ENET handle pointer.
+ * @param config ENET Mac configuration.
+ * @param bufferConfig ENET buffer configuration.
+ * @param macAddr ENET six-byte mac address.
+ * @param srcClock_Hz ENET module clock source, normally it's system clock.
+ */
+static void ENET_SetMacController(ENET_Type *base,
+ enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig,
+ uint8_t *macAddr,
+ uint32_t srcClock_Hz);
+
+/*!
+ * @brief Set ENET handler.
+ *
+ * @param base ENET peripheral base address.
+ * @param handle The ENET handle pointer.
+ * @param config ENET configuration stucture pointer.
+ * @param bufferConfig ENET buffer configuration.
+ */
+static void ENET_SetHandler(ENET_Type *base,
+ enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig);
+
+/*!
+ * @brief Set ENET MAC transmit buffer descriptors.
+ *
+ * @param handle The ENET handle pointer.
+ * @param config The ENET configuration structure.
+ * @param bufferConfig The ENET buffer configuration.
+ */
+static void ENET_SetTxBufferDescriptors(enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig);
+
+/*!
+ * @brief Set ENET MAC receive buffer descriptors.
+ *
+ * @param handle The ENET handle pointer.
+ * @param config The ENET configuration structure.
+ * @param bufferConfig The ENET buffer configuration.
+ */
+static void ENET_SetRxBufferDescriptors(enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig);
+
+/*!
+ * @brief Updates the ENET read buffer descriptors.
+ *
+ * @param base ENET peripheral base address.
+ * @param handle The ENET handle pointer.
+ * @param ringId The descriptor ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
+ */
+static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle, uint8_t ringId);
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * @brief Get the ENET instance from peripheral base address.
+ *
+ * @param base ENET peripheral base address.
+ * @return ENET instance.
+ */
+uint32_t ENET_GetInstance(ENET_Type *base)
+{
+ uint32_t instance;
+
+ /* Find the instance index from base address mappings. */
+ for (instance = 0; instance < ARRAY_SIZE(s_enetBases); instance++)
+ {
+ if (s_enetBases[instance] == base)
+ {
+ break;
+ }
+ }
+
+ assert(instance < ARRAY_SIZE(s_enetBases));
+
+ return instance;
+}
+
+/*!
+ * brief Gets the ENET default configuration structure.
+ *
+ * The purpose of this API is to get the default ENET MAC controller
+ * configure structure for ENET_Init(). User may use the initialized
+ * structure unchanged in ENET_Init(), or modify some fields of the
+ * structure before calling ENET_Init().
+ * Example:
+ code
+ enet_config_t config;
+ ENET_GetDefaultConfig(&config);
+ endcode
+ * param config The ENET mac controller configuration structure pointer.
+ */
+void ENET_GetDefaultConfig(enet_config_t *config)
+{
+ /* Checks input parameter. */
+ assert(config != NULL);
+
+ /* Initializes the MAC configure structure to zero. */
+ (void)memset(config, 0, sizeof(enet_config_t));
+
+ /* Sets MII mode, full duplex, 100Mbps for MAC and PHY data interface. */
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+ config->miiMode = kENET_RgmiiMode;
+#else
+ config->miiMode = kENET_RmiiMode;
+#endif
+ config->miiSpeed = kENET_MiiSpeed100M;
+ config->miiDuplex = kENET_MiiFullDuplex;
+
+ config->ringNum = 1;
+
+ /* Sets the maximum receive frame length. */
+ config->rxMaxFrameLen = ENET_FRAME_MAX_FRAMELEN;
+}
+
+/*!
+ * brief Initializes the ENET module.
+ *
+ * This function initializes the module with the ENET configuration.
+ * note ENET has two buffer descriptors legacy buffer descriptors and
+ * enhanced IEEE 1588 buffer descriptors. The legacy descriptor is used by default. To
+ * use the IEEE 1588 feature, use the enhanced IEEE 1588 buffer descriptor
+ * by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure()
+ * to configure the 1588 feature and related buffers after calling ENET_Up().
+ *
+ * param base ENET peripheral base address.
+ * param handle ENET handler pointer.
+ * param config ENET mac configuration structure pointer.
+ * The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig
+ * can be used directly. It is also possible to verify the Mac configuration using other methods.
+ * param bufferConfig ENET buffer configuration structure pointer.
+ * The buffer configuration should be prepared for ENET Initialization.
+ * It is the start address of "ringNum" enet_buffer_config structures.
+ * To support added multi-ring features in some soc and compatible with the previous
+ * enet driver version. For single ring supported, this bufferConfig is a buffer
+ * configure structure pointer, for multi-ring supported and used case, this bufferConfig
+ * pointer should be a buffer configure structure array pointer.
+ * param macAddr ENET mac address of Ethernet device. This MAC address should be
+ * provided.
+ * param srcClock_Hz The internal module clock source for MII clock.
+ */
+void ENET_Up(ENET_Type *base,
+ enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig,
+ uint8_t *macAddr,
+ uint32_t srcClock_Hz)
+{
+ /* Checks input parameters. */
+ assert(handle != NULL);
+ assert(config != NULL);
+ assert(bufferConfig != NULL);
+ assert(macAddr != NULL);
+ assert(config->ringNum <= (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ /* Initializes the ENET transmit buffer descriptors. */
+ ENET_SetTxBufferDescriptors(handle, config, bufferConfig);
+
+ /* Initializes the ENET receive buffer descriptors. */
+ ENET_SetRxBufferDescriptors(handle, config, bufferConfig);
+
+ /* Initializes the ENET MAC controller with basic function. */
+ ENET_SetMacController(base, handle, config, bufferConfig, macAddr, srcClock_Hz);
+
+ /* Set all buffers or data in handler for data transmit/receive process. */
+ ENET_SetHandler(base, handle, config, bufferConfig);
+}
+
+/*!
+ * brief Initializes the ENET module.
+ *
+ * This function ungates the module clock and initializes it with the ENET configuration.
+ * note ENET has two buffer descriptors legacy buffer descriptors and
+ * enhanced IEEE 1588 buffer descriptors. The legacy descriptor is used by default. To
+ * use the IEEE 1588 feature, use the enhanced IEEE 1588 buffer descriptor
+ * by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure()
+ * to configure the 1588 feature and related buffers after calling ENET_Init().
+ *
+ * param base ENET peripheral base address.
+ * param handle ENET handler pointer.
+ * param config ENET mac configuration structure pointer.
+ * The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig
+ * can be used directly. It is also possible to verify the Mac configuration using other methods.
+ * param bufferConfig ENET buffer configuration structure pointer.
+ * The buffer configuration should be prepared for ENET Initialization.
+ * It is the start address of "ringNum" enet_buffer_config structures.
+ * To support added multi-ring features in some soc and compatible with the previous
+ * enet driver version. For single ring supported, this bufferConfig is a buffer
+ * configure structure pointer, for multi-ring supported and used case, this bufferConfig
+ * pointer should be a buffer configure structure array pointer.
+ * param macAddr ENET mac address of Ethernet device. This MAC address should be
+ * provided.
+ * param srcClock_Hz The internal module clock source for MII clock.
+ */
+void ENET_Init(ENET_Type *base,
+ enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig,
+ uint8_t *macAddr,
+ uint32_t srcClock_Hz)
+{
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ uint32_t instance = ENET_GetInstance(base);
+
+ /* Ungate ENET clock. */
+ (void)CLOCK_EnableClock(s_enetClock[instance]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+ /* Reset ENET module. */
+ ENET_Reset(base);
+
+ ENET_Up(base, handle, config, bufferConfig, macAddr, srcClock_Hz);
+}
+
+/*!
+ * brief Stops the ENET module.
+
+ * This function disables the ENET module.
+ *
+ * param base ENET peripheral base address.
+ */
+void ENET_Down(ENET_Type *base)
+{
+ /* Disable interrupt. */
+ base->EIMR = 0;
+
+ /* Disable ENET. */
+ base->ECR &= ~ENET_ECR_ETHEREN_MASK;
+}
+
+/*!
+ * brief Deinitializes the ENET module.
+
+ * This function gates the module clock, clears ENET interrupts, and disables the ENET module.
+ *
+ * param base ENET peripheral base address.
+ */
+void ENET_Deinit(ENET_Type *base)
+{
+ ENET_Down(base);
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ /* Disables the clock source. */
+ (void)CLOCK_DisableClock(s_enetClock[ENET_GetInstance(base)]);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+}
+
+/*!
+ * brief Sets the callback function.
+ * This API is provided for the application callback required case when ENET
+ * interrupt is enabled. This API should be called after calling ENET_Init.
+ *
+ * param handle ENET handler pointer. Should be provided by application.
+ * param callback The ENET callback function.
+ * param userData The callback function parameter.
+ */
+void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *userData)
+{
+ assert(handle != NULL);
+
+ /* Set callback and userData. */
+ handle->callback = callback;
+ handle->userData = userData;
+}
+
+#if FSL_FEATURE_ENET_QUEUE > 1
+void ENET_SetRxISRHandler(ENET_Type *base, enet_isr_ring_t ISRHandler)
+{
+ uint32_t instance = ENET_GetInstance(base);
+
+ s_enetRxIsr[instance] = ISRHandler;
+ (void)EnableIRQ(s_enetRxIrqId[instance]);
+}
+
+void ENET_SetTxISRHandler(ENET_Type *base, enet_isr_ring_t ISRHandler)
+{
+ uint32_t instance = ENET_GetInstance(base);
+
+ s_enetTxIsr[instance] = ISRHandler;
+ (void)EnableIRQ(s_enetTxIrqId[instance]);
+}
+#else
+void ENET_SetRxISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
+{
+ uint32_t instance = ENET_GetInstance(base);
+
+ s_enetRxIsr[instance] = ISRHandler;
+ (void)EnableIRQ(s_enetRxIrqId[instance]);
+}
+
+void ENET_SetTxISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
+{
+ uint32_t instance = ENET_GetInstance(base);
+
+ s_enetTxIsr[instance] = ISRHandler;
+ (void)EnableIRQ(s_enetTxIrqId[instance]);
+}
+#endif
+
+void ENET_SetErrISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
+{
+ uint32_t instance = ENET_GetInstance(base);
+
+ s_enetErrIsr[instance] = ISRHandler;
+ (void)EnableIRQ(s_enetErrIrqId[instance]);
+}
+
+#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+void ENET_SetTsISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
+{
+ uint32_t instance = ENET_GetInstance(base);
+
+ s_enetTsIsr[instance] = ISRHandler;
+ (void)EnableIRQ(s_enetTsIrqId[instance]);
+}
+
+#if (FSL_FEATURE_ENET_QUEUE > 1) && defined(ENET_1G)
+void ENET_Set1588TimerISRHandler(ENET_Type *base, enet_isr_t ISRHandler)
+{
+ uint32_t instance = ENET_GetInstance(base);
+
+ s_enet1588TimerIsr[instance] = ISRHandler;
+ (void)EnableIRQ(s_enet1588TimerIrqId[instance]);
+}
+#endif
+#endif
+
+static void ENET_SetHandler(ENET_Type *base,
+ enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig)
+{
+ uint8_t count;
+ uint32_t instance = ENET_GetInstance(base);
+ const enet_buffer_config_t *buffCfg = bufferConfig;
+
+ /* Store transfer parameters in handle pointer. */
+ (void)memset(handle, 0, sizeof(enet_handle_t));
+
+ handle->ringNum =
+ (config->ringNum > (uint8_t)FSL_FEATURE_ENET_QUEUE) ? (uint8_t)FSL_FEATURE_ENET_QUEUE : config->ringNum;
+ for (count = 0; count < handle->ringNum; count++)
+ {
+ assert(buffCfg->rxBuffSizeAlign * buffCfg->rxBdNumber > config->rxMaxFrameLen);
+
+ handle->rxBdRing[count].rxBdBase = buffCfg->rxBdStartAddrAlign;
+ handle->rxBuffSizeAlign[count] = buffCfg->rxBuffSizeAlign;
+ handle->rxBdRing[count].rxRingLen = buffCfg->rxBdNumber;
+ handle->rxMaintainEnable[count] = buffCfg->rxMaintainEnable;
+ handle->txBdRing[count].txBdBase = buffCfg->txBdStartAddrAlign;
+ handle->txBuffSizeAlign[count] = buffCfg->txBuffSizeAlign;
+ handle->txBdRing[count].txRingLen = buffCfg->txBdNumber;
+ handle->txMaintainEnable[count] = buffCfg->txMaintainEnable;
+ handle->txDirtyRing[count].txDirtyBase = buffCfg->txFrameInfo;
+ handle->txDirtyRing[count].txRingLen = buffCfg->txBdNumber;
+ buffCfg++;
+ }
+
+ /* Save the handle pointer in the global variables. */
+ s_ENETHandle[instance] = handle;
+
+ /* Set the IRQ handler when the interrupt is enabled. */
+ if (0U != (config->interrupt & (uint32_t)ENET_TX_INTERRUPT))
+ {
+ ENET_SetTxISRHandler(base, ENET_TransmitIRQHandler);
+ }
+ if (0U != (config->interrupt & (uint32_t)ENET_RX_INTERRUPT))
+ {
+ ENET_SetRxISRHandler(base, ENET_ReceiveIRQHandler);
+ }
+ if (0U != (config->interrupt & (uint32_t)ENET_ERR_INTERRUPT))
+ {
+ ENET_SetErrISRHandler(base, ENET_ErrorIRQHandler);
+ }
+}
+
+static void ENET_SetMacController(ENET_Type *base,
+ enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig,
+ uint8_t *macAddr,
+ uint32_t srcClock_Hz)
+{
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+ /* Check the MII mode/speed/duplex setting. */
+ if (config->miiSpeed == kENET_MiiSpeed1000M)
+ {
+ /* Only RGMII mode has the 1000M bit/s. The 1000M only support full duplex. */
+ assert(config->miiMode == kENET_RgmiiMode);
+ assert(config->miiDuplex == kENET_MiiFullDuplex);
+ }
+#endif /* FSL_FEATURE_ENET_HAS_AVB */
+
+ uint32_t rcr = 0;
+ uint32_t tcr = 0;
+ uint32_t ecr = base->ECR;
+ uint32_t macSpecialConfig = config->macSpecialConfig;
+ uint32_t maxFrameLen = config->rxMaxFrameLen;
+ uint32_t configVal = 0;
+
+ /* Maximum frame length check. */
+ if ((0U != (macSpecialConfig & (uint32_t)kENET_ControlVLANTagEnable)) && (maxFrameLen <= ENET_FRAME_MAX_FRAMELEN))
+ {
+ maxFrameLen = (ENET_FRAME_MAX_FRAMELEN + ENET_FRAME_VLAN_TAGLEN);
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+ if (0U != (macSpecialConfig & (uint32_t)kENET_ControlSVLANEnable))
+ {
+ /* Double vlan tag (SVLAN) supported. */
+ maxFrameLen += ENET_FRAME_VLAN_TAGLEN;
+ }
+ ecr |=
+ (uint32_t)(((macSpecialConfig & (uint32_t)kENET_ControlSVLANEnable) != 0U) ?
+ (ENET_ECR_SVLANEN_MASK | ENET_ECR_SVLANDBL_MASK) :
+ 0U) |
+ (uint32_t)(((macSpecialConfig & (uint32_t)kENET_ControlVLANUseSecondTag) != 0U) ? ENET_ECR_VLANUSE2ND_MASK :
+ 0U);
+#endif /* FSL_FEATURE_ENET_HAS_AVB */
+ }
+
+ /* Configures MAC receive controller with user configure structure. */
+ rcr = ((0U != (macSpecialConfig & (uint32_t)kENET_ControlRxPayloadCheckEnable)) ? ENET_RCR_NLC_MASK : 0U) |
+ ((0U != (macSpecialConfig & (uint32_t)kENET_ControlFlowControlEnable)) ? ENET_RCR_CFEN_MASK : 0U) |
+ ((0U != (macSpecialConfig & (uint32_t)kENET_ControlFlowControlEnable)) ? ENET_RCR_FCE_MASK : 0U) |
+ ((0U != (macSpecialConfig & (uint32_t)kENET_ControlRxPadRemoveEnable)) ? ENET_RCR_PADEN_MASK : 0U) |
+ ((0U != (macSpecialConfig & (uint32_t)kENET_ControlRxBroadCastRejectEnable)) ? ENET_RCR_BC_REJ_MASK : 0U) |
+ ((0U != (macSpecialConfig & (uint32_t)kENET_ControlPromiscuousEnable)) ? ENET_RCR_PROM_MASK : 0U) |
+ ENET_RCR_MAX_FL(maxFrameLen) | ENET_RCR_CRCFWD_MASK;
+
+/* Set the RGMII or RMII, MII mode and control register. */
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+ if (config->miiMode == kENET_RgmiiMode)
+ {
+ rcr |= ENET_RCR_RGMII_EN_MASK;
+ rcr &= ~ENET_RCR_MII_MODE_MASK;
+ }
+ else
+ {
+ rcr &= ~ENET_RCR_RGMII_EN_MASK;
+#endif /* FSL_FEATURE_ENET_HAS_AVB */
+ rcr |= ENET_RCR_MII_MODE_MASK;
+ if (config->miiMode == kENET_RmiiMode)
+ {
+ rcr |= ENET_RCR_RMII_MODE_MASK;
+ }
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+ }
+#endif /* FSL_FEATURE_ENET_HAS_AVB */
+ /* Speed. */
+ if (config->miiSpeed == kENET_MiiSpeed10M)
+ {
+ rcr |= ENET_RCR_RMII_10T_MASK;
+ }
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+ if (config->miiSpeed == kENET_MiiSpeed1000M)
+ {
+ ecr |= ENET_ECR_SPEED_MASK;
+ }
+ else
+ {
+ ecr &= ~ENET_ECR_SPEED_MASK;
+ }
+#endif /* FSL_FEATURE_ENET_HAS_AVB */
+
+ /* Receive setting for half duplex. */
+ if (config->miiDuplex == kENET_MiiHalfDuplex)
+ {
+ rcr |= ENET_RCR_DRT_MASK;
+ }
+ /* Sets internal loop only for MII mode. */
+ if ((0U != (config->macSpecialConfig & (uint32_t)kENET_ControlMIILoopEnable)) &&
+ (config->miiMode != kENET_RmiiMode))
+ {
+ rcr |= ENET_RCR_LOOP_MASK;
+ rcr &= ~ENET_RCR_DRT_MASK;
+ }
+ base->RCR = rcr;
+
+ /* Configures MAC transmit controller: duplex mode, mac address insertion. */
+ tcr = base->TCR & ~(ENET_TCR_FDEN_MASK | ENET_TCR_ADDINS_MASK);
+ tcr |= ((kENET_MiiHalfDuplex != config->miiDuplex) ? (uint32_t)ENET_TCR_FDEN_MASK : 0U) |
+ ((0U != (macSpecialConfig & (uint32_t)kENET_ControlMacAddrInsert)) ? (uint32_t)ENET_TCR_ADDINS_MASK : 0U);
+ base->TCR = tcr;
+
+ /* Configures receive and transmit accelerator. */
+ base->TACC = config->txAccelerConfig;
+ base->RACC = config->rxAccelerConfig;
+
+ /* Sets the pause duration and FIFO threshold for the flow control enabled case. */
+ if (0U != (macSpecialConfig & (uint32_t)kENET_ControlFlowControlEnable))
+ {
+ uint32_t reemReg;
+ base->OPD = config->pauseDuration;
+ reemReg = ENET_RSEM_RX_SECTION_EMPTY(config->rxFifoEmptyThreshold);
+#if defined(FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD) && FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD
+ reemReg |= ENET_RSEM_STAT_SECTION_EMPTY(config->rxFifoStatEmptyThreshold);
+#endif /* FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD */
+ base->RSEM = reemReg;
+ }
+
+ /* FIFO threshold setting for store and forward enable/disable case. */
+ if (0U != (macSpecialConfig & (uint32_t)kENET_ControlStoreAndFwdDisable))
+ {
+ /* Transmit fifo watermark settings. */
+ configVal = ((uint32_t)config->txFifoWatermark) & ENET_TFWR_TFWR_MASK;
+ base->TFWR = configVal;
+ /* Receive fifo full threshold settings. */
+ configVal = ((uint32_t)config->rxFifoFullThreshold) & ENET_RSFL_RX_SECTION_FULL_MASK;
+ base->RSFL = configVal;
+ }
+ else
+ {
+ /* Transmit fifo watermark settings. */
+ base->TFWR = ENET_TFWR_STRFWD_MASK;
+ base->RSFL = 0;
+ }
+
+ /* Enable store and forward when accelerator is enabled */
+ if (0U !=
+ (config->txAccelerConfig & ((uint32_t)kENET_TxAccelIpCheckEnabled | (uint32_t)kENET_TxAccelProtoCheckEnabled)))
+ {
+ base->TFWR = ENET_TFWR_STRFWD_MASK;
+ }
+ if (0U != ((config->rxAccelerConfig &
+ ((uint32_t)kENET_RxAccelIpCheckEnabled | (uint32_t)kENET_RxAccelProtoCheckEnabled))))
+ {
+ base->RSFL = 0;
+ }
+
+/* Initializes the ring 0. */
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ base->TDSR = MEMORY_ConvertMemoryMapAddress((uint32_t)bufferConfig->txBdStartAddrAlign, kMEMORY_Local2DMA);
+ base->RDSR = MEMORY_ConvertMemoryMapAddress((uint32_t)bufferConfig->rxBdStartAddrAlign, kMEMORY_Local2DMA);
+#else
+ base->TDSR = (uint32_t)bufferConfig->txBdStartAddrAlign;
+ base->RDSR = (uint32_t)bufferConfig->rxBdStartAddrAlign;
+#endif
+ base->MRBR = (uint32_t)bufferConfig->rxBuffSizeAlign;
+
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+ const enet_buffer_config_t *buffCfg = bufferConfig;
+
+ if (config->ringNum > 1U)
+ {
+ /* Initializes the ring 1. */
+ buffCfg++;
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ base->TDSR1 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->txBdStartAddrAlign, kMEMORY_Local2DMA);
+ base->RDSR1 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->rxBdStartAddrAlign, kMEMORY_Local2DMA);
+#else
+ base->TDSR1 = (uint32_t)buffCfg->txBdStartAddrAlign;
+ base->RDSR1 = (uint32_t)buffCfg->rxBdStartAddrAlign;
+#endif
+ base->MRBR1 = (uint32_t)buffCfg->rxBuffSizeAlign;
+ /* Enable the DMAC for ring 1 and with no rx classification set. */
+ base->DMACFG[0] = ENET_DMACFG_DMA_CLASS_EN_MASK;
+ }
+ if (config->ringNum > 2U)
+ {
+ /* Initializes the ring 2. */
+ buffCfg++;
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ base->TDSR2 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->txBdStartAddrAlign, kMEMORY_Local2DMA);
+ base->RDSR2 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->rxBdStartAddrAlign, kMEMORY_Local2DMA);
+#else
+ base->TDSR2 = (uint32_t)buffCfg->txBdStartAddrAlign;
+ base->RDSR2 = (uint32_t)buffCfg->rxBdStartAddrAlign;
+#endif
+ base->MRBR2 = (uint32_t)buffCfg->rxBuffSizeAlign;
+ /* Enable the DMAC for ring 2 and with no rx classification set. */
+ base->DMACFG[1] = ENET_DMACFG_DMA_CLASS_EN_MASK;
+ }
+
+ /* Default the class/ring 1 and 2 are not enabled and the receive classification is disabled
+ * so we set the default transmit scheme with the round-robin mode. beacuse the legacy bd mode
+ * only support the round-robin mode. if the avb feature is required, just call the setup avb
+ * feature API. */
+ base->QOS |= ENET_QOS_TX_SCHEME(1);
+#endif /* FSL_FEATURE_ENET_HAS_AVB */
+
+ /* Configures the Mac address. */
+ ENET_SetMacAddr(base, macAddr);
+
+ /* Initialize the SMI if uninitialized. */
+ if (!ENET_GetSMI(base))
+ {
+ ENET_SetSMI(base, srcClock_Hz,
+ ((0U != (config->macSpecialConfig & (uint32_t)kENET_ControlSMIPreambleDisable)) ? true : false));
+ }
+
+/* Enables Ethernet interrupt, enables the interrupt coalsecing if it is required. */
+#if defined(FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE) && FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE
+ if (NULL != config->intCoalesceCfg)
+ {
+ uint32_t intMask = (ENET_EIMR_TXB_MASK | ENET_EIMR_RXB_MASK);
+
+#if FSL_FEATURE_ENET_QUEUE > 1
+ uint8_t queue = 0;
+ intMask |= ENET_EIMR_TXB2_MASK | ENET_EIMR_RXB2_MASK | ENET_EIMR_TXB1_MASK | ENET_EIMR_RXB1_MASK;
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+
+ /* Clear all buffer interrupts. */
+ base->EIMR &= ~intMask;
+
+/* Set the interrupt coalescence. */
+#if FSL_FEATURE_ENET_QUEUE > 1
+ for (queue = 0; queue < (uint8_t)FSL_FEATURE_ENET_QUEUE; queue++)
+ {
+ base->TXIC[queue] = ENET_TXIC_ICFT(config->intCoalesceCfg->txCoalesceFrameCount[queue]) |
+ config->intCoalesceCfg->txCoalesceTimeCount[queue] | ENET_TXIC_ICCS_MASK |
+ ENET_TXIC_ICEN_MASK;
+ base->RXIC[queue] = ENET_RXIC_ICFT(config->intCoalesceCfg->rxCoalesceFrameCount[queue]) |
+ config->intCoalesceCfg->rxCoalesceTimeCount[queue] | ENET_RXIC_ICCS_MASK |
+ ENET_RXIC_ICEN_MASK;
+ }
+#else
+ base->TXIC = ENET_TXIC_ICFT(config->intCoalesceCfg->txCoalesceFrameCount[0]) |
+ config->intCoalesceCfg->txCoalesceTimeCount[0] | ENET_TXIC_ICCS_MASK | ENET_TXIC_ICEN_MASK;
+ base->RXIC = ENET_RXIC_ICFT(config->intCoalesceCfg->rxCoalesceFrameCount[0]) |
+ config->intCoalesceCfg->rxCoalesceTimeCount[0] | ENET_RXIC_ICCS_MASK | ENET_RXIC_ICEN_MASK;
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+#endif /* FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE */
+ ENET_EnableInterrupts(base, config->interrupt);
+
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ /* Sets the 1588 enhanced feature. */
+ ecr |= ENET_ECR_EN1588_MASK;
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+ /* Enables Ethernet module after all configuration except the buffer descriptor active. */
+ ecr |= ENET_ECR_ETHEREN_MASK | ENET_ECR_DBSWP_MASK;
+ base->ECR = ecr;
+}
+
+static void ENET_SetTxBufferDescriptors(enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig)
+{
+ assert(config != NULL);
+ assert(bufferConfig != NULL);
+
+ /* Default single ring is supported. */
+ uint8_t ringNum;
+ uint16_t count;
+ uint32_t txBuffSizeAlign;
+ uint8_t *txBuffer = NULL;
+ const enet_buffer_config_t *buffCfg = bufferConfig;
+
+ /* Check the input parameters. */
+ for (ringNum = 0; ringNum < config->ringNum; ringNum++)
+ {
+ if (buffCfg->txBdStartAddrAlign != NULL)
+ {
+ volatile enet_tx_bd_struct_t *curBuffDescrip = buffCfg->txBdStartAddrAlign;
+ txBuffSizeAlign = buffCfg->txBuffSizeAlign;
+
+ if (buffCfg->txBufferAlign != NULL)
+ {
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ txBuffer =
+ (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->txBufferAlign, kMEMORY_Local2DMA);
+#else
+ txBuffer = buffCfg->txBufferAlign;
+#endif
+ }
+
+ for (count = 0; count < buffCfg->txBdNumber; count++)
+ {
+ if (buffCfg->txBufferAlign != NULL)
+ {
+ /* Set data buffer address. */
+ curBuffDescrip->buffer = (uint8_t *)((uint32_t)&txBuffer[count * txBuffSizeAlign]);
+ }
+ /* Initializes data length. */
+ curBuffDescrip->length = 0;
+ /* Sets the crc. */
+ curBuffDescrip->control = ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK;
+ /* Sets the last buffer descriptor with the wrap flag. */
+ if (count == (buffCfg->txBdNumber - 1U))
+ {
+ curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_WRAP_MASK;
+ }
+
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ /* Enable transmit interrupt for store the transmit timestamp. */
+ curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK;
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+ /* Set the type of the frame when the credit-based scheme is used. */
+ curBuffDescrip->controlExtend1 |= (uint16_t)(ENET_BD_FTYPE(ringNum));
+#endif /* FSL_FEATURE_ENET_HAS_AVB */
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+ /* Increase the index. */
+ curBuffDescrip++;
+ }
+ }
+ buffCfg++;
+ }
+}
+
+static void ENET_SetRxBufferDescriptors(enet_handle_t *handle,
+ const enet_config_t *config,
+ const enet_buffer_config_t *bufferConfig)
+{
+ assert(config != NULL);
+ assert(bufferConfig != NULL);
+
+ /* Default single ring is supported. */
+ uint8_t ringNum;
+ uint16_t count;
+ uint16_t rxBuffSizeAlign;
+ uint8_t *rxBuffer;
+ const enet_buffer_config_t *buffCfg = bufferConfig;
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ uint32_t mask = ((uint32_t)kENET_RxFrameInterrupt | (uint32_t)kENET_RxBufferInterrupt);
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+ /* Check the input parameters. */
+ for (ringNum = 0; ringNum < config->ringNum; ringNum++)
+ {
+ assert(buffCfg->rxBuffSizeAlign >= ENET_RX_MIN_BUFFERSIZE);
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+#if FSL_FEATURE_ENET_QUEUE > 1
+ if (ringNum == 1U)
+ {
+ mask = ((uint32_t)kENET_RxFrame1Interrupt | (uint32_t)kENET_RxBuffer1Interrupt);
+ }
+ else if (ringNum == 2U)
+ {
+ mask = ((uint32_t)kENET_RxFrame2Interrupt | (uint32_t)kENET_RxBuffer2Interrupt);
+ }
+ else
+ {
+ /* Intentional empty */
+ }
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+ if ((buffCfg->rxBdStartAddrAlign != NULL) && (buffCfg->rxBufferAlign != NULL))
+ {
+ volatile enet_rx_bd_struct_t *curBuffDescrip = buffCfg->rxBdStartAddrAlign;
+ rxBuffSizeAlign = buffCfg->rxBuffSizeAlign;
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ rxBuffer = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->rxBufferAlign, kMEMORY_Local2DMA);
+#else
+ rxBuffer = buffCfg->rxBufferAlign;
+#endif
+
+#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
+ if (buffCfg->rxMaintainEnable)
+ {
+ /* Invalidate rx buffers before DMA transfer data into them. */
+ DCACHE_InvalidateByRange((uint32_t)rxBuffer, ((uint32_t)buffCfg->rxBdNumber * rxBuffSizeAlign));
+ }
+#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
+
+ for (count = 0; count < buffCfg->rxBdNumber; count++)
+ {
+ /* Set data buffer and the length. */
+ curBuffDescrip->buffer = (uint8_t *)((uint32_t)&rxBuffer[count * rxBuffSizeAlign]);
+ curBuffDescrip->length = 0;
+
+ /* Initializes the buffer descriptors with empty bit. */
+ curBuffDescrip->control = ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
+ /* Sets the last buffer descriptor with the wrap flag. */
+ if (count == (buffCfg->rxBdNumber - 1U))
+ {
+ curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
+ }
+
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ if (0U != (config->interrupt & mask))
+ {
+ /* Enable receive interrupt. */
+ curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_RX_INTERRUPT_MASK;
+ }
+ else
+ {
+ curBuffDescrip->controlExtend1 = 0;
+ }
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+ /* Increase the index. */
+ curBuffDescrip++;
+ }
+ }
+ buffCfg++;
+ }
+}
+
+/*!
+ * @brief Activates ENET send for multiple tx rings.
+ * @note This must be called after the MAC configuration and
+ * state are ready. It must be called after the ENET_Init() and
+ * this should be called when the ENET receive required.
+ *
+ * @param base ENET peripheral base address.
+ * @param ringId The descriptor ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
+ *
+ */
+static void ENET_ActiveSend(ENET_Type *base, uint8_t ringId)
+{
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ volatile uint32_t *txDesActive = NULL;
+
+ /* Ensure previous data update is completed with Data Synchronization Barrier before activing Tx BD. */
+ __DSB();
+
+ switch (ringId)
+ {
+ case kENET_Ring0:
+ txDesActive = &(base->TDAR);
+ break;
+#if FSL_FEATURE_ENET_QUEUE > 1
+ case kENET_Ring1:
+ txDesActive = &(base->TDAR1);
+ break;
+ case kENET_Ring2:
+ txDesActive = &(base->TDAR2);
+ break;
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ default:
+ txDesActive = &(base->TDAR);
+ break;
+ }
+
+#if defined(FSL_FEATURE_ENET_HAS_ERRATA_007885) && FSL_FEATURE_ENET_HAS_ERRATA_007885
+ /* There is a TDAR race condition for mutliQ when the software sets TDAR
+ * and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles).
+ * This will cause the udma_tx and udma_tx_arbiter state machines to hang.
+ * Software workaround: introduces a delay by reading the relevant ENET_TDARn_TDAR 4 times
+ */
+ for (uint8_t i = 0; i < 4U; i++)
+ {
+ if (*txDesActive == 0U)
+ {
+ break;
+ }
+ }
+#endif
+
+ /* Write to active tx descriptor */
+ *txDesActive = 0;
+}
+
+/*!
+ * brief Sets the ENET MII speed and duplex.
+ *
+ * This API is provided to dynamically change the speed and dulpex for MAC.
+ *
+ * param base ENET peripheral base address.
+ * param speed The speed of the RMII mode.
+ * param duplex The duplex of the RMII mode.
+ */
+void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex)
+{
+ uint32_t rcr = base->RCR;
+ uint32_t tcr = base->TCR;
+
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+ uint32_t ecr = base->ECR;
+
+ if (kENET_MiiSpeed1000M == speed)
+ {
+ assert(duplex == kENET_MiiFullDuplex);
+ ecr |= ENET_ECR_SPEED_MASK;
+ }
+ else
+ {
+ ecr &= ~ENET_ECR_SPEED_MASK;
+ }
+
+ base->ECR = ecr;
+#endif /* FSL_FEATURE_ENET_HAS_AVB */
+
+ /* Sets speed mode. */
+ if (kENET_MiiSpeed10M == speed)
+ {
+ rcr |= ENET_RCR_RMII_10T_MASK;
+ }
+ else
+ {
+ rcr &= ~ENET_RCR_RMII_10T_MASK;
+ }
+ /* Set duplex mode. */
+ if (duplex == kENET_MiiHalfDuplex)
+ {
+ rcr |= ENET_RCR_DRT_MASK;
+ tcr &= ~ENET_TCR_FDEN_MASK;
+ }
+ else
+ {
+ rcr &= ~ENET_RCR_DRT_MASK;
+ tcr |= ENET_TCR_FDEN_MASK;
+ }
+
+ base->RCR = rcr;
+ base->TCR = tcr;
+}
+
+/*!
+ * brief Sets the ENET module Mac address.
+ *
+ * param base ENET peripheral base address.
+ * param macAddr The six-byte Mac address pointer.
+ * The pointer is allocated by application and input into the API.
+ */
+void ENET_SetMacAddr(ENET_Type *base, uint8_t *macAddr)
+{
+ uint32_t address;
+
+ /* Set physical address lower register. */
+ address = (uint32_t)(((uint32_t)macAddr[0] << 24U) | ((uint32_t)macAddr[1] << 16U) | ((uint32_t)macAddr[2] << 8U) |
+ (uint32_t)macAddr[3]);
+ base->PALR = address;
+ /* Set physical address high register. */
+ address = (uint32_t)(((uint32_t)macAddr[4] << 8U) | ((uint32_t)macAddr[5]));
+ base->PAUR = address << ENET_PAUR_PADDR2_SHIFT;
+}
+
+/*!
+ * brief Gets the ENET module Mac address.
+ *
+ * param base ENET peripheral base address.
+ * param macAddr The six-byte Mac address pointer.
+ * The pointer is allocated by application and input into the API.
+ */
+void ENET_GetMacAddr(ENET_Type *base, uint8_t *macAddr)
+{
+ assert(macAddr != NULL);
+
+ uint32_t address;
+
+ /* Get from physical address lower register. */
+ address = base->PALR;
+ macAddr[0] = 0xFFU & (uint8_t)(address >> 24U);
+ macAddr[1] = 0xFFU & (uint8_t)(address >> 16U);
+ macAddr[2] = 0xFFU & (uint8_t)(address >> 8U);
+ macAddr[3] = 0xFFU & (uint8_t)address;
+
+ /* Get from physical address high register. */
+ address = (base->PAUR & ENET_PAUR_PADDR2_MASK) >> ENET_PAUR_PADDR2_SHIFT;
+ macAddr[4] = 0xFFU & (uint8_t)(address >> 8U);
+ macAddr[5] = 0xFFU & (uint8_t)address;
+}
+
+/*!
+ * brief Sets the ENET SMI(serial management interface)- MII management interface.
+ *
+ * param base ENET peripheral base address.
+ * param srcClock_Hz This is the ENET module clock frequency. Normally it's the system clock. See clock distribution.
+ * param isPreambleDisabled The preamble disable flag.
+ * - true Enables the preamble.
+ * - false Disables the preamble.
+ */
+void ENET_SetSMI(ENET_Type *base, uint32_t srcClock_Hz, bool isPreambleDisabled)
+{
+ assert((srcClock_Hz / (2U * ENET_MDC_FREQUENCY)) != 0U);
+
+ uint32_t clkCycle = 0;
+ uint32_t speed = 0;
+ uint32_t mscr = 0;
+
+ /* Calculate the MII speed which controls the frequency of the MDC. */
+ speed = srcClock_Hz / (2U * ENET_MDC_FREQUENCY) - 1U;
+ /* Calculate the hold time on the MDIO output. */
+ clkCycle = (10U + ENET_NANOSECOND_ONE_SECOND / srcClock_Hz - 1U) / (ENET_NANOSECOND_ONE_SECOND / srcClock_Hz) - 1U;
+ /* Build the configuration for MDC/MDIO control. */
+ mscr =
+ ENET_MSCR_MII_SPEED(speed) | ENET_MSCR_HOLDTIME(clkCycle) | (isPreambleDisabled ? ENET_MSCR_DIS_PRE_MASK : 0U);
+ base->MSCR = mscr;
+}
+
+/*!
+ * brief Starts an SMI write command.
+ *
+ * Used for standard IEEE802.3 MDIO Clause 22 format.
+ *
+ * param base ENET peripheral base address.
+ * param phyAddr The PHY address.
+ * param phyReg The PHY register. Range from 0 ~ 31.
+ * param operation The write operation.
+ * param data The data written to PHY.
+ */
+void ENET_StartSMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_write_t operation, uint32_t data)
+{
+ uint32_t mmfr = 0;
+
+ /* Build MII write command. */
+ mmfr = ENET_MMFR_ST(1U) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) |
+ ENET_MMFR_TA(2U) | (data & 0xFFFFU);
+ base->MMFR = mmfr;
+}
+
+/*!
+ * brief Starts an SMI (Serial Management Interface) read command.
+ *
+ * Used for standard IEEE802.3 MDIO Clause 22 format.
+ *
+ * param base ENET peripheral base address.
+ * param phyAddr The PHY address.
+ * param phyReg The PHY register. Range from 0 ~ 31.
+ * param operation The read operation.
+ */
+void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_read_t operation)
+{
+ uint32_t mmfr = 0;
+
+ /* Build MII read command. */
+ mmfr = ENET_MMFR_ST(1U) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) | ENET_MMFR_TA(2U);
+ base->MMFR = mmfr;
+}
+
+#if defined(FSL_FEATURE_ENET_HAS_EXTEND_MDIO) && FSL_FEATURE_ENET_HAS_EXTEND_MDIO
+/*!
+ * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI write command.
+ * deprecated Do not use this function. It has been superceded by @ref ENET_StartExtC45SMIWriteReg and
+ * ENET_StartExtC45SMIWriteData.
+ *
+ * param base ENET peripheral base address.
+ * param phyAddr The PHY address.
+ * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45,
+ * the phyReg is a 21-bits combination of the devaddr (5 bits device address)
+ * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr.
+ * param data The data written to PHY.
+ */
+void ENET_StartExtC45SMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data)
+{
+ uint32_t mmfr = 0;
+
+ /* Parse the address from the input register. */
+ uint16_t devAddr = (uint16_t)((phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU);
+ uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU);
+
+ /* Address write firstly. */
+ mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
+ ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr);
+ base->MMFR = mmfr;
+
+ /* Build MII write command. */
+ mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiWriteFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
+ ENET_MMFR_TA(2) | ENET_MMFR_DATA(data);
+ base->MMFR = mmfr;
+}
+
+/*!
+ * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI read command.
+ * deprecated Do not use this function. It has been superceded by @ref ENET_StartExtC45SMIWriteReg and
+ * ENET_StartExtC45SMIReadData.
+ *
+ * param base ENET peripheral base address.
+ * param phyAddr The PHY address.
+ * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45,
+ * the phyReg is a 21-bits combination of the devaddr (5 bits device address)
+ * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr.
+ */
+void ENET_StartExtC45SMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg)
+{
+ uint32_t mmfr = 0;
+
+ /* Parse the address from the input register. */
+ uint16_t devAddr = (uint16_t)((phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU);
+ uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU);
+
+ /* Address write firstly. */
+ mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
+ ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr);
+ base->MMFR = mmfr;
+
+ /* Build MII read command. */
+ mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiReadFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
+ ENET_MMFR_TA(2);
+ base->MMFR = mmfr;
+}
+
+/*!
+ * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI write register command.
+ *
+ * param base ENET peripheral base address.
+ * param phyAddr The PHY address.
+ * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45,
+ * the phyReg is a 21-bits combination of the devaddr (5 bits device address)
+ * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr.
+ */
+void ENET_StartExtC45SMIWriteReg(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg)
+{
+ uint32_t mmfr = 0;
+
+ /* Parse the address from the input register. */
+ uint16_t devAddr = (uint16_t)((phyReg >> 16U) & 0x1FU);
+ uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU);
+
+ /* Address write. */
+ mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
+ ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr);
+ base->MMFR = mmfr;
+}
+
+/*!
+ * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI write data command.
+ *
+ * After writing MMFR register, we need to check whether the transmission is over.
+ * This is an example for whole precedure of clause 45 MDIO write.
+ * code
+ * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
+ * ENET_StartExtC45SMIWriteReg(base, phyAddr, phyReg);
+ * while ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) == 0U)
+ * {
+ * }
+ * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
+ * ENET_StartExtC45SMIWriteData(base, phyAddr, phyReg, data);
+ * while ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) == 0U)
+ * {
+ * }
+ * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
+ * endcode
+ * param base ENET peripheral base address.
+ * param phyAddr The PHY address.
+ * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45,
+ * the phyReg is a 21-bits combination of the devaddr (5 bits device address)
+ * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr.
+ * param data The data written to PHY.
+ */
+void ENET_StartExtC45SMIWriteData(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data)
+{
+ uint32_t mmfr = 0;
+
+ /* Parse the address from the input register. */
+ uint16_t devAddr = (uint16_t)((phyReg >> 16U) & 0x1FU);
+
+ /* Build MII write command. */
+ mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiWriteFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
+ ENET_MMFR_TA(2) | ENET_MMFR_DATA(data);
+ base->MMFR = mmfr;
+}
+
+/*!
+ * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI read data command.
+ *
+ * After writing MMFR register, we need to check whether the transmission is over.
+ * This is an example for whole precedure of clause 45 MDIO read.
+ * code
+ * uint32_t data;
+ * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
+ * ENET_StartExtC45SMIWriteReg(base, phyAddr, phyReg);
+ * while ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) == 0U)
+ * {
+ * }
+ * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
+ * ENET_StartExtC45SMIReadData(base, phyAddr, phyReg);
+ * while ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) == 0U)
+ * {
+ * }
+ * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK);
+ * data = ENET_ReadSMIData(base);
+ * endcode
+ * param base ENET peripheral base address.
+ * param phyAddr The PHY address.
+ * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45,
+ * the phyReg is a 21-bits combination of the devaddr (5 bits device address)
+ * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr.
+ */
+void ENET_StartExtC45SMIReadData(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg)
+{
+ uint32_t mmfr = 0;
+
+ /* Parse the address from the input register. */
+ uint16_t devAddr = (uint16_t)((phyReg >> 16U) & 0x1FU);
+
+ /* Build MII read command. */
+ mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiReadFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) |
+ ENET_MMFR_TA(2);
+ base->MMFR = mmfr;
+}
+#endif /* FSL_FEATURE_ENET_HAS_EXTEND_MDIO */
+
+static uint16_t ENET_IncreaseIndex(uint16_t index, uint16_t max)
+{
+ /* Increase the index. */
+ index++;
+ if (index >= max)
+ {
+ index = 0;
+ }
+ return index;
+}
+
+static inline bool ENET_TxDirtyRingAvailable(enet_tx_dirty_ring_t *txDirtyRing)
+{
+ return !txDirtyRing->isFull;
+}
+
+/*!
+ * brief Gets the error statistics of a received frame for ENET specified ring.
+ *
+ * This API must be called after the ENET_GetRxFrameSize and before the ENET_ReadFrame().
+ * If the ENET_GetRxFrameSize returns kStatus_ENET_RxFrameError,
+ * the ENET_GetRxErrBeforeReadFrame can be used to get the exact error statistics.
+ * This is an example.
+ * code
+ * status = ENET_GetRxFrameSize(&g_handle, &length, 0);
+ * if (status == kStatus_ENET_RxFrameError)
+ * {
+ * ENET_GetRxErrBeforeReadFrame(&g_handle, &eErrStatic, 0);
+ * ENET_ReadFrame(EXAMPLE_ENET, &g_handle, NULL, 0);
+ * }
+ * endcode
+ * param handle The ENET handler structure pointer. This is the same handler pointer used in the ENET_Init.
+ * param eErrorStatic The error statistics structure pointer.
+ * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
+ */
+void ENET_GetRxErrBeforeReadFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic, uint8_t ringId)
+{
+ assert(handle != NULL);
+ assert(eErrorStatic != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ uint16_t control = 0;
+ enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId];
+ volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
+ volatile enet_rx_bd_struct_t *cmpBuffDescrip = curBuffDescrip;
+
+ do
+ {
+ /* The last buffer descriptor of a frame. */
+ if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
+ {
+ control = curBuffDescrip->control;
+ if (0U != (control & ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK))
+ {
+ /* The receive truncate error. */
+ eErrorStatic->statsRxTruncateErr++;
+ }
+ if (0U != (control & ENET_BUFFDESCRIPTOR_RX_OVERRUN_MASK))
+ {
+ /* The receive over run error. */
+ eErrorStatic->statsRxOverRunErr++;
+ }
+ if (0U != (control & ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK))
+ {
+ /* The receive length violation error. */
+ eErrorStatic->statsRxLenGreaterErr++;
+ }
+ if (0U != (control & ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK))
+ {
+ /* The receive alignment error. */
+ eErrorStatic->statsRxAlignErr++;
+ }
+ if (0U != (control & ENET_BUFFDESCRIPTOR_RX_CRC_MASK))
+ {
+ /* The receive CRC error. */
+ eErrorStatic->statsRxFcsErr++;
+ }
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ uint16_t controlExt = curBuffDescrip->controlExtend1;
+ if (0U != (controlExt & ENET_BUFFDESCRIPTOR_RX_MACERR_MASK))
+ {
+ /* The MAC error. */
+ eErrorStatic->statsRxMacErr++;
+ }
+ if (0U != (controlExt & ENET_BUFFDESCRIPTOR_RX_PHYERR_MASK))
+ {
+ /* The PHY error. */
+ eErrorStatic->statsRxPhyErr++;
+ }
+ if (0U != (controlExt & ENET_BUFFDESCRIPTOR_RX_COLLISION_MASK))
+ {
+ /* The receive collision error. */
+ eErrorStatic->statsRxCollisionErr++;
+ }
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+ break;
+ }
+
+ /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
+ if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK))
+ {
+ curBuffDescrip = rxBdRing->rxBdBase;
+ }
+ else
+ {
+ curBuffDescrip++;
+ }
+
+ } while (curBuffDescrip != cmpBuffDescrip);
+}
+
+/*!
+ * brief Gets the size of the read frame for specified ring.
+ *
+ * This function gets a received frame size from the ENET buffer descriptors.
+ * note The FCS of the frame is automatically removed by MAC and the size is the length without the FCS.
+ * After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to update the
+ * receive buffers if the result is not "kStatus_ENET_RxFrameEmpty".
+ *
+ * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
+ * param length The length of the valid frame received.
+ * param ringId The ring index or ring number.
+ * retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame.
+ * retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data
+ * and NULL length to update the receive buffers.
+ * retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame
+ * should be called with the right data buffer and the captured data length input.
+ */
+status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length, uint8_t ringId)
+{
+ assert(handle != NULL);
+ assert(length != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ /* Reset the length to zero. */
+ *length = 0;
+
+ uint16_t validLastMask = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
+ enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId];
+ volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
+ uint16_t index = rxBdRing->rxGenIdx;
+ bool isReturn = false;
+ status_t result = kStatus_Success;
+
+ /* Check the current buffer descriptor's empty flag. If empty means there is no frame received. */
+ /* If this buffer descriptor is owned by application, return empty. Only need to check the first BD's owner if one
+ * frame in mutiple BDs. */
+ if (0U != (curBuffDescrip->control & (ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK | ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK)))
+ {
+ isReturn = true;
+ result = kStatus_ENET_RxFrameEmpty;
+ }
+ else
+ {
+ do
+ {
+ /* Add check for abnormal case. */
+ if (curBuffDescrip->length == 0U)
+ {
+ isReturn = true;
+ result = kStatus_ENET_RxFrameError;
+ break;
+ }
+
+ /* Find the last buffer descriptor. */
+ if ((curBuffDescrip->control & validLastMask) == ENET_BUFFDESCRIPTOR_RX_LAST_MASK)
+ {
+ isReturn = true;
+ /* The last buffer descriptor in the frame check the status of the received frame. */
+ if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_ERR_MASK))
+ {
+ result = kStatus_ENET_RxFrameError;
+ break;
+ }
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ if (0U != (curBuffDescrip->controlExtend1 & ENET_BUFFDESCRIPTOR_RX_EXT_ERR_MASK))
+ {
+ result = kStatus_ENET_RxFrameError;
+ break;
+ }
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+ /* FCS is removed by MAC. */
+ *length = curBuffDescrip->length;
+ break;
+ }
+ /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */
+ index = ENET_IncreaseIndex(index, rxBdRing->rxRingLen);
+ curBuffDescrip = rxBdRing->rxBdBase + index;
+ } while (index != rxBdRing->rxGenIdx);
+ }
+
+ if (isReturn == false)
+ {
+ /* The frame is on processing - set to empty status to make application to receive it next time. */
+ result = kStatus_ENET_RxFrameEmpty;
+ }
+
+ return result;
+}
+
+/*!
+ * brief Reads a frame from the ENET device.
+ * This function reads a frame (both the data and the length) from the ENET buffer descriptors.
+ * User can get timestamp through ts pointer if the ts is not NULL.
+ * Note that it doesn't store the timestamp in the receive timestamp queue.
+ * The ENET_GetRxFrameSize should be used to get the size of the prepared data buffer.
+ * This is an example:
+ * code
+ * uint32_t length;
+ * enet_handle_t g_handle;
+ * Comments: Get the received frame size firstly.
+ * status = ENET_GetRxFrameSize(&g_handle, &length, 0);
+ * if (length != 0)
+ * {
+ * Comments: Allocate memory here with the size of "length"
+ * uint8_t *data = memory allocate interface;
+ * if (!data)
+ * {
+ * ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0, NULL);
+ * Comments: Add the console warning log.
+ * }
+ * else
+ * {
+ * status = ENET_ReadFrame(ENET, &g_handle, data, length, 0, NULL);
+ * Comments: Call stack input API to deliver the data to stack
+ * }
+ * }
+ * else if (status == kStatus_ENET_RxFrameError)
+ * {
+ * Comments: Update the received buffer when a error frame is received.
+ * ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0, NULL);
+ * }
+ * endcode
+ * param base ENET peripheral base address.
+ * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
+ * param data The data buffer provided by user to store the frame which memory size should be at least "length".
+ * param length The size of the data buffer which is still the length of the received frame.
+ * param ringId The ring index or ring number.
+ * param ts The timestamp address to store received timestamp.
+ * return The execute status, successful or failure.
+ */
+status_t ENET_ReadFrame(
+ ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length, uint8_t ringId, uint32_t *ts)
+{
+ assert(handle != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ uint32_t len = 0;
+ uint32_t offset = 0;
+ uint16_t control;
+ bool isLastBuff = false;
+ enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId];
+ volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
+ uint16_t index = rxBdRing->rxGenIdx;
+ status_t result = kStatus_Success;
+ uint32_t address;
+ uint32_t dest;
+
+ /* For data-NULL input, only update the buffer descriptor. */
+ if (data == NULL)
+ {
+ do
+ {
+ /* Update the control flag. */
+ control = curBuffDescrip->control;
+
+ /* Updates the receive buffer descriptors. */
+ ENET_UpdateReadBuffers(base, handle, ringId);
+
+ /* Find the last buffer descriptor for the frame. */
+ if (0U != (control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
+ {
+ break;
+ }
+ curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
+ } while (index != rxBdRing->rxGenIdx);
+ }
+ else
+ {
+ while (!isLastBuff)
+ {
+/* A frame on one buffer or several receive buffers are both considered. */
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
+#else
+ address = (uint32_t)curBuffDescrip->buffer;
+#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
+#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
+ if (handle->rxMaintainEnable[ringId])
+ {
+ /* Add the cache invalidate maintain. */
+ DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[ringId]);
+ }
+#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
+
+ dest = (uint32_t)data + offset;
+ /* The last buffer descriptor of a frame. */
+ if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
+ {
+ /* This is a valid frame. */
+ isLastBuff = true;
+ if (length == curBuffDescrip->length)
+ {
+ /* Copy the frame to user's buffer without FCS. */
+ len = curBuffDescrip->length - offset;
+ (void)memcpy((uint32_t *)dest, (uint32_t *)address, len);
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ /* Get the timestamp if the ts isn't NULL. */
+ if (ts != NULL)
+ {
+ *ts = curBuffDescrip->timestamp;
+ }
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+ /* Updates the receive buffer descriptors. */
+ ENET_UpdateReadBuffers(base, handle, ringId);
+ break;
+ }
+ else
+ {
+ /* Updates the receive buffer descriptors. */
+ ENET_UpdateReadBuffers(base, handle, ringId);
+ }
+ }
+ else
+ {
+ /* Store a frame on several buffer descriptors. */
+ isLastBuff = false;
+ /* Length check. */
+ if (offset >= length)
+ {
+ result = kStatus_ENET_RxFrameFail;
+ break;
+ }
+ (void)memcpy((uint32_t *)dest, (uint32_t *)address, handle->rxBuffSizeAlign[ringId]);
+ offset += handle->rxBuffSizeAlign[ringId];
+
+ /* Updates the receive buffer descriptors. */
+ ENET_UpdateReadBuffers(base, handle, ringId);
+ }
+
+ /* Get the current buffer descriptor. */
+ curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
+ }
+ }
+
+ return result;
+}
+
+static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle, uint8_t ringId)
+{
+ assert(handle != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ volatile enet_rx_bd_struct_t *curBuffDescrip =
+ handle->rxBdRing[ringId].rxBdBase + handle->rxBdRing[ringId].rxGenIdx;
+
+ /* Clears status. */
+ curBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
+ /* Sets the receive buffer descriptor with the empty flag. */
+ curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
+
+ /* Increase current buffer descriptor to the next one. */
+ handle->rxBdRing[ringId].rxGenIdx =
+ ENET_IncreaseIndex(handle->rxBdRing[ringId].rxGenIdx, handle->rxBdRing[ringId].rxRingLen);
+
+ /* Ensure previous data update is completed with Data Synchronization Barrier before activing Rx BD. */
+ __DSB();
+
+ /* Actives the receive buffer descriptor. */
+ switch (ringId)
+ {
+ case kENET_Ring0:
+ base->RDAR = ENET_RDAR_RDAR_MASK;
+ break;
+#if FSL_FEATURE_ENET_QUEUE > 1
+ case kENET_Ring1:
+ base->RDAR1 = ENET_RDAR1_RDAR_MASK;
+ break;
+ case kENET_Ring2:
+ base->RDAR2 = ENET_RDAR2_RDAR_MASK;
+ break;
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ default:
+ assert(false);
+ base->RDAR = ENET_RDAR_RDAR_MASK;
+ break;
+ }
+}
+
+/*!
+ * brief Transmits an ENET frame for specified ring.
+ * note The CRC is automatically appended to the data. Input the data
+ * to send without the CRC.
+ *
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
+ * param data The data buffer provided by user to send.
+ * param length The length of the data to send.
+ * param ringId The ring index or ring number.
+ * param tsFlag Timestamp enable flag.
+ * param context Used by user to handle some events after transmit over.
+ * retval kStatus_Success Send frame succeed.
+ * retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission.
+ * The transmit busy happens when the data send rate is over the MAC capacity.
+ * The waiting mechanism is recommended to be added after each call return with
+ * kStatus_ENET_TxFrameBusy.
+ */
+status_t ENET_SendFrame(ENET_Type *base,
+ enet_handle_t *handle,
+ const uint8_t *data,
+ uint32_t length,
+ uint8_t ringId,
+ bool tsFlag,
+ void *context)
+{
+ assert(handle != NULL);
+ assert(data != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ volatile enet_tx_bd_struct_t *curBuffDescrip;
+ enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId];
+ enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId];
+ enet_frame_info_t *txDirty = NULL;
+ uint32_t len = 0;
+ uint32_t sizeleft = 0;
+ uint32_t address;
+ status_t result = kStatus_Success;
+ uint32_t src;
+ uint32_t configVal;
+ bool isReturn = false;
+
+ /* Check the frame length. */
+ if (length > ENET_FRAME_MAX_FRAMELEN)
+ {
+ result = kStatus_ENET_TxFrameOverLen;
+ }
+ else
+ {
+ /* Check if the transmit buffer is ready. */
+ curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
+ if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))
+ {
+ result = kStatus_ENET_TxFrameBusy;
+ }
+ /* Check txDirtyRing if need frameinfo in tx interrupt callback. */
+ else if ((handle->TxReclaimEnable[ringId]) && !ENET_TxDirtyRingAvailable(txDirtyRing))
+ {
+ result = kStatus_ENET_TxFrameBusy;
+ }
+ else
+ {
+ /* One transmit buffer is enough for one frame. */
+ if (handle->txBuffSizeAlign[ringId] >= length)
+ {
+ /* Copy data to the buffer for uDMA transfer. */
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
+#else
+ address = (uint32_t)curBuffDescrip->buffer;
+#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
+ (void)memcpy((void *)(uint32_t *)address, (const void *)(uint32_t *)(uint32_t)data, length);
+#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
+ if (handle->txMaintainEnable[ringId])
+ {
+ DCACHE_CleanByRange(address, length);
+ }
+#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
+ /* Set data length. */
+ curBuffDescrip->length = (uint16_t)length;
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ /* For enable the timestamp. */
+ if (tsFlag)
+ {
+ curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
+ }
+ else
+ {
+ curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK);
+ }
+
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+ curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
+
+ /* Increase the buffer descriptor address. */
+ txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen);
+
+ /* Add context to frame info ring */
+ if (handle->TxReclaimEnable[ringId])
+ {
+ txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx;
+ txDirty->context = context;
+ txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen);
+ if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx)
+ {
+ txDirtyRing->isFull = true;
+ }
+ txBdRing->txDescUsed++;
+ }
+
+ /* Active the transmit buffer descriptor. */
+ ENET_ActiveSend(base, ringId);
+ }
+ else
+ {
+ /* One frame requires more than one transmit buffers. */
+ do
+ {
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ /* For enable the timestamp. */
+ if (tsFlag)
+ {
+ curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
+ }
+ else
+ {
+ curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK);
+ }
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+ /* Update the size left to be transmit. */
+ sizeleft = length - len;
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
+#else
+ address = (uint32_t)curBuffDescrip->buffer;
+#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
+ src = (uint32_t)data + len;
+ if (sizeleft > handle->txBuffSizeAlign[ringId])
+ {
+ /* Data copy. */
+ (void)memcpy((uint32_t *)address, (uint32_t *)src, handle->txBuffSizeAlign[ringId]);
+#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
+ if (handle->txMaintainEnable[ringId])
+ {
+ /* Add the cache clean maintain. */
+ DCACHE_CleanByRange(address, handle->txBuffSizeAlign[ringId]);
+ }
+#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
+ /* Data length update. */
+ curBuffDescrip->length = handle->txBuffSizeAlign[ringId];
+ len += handle->txBuffSizeAlign[ringId];
+ /* Sets the control flag. */
+ configVal = (uint32_t)curBuffDescrip->control;
+ configVal &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
+ configVal |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
+ curBuffDescrip->control = (uint16_t)configVal;
+
+ if (handle->TxReclaimEnable[ringId])
+ {
+ txBdRing->txDescUsed++;
+ }
+ /* Active the transmit buffer descriptor*/
+ ENET_ActiveSend(base, ringId);
+ }
+ else
+ {
+ (void)memcpy((uint32_t *)address, (uint32_t *)src, sizeleft);
+#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
+ if (handle->txMaintainEnable[ringId])
+ {
+ /* Add the cache clean maintain. */
+ DCACHE_CleanByRange(address, sizeleft);
+ }
+#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
+ curBuffDescrip->length = (uint16_t)sizeleft;
+ /* Set Last buffer wrap flag. */
+ curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
+
+ if (handle->TxReclaimEnable[ringId])
+ {
+ /* Add context to frame info ring */
+ txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx;
+ txDirty->context = context;
+ txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen);
+ if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx)
+ {
+ txDirtyRing->isFull = true;
+ }
+ txBdRing->txDescUsed++;
+ }
+ /* Active the transmit buffer descriptor. */
+ ENET_ActiveSend(base, ringId);
+ isReturn = true;
+ break;
+ }
+ /* Increase and get the current buffer descriptor address. */
+ txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen);
+ curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
+
+ } while (0U == (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK));
+
+ if (isReturn == false)
+ {
+ result = kStatus_ENET_TxFrameBusy;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+/*!
+ * brief Enable or disable tx descriptors reclaim mechanism.
+ * note This function must be called when no pending send frame action.
+ * Set enable if you want to reclaim context or timestamp in interrupt.
+ *
+ * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
+ * param isEnable Enable or disable flag.
+ * param ringId The ring index or ring number.
+ * retval kStatus_Success Succeed to enable/disable Tx reclaim.
+ * retval kStatus_Fail Fail to enable/disable Tx reclaim.
+ */
+status_t ENET_SetTxReclaim(enet_handle_t *handle, bool isEnable, uint8_t ringId)
+{
+ assert(handle != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId];
+ enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId];
+
+ status_t result = kStatus_Success;
+
+ /* If tx dirty ring is empty, can set this flag and reset txConsumIdx */
+ if ((txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx) && ENET_TxDirtyRingAvailable(txDirtyRing))
+ {
+ if (isEnable)
+ {
+ handle->TxReclaimEnable[ringId] = true;
+ txBdRing->txConsumIdx = txBdRing->txGenIdx;
+ }
+ else
+ {
+ handle->TxReclaimEnable[ringId] = false;
+ }
+ }
+ else
+ {
+ result = kStatus_Fail;
+ }
+ return result;
+}
+
+/*!
+ * brief Reclaim tx descriptors.
+ * This function is used to update the tx descriptor status and
+ * store the tx timestamp when the 1588 feature is enabled.
+ * This is called by the transmit interupt IRQ handler after the
+ * complete of a frame transmission.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
+ * param ringId The ring index or ring number.
+ */
+static void ENET_ReclaimTxDescriptor(ENET_Type *base, enet_handle_t *handle, uint8_t ringId)
+{
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId];
+ volatile enet_tx_bd_struct_t *curBuffDescrip = txBdRing->txBdBase + txBdRing->txConsumIdx;
+ enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId];
+ enet_frame_info_t *txDirty = NULL;
+
+ /* Need to update the first index for transmit buffer free. */
+ while ((0U == (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)) && (txBdRing->txDescUsed > 0U))
+ {
+ if ((curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK) != 0U)
+ {
+ txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txConsumIdx;
+ txDirtyRing->txConsumIdx = ENET_IncreaseIndex(txDirtyRing->txConsumIdx, txDirtyRing->txRingLen);
+ txDirtyRing->isFull = false;
+
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ if ((curBuffDescrip->controlExtend1 & ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK) != 0U)
+ {
+ enet_ptp_time_t *ts = &txDirty->timeStamp;
+ /* Get transmit time stamp second. */
+ txDirty->isTsAvail = true;
+ ts->second = handle->msTimerSecond;
+ ts->nanosecond = curBuffDescrip->timestamp;
+ }
+#endif
+ }
+
+ /* For tx buffer free or requeue for each descriptor.
+ * The tx interrupt callback should free/requeue the tx buffer. */
+ if (handle->callback != NULL)
+ {
+#if FSL_FEATURE_ENET_QUEUE > 1
+ handle->callback(base, handle, ringId, kENET_TxEvent, txDirty, handle->userData);
+#else
+ handle->callback(base, handle, kENET_TxEvent, txDirty, handle->userData);
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+
+ /* Clean the txDirty pointer after used */
+ if (txDirty != NULL)
+ {
+ txDirty = NULL;
+ }
+ txBdRing->txDescUsed--;
+
+ /* Update the index. */
+ txBdRing->txConsumIdx = ENET_IncreaseIndex(txBdRing->txConsumIdx, txBdRing->txRingLen);
+ curBuffDescrip = txBdRing->txBdBase + txBdRing->txConsumIdx;
+ }
+}
+
+/*!
+ * brief Get a receive buffer pointer of the ENET device for specified ring.
+ *
+ * This function can get the data address which stores frame. Then can analyze these data directly without doing any
+ * memory copy. When the frame locates in multiple BD buffer, need to repeat calling this function until isLastBuff=true
+ * (need to store the temp buf pointer everytime call this function). After finishing the analysis of this frame,
+ * call ENET_ReleaseRxBuffer to release rxbuff memory to DMA.
+ * This is an example:
+ * code
+ * uint32_t length;
+ * uint8_t *buf = NULL;
+ * uint32_t data_len = 0;
+ * bool isLastBuff = false;
+ * enet_handle_t g_handle;
+ * status_t status;
+ * status = ENET_GetRxFrameSize(&g_handle, &length, 0);
+ * if (length != 0)
+ * {
+ * ENET_GetRxBuffer(EXAMPLE_ENET, &g_handle, &buf, &data_len, 0, &isLastBuff, NULL);
+ * ENET_ReleaseRxBuffer(EXAMPLE_ENET, &g_handle, buf, 0);
+ * }
+ * endcode
+ * param base ENET peripheral base address.
+ * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
+ * param buffer The data buffer pointer to store the frame.
+ * param length The size of the data buffer. If isLastBuff=false, it represents data length of this buffer. If
+ * isLastBuff=true, it represents data length of total frame.
+ * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
+ * param isLastBuff The flag represents whether this buffer is the last buffer to store frame.
+ * param ts The 1588 timestamp value, vaild in last buffer.
+ * retval kStatus_Success Get receive buffer succeed.
+ * retval kStatus_ENET_RxFrameFail Get receive buffer fails, it's owned by application, should wait app to release this
+ * buffer.
+ */
+status_t ENET_GetRxBuffer(ENET_Type *base,
+ enet_handle_t *handle,
+ void **buffer,
+ uint32_t *length,
+ uint8_t ringId,
+ bool *isLastBuff,
+ uint32_t *ts)
+{
+ assert(handle != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+ assert(handle->rxBdRing[ringId].rxBdBase != NULL);
+
+ enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId];
+ volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
+ uint32_t address;
+
+ /* Check if current rx BD is under usage by certain application */
+ /* Buffer owner flag, 1: owned by application, 0: owned by driver */
+ if ((curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK) == 0U)
+ {
+ curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK;
+ }
+ else
+ {
+ return kStatus_ENET_RxFrameFail;
+ }
+
+/* A frame on one buffer or several receive buffers are both considered. */
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local);
+#else
+ address = (uint32_t)curBuffDescrip->buffer;
+#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
+#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL
+ if (handle->rxMaintainEnable[ringId])
+ {
+ /* Add the cache invalidate maintain. */
+ DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[ringId]);
+ }
+#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */
+
+ *buffer = (void *)(uint32_t *)address;
+ *length = curBuffDescrip->length;
+
+ /* The last buffer descriptor of a frame. */
+ if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK))
+ {
+ /* This is a valid frame. */
+ *isLastBuff = true;
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ if (ts != NULL)
+ {
+ *ts = curBuffDescrip->timestamp;
+ }
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+ }
+ else
+ {
+ *isLastBuff = false;
+ }
+
+ /* Increase current buffer descriptor to the next one. */
+ rxBdRing->rxGenIdx = ENET_IncreaseIndex(rxBdRing->rxGenIdx, rxBdRing->rxRingLen);
+
+ return kStatus_Success;
+}
+
+/*!
+ * brief Release receive buffer descriptor to DMA.
+ *
+ * This function can release specified BD owned by application, meanwhile it may rearrange the BD to let the no-owned
+ * BDs always in back of the index of DMA transfer. So for the situation that releasing order is not same as the getting
+ * order, the rearrangement makes all ready BDs can be used by DMA.
+ * note This function can't be interrupted by ENET_GetRxBuffer, so in application must make sure ENET_GetRxBuffer is
+ * called before or after this function. And this function itself isn't thread safe due to BD content exchanging.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init.
+ * param buffer The buffer address to store frame, using it to find the correspond BD and release it.
+ * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
+ */
+void ENET_ReleaseRxBuffer(ENET_Type *base, enet_handle_t *handle, void *buffer, uint8_t ringId)
+{
+ assert(handle != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId];
+ enet_rx_bd_struct_t *ownBuffDescrip = (enet_rx_bd_struct_t *)(uint32_t)rxBdRing->rxBdBase;
+ enet_rx_bd_struct_t *blockBuffDescrip = (enet_rx_bd_struct_t *)(uint32_t)rxBdRing->rxBdBase + rxBdRing->rxGenIdx;
+ enet_rx_bd_struct_t tempBuffDescrip;
+ uint16_t index = rxBdRing->rxGenIdx;
+ bool isReleaseBd = false;
+
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ buffer = (void *)(uint32_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)(uint32_t *)buffer, kMEMORY_Local2DMA);
+#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
+
+ do
+ {
+ /* Find the BD for releasing, do nothing if it's not owned by application. */
+ if (buffer == ownBuffDescrip->buffer)
+ {
+ if (0U != (ownBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK))
+ {
+ isReleaseBd = true;
+ break;
+ }
+ }
+
+ if (0U != (ownBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK))
+ {
+ break;
+ }
+ ownBuffDescrip++;
+ } while (true);
+
+ if (isReleaseBd)
+ {
+ /* Find the first BD owned by application after rxBdCurrent, isReleaseBd is true so there's at least one BD is
+ * owned by application */
+ do
+ {
+ if (0U != (blockBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK))
+ {
+ break;
+ }
+ if (0U != (blockBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK))
+ {
+ blockBuffDescrip = (enet_rx_bd_struct_t *)(uint32_t)rxBdRing->rxBdBase;
+ }
+ else
+ {
+ blockBuffDescrip++;
+ }
+ index = ENET_IncreaseIndex(index, rxBdRing->rxRingLen);
+ } while (index != rxBdRing->rxGenIdx);
+
+ /* If the BD ready for releasing isn't the first BD owned by application after rxBdCurrent then exchange the two
+ * BDs */
+ if (blockBuffDescrip != ownBuffDescrip)
+ {
+ /* Exchange buffer descriptor content */
+ tempBuffDescrip = *ownBuffDescrip;
+ *ownBuffDescrip = *blockBuffDescrip;
+ *blockBuffDescrip = tempBuffDescrip;
+
+ /* Maintain the wrap flag */
+ if (0U != (ownBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK))
+ {
+ ownBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_RX_WRAP_MASK);
+ blockBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
+ }
+ else if (0U != (blockBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK))
+ {
+ blockBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_RX_WRAP_MASK);
+ ownBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
+ }
+ else
+ {
+ /* Intentional empty */
+ }
+
+ /* Clears status including the owner flag. */
+ blockBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
+ /* Sets the receive buffer descriptor with the empty flag. */
+ blockBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
+ }
+ else
+ {
+ /* Clears status including the owner flag. */
+ ownBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK;
+ /* Sets the receive buffer descriptor with the empty flag. */
+ ownBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK;
+ }
+
+ /* Ensure previous data update is completed with Data Synchronization Barrier before activing Rx BD. */
+ __DSB();
+
+ /* Actives the receive buffer descriptor. */
+ base->RDAR = ENET_RDAR_RDAR_MASK;
+ }
+}
+
+/*!
+ * brief Transmits an ENET frame for specified ring with zero-copy.
+ * note The CRC is automatically appended to the data. Input the data
+ * to send without the CRC. The frame must store in continuous memeory
+ * and need to check the buffer start address alignment based on your
+ * device, otherwise it has issue or can't get highest DMA transmit speed.
+ *
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
+ * param data The data buffer provided by user to send.
+ * param length The length of the data to send.
+ * param ringId The ring index or ring number.
+ * param tsFlag Timestamp enable flag.
+ * param context Used by user to handle some events after transmit over.
+ * retval kStatus_Success Send frame succeed.
+ * retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission.
+ * The transmit busy happens when the data send rate is over the MAC capacity.
+ * The waiting mechanism is recommended to be added after each call return with
+ * kStatus_ENET_TxFrameBusy.
+ */
+status_t ENET_SendFrameZeroCopy(ENET_Type *base,
+ enet_handle_t *handle,
+ const uint8_t *data,
+ uint32_t length,
+ uint8_t ringId,
+ bool tsFlag,
+ void *context)
+{
+ assert(handle != NULL);
+ assert(data != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ volatile enet_tx_bd_struct_t *curBuffDescrip;
+ enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId];
+ enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId];
+ enet_frame_info_t *txDirty = NULL;
+ uint32_t len = 0;
+ uint32_t sizeleft = 0;
+ status_t result = kStatus_Success;
+ uint8_t *data_temp;
+ uint32_t configVal;
+ bool isReturn = false;
+
+ /* Check the frame length. */
+ if (length > ENET_FRAME_MAX_FRAMELEN)
+ {
+ result = kStatus_ENET_TxFrameOverLen;
+ }
+ else
+ {
+ /* Check if the transmit buffer is ready. */
+ curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
+ if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))
+ {
+ result = kStatus_ENET_TxFrameBusy;
+ }
+ /* Check txDirtyRing if need frameinfo in tx interrupt callback. */
+ else if (handle->TxReclaimEnable[ringId] && !ENET_TxDirtyRingAvailable(txDirtyRing))
+ {
+ result = kStatus_ENET_TxFrameBusy;
+ }
+ else
+ {
+ /* One transmit buffer is enough for one frame. */
+ if (handle->txBuffSizeAlign[ringId] >= length)
+ {
+ /* Copy data to the buffer for uDMA transfer. */
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ data = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)data, kMEMORY_Local2DMA);
+#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
+ curBuffDescrip->buffer = (uint8_t *)(uint32_t)data;
+ /* Set data length. */
+ curBuffDescrip->length = (uint16_t)length;
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ /* For enable the timestamp. */
+ if (tsFlag)
+ {
+ curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
+ }
+ else
+ {
+ curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK);
+ }
+
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+ curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
+
+ /* Increase the buffer descriptor address. */
+ txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen);
+
+ /* Add context to frame info ring */
+ if (handle->TxReclaimEnable[ringId])
+ {
+ txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx;
+ txDirty->context = context;
+ txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen);
+ if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx)
+ {
+ txDirtyRing->isFull = true;
+ }
+ txBdRing->txDescUsed++;
+ }
+
+ /* Active the transmit buffer descriptor. */
+ ENET_ActiveSend(base, ringId);
+ }
+ else
+ {
+ /* One frame requires more than one transmit buffers. */
+ do
+ {
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ /* For enable the timestamp. */
+ if (tsFlag)
+ {
+ curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
+ }
+ else
+ {
+ curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK);
+ }
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+ /* Update the size left to be transmit. */
+ sizeleft = length - len;
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ data = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)data, kMEMORY_Local2DMA);
+#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
+ data_temp = (uint8_t *)(uint32_t)data + len;
+ if (sizeleft > handle->txBuffSizeAlign[ringId])
+ {
+ /* Data copy. */
+ curBuffDescrip->buffer = data_temp;
+ /* Data length update. */
+ curBuffDescrip->length = handle->txBuffSizeAlign[ringId];
+ len += handle->txBuffSizeAlign[ringId];
+ /* Sets the control flag. */
+ configVal = (uint32_t)curBuffDescrip->control;
+ configVal &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
+ configVal |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
+ curBuffDescrip->control = (uint16_t)configVal;
+
+ if (handle->TxReclaimEnable[ringId])
+ {
+ txBdRing->txDescUsed++;
+ }
+ /* Active the transmit buffer descriptor*/
+ ENET_ActiveSend(base, ringId);
+ }
+ else
+ {
+ curBuffDescrip->buffer = data_temp;
+ curBuffDescrip->length = (uint16_t)sizeleft;
+ /* Set Last buffer wrap flag. */
+ curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK;
+
+ if (handle->TxReclaimEnable[ringId])
+ {
+ /* Add context to frame info ring */
+ txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx;
+ txDirty->context = context;
+ txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen);
+ if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx)
+ {
+ txDirtyRing->isFull = true;
+ }
+ txBdRing->txDescUsed++;
+ }
+ /* Active the transmit buffer descriptor. */
+ ENET_ActiveSend(base, ringId);
+ isReturn = true;
+ break;
+ }
+ /* Increase and get the current buffer descriptor address. */
+ txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen);
+ curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
+
+ } while (0U == (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK));
+
+ if (isReturn == false)
+ {
+ result = kStatus_ENET_TxFrameBusy;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+/*!
+ * brief Set up ENET Tx buffer descriptor, preparing for one frame stores in scattered buffer.
+ * This function only set one Tx BD everytime calls, all ready data will be sent out with last flag sets or
+ * gets error. Send frame succeeds with last flag sets, then you can get context from frameInfo in callback.
+ * note The CRC is automatically appended to the data. Input the data to send without the CRC. And if doesn't
+ * succeed to call this function, user can't get context in frameInfo of callback.
+ *
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init.
+ * param data The data buffer provided by user to send.
+ * param length The length of the data to send.
+ * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
+ * param txFlag This function uses timestamp enable flag, last BD flag.
+ * param context Used by user to handle some events after transmit over.
+ * retval kStatus_Success Send frame succeed.
+ * retval kStatus_ENET_TxFrameOverLen Buffer length isn't enough to store data.
+ * retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission.
+ * The transmit busy happens when the data send rate is over the MAC capacity.
+ */
+status_t ENET_SetTxBuffer(ENET_Type *base,
+ enet_handle_t *handle,
+ const uint8_t *data,
+ uint32_t length,
+ uint8_t ringId,
+ uint8_t txFlag,
+ void *context)
+{
+ assert(handle != NULL);
+ assert(data != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId];
+ enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId];
+ enet_frame_info_t *txDirty = NULL;
+ volatile enet_tx_bd_struct_t *curBuffDescrip;
+ volatile enet_tx_bd_struct_t *tempBuffDescrip;
+ status_t result = kStatus_Success;
+ uint16_t index;
+
+ /* Check the data length. */
+ if (handle->txBuffSizeAlign[ringId] < length)
+ {
+ result = kStatus_ENET_TxFrameOverLen;
+ }
+ /* Check txDirtyRing if need frameinfo in tx interrupt callback. */
+ else if (handle->TxReclaimEnable[ringId] && !ENET_TxDirtyRingAvailable(txDirtyRing))
+ {
+ result = kStatus_ENET_TxFrameBusy;
+ }
+ else
+ {
+ /* Check if the transmit buffer is ready or ring with framinfo is full. */
+ curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
+ if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))
+ {
+ result = kStatus_ENET_TxFrameBusy;
+ }
+ else
+ {
+ /* Prepare data address for uDMA transfer. */
+#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET
+ data = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)data, kMEMORY_Local2DMA);
+#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */
+ curBuffDescrip->buffer = (uint8_t *)(uint32_t)data;
+
+ /* Set data length. */
+ curBuffDescrip->length = (uint16_t)length;
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+ /* For enable the timestamp. */
+ if ((txFlag & ENET_TX_TIMESTAMP_FLAG) != 0U)
+ {
+ curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK;
+ }
+ else
+ {
+ curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK);
+ }
+
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+ if (handle->TxReclaimEnable[ringId])
+ {
+ txBdRing->txDescUsed++;
+ }
+ /* If BD is full or last flag sets, send out all data */
+ if ((txFlag & ENET_TX_LAST_BD_FLAG) != 0U)
+ {
+ /* Set all configurated BDs with own flag ready */
+ tempBuffDescrip = curBuffDescrip;
+ index = txBdRing->txGenIdx;
+ do
+ {
+ if ((tempBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK) != 0U)
+ {
+ tempBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK);
+ tempBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
+ }
+ index = ENET_IncreaseIndex(index, txBdRing->txRingLen);
+ tempBuffDescrip = txBdRing->txBdBase + index;
+ } while (tempBuffDescrip != curBuffDescrip);
+
+ /* Add context to frame info ring */
+ if (handle->TxReclaimEnable[ringId])
+ {
+ txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx;
+ txDirty->context = context;
+ txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen);
+ if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx)
+ {
+ txDirtyRing->isFull = true;
+ }
+ }
+
+ curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
+
+ /* Active the transmit buffer descriptor. */
+ ENET_ActiveSend(base, 0);
+ }
+ else
+ {
+ curBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_LAST_MASK);
+ /* Set owner flag, need to set Tx ready for all BDs with this flag after configurating last BD */
+ curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK;
+ }
+
+ /* Increase the buffer descriptor address. */
+ txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen);
+ }
+ }
+
+ /* If fails to send whole frame success, need to send out all left ready data in BDs, make sure. */
+ if (result != kStatus_Success)
+ {
+ tempBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
+ index = txBdRing->txGenIdx;
+ do
+ {
+ if ((tempBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK) != 0U)
+ {
+ tempBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK);
+ tempBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK;
+ }
+ index = ENET_IncreaseIndex(index, txBdRing->txRingLen);
+ tempBuffDescrip = txBdRing->txBdBase + index;
+ } while (index != txBdRing->txGenIdx);
+ }
+
+ return result;
+}
+
+/*!
+ * brief Adds the ENET device to a multicast group.
+ *
+ * param base ENET peripheral base address.
+ * param address The six-byte multicast group address which is provided by application.
+ */
+void ENET_AddMulticastGroup(ENET_Type *base, uint8_t *address)
+{
+ assert(address != NULL);
+
+ uint32_t crc = 0xFFFFFFFFU;
+ uint32_t count1 = 0;
+ uint32_t count2 = 0;
+ uint32_t configVal = 0;
+
+ /* Calculates the CRC-32 polynomial on the multicast group address. */
+ for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
+ {
+ uint8_t c = address[count1];
+ for (count2 = 0; count2 < 0x08U; count2++)
+ {
+ if (0U != ((c ^ crc) & 1U))
+ {
+ crc >>= 1U;
+ c >>= 1U;
+ crc ^= 0xEDB88320U;
+ }
+ else
+ {
+ crc >>= 1U;
+ c >>= 1U;
+ }
+ }
+ }
+
+ /* Enable a multicast group address. */
+ configVal = 1U;
+ configVal = configVal << ((crc >> 0x1AU) & 0x1FU);
+
+ if (0U == ((crc >> 0x1FU) & 1U))
+ {
+ base->GALR |= configVal;
+ }
+ else
+ {
+ base->GAUR |= configVal;
+ }
+}
+
+/*!
+ * brief Moves the ENET device from a multicast group.
+ *
+ * param base ENET peripheral base address.
+ * param address The six-byte multicast group address which is provided by application.
+ */
+void ENET_LeaveMulticastGroup(ENET_Type *base, uint8_t *address)
+{
+ assert(address != NULL);
+
+ uint32_t crc = 0xFFFFFFFFU;
+ uint32_t count1 = 0;
+ uint32_t count2 = 0;
+ uint32_t configVal = 0;
+
+ /* Calculates the CRC-32 polynomial on the multicast group address. */
+ for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++)
+ {
+ uint8_t c = address[count1];
+ for (count2 = 0; count2 < 0x08U; count2++)
+ {
+ if (0U != ((c ^ crc) & 1U))
+ {
+ crc >>= 1U;
+ c >>= 1U;
+ crc ^= 0xEDB88320U;
+ }
+ else
+ {
+ crc >>= 1U;
+ c >>= 1U;
+ }
+ }
+ }
+
+ /* Set the hash table. */
+ configVal = 1U;
+ configVal = ~(configVal << ((crc >> 0x1AU) & 0x1FU));
+ if (0U == ((crc >> 0x1FU) & 1U))
+ {
+ base->GALR &= configVal;
+ }
+ else
+ {
+ base->GAUR &= configVal;
+ }
+}
+
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+/*!
+ * brief Gets the ENET transmit frame statistics after the data send for specified ring.
+ *
+ * This interface gets the error statistics of the transmit frame.
+ * Because the error information is reported by the uDMA after the data delivery, this interface
+ * should be called after the data transmit API. It is recommended to call this function on
+ * transmit interrupt handler. After calling the ENET_SendFrame, the
+ * transmit interrupt notifies the transmit completion.
+ *
+ * param handle The PTP handler pointer. This is the same handler pointer used in the ENET_Init.
+ * param eErrorStatic The error statistics structure pointer.
+ * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1.
+ * return The execute status.
+ */
+status_t ENET_GetTxErrAfterSendFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic, uint8_t ringId)
+{
+ assert(handle != NULL);
+ assert(eErrorStatic != NULL);
+ assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE);
+
+ uint16_t control = 0;
+ uint16_t controlExt = 0;
+ status_t result = kStatus_Success;
+ bool isReturn = false;
+ enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId];
+ volatile enet_tx_bd_struct_t *curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx;
+
+ do
+ {
+ /* Get the current dirty transmit buffer descriptor. */
+ control = handle->txBdDirtyStatic[ringId]->control;
+ controlExt = handle->txBdDirtyStatic[ringId]->controlExtend0;
+
+ /* Get the control status data, If the buffer descriptor has not been processed break out. */
+ if (0U != (control & ENET_BUFFDESCRIPTOR_TX_READY_MASK))
+ {
+ result = kStatus_ENET_TxFrameBusy;
+ isReturn = true;
+ break;
+ }
+
+ /* Increase the transmit dirty static pointer. */
+ if (0U != (handle->txBdDirtyStatic[ringId]->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK))
+ {
+ handle->txBdDirtyStatic[ringId] = txBdRing->txBdBase;
+ }
+ else
+ {
+ handle->txBdDirtyStatic[ringId]++;
+ }
+
+ /* If the transmit buffer descriptor is ready and the last buffer descriptor, store packet statistic. */
+ if (0U != (control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK))
+ {
+ if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_ERR_MASK))
+ {
+ /* Transmit error. */
+ eErrorStatic->statsTxErr++;
+ }
+ if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_EXCCOLLISIONERR_MASK))
+ {
+ /* Transmit excess collision error. */
+ eErrorStatic->statsTxExcessCollisionErr++;
+ }
+ if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_LATECOLLISIONERR_MASK))
+ {
+ /* Transmit late collision error. */
+ eErrorStatic->statsTxLateCollisionErr++;
+ }
+ if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_UNDERFLOWERR_MASK))
+ {
+ /* Transmit under flow error. */
+ eErrorStatic->statsTxUnderFlowErr++;
+ }
+ if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_OVERFLOWERR_MASK))
+ {
+ /* Transmit over flow error. */
+ eErrorStatic->statsTxOverFlowErr++;
+ }
+ isReturn = true;
+ break;
+ }
+
+ } while (handle->txBdDirtyStatic[ringId] != curBuffDescrip);
+
+ if (isReturn == false)
+ {
+ result = kStatus_ENET_TxFrameFail;
+ }
+ return result;
+}
+
+void ENET_Ptp1588ConfigureHandler(ENET_Type *base, enet_handle_t *handle, enet_ptp_config_t *ptpConfig)
+{
+ assert(handle != NULL);
+ assert(ptpConfig != NULL);
+ uint8_t count;
+
+ uint32_t mask = (uint32_t)kENET_TxBufferInterrupt;
+#if FSL_FEATURE_ENET_QUEUE > 1
+ mask |= (uint32_t)kENET_TxBuffer1Interrupt | (uint32_t)kENET_TxBuffer2Interrupt;
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+
+ for (count = 0; count < handle->ringNum; count++)
+ {
+ handle->txBdDirtyStatic[count] = handle->txBdRing[count].txBdBase;
+ }
+
+ /* Setting the receive and transmit state for transaction. */
+ handle->msTimerSecond = 0;
+
+ /* Enables the time stamp interrupt and transmit frame interrupt to
+ * handle the time-stamp . */
+ ENET_EnableInterrupts(base, (ENET_TS_INTERRUPT | ENET_TX_INTERRUPT));
+ ENET_DisableInterrupts(base, mask);
+
+ /* Set the IRQ handler when the interrupt is enabled. */
+ ENET_SetTsISRHandler(base, ENET_TimeStampIRQHandler);
+ ENET_SetTxISRHandler(base, ENET_TransmitIRQHandler);
+}
+
+/*!
+ * brief Configures the ENET PTP IEEE 1588 feature with the basic configuration.
+ * The function sets the clock for PTP 1588 timer and enables
+ * time stamp interrupts and transmit interrupts for PTP 1588 features.
+ * This API should be called when the 1588 feature is enabled
+ * or the ENET_ENHANCEDBUFFERDESCRIPTOR_MODE is defined.
+ * ENET_Init should be called before calling this API.
+ *
+ * note The PTP 1588 time-stamp second increase though time-stamp interrupt handler
+ * and the transmit time-stamp store is done through transmit interrupt handler.
+ * As a result, the TS interrupt and TX interrupt are enabled when you call this API.
+ *
+ * param base ENET peripheral base address.
+ * param handle ENET handler pointer.
+ * param ptpConfig The ENET PTP1588 configuration.
+ */
+void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_config_t *ptpConfig)
+{
+ assert(handle != NULL);
+ assert(ptpConfig != NULL);
+
+ /* Start the 1588 timer. */
+ ENET_Ptp1588StartTimer(base, ptpConfig->ptp1588ClockSrc_Hz);
+
+ ENET_Ptp1588ConfigureHandler(base, handle, ptpConfig);
+}
+
+/*!
+ * brief Starts the ENET PTP 1588 Timer.
+ * This function is used to initialize the PTP timer. After the PTP starts,
+ * the PTP timer starts running.
+ *
+ * param base ENET peripheral base address.
+ * param ptpClkSrc The clock source of the PTP timer.
+ */
+void ENET_Ptp1588StartTimer(ENET_Type *base, uint32_t ptpClkSrc)
+{
+ /* Restart PTP 1588 timer, master clock. */
+ base->ATCR = ENET_ATCR_RESTART_MASK;
+
+ /* Initializes PTP 1588 timer. */
+ base->ATINC = ENET_ATINC_INC(ENET_NANOSECOND_ONE_SECOND / ptpClkSrc);
+ base->ATPER = ENET_NANOSECOND_ONE_SECOND;
+ /* Sets periodical event and the event signal output assertion and Actives PTP 1588 timer. */
+ base->ATCR = ENET_ATCR_PEREN_MASK | ENET_ATCR_PINPER_MASK | ENET_ATCR_EN_MASK;
+}
+
+/*!
+ * brief Gets the current ENET time from the PTP 1588 timer.
+ * Interrupts are not disabled.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
+ * param ptpTime The PTP timer structure.
+ */
+void ENET_Ptp1588GetTimerNoIrqDisable(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
+{
+ uint16_t count = ENET_1588TIME_DELAY_COUNT;
+
+ /* Get the current PTP time. */
+ ptpTime->second = handle->msTimerSecond;
+ /* Get the nanosecond from the master timer. */
+ base->ATCR |= ENET_ATCR_CAPTURE_MASK;
+ /* Add at least six clock cycle delay to get accurate time.
+ It's the requirement when the 1588 clock source is slower
+ than the register clock.
+ */
+ while (0U != (count--))
+ {
+ __NOP();
+ }
+ /* Get the captured time. */
+ ptpTime->nanosecond = base->ATVR;
+}
+
+/*!
+ * brief Gets the current ENET time from the PTP 1588 timer.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
+ * param ptpTime The PTP timer structure.
+ */
+void ENET_Ptp1588GetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
+{
+ assert(handle != NULL);
+ assert(ptpTime != NULL);
+ uint32_t primask;
+
+ /* Disables the interrupt. */
+ primask = DisableGlobalIRQ();
+
+ ENET_Ptp1588GetTimerNoIrqDisable(base, handle, ptpTime);
+
+ /* Get PTP timer wrap event. */
+ if (0U != (base->EIR & (uint32_t)kENET_TsTimerInterrupt))
+ {
+ ptpTime->second++;
+ }
+
+ /* Enables the interrupt. */
+ EnableGlobalIRQ(primask);
+}
+
+/*!
+ * brief Sets the ENET PTP 1588 timer to the assigned time.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
+ * param ptpTime The timer to be set to the PTP timer.
+ */
+void ENET_Ptp1588SetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime)
+{
+ assert(handle != NULL);
+ assert(ptpTime != NULL);
+
+ uint32_t primask;
+
+ /* Disables the interrupt. */
+ primask = DisableGlobalIRQ();
+
+ /* Sets PTP timer. */
+ handle->msTimerSecond = ptpTime->second;
+ base->ATVR = ptpTime->nanosecond;
+
+ /* Enables the interrupt. */
+ EnableGlobalIRQ(primask);
+}
+
+/*!
+ * brief Adjusts the ENET PTP 1588 timer.
+ *
+ * param base ENET peripheral base address.
+ * param corrIncrease The correction increment value. This value is added every time the correction
+ * timer expires. A value less than the PTP timer frequency(1/ptpClkSrc) slows down the timer,
+ * a value greater than the 1/ptpClkSrc speeds up the timer.
+ * param corrPeriod The PTP timer correction counter wrap-around value. This defines after how
+ * many timer clock the correction counter should be reset and trigger a correction
+ * increment on the timer. A value of 0 disables the correction counter and no correction occurs.
+ */
+void ENET_Ptp1588AdjustTimer(ENET_Type *base, uint32_t corrIncrease, uint32_t corrPeriod)
+{
+ /* Set correction for PTP timer increment. */
+ base->ATINC = (base->ATINC & ~ENET_ATINC_INC_CORR_MASK) | (corrIncrease << ENET_ATINC_INC_CORR_SHIFT);
+ /* Set correction for PTP timer period. */
+ base->ATCOR = (base->ATCOR & ~ENET_ATCOR_COR_MASK) | (corrPeriod << ENET_ATCOR_COR_SHIFT);
+}
+
+#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB
+/*!
+ * brief Sets the ENET AVB feature.
+ *
+ * ENET AVB feature configuration, set the Receive classification match and transmit
+ * bandwidth. This API is called when the AVB feature is required.
+ *
+ * Note: The AVB frames transmission scheme is credit-based tx scheme and it's only supported
+ * with the Enhanced buffer descriptors. so the AVB configuration should only done with
+ * Enhanced buffer descriptor. so when the AVB feature is required, please make sure the
+ * the "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" is defined.
+ *
+ * param base ENET peripheral base address.
+ * param handle ENET handler pointer.
+ * param config The ENET AVB feature configuration structure.
+ */
+void ENET_AVBConfigure(ENET_Type *base, enet_handle_t *handle, const enet_avb_config_t *config)
+{
+ assert(config != NULL);
+
+ uint8_t count = 0;
+
+ for (count = 0; count < (uint8_t)FSL_FEATURE_ENET_QUEUE - 1U; count++)
+ {
+ /* Set the AVB receive ring classification match when the match is not 0. */
+ if (0U != (config->rxClassifyMatch[count]))
+ {
+ base->RCMR[count] = ((uint32_t)config->rxClassifyMatch[count] & 0xFFFFU) | ENET_RCMR_MATCHEN_MASK;
+ }
+ /* Set the dma controller for the extended ring. */
+ base->DMACFG[count] |= ENET_DMACFG_IDLE_SLOPE(config->idleSlope[count]);
+ }
+
+ /* Shall use the credit-based scheme for avb. */
+ base->QOS &= ~ENET_QOS_TX_SCHEME_MASK;
+ base->QOS |= ENET_QOS_RX_FLUSH0_MASK;
+}
+#endif /* FSL_FETAURE_ENET_HAS_AVB */
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+#if FSL_FEATURE_ENET_QUEUE > 1
+/*!
+ * brief The transmit IRQ handler.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler pointer.
+ */
+void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle, uint32_t ringId)
+#else
+/*!
+ * brief The transmit IRQ handler.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler pointer.
+ */
+void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle)
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+{
+ assert(handle != NULL);
+ uint32_t mask = (uint32_t)kENET_TxBufferInterrupt | (uint32_t)kENET_TxFrameInterrupt;
+ uint32_t index = 0;
+ uint32_t irq;
+
+/* Check if the transmit interrupt happen. */
+#if FSL_FEATURE_ENET_QUEUE > 1
+ switch (ringId)
+ {
+ case kENET_Ring1:
+ mask = ((uint32_t)kENET_TxFrame1Interrupt | (uint32_t)kENET_TxBuffer1Interrupt);
+ break;
+ case kENET_Ring2:
+ mask = ((uint32_t)kENET_TxFrame2Interrupt | (uint32_t)kENET_TxBuffer2Interrupt);
+ break;
+ default:
+ mask = (uint32_t)kENET_TxBufferInterrupt | (uint32_t)kENET_TxFrameInterrupt;
+ break;
+ }
+ index = ringId;
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+
+ while (0U != (mask & base->EIR))
+ {
+ irq = base->EIR;
+
+ /* Clear the transmit interrupt event. */
+ base->EIR = mask;
+
+ /* Callback Handler. */
+ if (handle->TxReclaimEnable[index] && (0U != (irq & (uint32_t)kENET_TxFrameInterrupt)))
+ {
+ ENET_ReclaimTxDescriptor(base, handle, (uint8_t)index);
+ }
+ else
+ {
+ if (NULL != handle->callback)
+ {
+#if FSL_FEATURE_ENET_QUEUE > 1
+ handle->callback(base, handle, index, kENET_TxEvent, NULL, handle->userData);
+#else
+ handle->callback(base, handle, kENET_TxEvent, NULL, handle->userData);
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+ }
+ }
+}
+
+#if FSL_FEATURE_ENET_QUEUE > 1
+/*!
+ * brief The receive IRQ handler.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler pointer.
+ */
+void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle, uint32_t ringId)
+#else
+/*!
+ * brief The receive IRQ handler.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler pointer.
+ */
+void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle)
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+{
+ assert(handle != NULL);
+ uint32_t mask = (uint32_t)kENET_RxFrameInterrupt | (uint32_t)kENET_RxBufferInterrupt;
+
+/* Check if the receive interrupt happen. */
+#if FSL_FEATURE_ENET_QUEUE > 1
+ switch (ringId)
+ {
+ case kENET_Ring1:
+ mask = ((uint32_t)kENET_RxFrame1Interrupt | (uint32_t)kENET_RxBuffer1Interrupt);
+ break;
+ case kENET_Ring2:
+ mask = ((uint32_t)kENET_RxFrame2Interrupt | (uint32_t)kENET_RxBuffer2Interrupt);
+ break;
+ default:
+ mask = (uint32_t)kENET_RxFrameInterrupt | (uint32_t)kENET_RxBufferInterrupt;
+ break;
+ }
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+
+ while (0U != (mask & base->EIR))
+ {
+ /* Clear the transmit interrupt event. */
+ base->EIR = mask;
+
+ /* Callback function. */
+ if (NULL != handle->callback)
+ {
+#if FSL_FEATURE_ENET_QUEUE > 1
+ handle->callback(base, handle, ringId, kENET_RxEvent, NULL, handle->userData);
+#else
+ handle->callback(base, handle, kENET_RxEvent, NULL, handle->userData);
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+ }
+}
+
+/*!
+ * brief Some special IRQ handler including the error, mii, wakeup irq handler.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET handler pointer.
+ */
+void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle)
+{
+ assert(handle != NULL);
+
+ uint32_t errMask = (uint32_t)kENET_BabrInterrupt | (uint32_t)kENET_BabtInterrupt | (uint32_t)kENET_EBusERInterrupt |
+ (uint32_t)kENET_PayloadRxInterrupt | (uint32_t)kENET_LateCollisionInterrupt |
+ (uint32_t)kENET_RetryLimitInterrupt | (uint32_t)kENET_UnderrunInterrupt;
+
+ /* Check if the error interrupt happen. */
+ if (0U != ((uint32_t)kENET_WakeupInterrupt & base->EIR))
+ {
+ /* Clear the wakeup interrupt. */
+ base->EIR = (uint32_t)kENET_WakeupInterrupt;
+ /* wake up and enter the normal mode. */
+ ENET_EnableSleepMode(base, false);
+ /* Callback function. */
+ if (NULL != handle->callback)
+ {
+#if FSL_FEATURE_ENET_QUEUE > 1
+ handle->callback(base, handle, 0, kENET_WakeUpEvent, NULL, handle->userData);
+#else
+ handle->callback(base, handle, kENET_WakeUpEvent, NULL, handle->userData);
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+ }
+ else
+ {
+ /* Clear the error interrupt event status. */
+ errMask &= base->EIR;
+ base->EIR = errMask;
+ /* Callback function. */
+ if (NULL != handle->callback)
+ {
+#if FSL_FEATURE_ENET_QUEUE > 1
+ handle->callback(base, handle, 0, kENET_ErrEvent, NULL, handle->userData);
+#else
+ handle->callback(base, handle, kENET_ErrEvent, NULL, handle->userData);
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
+/*!
+ * brief The IEEE 1588 PTP time stamp interrupt handler.
+ *
+ * param base ENET peripheral base address.
+ * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init.
+ */
+void ENET_TimeStampIRQHandler(ENET_Type *base, enet_handle_t *handle)
+{
+ assert(handle != NULL);
+
+ /* Check if the PTP time stamp interrupt happen. */
+ if (0U != ((uint32_t)kENET_TsTimerInterrupt & base->EIR))
+ {
+ /* Clear the time stamp interrupt. */
+ base->EIR = (uint32_t)kENET_TsTimerInterrupt;
+
+ /* Increase timer second counter. */
+ handle->msTimerSecond++;
+
+ /* Callback function. */
+ if (NULL != handle->callback)
+ {
+#if FSL_FEATURE_ENET_QUEUE > 1
+ handle->callback(base, handle, 0, kENET_TimeStampEvent, NULL, handle->userData);
+#else
+ handle->callback(base, handle, kENET_TimeStampEvent, NULL, handle->userData);
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+ }
+
+ if (0U != ((uint32_t)kENET_TsAvailInterrupt & base->EIR))
+ {
+ /* Clear the time stamp interrupt. */
+ base->EIR = (uint32_t)kENET_TsAvailInterrupt;
+ /* Callback function. */
+ if (NULL != handle->callback)
+ {
+#if FSL_FEATURE_ENET_QUEUE > 1
+ handle->callback(base, handle, 0, kENET_TimeStampAvailEvent, NULL, handle->userData);
+#else
+ handle->callback(base, handle, kENET_TimeStampAvailEvent, NULL, handle->userData);
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */
+
+/*!
+ * brief the common IRQ handler for the tx/rx/error etc irq handler.
+ *
+ * This is used for the combined tx/rx/error interrupt for single/mutli-ring (frame 0).
+ *
+ * param base ENET peripheral base address.
+ */
+void ENET_CommonFrame0IRQHandler(ENET_Type *base)
+{
+ uint32_t event = base->EIR;
+ uint32_t instance = ENET_GetInstance(base);
+
+ if (0U != (event & ((uint32_t)kENET_TxBufferInterrupt | (uint32_t)kENET_TxFrameInterrupt)))
+ {
+#if FSL_FEATURE_ENET_QUEUE > 1
+ s_enetTxIsr[instance](base, s_ENETHandle[instance], 0);
+#else
+ s_enetTxIsr[instance](base, s_ENETHandle[instance]);
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+
+ if (0U != (event & ((uint32_t)kENET_RxBufferInterrupt | (uint32_t)kENET_RxFrameInterrupt)))
+ {
+#if FSL_FEATURE_ENET_QUEUE > 1
+ s_enetRxIsr[instance](base, s_ENETHandle[instance], 0);
+#else
+ s_enetRxIsr[instance](base, s_ENETHandle[instance]);
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+ }
+
+ if (0U != (event & ENET_TS_INTERRUPT) && (NULL != s_enetTsIsr[instance]))
+ {
+ s_enetTsIsr[instance](base, s_ENETHandle[instance]);
+ }
+ if (0U != (event & ENET_ERR_INTERRUPT) && (NULL != s_enetErrIsr[instance]))
+ {
+ s_enetErrIsr[instance](base, s_ENETHandle[instance]);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+#if FSL_FEATURE_ENET_QUEUE > 1
+/*!
+ * brief the common IRQ handler for the tx/rx irq handler.
+ *
+ * This is used for the combined tx/rx interrupt for multi-ring (frame 1).
+ *
+ * param base ENET peripheral base address.
+ */
+void ENET_CommonFrame1IRQHandler(ENET_Type *base)
+{
+ uint32_t event = base->EIR;
+ uint32_t instance = ENET_GetInstance(base);
+
+ if (0U != (event & ((uint32_t)kENET_TxBuffer1Interrupt | (uint32_t)kENET_TxFrame1Interrupt)))
+ {
+ s_enetTxIsr[instance](base, s_ENETHandle[instance], 1);
+ }
+
+ if (0U != (event & ((uint32_t)kENET_RxBuffer1Interrupt | (uint32_t)kENET_RxFrame1Interrupt)))
+ {
+ s_enetRxIsr[instance](base, s_ENETHandle[instance], 1);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+
+/*!
+ * brief the common IRQ handler for the tx/rx irq handler.
+ *
+ * This is used for the combined tx/rx interrupt for multi-ring (frame 2).
+ *
+ * param base ENET peripheral base address.
+ */
+void ENET_CommonFrame2IRQHandler(ENET_Type *base)
+{
+ uint32_t event = base->EIR;
+ uint32_t instance = ENET_GetInstance(base);
+
+ if (0U != (event & ((uint32_t)kENET_TxBuffer2Interrupt | (uint32_t)kENET_TxFrame2Interrupt)))
+ {
+ s_enetTxIsr[instance](base, s_ENETHandle[instance], 2);
+ }
+
+ if (0U != (event & ((uint32_t)kENET_RxBuffer2Interrupt | (uint32_t)kENET_RxFrame2Interrupt)))
+ {
+ s_enetRxIsr[instance](base, s_ENETHandle[instance], 2);
+ }
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif /* FSL_FEATURE_ENET_QUEUE > 1 */
+
+#if defined(ENET)
+void ENET_Transmit_IRQHandler(void)
+{
+ s_enetTxIsr[0](ENET, s_ENETHandle[0]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void ENET_Receive_IRQHandler(void)
+{
+ s_enetRxIsr[0](ENET, s_ENETHandle[0]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void ENET_Error_IRQHandler(void)
+{
+ s_enetErrIsr[0](ENET, s_ENETHandle[0]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void ENET_1588_Timer_IRQHandler(void)
+{
+ s_enetTsIsr[0](ENET, s_ENETHandle[0]);
+ SDK_ISR_EXIT_BARRIER;
+}
+
+void ENET_DriverIRQHandler(void)
+{
+ ENET_CommonFrame0IRQHandler(ENET);
+ SDK_ISR_EXIT_BARRIER;
+ SDK_ISR_EXIT_BARRIER;
+}
+
+#endif
+
+#if defined(ENET1)
+void ENET1_DriverIRQHandler(void)
+{
+ ENET_CommonFrame0IRQHandler(ENET1);
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif
+
+#if defined(ENET2)
+void ENET2_DriverIRQHandler(void)
+{
+ ENET_CommonFrame0IRQHandler(ENET2);
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif
+
+#if defined(CONNECTIVITY__ENET0)
+void CONNECTIVITY_ENET0_FRAME0_EVENT_INT_DriverIRQHandler(void)
+{
+ ENET_CommonFrame0IRQHandler(CONNECTIVITY__ENET0);
+ SDK_ISR_EXIT_BARRIER;
+}
+#if FSL_FEATURE_ENET_QUEUE > 1
+void CONNECTIVITY_ENET0_FRAME1_INT_DriverIRQHandler(void)
+{
+ ENET_CommonFrame1IRQHandler(CONNECTIVITY__ENET0);
+ SDK_ISR_EXIT_BARRIER;
+}
+void CONNECTIVITY_ENET0_FRAME2_INT_DriverIRQHandler(void)
+{
+ ENET_CommonFrame2IRQHandler(CONNECTIVITY__ENET0);
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif
+#endif
+#if defined(CONNECTIVITY__ENET1)
+void CONNECTIVITY_ENET1_FRAME0_EVENT_INT_DriverIRQHandler(void)
+{
+ ENET_CommonFrame0IRQHandler(CONNECTIVITY__ENET1);
+ SDK_ISR_EXIT_BARRIER;
+}
+#if FSL_FEATURE_ENET_QUEUE > 1
+void CONNECTIVITY_ENET1_FRAME1_INT_DriverIRQHandler(void)
+{
+ ENET_CommonFrame1IRQHandler(CONNECTIVITY__ENET1);
+ SDK_ISR_EXIT_BARRIER;
+}
+void CONNECTIVITY_ENET1_FRAME2_INT_DriverIRQHandler(void)
+{
+ ENET_CommonFrame2IRQHandler(CONNECTIVITY__ENET1);
+ SDK_ISR_EXIT_BARRIER;
+}
+#endif
+#endif
+#if FSL_FEATURE_ENET_QUEUE > 1
+#if defined(ENET_1G)
+void ENET_1G_DriverIRQHandler(void)
+{
+ ENET_CommonFrame0IRQHandler(ENET_1G);
+/* Added for ARM errata 838869: storing immediate overlapping exception return operation
+ * might vector to incorrect interrupt, this affects Cortex-M4, Cortex-M4F. */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+void ENET_MAC0_Tx_Rx_Done_0_DriverIRQHandler(void)
+{
+ ENET_CommonFrame1IRQHandler(ENET_1G);
+/* Added for ARM errata 838869: storing immediate overlapping exception return operation
+ * might vector to incorrect interrupt, this affects Cortex-M4, Cortex-M4F. */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+void ENET_MAC0_Tx_Rx_Done_1_DriverIRQHandler(void)
+{
+ ENET_CommonFrame2IRQHandler(ENET_1G);
+/* Added for ARM errata 838869: storing immediate overlapping exception return operation
+ * might vector to incorrect interrupt, this affects Cortex-M4, Cortex-M4F. */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+void ENET_1G_1588_Timer_DriverIRQHandler(void)
+{
+ s_enet1588TimerIsr(ENET_1G, s_ENETHandle[1]);
+/* Added for ARM errata 838869: storing immediate overlapping exception return operation
+ * might vector to incorrect interrupt, this affects Cortex-M4, Cortex-M4F. */
+#if defined __CORTEX_M && (__CORTEX_M == 4U)
+ __DSB();
+#endif
+}
+#endif
+#endif
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ewm.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ewm.c
new file mode 100644
index 0000000000..593cf87a50
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ewm.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017, 2020 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_ewm.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.ewm"
+#endif
+
+/*******************************************************************************
+ * Code
+ ******************************************************************************/
+
+/*!
+ * brief Initializes the EWM peripheral.
+ *
+ * This function is used to initialize the EWM. After calling, the EWM
+ * runs immediately according to the configuration.
+ * Note that, except for the interrupt enable control bit, other control bits and registers are write once after a
+ * CPU reset. Modifying them more than once generates a bus transfer error.
+ *
+ * This is an example.
+ * code
+ * ewm_config_t config;
+ * EWM_GetDefaultConfig(&config);
+ * config.compareHighValue = 0xAAU;
+ * EWM_Init(ewm_base,&config);
+ * endcode
+ *
+ * param base EWM peripheral base address
+ * param config The configuration of the EWM
+ */
+void EWM_Init(EWM_Type *base, const ewm_config_t *config)
+{
+ assert(NULL != config);
+
+ uint8_t value = 0U;
+
+#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \
+ (defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE))
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ CLOCK_EnableClock(kCLOCK_Ewm0);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+#endif
+ value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) |
+ EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt);
+#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
+ base->CLKPRESCALER = config->prescaler;
+#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
+
+#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
+ base->CLKCTRL = (uint8_t)config->clockSource;
+#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/
+
+ base->CMPL = config->compareLowValue;
+ base->CMPH = config->compareHighValue;
+ base->CTRL = value;
+}
+
+/*!
+ * brief Deinitializes the EWM peripheral.
+ *
+ * This function is used to shut down the EWM.
+ *
+ * param base EWM peripheral base address
+ */
+void EWM_Deinit(EWM_Type *base)
+{
+ EWM_DisableInterrupts(base, (uint32_t)kEWM_InterruptEnable);
+#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \
+ (defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE))
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+ CLOCK_DisableClock(kCLOCK_Ewm0);
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+#endif /* FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE */
+}
+
+/*!
+ * brief Initializes the EWM configuration structure.
+ *
+ * This function initializes the EWM configuration structure to default values. The default
+ * values are as follows.
+ * code
+ * ewmConfig->enableEwm = true;
+ * ewmConfig->enableEwmInput = false;
+ * ewmConfig->setInputAssertLogic = false;
+ * ewmConfig->enableInterrupt = false;
+ * ewmConfig->ewm_lpo_clock_source_t = kEWM_LpoClockSource0;
+ * ewmConfig->prescaler = 0;
+ * ewmConfig->compareLowValue = 0;
+ * ewmConfig->compareHighValue = 0xFEU;
+ * endcode
+ *
+ * param config Pointer to the EWM configuration structure.
+ * see ewm_config_t
+ */
+void EWM_GetDefaultConfig(ewm_config_t *config)
+{
+ assert(NULL != config);
+
+ /* Initializes the configure structure to zero. */
+ (void)memset(config, 0, sizeof(*config));
+
+ config->enableEwm = true;
+ config->enableEwmInput = false;
+ config->setInputAssertLogic = false;
+ config->enableInterrupt = false;
+#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT
+ config->clockSource = kEWM_LpoClockSource0;
+#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/
+#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER
+ config->prescaler = 0U;
+#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */
+ config->compareLowValue = 0U;
+ config->compareHighValue = 0xFEU;
+}
+
+/*!
+ * brief Services the EWM.
+ *
+ * This function resets the EWM counter to zero.
+ *
+ * param base EWM peripheral base address
+ */
+void EWM_Refresh(EWM_Type *base)
+{
+ uint32_t primaskValue = 0U;
+
+ /* Disable the global interrupt to protect refresh sequence */
+ primaskValue = DisableGlobalIRQ();
+ base->SERV = (uint8_t)0xB4U;
+ base->SERV = (uint8_t)0x2CU;
+ EnableGlobalIRQ(primaskValue);
+}
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexcan.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexcan.c
new file mode 100644
index 0000000000..682dae7492
--- /dev/null
+++ b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexcan.c
@@ -0,0 +1,3564 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2020 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flexcan.h"
+
+/*******************************************************************************
+ * Definitions
+ ******************************************************************************/
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.flexcan"
+#endif
+
+#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032)
+#define RXINTERMISSION (CAN_DBG1_CFSM(0x2f))
+#define TXINTERMISSION (CAN_DBG1_CFSM(0x14))
+#define BUSIDLE (CAN_DBG1_CFSM(0x02))
+#define CBN_VALUE3 (CAN_DBG1_CBN(0x03))
+#define DELAY_BUSIDLE (200)
+#endif
+
+#define IDEAL_SP_LOW (750U)
+#define IDEAL_SP_MID (800U)
+#define IDEAL_SP_HIGH (875U)
+#define IDEAL_SP_FACTOR (1000U)
+
+#define MAX_PROPSEG (CAN_CTRL1_PROPSEG_MASK >> CAN_CTRL1_PROPSEG_SHIFT)
+#define MAX_PSEG1 (CAN_CTRL1_PSEG1_MASK >> CAN_CTRL1_PSEG1_SHIFT)
+#define MAX_PSEG2 (CAN_CTRL1_PSEG2_MASK >> CAN_CTRL1_PSEG2_SHIFT)
+#define MAX_RJW (CAN_CTRL1_RJW_MASK >> CAN_CTRL1_RJW_SHIFT)
+#define MAX_PRESDIV (CAN_CTRL1_PRESDIV_MASK >> CAN_CTRL1_PRESDIV_SHIFT)
+#define CTRL1_MAX_TIME_QUANTA (1U + MAX_PROPSEG + 1U + MAX_PSEG1 + 1U + MAX_PSEG2 + 1U)
+#define CTRL1_MIN_TIME_QUANTA (8U)
+
+#define MAX_EPROPSEG (CAN_CBT_EPROPSEG_MASK >> CAN_CBT_EPROPSEG_SHIFT)
+#define MAX_EPSEG1 (CAN_CBT_EPSEG1_MASK >> CAN_CBT_EPSEG1_SHIFT)
+#define MAX_EPSEG2 (CAN_CBT_EPSEG2_MASK >> CAN_CBT_EPSEG2_SHIFT)
+#define MAX_ERJW (CAN_CBT_ERJW_MASK >> CAN_CBT_ERJW_SHIFT)
+#define MAX_EPRESDIV (CAN_CBT_EPRESDIV_MASK >> CAN_CBT_EPRESDIV_SHIFT)
+#define CBT_MAX_TIME_QUANTA (1U + MAX_EPROPSEG + 1U + MAX_EPSEG1 + 1U + MAX_EPSEG2 + 1U)
+#define CBT_MIN_TIME_QUANTA (8U)
+
+#define MAX_FPROPSEG (CAN_FDCBT_FPROPSEG_MASK >> CAN_FDCBT_FPROPSEG_SHIFT)
+#define MAX_FPSEG1 (CAN_FDCBT_FPSEG1_MASK >> CAN_FDCBT_FPSEG1_SHIFT)
+#define MAX_FPSEG2 (CAN_FDCBT_FPSEG2_MASK >> CAN_FDCBT_FPSEG2_SHIFT)
+#define MAX_FRJW (CAN_FDCBT_FRJW_MASK >> CAN_FDCBT_FRJW_SHIFT)
+#define MAX_FPRESDIV (CAN_FDCBT_FPRESDIV_MASK >> CAN_FDCBT_FPRESDIV_SHIFT)
+#define FDCBT_MAX_TIME_QUANTA (1U + MAX_FPROPSEG + 0U + MAX_FPSEG1 + 1U + MAX_FPSEG2 + 1U)
+#define FDCBT_MIN_TIME_QUANTA (5U)
+
+#define MAX_CANFD_BAUDRATE (8000000U)
+#define MAX_CAN_BAUDRATE (1000000U)
+
+#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595)
+#define CAN_ESR1_FLTCONF_BUSOFF CAN_ESR1_FLTCONF(2U)
+#endif
+
+#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
+#ifndef CAN_CLOCK_CHECK_NO_AFFECTS
+/* If no define such MACRO, it mean that the CAN in current device have no clock affect issue. */
+#define CAN_CLOCK_CHECK_NO_AFFECTS (true)
+#endif /* CAN_CLOCK_CHECK_NO_AFFECTS */
+#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
+
+/*! @brief FlexCAN Internal State. */
+enum _flexcan_state
+{
+ kFLEXCAN_StateIdle = 0x0, /*!< MB/RxFIFO idle.*/
+ kFLEXCAN_StateRxData = 0x1, /*!< MB receiving.*/
+ kFLEXCAN_StateRxRemote = 0x2, /*!< MB receiving remote reply.*/
+ kFLEXCAN_StateTxData = 0x3, /*!< MB transmitting.*/
+ kFLEXCAN_StateTxRemote = 0x4, /*!< MB transmitting remote request.*/
+ kFLEXCAN_StateRxFifo = 0x5, /*!< RxFIFO receiving.*/
+};
+
+/*! @brief FlexCAN message buffer CODE for Rx buffers. */
+enum _flexcan_mb_code_rx
+{
+ kFLEXCAN_RxMbInactive = 0x0, /*!< MB is not active.*/
+ kFLEXCAN_RxMbFull = 0x2, /*!< MB is full.*/
+ kFLEXCAN_RxMbEmpty = 0x4, /*!< MB is active and empty.*/
+ kFLEXCAN_RxMbOverrun = 0x6, /*!< MB is overwritten into a full buffer.*/
+ kFLEXCAN_RxMbBusy = 0x8, /*!< FlexCAN is updating the contents of the MB.*/
+ /*! The CPU must not access the MB.*/
+ kFLEXCAN_RxMbRanswer = 0xA, /*!< A frame was configured to recognize a Remote Request Frame */
+ /*! and transmit a Response Frame in return.*/
+ kFLEXCAN_RxMbNotUs