diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 013eb1c834..bc0f928dbd 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -50,6 +50,9 @@ #elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K) #include "fsl_device_registers.h" +#elif TU_CHECK_MCU(OPT_MCU_KINETIS_K28F) + #include "fsl_device_registers.h" + #elif CFG_TUSB_MCU == OPT_MCU_NRF5X #include "nrf.h" diff --git a/hw/bsp/kinetis_k28/boards/frdm_k28fa15/board.h b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/board.h new file mode 100644 index 0000000000..d329b68349 --- /dev/null +++ b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/board.h @@ -0,0 +1,56 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, 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 BOARD_H_ +#define BOARD_H_ + +#include "fsl_device_registers.h" + +// Green LED +#define LED_PIN_CLOCK kCLOCK_PortE +#define LED_GPIO GPIOE +#define LED_PORT PORTE +#define LED_PIN 6 +#define LED_STATE_ON 1 + +// SW3 button1 +#define BUTTON_PIN_CLOCK kCLOCK_PortD +#define BUTTON_GPIO GPIOD +#define BUTTON_PORT PORTD +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_PORT LPUART0 +#define UART_PIN_CLOCK kCLOCK_PortC +#define UART_PIN_PORT PORTC +#define UART_PIN_RX 24u +#define UART_PIN_TX 25u +#define SOPT5_LPUART0RXSRC_LPUART_RX 0x00u /*!<@brief LPUART0 Receive Data Source Select: LPUART_RX pin */ +#define SOPT5_LPUART0TXSRC_LPUART_TX 0x00u /*!<@brief LPUART0 Transmit Data Source Select: LPUART0_TX pin */ + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/kinetis_k28/boards/frdm_k28fa15/board.mk b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/board.mk new file mode 100644 index 0000000000..c7286fd75e --- /dev/null +++ b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/board.mk @@ -0,0 +1,18 @@ +MCU = MK28FA15 + +CFLAGS += -DCPU_MK28FN2M0AVMI15 + +# mcu driver cause following warnings +CFLAGS += -Wno-unused-parameter -Wno-redundant-decls + +# All source paths should be relative to the top level. +LD_FILE = $(MCU_DIR)/gcc/MK28FN2M0Axxx15_flash.ld + +# For flash-jlink target +JLINK_DEVICE = MK28FN2M0Axxx15 + +# For flash-pyocd target +PYOCD_TARGET = MK28FA15 + +# flash using pyocd +flash: flash-pyocd diff --git a/hw/bsp/kinetis_k28/boards/frdm_k28fa15/clock_config.c b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/clock_config.c new file mode 100644 index 0000000000..fce2e1b121 --- /dev/null +++ b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/clock_config.c @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017,2019 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. + **********************************************************************************************************************/ +/* + * How to setup clock using clock driver functions: + * + * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock + * and flash clock are in allowed range during clock mode switch. + * + * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. + * + * 3. Set MCG configuration, MCG includes three parts: FLL clock, PLL clock and + * internal reference clock(MCGIRCLK). Follow the steps to setup: + * + * 1). Call CLOCK_BootToXxxMode to set MCG to target mode. + * + * 2). If target mode is FBI/BLPI/PBI mode, the MCGIRCLK has been configured + * correctly. For other modes, need to call CLOCK_SetInternalRefClkConfig + * explicitly to setup MCGIRCLK. + * + * 3). Don't need to configure FLL explicitly, because if target mode is FLL + * mode, then FLL has been configured by the function CLOCK_BootToXxxMode, + * if the target mode is not FLL mode, the FLL is disabled. + * + * 4). If target mode is PEE/PBE/PEI/PBI mode, then the related PLL has been + * setup by CLOCK_BootToXxxMode. In FBE/FBI/FEE/FBE mode, the PLL could + * be enabled independently, call CLOCK_EnablePll0 explicitly in this case. + * + * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. + */ + +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v7.0 +processor: MK28FN2M0Axxx15 +package_id: MK28FN2M0AVMI15 +mcu_data: ksdk2_0 +processor_version: 0.7.1 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +#include "fsl_smc.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define MCG_PLL_DISABLE 0U /*!< MCGPLLCLK disabled */ +#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ +#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ +#define SIM_OSC32KSEL_RTC32KCLK_CLK 2U /*!< OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ +#define SIM_PLLFLLSEL_IRC48MCLK_CLK 3U /*!< PLLFLL select: IRC48MCLK clock */ +#define SIM_PLLFLLSEL_MCGPLLCLK_CLK 1U /*!< PLLFLL select: MCGPLLCLK clock */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : CLOCK_CONFIG_SetFllExtRefDiv + * Description : Configure FLL external reference divider (FRDIV). + * Param frdiv : The value to set FRDIV. + * + *END**************************************************************************/ +static void CLOCK_CONFIG_SetFllExtRefDiv(uint8_t frdiv) +{ + MCG->C1 = ((MCG->C1 & ~MCG_C1_FRDIV_MASK) | MCG_C1_FRDIV(frdiv)); +} + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockRUN(); +} + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockRUN +called_from_default_init: true +outputs: +- {id: Bus_clock.outFreq, value: 60 MHz} +- {id: Core_clock.outFreq, value: 120 MHz} +- {id: Flash_clock.outFreq, value: 24 MHz} +- {id: FlexBus_clock.outFreq, value: 60 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGFFCLK.outFreq, value: 375 kHz} +- {id: MCGIRCLK.outFreq, value: 32.768 kHz} +- {id: MCGPLLCLK.outFreq, value: 120 MHz} +- {id: MCGPLLCLK2X.outFreq, value: 240 MHz} +- {id: OSCERCLK.outFreq, value: 12 MHz} +- {id: OSCERCLK_UNDIV.outFreq, value: 12 MHz} +- {id: PLLFLLCLK.outFreq, value: 120 MHz} +- {id: System_clock.outFreq, value: 120 MHz} +settings: +- {id: MCGMode, value: PEE} +- {id: MCG.FCRDIV.scale, value: '1', locked: true} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IREFS.sel, value: MCG.FRDIV} +- {id: MCG.PLLS.sel, value: MCG.PLLCS} +- {id: MCG.PRDIV.scale, value: '1', locked: true} +- {id: MCG.VDIV.scale, value: '20', locked: true} +- {id: MCG_C1_IRCLKEN_CFG, value: Enabled} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: OSC_CR_ERCLKEN_UNDIV_CFG, value: Enabled} +- {id: RTC_CR_OSCE_CFG, value: Enabled} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV2.scale, value: '2'} +- {id: SIM.OUTDIV3.scale, value: '2'} +- {id: SIM.OUTDIV4.scale, value: '5'} +- {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} +sources: +- {id: OSC.OSC.outFreq, value: 12 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockRUN = { + .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ + .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */ + .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ + .vdiv = 0x4U, /* VCO divider: multiplied by 20 */ + }, + .pllcs = kMCG_PllClkSelPll0, /* PLL0 output clock is selected */ +}; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = { + .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ + .pllFllDiv = 0, /* PLLFLLSEL clock divider divisor: divided by 1 */ + .pllFllFrac = 0, /* PLLFLLSEL clock divider fraction: multiplied by 1 */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x1140000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /2, OUTDIV4: /5 */ +}; +const osc_config_t oscConfig_BOARD_BootClockRUN = { + .freq = 12000000U, /* Oscillator frequency: 12000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = { + .enableMode = + kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + .erclkDiv = 0, /* Divider for OSCERCLK: divided by 1 */ + }}; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockRUN); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockRUN.freq); + /* Configure the Internal Reference clock (MCGIRCLK). */ + CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockRUN.irclkEnableMode, mcgConfig_BOARD_BootClockRUN.ircs, + mcgConfig_BOARD_BootClockRUN.fcrdiv); + /* Configure FLL external reference divider (FRDIV). */ + CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockRUN.frdiv); + /* Set MCG to PEE mode. */ + CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockRUN.oscsel, mcgConfig_BOARD_BootClockRUN.pllcs, + &mcgConfig_BOARD_BootClockRUN.pll0Config); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockVLPR +outputs: +- {id: Bus_clock.outFreq, value: 4 MHz} +- {id: Core_clock.outFreq, value: 4 MHz} +- {id: Flash_clock.outFreq, value: 800 kHz} +- {id: FlexBus_clock.outFreq, value: 4 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGIRCLK.outFreq, value: 4 MHz} +- {id: System_clock.outFreq, value: 4 MHz} +settings: +- {id: MCGMode, value: BLPI} +- {id: powerMode, value: VLPR} +- {id: MCG.CLKS.sel, value: MCG.IRCS} +- {id: MCG.FCRDIV.scale, value: '1', locked: true} +- {id: MCG.IRCS.sel, value: MCG.FCRDIV} +- {id: MCG_C1_IRCLKEN_CFG, value: Enabled} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV2.scale, value: '1', locked: true} +- {id: SIM.OUTDIV3.scale, value: '1', locked: true} +- {id: SIM.OUTDIV4.scale, value: '5', locked: true} +- {id: SIM.PLLFLLSEL.sel, value: IRC48M.IRC48MCLK} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * 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 1 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ + .vdiv = 0x0U, /* VCO divider: multiplied by 16 */ + }, + .pllcs = kMCG_PllClkSelPll0, /* PLL0 output clock is selected */ +}; +const sim_clock_config_t simConfig_BOARD_BootClockVLPR = { + .pllFllSel = SIM_PLLFLLSEL_IRC48MCLK_CLK, /* PLLFLL select: IRC48MCLK clock */ + .pllFllDiv = 0, /* PLLFLLSEL clock divider divisor: divided by 1 */ + .pllFllFrac = 0, /* PLLFLLSEL clock divider fraction: multiplied by 1 */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x40000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /1, OUTDIV3: /1, OUTDIV4: /5 */ +}; +const osc_config_t oscConfig_BOARD_BootClockVLPR = { + .freq = 0U, /* Oscillator frequency: 0Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeExt, /* Use external clock */ + .oscerConfig = { + .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ + .erclkDiv = 0, /* Divider for OSCERCLK: divided by 1 */ + }}; + +/******************************************************************************* + * Code for BOARD_BootClockVLPR configuration + ******************************************************************************/ +void BOARD_BootClockVLPR(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* 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; +} + +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/* clang-format off */ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockHSRUN +outputs: +- {id: Bus_clock.outFreq, value: 75 MHz} +- {id: Core_clock.outFreq, value: 150 MHz} +- {id: Flash_clock.outFreq, value: 25 MHz} +- {id: FlexBus_clock.outFreq, value: 75 MHz} +- {id: LPO_clock.outFreq, value: 1 kHz} +- {id: MCGFFCLK.outFreq, value: 375 kHz} +- {id: MCGIRCLK.outFreq, value: 32.768 kHz} +- {id: MCGPLLCLK.outFreq, value: 150 MHz} +- {id: MCGPLLCLK2X.outFreq, value: 300 MHz} +- {id: OSCERCLK.outFreq, value: 12 MHz} +- {id: OSCERCLK_UNDIV.outFreq, value: 12 MHz} +- {id: PLLFLLCLK.outFreq, value: 150 MHz} +- {id: System_clock.outFreq, value: 150 MHz} +settings: +- {id: MCGMode, value: PEE} +- {id: powerMode, value: HSRUN} +- {id: MCG.FCRDIV.scale, value: '1', locked: true} +- {id: MCG.FRDIV.scale, value: '32'} +- {id: MCG.IREFS.sel, value: MCG.FRDIV} +- {id: MCG.PLLS.sel, value: MCG.PLLCS} +- {id: MCG.PRDIV.scale, value: '1', locked: true} +- {id: MCG.VDIV.scale, value: '25', locked: true} +- {id: MCG_C1_IRCLKEN_CFG, value: Enabled} +- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} +- {id: MCG_C2_RANGE0_CFG, value: Very_high} +- {id: MCG_C2_RANGE0_FRDIV_CFG, value: Very_high} +- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} +- {id: OSC_CR_ERCLKEN_UNDIV_CFG, value: Enabled} +- {id: SIM.OSC32KSEL.sel, value: RTC.RTC32KCLK} +- {id: SIM.OUTDIV2.scale, value: '2'} +- {id: SIM.OUTDIV3.scale, value: '2', locked: true} +- {id: SIM.OUTDIV4.scale, value: '6'} +- {id: SIM.PLLFLLSEL.sel, value: MCG.MCGPLLCLK} +sources: +- {id: OSC.OSC.outFreq, value: 12 MHz, enabled: true} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ +/* clang-format on */ + +/******************************************************************************* + * Variables for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +const mcg_config_t mcgConfig_BOARD_BootClockHSRUN = { + .mcgMode = kMCG_ModePEE, /* PEE - PLL Engaged External */ + .irclkEnableMode = kMCG_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCG_IrcSlow, /* Slow internal reference clock selected */ + .fcrdiv = 0x0U, /* Fast IRC divider: divided by 1 */ + .frdiv = 0x0U, /* FLL reference clock divider: divided by 32 */ + .drs = kMCG_DrsLow, /* Low frequency range */ + .dmx32 = kMCG_Dmx32Default, /* DCO has a default range of 25% */ + .oscsel = kMCG_OscselOsc, /* Selects System Oscillator (OSCCLK) */ + .pll0Config = + { + .enableMode = MCG_PLL_DISABLE, /* MCGPLLCLK disabled */ + .prdiv = 0x0U, /* PLL Reference divider: divided by 1 */ + .vdiv = 0x9U, /* VCO divider: multiplied by 25 */ + }, + .pllcs = kMCG_PllClkSelPll0, /* PLL0 output clock is selected */ +}; +const sim_clock_config_t simConfig_BOARD_BootClockHSRUN = { + .pllFllSel = SIM_PLLFLLSEL_MCGPLLCLK_CLK, /* PLLFLL select: MCGPLLCLK clock */ + .pllFllDiv = 0, /* PLLFLLSEL clock divider divisor: divided by 1 */ + .pllFllFrac = 0, /* PLLFLLSEL clock divider fraction: multiplied by 1 */ + .er32kSrc = SIM_OSC32KSEL_RTC32KCLK_CLK, /* OSC32KSEL select: RTC32KCLK clock (32.768kHz) */ + .clkdiv1 = 0x1150000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV2: /2, OUTDIV3: /2, OUTDIV4: /6 */ +}; +const osc_config_t oscConfig_BOARD_BootClockHSRUN = { + .freq = 12000000U, /* Oscillator frequency: 12000000Hz */ + .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ + .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ + .oscerConfig = { + .enableMode = + kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ + .erclkDiv = 0, /* Divider for OSCERCLK: divided by 1 */ + }}; + +/******************************************************************************* + * Code for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +void BOARD_BootClockHSRUN(void) +{ + /* Set HSRUN power mode */ + SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); + SMC_SetPowerModeHsrun(SMC); + while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) + { + } + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Initializes OSC0 according to board configuration. */ + CLOCK_InitOsc0(&oscConfig_BOARD_BootClockHSRUN); + CLOCK_SetXtal0Freq(oscConfig_BOARD_BootClockHSRUN.freq); + /* Configure the Internal Reference clock (MCGIRCLK). */ + CLOCK_SetInternalRefClkConfig(mcgConfig_BOARD_BootClockHSRUN.irclkEnableMode, mcgConfig_BOARD_BootClockHSRUN.ircs, + mcgConfig_BOARD_BootClockHSRUN.fcrdiv); + /* Configure FLL external reference divider (FRDIV). */ + CLOCK_CONFIG_SetFllExtRefDiv(mcgConfig_BOARD_BootClockHSRUN.frdiv); + /* Set MCG to PEE mode. */ + CLOCK_BootToPeeMode(mcgConfig_BOARD_BootClockHSRUN.oscsel, mcgConfig_BOARD_BootClockHSRUN.pllcs, + &mcgConfig_BOARD_BootClockHSRUN.pll0Config); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockHSRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK; +} diff --git a/hw/bsp/kinetis_k28/boards/frdm_k28fa15/clock_config.h b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/clock_config.h new file mode 100644 index 0000000000..f9e7087b0c --- /dev/null +++ b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/clock_config.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017,2019 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. + **********************************************************************************************************************/ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 12000000U /*!< Board xtal0 frequency in Hz */ + +/******************************************************************************* + ************************ 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*/ + +/******************************************************************************* + ********************** Configuration BOARD_BootClockRUN *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 120000000U /*!< Core clock frequency: 120000000Hz */ + +/*! @brief MCG set for BOARD_BootClockRUN configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockRUN; +/*! @brief SIM module set for BOARD_BootClockRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; +/*! @brief OSC set for BOARD_BootClockRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockRUN; + +/******************************************************************************* + * API for BOARD_BootClockRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockVLPR *********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 4000000U /*!< Core clock frequency: 4000000Hz */ + +/*! @brief MCG set for BOARD_BootClockVLPR configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockVLPR; +/*! @brief SIM module set for BOARD_BootClockVLPR configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; +/*! @brief OSC set for BOARD_BootClockVLPR configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockVLPR; + +/******************************************************************************* + * API for BOARD_BootClockVLPR configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockVLPR(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ********************* Configuration BOARD_BootClockHSRUN ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKHSRUN_CORE_CLOCK 150000000U /*!< Core clock frequency: 150000000Hz */ + +/*! @brief MCG set for BOARD_BootClockHSRUN configuration. + */ +extern const mcg_config_t mcgConfig_BOARD_BootClockHSRUN; +/*! @brief SIM module set for BOARD_BootClockHSRUN configuration. + */ +extern const sim_clock_config_t simConfig_BOARD_BootClockHSRUN; +/*! @brief OSC set for BOARD_BootClockHSRUN configuration. + */ +extern const osc_config_t oscConfig_BOARD_BootClockHSRUN; + +/******************************************************************************* + * API for BOARD_BootClockHSRUN configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockHSRUN(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k28/boards/frdm_k28fa15/frdm_k28fa15.c b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/frdm_k28fa15.c new file mode 100644 index 0000000000..cad5f724b0 --- /dev/null +++ b/hw/bsp/kinetis_k28/boards/frdm_k28fa15/frdm_k28fa15.c @@ -0,0 +1,169 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * 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 "bsp/board_api.h" +#include "board.h" +#include "fsl_gpio.h" +#include "fsl_port.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +#include "clock_config.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USBHS_IRQHandler(void) +{ + tud_int_handler(0); +} + +__attribute__((unused)) static void init_usb_phy(void) { + CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_UsbPhySrcExt, CPU_XTAL_CLK_HZ); + CLOCK_EnableUsbhs0Clock(kCLOCK_UsbSrcUnused, 0); + + USBPHY_Type* usb_phy = USBPHY; + + // Enable PHY support for Low speed device + LS via FS Hub + usb_phy->CTRL |= USBPHY_CTRL_SET_ENUTMILEVEL2_MASK | USBPHY_CTRL_SET_ENUTMILEVEL3_MASK; + + // Enable all power for normal operation + // TODO may not be needed since it is called within CLOCK_EnableUsbhs0PhyPllClock() + usb_phy->PWD = 0; + + // TX Timing + uint32_t phytx = usb_phy->TX; + phytx &= ~(USBPHY_TX_D_CAL_MASK | USBPHY_TX_TXCAL45DM_MASK | USBPHY_TX_TXCAL45DP_MASK); + phytx |= USBPHY_TX_D_CAL(0x0C) | USBPHY_TX_TXCAL45DP(0x06) | USBPHY_TX_TXCAL45DM(0x06); + usb_phy->TX = phytx; +} + +void board_init(void) +{ + /* Enable port clocks for UART/LED/Button pins */ + CLOCK_EnableClock(UART_PIN_CLOCK); + CLOCK_EnableClock(LED_PIN_CLOCK); + CLOCK_EnableClock(BUTTON_PIN_CLOCK); + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 0 }; + GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); + PORT_SetPinMux(LED_PORT, LED_PIN, kPORT_MuxAsGpio); + + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; + GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); + const port_pin_config_t BUTTON_CFG = { + .pullSelect = kPORT_PullUp, + .slewRate = kPORT_FastSlewRate, + .passiveFilterEnable = kPORT_PassiveFilterDisable, + .driveStrength = kPORT_LowDriveStrength, + .mux = kPORT_MuxAsGpio + }; + PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); + + /* PORTC24 (pin B7) is configured as LPUART0_TX */ + PORT_SetPinMux(PORTC, 24U, kPORT_MuxAlt3); + + /* PORTC25 (pin A7) is configured as LPUART0_RX */ + PORT_SetPinMux(PORTC, 25U, kPORT_MuxAlt3); + + SIM->SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK))) + + /* LPUART0 transmit data source select: LPUART0_TX pin. */ + | SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX) + + /* LPUART0 receive data source select: LPUART0_RX pin. */ + | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX)); + + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + + /* SIM_SOPT2[27:26]: + * 00: Clock Disabled + * 01: MCGFLLCLK, or MCGPLLCLK, or IRC48M + * 10: OSCERCLK + * 11: MCGIRCCLK + */ + CLOCK_SetLpuartClock(2); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, CLOCK_GetOsc0ErClkFreq()); + + init_usb_phy(); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); +} + +int board_uart_read(uint8_t* buf, int len) +{ + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; +} + +int board_uart_write(void const * buf, int len) +{ + LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/kinetis_k28/family.mk b/hw/bsp/kinetis_k28/family.mk new file mode 100644 index 0000000000..3a1c422d4f --- /dev/null +++ b/hw/bsp/kinetis_k28/family.mk @@ -0,0 +1,35 @@ +UF2_FAMILY_ID = 0x7f83e793 +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 +CPU_CORE ?= cortex-m4 + +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K28F + +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs + +SRC_C += \ + src/portable/chipidea/ci_hs/dcd_ci_hs.c \ + src/portable/chipidea/ci_hs/hcd_ci_hs.c \ + src/portable/ehci/ehci.c \ + $(MCU_DIR)/system_$(MCU).c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ + $(SDK_DIR)/drivers/lpuart/fsl_lpuart.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/project_template \ + $(TOP)/$(MCU_DIR)/drivers \ + $(TOP)/$(SDK_DIR)/drivers/smc \ + $(TOP)/$(SDK_DIR)/drivers/common \ + $(TOP)/$(SDK_DIR)/drivers/gpio \ + $(TOP)/$(SDK_DIR)/drivers/port \ + $(TOP)/$(SDK_DIR)/drivers/lpuart \ + +SRC_S += $(MCU_DIR)/gcc/startup_$(MCU).S diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 308ee713c3..e52f8a5ef8 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -107,6 +107,13 @@ #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_RHPORT_HIGHSPEED 1 +#elif TU_CHECK_MCU(OPT_MCU_KINETIS_K28F) + #define TUP_USBIP_CHIPIDEA_HS + #define TUP_USBIP_EHCI + + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 1 + #elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K) #define TUP_USBIP_CHIPIDEA_FS #define TUP_USBIP_CHIPIDEA_FS_KINETIS diff --git a/src/portable/chipidea/ci_hs/ci_hs_kinetis_k28f.h b/src/portable/chipidea/ci_hs/ci_hs_kinetis_k28f.h new file mode 100644 index 0000000000..7936833aaf --- /dev/null +++ b/src/portable/chipidea/ci_hs/ci_hs_kinetis_k28f.h @@ -0,0 +1,47 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, 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_HS_KINETIS_K28F_H_ +#define _CI_HS_KINETIS_K28F_H_ + +#include "fsl_device_registers.h" + +static const ci_hs_controller_t _ci_controller[] = { + {.reg_base = USBHS_BASE, .irqnum = USBHS_IRQn} +}; + +TU_ATTR_ALWAYS_INLINE static inline ci_hs_regs_t* CI_HS_REG(uint8_t port) { + (void) port; + return ((ci_hs_regs_t*) _ci_controller[0].reg_base); +} + +#define CI_DCD_INT_ENABLE(_p) do { (void) _p; NVIC_EnableIRQ (_ci_controller[0].irqnum); } while (0) +#define CI_DCD_INT_DISABLE(_p) do { (void) _p; NVIC_DisableIRQ(_ci_controller[0].irqnum); } while (0) + +#define CI_HCD_INT_ENABLE(_p) NVIC_EnableIRQ (_ci_controller[_p].irqnum) +#define CI_HCD_INT_DISABLE(_p) NVIC_DisableIRQ(_ci_controller[_p].irqnum) + +#endif diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index f9ec666e5a..b40fa40c9f 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -54,6 +54,8 @@ #elif TU_CHECK_MCU(OPT_MCU_MCXN9) // MCX N9 only port 1 use this controller #include "ci_hs_mcx.h" +#elif TU_CHECK_MCU(OPT_MCU_KINETIS_K28F) + #include "ci_hs_kinetis_k28f.h" #else #error "Unsupported MCUs" #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 96378cb804..caddb2b3c5 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -126,6 +126,7 @@ #define OPT_MCU_KINETIS_K32L 1201 ///< NXP K32L series #define OPT_MCU_KINETIS_K32 1201 ///< Alias to K32L #define OPT_MCU_KINETIS_K 1202 ///< NXP K series +#define OPT_MCU_KINETIS_K28F 1203 ///< NXP K28F series #define OPT_MCU_MKL25ZXX 1200 ///< Alias to KL (obsolete) #define OPT_MCU_K32L2BXX 1201 ///< Alias to K32 (obsolete)