The RW612 TinyUSB implementation is missing USB PHY initialization, causing Windows 10 to not detect the device at all when plugged in.
Root Cause: hw/bsp/rw612/family.c only enables the USB controller clock but does not initialize the USB PHY registers needed for USB communication.
The RW612 USB PHY requires NXP-specific initialization. Download the reference code:
- Go to: https://mcuxpresso.nxp.com/
- Search for: "RW612 SDK"
- Download: SDK for RW612
- Find example:
boards/frdmrw612/usb_examples/usb_device_cdc_vcom - Locate: USB PHY init code in
board.corusb_device_config.c
Look for code that:
- Initializes USB clocks
- Configures USB PHY registers
- Enables USB VBUS detection
- Sets up USB D+/D- pins
From the NXP SDK example, you should find something similar to:
// Example pattern from NXP SDK (adapt to actual RW612 API)
void USB_DeviceClockInit(void)
{
// Enable USB clock from reference clock
CLOCK_AttachClk(kXTAL_to_USB_CLK); // Attach 40MHz XTAL to USB
CLOCK_SetClkDiv(kCLOCK_DivUsbClk, 1U); // USB clock divider
// Enable USB controller clock
CLOCK_EnableClock(kCLOCK_Usb);
// Reset USB controller
RESET_PeripheralReset(kUSB_RST_SHIFT_RSTn);
}
void USB_DevicePhyInit(void)
{
// These register names are EXAMPLES - check actual RW612 definitions
// RW612 may use USBPHY or USB_ANALOG peripheral
// Power on USB PHY
USB_ANALOG->PWD &= ~USB_ANALOG_PWD_RXPWDRX_MASK;
USB_ANALOG->PWD &= ~USB_ANALOG_PWD_TXPWDFS_MASK;
// Enable USB PHY
USB_ANALOG->CTRL &= ~USB_ANALOG_CTRL_SFTRST_MASK;
USB_ANALOG->CTRL &= ~USB_ANALOG_CTRL_CLKGATE_MASK;
// Configure USB transceiver
// ... additional PHY configuration ...
}Key APIs to look for:
USB_DeviceClockInit()USB_DevicePhyInit()BOARD_USB0_Init()or similar- Register accesses to
USBPHYorUSB_ANALOG
Add USB clock initialization function:
// Add after board_uart_init_clock() function (around line 55)
// USB PHY clock initialization
static inline void board_usb_phy_init_clock(void) {
// TODO: Add USB clock configuration from NXP SDK
// Example (adapt to actual RW612 API):
// CLOCK_AttachClk(kXTAL_to_USB_CLK);
// CLOCK_SetClkDiv(kCLOCK_DivUsbClk, 1U);
}Replace the USB initialization in board_init():
Current code (lines 86-91):
// USB Controller Initialization for RW612
// USB clock is configured by BOARD_BootClockRUN()
// Just enable the clock gate and reset the peripheral
CLOCK_EnableClock(kCLOCK_Usb);
RESET_PeripheralReset(kUSB_RST_SHIFT_RSTn);Replace with:
// USB Controller and PHY Initialization for RW612
board_usb_phy_init_clock(); // Initialize USB clocks
CLOCK_EnableClock(kCLOCK_Usb);
RESET_PeripheralReset(kUSB_RST_SHIFT_RSTn);
// TODO: Add USB PHY initialization from NXP SDK
// Example (adapt to actual RW612 registers):
// USB_ANALOG->PWD = 0; // Power on USB PHY
// USB_ANALOG->CTRL |= USB_ANALOG_CTRL_ENAUTOCLR_MASK; // Enable auto-clear
// Additional PHY configuration as per NXP SDK...If NXP SDK provides a ready-to-use USB init function:
-
Copy NXP SDK USB initialization files to
hw/bsp/rw612/ -
Add to
family.cmakeorfamily.mk:target_sources(${BOARD_TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/usb_device_dci.c # NXP USB driver ${CMAKE_CURRENT_LIST_DIR}/usb_phy_init.c # USB PHY init )
-
Call NXP init function in
family.c:#include "usb_device_config.h" // From NXP SDK void board_init(void) { // ... existing init ... // USB initialization from NXP SDK USB_DeviceClockInit(); USB_DevicePhyInit(); }
If you can't access NXP SDK, here's a minimal template based on common NXP USB PHY patterns:
Add to hw/bsp/rw612/family.c:
#include "fsl_device_registers.h"
// USB PHY initialization (adapt register names for RW612)
static void init_usb_phy_rw612(void) {
// Note: These are EXAMPLE register names - verify against RW612 reference manual!
// Option 1: If RW612 has USB_ANALOG peripheral (like iMXRT)
#ifdef USB_ANALOG
// Power on USB PHY
USB_ANALOG->PWD = 0; // Clear all power-down bits
// Enable USB PHY
USB_ANALOG->CTRL |= (1 << 30); // ENAUTOCLR_PHY_PWD
USB_ANALOG->CTRL &= ~((1 << 31) | (1 << 30)); // Clear SFTRST and CLKGATE
#endif
// Option 2: If RW612 has USBPHY peripheral (like some Kinetis)
#ifdef USBPHY
// Power on USB PHY
USBPHY->PWD = 0;
// Enable LS/FS support
USBPHY->CTRL_SET = USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK;
#endif
// Option 3: If USB PHY is integrated and needs minimal setup
// May only need clock enable (already done above)
}
void board_init(void) {
BOARD_InitPins();
BOARD_BootClockRUN();
#if CFG_TUSB_OS == OPT_OS_NONE
SysTick_Config(SystemCoreClock / 1000);
#elif CFG_TUSB_OS == OPT_OS_FREERTOS
NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif
// LED
CLOCK_EnableClock(LED_CLK);
gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0};
GPIO_PinInit(LED_GPIO, 0, LED_PIN, &led_config);
board_led_write(0);
// Button
#ifdef BUTTON_GPIO
CLOCK_EnableClock(BUTTON_CLK);
gpio_pin_config_t const button_config = {kGPIO_DigitalInput, 0};
GPIO_PinInit(BUTTON_GPIO, 0, BUTTON_PIN, &button_config);
#endif
#ifdef UART_DEV
board_uart_init_clock();
usart_config_t uart_config;
USART_GetDefaultConfig(&uart_config);
uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE;
uart_config.enableTx = true;
uart_config.enableRx = true;
USART_Init(UART_DEV, &uart_config, CLOCK_GetFlexCommClkFreq(UART_FLEXCOMM_INST));
#endif
// USB Controller and PHY Initialization
CLOCK_EnableClock(kCLOCK_Usb);
RESET_PeripheralReset(kUSB_RST_SHIFT_RSTn);
// Initialize USB PHY
init_usb_phy_rw612();
}RW612 likely has internal USB D+/D- routing, but verify:
- Check RW612 schematic for USB pins
- If USB pins are exposed on package, add to
pin_mux.c:
void BOARD_InitPins(void) {
// ... existing pins ...
// USB pins (if external)
// IO_MUX_SetPinMux(IO_MUX_USB_DP); // USB D+
// IO_MUX_SetPinMux(IO_MUX_USB_DM); // USB D-
}Most likely, USB is internal and doesn't need pin mux.
cd examples/device/net_lwip_webserver
make BOARD=frdm_rw612 clean
make BOARD=frdm_rw612 -j8make BOARD=frdm_rw612 flash-jlink- Plug USB cable into Windows 10 PC
- Check Device Manager → "Ports & Devices"
- Should see:
- Best case: "USB Ethernet/RNDIS Gadget" under Network Adapters
- Progress: "Unknown USB Device" (descriptor issue, but PHY works!)
- Fail: Nothing appears (USB PHY still not working)
# Monitor debug output
picocom /dev/ttyACM0 -b 115200Look for:
USB NCM network interface initialized
If device still not detected:
- USB D+ should have 1.5kΩ pull-up to 3.3V (Full-Speed device)
- D+ voltage: Should be ~3.3V when connected
- D- voltage: Should be ~0V when connected
- On reset: Host drives both D+/D- low for 10ms
Add debug output in family.c:
void board_init(void) {
// ... USB init ...
// Debug: Check USB controller registers
printf("USB USBCMD: 0x%08lX\n", USBOTG->USBCMD);
printf("USB PORTSC1: 0x%08lX\n", USBOTG->PORTSC1);
printf("USB USBSTS: 0x%08lX\n", USBOTG->USBSTS);
}Expected values:
PORTSC1should show PHY enabled and connectedUSBSTSshould show USB reset after connecting
USB_ANALOG->PWD = 0; // Power on everything
// or selectively:
USB_ANALOG->PWD &= ~(USB_ANALOG_PWD_RXPWDRX_MASK |
USB_ANALOG_PWD_RXPWDFS_MASK |
USB_ANALOG_PWD_TXPWDFS_MASK |
USB_ANALOG_PWD_TXPWDV2I_MASK);// Enable auto-clear of PWD bits
USB_ANALOG->CTRL |= USB_ANALOG_CTRL_ENAUTOCLR_MASK;
// Take PHY out of reset
USB_ANALOG->CTRL &= ~USB_ANALOG_CTRL_SFTRST_MASK;
// Enable PHY clock
USB_ANALOG->CTRL &= ~USB_ANALOG_CTRL_CLKGATE_MASK;// D+/D- calibration (typical values)
USB_ANALOG->TX = (USB_ANALOG->TX & ~USB_ANALOG_TX_D_CAL_MASK) |
USB_ANALOG_TX_D_CAL(0x0C);- Download from: https://mcuxpresso.nxp.com/
- Board: FRDM-RW612
- Examples to check:
usb_examples/usb_device_cdc_vcomusb_examples/usb_device_hid_mousedemo_apps/hello_world(may have USB init)
boards/frdmrw612/usb_examples/*/board.cboards/frdmrw612/usb_examples/*/usb_device_config.cmiddleware/usb/device/usb_device_dci.cdevices/RW612/drivers/fsl_clock.h(for clock APIs)
USB_DeviceClockInitUSB_DevicePhyInitUSBPHY->orUSB_ANALOG->kCLOCK_UsborkUSB_
✅ Windows 10 should:
- Detect "USB Ethernet/RNDIS Gadget" automatically
- Auto-install WINNCM driver (for NCM)
- Show network adapter in Device Manager
✅ You should be able to:
ping 192.168.7.1
curl http://192.168.7.1- Download NXP RW612 SDK
- Find USB PHY init code in SDK examples
- Add
board_usb_phy_init_clock()toboard.h - Add USB PHY initialization to
family.c board_init() - Build and test
- Verify USB enumeration on Windows 10
- Test network connectivity (ping/curl)
Need Help?
- RW612 Reference Manual: Check USB PHY chapter for register details
- NXP Community: https://community.nxp.com/
- TinyUSB Discord: https://discord.gg/tinyusb
Analysis Document: See RW612_USB_PHY_ISSUE_ANALYSIS.md for detailed root cause analysis.
Last Updated: 2025-11-16 Issue: RW612 USB not detected on Windows 10 Status: Fix implementation required (USB PHY init missing)