Skip to content

Add IP3516 HCD support #3530

Merged
hathach merged 13 commits into
masterfrom
hcd_ip3516
Mar 10, 2026
Merged

Add IP3516 HCD support #3530
hathach merged 13 commits into
masterfrom
hcd_ip3516

Conversation

@HiFiPhile
Copy link
Copy Markdown
Collaborator

@HiFiPhile HiFiPhile commented Mar 6, 2026

I did it some time ago and nearly forgot... it's somehow EHCI like.

mcux-sdk-lpc still missing some drivers nxp-mcuxpresso/mcux-devices-lpc#1

Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Signed-off-by: HiFiPhile <admin@hifiphile.com>
Copilot AI review requested due to automatic review settings March 6, 2026 14:34
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new NXP IP3516 USB Host Controller Driver (HCD) (EHCI-like) and updates NXP BSP integration to use newer, split-out MCUX repositories (core + device packs), along with some example updates to support host-mode memory placement constraints.

Changes:

  • Add a new IP3516 HCD implementation under src/portable/nxp/lpc_ip3516/.
  • Update dependency fetching (tools/get_deps.py) and multiple NXP BSP make/cmake files to use mcuxsdk-core + mcux-devices-* repos and CMSIS_6.
  • Adjust LPC5x/MCX BSP init/build settings and update host examples + README to reflect LPC54/LPC55 host support.

Reviewed changes

Copilot reviewed 43 out of 47 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tools/get_deps.py Adds NXP split MCUX repos and adjusts CMSIS dependency mapping.
src/portable/ohci/ohci.c Minor safety/constant-type tweak and a null assert.
src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h Introduces IP3516 PTD structures/constants.
src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c Implements the IP3516 host controller driver.
src/common/tusb_mcu.h Enables IP3516 USB IP defines for LPC54/LPC55.
hw/bsp/mcx/* Switches MCX BSPs to mcuxsdk-core + mcux-devices-mcx, CMSIS_6, and adds MCU_FAMILY plumbing.
hw/bsp/lpc55/* Switches LPC55 BSP to mcuxsdk-core + mcux-devices-lpc, adds host-path selection for IP3516.
hw/bsp/lpc54/* Adds IAR startup/linker files and updates port/speed selection and host IP selection.
hw/bsp/lpc51/* Switches LPC51 BSP to mcuxsdk-core + mcux-devices-lpc and updates board variable naming.
examples/host/* Updates supported MCU lists and places some buffers/objects into CFG_TUH_MEM_SECTION.
README.rst Updates NXP LPC54/LPC55 support matrix to include IP3516 host.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread hw/bsp/lpc55/family.mk Outdated
Comment thread examples/host/msc_file_explorer/src/msc_app.c Dismissed
@HiFiPhile HiFiPhile force-pushed the hcd_ip3516 branch 4 times, most recently from 8368fc0 to d23ffe7 Compare March 6, 2026 15:53
Signed-off-by: HiFiPhile <admin@hifiphile.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 6, 2026

TinyUSB Average Code Size Metrics

File .text .rodata .data .bss size %
cdc_host.c 6615 487 15 1498 8325 5.1%
ehci.c 2763 0 0 6043 7597 4.7%
ncm_device.c 1514 28 1408 5830 7358 4.5%
usbh.c 4649 55 99 961 5731 3.5%
hcd_dwc2.c 4994 33 1 513 5540 3.4%
midi_host.c 1351 7 7 3635 4989 3.1%
video_device.c 4394 5 1852 478 4865 3.0%
audio_device.c 2848 0 1248 1678 4522 2.8%
dcd_dwc2.c 4176 25 0 265 4465 2.7%
ohci.c 1940 0 0 2414 4353 2.7%
dcd_ch32_usbfs.c 1473 0 0 2444 3917 2.4%
ecm_rndis_device.c 1037 0 1 2858 3896 2.4%
hcd_stm32_fsdev.c 3287 0 1 420 3708 2.3%
usbd.c 3215 57 89 275 3554 2.2%
dcd_khci.c 1953 0 0 1290 3243 2.0%
hcd_musb.c 3073 0 0 157 3230 2.0%
dcd_ci_fs.c 1925 0 0 1290 3215 2.0%
dcd_da146xx.c 3067 0 0 144 3211 2.0%
dcd_nrf5x.c 2918 0 0 292 3210 2.0%
hcd_rusb2.c 2923 0 0 245 3168 1.9%
dcd_rusb2.c 2919 0 0 156 3075 1.9%
msc_device.c 2517 108 2286 546 3063 1.9%
hcd_ch32_usbfs.c 2484 0 0 498 2982 1.8%
hcd_khci.c 2442 0 0 449 2891 1.8%
dcd_stm32_fsdev.c 2557 0 0 291 2848 1.7%
dcd_mm32f327x_otg.c 1478 0 0 1290 2768 1.7%
dcd_musb.c 2445 0 0 160 2605 1.6%
hcd_samd.c 2220 0 0 324 2544 1.6%
dcd_ci_hs.c 1759 0 0 1344 2538 1.6%
dcd_eptri.c 2271 0 0 259 2530 1.5%
usbtmc_device.c 2176 24 69 294 2502 1.5%
hid_host.c 1206 0 0 1251 2457 1.5%
mtp_device.c 1689 22 1449 587 2283 1.4%
dcd_rp2040.c 858 20 604 655 2137 1.3%
dcd_ch32_usbhs.c 1649 0 0 448 2097 1.3%
msc_host.c 1587 0 0 394 1982 1.2%
dcd_msp430x5xx.c 1798 0 0 176 1974 1.2%
cdc_device.c 1306 16 19 630 1935 1.2%
hcd_rp2040.c 976 73 416 384 1849 1.1%
dcd_lpc17_40.c 1474 0 0 648 1798 1.1%
midi_device.c 1129 0 995 578 1705 1.0%
dcd_nuc505.c 0 0 1531 157 1688 1.0%
dcd_lpc_ip3511.c 1463 0 0 264 1683 1.0%
hub.c 1384 8 8 30 1418 0.9%
dcd_samg.c 1320 0 0 72 1392 0.9%
printer_device.c 813 0 694 519 1330 0.8%
dcd_samd.c 1034 0 0 266 1300 0.8%
dcd_nuc121.c 1168 0 0 101 1269 0.8%
hid_device.c 1118 44 997 119 1236 0.8%
dcd_nuc120.c 1094 0 0 78 1172 0.7%
vendor_device.c 624 0 530 453 1076 0.7%
rp2040_usb.c 172 75 717 4 968 0.6%
dfu_device.c 744 28 712 176 920 0.6%
tusb_fifo.c 850 0 480 0 844 0.5%
typec_stm32.c 820 8 2 12 842 0.5%
dwc2_common.c 602 30 0 0 618 0.4%
usbc.c 420 2 20 166 608 0.4%
usbd_control.c 523 0 474 79 601 0.4%
hcd_pio_usb.c 262 0 240 0 502 0.3%
tusb.c 452 0 384 3 453 0.3%
hcd_ci_hs.c 184 0 0 0 184 0.1%
fsdev_common.c 180 0 0 0 180 0.1%
rusb2_common.c 160 0 16 0 176 0.1%
dfu_rt_device.c 156 0 134 0 156 0.1%
TOTAL 114598 1155 17498 46591 163276 100.0%
Input files
  • cmake-build/cmake-build-adafruit_clue/metrics.json
  • cmake-build/cmake-build-apard32690/metrics.json
  • cmake-build/cmake-build-at32f403a_weact_blackpill/metrics.json
  • cmake-build/cmake-build-at_start_f402/metrics.json
  • cmake-build/cmake-build-at_start_f413/metrics.json
  • cmake-build/cmake-build-at_start_f415/metrics.json
  • cmake-build/cmake-build-at_start_f423/metrics.json
  • cmake-build/cmake-build-at_start_f425/metrics.json
  • cmake-build/cmake-build-at_start_f435/metrics.json
  • cmake-build/cmake-build-at_start_f455/metrics.json
  • cmake-build/cmake-build-b_g474e_dpow1/metrics.json
  • cmake-build/cmake-build-b_u585i_iot2a/metrics.json
  • cmake-build/cmake-build-ch32v103r_r1_1v0/metrics.json
  • cmake-build/cmake-build-ch32v203c_r0_1v0/metrics.json
  • cmake-build/cmake-build-ch32v307v_r1_1v0/metrics.json
  • cmake-build/cmake-build-cynthion_d11/metrics.json
  • cmake-build/cmake-build-da14695_dk_usb/metrics.json
  • cmake-build/cmake-build-double_m33_express/metrics.json
  • cmake-build/cmake-build-ea4088_quickstart/metrics.json
  • cmake-build/cmake-build-ea4357/metrics.json
  • cmake-build/cmake-build-ek_tm4c123gxl/metrics.json
  • cmake-build/cmake-build-feather_stm32f405/metrics.json
  • cmake-build/cmake-build-fomu/metrics.json
  • cmake-build/cmake-build-frdm_k32l2a4s/metrics.json
  • cmake-build/cmake-build-frdm_k64f/metrics.json
  • cmake-build/cmake-build-frdm_kl25z/metrics.json
  • cmake-build/cmake-build-frdm_mcxa153/metrics.json
  • cmake-build/cmake-build-frdm_rw612/metrics.json
  • cmake-build/cmake-build-hpm6750evk2/metrics.json
  • cmake-build/cmake-build-lpcxpresso11u37/metrics.json
  • cmake-build/cmake-build-lpcxpresso1347/metrics.json
  • cmake-build/cmake-build-lpcxpresso1549/metrics.json
  • cmake-build/cmake-build-lpcxpresso1769/metrics.json
  • cmake-build/cmake-build-lpcxpresso18s37/metrics.json
  • cmake-build/cmake-build-lpcxpresso51u68/metrics.json
  • cmake-build/cmake-build-lpcxpresso54114/metrics.json
  • cmake-build/cmake-build-metro_m0_express/metrics.json
  • cmake-build/cmake-build-metro_m4_express/metrics.json
  • cmake-build/cmake-build-metro_m7_1011/metrics.json
  • cmake-build/cmake-build-mm32f327x_mb39/metrics.json
  • cmake-build/cmake-build-msp_exp430f5529lp/metrics.json
  • cmake-build/cmake-build-msp_exp432e401y/metrics.json
  • cmake-build/cmake-build-nutiny_nuc126v/metrics.json
  • cmake-build/cmake-build-nutiny_sdk_nuc120/metrics.json
  • cmake-build/cmake-build-nutiny_sdk_nuc121/metrics.json
  • cmake-build/cmake-build-nutiny_sdk_nuc505/metrics.json
  • cmake-build/cmake-build-portenta_c33/metrics.json
  • cmake-build/cmake-build-raspberry_pi_pico/metrics.json
  • cmake-build/cmake-build-raspberrypi_cm4/metrics.json
  • cmake-build/cmake-build-raspberrypi_zero/metrics.json
  • cmake-build/cmake-build-samg55_xplained/metrics.json
  • cmake-build/cmake-build-sipeed_longan_nano/metrics.json
  • cmake-build/cmake-build-stlinkv3mini/metrics.json
  • cmake-build/cmake-build-stm32c071nucleo/metrics.json
  • cmake-build/cmake-build-stm32f070rbnucleo/metrics.json
  • cmake-build/cmake-build-stm32f103_bluepill/metrics.json
  • cmake-build/cmake-build-stm32f207nucleo/metrics.json
  • cmake-build/cmake-build-stm32f303disco/metrics.json
  • cmake-build/cmake-build-stm32g0b1nucleo/metrics.json
  • cmake-build/cmake-build-stm32h503nucleo/metrics.json
  • cmake-build/cmake-build-stm32h743eval/metrics.json
  • cmake-build/cmake-build-stm32h7s3nucleo/metrics.json
  • cmake-build/cmake-build-stm32l052dap52/metrics.json
  • cmake-build/cmake-build-stm32l412nucleo/metrics.json
  • cmake-build/cmake-build-stm32n6570dk/metrics.json
  • cmake-build/cmake-build-stm32u083cdk/metrics.json
  • cmake-build/cmake-build-stm32wb55nucleo/metrics.json
  • cmake-build/cmake-build-stm32wba_nucleo/metrics.json
  • cmake-build/cmake-build-xmc4500_relax/metrics.json

@hathach
Copy link
Copy Markdown
Owner

hathach commented Mar 7, 2026

@claude review

@claude
Copy link
Copy Markdown

claude Bot commented Mar 7, 2026

Claude finished @hathach's task in 4m 1s —— View job


PR Review: Add IP3516 HCD Support

Tasks:

  • Gather context and understand PR scope
  • Review new HCD driver (hcd_lpc_ip3516.c / .h)
  • Review BSP changes (lpc54, lpc55, lpc51, mcx families)
  • Review example changes
  • Review build system changes (get_deps.py, CMake, Make)
  • Compile final review

Overall this is a solid implementation. The driver is well-structured, handles split transactions, and the BSP integration is clean. A few issues worth addressing before merge:

src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.c

Bug: Wrong memory section macro for PTD array (line 79)

CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(1024) static ip3516_ptd_t _ptd;

CFG_TUD_MEM_SECTION (device section) is used for a host-controller data structure. This should be CFG_TUH_MEM_SECTION. On LPC55/LPC54 with separate USB SRAM for host and device, these macros are defined the same way (m_usb_global) but the semantic mismatch is confusing and could be a real bug in dual-role or future configurations. Fix this →

Race condition in hcd_edpt_close (lines 648-664)

find_and_close_ptd is called with NULL as skip_reg, which causes direct memory clear without first telling the controller to skip the PTD. If the hardware is actively DMAing that PTD when it's cleared, corruption or assertion could occur. The hcd_edpt_abort_xfer path correctly sets the skip bit and waits one uframe first; hcd_edpt_close should do the same. This is particularly relevant for ATL (control/bulk) where the same skip register exists:

// Current (unsafe for active PTDs)
find_and_close_ptd(..., NULL)   // direct memclr

// Should be:
find_and_close_ptd(..., &USBHSH->ATLPTDS)  // skip → wait → clear

Potential infinite loop in close_ptds_by_device / find_and_close_ptd (lines 165-168, 225-227)

The uframe busy-wait has no timeout:

while (((USBHSH->FLADJ_FRINDEX & ...) >> ...) == start_uframe) {}

If the USB controller clock is gated, paused, or hangs, this spins forever. A timeout guard (e.g., tu_timeout_expired) would be safer.

find_opened_ptd returns pointer-typed TUSB_INDEX_INVALID_8 (line 275)

The function signature returns intptr_t but uses TUSB_INDEX_INVALID_8 (0xFF = 255) as "not found":

return TUSB_INDEX_INVALID_8;  // 0xFF — but callers compare as pointer

Callers check ptd_ptr != TUSB_INDEX_INVALID_8. Since the PTD array is 1024-byte aligned this won't produce a false match in practice, but using a proper sentinel like 0 or (intptr_t)NULL (or at least documenting the convention) would be cleaner and less surprising.

is_xfer_asyc typo (lines 96, 135, 476)

static inline bool is_xfer_asyc(tusb_xfer_type_t xfer_type) {  // should be is_xfer_async

Minor, but worth fixing for searchability. Fix this →

Hardcoded USB1_IRQn in hcd_int_enable/disable (lines 375-382)

void hcd_int_enable(uint8_t rhport) {
  (void)rhport;
  NVIC_EnableIRQ(USB1_IRQn);   // always USB1
}

The rhport parameter is suppressed. If a board ever routes the IP3516 controller to a different interrupt vector, this breaks silently. Consider making the IRQn board-configurable via a BOARD_TUH_USB_IRQ macro.

src/portable/nxp/lpc_ip3516/hcd_lpc_ip3516.h

Wrong section comment (line 60)

//--------------------------------------------------------------------+
// OHCI Data Structure          <-- should be "IP3516 Data Structure"
//--------------------------------------------------------------------+

Copy-paste error from the OHCI driver.

Unused defines (lines 45-47)

#define IP3516_PTD_EPTYPE_OUT   0x00U
#define IP3516_PTD_EPTYPE_IN    0x01U
#define IP3516_PTD_EPTYPE_SETUP 0x02U

These are defined but not used in the driver (the driver uses the tusb_xfer_type_t enum instead). Either use them or remove them.

Unused defines (lines 55-56)

#define IP3516_PERIODIC_TRANSFER_GAP  (3U)
#define IP3516_ISO_MULTIPLE_TRANSFER  (8U)

These are defined but not referenced anywhere in the driver.

hw/bsp/lpc55/family.mk

Missing hcd_lpc_ip3516.c in Make build

The CMake build (lpc55/family.cmake lines 136-140) conditionally adds hcd_lpc_ip3516.c when RHPORT_HOST == 1, but lpc55/family.mk only adds dcd_lpc_ip3511.c with no equivalent conditional for the host driver. Make-based host builds for LPC55 will fail to link the HCD. Fix this →

LD_FILE missing $(TOP) prefix (line 38)

LD_FILE ?= $(SDK_DIR)/LPC5500/$(MCU_VARIANT)/gcc/$(MCU_CORE)_flash.ld

All SRC_C and INC entries use $(TOP)/$(SDK_DIR)/... but LD_FILE uses $(SDK_DIR)/... directly. This inconsistency means the linker script path is relative to the build directory rather than the repo root, which may break out-of-tree builds. Copilot flagged this as well. Fix this →

examples/host/msc_file_explorer/src/msc_app.c (line ~165)

Commented-out block of code (flagged by GitHub security scanner) should be cleaned up — either restored or removed entirely.

Minor / Informational

  • lpc54/family.cmake still uses old mcux-sdk — understood from the PR description that mcux-devices-lpc is missing drivers needed for LPC54. A comment in family.cmake explaining why it wasn't migrated (linking to the upstream issue) would help future maintainers.
  • uframe_active mask 0x11 for interval-4 (line 554): The comment example says "0, 2, 4, 6" for interval 2 with mask 0xAA, but 0x11 for interval-4 gives u-frames 0 and 4 (not 0, 4 as the comment says; the comment is correct, just confirming).
  • ctrl2->speed magic values (line 515): 2 for low speed, 0 for full/high. A comment or named constant would help readability.
  • Split-transaction TODO (lines 598-599): The scheduling budget check is noted as a TODO. This is acceptable for initial support but worth tracking for correctness with multiple split-transaction endpoints.

Copy link
Copy Markdown
Owner

@hathach hathach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefect, I tested and it works well with my lpc55s28 board. I also make some changes to lpc55 bsp to use the mcxconfig tool (generated pinmux, clock_config) as well.

@hathach hathach merged commit 7249c65 into master Mar 10, 2026
304 of 306 checks passed
@hathach hathach deleted the hcd_ip3516 branch March 10, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants