Merge pull request #3404 from gab-k/support-nxp-rw612

Add support for NXP RW61x
This commit is contained in:
Zixun LI
2025-12-17 10:50:54 +01:00
committed by GitHub
29 changed files with 1526 additions and 237 deletions

View File

@ -22,7 +22,7 @@ family_list = {
"kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"],
"lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"],
"lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"],
"maxim mcx mm32 msp432e4 tm4c": ["arm-gcc"],
"maxim mcx mm32 msp432e4 rw61x tm4c": ["arm-gcc"],
"msp430": ["msp430-gcc"],
"nrf": ["arm-gcc", "arm-clang"],
"nuc100_120 nuc121_125 nuc126 nuc505 xmc4000": ["arm-gcc"],

View File

@ -208,7 +208,9 @@ Supported CPUs
| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs, ehci | |
| | +-------------------+--------+------+-----------+------------------------+--------------------+
| | | A15 | ✔ | | | ci_fs | |
+--------------+---------+-------------------+--------+------+-----------+------------------------+--------------------+
| +---------+-------------------+--------+------+-----------+------------------------+--------------------+
| | RW61x | ✔ | ✔ | ✔ | ci_hs, ehci | |
+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
| Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | |
+--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+
| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | |

View File

@ -15,6 +15,7 @@ mcu:MIMXRT1XXX
mcu:MSP432E4
mcu:RAXXX
mcu:RP2040
mcu:RW61X
mcu:RX65X
mcu:STM32C0
mcu:STM32F4

View File

@ -15,6 +15,7 @@ mcu:MIMXRT1XXX
mcu:MSP432E4
mcu:RAXXX
mcu:RP2040
mcu:RW61X
mcu:RX65X
mcu:STM32C0
mcu:STM32F4

View File

@ -11,6 +11,7 @@ mcu:MIMXRT10XX
mcu:MIMXRT11XX
mcu:MIMXRT1XXX
mcu:MSP432E4
mcu:RW61X
mcu:RX65X
mcu:STM32C0
mcu:STM32F4

View File

@ -16,6 +16,7 @@ mcu:MIMXRT1XXX
mcu:MSP432E4
mcu:RAXXX
mcu:RP2040
mcu:RW61X
mcu:RX65X
mcu:STM32C0
mcu:STM32F4

View File

@ -15,6 +15,7 @@ mcu:MIMXRT1XXX
mcu:MSP432E4
mcu:RAXXX
mcu:RP2040
mcu:RW61X
mcu:RX65X
mcu:STM32F4
mcu:STM32F7

View File

@ -18,6 +18,7 @@ mcu:MIMXRT1XXX
mcu:MSP432E4
mcu:RAXXX
mcu:RP2040
mcu:RW61X
mcu:RX65X
mcu:STM32C0
mcu:STM32F4

View File

@ -15,6 +15,7 @@ mcu:MIMXRT1XXX
mcu:MSP432E4
mcu:RAXXX
mcu:RP2040
mcu:RW61X
mcu:RX65X
mcu:STM32C0
mcu:STM32F4

View File

@ -234,6 +234,10 @@
"name": "frdm_mcxn947",
"inherits": "default"
},
{
"name": "frdm_rw612",
"inherits": "default"
},
{
"name": "hpm6750evk2",
"inherits": "default"
@ -1224,6 +1228,11 @@
"description": "Build preset for the frdm_mcxn947 board",
"configurePreset": "frdm_mcxn947"
},
{
"name": "frdm_rw612",
"description": "Build preset for the frdm_rw612 board",
"configurePreset": "frdm_rw612"
},
{
"name": "hpm6750evk2",
"description": "Build preset for the hpm6750evk2 board",
@ -2845,6 +2854,19 @@
}
]
},
{
"name": "frdm_rw612",
"steps": [
{
"type": "configure",
"name": "frdm_rw612"
},
{
"type": "build",
"name": "frdm_rw612"
}
]
},
{
"name": "hpm6750evk2",
"steps": [

View File

@ -0,0 +1,150 @@
/*
* 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__
#include "fsl_device_registers.h"
#endif
/* Cortex M23/M33 port configuration. */
#define configENABLE_MPU 0
#define configENABLE_FPU 0 // RW61x has FPU but is disabled due to using cortex-m33-nodsp-nofp.mk
#define configENABLE_TRUSTZONE 0
#define configRUN_FREERTOS_SECURE_ONLY 1 // Cortex-M33 runs in secure mode after reset by default!
#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 4
#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 1
#define configSUPPORT_DYNAMIC_ALLOCATION 0
/* 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
#define configCHECK_HANDLER_INSTALLATION 0
/* 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
/* 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 3
/* The lowest interrupt priority that can be used in a call to a "set priority" function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<<configPRIO_BITS) - 1)
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 2
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#endif

View File

@ -0,0 +1,30 @@
set(MCU_VARIANT RW612)
set(MCU_CORE RW612)
set(JLINK_DEVICE ${MCU_VARIANT})
set(PYOCD_TARGET rw612eta2i)
set(BOARD_DIR ${SDK_DIR}/boards/frdmrw612)
set(PORT 1)
function(update_board BOARD_TARGET)
target_compile_definitions(${BOARD_TARGET} PUBLIC
CPU_RW612ETA2I
BOARD_TUD_RHPORT=${PORT}
BOARD_TUH_RHPORT=${PORT}
BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
BOOT_HEADER_ENABLE=1
)
target_sources(${BOARD_TARGET} PUBLIC
${BOARD_DIR}/flash_config/flash_config.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/pin_mux.c
)
target_include_directories(${BOARD_TARGET} PUBLIC
${BOARD_DIR}/flash_config
)
endfunction()

View File

@ -0,0 +1,74 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021, Ha Thach (tinyusb.org)
* Copyright (c) 2025, Gabriel Koppenstein
*
* 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.
*/
/* metadata:
name: FRDM-RW612
url: https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-RW612
*/
#ifndef BOARD_H_
#define BOARD_H_
#ifdef __cplusplus
extern "C" {
#endif
// LED - Green channel of RGB LED
#define LED_GPIO BOARD_INITLEDPINS_LED_GREEN_PERIPHERAL
#define LED_CLK kCLOCK_HsGpio0
#define LED_PIN BOARD_INITLEDPINS_LED_GREEN_PIN
#define LED_PORT BOARD_INITLEDPINS_LED_GREEN_PORT
#define LED_STATE_ON 0
// WAKE button (Dummy, use unused pin
#define BUTTON_GPIO BOARD_INITPINS_WAKEUP_BTN_PERIPHERAL
#define BUTTON_CLK kCLOCK_HsGpio0
#define BUTTON_PIN BOARD_INITPINS_WAKEUP_BTN_PIN
#define BUTTON_PORT BOARD_INITPINS_WAKEUP_BTN_PORT
#define BUTTON_STATE_ACTIVE 0
// UART
#define UART_DEV USART3
#define LP_FLEXCOMM_INST 3U
#define BOARD_DEBUG_UART_FRG_CLK \
(&(const clock_frg_clk_config_t){3, kCLOCK_FrgPllDiv, 255, 0}) /*!< Select FRG3 mux as frg_pll */
#define BOARD_DEBUG_UART_CLK_ATTACH kFRG_to_FLEXCOMM3
static inline void board_uart_init_clock(void) {
/* attach FRG0 clock to FLEXCOMM3/USART3 */
CLOCK_SetFRGClock(BOARD_DEBUG_UART_FRG_CLK);
CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,20 @@
MCU_VARIANT = RW612
MCU_CORE = RW612
CPU_CORE = cortex-m33-nodsp-nofp
CFLAGS += \
-DCPU_RW612ETA2I \
-DCFG_TUSB_MCU=OPT_MCU_RW61X \
-DBOOT_HEADER_ENABLE=1 \
JLINK_DEVICE = ${MCU_VARIANT}
PYOCD_TARGET = rw612eta2i
SRC_C += \
$(SDK_DIR)/boards/frdmrw612/flash_config/flash_config.c \
INC += \
$(TOP)/$(SDK_DIR)/boards/frdmrw612/flash_config/ \
# flash using pyocd
flash: flash-jlink

View File

@ -0,0 +1,169 @@
/*
* Copyright 2024,2025 NXP
*
* 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 set up clock using clock driver functions:
*
* 1. Setup clock sources.
*
* 2. Set up all selectors to provide selected clocks.
*
* 3. Set up all dividers.
*/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Clocks v15.0
processor: RW612
package_id: RW612ETA2I
mcu_data: ksdk2_0
processor_version: 24.12.10
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
#include "fsl_power.h"
#include "fsl_clock.h"
#include "clock_config.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
************************ 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: audio_pll_clk.outFreq, value: 4246732800/345600007 MHz}
- {id: aux0_pll_clk.outFreq, value: 260 MHz}
- {id: avpll_ch1_clkout.outFreq, value: 4246732800/345600007 MHz}
- {id: avpll_ch2_clkout.outFreq, value: 1415577600/22118401 MHz}
- {id: cau_slp_clk.outFreq, value: 4 MHz}
- {id: clk_32k.outFreq, value: 32 kHz}
- {id: clk_pmu_sys.outFreq, value: 52 MHz}
- {id: els_128m_clk.outFreq, value: 128 MHz}
- {id: els_256m_clk.outFreq, value: 256 MHz}
- {id: els_64m_clk.outFreq, value: 64 MHz}
- {id: ffro_clk_div4.outFreq, value: 640/53 MHz}
- {id: hclk.outFreq, value: 260 MHz}
- {id: lposc_clk_i.outFreq, value: 1 MHz}
- {id: main_clk.outFreq, value: 260 MHz}
- {id: main_pll_clk.outFreq, value: 260 MHz}
- {id: otp_fuse_32m_clk.outFreq, value: 32 MHz}
- {id: refclk_phy.outFreq, value: 40 MHz}
- {id: sfro_clk_i.outFreq, value: 16 MHz}
- {id: systick_fclk.outFreq, value: 260 MHz}
- {id: t3pll_mci_256m.outFreq, value: 256 MHz}
- {id: t3pll_mci_48_60m_irc.outFreq, value: 2560/53 MHz}
- {id: tcpu_mci_clk.outFreq, value: 260 MHz}
- {id: tddr_mci_flexspi_clk.outFreq, value: 320 MHz}
settings:
- {id: CLKCTL0.MAINCLKSELB.sel, value: CLKCTL0.MAINPLLCLKDIV}
- {id: CLKCTL0.MAINPLLCLKDIV.scale, value: '1', locked: true}
- {id: CLKCTL0.PMUFCLKDIV.scale, value: '5', locked: true}
- {id: CLKCTL0.SYSCPUAHBCLKDIV.scale, value: '1', locked: true}
- {id: CLKCTL0.SYSTICKFCLKSEL.sel, value: CLKCTL0.SYSTICKFCLKDIV}
- {id: CLKCTL0.WDT0FCLKSEL.sel, value: NO_CLOCK}
- {id: CLKCTL1.FRGPLLCLKDIV.scale, value: '13', locked: true}
- {id: CLKCTL1.OSEVENTFCLKSEL.sel, value: NO_CLOCK}
- {id: REFCLK_SYS_Config, value: Disabled}
- {id: SYSCTL2.CH1_M.scale, value: '2621440', locked: true}
- {id: SYSCTL2.CH1_OFFSET_DIV.scale, value: '345600007', locked: true}
- {id: SYSCTL2.CH2_M.scale, value: '2621440', locked: true}
- {id: SYSCTL2.CH2_OFFSET_DIV.scale, value: '66355203', locked: true}
- {id: SYSCTL2.T3_FBDIV.scale, value: '64', locked: true}
- {id: SYSCTL2.T3_REFDIV.scale, value: '1', locked: true}
- {id: T3PLL_MCI_213P3M_Config, value: Disabled}
- {id: T3PLL_MCI_FLEXSPI_Config, value: Disabled}
- {id: TCPU_MCI_FLEXSPI_CLK_Config, value: Disabled}
- {id: TDDR_MCI_ENET_CLK_Config, value: Disabled}
sources:
- {id: CAU.XTAL_OSC.outFreq, value: 40 MHz, enabled: true}
- {id: PMU.XTAL32K.outFreq, value: 32.768 kHz}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
/*******************************************************************************
* Variables for BOARD_BootClockRUN configuration
******************************************************************************/
const clock_avpll_config_t avpllConfig_BOARD_BootClockRUN =
{
.ch1Freq = kCLOCK_AvPllChFreq12p288m, /* AVPLL channel frequency 12.288 MHz */
.ch2Freq = kCLOCK_AvPllChFreq64m, /* AVPLL channel frequency 64 MHz */
.enableCali = true, /* AVPLL calibration is enabled */
};
/*******************************************************************************
* Code for BOARD_BootClockRUN configuration
******************************************************************************/
void BOARD_BootClockRUN(void)
{
/* Disable GDET and VSensors */
POWER_DisableGDetVSensors();
/* Enable CAU sleep clock for PMU */
if ((PMU->CAU_SLP_CTRL & PMU_CAU_SLP_CTRL_SOC_SLP_RDY_MASK) == 0U)
{
/* Enable the CAU sleep clock. */
CLOCK_EnableClock(kCLOCK_RefClkCauSlp);
}
if ((SYSCTL2->SOURCE_CLK_GATE & SYSCTL2_SOURCE_CLK_GATE_REFCLK_SYS_CG_MASK) != 0U)
{
/* Enable the REFCLK_SYS clock. */
CLOCK_EnableClock(kCLOCK_RefClkSys);
}
/* Initialize T3 PLL and enable outputs that are not clock gated. */
CLOCK_InitT3RefClk(kCLOCK_T3MciIrc48m);
/* Enable FFRO - T3 PLL 48/60 MHz IRC clock output */
CLOCK_EnableClock(kCLOCK_T3PllMciIrcClk);
/* Enable T3 PLL 256 MHz clock output */
CLOCK_EnableClock(kCLOCK_T3PllMci256mClk);
/* Set core clock to safe system oscillator clock for initialization of other sources. */
CLOCK_AttachClk(kSYSOSC_to_MAIN_CLK);
CLOCK_SetClkDiv(kCLOCK_DivSysCpuAhbClk, 1);
/* Enable TCPU PLL MCI clock output */
CLOCK_EnableClock(kCLOCK_TcpuMciClk);
/* Initialize TDDR PLL and enable outputs that are not clock gated. */
CLOCK_InitTddrRefClk(kCLOCK_TddrFlexspiDiv10);
/* Enable TDDR PLL FlexSPI clock output */
CLOCK_EnableClock(kCLOCK_TddrMciFlexspiClk);
/* Initialize AVPLL and enable both channels. */
CLOCK_InitAvPll(&avpllConfig_BOARD_BootClockRUN);
/* Set up clock selectors - Attach clocks to the peripheries */
CLOCK_AttachClk(kRC32K_to_CLK32K); /* Switch CLK32K to RC32K */
/*!< Please note SYSTICK_CLK source is used only if the SysTick SYST_CSR register CLKSOURCE bit is set to 0. */
CLOCK_AttachClk(kSYSTICK_DIV_to_SYSTICK_CLK); /* Switch SYSTICK_CLK to SYSTICK_DIV */
/* Set up dividers */
CLOCK_SetClkDiv(kCLOCK_DivAudioPllClk, 1U); /* Set .AUDIOPLLCLKDIV divider to value 1 */
CLOCK_SetClkDiv(kCLOCK_DivPllFrgClk, 13U); /* Set .FRGPLLCLKDIV divider to value 13 */
CLOCK_SetClkDiv(kCLOCK_DivMainPllClk, 1U); /* Set .MAINPLLCLKDIV divider to value 1 */
CLOCK_SetClkDiv(kCLOCK_DivAux0PllClk, 1U); /* Set .AUX0PLLCLKDIV divider to value 1 */
CLOCK_SetClkDiv(kCLOCK_DivSystickClk, 1U); /* Set .SYSTICKFCLKDIV divider to value 1 */
CLOCK_SetClkDiv(kCLOCK_DivPmuFclk, 5U); /* Set .PMUFCLKDIV divider to value 5 */
/* Select the main clock source for the main system clock (MAINCLKSELA and MAINCLKSELB). */
CLOCK_AttachClk(kMAIN_PLL_to_MAIN_CLK);
/*!< Set SystemCoreClock variable. */
SystemCoreClock = BOARD_BOOTCLOCKRUN_HCLK;
}

View File

@ -0,0 +1,115 @@
/*
* Copyright 2024 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#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*/
/*******************************************************************************
********************** Configuration BOARD_BootClockRUN ***********************
******************************************************************************/
/*******************************************************************************
* Definitions for BOARD_BootClockRUN configuration
******************************************************************************/
/* Clock outputs (values are in Hz): */
#define BOARD_BOOTCLOCKRUN_AUDIO_PLL_CLK 12287999UL /* Clock consumers of audio_pll_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_AUX0_PLL_CLK 260000000UL /* Clock consumers of aux0_pll_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_AUX1_PLL_CLK 0UL /* Clock consumers of aux1_pll_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_AVPLL_CH1_CLKOUT 12287999UL /* Clock consumers of avpll_ch1_clkout output : N/A */
#define BOARD_BOOTCLOCKRUN_AVPLL_CH2_CLKOUT 63999997UL /* Clock consumers of avpll_ch2_clkout output : N/A */
#define BOARD_BOOTCLOCKRUN_CAU_SLP_CLK 4000000UL /* Clock consumers of cau_slp_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_CLK_32K 32000UL /* Clock consumers of clk_32k output : RTC */
#define BOARD_BOOTCLOCKRUN_CLK_OUT 0UL /* Clock consumers of clk_out output : N/A */
#define BOARD_BOOTCLOCKRUN_CLK_PMU_SYS 52000000UL /* Clock consumers of clk_pmu_sys output : PMU */
#define BOARD_BOOTCLOCKRUN_CTIMER0_FCLK 0UL /* Clock consumers of ctimer0_fclk output : CTIMER0 */
#define BOARD_BOOTCLOCKRUN_CTIMER1_FCLK 0UL /* Clock consumers of ctimer1_fclk output : CTIMER1 */
#define BOARD_BOOTCLOCKRUN_CTIMER2_FCLK 0UL /* Clock consumers of ctimer2_fclk output : CTIMER2 */
#define BOARD_BOOTCLOCKRUN_CTIMER3_FCLK 0UL /* Clock consumers of ctimer3_fclk output : CTIMER3 */
#define BOARD_BOOTCLOCKRUN_DMIC_FCLK 0UL /* Clock consumers of dmic_fclk output : DMIC0 */
#define BOARD_BOOTCLOCKRUN_ELS_128M_CLK 128000000UL /* Clock consumers of els_128m_clk output : ELS */
#define BOARD_BOOTCLOCKRUN_ELS_256M_CLK 256000000UL /* Clock consumers of els_256m_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_ELS_64M_CLK 64000000UL /* Clock consumers of els_64m_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_ELS_FCLK 0UL /* Clock consumers of els_fclk output : ELS */
#define BOARD_BOOTCLOCKRUN_FFRO_CLK_DIV4 12075471UL /* Clock consumers of ffro_clk_div4 output : N/A */
#define BOARD_BOOTCLOCKRUN_FLEXCOMM0_FCLK 0UL /* Clock consumers of flexcomm0_fclk output : FLEXCOMM0 */
#define BOARD_BOOTCLOCKRUN_FLEXCOMM14_FCLK 0UL /* Clock consumers of flexcomm14_fclk output : FLEXCOMM14 */
#define BOARD_BOOTCLOCKRUN_FLEXCOMM1_FCLK 0UL /* Clock consumers of flexcomm1_fclk output : FLEXCOMM1 */
#define BOARD_BOOTCLOCKRUN_FLEXCOMM2_FCLK 0UL /* Clock consumers of flexcomm2_fclk output : FLEXCOMM2 */
#define BOARD_BOOTCLOCKRUN_FLEXCOMM3_FCLK 0UL /* Clock consumers of flexcomm3_fclk output : FLEXCOMM3 */
#define BOARD_BOOTCLOCKRUN_FLEXSPI_FCLK 0UL /* Clock consumers of flexspi_fclk output : FLEXSPI */
#define BOARD_BOOTCLOCKRUN_GAU_FCLK 0UL /* Clock consumers of gau_fclk output : GAU_ACOMP, GAU_BG, GAU_DAC0, GAU_GPADC0, GAU_GPADC1 */
#define BOARD_BOOTCLOCKRUN_HCLK 260000000UL /* Clock consumers of hclk output : AHB_SECURE_CTRL, APU0, APU1, BLEAPU, BLECTRL, BUCK11, BUCK18, CACHE64_CTRL0, CACHE64_CTRL1, CACHE64_POLSEL0, CACHE64_POLSEL1, CAU, CDOG, CLKCTL0, CLKCTL1, CRC, CTIMER0, CTIMER1, CTIMER2, CTIMER3, DMA0, DMA1, DMIC0, ELS, ENET, FLEXCOMM0, FLEXCOMM1, FLEXCOMM14, FLEXCOMM2, FLEXCOMM3, FLEXSPI, FREQME, GAU_ACOMP, GAU_BG, GAU_DAC0, GAU_GPADC0, GAU_GPADC1, GDMA, GPIO, INPUTMUX, ITRC, LCDIC, MCI_IO_MUX, MRT0, MRT1, OCOTP, OSTIMER, PINT, PKC, PMU, POWERQUAD, PUF, ROMCP, RSTCTL0, RSTCTL1, RTC, SCT0, SDU_FBR_CARD, SDU_FN0_CARD, SDU_FN_CARD, SECGPIO, SENSOR_CTRL, SOCCTRL, SOC_OTP_CTRL, SYSCTL0, SYSCTL1, SYSCTL2, SysTick, TRNG, USBOTG, USIM, UTICK, WLAPU, WLCTRL, WWDT0 */
#define BOARD_BOOTCLOCKRUN_LCD_FCLK 0UL /* Clock consumers of lcd_fclk output : LCDIC */
#define BOARD_BOOTCLOCKRUN_LPOSC_CLK_I 1000000UL /* Clock consumers of lposc_clk_i output : N/A */
#define BOARD_BOOTCLOCKRUN_MAIN_CLK 260000000UL /* Clock consumers of main_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_MAIN_PLL_CLK 260000000UL /* Clock consumers of main_pll_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_MCLK_OUT 0UL /* Clock consumers of mclk_out output : N/A */
#define BOARD_BOOTCLOCKRUN_OSEVENT_FCLK 0UL /* Clock consumers of osevent_fclk output : OSTIMER */
#define BOARD_BOOTCLOCKRUN_OTP_FUSE_32M_CLK 32000000UL /* Clock consumers of otp_fuse_32m_clk output : OCOTP */
#define BOARD_BOOTCLOCKRUN_REFCLK_PHY 40000000UL /* Clock consumers of refclk_phy output : USBOTG */
#define BOARD_BOOTCLOCKRUN_REFCLK_SYS 0UL /* Clock consumers of refclk_sys output : N/A */
#define BOARD_BOOTCLOCKRUN_SCT_FCLK 0UL /* Clock consumers of sct_fclk output : SCT0 */
#define BOARD_BOOTCLOCKRUN_SFRO_CLK_I 16000000UL /* Clock consumers of sfro_clk_i output : N/A */
#define BOARD_BOOTCLOCKRUN_SYSOSC_CLK_I 0UL /* Clock consumers of sysosc_clk_i output : N/A */
#define BOARD_BOOTCLOCKRUN_SYSTICK_FCLK 260000000UL /* Clock consumers of systick_fclk output : SysTick */
#define BOARD_BOOTCLOCKRUN_T3PLL_MCI_213P3M 0UL /* Clock consumers of t3pll_mci_213p3m output : N/A */
#define BOARD_BOOTCLOCKRUN_T3PLL_MCI_256M 256000000UL /* Clock consumers of t3pll_mci_256m output : N/A */
#define BOARD_BOOTCLOCKRUN_T3PLL_MCI_48_60M_IRC 48301886UL /* Clock consumers of t3pll_mci_48_60m_irc output : N/A */
#define BOARD_BOOTCLOCKRUN_T3PLL_MCI_FLEXSPI_CLK 0UL /* Clock consumers of t3pll_mci_flexspi_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_TCPU_MCI_CLK 260000000UL /* Clock consumers of tcpu_mci_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_TCPU_MCI_FLEXSPI_CLK 0UL /* Clock consumers of tcpu_mci_flexspi_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_TDDR_MCI_ENET_CLK 0UL /* Clock consumers of tddr_mci_enet_clk output : ENET */
#define BOARD_BOOTCLOCKRUN_TDDR_MCI_FLEXSPI_CLK 320000000UL /* Clock consumers of tddr_mci_flexspi_clk output : N/A */
#define BOARD_BOOTCLOCKRUN_USIM_FCLK 0UL /* Clock consumers of usim_fclk output : USIM */
#define BOARD_BOOTCLOCKRUN_UTICK_FCLK 0UL /* Clock consumers of utick_fclk output : UTICK */
#define BOARD_BOOTCLOCKRUN_WDT0_FCLK 0UL /* Clock consumers of wdt0_fclk output : WWDT0 */
/*! @brief AVPLL set for BOARD_BootClockRUN configuration.
*/
extern const clock_avpll_config_t avpllConfig_BOARD_BootClockRUN;
/*******************************************************************************
* API for BOARD_BootClockRUN configuration
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus*/
/*!
* @brief This function executes configuration of clocks.
*
*/
void BOARD_BootClockRUN(void);
#if defined(__cplusplus)
}
#endif /* __cplusplus*/
#endif /* _CLOCK_CONFIG_H_ */

View File

@ -0,0 +1,223 @@
/***********************************************************************************************************************
* 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.
**********************************************************************************************************************/
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
!!GlobalInfo
product: Pins v17.0
processor: RW612
package_id: RW612ETA2I
mcu_data: ksdk2_0
processor_version: 25.09.10
board: FRDM-RW612
pin_labels:
- {pin_num: M2, pin_signal: GPIO_11, label: 'J1[6]/WAKEUP_BTN', identifier: WAKEUP;WAKEUP_BTN}
- {pin_num: L7, pin_signal: GPIO_5, label: 'J1[7]/MCLK', identifier: MCLKOUT}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
#include "fsl_common.h"
#include "fsl_gpio.h"
#include "fsl_io_mux.h"
#include "pin_mux.h"
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitBootPins
* Description : Calls initialization functions.
*
* END ****************************************************************************************************************/
void BOARD_InitBootPins(void)
{
BOARD_InitPins();
BOARD_InitDEBUG_UARTPins();
BOARD_InitSWD_DEBUGPins();
BOARD_InitLEDPins();
}
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitPins:
- options: {callFromInitBoot: 'true', coreID: cm33, enableClock: 'true'}
- pin_list:
- {pin_num: M2, peripheral: GPIO, signal: 'PIO0, 11', pin_signal: GPIO_11, identifier: WAKEUP_BTN, direction: INPUT}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitPins
* Description :
*
* END ****************************************************************************************************************/
/* Function assigned for the Cortex-M33 */
void BOARD_InitPins(void)
{
/* Enables the clock for the GPIO0 module */
GPIO_PortInit(GPIO, 0);
gpio_pin_config_t WAKEUP_BTN_config = {
.pinDirection = kGPIO_DigitalInput,
.outputLogic = 0U
};
/* Initialize GPIO functionality on pin PIO0_11 (pin M2) */
GPIO_PinInit(BOARD_INITPINS_WAKEUP_BTN_GPIO, BOARD_INITPINS_WAKEUP_BTN_PORT, BOARD_INITPINS_WAKEUP_BTN_PIN, &WAKEUP_BTN_config);
}
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitDEBUG_UARTPins:
- options: {callFromInitBoot: 'true', coreID: cm33, enableClock: 'true'}
- pin_list:
- {pin_num: E5, peripheral: FLEXCOMM3, signal: USART_RXD, pin_signal: GPIO_24}
- {pin_num: F6, peripheral: FLEXCOMM3, signal: USART_TXD, pin_signal: GPIO_26}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitDEBUG_UARTPins
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
/* Function assigned for the Cortex-M33 */
void BOARD_InitDEBUG_UARTPins(void)
{
/* Initialize FC3_USART_DATA functionality on pin GPIO_24, GPIO_26 (pin E5_F6) */
IO_MUX_SetPinMux(IO_MUX_FC3_USART_DATA);
}
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitSWD_DEBUGPins:
- options: {callFromInitBoot: 'true', coreID: cm33, enableClock: 'true'}
- pin_list:
- {pin_num: G5, peripheral: SWD, signal: CLK, pin_signal: GPIO_13}
- {pin_num: K4, peripheral: SWD, signal: IO, pin_signal: GPIO_14}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitSWD_DEBUGPins
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
/* Function assigned for the Cortex-M33 */
void BOARD_InitSWD_DEBUGPins(void)
{
MCI_IO_MUX->C_TIMER_IN = ((MCI_IO_MUX->C_TIMER_IN &
/* Mask bits to zero which are setting */
(~(MCI_IO_MUX_C_TIMER_IN_CT_INP3_SEL_MASK | MCI_IO_MUX_C_TIMER_IN_CT_INP4_SEL_MASK)))
/* sel GPIO-13 as ct_inp3: 0x00u */
| MCI_IO_MUX_C_TIMER_IN_CT_INP3_SEL(0x00u)
/* sel GPIO-14 as ct_inp4: 0x00u */
| MCI_IO_MUX_C_TIMER_IN_CT_INP4_SEL(0x00u));
MCI_IO_MUX->C_TIMER_OUT = ((MCI_IO_MUX->C_TIMER_OUT &
/* Mask bits to zero which are setting */
(~(MCI_IO_MUX_C_TIMER_OUT_CT0MAT3_SEL_MASK | MCI_IO_MUX_C_TIMER_OUT_CT1MAT0_SEL_MASK)))
/* sel GPIO-13 as ct0mat3: 0x00u */
| MCI_IO_MUX_C_TIMER_OUT_CT0MAT3_SEL(0x00u)
/* sel GPIO-14 as ct1mat0: 0x00u */
| MCI_IO_MUX_C_TIMER_OUT_CT1MAT0_SEL(0x00u));
MCI_IO_MUX->FC2 =
((MCI_IO_MUX->FC2 &
/* Mask bits to zero which are setting */
(~(MCI_IO_MUX_FC2_SEL_FC2_I2C_MASK | MCI_IO_MUX_FC2_SEL_FC2_I2S_MASK | MCI_IO_MUX_FC2_SEL_FC2_SPI_MASK | MCI_IO_MUX_FC2_SEL_FC2_I2S_DATA_ONLY_MASK | MCI_IO_MUX_FC2_SEL_FC2_USART_DATA_MASK)))
/* flexcomm2:select GPIO-13/14 as i2c function: 0x00u */
| MCI_IO_MUX_FC2_SEL_FC2_I2C(0x00u)
/* flexcomm2:select GPIO-13/14/15 as i2s function: 0x00u */
| MCI_IO_MUX_FC2_SEL_FC2_I2S(0x00u)
/* flexcomm2:select GPIO-13/14/15/16 as spi function: 0x00u */
| MCI_IO_MUX_FC2_SEL_FC2_SPI(0x00u)
/* flexcomm2:select GPIO-13 as i2s data function: 0x00u */
| MCI_IO_MUX_FC2_SEL_FC2_I2S_DATA_ONLY(0x00u)
/* flexcomm2:select GPIO-13/14 as usart rxd/txd: 0x00u */
| MCI_IO_MUX_FC2_SEL_FC2_USART_DATA(0x00u));
MCI_IO_MUX->GPIO_GRP0 = ((MCI_IO_MUX->GPIO_GRP0 &
/* Mask bits to zero which are setting */
(~(MCI_IO_MUX_GPIO_GRP0_SEL_13_MASK | MCI_IO_MUX_GPIO_GRP0_SEL_14_MASK)))
/* pio0[31:0] selection, high valid; sel[i]->pio0[i]->GPIO[i]: 0x00u */
| MCI_IO_MUX_GPIO_GRP0_SEL(0x00u));
SOCCTRL->MCI_IOMUX_EN0 = ((SOCCTRL->MCI_IOMUX_EN0 &
/* Mask bits to zero which are setting */
(~(SOCCIU_MCI_IOMUX_EN0_EN_21_0_13_MASK | SOCCIU_MCI_IOMUX_EN0_EN_21_0_14_MASK)))
/* Bitwise enable control for mci_io_mux GPIO[21:0]: 0x00u */
| SOCCIU_MCI_IOMUX_EN0_EN_21_0(0x00u));
}
/* clang-format off */
/*
* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
BOARD_InitLEDPins:
- options: {callFromInitBoot: 'true', coreID: cm33, enableClock: 'true'}
- pin_list:
- {pin_num: M1, peripheral: GPIO, signal: 'PIO0, 0', pin_signal: GPIO_0, direction: OUTPUT, gpio_init_state: 'true'}
- {pin_num: N2, peripheral: GPIO, signal: 'PIO0, 1', pin_signal: GPIO_1, direction: OUTPUT, gpio_init_state: 'true'}
- {pin_num: N8, peripheral: GPIO, signal: 'PIO0, 12', pin_signal: GPIO_12, direction: OUTPUT, gpio_init_state: 'true'}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
/* FUNCTION ************************************************************************************************************
*
* Function Name : BOARD_InitLEDPins
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
/* Function assigned for the Cortex-M33 */
void BOARD_InitLEDPins(void)
{
/* Enables the clock for the GPIO0 module */
CLOCK_EnableClock(kCLOCK_HsGpio0);
gpio_pin_config_t LED_BLUE_config = {
.pinDirection = kGPIO_DigitalOutput,
.outputLogic = 1U
};
/* Initialize GPIO functionality on pin PIO0_0 (pin M1) */
GPIO_PinInit(BOARD_INITLEDPINS_LED_BLUE_GPIO, BOARD_INITLEDPINS_LED_BLUE_PORT, BOARD_INITLEDPINS_LED_BLUE_PIN, &LED_BLUE_config);
gpio_pin_config_t LED_RED_config = {
.pinDirection = kGPIO_DigitalOutput,
.outputLogic = 1U
};
/* Initialize GPIO functionality on pin PIO0_1 (pin N2) */
GPIO_PinInit(BOARD_INITLEDPINS_LED_RED_GPIO, BOARD_INITLEDPINS_LED_RED_PORT, BOARD_INITLEDPINS_LED_RED_PIN, &LED_RED_config);
gpio_pin_config_t LED_GREEN_config = {
.pinDirection = kGPIO_DigitalOutput,
.outputLogic = 1U
};
/* Initialize GPIO functionality on pin PIO0_12 (pin N8) */
GPIO_PinInit(BOARD_INITLEDPINS_LED_GREEN_GPIO, BOARD_INITLEDPINS_LED_GREEN_PORT, BOARD_INITLEDPINS_LED_GREEN_PIN, &LED_GREEN_config);
/* Initialize GPIO0 functionality on pin GPIO_0 (pin M1) */
IO_MUX_SetPinMux(IO_MUX_GPIO0);
/* Initialize GPIO1 functionality on pin GPIO_1 (pin N2) */
IO_MUX_SetPinMux(IO_MUX_GPIO1);
/* Initialize GPIO12 functionality on pin GPIO_12 (pin N8) */
IO_MUX_SetPinMux(IO_MUX_GPIO12);
}
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/

View File

@ -0,0 +1,146 @@
/***********************************************************************************************************************
* 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 _PIN_MUX_H_
#define _PIN_MUX_H_
/*!
* @addtogroup pin_mux
* @{
*/
/***********************************************************************************************************************
* API
**********************************************************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Calls initialization functions.
*
*/
void BOARD_InitBootPins(void);
/*!
* @brief mclk direction control: MCLK is in the output direction. */
#define MCLKPINDIR_MCLKPINDIR_OUTPUT_DIRECTION 0x01u
/*! @name GPIO_5 (coord L7), J1[7]/MCLK
@{ */
/* Routed pin properties */
#define BOARD_INITPINS_MCLKOUT_PERIPHERAL CLKCTL1 /*!<@brief Peripheral name */
#define BOARD_INITPINS_MCLKOUT_SIGNAL MCLK /*!<@brief Signal name */
#define BOARD_INITPINS_MCLKOUT_GPIO_PIN 5U /*!<@brief GPIO pin number */
#define BOARD_INITPINS_MCLKOUT_PORT 0U /*!<@brief PORT number */
#define BOARD_INITPINS_MCLKOUT_PIN 5U /*!<@brief PORT pin number */
#define BOARD_INITPINS_MCLKOUT_PIN_MASK (1U << 5U) /*!<@brief PORT pin mask */
/* @} */
/*! @name GPIO_11 (coord M2), J1[6]/WAKEUP_BTN
@{ */
/* Routed pin properties */
#define BOARD_INITPINS_WAKEUP_BTN_PERIPHERAL GPIO /*!<@brief Peripheral name */
#define BOARD_INITPINS_WAKEUP_BTN_SIGNAL PIO0 /*!<@brief Signal name */
#define BOARD_INITPINS_WAKEUP_BTN_CHANNEL 11 /*!<@brief Signal channel */
#define BOARD_INITPINS_WAKEUP_BTN_GPIO GPIO /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITPINS_WAKEUP_BTN_GPIO_PIN 11U /*!<@brief GPIO pin number */
#define BOARD_INITPINS_WAKEUP_BTN_PORT 0U /*!<@brief PORT number */
#define BOARD_INITPINS_WAKEUP_BTN_PIN 11U /*!<@brief PORT pin number */
#define BOARD_INITPINS_WAKEUP_BTN_PIN_MASK (1U << 11U) /*!<@brief PORT pin mask */
/* @} */
/*!
* @brief
*
*/
void BOARD_InitPins(void); /* Function assigned for the Cortex-M33 */
/*!
* @brief Configures pin routing and optionally pin electrical features.
*
*/
void BOARD_InitDEBUG_UARTPins(void); /* Function assigned for the Cortex-M33 */
/*!
* @brief pio0[31:0] selection, high valid; sel[i]->pio0[i]->GPIO[i] Mask for item 13. */
#define MCI_IO_MUX_GPIO_GRP0_SEL_13_MASK 0x2000u
/*!
* @brief pio0[31:0] selection, high valid; sel[i]->pio0[i]->GPIO[i] Mask for item 14. */
#define MCI_IO_MUX_GPIO_GRP0_SEL_14_MASK 0x4000u
/*!
* @brief Bitwise enable control for mci_io_mux GPIO[21:0] Mask for item 13. */
#define SOCCIU_MCI_IOMUX_EN0_EN_21_0_13_MASK 0x2000u
/*!
* @brief Bitwise enable control for mci_io_mux GPIO[21:0] Mask for item 14. */
#define SOCCIU_MCI_IOMUX_EN0_EN_21_0_14_MASK 0x4000u
/*!
* @brief Configures pin routing and optionally pin electrical features.
*
*/
void BOARD_InitSWD_DEBUGPins(void); /* Function assigned for the Cortex-M33 */
/*! @name GPIO_0 (coord M1), J1[14]/LED_BLUE
@{ */
/* Routed pin properties */
#define BOARD_INITLEDPINS_LED_BLUE_PERIPHERAL GPIO /*!<@brief Peripheral name */
#define BOARD_INITLEDPINS_LED_BLUE_SIGNAL PIO0 /*!<@brief Signal name */
#define BOARD_INITLEDPINS_LED_BLUE_CHANNEL 0 /*!<@brief Signal channel */
#define BOARD_INITLEDPINS_LED_BLUE_GPIO GPIO /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITLEDPINS_LED_BLUE_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */
#define BOARD_INITLEDPINS_LED_BLUE_GPIO_PIN 0U /*!<@brief GPIO pin number */
#define BOARD_INITLEDPINS_LED_BLUE_PORT 0U /*!<@brief PORT number */
#define BOARD_INITLEDPINS_LED_BLUE_PIN 0U /*!<@brief PORT pin number */
#define BOARD_INITLEDPINS_LED_BLUE_PIN_MASK (1U << 0U) /*!<@brief PORT pin mask */
/* @} */
/*! @name GPIO_1 (coord N2), J5[1]/LED_RED
@{ */
/* Routed pin properties */
#define BOARD_INITLEDPINS_LED_RED_PERIPHERAL GPIO /*!<@brief Peripheral name */
#define BOARD_INITLEDPINS_LED_RED_SIGNAL PIO0 /*!<@brief Signal name */
#define BOARD_INITLEDPINS_LED_RED_CHANNEL 1 /*!<@brief Signal channel */
#define BOARD_INITLEDPINS_LED_RED_GPIO GPIO /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITLEDPINS_LED_RED_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */
#define BOARD_INITLEDPINS_LED_RED_GPIO_PIN 1U /*!<@brief GPIO pin number */
#define BOARD_INITLEDPINS_LED_RED_PORT 0U /*!<@brief PORT number */
#define BOARD_INITLEDPINS_LED_RED_PIN 1U /*!<@brief PORT pin number */
#define BOARD_INITLEDPINS_LED_RED_PIN_MASK (1U << 1U) /*!<@brief PORT pin mask */
/* @} */
/*! @name GPIO_12 (coord N8), LED_GREEN
@{ */
/* Routed pin properties */
#define BOARD_INITLEDPINS_LED_GREEN_PERIPHERAL GPIO /*!<@brief Peripheral name */
#define BOARD_INITLEDPINS_LED_GREEN_SIGNAL PIO0 /*!<@brief Signal name */
#define BOARD_INITLEDPINS_LED_GREEN_CHANNEL 12 /*!<@brief Signal channel */
#define BOARD_INITLEDPINS_LED_GREEN_GPIO GPIO /*!<@brief GPIO peripheral base pointer */
#define BOARD_INITLEDPINS_LED_GREEN_INIT_GPIO_VALUE 1U /*!<@brief GPIO output initial state */
#define BOARD_INITLEDPINS_LED_GREEN_GPIO_PIN 12U /*!<@brief GPIO pin number */
#define BOARD_INITLEDPINS_LED_GREEN_PORT 0U /*!<@brief PORT number */
#define BOARD_INITLEDPINS_LED_GREEN_PIN 12U /*!<@brief PORT pin number */
#define BOARD_INITLEDPINS_LED_GREEN_PIN_MASK (1U << 12U) /*!<@brief PORT pin mask */
/* @} */
/*!
* @brief Configures pin routing and optionally pin electrical features.
*
*/
void BOARD_InitLEDPins(void); /* Function assigned for the Cortex-M33 */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* _PIN_MUX_H_ */
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/

135
hw/bsp/rw61x/family.c Normal file
View File

@ -0,0 +1,135 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018, hathach (tinyusb.org)
* Copyright (c) 2025, Gabriel Koppenstein
*
* 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.
*/
/* metadata:
manufacturer: NXP
*/
#include "bsp/board_api.h"
#include "fsl_device_registers.h"
#include "fsl_gpio.h"
#include "board.h"
#include "fsl_usart.h"
#include "fsl_clock.h"
#include "pin_mux.h"
#include "clock_config.h"
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void USB_IRQHandler(void) {
tusb_int_handler(1, true);
}
void board_init(void) {
// Init button pin, LED pins, SWD pins & UART pins
BOARD_InitBootPins();
// Init Clocks
BOARD_InitBootClocks();
#if CFG_TUSB_OS == OPT_OS_NONE
// 1ms tick timer
SysTick_Config(SystemCoreClock / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
// Explicitly disable systick to prevent its ISR from running before scheduler start
SysTick->CTRL &= ~1U;
// If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif
#ifdef NEOPIXEL_PIN
// No neo pixel support yet
#endif
#ifdef UART_DEV
// Enable UART when debug log is on
board_uart_init_clock();
usart_config_t uart_config;
USART_GetDefaultConfig(&uart_config);
uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE;
uart_config.enableRx = true;
uart_config.enableTx = true;
USART_Init(UART_DEV, &uart_config, CLOCK_GetFlexCommClkFreq(LP_FLEXCOMM_INST));
#endif
// USB Initialization
// Reset USB
RESET_PeripheralReset(kUSB_RST_SHIFT_RSTn);
// Enable USB Clock
CLOCK_EnableClock(kCLOCK_Usb);
// Enable USB PHY
CLOCK_EnableUsbhsPhyClock();
}
//--------------------------------------------------------------------+
// Board porting API
//--------------------------------------------------------------------+
void board_led_write(bool state) {
GPIO_PinWrite(LED_GPIO, LED_PORT, LED_PIN, state ? LED_STATE_ON : (1 - LED_STATE_ON));
}
uint32_t board_button_read(void) {
#ifdef BUTTON_GPIO
return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BOARD_INITPINS_WAKEUP_BTN_PORT, BUTTON_PIN);
#endif
}
int board_uart_read(uint8_t* buf, int len) {
(void) buf;
(void) len;
return 0;
}
int board_uart_write(void const* buf, int len) {
#ifdef UART_DEV
USART_WriteBlocking(UART_DEV, (uint8_t const*) buf, len);
return len;
#else
(void) buf; (void) len;
return 0;
#endif
}
#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

109
hw/bsp/rw61x/family.cmake Normal file
View File

@ -0,0 +1,109 @@
include_guard()
set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk)
set(CMSIS_5 ${TOP}/lib/CMSIS_5)
# include board specific
include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
# toolchain set up
set(CMAKE_SYSTEM_CPU cortex-m33-nodsp-nofp CACHE INTERNAL "System Processor")
set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake)
set(FAMILY_MCUS RW61X CACHE INTERNAL "")
#------------------------------------
# Startup & Linker script
#------------------------------------
set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_CORE}.S)
set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/${MCU_CORE}_flash.ld)
#------------------------------------
# BOARD_TARGET
#------------------------------------
function(family_add_board BOARD_TARGET)
add_library(${BOARD_TARGET} STATIC
${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
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_power.c
${SDK_DIR}/drivers/lpc_gpio/fsl_gpio.c
${SDK_DIR}/drivers/common/fsl_common_arm.c
${SDK_DIR}/drivers/flexcomm/fsl_flexcomm.c
${SDK_DIR}/drivers/flexcomm/usart/fsl_usart.c
${SDK_DIR}/drivers/flexspi/fsl_flexspi.c
)
target_include_directories(${BOARD_TARGET} PUBLIC
${CMSIS_5}/CMSIS/Core/Include
${SDK_DIR}/devices/${MCU_VARIANT}
${SDK_DIR}/devices/${MCU_VARIANT}/drivers
${SDK_DIR}/drivers
${SDK_DIR}/drivers/common
${SDK_DIR}/drivers/lpc_gpio
${SDK_DIR}/drivers/flexcomm
${SDK_DIR}/drivers/flexcomm/usart
${SDK_DIR}/drivers/flexspi
)
update_board(${BOARD_TARGET})
endfunction()
#------------------------------------
# Functions
#------------------------------------
function(family_configure_example TARGET RTOS)
family_configure_common(${TARGET} ${RTOS})
family_add_tinyusb(${TARGET} OPT_MCU_RW61X)
target_sources(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
# ChipIdea HS
${TOP}/src/portable/chipidea/ci_hs/dcd_ci_hs.c
${TOP}/src/portable/chipidea/ci_hs/hcd_ci_hs.c
${TOP}/src/portable/ehci/ehci.c
# Startup File
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
# Add Board specific includes
target_include_directories(${TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
)
# Linker Options
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_link_options(${TARGET} PUBLIC
"LINKER:--script=${LD_FILE_GNU}"
--specs=nosys.specs --specs=nano.specs
)
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_link_options(${TARGET} PUBLIC
"LINKER:--script=${LD_FILE_Clang}"
)
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
target_link_options(${TARGET} PUBLIC
"LINKER:--config=${LD_FILE_IAR}"
)
endif ()
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes")
endif ()
# Handle Startup File Properties (Linting/Warnings)
set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES
SKIP_LINTING ON
COMPILE_OPTIONS -w
)
# Flashing & Binary Generation
family_add_bin_hex(${TARGET})
family_flash_jlink(${TARGET})
endfunction()

52
hw/bsp/rw61x/family.mk Normal file
View File

@ -0,0 +1,52 @@
UF2_FAMILY_ID = 0x2abc77ec
SDK_DIR = hw/mcu/nxp/mcux-sdk
include $(TOP)/$(BOARD_PATH)/board.mk
# Default to Highspeed PORT1
PORT ?= 1
CFLAGS += \
-flto \
-DBOARD_TUD_RHPORT=$(PORT) \
-DBOARD_TUH_RHPORT=$(PORT) \
-DSERIAL_PORT_TYPE_UART=1 \
-DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED \
-DBOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED \
# mcu driver cause following warnings
CFLAGS += -Wno-error=unused-parameter -Wno-error=old-style-declaration -Wno-error=redundant-decls
LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs
# All source paths should be relative to the top level.
LD_FILE ?= $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/$(MCU_CORE)_flash.ld
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 \
$(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 \
$(SDK_DIR)/devices/$(MCU_VARIANT)/drivers/fsl_power.c \
$(SDK_DIR)/drivers/lpc_gpio/fsl_gpio.c \
$(SDK_DIR)/drivers/common/fsl_common_arm.c\
$(SDK_DIR)/drivers/flexcomm/fsl_flexcomm.c \
$(SDK_DIR)/drivers/flexcomm/usart/fsl_usart.c \
$(SDK_DIR)/drivers/flexspi/fsl_flexspi.c \
INC += \
$(TOP)/$(BOARD_PATH) \
$(TOP)/lib/CMSIS_5/CMSIS/Core/Include \
$(TOP)/$(SDK_DIR)/devices/$(MCU_VARIANT) \
$(TOP)/$(SDK_DIR)/devices/$(MCU_VARIANT)/drivers \
$(TOP)/$(SDK_DIR)/drivers/ \
$(TOP)/$(SDK_DIR)/drivers/common\
$(TOP)/$(SDK_DIR)/drivers/lpc_gpio\
$(TOP)/$(SDK_DIR)/drivers/flexcomm \
$(TOP)/$(SDK_DIR)/drivers/flexcomm/usart \
$(TOP)/$(SDK_DIR)/drivers/flexspi \
SRC_S += $(SDK_DIR)/devices/$(MCU_VARIANT)/gcc/startup_$(MCU_CORE).S

View File

@ -49,6 +49,7 @@ SRC_C += \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart_ex.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_i2c.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_dma.c
INC += \

View File

@ -111,6 +111,14 @@
#define TUP_DCD_ENDPOINT_MAX 16
#elif TU_CHECK_MCU(OPT_MCU_RW61X)
// USB0 is chipidea HS
#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_MIMXRT1XXX)
#include "fsl_device_registers.h"

View File

@ -0,0 +1,48 @@
/*
* 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_RW61X_H_
#define _CI_HS_RW61X_H_
#include "fsl_device_registers.h"
static const ci_hs_controller_t _ci_controller[] = {
{.reg_base = USBOTG_BASE, .irqnum = USB_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

View File

@ -34,19 +34,19 @@
#if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX
#include "ci_hs_imxrt.h"
#if CFG_TUD_MEM_DCACHE_ENABLE
bool dcd_dcache_clean(void const* addr, uint32_t data_size) {
return imxrt_dcache_clean(addr, data_size);
}
#if CFG_TUD_MEM_DCACHE_ENABLE
bool dcd_dcache_clean(const void *addr, uint32_t data_size) {
return imxrt_dcache_clean(addr, data_size);
}
bool dcd_dcache_invalidate(void const* addr, uint32_t data_size) {
return imxrt_dcache_invalidate(addr, data_size);
}
bool dcd_dcache_invalidate(const void *addr, uint32_t data_size) {
return imxrt_dcache_invalidate(addr, data_size);
}
bool dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
return imxrt_dcache_clean_invalidate(addr, data_size);
}
#endif
bool dcd_dcache_clean_invalidate(const void *addr, uint32_t data_size) {
return imxrt_dcache_clean_invalidate(addr, data_size);
}
#endif
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)
#include "ci_hs_lpc18_43.h"
@ -56,9 +56,11 @@ bool dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
#include "ci_hs_mcx.h"
#elif TU_CHECK_MCU(OPT_MCU_HPM)
#include "ci_hs_hpm.h"
#elif TU_CHECK_MCU(OPT_MCU_RW61X)
#include "ci_hs_rw61x.h"
#else
#error "Unsupported MCUs"
#endif
@ -80,7 +82,7 @@ enum {
};
#define ENDPTCTRL_TYPE(_type) ((_type) << ENDPTCTRL_TYPE_POS)
#define ENDPTCTRL_RESET_MASK (ENDPTCTRL_TYPE(TUSB_XFER_BULK) | (ENDPTCTRL_TYPE(TUSB_XFER_BULK) << 16u))
#define ENDPTCTRL_RESET_MASK (ENDPTCTRL_TYPE(TUSB_XFER_BULK) | (ENDPTCTRL_TYPE(TUSB_XFER_BULK) << 16u))
// USBSTS, USBINTR
enum {
@ -94,26 +96,28 @@ enum {
};
// Queue Transfer Descriptor
typedef struct
{
typedef struct {
// Word 0: Next QTD Pointer
uint32_t next; ///< Next link pointer This field contains the physical memory address of the next dTD to be processed
// Word 1: qTQ Token
uint32_t : 3 ;
volatile uint32_t xact_err : 1 ;
uint32_t : 1 ;
volatile uint32_t buffer_err : 1 ;
volatile uint32_t halted : 1 ;
volatile uint32_t active : 1 ;
uint32_t : 2 ;
uint32_t iso_mult_override : 2 ; ///< This field can be used for transmit ISOs to override the MULT field in the dQH. This field must be zero for all packet types that are not transmit-ISO.
uint32_t : 3 ;
uint32_t int_on_complete : 1 ;
volatile uint32_t total_bytes : 15 ;
uint32_t : 1 ;
uint32_t : 3;
volatile uint32_t xact_err : 1;
uint32_t : 1;
volatile uint32_t buffer_err : 1;
volatile uint32_t halted : 1;
volatile uint32_t active : 1;
uint32_t : 2;
uint32_t iso_mult_override : 2; ///< This field can be used for transmit ISOs to override the MULT field in the dQH.
///< This field must be zero for all packet types that are not transmit-ISO.
uint32_t : 3;
uint32_t int_on_complete : 1;
volatile uint32_t total_bytes : 15;
uint32_t : 1;
// Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the start of a 4K page
// Word 2-6: Buffer Page Pointer List, Each element in the list is a 4K page aligned, physical memory address. The
// lower 12 bits in each pointer are reserved (except for the first one) as each memory pointer must reference the
// start of a 4K page
uint32_t buffer[5]; ///< buffer1 has frame_n for TODO Isochronous
//--------------------------------------------------------------------+
@ -121,21 +125,28 @@ typedef struct
// Therefore there are 4 bytes padding that we can use.
//--------------------------------------------------------------------+
uint16_t expected_bytes;
uint8_t reserved[2];
uint8_t reserved[2];
} dcd_qtd_t;
TU_VERIFY_STATIC( sizeof(dcd_qtd_t) == 32, "size is not correct");
TU_VERIFY_STATIC(sizeof(dcd_qtd_t) == 32, "size is not correct");
// Queue Head
typedef struct
{
typedef struct {
// Word 0: Capabilities and Characteristics
uint32_t : 15 ; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated by the USB variable length protocol where N is computed using Max_packet_length and the Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 - Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark: Isochronous endpoints must set MULT = 01, 10, or 11 as needed.
uint32_t int_on_setup : 1 ; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is set in response to a setup being received.
uint32_t max_packet_size : 11 ; ///< Endpoint's wMaxPacketSize
uint32_t : 2 ;
uint32_t zero_length_termination : 1 ; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on transfers that are equal in length to a multiple Max_packet_length.
uint32_t iso_mult : 2 ; ///<
uint32_t : 15; ///< Number of packets executed per transaction descriptor 00 - Execute N transactions as demonstrated
///< by the USB variable length protocol where N is computed using Max_packet_length and the
///< Total_bytes field in the dTD. 01 - Execute one transaction 10 - Execute two transactions 11 -
///< Execute three transactions Remark: Non-isochronous endpoints must set MULT = 00. Remark:
///< Isochronous endpoints must set MULT = 01, 10, or 11 as needed.
uint32_t int_on_setup : 1; ///< Interrupt on setup This bit is used on control type endpoints to indicate if USBINT is
///< set in response to a setup being received.
uint32_t max_packet_size : 11; ///< Endpoint's wMaxPacketSize
uint32_t : 2;
uint32_t zero_length_termination : 1; ///< This bit is used for non-isochronous endpoints to indicate when a zero-length packet is received to
///< terminate transfers in case the total transfer length is “multiple”. 0 - Enable zero-length packet to
///< terminate transfers equal to a multiple of Max_packet_length (default). 1 - Disable zero-length packet on
///< transfers that are equal in length to a multiple Max_packet_length.
uint32_t iso_mult : 2; ///<
// Word 1: Current qTD Pointer
volatile uint32_t qtd_addr;
@ -150,11 +161,11 @@ typedef struct
// QHD is 64 bytes aligned but occupies only 48 bytes
// Therefore there are 16 bytes padding that we can use.
//--------------------------------------------------------------------+
tu_fifo_t * ff;
uint8_t reserved[12];
tu_fifo_t *ff;
uint8_t reserved[12];
} dcd_qhd_t;
TU_VERIFY_STATIC( sizeof(dcd_qhd_t) == 64, "size is not correct");
TU_VERIFY_STATIC(sizeof(dcd_qhd_t) == 64, "size is not correct");
//--------------------------------------------------------------------+
// Variables
@ -168,10 +179,9 @@ typedef struct {
// for portability, TinyUSB only queue 1 TD for each Qhd
dcd_qhd_t qhd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(64);
dcd_qtd_t qtd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32);
}dcd_data_t;
} dcd_data_t;
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(2048)
static dcd_data_t _dcd_data;
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(2048) static dcd_data_t _dcd_data;
//--------------------------------------------------------------------+
// Prototypes and Helper Functions
@ -186,16 +196,15 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t ci_ep_count(const ci_hs_regs_t *dcd_
//--------------------------------------------------------------------+
/// follows LPC43xx User Manual 23.10.3
static void bus_reset(uint8_t rhport)
{
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
static void bus_reset(uint8_t rhport) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
// The reset value for all endpoint types is the control endpoint. If one endpoint
// direction is enabled and the paired endpoint of opposite direction is disabled, then the
// endpoint type of the unused direction must be changed from the control type to any other
// type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior
// for the data PID tracking on the active endpoint.
uint8_t const ep_count = ci_ep_count(dcd_reg);
const uint8_t ep_count = ci_ep_count(dcd_reg);
for (uint8_t i = 1; i < ep_count; i++) {
dcd_reg->ENDPTCTRL[i] = ENDPTCTRL_RESET_MASK;
}
@ -218,7 +227,7 @@ static void bus_reset(uint8_t rhport)
//------------- Set up Control Endpoints (0 OUT, 1 IN) -------------//
_dcd_data.qhd[0][0].zero_length_termination = _dcd_data.qhd[0][1].zero_length_termination = 1;
_dcd_data.qhd[0][0].max_packet_size = _dcd_data.qhd[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE;
_dcd_data.qhd[0][0].max_packet_size = _dcd_data.qhd[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE;
_dcd_data.qhd[0][0].qtd_overlay.next = _dcd_data.qhd[0][1].qtd_overlay.next = QTD_NEXT_INVALID;
_dcd_data.qhd[0][0].int_on_setup = 1; // OUT only
@ -226,100 +235,93 @@ static void bus_reset(uint8_t rhport)
dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
}
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
(void) rh_init;
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
(void)rh_init;
tu_memclr(&_dcd_data, sizeof(dcd_data_t));
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
TU_ASSERT(ci_ep_count(dcd_reg) <= TUP_DCD_ENDPOINT_MAX);
#if TU_CHECK_MCU(OPT_MCU_HPM)
#if TU_CHECK_MCU(OPT_MCU_HPM)
usb_phy_init((USB_Type *)dcd_reg, false);
#endif
#endif
// Reset controller
dcd_reg->USBCMD |= USBCMD_RESET;
while( dcd_reg->USBCMD & USBCMD_RESET ) {}
while (dcd_reg->USBCMD & USBCMD_RESET) {}
// Set mode to device, must be set immediately after reset
uint32_t usbmode = dcd_reg->USBMODE & ~USBMOD_CM_MASK;
usbmode |= USBMODE_CM_DEVICE;
dcd_reg->USBMODE = usbmode;
#ifdef CFG_TUD_CI_HS_VBUS_CHARGE
#ifdef CFG_TUD_CI_HS_VBUS_CHARGE
dcd_reg->OTGSC = OTGSC_VBUS_CHARGE | OTGSC_OTG_TERMINATION;
#else
#else
dcd_reg->OTGSC = OTGSC_VBUS_DISCHARGE | OTGSC_OTG_TERMINATION;
#endif
#endif
#if !TUD_OPT_HIGH_SPEED
#if !TUD_OPT_HIGH_SPEED
dcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
#endif
#endif
#if TU_CHECK_MCU(OPT_MCU_HPM)
#if TU_CHECK_MCU(OPT_MCU_HPM)
dcd_reg->PORTSC1 &= ~USB_PORTSC1_STS_MASK;
#endif
#endif
dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment
dcd_reg->USBSTS = dcd_reg->USBSTS;
dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_SUSPEND;
dcd_reg->ENDPTLISTADDR = (uint32_t)_dcd_data.qhd; // Endpoint List Address has to be 2K alignment
dcd_reg->USBSTS = dcd_reg->USBSTS;
dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_SUSPEND;
uint32_t usbcmd = dcd_reg->USBCMD;
usbcmd &= ~USBCMD_INTR_THRESHOLD_MASK; // Interrupt Threshold Interval = 0
usbcmd |= USBCMD_RUN_STOP; // run
usbcmd |= USBCMD_RUN_STOP; // run
dcd_reg->USBCMD = usbcmd;
return true;
}
void dcd_int_enable(uint8_t rhport)
{
void dcd_int_enable(uint8_t rhport) {
CI_DCD_INT_ENABLE(rhport);
}
void dcd_int_disable(uint8_t rhport)
{
void dcd_int_disable(uint8_t rhport) {
CI_DCD_INT_DISABLE(rhport);
}
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
{
void dcd_set_address(uint8_t rhport, uint8_t dev_addr) {
// Response with status first before changing device address
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0, false);
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
dcd_reg->DEVICEADDR = (dev_addr << 25) | TU_BIT(24);
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
dcd_reg->DEVICEADDR = (dev_addr << 25) | TU_BIT(24);
}
void dcd_remote_wakeup(uint8_t rhport)
{
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
void dcd_remote_wakeup(uint8_t rhport) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
dcd_reg->PORTSC1 |= PORTSC1_FORCE_PORT_RESUME;
}
void dcd_connect(uint8_t rhport)
{
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
void dcd_connect(uint8_t rhport) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
dcd_reg->USBCMD |= USBCMD_RUN_STOP;
}
void dcd_disconnect(uint8_t rhport)
{
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
void dcd_disconnect(uint8_t rhport) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
dcd_reg->USBCMD &= ~USBCMD_RUN_STOP;
}
void dcd_sof_enable(uint8_t rhport, bool en)
{
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
void dcd_sof_enable(uint8_t rhport, bool en) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
if (en) {
dcd_reg->USBINTR |= INTR_SOF;
dcd_reg->USBINTR |= INTR_SOF;
} else {
dcd_reg->USBINTR &= ~INTR_SOF;
dcd_reg->USBINTR &= ~INTR_SOF;
}
}
@ -386,26 +388,24 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_clear(volatile uint32_t *epctrl
ep_ctrl_mask(epctrl, dir, ~mask, 0);
}
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
const uint8_t epnum = tu_edpt_number(ep_addr);
const uint8_t dir = tu_edpt_dir(ep_addr);
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_STALL << (dir ? 16 : 0);
// flush to abort any primed buffer
dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0));
}
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
const uint8_t epnum = tu_edpt_number(ep_addr);
const uint8_t dir = tu_edpt_dir(ep_addr);
// data toggle also need to be reset
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 );
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << (dir ? 16 : 0);
dcd_reg->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << (dir ? 16 : 0));
}
@ -483,7 +483,7 @@ void dcd_edpt_close_all(uint8_t rhport) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
// Disable all non-control endpoints
uint8_t const ep_count = ci_ep_count(dcd_reg);
const uint8_t ep_count = ci_ep_count(dcd_reg);
for (uint8_t epnum = 1; epnum < ep_count; epnum++) {
_dcd_data.qhd[epnum][TUSB_DIR_OUT].qtd_overlay.halted = 1;
_dcd_data.qhd[epnum][TUSB_DIR_IN].qtd_overlay.halted = 1;
@ -493,37 +493,34 @@ void dcd_edpt_close_all(uint8_t rhport) {
}
}
static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir)
{
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir];
dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir];
static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir];
dcd_qtd_t *p_qtd = &_dcd_data.qtd[epnum][dir];
p_qhd->qtd_overlay.halted = false; // clear any previous error
p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd
p_qhd->qtd_overlay.halted = false; // clear any previous error
p_qhd->qtd_overlay.next = (uint32_t)p_qtd; // link qtd to qhd
// flush cache
dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
if ( epnum == 0 )
{
if (epnum == 0) {
// follows UM 24.10.8.1.1 Setup packet handling using setup lockout mechanism
// wait until ENDPTSETUPSTAT before priming data/status in response TODO add time out
while(dcd_reg->ENDPTSETUPSTAT & TU_BIT(0)) {}
while (dcd_reg->ENDPTSETUPSTAT & TU_BIT(0)) {}
}
// start transfer
dcd_reg->ENDPTPRIME = TU_BIT(epnum + (dir ? 16 : 0));
}
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes, bool is_isr)
{
(void) is_isr;
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes, bool is_isr) {
(void)is_isr;
const uint8_t epnum = tu_edpt_number(ep_addr);
const uint8_t dir = tu_edpt_dir(ep_addr);
dcd_qhd_t* p_qhd = &_dcd_data.qhd[epnum][dir];
dcd_qtd_t* p_qtd = &_dcd_data.qtd[epnum][dir];
dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir];
dcd_qtd_t *p_qtd = &_dcd_data.qtd[epnum][dir];
// Prepare qtd
qtd_init(p_qtd, buffer, total_bytes);
@ -535,58 +532,47 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t
return true;
}
#if !CFG_TUD_MEM_DCACHE_ENABLE
#if !CFG_TUD_MEM_DCACHE_ENABLE
// fifo has to be aligned to 4k boundary
// It's incompatible with dcache enabled transfer, since neither address nor size is aligned to cache line
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes, bool is_isr)
{
(void) is_isr;
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes, bool is_isr) {
(void)is_isr;
const uint8_t epnum = tu_edpt_number(ep_addr);
const uint8_t dir = tu_edpt_dir(ep_addr);
dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir];
dcd_qtd_t * p_qtd = &_dcd_data.qtd[epnum][dir];
dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir];
dcd_qtd_t *p_qtd = &_dcd_data.qtd[epnum][dir];
tu_fifo_buffer_info_t fifo_info;
if (dir)
{
if (dir) {
tu_fifo_get_read_info(ff, &fifo_info);
} else
{
} else {
tu_fifo_get_write_info(ff, &fifo_info);
}
if ( fifo_info.linear.len >= total_bytes )
{
if (fifo_info.linear.len >= total_bytes) {
// Linear length is enough for this transfer
qtd_init(p_qtd, fifo_info.linear.ptr, total_bytes);
}
else
{
} else {
// linear part is not enough
// prepare TD up to linear length
qtd_init(p_qtd, fifo_info.linear.ptr, fifo_info.linear.len);
if ( !tu_offset4k((uint32_t) fifo_info.wrapped.ptr) && !tu_offset4k(tu_fifo_depth(ff)) )
{
if (!tu_offset4k((uint32_t)fifo_info.wrapped.ptr) && !tu_offset4k(tu_fifo_depth(ff))) {
// If buffer is aligned to 4K & buffer size is multiple of 4K
// We can make use of buffer page array to also combine the linear + wrapped length
p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes;
for(uint8_t i = 1, page = 0; i < 5; i++)
{
for (uint8_t i = 1, page = 0; i < 5; i++) {
// pick up buffer array where linear ends
if (p_qtd->buffer[i] == 0)
{
p_qtd->buffer[i] = (uint32_t) fifo_info.wrapped.ptr + 4096 * page;
if (p_qtd->buffer[i] == 0) {
p_qtd->buffer[i] = (uint32_t)fifo_info.wrapped.ptr + 4096 * page;
page++;
}
}
}
else
{
} else {
// TODO we may need to carry the wrapped length after the linear part complete
// for now only transfer up to linear part
}
@ -598,36 +584,32 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
return true;
}
#endif
#endif
//--------------------------------------------------------------------+
// ISR
//--------------------------------------------------------------------+
static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir)
{
dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir];
dcd_qtd_t * p_qtd = &_dcd_data.qtd[epnum][dir];
static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir) {
dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir];
dcd_qtd_t *p_qtd = &_dcd_data.qtd[epnum][dir];
uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED :
( p_qtd->xact_err || p_qtd->buffer_err ) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS;
uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED
: (p_qtd->xact_err || p_qtd->buffer_err) ? XFER_RESULT_FAILED
: XFER_RESULT_SUCCESS;
if ( result != XFER_RESULT_SUCCESS )
{
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
if (result != XFER_RESULT_SUCCESS) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
// flush to abort error buffer
dcd_reg->ENDPTFLUSH = TU_BIT(epnum + (dir ? 16 : 0));
}
uint16_t const xferred_bytes = p_qtd->expected_bytes - p_qtd->total_bytes;
const uint16_t xferred_bytes = p_qtd->expected_bytes - p_qtd->total_bytes;
if (p_qhd->ff)
{
if (dir == TUSB_DIR_IN)
{
if (p_qhd->ff) {
if (dir == TUSB_DIR_IN) {
tu_fifo_advance_read_pointer(p_qhd->ff, xferred_bytes);
} else
{
} else {
tu_fifo_advance_write_pointer(p_qhd->ff, xferred_bytes);
}
}
@ -636,82 +618,74 @@ static void process_edpt_complete_isr(uint8_t rhport, uint8_t epnum, uint8_t dir
dcd_event_xfer_complete(rhport, tu_edpt_addr(epnum, dir), xferred_bytes, result, true);
}
void dcd_int_handler(uint8_t rhport)
{
ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport);
void dcd_int_handler(uint8_t rhport) {
ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport);
uint32_t const int_enable = dcd_reg->USBINTR;
uint32_t const int_status = dcd_reg->USBSTS & int_enable;
dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt
const uint32_t int_enable = dcd_reg->USBINTR;
const uint32_t int_status = dcd_reg->USBSTS & int_enable;
dcd_reg->USBSTS = int_status; // Acknowledge handled interrupt
// disabled interrupt sources
if (int_status == 0) return;
if (int_status == 0) {
return;
}
// Set if the port controller enters the full or high-speed operational state.
// either from Bus Reset or Suspended state
if (int_status & INTR_PORT_CHANGE)
{
// TU_LOG2("PortChange %08lx\r\n", dcd_reg->PORTSC1);
if (int_status & INTR_PORT_CHANGE) {
// TU_LOG2("PortChange %08lx\r\n", dcd_reg->PORTSC1);
// Reset interrupt is not enabled, we manually check if Port Change is due
// to connection / disconnection
if ( dcd_reg->USBSTS & INTR_RESET )
{
dcd_reg->USBSTS = INTR_RESET;
// Reset interrupt is not enabled, we manually check if Port Change is due
// to connection / disconnection
if (dcd_reg->USBSTS & INTR_RESET) {
dcd_reg->USBSTS = INTR_RESET;
if (dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS)
{
uint32_t const speed = (dcd_reg->PORTSC1 & PORTSC1_PORT_SPEED) >> PORTSC1_PORT_SPEED_POS;
bus_reset(rhport);
dcd_event_bus_reset(rhport, (tusb_speed_t) speed, true);
}else
{
dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true);
}
}
else
{
// Triggered by resuming from suspended state
if ( !(dcd_reg->PORTSC1 & PORTSC1_SUSPEND) )
{
dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
}
}
}
if (dcd_reg->PORTSC1 & PORTSC1_CURRENT_CONNECT_STATUS) {
const uint32_t speed = (dcd_reg->PORTSC1 & PORTSC1_PORT_SPEED) >> PORTSC1_PORT_SPEED_POS;
bus_reset(rhport);
dcd_event_bus_reset(rhport, (tusb_speed_t)speed, true);
} else {
dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true);
}
} else {
// Triggered by resuming from suspended state
if (!(dcd_reg->PORTSC1 & PORTSC1_SUSPEND)) {
dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
}
}
}
if (int_status & INTR_SUSPEND)
{
if (int_status & INTR_SUSPEND) {
// TU_LOG2("Suspend %08lx\r\n", dcd_reg->PORTSC1);
if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND)
{
if (dcd_reg->PORTSC1 & PORTSC1_SUSPEND) {
// Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration.
// Skip suspend event if we are not addressed
if ((dcd_reg->DEVICEADDR >> 25) & 0x0f)
{
if ((dcd_reg->DEVICEADDR >> 25) & 0x0f) {
dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
}
}
}
if (int_status & INTR_USB)
{
if (int_status & INTR_USB) {
// Make sure we read the latest version of _dcd_data.
dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t));
uint32_t const edpt_complete = dcd_reg->ENDPTCOMPLETE;
dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge
const uint32_t edpt_complete = dcd_reg->ENDPTCOMPLETE;
dcd_reg->ENDPTCOMPLETE = edpt_complete; // acknowledge
// 23.10.12.3 Failed QTD also get ENDPTCOMPLETE set
// nothing to do, we will submit xfer as error to usbd
// if (int_status & INTR_ERROR) { }
if ( edpt_complete )
{
for(uint8_t epnum = 0; epnum < TUP_DCD_ENDPOINT_MAX; epnum++)
{
if ( tu_bit_test(edpt_complete, epnum) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_OUT);
if ( tu_bit_test(edpt_complete, epnum+16) ) process_edpt_complete_isr(rhport, epnum, TUSB_DIR_IN);
if (edpt_complete) {
for (uint8_t epnum = 0; epnum < TUP_DCD_ENDPOINT_MAX; epnum++) {
if (tu_bit_test(edpt_complete, epnum)) {
process_edpt_complete_isr(rhport, epnum, TUSB_DIR_OUT);
}
if (tu_bit_test(edpt_complete, epnum + 16)) {
process_edpt_complete_isr(rhport, epnum, TUSB_DIR_IN);
}
}
}
@ -721,12 +695,11 @@ void dcd_int_handler(uint8_t rhport)
// in the same frame and we should handle previous status first.
if (dcd_reg->ENDPTSETUPSTAT) {
dcd_reg->ENDPTSETUPSTAT = dcd_reg->ENDPTSETUPSTAT;
dcd_event_setup_received(rhport, (uint8_t *) (uintptr_t) &_dcd_data.qhd[0][0].setup_request, true);
dcd_event_setup_received(rhport, (uint8_t *)(uintptr_t)&_dcd_data.qhd[0][0].setup_request, true);
}
}
if (int_status & INTR_SOF)
{
if (int_status & INTR_SOF) {
const uint32_t frame = dcd_reg->FRINDEX;
dcd_event_sof(rhport, frame, true);
}

View File

@ -41,32 +41,36 @@
#if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX
#include "ci_hs_imxrt.h"
#include "ci_hs_imxrt.h"
#if CFG_TUH_MEM_DCACHE_ENABLE
bool hcd_dcache_clean(void const* addr, uint32_t data_size) {
#if CFG_TUH_MEM_DCACHE_ENABLE
bool hcd_dcache_clean(const void *addr, uint32_t data_size) {
return imxrt_dcache_clean(addr, data_size);
}
bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
bool hcd_dcache_invalidate(const void *addr, uint32_t data_size) {
return imxrt_dcache_invalidate(addr, data_size);
}
bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
bool hcd_dcache_clean_invalidate(const void *addr, uint32_t data_size) {
return imxrt_dcache_clean_invalidate(addr, data_size);
}
#endif
#endif
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)
#include "ci_hs_lpc18_43.h"
#include "ci_hs_lpc18_43.h"
#elif TU_CHECK_MCU(OPT_MCU_HPM)
#include "ci_hs_hpm.h"
#include "ci_hs_hpm.h"
#elif TU_CHECK_MCU(OPT_MCU_RW61X)
#include "ci_hs_rw61x.h"
#else
#error "Unsupported MCUs"
#error "Unsupported MCUs"
#endif
//--------------------------------------------------------------------+
@ -77,31 +81,31 @@ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
// Controller API
//--------------------------------------------------------------------+
bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
(void) rh_init;
bool hcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
(void)rh_init;
ci_hs_regs_t *hcd_reg = CI_HS_REG(rhport);
#if CFG_TUSB_MCU == OPT_MCU_HPM
#if CFG_TUSB_MCU == OPT_MCU_HPM
usb_phy_init((USB_Type *)hcd_reg, true);
#endif
#endif
// Reset controller
hcd_reg->USBCMD |= USBCMD_RESET;
while ( hcd_reg->USBCMD & USBCMD_RESET ) {}
while (hcd_reg->USBCMD & USBCMD_RESET) {}
// Set mode to device, must be set immediately after reset
#if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX
#if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX
// LPC18XX/43XX need to set VBUS Power Select to HIGH
// RHPORT1 is fullspeed only (need external PHY for Highspeed)
hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT;
if (rhport == 1) {
hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
}
#else
#else
hcd_reg->USBMODE = USBMODE_CM_HOST;
#endif
#endif
return ehci_init(rhport, (uint32_t) &hcd_reg->CAPLENGTH, (uint32_t) &hcd_reg->USBCMD);
return ehci_init(rhport, (uint32_t)&hcd_reg->CAPLENGTH, (uint32_t)&hcd_reg->USBCMD);
}
void hcd_int_enable(uint8_t rhport) {

View File

@ -40,7 +40,7 @@
#include "ehci.h"
// NXP specific fixes
#if TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX, OPT_MCU_LPC55, OPT_MCU_MCXN9)
#if TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX, OPT_MCU_LPC55, OPT_MCU_MCXN9, OPT_MCU_RW61X)
#include "fsl_device_registers.h"
#endif

View File

@ -199,6 +199,7 @@
// NXP LPC MCX
#define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series
#define OPT_MCU_MCXA15 2301 ///< NXP MCX A15 Series
#define OPT_MCU_RW61X 2302 ///< NXP RW61x Series
// Analog Devices
#define OPT_MCU_MAX32690 2400 ///< ADI MAX32690

View File

@ -60,7 +60,7 @@ deps_optional = {
'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43'],
'hw/mcu/nxp/mcux-sdk': ['https://github.com/nxp-mcuxpresso/mcux-sdk',
'a1bdae309a14ec95a4f64a96d3315a4f89c397c6',
'kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt'],
'kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx rw61x imxrt'],
'hw/mcu/raspberry_pi/Pico-PIO-USB': ['https://github.com/sekigon-gonnoc/Pico-PIO-USB.git',
'675543bcc9baa8170f868ab7ba316d418dbcf41f',
'rp2040'],
@ -249,7 +249,7 @@ deps_optional = {
'hpmicro'],
'lib/CMSIS_5': ['https://github.com/ARM-software/CMSIS_5.git',
'2b7495b8535bdcb306dac29b9ded4cfb679d7e5c',
'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x '
'imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx rw61x mm32 msp432e4 nrf saml2x '
'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 '
'stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 '
'stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba '