diff --git a/.github/workflows/build_win_mac.yml b/.github/workflows/build_win_mac.yml
index 45fc62f78..cb879a705 100644
--- a/.github/workflows/build_win_mac.yml
+++ b/.github/workflows/build_win_mac.yml
@@ -48,7 +48,7 @@ jobs:
uses: actions/checkout@v3
- name: Get Dependencies
- run: python3 tools/get_family_deps.py stm32f4
+ run: python3 tools/get_deps.py stm32f4
- name: Build
run: python3 tools/build_family.py stm32f4 stm32f411disco
diff --git a/.idea/cmake.xml b/.idea/cmake.xml
index 3c016ccff..c9024715c 100644
--- a/.idea/cmake.xml
+++ b/.idea/cmake.xml
@@ -2,7 +2,7 @@
-
+
@@ -37,6 +37,7 @@
+
\ No newline at end of file
diff --git a/.idea/runConfigurations/mcx947_jlink.xml b/.idea/runConfigurations/mcx947_jlink.xml
index 71616ab70..27661bec5 100644
--- a/.idea/runConfigurations/mcx947_jlink.xml
+++ b/.idea/runConfigurations/mcx947_jlink.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/.idea/runConfigurations/rt1010_jlink.xml b/.idea/runConfigurations/rt1010_jlink.xml
index e660a46ae..68ebb8885 100644
--- a/.idea/runConfigurations/rt1010_jlink.xml
+++ b/.idea/runConfigurations/rt1010_jlink.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/.idea/runConfigurations/rt1060_jlink.xml b/.idea/runConfigurations/rt1060_jlink.xml
index b9a47a2ce..014a4d1b1 100644
--- a/.idea/runConfigurations/rt1060_jlink.xml
+++ b/.idea/runConfigurations/rt1060_jlink.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/hw/bsp/kinetis_kl/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_kl/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..960bb23e1
--- /dev/null
+++ b/hw/bsp/kinetis_kl/FreeRTOSConfig/FreeRTOSConfig.h
@@ -0,0 +1,166 @@
+/*
+ * FreeRTOS Kernel V10.0.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software. If you wish to use our Amazon
+ * FreeRTOS name, please do so in a fair use way that does not cause confusion.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+/*-----------------------------------------------------------
+ * Application specific definitions.
+ *
+ * These definitions should be adjusted for your particular hardware and
+ * application requirements.
+ *
+ * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
+ * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
+ *
+ * See http://www.freertos.org/a00110.html.
+ *----------------------------------------------------------*/
+
+// skip if included from IAR assembler
+#ifndef __IASMARM__
+// FIXME cause redundant-decls warnings
+extern uint32_t SystemCoreClock;
+#endif
+
+/* Cortex M23/M33 port configuration. */
+#define configENABLE_MPU 0
+#define configENABLE_FPU 1
+#define configENABLE_TRUSTZONE 0
+#define configMINIMAL_SECURE_STACK_SIZE (1024)
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configCPU_CLOCK_HZ SystemCoreClock
+#define configTICK_RATE_HZ ( 1000 )
+#define configMAX_PRIORITIES ( 5 )
+#define configMINIMAL_STACK_SIZE ( 128 )
+#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 )
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 1
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 2
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 0
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 1
+#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
+
+#define configSUPPORT_STATIC_ALLOCATION 0
+#define configSUPPORT_DYNAMIC_ALLOCATION 1
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning
+#define configCHECK_FOR_STACK_OVERFLOW 2
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configRECORD_STACK_HIGH_ADDRESS 1
+#define configUSE_TRACE_FACILITY 1 // legacy trace
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 2
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2)
+#define configTIMER_QUEUE_LENGTH 32
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 0
+#define INCLUDE_uxTaskPriorityGet 0
+#define INCLUDE_vTaskDelete 0
+#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY
+#define INCLUDE_xResumeFromISR 0
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 0
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 0
+#define INCLUDE_xTaskGetIdleTaskHandle 0
+#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0
+#define INCLUDE_pcTaskGetTaskName 0
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 0
+#define INCLUDE_xTimerPendFunctionCall 0
+
+/* Define to trap errors during development. */
+// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7
+#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__)
+ #define configASSERT(_exp) \
+ do {\
+ if ( !(_exp) ) { \
+ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
+ if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \
+ taskDISABLE_INTERRUPTS(); \
+ __asm("BKPT #0\n"); \
+ }\
+ }\
+ } while(0)
+#else
+ #define configASSERT( x )
+#endif
+
+/* FreeRTOS hooks to NVIC vectors */
+#define xPortPendSVHandler PendSV_Handler
+#define xPortSysTickHandler SysTick_Handler
+#define vPortSVCHandler SVC_Handler
+
+//--------------------------------------------------------------------+
+// Interrupt nesting behavior configuration.
+//--------------------------------------------------------------------+
+
+// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header
+#define configPRIO_BITS 2
+
+/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
+#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv));
+}
+
+/*******************************************************************************
+ ********************** Configuration BOARD_BootClockRUN ***********************
+ ******************************************************************************/
+/* TEXT BELOW IS USED AS SETTING FOR THE CLOCKS TOOL *****************************
+!!Configuration
+name: BOARD_BootClockRUN
+outputs:
+- {id: Bus_clock.outFreq, value: 24 MHz}
+- {id: Core_clock.outFreq, value: 48 MHz, locked: true, accuracy: '0.001'}
+- {id: ERCLK32K.outFreq, value: 1 kHz}
+- {id: Flash_clock.outFreq, value: 24 MHz}
+- {id: LPO_clock.outFreq, value: 1 kHz}
+- {id: MCGIRCLK.outFreq, value: 32.768 kHz}
+- {id: OSCERCLK.outFreq, value: 8 MHz}
+- {id: PLLFLLCLK.outFreq, value: 48 MHz}
+- {id: System_clock.outFreq, value: 48 MHz}
+settings:
+- {id: MCGMode, value: PEE}
+- {id: MCG.FCRDIV.scale, value: '1', locked: true}
+- {id: MCG.FRDIV.scale, value: '32'}
+- {id: MCG.IREFS.sel, value: MCG.FRDIV}
+- {id: MCG.PLLS.sel, value: MCG.PLL}
+- {id: MCG.PRDIV.scale, value: '2', locked: true}
+- {id: MCG.VDIV.scale, value: '24', locked: true}
+- {id: MCG_C1_IRCLKEN_CFG, value: Enabled}
+- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower}
+- {id: MCG_C2_RANGE0_CFG, value: High}
+- {id: MCG_C2_RANGE0_FRDIV_CFG, value: High}
+- {id: OSC0_CR_ERCLKEN_CFG, value: Enabled}
+- {id: OSC_CR_ERCLKEN_CFG, value: Enabled}
+- {id: SIM.CLKOUTSEL.sel, value: SIM.OUTDIV4}
+- {id: SIM.OSC32KSEL.sel, value: PMC.LPOCLK}
+- {id: SIM.OUTDIV1.scale, value: '2'}
+- {id: SIM.PLLFLLSEL.sel, value: SIM.MCGPLLCLK_DIV2}
+- {id: SIM.TPMSRCSEL.sel, value: SIM.PLLFLLSEL}
+- {id: SIM.UART0SRCSEL.sel, value: SIM.PLLFLLSEL}
+- {id: SIM.USBSRCSEL.sel, value: SIM.PLLFLLSEL}
+sources:
+- {id: OSC.OSC.outFreq, value: 8 MHz, enabled: true}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE CLOCKS TOOL **/
+
+/*******************************************************************************
+ * Variables for BOARD_BootClockRUN configuration
+ ******************************************************************************/
+const mcg_config_t mcgConfig_BOARD_BootClockRUN =
+ {
+ .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */
+ .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */
+ .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */
+ .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */
+ .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */
+ .drs = kMCG_DrsLow, /* Low frequency range */
+ .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */
+ .pll0Config =
+ {
+ .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */
+ .prdiv = 0x1U, /* PLL Reference divider: divided by 2 */
+ .vdiv = 0x0U, /* VCO divider: multiplied by 24 */
+ },
+ };
+const sim_clock_config_t simConfig_BOARD_BootClockRUN =
+ {
+ .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */
+ .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */
+ .clkdiv1 = 0x10010000U, /* SIM_CLKDIV1 - OUTDIV1: /2, OUTDIV4: /2 */
+ };
+const osc_config_t oscConfig_BOARD_BootClockRUN =
+ {
+ .freq = 8000000U, /* Oscillator frequency: 8000000Hz */
+ .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */
+ .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */
+ .oscerConfig =
+ {
+ .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */
+ }
+ };
+
+/*******************************************************************************
+ * Code for BOARD_BootClockRUN configuration
+ ******************************************************************************/
+void BOARD_BootClockRUN(void)
+{
+ /* Set the system clock dividers in SIM to safe value. */
+ CLOCK_SetSimSafeDivs();
+ /* Initializes OSC0 according to board configuration. */
+ CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN);
+ CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq);
+ /* Configure FLL external reference divider (FRDIV). */
+ CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv);
+ /* Set MCG to PEE mode. */
+ CLOCK_BootToPeeMode(kMCG_OscselOsc,
+ kMCG_PllClkSelPll0,
+ &mcgConfig_BOARD_BootClockRUN.pll0Config);
+ /* Configure the Internal Reference clock (MCGIRCLK). */
+ CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockRUN.irclkEnableMode,
+ mcgConfig_BOARD_BootClockRUN.ircs,
+ mcgConfig_BOARD_BootClockRUN.fcrdiv);
+ /* Set the clock configuration in SIM module. */
+ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN);
+ /* Set SystemCoreClock variable. */
+ SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK;
+}
+
+/*******************************************************************************
+ ********************* Configuration BOARD_BootClockVLPR ***********************
+ ******************************************************************************/
+/* TEXT BELOW IS USED AS SETTING FOR THE CLOCKS TOOL *****************************
+!!Configuration
+name: BOARD_BootClockVLPR
+outputs:
+- {id: Bus_clock.outFreq, value: 800 kHz}
+- {id: Core_clock.outFreq, value: 4 MHz}
+- {id: ERCLK32K.outFreq, value: 1 kHz}
+- {id: Flash_clock.outFreq, value: 800 kHz}
+- {id: LPO_clock.outFreq, value: 1 kHz}
+- {id: MCGIRCLK.outFreq, value: 4 MHz}
+- {id: System_clock.outFreq, value: 4 MHz}
+settings:
+- {id: MCGMode, value: BLPI}
+- {id: powerMode, value: VLPR}
+- {id: MCG.CLKS.sel, value: MCG.IRCS}
+- {id: MCG.FCRDIV.scale, value: '1', locked: true}
+- {id: MCG.FRDIV.scale, value: '32'}
+- {id: MCG.IRCS.sel, value: MCG.FCRDIV}
+- {id: MCG_C1_IRCLKEN_CFG, value: Enabled}
+- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower}
+- {id: MCG_C2_RANGE0_CFG, value: High}
+- {id: MCG_C2_RANGE0_FRDIV_CFG, value: High}
+- {id: SIM.OSC32KSEL.sel, value: PMC.LPOCLK}
+- {id: SIM.OUTDIV4.scale, value: '5'}
+sources:
+- {id: OSC.OSC.outFreq, value: 8 MHz}
+ * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE CLOCKS TOOL **/
+
+/*******************************************************************************
+ * Variables for BOARD_BootClockVLPR configuration
+ ******************************************************************************/
+const mcg_config_t mcgConfig_BOARD_BootClockVLPR =
+ {
+ .mcgMode = kMCG_ModeBLPI, /* BLPI - Bypassed Low Power Internal */
+ .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */
+ .ircs = kMCG_IrcFast, /* Fast internal reference clock selected */
+ .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */
+ .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */
+ .drs = kMCG_DrsLow, /* Low frequency range */
+ .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */
+ .pll0Config =
+ {
+ .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */
+ .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */
+ .vdiv = 0x0U, /* VCO divider: multiplied by 24 */
+ },
+ };
+const sim_clock_config_t simConfig_BOARD_BootClockVLPR =
+ {
+ .pllFllSel = SIM_PLLFLLSEL_MCGFLLCLK_CLK, /* PLLFLL select: MCGFLLCLK clock */
+ .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */
+ .clkdiv1 = 0x40000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /5 */
+ };
+const osc_config_t oscConfig_BOARD_BootClockVLPR =
+ {
+ .freq = 0U, /* Oscillator frequency: 0Hz */
+ .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */
+ .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */
+ .oscerConfig =
+ {
+ .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */
+ }
+ };
+
+/*******************************************************************************
+ * Code for BOARD_BootClockVLPR configuration
+ ******************************************************************************/
+void BOARD_BootClockVLPR(void)
+{
+ /* Set the system clock dividers in SIM to safe value. */
+ CLOCK_SetSimSafeDivs();
+ /* Set MCG to BLPI mode. */
+ CLOCK_BootToBlpiMode(mcgConfig_BOARD_BootClockVLPR.fcrdiv,
+ mcgConfig_BOARD_BootClockVLPR.ircs,
+ mcgConfig_BOARD_BootClockVLPR.irclkEnableMode);
+ /* Set the clock configuration in SIM module. */
+ CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR);
+ /* Set VLPR power mode. */
+ SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll);
+#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI)
+ SMC_SetPowerModeVlpr(SMC, false);
+#else
+ SMC_SetPowerModeVlpr(SMC);
+#endif
+ while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr)
+ {
+ }
+ /* Set SystemCoreClock variable. */
+ SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK;
+}
diff --git a/hw/bsp/kinetis_kl/boards/frdm_kl25z/clock_config.h b/hw/bsp/kinetis_kl/boards/frdm_kl25z/clock_config.h
new file mode 100644
index 000000000..1033d4e55
--- /dev/null
+++ b/hw/bsp/kinetis_kl/boards/frdm_kl25z/clock_config.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ * of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * o Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CLOCK_CONFIG_H_
+#define _CLOCK_CONFIG_H_
+
+#include "fsl_common.h"
+
+/*******************************************************************************
+ * Definitions
+******************************************************************************/
+
+/*******************************************************************************
+ ************************ BOARD_InitBootClocks function ************************
+ ******************************************************************************/
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus*/
+
+/*!
+ * @brief This function executes default configuration of clocks.
+ *
+ */
+void BOARD_InitBootClocks(void);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus*/
+
+#define BOARD_XTAL0_CLK_HZ 8000000U /*!< Board xtal0 frequency in Hz */
+
+/*******************************************************************************
+ ********************** Configuration BOARD_BootClockRUN ***********************
+ ******************************************************************************/
+/*******************************************************************************
+ * Definitions for BOARD_BootClockRUN configuration
+ ******************************************************************************/
+#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */
+
+/*! @brief MCG set for BOARD_BootClockRUN configuration.
+ */
+extern const mcg_config_t mcgConfig_BOARD_BootClockRUN;
+/*! @brief SIM module set for BOARD_BootClockRUN configuration.
+ */
+extern const sim_clock_config_t simConfig_BOARD_BootClockRUN;
+/*! @brief OSC set for BOARD_BootClockRUN configuration.
+ */
+extern const osc_config_t oscConfig_BOARD_BootClockRUN;
+
+/*******************************************************************************
+ * API for BOARD_BootClockRUN configuration
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus*/
+
+/*!
+ * @brief This function executes configuration of clocks.
+ *
+ */
+void BOARD_BootClockRUN(void);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus*/
+
+/*******************************************************************************
+ ********************* Configuration BOARD_BootClockVLPR ***********************
+ ******************************************************************************/
+/*******************************************************************************
+ * Definitions for BOARD_BootClockVLPR configuration
+ ******************************************************************************/
+#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 4000000U /*!< Core clock frequency: 4000000Hz */
+
+/*! @brief MCG set for BOARD_BootClockVLPR configuration.
+ */
+extern const mcg_config_t mcgConfig_BOARD_BootClockVLPR;
+/*! @brief SIM module set for BOARD_BootClockVLPR configuration.
+ */
+extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR;
+/*! @brief OSC set for BOARD_BootClockVLPR configuration.
+ */
+extern const osc_config_t oscConfig_BOARD_BootClockVLPR;
+
+/*******************************************************************************
+ * API for BOARD_BootClockVLPR configuration
+ ******************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus*/
+
+/*!
+ * @brief This function executes configuration of clocks.
+ *
+ */
+void BOARD_BootClockVLPR(void);
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus*/
+
+#endif /* _CLOCK_CONFIG_H_ */
diff --git a/hw/bsp/kinetis_kl/boards/frdm_kl25z/frdm_kl25z.c b/hw/bsp/kinetis_kl/family.c
similarity index 74%
rename from hw/bsp/kinetis_kl/boards/frdm_kl25z/frdm_kl25z.c
rename to hw/bsp/kinetis_kl/family.c
index 46f85f6a5..8914078d5 100644
--- a/hw/bsp/kinetis_kl/boards/frdm_kl25z/frdm_kl25z.c
+++ b/hw/bsp/kinetis_kl/family.c
@@ -21,11 +21,10 @@
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
- *
- * This file is part of the TinyUSB stack.
*/
-#include "../board.h"
+#include "bsp/board.h"
+#include "board.h"
#include "fsl_device_registers.h"
#include "fsl_gpio.h"
#include "fsl_port.h"
@@ -47,38 +46,6 @@ void USB0_IRQHandler(void)
#endif
}
-//--------------------------------------------------------------------+
-// MACRO TYPEDEF CONSTANT ENUM DECLARATION
-//--------------------------------------------------------------------+
-// LED
-#define LED_PINMUX IOMUXC_GPIO_AD_B0_09_GPIO1_IO09
-#define LED_PORT GPIOB
-#define LED_PIN_CLOCK kCLOCK_PortB
-#define LED_PIN_PORT PORTB
-#define LED_PIN 19U
-#define LED_PIN_FUNCTION kPORT_MuxAsGpio
-#define LED_STATE_ON 0
-
-// Button
-#define BUTTON_PORT GPIOC
-#define BUTTON_PIN_CLOCK kCLOCK_PortC
-#define BUTTON_PIN_PORT PORTC
-#define BUTTON_PIN 9U
-#define BUTTON_PIN_FUNCTION kPORT_MuxAsGpio
-#define BUTTON_STATE_ACTIVE 0
-
-// UART
-#define UART_PORT UART0
-#define UART_PIN_CLOCK kCLOCK_PortA
-#define UART_PIN_PORT PORTA
-#define UART_PIN_RX 1u
-#define UART_PIN_TX 2u
-#define UART_PIN_FUNCTION kPORT_MuxAlt2
-#define SOPT5_UART0RXSRC_UART_RX 0x00u /*!< UART0 receive data source select: UART0_RX pin */
-#define SOPT5_UART0TXSRC_UART_TX 0x00u /*!< UART0 transmit data source select: UART0_TX pin */
-
-const uint8_t dcd_data[] = { 0x00 };
-
void board_init(void)
{
BOARD_BootClockRUN();
@@ -139,13 +106,13 @@ void board_init(void)
void board_led_write(bool state)
{
- GPIO_WritePinOutput(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
+ GPIO_PinWrite(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON));
}
uint32_t board_button_read(void)
{
#if defined(BUTTON_PORT) && defined(BUTTON_PIN)
- return BUTTON_STATE_ACTIVE == GPIO_ReadPinInput(BUTTON_PORT, BUTTON_PIN);
+ return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_PORT, BUTTON_PIN);
#endif
return 0;
}
diff --git a/hw/bsp/kinetis_kl/family.cmake b/hw/bsp/kinetis_kl/family.cmake
new file mode 100644
index 000000000..f491b3dee
--- /dev/null
+++ b/hw/bsp/kinetis_kl/family.cmake
@@ -0,0 +1,126 @@
+include_guard()
+
+if (NOT BOARD)
+ message(FATAL_ERROR "BOARD not specified")
+endif ()
+
+set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk)
+set(CMSIS_DIR ${TOP}/lib/CMSIS_5)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+set(CMAKE_SYSTEM_PROCESSOR cortex-m0plus CACHE INTERNAL "System Processor")
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/tools/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS KINETIS_KL CACHE INTERNAL "")
+
+# enable LTO if supported
+include(CheckIPOSupported)
+check_ipo_supported(RESULT IPO_SUPPORTED)
+if (IPO_SUPPORTED)
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
+endif ()
+
+
+#------------------------------------
+# BOARD_TARGET
+#------------------------------------
+# only need to be built ONCE for all examples
+function(add_board_target BOARD_TARGET)
+ if (NOT TARGET ${BOARD_TARGET})
+ add_library(${BOARD_TARGET} STATIC
+ ${SDK_DIR}/drivers/gpio/fsl_gpio.c
+ ${SDK_DIR}/drivers/lpsci/fsl_lpsci.c
+ ${SDK_DIR}/drivers/uart/fsl_uart.c
+ ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
+ ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c
+ )
+ target_compile_definitions(${BOARD_TARGET} PUBLIC
+ )
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMSIS_DIR}/CMSIS/Core/Include
+ ${SDK_DIR}/devices/${MCU_VARIANT}
+ ${SDK_DIR}/devices/${MCU_VARIANT}/drivers
+ ${SDK_DIR}/drivers/common
+ ${SDK_DIR}/drivers/gpio
+ ${SDK_DIR}/drivers/lpsci
+ ${SDK_DIR}/drivers/port
+ ${SDK_DIR}/drivers/smc
+ ${SDK_DIR}/drivers/uart
+ )
+
+ update_board(${BOARD_TARGET})
+
+ # LD_FILE and STARTUP_FILE can be defined in board.cmake
+
+ target_sources(${BOARD_TARGET} PUBLIC
+ ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
+ )
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ # nanolib
+ --specs=nosys.specs
+ --specs=nano.specs
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
+ target_link_options(${BOARD_TARGET} PUBLIC
+ "LINKER:--config=${LD_FILE_IAR}"
+ )
+ endif ()
+ endif ()
+endfunction()
+
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET)
+ family_configure_common(${TARGET})
+
+ # Board target
+ add_board_target(board_${BOARD})
+
+ #---------- Port Specific ----------
+ # These files are built for each example since it depends on example's tusb_config.h
+ target_sources(${TARGET} PUBLIC
+ # TinyUSB Port
+ ${TOP}/src/portable/chipidea/ci_fs/dcd_ci_fs.c
+ ${TOP}/src/portable/nxp/khci/hcd_khci.c
+ # BSP
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ # family, hw, board
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ )
+
+ # Add TinyUSB
+ family_add_tinyusb(${TARGET} OPT_MCU_KINETIS_KL)
+
+ # Link dependencies
+ target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb)
+
+ # Flashing
+ family_flash_jlink(${TARGET})
+ #family_flash_nxplink(${TARGET})
+endfunction()
+
+
+function(family_configure_device_example TARGET)
+ family_configure_example(${TARGET})
+endfunction()
+
+function(family_configure_host_example TARGET)
+ family_configure_example(${TARGET})
+endfunction()
+
+function(family_configure_dual_usb_example TARGET)
+ family_configure_example(${TARGET})
+endfunction()
diff --git a/hw/bsp/kinetis_kl/family.mk b/hw/bsp/kinetis_kl/family.mk
index e805d6dae..2bed6b486 100644
--- a/hw/bsp/kinetis_kl/family.mk
+++ b/hw/bsp/kinetis_kl/family.mk
@@ -1,5 +1,5 @@
-SDK_DIR = hw/mcu/nxp/nxp_sdk
-DEPS_SUBMODULES += $(SDK_DIR)
+SDK_DIR = hw/mcu/nxp/mcux-sdk
+DEPS_SUBMODULES += $(SDK_DIR) lib/CMSIS_5
MCU_DIR = $(SDK_DIR)/devices/$(MCU)
include $(TOP)/$(BOARD_PATH)/board.mk
@@ -18,20 +18,22 @@ SRC_C += \
src/portable/nxp/khci/dcd_khci.c \
src/portable/nxp/khci/hcd_khci.c \
$(MCU_DIR)/system_$(MCU).c \
- $(MCU_DIR)/project_template/clock_config.c \
$(MCU_DIR)/drivers/fsl_clock.c \
- $(MCU_DIR)/drivers/fsl_gpio.c \
- $(MCU_DIR)/drivers/fsl_lpsci.c \
- $(MCU_DIR)/drivers/fsl_uart.c
+ $(SDK_DIR)/drivers/gpio/fsl_gpio.c \
+ $(SDK_DIR)/drivers/lpsci/fsl_lpsci.c \
+ $(SDK_DIR)/drivers/uart/fsl_uart.c \
INC += \
$(TOP)/$(BOARD_PATH) \
- $(TOP)/$(SDK_DIR)/CMSIS/Include \
+ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \
$(TOP)/$(MCU_DIR) \
- $(TOP)/$(MCU_DIR)/project_template \
- $(TOP)/$(MCU_DIR)/drivers
-
-SRC_S += $(MCU_DIR)/gcc/startup_$(MCU).S
+ $(TOP)/$(MCU_DIR)/drivers \
+ $(TOP)/$(SDK_DIR)/drivers/common \
+ $(TOP)/$(SDK_DIR)/drivers/gpio \
+ $(TOP)/$(SDK_DIR)/drivers/lpsci \
+ $(TOP)/$(SDK_DIR)/drivers/port \
+ $(TOP)/$(SDK_DIR)/drivers/smc \
+ $(TOP)/$(SDK_DIR)/drivers/uart \
# For freeRTOS port source
FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/ARM_CM0
diff --git a/hw/bsp/kinetis_kl/gcc/MKL25Z128xxx4_flash.ld b/hw/bsp/kinetis_kl/gcc/MKL25Z128xxx4_flash.ld
new file mode 100644
index 000000000..b38aa827c
--- /dev/null
+++ b/hw/bsp/kinetis_kl/gcc/MKL25Z128xxx4_flash.ld
@@ -0,0 +1,253 @@
+/*
+** ###################################################################
+** Processors: MKL25Z128VFM4
+** MKL25Z128VFT4
+** MKL25Z128VLH4
+** MKL25Z128VLK4
+**
+** Compiler: GNU C Compiler
+** Reference manual: KL25P80M48SF0RM, Rev.3, Sep 2012
+** Version: rev. 2.5, 2015-02-19
+** Build: b170214
+**
+** Abstract:
+** Linker file for the GNU C Compiler
+**
+** Copyright 2016 Freescale Semiconductor, Inc.
+** Copyright 2016-2017 NXP
+** Redistribution and use in source and binary forms, with or without modification,
+** are permitted provided that the following conditions are met:
+**
+** o Redistributions of source code must retain the above copyright notice, this list
+** of conditions and the following disclaimer.
+**
+** o Redistributions in binary form must reproduce the above copyright notice, this
+** list of conditions and the following disclaimer in the documentation and/or
+** other materials provided with the distribution.
+**
+** o Neither the name of the copyright holder nor the names of its
+** contributors may be used to endorse or promote products derived from this
+** software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+** http: www.nxp.com
+** mail: support@nxp.com
+**
+** ###################################################################
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
+STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400;
+M_VECTOR_RAM_SIZE = DEFINED(__ram_vector_table__) ? 0x0200 : 0x0;
+
+/* Specify the memory areas */
+MEMORY
+{
+ m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x00000200
+ m_flash_config (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010
+ m_text (RX) : ORIGIN = 0x00000410, LENGTH = 0x0001FBF0
+ m_data (RW) : ORIGIN = 0x1FFFF000, LENGTH = 0x00004000
+}
+
+/* Define output sections */
+SECTIONS
+{
+ /* The startup code goes first into internal flash */
+ .interrupts :
+ {
+ __VECTOR_TABLE = .;
+ . = ALIGN(4);
+ KEEP(*(.isr_vector)) /* Startup code */
+ . = ALIGN(4);
+ } > m_interrupts
+
+ .flash_config :
+ {
+ . = ALIGN(4);
+ KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */
+ . = ALIGN(4);
+ } > m_flash_config
+
+ /* The program code and other data goes into internal flash */
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ *(.glue_7) /* glue arm to thumb code */
+ *(.glue_7t) /* glue thumb to arm code */
+ *(.eh_frame)
+ KEEP (*(.init))
+ KEEP (*(.fini))
+ . = ALIGN(4);
+ } > m_text
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ } > m_text
+
+ .ARM :
+ {
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ } > m_text
+
+ .ctors :
+ {
+ __CTOR_LIST__ = .;
+ /* gcc uses crtbegin.o to find the start of
+ the constructors, so we make sure it is
+ first. Because this is a wildcard, it
+ doesn't matter if the user does not
+ actually link against crtbegin.o; the
+ linker won't look for a file to match a
+ wildcard. The wildcard also means that it
+ doesn't matter which directory crtbegin.o
+ is in. */
+ KEEP (*crtbegin.o(.ctors))
+ KEEP (*crtbegin?.o(.ctors))
+ /* We don't want to include the .ctor section from
+ from the crtend.o file until after the sorted ctors.
+ The .ctor section from the crtend file contains the
+ end of ctors marker and it must be last */
+ KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
+ KEEP (*(SORT(.ctors.*)))
+ KEEP (*(.ctors))
+ __CTOR_END__ = .;
+ } > m_text
+
+ .dtors :
+ {
+ __DTOR_LIST__ = .;
+ KEEP (*crtbegin.o(.dtors))
+ KEEP (*crtbegin?.o(.dtors))
+ KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
+ KEEP (*(SORT(.dtors.*)))
+ KEEP (*(.dtors))
+ __DTOR_END__ = .;
+ } > m_text
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array*))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ } > m_text
+
+ .init_array :
+ {
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array*))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ } > m_text
+
+ .fini_array :
+ {
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array*))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ } > m_text
+
+ __etext = .; /* define a global symbol at end of code */
+ __DATA_ROM = .; /* Symbol is used by startup for data initialization */
+
+ /* reserve MTB memory at the beginning of m_data */
+ .mtb : /* MTB buffer address as defined by the hardware */
+ {
+ . = ALIGN(8);
+ _mtb_start = .;
+ KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */
+ . = ALIGN(8);
+ _mtb_end = .;
+ } > m_data
+
+ .interrupts_ram :
+ {
+ . = ALIGN(4);
+ __VECTOR_RAM__ = .;
+ __interrupts_ram_start__ = .; /* Create a global symbol at data start */
+ *(.m_interrupts_ram) /* This is a user defined section */
+ . += M_VECTOR_RAM_SIZE;
+ . = ALIGN(4);
+ __interrupts_ram_end__ = .; /* Define a global symbol at data end */
+ } > m_data
+
+ __VECTOR_RAM = DEFINED(__ram_vector_table__) ? __VECTOR_RAM__ : ORIGIN(m_interrupts);
+ __RAM_VECTOR_TABLE_SIZE_BYTES = DEFINED(__ram_vector_table__) ? (__interrupts_ram_end__ - __interrupts_ram_start__) : 0x0;
+
+ .data : AT(__DATA_ROM)
+ {
+ . = ALIGN(4);
+ __DATA_RAM = .;
+ __data_start__ = .; /* create a global symbol at data start */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+ KEEP(*(.jcr*))
+ . = ALIGN(4);
+ __data_end__ = .; /* define a global symbol at data end */
+ } > m_data
+
+ __DATA_END = __DATA_ROM + (__data_end__ - __data_start__);
+ text_end = ORIGIN(m_text) + LENGTH(m_text);
+ ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
+
+ /* Uninitialized data section */
+ .bss :
+ {
+ /* This is used by the startup in order to initialize the .bss section */
+ . = ALIGN(4);
+ __START_BSS = .;
+ __bss_start__ = .;
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ __END_BSS = .;
+ } > m_data
+
+ .heap :
+ {
+ . = ALIGN(8);
+ __end__ = .;
+ PROVIDE(end = .);
+ __HeapBase = .;
+ . += HEAP_SIZE;
+ __HeapLimit = .;
+ __heap_limit = .; /* Add for _sbrk */
+ } > m_data
+
+ .stack :
+ {
+ . = ALIGN(8);
+ . += STACK_SIZE;
+ } > m_data
+
+ /* Initializes stack on the end of block */
+ __StackTop = ORIGIN(m_data) + LENGTH(m_data);
+ __StackLimit = __StackTop - STACK_SIZE;
+ PROVIDE(__stack = __StackTop);
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+
+ ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap")
+}
diff --git a/hw/bsp/kinetis_kl/gcc/startup_MKL25Z4.S b/hw/bsp/kinetis_kl/gcc/startup_MKL25Z4.S
new file mode 100644
index 000000000..dc1438f3a
--- /dev/null
+++ b/hw/bsp/kinetis_kl/gcc/startup_MKL25Z4.S
@@ -0,0 +1,383 @@
+/* ---------------------------------------------------------------------------------------*/
+/* @file: startup_MKL25Z4.s */
+/* @purpose: CMSIS Cortex-M0P Core Device Startup File */
+/* MKL25Z4 */
+/* @version: 2.5 */
+/* @date: 2015-2-19 */
+/* @build: b170112 */
+/* ---------------------------------------------------------------------------------------*/
+/* */
+/* Copyright (c) 1997 - 2016, Freescale Semiconductor, Inc. */
+/* Copyright 2016 - 2017 NXP */
+/* Redistribution and use in source and binary forms, with or without modification, */
+/* are permitted provided that the following conditions are met: */
+/* */
+/* o Redistributions of source code must retain the above copyright notice, this list */
+/* of conditions and the following disclaimer. */
+/* */
+/* o Redistributions in binary form must reproduce the above copyright notice, this */
+/* list of conditions and the following disclaimer in the documentation and/or */
+/* other materials provided with the distribution. */
+/* */
+/* o Neither the name of the copyright holder nor the names of its */
+/* contributors may be used to endorse or promote products derived from this */
+/* software without specific prior written permission. */
+/* */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
+/* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
+/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
+/* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
+/* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
+/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
+/* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
+/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
+/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+/*****************************************************************************/
+/* Version: GCC for ARM Embedded Processors */
+/*****************************************************************************/
+ .syntax unified
+ .arch armv6-m
+
+ .section .isr_vector, "a"
+ .align 2
+ .globl __isr_vector
+__isr_vector:
+ .long __StackTop /* Top of Stack */
+ .long Reset_Handler /* Reset Handler */
+ .long NMI_Handler /* NMI Handler*/
+ .long HardFault_Handler /* Hard Fault Handler*/
+ .long 0 /* Reserved*/
+ .long 0 /* Reserved*/
+ .long 0 /* Reserved*/
+ .long 0 /* Reserved*/
+ .long 0 /* Reserved*/
+ .long 0 /* Reserved*/
+ .long 0 /* Reserved*/
+ .long SVC_Handler /* SVCall Handler*/
+ .long 0 /* Reserved*/
+ .long 0 /* Reserved*/
+ .long PendSV_Handler /* PendSV Handler*/
+ .long SysTick_Handler /* SysTick Handler*/
+
+ /* External Interrupts*/
+ .long DMA0_IRQHandler /* DMA channel 0 transfer complete*/
+ .long DMA1_IRQHandler /* DMA channel 1 transfer complete*/
+ .long DMA2_IRQHandler /* DMA channel 2 transfer complete*/
+ .long DMA3_IRQHandler /* DMA channel 3 transfer complete*/
+ .long Reserved20_IRQHandler /* Reserved interrupt*/
+ .long FTFA_IRQHandler /* Command complete and read collision*/
+ .long LVD_LVW_IRQHandler /* Low-voltage detect, low-voltage warning*/
+ .long LLWU_IRQHandler /* Low leakage wakeup Unit*/
+ .long I2C0_IRQHandler /* I2C0 interrupt*/
+ .long I2C1_IRQHandler /* I2C1 interrupt*/
+ .long SPI0_IRQHandler /* SPI0 single interrupt vector for all sources*/
+ .long SPI1_IRQHandler /* SPI1 single interrupt vector for all sources*/
+ .long UART0_IRQHandler /* UART0 status and error*/
+ .long UART1_IRQHandler /* UART1 status and error*/
+ .long UART2_IRQHandler /* UART2 status and error*/
+ .long ADC0_IRQHandler /* ADC0 interrupt*/
+ .long CMP0_IRQHandler /* CMP0 interrupt*/
+ .long TPM0_IRQHandler /* TPM0 single interrupt vector for all sources*/
+ .long TPM1_IRQHandler /* TPM1 single interrupt vector for all sources*/
+ .long TPM2_IRQHandler /* TPM2 single interrupt vector for all sources*/
+ .long RTC_IRQHandler /* RTC alarm*/
+ .long RTC_Seconds_IRQHandler /* RTC seconds*/
+ .long PIT_IRQHandler /* PIT interrupt*/
+ .long Reserved39_IRQHandler /* Reserved interrupt*/
+ .long USB0_IRQHandler /* USB0 interrupt*/
+ .long DAC0_IRQHandler /* DAC0 interrupt*/
+ .long TSI0_IRQHandler /* TSI0 interrupt*/
+ .long MCG_IRQHandler /* MCG interrupt*/
+ .long LPTMR0_IRQHandler /* LPTMR0 interrupt*/
+ .long Reserved45_IRQHandler /* Reserved interrupt*/
+ .long PORTA_IRQHandler /* PORTA Pin detect*/
+ .long PORTD_IRQHandler /* PORTD Pin detect*/
+
+ .size __isr_vector, . - __isr_vector
+
+/* Flash Configuration */
+ .section .FlashConfig, "a"
+ .long 0xFFFFFFFF
+ .long 0xFFFFFFFF
+ .long 0xFFFFFFFF
+ .long 0xFFFFFFFE
+
+ .text
+ .thumb
+
+/* Reset Handler */
+
+ .thumb_func
+ .align 2
+ .globl Reset_Handler
+ .weak Reset_Handler
+ .type Reset_Handler, %function
+Reset_Handler:
+ cpsid i /* Mask interrupts */
+ .equ VTOR, 0xE000ED08
+ ldr r0, =VTOR
+ ldr r1, =__isr_vector
+ str r1, [r0]
+ ldr r2, [r1]
+ msr msp, r2
+#ifndef __NO_SYSTEM_INIT
+ ldr r0,=SystemInit
+ blx r0
+#endif
+/* Loop to copy data from read only memory to RAM. The ranges
+ * of copy from/to are specified by following symbols evaluated in
+ * linker script.
+ * __etext: End of code section, i.e., begin of data sections to copy from.
+ * __data_start__/__data_end__: RAM address range that data should be
+ * copied to. Both must be aligned to 4 bytes boundary. */
+
+ ldr r1, =__etext
+ ldr r2, =__data_start__
+ ldr r3, =__data_end__
+
+ subs r3, r2
+ ble .LC0
+
+.LC1:
+ subs r3, 4
+ ldr r0, [r1,r3]
+ str r0, [r2,r3]
+ bgt .LC1
+.LC0:
+
+#ifdef __STARTUP_CLEAR_BSS
+/* This part of work usually is done in C library startup code. Otherwise,
+ * define this macro to enable it in this startup.
+ *
+ * Loop to zero out BSS section, which uses following symbols
+ * in linker script:
+ * __bss_start__: start of BSS section. Must align to 4
+ * __bss_end__: end of BSS section. Must align to 4
+ */
+ ldr r1, =__bss_start__
+ ldr r2, =__bss_end__
+
+ subs r2, r1
+ ble .LC3
+
+ movs r0, 0
+.LC2:
+ str r0, [r1, r2]
+ subs r2, 4
+ bge .LC2
+.LC3:
+#endif
+ cpsie i /* Unmask interrupts */
+#ifndef __START
+#define __START _start
+#endif
+#ifndef __ATOLLIC__
+ ldr r0,=__START
+ blx r0
+#else
+ ldr r0,=__libc_init_array
+ blx r0
+ ldr r0,=main
+ bx r0
+#endif
+ .pool
+ .size Reset_Handler, . - Reset_Handler
+
+ .align 1
+ .thumb_func
+ .weak DefaultISR
+ .type DefaultISR, %function
+DefaultISR:
+ ldr r0, =DefaultISR
+ bx r0
+ .size DefaultISR, . - DefaultISR
+
+ .align 1
+ .thumb_func
+ .weak NMI_Handler
+ .type NMI_Handler, %function
+NMI_Handler:
+ ldr r0,=NMI_Handler
+ bx r0
+ .size NMI_Handler, . - NMI_Handler
+
+ .align 1
+ .thumb_func
+ .weak HardFault_Handler
+ .type HardFault_Handler, %function
+HardFault_Handler:
+ ldr r0,=HardFault_Handler
+ bx r0
+ .size HardFault_Handler, . - HardFault_Handler
+
+ .align 1
+ .thumb_func
+ .weak SVC_Handler
+ .type SVC_Handler, %function
+SVC_Handler:
+ ldr r0,=SVC_Handler
+ bx r0
+ .size SVC_Handler, . - SVC_Handler
+
+ .align 1
+ .thumb_func
+ .weak PendSV_Handler
+ .type PendSV_Handler, %function
+PendSV_Handler:
+ ldr r0,=PendSV_Handler
+ bx r0
+ .size PendSV_Handler, . - PendSV_Handler
+
+ .align 1
+ .thumb_func
+ .weak SysTick_Handler
+ .type SysTick_Handler, %function
+SysTick_Handler:
+ ldr r0,=SysTick_Handler
+ bx r0
+ .size SysTick_Handler, . - SysTick_Handler
+
+ .align 1
+ .thumb_func
+ .weak DMA0_IRQHandler
+ .type DMA0_IRQHandler, %function
+DMA0_IRQHandler:
+ ldr r0,=DMA0_DriverIRQHandler
+ bx r0
+ .size DMA0_IRQHandler, . - DMA0_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak DMA1_IRQHandler
+ .type DMA1_IRQHandler, %function
+DMA1_IRQHandler:
+ ldr r0,=DMA1_DriverIRQHandler
+ bx r0
+ .size DMA1_IRQHandler, . - DMA1_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak DMA2_IRQHandler
+ .type DMA2_IRQHandler, %function
+DMA2_IRQHandler:
+ ldr r0,=DMA2_DriverIRQHandler
+ bx r0
+ .size DMA2_IRQHandler, . - DMA2_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak DMA3_IRQHandler
+ .type DMA3_IRQHandler, %function
+DMA3_IRQHandler:
+ ldr r0,=DMA3_DriverIRQHandler
+ bx r0
+ .size DMA3_IRQHandler, . - DMA3_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak I2C0_IRQHandler
+ .type I2C0_IRQHandler, %function
+I2C0_IRQHandler:
+ ldr r0,=I2C0_DriverIRQHandler
+ bx r0
+ .size I2C0_IRQHandler, . - I2C0_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak I2C1_IRQHandler
+ .type I2C1_IRQHandler, %function
+I2C1_IRQHandler:
+ ldr r0,=I2C1_DriverIRQHandler
+ bx r0
+ .size I2C1_IRQHandler, . - I2C1_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak SPI0_IRQHandler
+ .type SPI0_IRQHandler, %function
+SPI0_IRQHandler:
+ ldr r0,=SPI0_DriverIRQHandler
+ bx r0
+ .size SPI0_IRQHandler, . - SPI0_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak SPI1_IRQHandler
+ .type SPI1_IRQHandler, %function
+SPI1_IRQHandler:
+ ldr r0,=SPI1_DriverIRQHandler
+ bx r0
+ .size SPI1_IRQHandler, . - SPI1_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak UART0_IRQHandler
+ .type UART0_IRQHandler, %function
+UART0_IRQHandler:
+ ldr r0,=UART0_DriverIRQHandler
+ bx r0
+ .size UART0_IRQHandler, . - UART0_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak UART1_IRQHandler
+ .type UART1_IRQHandler, %function
+UART1_IRQHandler:
+ ldr r0,=UART1_DriverIRQHandler
+ bx r0
+ .size UART1_IRQHandler, . - UART1_IRQHandler
+
+ .align 1
+ .thumb_func
+ .weak UART2_IRQHandler
+ .type UART2_IRQHandler, %function
+UART2_IRQHandler:
+ ldr r0,=UART2_DriverIRQHandler
+ bx r0
+ .size UART2_IRQHandler, . - UART2_IRQHandler
+
+
+/* Macro to define default handlers. Default handler
+ * will be weak symbol and just dead loops. They can be
+ * overwritten by other handlers */
+ .macro def_irq_handler handler_name
+ .weak \handler_name
+ .set \handler_name, DefaultISR
+ .endm
+
+/* Exception Handlers */
+ def_irq_handler DMA0_DriverIRQHandler
+ def_irq_handler DMA1_DriverIRQHandler
+ def_irq_handler DMA2_DriverIRQHandler
+ def_irq_handler DMA3_DriverIRQHandler
+ def_irq_handler Reserved20_IRQHandler
+ def_irq_handler FTFA_IRQHandler
+ def_irq_handler LVD_LVW_IRQHandler
+ def_irq_handler LLWU_IRQHandler
+ def_irq_handler I2C0_DriverIRQHandler
+ def_irq_handler I2C1_DriverIRQHandler
+ def_irq_handler SPI0_DriverIRQHandler
+ def_irq_handler SPI1_DriverIRQHandler
+ def_irq_handler UART0_DriverIRQHandler
+ def_irq_handler UART1_DriverIRQHandler
+ def_irq_handler UART2_DriverIRQHandler
+ def_irq_handler ADC0_IRQHandler
+ def_irq_handler CMP0_IRQHandler
+ def_irq_handler TPM0_IRQHandler
+ def_irq_handler TPM1_IRQHandler
+ def_irq_handler TPM2_IRQHandler
+ def_irq_handler RTC_IRQHandler
+ def_irq_handler RTC_Seconds_IRQHandler
+ def_irq_handler PIT_IRQHandler
+ def_irq_handler Reserved39_IRQHandler
+ def_irq_handler USB0_IRQHandler
+ def_irq_handler DAC0_IRQHandler
+ def_irq_handler TSI0_IRQHandler
+ def_irq_handler MCG_IRQHandler
+ def_irq_handler LPTMR0_IRQHandler
+ def_irq_handler Reserved45_IRQHandler
+ def_irq_handler PORTA_IRQHandler
+ def_irq_handler PORTD_IRQHandler
+
+ .end
diff --git a/hw/bsp/mcx/boards/mcxn947brk/board.cmake b/hw/bsp/mcx/boards/mcxn947brk/board.cmake
index 650f10967..8c3280743 100644
--- a/hw/bsp/mcx/boards/mcxn947brk/board.cmake
+++ b/hw/bsp/mcx/boards/mcxn947brk/board.cmake
@@ -5,12 +5,14 @@ set(JLINK_DEVICE MCXN947_M33_0)
set(PYOCD_TARGET MCXN947)
set(NXPLINK_DEVICE MCXN947:MCXN947)
+set(PORT 1)
+
function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
CPU_MCXN947VDF_cm33_core0
- # port 1 is highspeed
- BOARD_TUD_RHPORT=1
- BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
+ BOARD_TUD_RHPORT=${PORT}
+ # port 0 is fullspeed, port 1 is highspeed
+ BOARD_TUD_MAX_SPEED=$
)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c
diff --git a/hw/bsp/mcx/family.c b/hw/bsp/mcx/family.c
index 36d2f2d0a..4344ffc4e 100644
--- a/hw/bsp/mcx/family.c
+++ b/hw/bsp/mcx/family.c
@@ -66,6 +66,7 @@ void board_init(void)
{
BOARD_InitPins();
BOARD_InitBootClocks();
+ CLOCK_SetupExtClocking(XTAL0_CLK_HZ);
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
@@ -122,31 +123,13 @@ void board_init(void)
// USB VBUS
/* PORT0 PIN22 configured as USB0_VBUS */
- CLOCK_SetupExtClocking(XTAL0_CLK_HZ);
-
#if PORT_SUPPORT_DEVICE(0)
// Port0 is Full Speed
- /* Turn on USB0 Phy */
- POWER_DisablePD(kPDRUNCFG_PD_USB0_PHY);
-
- /* reset the IP to make sure it's in reset state. */
- RESET_PeripheralReset(kUSB0D_RST_SHIFT_RSTn);
- RESET_PeripheralReset(kUSB0HSL_RST_SHIFT_RSTn);
- RESET_PeripheralReset(kUSB0HMR_RST_SHIFT_RSTn);
-
- // Enable USB Clock Adjustments to trim the FRO for the full speed controller
- ANACTRL->FRO192M_CTRL |= ANACTRL_FRO192M_CTRL_USBCLKADJ_MASK;
- CLOCK_SetClkDiv(kCLOCK_DivUsb0Clk, 1, false);
- CLOCK_AttachClk(kFRO_HF_to_USB0_CLK);
-
- /*According to reference manual, device mode setting has to be set by access usb host register */
- CLOCK_EnableClock(kCLOCK_Usbhsl0); // enable usb0 host clock
- USBFSH->PORTMODE |= USBFSH_PORTMODE_DEV_ENABLE_MASK;
- CLOCK_DisableClock(kCLOCK_Usbhsl0); // disable usb0 host clock
-
- /* enable USB Device clock */
- CLOCK_EnableUsbfs0DeviceClock(kCLOCK_UsbfsSrcFro, CLOCK_GetFreq(kCLOCK_FroHf));
+ CLOCK_AttachClk(kCLK_48M_to_USB0);
+ CLOCK_EnableClock(kCLOCK_Usb0Ram);
+ CLOCK_EnableClock(kCLOCK_Usb0Fs);
+ CLOCK_EnableUsbfsClock();
#endif
#if PORT_SUPPORT_DEVICE(1)
diff --git a/hw/bsp/mcx/family.cmake b/hw/bsp/mcx/family.cmake
index 1c85b51f8..7c5feaecf 100644
--- a/hw/bsp/mcx/family.cmake
+++ b/hw/bsp/mcx/family.cmake
@@ -88,8 +88,8 @@ function(family_configure_example TARGET)
#---------- Port Specific ----------
# These files are built for each example since it depends on example's tusb_config.h
target_sources(${TARGET} PUBLIC
- # TinyUSB Port
- ${TOP}/src/portable/chipidea/ci_hs/dcd_ci_hs.c
+ # TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS
+ ${TOP}/src/portable/chipidea/$
# BSP
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
diff --git a/hw/bsp/mcx/family.mk b/hw/bsp/mcx/family.mk
index 2cd4c2448..2722c2038 100644
--- a/hw/bsp/mcx/family.mk
+++ b/hw/bsp/mcx/family.mk
@@ -16,21 +16,24 @@ CFLAGS += \
-DCFG_TUSB_MCU=OPT_MCU_MCXN9 \
-DBOARD_TUD_RHPORT=$(PORT) \
-ifeq ($(PORT), 1)
- $(info "PORT1 High Speed")
- CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
-else
- $(info "PORT0 Full Speed")
-endif
-
# mcu driver cause following warnings
CFLAGS += -Wno-error=unused-parameter -Wno-error=old-style-declaration
# All source paths should be relative to the top level.
LD_FILE ?= $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/$(MCU_CORE)_flash.ld
+# TinyUSB: Port0 is chipidea FS, Port1 is chipidea HS
+ifeq ($(PORT), 1)
+ $(info "PORT1 High Speed")
+ CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
+ SRC_C += src/portable/chipidea/ci_hs/dcd_ci_hs.c
+else
+ $(info "PORT0 Full Speed")
+ CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED
+ SRC_C += src/portable/chipidea/ci_fs/dcd_ci_fs.c
+endif
+
SRC_C += \
- src/portable/chipidea/ci_hs/dcd_ci_hs.c \
$(SDK_DIR)/devices/$(MCU_VARIANT)/system_$(MCU_CORE).c \
$(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_clock.c \
$(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_reset.c \
diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h
index f89467e75..485d6168d 100644
--- a/src/common/tusb_mcu.h
+++ b/src/common/tusb_mcu.h
@@ -79,7 +79,11 @@
#define TUP_RHPORT_HIGHSPEED 1
#elif TU_CHECK_MCU(OPT_MCU_MCXN9)
- // NOTE: MCXN943 port 1 use chipidea HS, port 0 use chipidea FS
+ // USB0 is chipidea FS
+ #define TUP_USBIP_CHIPIDEA_FS
+ #define TUP_USBIP_CHIPIDEA_FS_MCX
+
+ // USB1 is chipidea HS
#define TUP_USBIP_CHIPIDEA_HS
#define TUP_USBIP_EHCI
diff --git a/src/portable/chipidea/ci_fs/ci_fs_kinetis.h b/src/portable/chipidea/ci_fs/ci_fs_kinetis.h
new file mode 100644
index 000000000..cd21af1c7
--- /dev/null
+++ b/src/portable/chipidea/ci_fs/ci_fs_kinetis.h
@@ -0,0 +1,51 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2023 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef _CI_FS_KINETIS_H
+#define _CI_FS_KINETIS_H
+
+#include "fsl_device_registers.h"
+
+//static const ci_fs_controller_t _ci_controller[] = {
+// {.reg_base = USB0_BASE, .irqnum = USB0_IRQn}
+//};
+
+#define CI_FS_REG(_port) ((ci_fs_regs_t*) USB0_BASE)
+#define CI_REG CI_FS_REG(0)
+
+void dcd_int_enable(uint8_t rhport)
+{
+ (void) rhport;
+ NVIC_EnableIRQ(USB0_IRQn);
+}
+
+void dcd_int_disable(uint8_t rhport)
+{
+ (void) rhport;
+ NVIC_DisableIRQ(USB0_IRQn);
+}
+
+#endif
diff --git a/src/portable/chipidea/ci_fs/ci_fs_mcx.h b/src/portable/chipidea/ci_fs/ci_fs_mcx.h
new file mode 100644
index 000000000..3bfcd398e
--- /dev/null
+++ b/src/portable/chipidea/ci_fs/ci_fs_mcx.h
@@ -0,0 +1,47 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2023 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef _CI_FS_MCX_H
+#define _CI_FS_MCX_H
+
+#include "fsl_device_registers.h"
+
+#define CI_FS_REG(_port) ((ci_fs_regs_t*) USBFS0_BASE)
+#define CI_REG CI_FS_REG(0)
+
+void dcd_int_enable(uint8_t rhport)
+{
+ (void) rhport;
+ NVIC_EnableIRQ(USB0_FS_IRQn);
+}
+
+void dcd_int_disable(uint8_t rhport)
+{
+ (void) rhport;
+ NVIC_DisableIRQ(USB0_FS_IRQn);
+}
+
+#endif
diff --git a/src/portable/chipidea/ci_fs/ci_fs_type.h b/src/portable/chipidea/ci_fs/ci_fs_type.h
new file mode 100644
index 000000000..5a5e53fb0
--- /dev/null
+++ b/src/portable/chipidea/ci_fs/ci_fs_type.h
@@ -0,0 +1,118 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2023 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#ifndef _CI_FS_TYPE_H
+#define _CI_FS_TYPE_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+// Note: some MCUs can only access these registers in 8-bit mode
+// align 4 is used to get rid of reserved fields
+#define _va32 volatile TU_ATTR_ALIGNED(4)
+
+typedef struct {
+ _va32 uint8_t PER_ID; // [00] Peripheral ID register
+ _va32 uint8_t ID_COMP; // [04] Peripheral ID complement register
+ _va32 uint8_t REV; // [08] Peripheral revision register
+ _va32 uint8_t ADD_INFO; // [0C] Peripheral additional info register
+ _va32 uint8_t OTG_ISTAT; // [10] OTG Interrupt Status Register
+ _va32 uint8_t OTG_ICTRL; // [14] OTG Interrupt Control Register
+ _va32 uint8_t OTG_STAT; // [18] OTG Status Register
+ _va32 uint8_t OTG_CTRL; // [1C] OTG Control register
+ uint32_t reserved_20[24]; // [20]
+ _va32 uint8_t INT_STAT; // [80] Interrupt status register
+ _va32 uint8_t INT_EN; // [84] Interrupt enable register
+ _va32 uint8_t ERR_STAT; // [88] Error interrupt status register
+ _va32 uint8_t ERR_ENB; // [8C] Error interrupt enable register
+ _va32 uint8_t STAT; // [90] Status register
+ _va32 uint8_t CTL; // [94] Control register
+ _va32 uint8_t ADDR; // [98] Address register
+ _va32 uint8_t BDT_PAGE1; // [9C] BDT page register 1
+ _va32 uint8_t FRM_NUML; // [A0] Frame number register
+ _va32 uint8_t FRM_NUMH; // [A4] Frame number register
+ _va32 uint8_t TOKEN; // [A8] Token register
+ _va32 uint8_t SOF_THLD; // [AC] SOF threshold register
+ _va32 uint8_t BDT_PAGE2; // [B0] BDT page register 2
+ _va32 uint8_t BDT_PAGE3; // [B4] BDT page register 3
+
+ uint32_t reserved_b8; // [B8]
+ uint32_t reserved_bc; // [BC]
+
+ struct {
+ _va32 uint8_t CTL;
+ }EP[16]; // [C0] Endpoint control register
+
+ //----- Following is only found available in NXP Kinetis
+ _va32 uint8_t USBCTRL; // [100] USB Control register,
+ _va32 uint8_t OBSERVE; // [104] USB OTG Observe register,
+ _va32 uint8_t CONTROL; // [108] USB OTG Control register,
+ _va32 uint8_t USBTRC0; // [10C] USB Transceiver Control Register 0,
+ uint32_t reserved_110; // [110]
+ _va32 uint8_t USBFRMADJUST; // [114] Frame Adjust Register,
+
+ //----- Following is only found available in NXP MCX
+ uint32_t reserved_118[3]; // [118]
+ _va32 uint8_t KEEP_ALIVE_CTRL; // [124] Keep Alive Mode Control,
+ _va32 uint8_t KEEP_ALIVE_WKCTRL; // [128] Keep Alive Mode Wakeup Control,
+ _va32 uint8_t MISCCTRL; // [12C] Miscellaneous Control,
+ _va32 uint8_t STALL_IL_DIS; // [130] Peripheral Mode Stall Disable for Endpoints[ 7..0] IN
+ _va32 uint8_t STALL_IH_DIS; // [134] Peripheral Mode Stall Disable for Endpoints[15..8] IN
+ _va32 uint8_t STALL_OL_DIS; // [138] Peripheral Mode Stall Disable for Endpoints[ 7..0] OUT
+ _va32 uint8_t STALL_OH_DIS; // [13C] Peripheral Mode Stall Disable for Endpoints[15..8] OUT
+ _va32 uint8_t CLK_RECOVER_CTRL; // [140] USB Clock Recovery Control,
+ _va32 uint8_t CLK_RECOVER_IRC_EN; // [144] FIRC Oscillator Enable,
+ uint32_t reserved_148[3]; // [148]
+ _va32 uint8_t CLK_RECOVER_INT_EN; // [154] Clock Recovery Combined Interrupt Enable,
+ uint32_t reserved_158; // [158]
+ _va32 uint8_t CLK_RECOVER_INT_STATUS; // [15C] Clock Recovery Separated Interrupt Status,
+} ci_fs_regs_t;
+
+TU_VERIFY_STATIC(sizeof(ci_fs_regs_t) == 0x160, "Size is not correct");
+
+typedef struct
+{
+ uint32_t reg_base;
+ uint32_t irqnum;
+} ci_fs_controller_t;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c
new file mode 100644
index 000000000..37265df8b
--- /dev/null
+++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c
@@ -0,0 +1,555 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Koji Kitayama
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "tusb_option.h"
+
+#if CFG_TUD_ENABLED && defined(TUP_USBIP_CHIPIDEA_FS)
+
+#include "device/dcd.h"
+#include "ci_fs_type.h"
+
+#if defined(TUP_USBIP_CHIPIDEA_FS_KINETIS)
+ #include "ci_fs_kinetis.h"
+#elif defined(TUP_USBIP_CHIPIDEA_FS_MCX)
+ #include "ci_fs_mcx.h"
+#else
+ #error "MCU is not supported"
+#endif
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+
+enum {
+ TOK_PID_OUT = 0x1u,
+ TOK_PID_IN = 0x9u,
+ TOK_PID_SETUP = 0xDu,
+};
+
+typedef struct TU_ATTR_PACKED
+{
+ union {
+ uint32_t head;
+ struct {
+ union {
+ struct {
+ uint16_t : 2;
+ __IO uint16_t tok_pid : 4;
+ uint16_t data : 1;
+ __IO uint16_t own : 1;
+ uint16_t : 8;
+ };
+ struct {
+ uint16_t : 2;
+ uint16_t bdt_stall : 1;
+ uint16_t dts : 1;
+ uint16_t ninc : 1;
+ uint16_t keep : 1;
+ uint16_t : 10;
+ };
+ };
+ __IO uint16_t bc : 10;
+ uint16_t : 6;
+ };
+ };
+ uint8_t *addr;
+}buffer_descriptor_t;
+
+TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" );
+
+typedef struct TU_ATTR_PACKED
+{
+ union {
+ uint32_t state;
+ struct {
+ uint32_t max_packet_size :11;
+ uint32_t : 5;
+ uint32_t odd : 1;
+ uint32_t :15;
+ };
+ };
+ uint16_t length;
+ uint16_t remaining;
+}endpoint_state_t;
+
+TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" );
+
+typedef struct
+{
+ union {
+ /* [#EP][OUT,IN][EVEN,ODD] */
+ buffer_descriptor_t bdt[16][2][2];
+ uint16_t bda[512];
+ };
+ TU_ATTR_ALIGNED(4) union {
+ endpoint_state_t endpoint[16][2];
+ endpoint_state_t endpoint_unified[16 * 2];
+ };
+ uint8_t setup_packet[8];
+ uint8_t addr;
+}dcd_data_t;
+
+//--------------------------------------------------------------------+
+// INTERNAL OBJECT & FUNCTION DECLARATION
+//--------------------------------------------------------------------+
+// BDT(Buffer Descriptor Table) must be 256-byte aligned
+CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
+
+TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
+
+static void prepare_next_setup_packet(uint8_t rhport)
+{
+ const unsigned out_odd = _dcd.endpoint[0][0].odd;
+ const unsigned in_odd = _dcd.endpoint[0][1].odd;
+ TU_ASSERT(0 == _dcd.bdt[0][0][out_odd].own, );
+
+ _dcd.bdt[0][0][out_odd].data = 0;
+ _dcd.bdt[0][0][out_odd ^ 1].data = 1;
+ _dcd.bdt[0][1][in_odd].data = 1;
+ _dcd.bdt[0][1][in_odd ^ 1].data = 0;
+ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT),
+ _dcd.setup_packet, sizeof(_dcd.setup_packet));
+}
+
+static void process_stall(uint8_t rhport)
+{
+ for (int i = 0; i < 16; ++i) {
+ uint32_t const ep_ctl = CI_REG->EP[i].CTL;
+
+ if (ep_ctl & USB_ENDPT_EPSTALL_MASK) {
+ // prepare next setup if endpoint0
+ if ( i == 0 ) prepare_next_setup_packet(rhport);
+
+ // clear stall bit
+ CI_REG->EP[i].CTL = ep_ctl & ~USB_ENDPT_EPSTALL_MASK;
+ }
+ }
+}
+
+static void process_tokdne(uint8_t rhport)
+{
+ const unsigned s = CI_REG->STAT;
+ CI_REG->INT_STAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */
+
+ uint8_t const epnum = (s >> USB_STAT_ENDP_SHIFT);
+ uint8_t const dir = (s & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT;
+ unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0;
+
+ buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s];
+ endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3];
+
+ /* fetch pid before discarded by the next steps */
+ const unsigned pid = bd->tok_pid;
+
+ /* reset values for a next transfer */
+ bd->bdt_stall = 0;
+ bd->dts = 1;
+ bd->ninc = 0;
+ bd->keep = 0;
+ /* update the odd variable to prepare for the next transfer */
+ ep->odd = odd ^ 1;
+ if (pid == TOK_PID_SETUP) {
+ dcd_event_setup_received(rhport, bd->addr, true);
+ CI_REG->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
+ return;
+ }
+
+ const unsigned bc = bd->bc;
+ const unsigned remaining = ep->remaining - bc;
+ if (remaining && bc == ep->max_packet_size) {
+ /* continue the transferring consecutive data */
+ ep->remaining = remaining;
+ const int next_remaining = remaining - ep->max_packet_size;
+ if (next_remaining > 0) {
+ /* prepare to the after next transfer */
+ bd->addr += ep->max_packet_size * 2;
+ bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining;
+ __DSB();
+ bd->own = 1; /* the own bit must set after addr */
+ }
+ return;
+ }
+ const unsigned length = ep->length;
+ dcd_event_xfer_complete(rhport,
+ tu_edpt_addr(epnum, dir),
+ length - remaining, XFER_RESULT_SUCCESS, true);
+ if (0 == epnum && 0 == length) {
+ /* After completion a ZLP of control transfer,
+ * it prepares for the next steup transfer. */
+ if (_dcd.addr) {
+ /* When the transfer was the SetAddress,
+ * the device address should be updated here. */
+ CI_REG->ADDR = _dcd.addr;
+ _dcd.addr = 0;
+ }
+ prepare_next_setup_packet(rhport);
+ }
+}
+
+static void process_bus_reset(uint8_t rhport)
+{
+ CI_REG->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;
+ CI_REG->CTL |= USB_CTL_ODDRST_MASK;
+ CI_REG->ADDR = 0;
+ CI_REG->INT_EN = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_SLEEPEN_MASK |
+ USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK;
+
+ CI_REG->EP[0].CTL = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK;
+ for (unsigned i = 1; i < 16; ++i) {
+ CI_REG->EP[i].CTL = 0;
+ }
+ buffer_descriptor_t *bd = _dcd.bdt[0][0];
+ for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) {
+ bd->head = 0;
+ }
+ const endpoint_state_t ep0 = {
+ .max_packet_size = CFG_TUD_ENDPOINT0_SIZE,
+ .odd = 0,
+ .length = 0,
+ .remaining = 0,
+ };
+ _dcd.endpoint[0][0] = ep0;
+ _dcd.endpoint[0][1] = ep0;
+ tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0]));
+ _dcd.addr = 0;
+ prepare_next_setup_packet(rhport);
+ CI_REG->CTL &= ~USB_CTL_ODDRST_MASK;
+ dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true);
+}
+
+static void process_bus_sleep(uint8_t rhport)
+{
+ // Enable resume & disable suspend interrupt
+ const unsigned inten = CI_REG->INT_EN;
+
+ CI_REG->INT_EN = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK;
+ CI_REG->USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK;
+ CI_REG->USBCTRL |= USB_USBCTRL_SUSP_MASK;
+
+ dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
+}
+
+static void process_bus_resume(uint8_t rhport)
+{
+ // Enable suspend & disable resume interrupt
+ const unsigned inten = CI_REG->INT_EN;
+
+ CI_REG->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; // will also clear USB_USBTRC0_USB_RESUME_INT_MASK
+ CI_REG->USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK;
+ CI_REG->INT_EN = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK;
+
+ dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
+}
+
+/*------------------------------------------------------------------*/
+/* Device API
+ *------------------------------------------------------------------*/
+void dcd_init(uint8_t rhport)
+{
+ (void) rhport;
+
+ CI_REG->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
+ while (CI_REG->USBTRC0 & USB_USBTRC0_USBRESET_MASK);
+
+ tu_memclr(&_dcd, sizeof(_dcd));
+ CI_REG->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */
+ CI_REG->BDT_PAGE1 = (uint8_t)((uintptr_t)_dcd.bdt >> 8);
+ CI_REG->BDT_PAGE2 = (uint8_t)((uintptr_t)_dcd.bdt >> 16);
+ CI_REG->BDT_PAGE3 = (uint8_t)((uintptr_t)_dcd.bdt >> 24);
+
+ CI_REG->INT_EN = USB_INTEN_USBRSTEN_MASK;
+
+ dcd_connect(rhport);
+ // NVIC_ClearPendingIRQ(USB0_IRQn);
+}
+
+void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
+{
+ _dcd.addr = dev_addr & 0x7F;
+ /* Response with status first before changing device address */
+ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
+}
+
+void dcd_remote_wakeup(uint8_t rhport)
+{
+ (void) rhport;
+
+ CI_REG->CTL |= USB_CTL_RESUME_MASK;
+
+ unsigned cnt = SystemCoreClock / 1000;
+ while (cnt--) __NOP();
+
+ CI_REG->CTL &= ~USB_CTL_RESUME_MASK;
+}
+
+void dcd_connect(uint8_t rhport)
+{
+ (void) rhport;
+ CI_REG->USBCTRL = 0;
+ CI_REG->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
+ CI_REG->CTL |= USB_CTL_USBENSOFEN_MASK;
+}
+
+void dcd_disconnect(uint8_t rhport)
+{
+ (void) rhport;
+ CI_REG->CTL = 0;
+ CI_REG->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
+}
+
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+ (void) rhport;
+ (void) en;
+
+ // TODO implement later
+}
+
+//--------------------------------------------------------------------+
+// Endpoint API
+//--------------------------------------------------------------------+
+bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
+{
+ (void) rhport;
+
+ const unsigned ep_addr = ep_desc->bEndpointAddress;
+ const unsigned epn = tu_edpt_number(ep_addr);
+ const unsigned dir = tu_edpt_dir(ep_addr);
+ const unsigned xfer = ep_desc->bmAttributes.xfer;
+ endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
+ const unsigned odd = ep->odd;
+ buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
+
+ /* No support for control transfer */
+ TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL));
+
+ ep->max_packet_size = tu_edpt_packet_size(ep_desc);
+ unsigned val = USB_ENDPT_EPCTLDIS_MASK;
+ val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK: 0;
+ val |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
+ CI_REG->EP[epn].CTL |= val;
+
+ if (xfer != TUSB_XFER_ISOCHRONOUS) {
+ bd[odd].dts = 1;
+ bd[odd].data = 0;
+ bd[odd ^ 1].dts = 1;
+ bd[odd ^ 1].data = 1;
+ }
+
+ return true;
+}
+
+void dcd_edpt_close_all(uint8_t rhport)
+{
+ dcd_int_disable(rhport);
+
+ for (unsigned i = 1; i < 16; ++i) {
+ CI_REG->EP[i].CTL = 0;
+ }
+
+ dcd_int_enable(rhport);
+
+ buffer_descriptor_t *bd = _dcd.bdt[1][0];
+ for (unsigned i = 2; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) {
+ bd->head = 0;
+ }
+
+ endpoint_state_t *ep = &_dcd.endpoint[1][0];
+ for (unsigned i = 2; i < sizeof(_dcd.endpoint)/sizeof(*ep); ++i, ++ep) {
+ /* Clear except the odd */
+ ep->max_packet_size = 0;
+ ep->length = 0;
+ ep->remaining = 0;
+ }
+}
+
+void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
+{
+ const unsigned epn = tu_edpt_number(ep_addr);
+ const unsigned dir = tu_edpt_dir(ep_addr);
+ endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
+ buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
+ const unsigned msk = dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
+
+ dcd_int_disable(rhport);
+
+ CI_REG->EP[epn].CTL &= ~msk;
+ ep->max_packet_size = 0;
+ ep->length = 0;
+ ep->remaining = 0;
+ bd[0].head = 0;
+ bd[1].head = 0;
+
+ dcd_int_enable(rhport);
+}
+
+bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
+{
+ const unsigned epn = tu_edpt_number(ep_addr);
+ const unsigned dir = tu_edpt_dir(ep_addr);
+ endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
+ buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd];
+ TU_ASSERT(0 == bd->own);
+
+ dcd_int_disable(rhport);
+
+ ep->length = total_bytes;
+ ep->remaining = total_bytes;
+
+ const unsigned mps = ep->max_packet_size;
+ if (total_bytes > mps) {
+ buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1;
+ /* When total_bytes is greater than the max packet size,
+ * it prepares to the next transfer to avoid NAK in advance. */
+ next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps;
+ next->addr = buffer + mps;
+ next->own = 1;
+ }
+ bd->bc = total_bytes >= mps ? mps: total_bytes;
+ bd->addr = buffer;
+ __DSB();
+ bd->own = 1; /* This bit must be set last */
+
+ dcd_int_enable(rhport);
+
+ return true;
+}
+
+void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
+{
+ (void) rhport;
+ const unsigned epn = tu_edpt_number(ep_addr);
+
+ if (0 == epn) {
+ CI_REG->EP[epn].CTL |= USB_ENDPT_EPSTALL_MASK;
+ } else {
+ const unsigned dir = tu_edpt_dir(ep_addr);
+ const unsigned odd = _dcd.endpoint[epn][dir].odd;
+ buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][odd];
+ TU_ASSERT(0 == bd->own,);
+
+ dcd_int_disable(rhport);
+
+ bd->bdt_stall = 1;
+ __DSB();
+ bd->own = 1; /* This bit must be set last */
+
+ dcd_int_enable(rhport);
+ }
+}
+
+void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
+{
+ const unsigned epn = tu_edpt_number(ep_addr);
+ TU_VERIFY(epn,);
+ const unsigned dir = tu_edpt_dir(ep_addr);
+ const unsigned odd = _dcd.endpoint[epn][dir].odd;
+ buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
+ TU_VERIFY(bd[odd].own,);
+
+ dcd_int_disable(rhport);
+
+ bd[odd].own = 0;
+ __DSB();
+
+ // clear stall
+ bd[odd].bdt_stall = 0;
+
+ // Reset data toggle
+ bd[odd ].data = 0;
+ bd[odd ^ 1].data = 1;
+
+ // We already cleared this in ISR, but just clear it here to be safe
+ const uint32_t ep_ctl = CI_REG->EP[epn].CTL;
+ if (ep_ctl & USB_ENDPT_EPSTALL_MASK) {
+ CI_REG->EP[epn].CTL = ep_ctl & ~USB_ENDPT_EPSTALL_MASK;
+ }
+
+ dcd_int_enable(rhport);
+}
+
+//--------------------------------------------------------------------+
+// ISR
+//--------------------------------------------------------------------+
+void dcd_int_handler(uint8_t rhport)
+{
+ uint32_t is = CI_REG->INT_STAT;
+ uint32_t msk = CI_REG->INT_EN;
+
+ // clear non-enabled interrupts
+ CI_REG->INT_STAT = is & ~msk;
+ is &= msk;
+
+ if (is & USB_ISTAT_ERROR_MASK) {
+ /* TODO: */
+ uint32_t es = CI_REG->ERR_STAT;
+ CI_REG->ERR_STAT = es;
+ CI_REG->INT_STAT = is; /* discard any pending events */
+ }
+
+ if (is & USB_ISTAT_USBRST_MASK) {
+ CI_REG->INT_STAT = is; /* discard any pending events */
+ process_bus_reset(rhport);
+ }
+
+ if (is & USB_ISTAT_SLEEP_MASK) {
+ // TU_LOG2("Suspend: "); TU_LOG2_HEX(is);
+
+ // Note Host usually has extra delay after bus reset (without SOF), which could falsely
+ // detected as Sleep event. Though usbd has debouncing logic so we are good
+ CI_REG->INT_STAT = USB_ISTAT_SLEEP_MASK;
+ process_bus_sleep(rhport);
+ }
+
+#if 0 // ISTAT_RESUME never trigger, probably for host mode ?
+ if (is & USB_ISTAT_RESUME_MASK) {
+ // TU_LOG2("ISTAT Resume: "); TU_LOG2_HEX(is);
+ KHCI->ISTAT = USB_ISTAT_RESUME_MASK;
+ process_bus_resume(rhport);
+ }
+#endif
+
+ if (CI_REG->USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK) {
+ // TU_LOG2("USBTRC0 Resume: "); TU_LOG2_HEX(is); TU_LOG2_HEX(KHCI->USBTRC0);
+ process_bus_resume(rhport);
+ }
+
+ if (is & USB_ISTAT_SOFTOK_MASK) {
+ CI_REG->INT_STAT = USB_ISTAT_SOFTOK_MASK;
+ dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
+ }
+
+ if (is & USB_ISTAT_STALL_MASK) {
+ CI_REG->INT_STAT = USB_ISTAT_STALL_MASK;
+ process_stall(rhport);
+ }
+
+ if (is & USB_ISTAT_TOKDNE_MASK) {
+ process_tokdne(rhport);
+ }
+}
+
+#endif
diff --git a/tools/get_deps.py b/tools/get_deps.py
index b4739e940..7e798cf9e 100644
--- a/tools/get_deps.py
+++ b/tools/get_deps.py
@@ -53,9 +53,6 @@ deps_optional = {
'hw/mcu/nxp/mcux-sdk': ['https://github.com/hathach/mcux-sdk.git',
'950819b7de9b32f92c3edf396bc5ffb8d66e7009',
'kinetis_k32l lpc51 lpc54 lpc55 mcx imxrt'],
- 'hw/mcu/nxp/nxp_sdk': ['https://github.com/hathach/nxp_sdk.git',
- '845c8fc49b6fb660f06a5c45225494eacb06f00c',
- 'kinetis_kl'],
'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/sekigon-gonnoc/Pico-PIO-USB.git',
'c3715ce94b6f6391856de56081d4d9b3e98fa93d',
'rp2040'],
diff --git a/tools/get_family_deps.py b/tools/get_family_deps.py
deleted file mode 100644
index 071d7b756..000000000
--- a/tools/get_family_deps.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import sys
-import subprocess
-import os
-
-# TOP is tinyusb root dir
-TOP = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-def get_family_dep(family):
- for entry in os.scandir("{}/hw/bsp/{}/boards".format(TOP, family)):
- if entry.is_dir():
- result = subprocess.run("make -C {}/examples/device/board_test BOARD={} get-deps".format(TOP, entry.name),
- shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- print(result.stdout.decode("utf-8"))
- return result.returncode
-
-
-status = 0
-for d in sys.argv[1:]:
- status += get_family_dep(d)
-
-sys.exit(status)