summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2026-01-06 18:42:58 +0100
committerHiFiPhile <[email protected]>2026-01-06 18:42:58 +0100
commit60154a128795bcd6ca36042cac1b8bebf1a2764e (patch)
tree0557ab4b2a01c64de109c54662ba6f3a58147bc9
parentc5f91ec6f54509d03529e276ffd42b0d9abab695 (diff)
parent593dce28349cf5b1299c2cf1193312cb783574f3 (diff)
Merge remote-tracking branch 'tinyusb/master' into ep0_direct
-rwxr-xr-x.github/workflows/ci_set_matrix.py4
-rw-r--r--README.rst264
-rw-r--r--examples/CMakeLists.txt7
-rw-r--r--examples/build_system/cmake/cpu/rv32imac-ilp32.cmake4
-rw-r--r--examples/build_system/make/cpu/rv32imac-ilp32.mk4
-rw-r--r--examples/build_system/make/toolchain/riscv_gcc.mk2
-rw-r--r--examples/device/audio_4_channel_mic/CMakeLists.txt17
-rw-r--r--examples/device/audio_4_channel_mic_freertos/CMakeLists.txt17
-rw-r--r--examples/device/audio_4_channel_mic_freertos/skip.txt1
-rw-r--r--examples/device/audio_test/CMakeLists.txt15
-rw-r--r--examples/device/audio_test_freertos/CMakeLists.txt15
-rw-r--r--examples/device/audio_test_freertos/skip.txt1
-rw-r--r--examples/device/audio_test_multi_rate/CMakeLists.txt15
-rw-r--r--examples/device/board_test/CMakeLists.txt9
-rw-r--r--examples/device/cdc_dual_ports/CMakeLists.txt15
-rw-r--r--examples/device/cdc_msc/CMakeLists.txt10
-rw-r--r--examples/device/cdc_msc_freertos/CMakeLists.txt15
-rw-r--r--examples/device/cdc_msc_freertos/skip.txt1
-rw-r--r--examples/device/cdc_uac2/CMakeLists.txt17
-rw-r--r--examples/device/dfu/CMakeLists.txt15
-rw-r--r--examples/device/dfu_runtime/CMakeLists.txt15
-rw-r--r--examples/device/dynamic_configuration/CMakeLists.txt15
-rw-r--r--examples/device/hid_boot_interface/CMakeLists.txt15
-rw-r--r--examples/device/hid_composite/CMakeLists.txt15
-rw-r--r--examples/device/hid_composite_freertos/CMakeLists.txt15
-rw-r--r--examples/device/hid_composite_freertos/skip.txt1
-rw-r--r--examples/device/hid_generic_inout/CMakeLists.txt15
-rw-r--r--examples/device/hid_multiple_interface/CMakeLists.txt15
-rw-r--r--examples/device/midi_test/CMakeLists.txt15
-rw-r--r--examples/device/midi_test_freertos/CMakeLists.txt15
-rw-r--r--examples/device/midi_test_freertos/skip.txt1
-rw-r--r--examples/device/msc_dual_lun/CMakeLists.txt9
-rw-r--r--examples/device/mtp/CMakeLists.txt9
-rw-r--r--examples/device/net_lwip_webserver/CMakeLists.txt22
-rw-r--r--examples/device/uac2_headset/CMakeLists.txt15
-rw-r--r--examples/device/uac2_speaker_fb/CMakeLists.txt15
-rw-r--r--examples/device/usbtmc/CMakeLists.txt15
-rw-r--r--examples/device/video_capture/CMakeLists.txt17
-rw-r--r--examples/device/video_capture_2ch/CMakeLists.txt17
-rw-r--r--examples/device/webusb_serial/CMakeLists.txt15
-rw-r--r--examples/device/webusb_serial/src/main.c1
-rw-r--r--examples/dual/host_hid_to_device_cdc/CMakeLists.txt17
-rw-r--r--examples/dual/host_info_to_device_cdc/CMakeLists.txt17
-rw-r--r--examples/host/bare_api/CMakeLists.txt15
-rw-r--r--examples/host/bare_api/only.txt19
-rw-r--r--examples/host/cdc_msc_hid/CMakeLists.txt15
-rw-r--r--examples/host/cdc_msc_hid/only.txt19
-rw-r--r--examples/host/cdc_msc_hid_freertos/CMakeLists.txt15
-rw-r--r--examples/host/cdc_msc_hid_freertos/only.txt16
-rw-r--r--examples/host/device_info/CMakeLists.txt15
-rw-r--r--examples/host/device_info/only.txt17
-rw-r--r--examples/host/hid_controller/CMakeLists.txt15
-rw-r--r--examples/host/hid_controller/only.txt18
-rw-r--r--examples/host/midi_rx/CMakeLists.txt15
-rw-r--r--examples/host/midi_rx/only.txt17
-rw-r--r--examples/host/msc_file_explorer/CMakeLists.txt15
-rw-r--r--examples/host/msc_file_explorer/only.txt19
-rw-r--r--examples/typec/power_delivery/CMakeLists.txt15
-rw-r--r--hw/bsp/BoardPresets.json88
-rw-r--r--hw/bsp/at32f403a_407/family.cmake1
-rw-r--r--hw/bsp/at32f403a_407/family.mk1
-rw-r--r--hw/bsp/at32f413/family.cmake1
-rw-r--r--hw/bsp/at32f413/family.mk1
-rw-r--r--hw/bsp/ch32v20x/family.cmake1
-rw-r--r--hw/bsp/ch32v20x/family.mk1
-rw-r--r--hw/bsp/family_support.cmake5
-rw-r--r--hw/bsp/family_support.mk17
-rw-r--r--hw/bsp/hpmicro/boards/hpm6750evk2/board.c295
-rw-r--r--hw/bsp/hpmicro/boards/hpm6750evk2/board.cmake22
-rw-r--r--hw/bsp/hpmicro/boards/hpm6750evk2/board.h105
-rw-r--r--hw/bsp/hpmicro/boards/hpm6750evk2/board.mk16
-rw-r--r--hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.c862
-rw-r--r--hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.h89
-rw-r--r--hw/bsp/hpmicro/family.c115
-rw-r--r--hw/bsp/hpmicro/family.cmake129
-rw-r--r--hw/bsp/hpmicro/family.mk74
-rw-r--r--hw/bsp/imxrt/family.c19
-rw-r--r--hw/bsp/imxrt/family.cmake28
-rw-r--r--hw/bsp/imxrt/family.mk1
-rw-r--r--hw/bsp/rp2040/family.cmake2
-rw-r--r--hw/bsp/rw61x/FreeRTOSConfig/FreeRTOSConfig.h150
-rw-r--r--hw/bsp/rw61x/boards/frdm_rw612/board.cmake30
-rw-r--r--hw/bsp/rw61x/boards/frdm_rw612/board.h74
-rw-r--r--hw/bsp/rw61x/boards/frdm_rw612/board.mk20
-rw-r--r--hw/bsp/rw61x/boards/frdm_rw612/clock_config.c169
-rw-r--r--hw/bsp/rw61x/boards/frdm_rw612/clock_config.h115
-rw-r--r--hw/bsp/rw61x/boards/frdm_rw612/pin_mux.c223
-rw-r--r--hw/bsp/rw61x/boards/frdm_rw612/pin_mux.h146
-rw-r--r--hw/bsp/rw61x/family.c135
-rw-r--r--hw/bsp/rw61x/family.cmake109
-rw-r--r--hw/bsp/rw61x/family.mk52
-rw-r--r--hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld2
-rw-r--r--hw/bsp/stm32c0/boards/stm32c071nucleo/board.cmake1
-rw-r--r--hw/bsp/stm32c0/boards/stm32c071nucleo/board.h32
-rw-r--r--hw/bsp/stm32c0/boards/stm32c071nucleo/board.mk2
-rw-r--r--hw/bsp/stm32c0/boards/stm32c071nucleo/stm32c071xx_flash.icf33
-rw-r--r--hw/bsp/stm32c0/family.c4
-rw-r--r--hw/bsp/stm32c0/family.cmake3
-rw-r--r--hw/bsp/stm32c0/family.mk2
-rw-r--r--hw/bsp/stm32c0/stm32c0xx_hal_conf.h2
-rw-r--r--hw/bsp/stm32f0/family.cmake1
-rw-r--r--hw/bsp/stm32f0/family.mk1
-rw-r--r--hw/bsp/stm32f1/family.cmake1
-rw-r--r--hw/bsp/stm32f1/family.mk1
-rw-r--r--hw/bsp/stm32f3/family.cmake1
-rw-r--r--hw/bsp/stm32f3/family.mk1
-rw-r--r--hw/bsp/stm32g0/family.c2
-rw-r--r--hw/bsp/stm32g0/family.cmake2
-rw-r--r--hw/bsp/stm32g0/family.mk2
-rw-r--r--hw/bsp/stm32g4/family.cmake1
-rw-r--r--hw/bsp/stm32g4/family.mk1
-rw-r--r--hw/bsp/stm32h5/boards/stm32h503nucleo/board.cmake3
-rw-r--r--hw/bsp/stm32h5/boards/stm32h503nucleo/board.h52
-rw-r--r--hw/bsp/stm32h5/boards/stm32h503nucleo/board.mk1
-rw-r--r--hw/bsp/stm32h5/boards/stm32h563nucleo/board.h52
-rw-r--r--hw/bsp/stm32h5/boards/stm32h573i_dk/board.cmake7
-rw-r--r--hw/bsp/stm32h5/boards/stm32h573i_dk/board.h152
-rw-r--r--hw/bsp/stm32h5/boards/stm32h573i_dk/board.mk7
-rw-r--r--hw/bsp/stm32h5/family.c85
-rw-r--r--hw/bsp/stm32h5/family.cmake6
-rw-r--r--hw/bsp/stm32h5/family.mk4
-rw-r--r--hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld2
-rw-r--r--hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld2
-rw-r--r--hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld2
-rw-r--r--hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld2
-rw-r--r--hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld2
-rw-r--r--hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld2
-rw-r--r--hw/bsp/stm32h5/linker/stm32h503xx_flash.icf32
-rw-r--r--hw/bsp/stm32h5/linker/stm32h523xx_flash.icf32
-rw-r--r--hw/bsp/stm32h5/linker/stm32h562xx_flash.icf32
-rw-r--r--hw/bsp/stm32h5/linker/stm32h563xx_flash.icf32
-rw-r--r--hw/bsp/stm32h5/linker/stm32h573xx_flash.icf32
-rw-r--r--hw/bsp/stm32h5/stm32h5xx_hal_conf.h2
-rw-r--r--hw/bsp/stm32l0/family.cmake1
-rw-r--r--hw/bsp/stm32l0/family.mk1
-rw-r--r--hw/bsp/stm32l4/family.cmake1
-rw-r--r--hw/bsp/stm32l4/family.mk1
-rw-r--r--hw/bsp/stm32u0/family.cmake1
-rw-r--r--hw/bsp/stm32u0/family.mk1
-rw-r--r--hw/bsp/stm32u5/family.c15
-rw-r--r--hw/bsp/stm32u5/family.cmake2
-rw-r--r--hw/bsp/stm32u5/family.mk8
-rw-r--r--hw/bsp/stm32wb/family.cmake1
-rw-r--r--hw/bsp/stm32wb/family.mk1
-rw-r--r--lib/rt-thread/SConscript3
-rw-r--r--src/class/audio/audio_device.c12
-rw-r--r--src/class/cdc/cdc_host.c2
-rw-r--r--src/class/vendor/vendor_device.c7
-rw-r--r--src/class/vendor/vendor_device.h7
-rw-r--r--src/common/tusb_common.h4
-rw-r--r--src/common/tusb_debug.h8
-rw-r--r--src/common/tusb_fifo.c395
-rw-r--r--src/common/tusb_fifo.h114
-rw-r--r--src/common/tusb_mcu.h176
-rw-r--r--src/common/tusb_verify.h10
-rw-r--r--src/device/usbd.c11
-rw-r--r--src/device/usbd.h2
-rw-r--r--src/host/usbh.c99
-rw-r--r--src/host/usbh.h11
-rw-r--r--src/osal/osal_none.h18
-rw-r--r--src/osal/osal_pico.h54
-rw-r--r--src/portable/chipidea/ci_hs/ci_hs_hpm.h54
-rw-r--r--src/portable/chipidea/ci_hs/ci_hs_rw61x.h48
-rw-r--r--src/portable/chipidea/ci_hs/dcd_ci_hs.c405
-rw-r--r--src/portable/chipidea/ci_hs/hcd_ci_hs.c42
-rw-r--r--src/portable/ehci/ehci.c14
-rw-r--r--src/portable/mentor/musb/dcd_musb.c74
-rw-r--r--src/portable/microchip/samg/dcd_samg.c4
-rw-r--r--src/portable/nuvoton/nuc505/dcd_nuc505.c4
-rw-r--r--src/portable/renesas/rusb2/dcd_rusb2.c259
-rw-r--r--src/portable/renesas/rusb2/hcd_rusb2.c135
-rw-r--r--src/portable/renesas/rusb2/rusb2_common.c80
-rw-r--r--src/portable/renesas/rusb2/rusb2_common.h58
-rw-r--r--src/portable/renesas/rusb2/rusb2_type.h20
-rw-r--r--src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c512
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_at32.h19
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_ch32.h10
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_common.c116
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_common.h (renamed from src/portable/st/stm32_fsdev/fsdev_type.h)209
-rw-r--r--src/portable/st/stm32_fsdev/fsdev_stm32.h201
-rw-r--r--src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c878
-rw-r--r--src/portable/synopsys/dwc2/dcd_dwc2.c97
-rw-r--r--src/portable/synopsys/dwc2/dwc2_common.c54
-rw-r--r--src/portable/synopsys/dwc2/hcd_dwc2.c4
-rw-r--r--src/tusb.c2
-rw-r--r--src/tusb_option.h70
-rw-r--r--test/fuzz/device/cdc/CMakeLists.txt15
-rw-r--r--test/fuzz/device/msc/CMakeLists.txt15
-rw-r--r--test/fuzz/device/net/CMakeLists.txt15
-rw-r--r--test/hil/tinyusb.json5
-rw-r--r--test/unit-test/CMakeLists.txt1
-rw-r--r--test/unit-test/project.yml4
-rw-r--r--test/unit-test/test/test_fifo.c130
-rwxr-xr-xtools/get_deps.py9
-rw-r--r--tools/iar_template.ipcf4
195 files changed, 6846 insertions, 2420 deletions
diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py
index 933a8375f..c276d5253 100755
--- a/.github/workflows/ci_set_matrix.py
+++ b/.github/workflows/ci_set_matrix.py
@@ -17,12 +17,12 @@ toolchain_list = [
family_list = {
"at32f402_405 at32f403a_407 at32f413 at32f415 at32f423 at32f425 at32f435_437 broadcom_32bit da1469x": ["arm-gcc"],
"broadcom_64bit": ["aarch64-gcc"],
- "ch32v10x ch32v20x ch32v30x fomu gd32vf103": ["riscv-gcc"],
+ "ch32v10x ch32v20x ch32v30x fomu gd32vf103 hpmicro": ["riscv-gcc"],
"imxrt": ["arm-gcc", "arm-clang"],
"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"],
diff --git a/README.rst b/README.rst
index 6a6f07825..2ad0b3439 100644
--- a/README.rst
+++ b/README.rst
@@ -129,138 +129,138 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR)
Supported CPUs
--------------
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Manufacturer | Family | Device | Host | Highspeed | Driver | Note |
-+==============+=============================+========+======+===========+========================+===================+
-| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | MAX32 650, 666, 690, | ✔ | | ✔ | musb | 1-dir ep |
-| | MAX78002 | | | | | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Artery AT32 | F403a_407, F413 | ✔ | | | fsdev | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | F415, F435_437, F423, F425 | ✔ | ✔ | | dwc2 | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | F402_F405 | ✔ | ✔ | ✔ | dwc2 | F405 is HS |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Bridgetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Espressif | S2, S3 | ✔ | ✔ | ✖ | dwc2 | |
-| ESP32 +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | P4 | ✔ | ✔ | ✔ | dwc2 | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | H4 | ✔ | ✔ | ✖ | dwc2 | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Infineon | XMC4500 | ✔ | ✔ | ✖ | dwc2 | |
-+--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+
-| MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | |
-| | +-----------------------+--------+------+-----------+------------------------+-------------------+
-| | | D51, E5x | ✔ | | ✖ | samd | |
-| | +-----------------------+--------+------+-----------+------------------------+-------------------+
-| | | G55 | ✔ | | ✖ | samg | 1-dir ep |
-| | +-----------------------+--------+------+-----------+------------------------+-------------------+
-| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | 1-dir ep |
-| +-----+-----------------------+--------+------+-----------+------------------------+-------------------+
-| | PIC | 24 | ✔ | | | pic | ci_fs variant |
-| | +-----------------------+--------+------+-----------+------------------------+-------------------+
-| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant |
-| | +-----------------------+--------+------+-----------+------------------------+-------------------+
-| | | dsPIC33 | ✔ | | | pic | ci_fs variant |
-| | +-----------------------+--------+------+-----------+------------------------+-------------------+
-| | | 32mz | ✔ | | | pic32mz | musb variant |
-+--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+
-| MindMotion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant |
-+--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+
-| NordicSemi | nRF 52833, 52840, 5340 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | NUC126 | ✔ | ✖ | ✖ | nuc121 | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | NUC505 | ✔ | | ✔ | nuc505 | |
-+--------------+---------+-------------------+--------+------+-----------+------------------------+-------------------+
-| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs, ehci | |
-| +---------+-------------------+--------+------+-----------+------------------------+-------------------+
-| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | |
-| | +-------------------+--------+------+-----------+------------------------+-------------------+
-| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant |
-| +---------+-------------------+--------+------+-----------+------------------------+-------------------+
-| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | |
-| | +-------------------+--------+------+-----------+------------------------+-------------------+
-| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40, ohci | |
-| | +-------------------+--------+------+-----------+------------------------+-------------------+
-| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs, ehci | |
-| | +-------------------+--------+------+-----------+------------------------+-------------------+
-| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | |
-| | +-------------------+--------+------+-----------+------------------------+-------------------+
-| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | |
-| +---------+-------------------+--------+------+-----------+------------------------+-------------------+
-| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs, ehci | |
-| | +-------------------+--------+------+-----------+------------------------+-------------------+
-| | | A15 | ✔ | | | ci_fs | |
-+--------------+---------+-------------------+--------+------+-----------+------------------------+-------------------+
-| Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | |
-+--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+
-| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | |
-| +-----+-----------------------+--------+------+-----------+------------------------+-------------------+
-| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | |
-| | +-----------------------+--------+------+-----------+------------------------+-------------------+
-| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | |
-+--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+
-| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| ST STM32 | F0, F3, L0, L1, L5, WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | |
-| +----+------------------------+--------+------+-----------+------------------------+-------------------+
-| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | |
-| | +------------------------+--------+------+-----------+------------------------+-------------------+
-| | | 105, 107 | ✔ | ✔ | ✖ | dwc2 | |
-| +----+------------------------+--------+------+-----------+------------------------+-------------------+
-| | F2, F4, F7, H7, H7RS | ✔ | ✔ | ✔ | dwc2 | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | C0, G0, H5 | ✔ | | ✖ | stm32_fsdev | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | |
-| +----+------------------------+--------+------+-----------+------------------------+-------------------+
-| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | |
-| | +------------------------+--------+------+-----------+------------------------+-------------------+
-| | | 4x5, 4x6, 4+ | ✔ | ✔ | ✖ | dwc2 | |
-| +----+------------------------+--------+------+-----------+------------------------+-------------------+
-| | N6 | ✔ | ✔ | ✔ | dwc2 | |
-| +----+------------------------+--------+------+-----------+------------------------+-------------------+
-| | U0 | ✔ | ✖ | ✖ | stm32_fsdev | |
-| +----+------------------------+--------+------+-----------+------------------------+-------------------+
-| | U3 | ✔ | | ✖ | stm32_fsdev | |
-| +----+------------------------+--------+------+-----------+------------------------+-------------------+
-| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | |
-| | +------------------------+--------+------+-----------+------------------------+-------------------+
-| | | 575, 585 | ✔ | ✔ | ✖ | dwc2 | |
-| | +------------------------+--------+------+-----------+------------------------+-------------------+
-| | | 59x,5Ax,5Fx,5Gx | ✔ | ✔ | ✔ | dwc2 | |
-+--------------+----+------------------------+--------+------+-----------+------------------------+-------------------+
-| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | MSP432E4, TM4C123 | ✔ | | ✖ | musb | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
-| WCH | CH32F20x | ✔ | | ✔ | ch32_usbhs | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | CH32V20x | ✔ | | ✖ | stm32_fsdev/ch32_usbfs | |
-| +-----------------------------+--------+------+-----------+------------------------+-------------------+
-| | CH32V305, CH32V307 | ✔ | | ✔ | ch32_usbfs/hs | |
-+--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Manufacturer | Family | Device | Host | Highspeed | Driver | Note |
++==============+=============================+========+======+===========+========================+====================+
+| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | MAX32 650, 666, 690, | ✔ | | ✔ | musb | 1-dir ep |
+| | MAX78002 | | | | | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Artery AT32 | F403a_407, F413 | ✔ | | | fsdev | 512 USB RAM |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | F415, F435_437, F423, F425 | ✔ | ✔ | | dwc2 | |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | F402_F405 | ✔ | ✔ | ✔ | dwc2 | F405 is HS |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Bridgetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Espressif | S2, S3 | ✔ | ✔ | ✖ | dwc2 | |
+| ESP32 +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | P4 | ✔ | ✔ | ✔ | dwc2 | |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | H4 | ✔ | ✔ | ✖ | dwc2 | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| HPMicro | HPM6750 | ✔ | ✔ | ✔ | ci_hs, ehci | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Infineon | XMC4500 | ✔ | ✔ | ✖ | dwc2 | |
++--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+
+| MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | |
+| | +-----------------------+--------+------+-----------+------------------------+--------------------+
+| | | D51, E5x | ✔ | | ✖ | samd | |
+| | +-----------------------+--------+------+-----------+------------------------+--------------------+
+| | | G55 | ✔ | | ✖ | samg | 1-dir ep |
+| | +-----------------------+--------+------+-----------+------------------------+--------------------+
+| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | 1-dir ep |
+| +-----+-----------------------+--------+------+-----------+------------------------+--------------------+
+| | PIC | 24 | ✔ | | | pic | ci_fs variant |
+| | +-----------------------+--------+------+-----------+------------------------+--------------------+
+| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant |
+| | +-----------------------+--------+------+-----------+------------------------+--------------------+
+| | | dsPIC33 | ✔ | | | pic | ci_fs variant |
+| | +-----------------------+--------+------+-----------+------------------------+--------------------+
+| | | 32mz | ✔ | | | pic32mz | musb variant |
++--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+
+| MindMotion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant |
++--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+
+| NordicSemi | nRF 52833, 52840, 5340 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | NUC121/NUC125, NUC126 | ✔ | ✖ | ✖ | nuc121 | |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | NUC505 | ✔ | | ✔ | nuc505 | |
++--------------+---------+-------------------+--------+------+-----------+------------------------+--------------------+
+| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs, ehci | |
+| +---------+-------------------+--------+------+-----------+------------------------+--------------------+
+| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | |
+| | +-------------------+--------+------+-----------+------------------------+--------------------+
+| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant |
+| +---------+-------------------+--------+------+-----------+------------------------+--------------------+
+| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | |
+| | +-------------------+--------+------+-----------+------------------------+--------------------+
+| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40, ohci | |
+| | +-------------------+--------+------+-----------+------------------------+--------------------+
+| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs, ehci | |
+| | +-------------------+--------+------+-----------+------------------------+--------------------+
+| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | |
+| | +-------------------+--------+------+-----------+------------------------+--------------------+
+| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | |
+| +---------+-------------------+--------+------+-----------+------------------------+--------------------+
+| | 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 | |
+| +-----+-----------------------+--------+------+-----------+------------------------+--------------------+
+| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | |
+| | +-----------------------+--------+------+-----------+------------------------+--------------------+
+| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | |
++--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+
+| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| ST STM32 | F0, F3, L0, L1, L5, WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | |
+| +----+------------------------+--------+------+-----------+------------------------+--------------------+
+| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | 512 USB RAM |
+| | +------------------------+--------+------+-----------+------------------------+--------------------+
+| | | 105, 107 | ✔ | ✔ | ✖ | dwc2 | |
+| +----+------------------------+--------+------+-----------+------------------------+--------------------+
+| | F2, F4, F7, H7, H7RS | ✔ | ✔ | ✔ | dwc2 | |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | C0, G0, H5, U3 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM |
+| +----+------------------------+--------+------+-----------+------------------------+--------------------+
+| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM |
+| | +------------------------+--------+------+-----------+------------------------+--------------------+
+| | | 4x5, 4x6, 4+ | ✔ | ✔ | ✖ | dwc2 | |
+| +----+------------------------+--------+------+-----------+------------------------+--------------------+
+| | N6 | ✔ | ✔ | ✔ | dwc2 | |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | U0 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM |
+| +----+------------------------+--------+------+-----------+------------------------+--------------------+
+| | U5 | 535, 545 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM |
+| | +------------------------+--------+------+-----------+------------------------+--------------------+
+| | | 575, 585 | ✔ | ✔ | ✖ | dwc2 | |
+| | +------------------------+--------+------+-----------+------------------------+--------------------+
+| | | 59x,5Ax,5Fx,5Gx | ✔ | ✔ | ✔ | dwc2 | |
++--------------+----+------------------------+--------+------+-----------+------------------------+--------------------+
+| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | MSP432E4, TM4C123 | ✔ | | ✖ | musb | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| WCH | CH32F20x | ✔ | | ✔ | ch32_usbhs | |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | CH32V20x | ✔ | | ✖ | stm32_fsdev/ch32_usbfs | |
+| +-----------------------------+--------+------+-----------+------------------------+--------------------+
+| | CH32V305, CH32V307 | ✔ | | ✔ | ch32_usbfs/hs | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
Table Legend
^^^^^^^^^^^^
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index b34131c2b..b458c9ce3 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,6 +1,5 @@
cmake_minimum_required(VERSION 3.20)
-#set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(${CMAKE_CURRENT_SOURCE_DIR}/../hw/bsp/family_support.cmake)
project(tinyusb_examples C CXX ASM)
@@ -27,3 +26,9 @@ add_custom_target(tinyusb_metrics
COMMENT "Generating average code size metrics"
VERBATIM
)
+
+#add_custom_command(TARGET tinyusb_metrics POST_BUILD
+# COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/metrics.py compare ${TOP}/cmake-build/cmake-build-${BOARD}/metrics.json ${CMAKE_BINARY_DIR}/metrics.json
+# COMMENT "Generating average code size metrics"
+# VERBATIM
+# )
diff --git a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake
index 584d90519..8c2538cee 100644
--- a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake
+++ b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake
@@ -1,13 +1,13 @@
if (TOOLCHAIN STREQUAL "gcc")
set(TOOLCHAIN_COMMON_FLAGS
- -march=rv32imac_zicsr
+ -march=rv32imac_zicsr_zifencei
-mabi=ilp32
)
set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "")
elseif (TOOLCHAIN STREQUAL "clang")
set(TOOLCHAIN_COMMON_FLAGS
- -march=rv32imac_zicsr
+ -march=rv32imac_zicsr_zifencei
-mabi=ilp32
)
set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "")
diff --git a/examples/build_system/make/cpu/rv32imac-ilp32.mk b/examples/build_system/make/cpu/rv32imac-ilp32.mk
index 19c322ebc..a7b2258d7 100644
--- a/examples/build_system/make/cpu/rv32imac-ilp32.mk
+++ b/examples/build_system/make/cpu/rv32imac-ilp32.mk
@@ -1,11 +1,11 @@
ifeq ($(TOOLCHAIN),gcc)
CFLAGS += \
- -march=rv32imac_zicsr \
+ -march=rv32imac_zicsr_zifencei \
-mabi=ilp32 \
else ifeq ($(TOOLCHAIN),clang)
CFLAGS += \
- -march=rv32imac_zicsr \
+ -march=rv32imac_zicsr_zifencei \
-mabi=ilp32 \
else ifeq ($(TOOLCHAIN),iar)
diff --git a/examples/build_system/make/toolchain/riscv_gcc.mk b/examples/build_system/make/toolchain/riscv_gcc.mk
index 843aff38c..b5de12a83 100644
--- a/examples/build_system/make/toolchain/riscv_gcc.mk
+++ b/examples/build_system/make/toolchain/riscv_gcc.mk
@@ -1,7 +1,7 @@
# makefile for arm gcc toolchain
# Can be set by family, default to ARM GCC
-CROSS_COMPILE ?= riscv-none-embed-
+CROSS_COMPILE ?= riscv-none-elf-
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
diff --git a/examples/device/audio_4_channel_mic/CMakeLists.txt b/examples/device/audio_4_channel_mic/CMakeLists.txt
index c8086ae46..5d7ffa4fc 100644
--- a/examples/device/audio_4_channel_mic/CMakeLists.txt
+++ b/examples/device/audio_4_channel_mic/CMakeLists.txt
@@ -2,37 +2,34 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(audio_4_channel_mic C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Add libm for GCC
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
- target_link_libraries(${PROJECT} PUBLIC m)
+ target_link_libraries(${PROJECT_NAME} PUBLIC m)
endif()
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt
index c50d4fef7..d43a72e58 100644
--- a/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt
+++ b/examples/device/audio_4_channel_mic_freertos/CMakeLists.txt
@@ -2,37 +2,34 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(audio_4_channel_mic_freertos C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Add libm for GCC
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
- target_link_libraries(${PROJECT} PUBLIC m)
+ target_link_libraries(${PROJECT_NAME} PUBLIC m)
endif()
# Configure compilation flags and libraries for the example with FreeRTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} freertos)
+family_configure_device_example(${PROJECT_NAME} freertos)
diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt
index 65925b32c..4c2780096 100644
--- a/examples/device/audio_4_channel_mic_freertos/skip.txt
+++ b/examples/device/audio_4_channel_mic_freertos/skip.txt
@@ -18,3 +18,4 @@ board:lpcxpresso1347
family:broadcom_32bit
family:broadcom_64bit
family:nuc121_125
+family:hpmicro
diff --git a/examples/device/audio_test/CMakeLists.txt b/examples/device/audio_test/CMakeLists.txt
index 6a7e68c3d..3382530c6 100644
--- a/examples/device/audio_test/CMakeLists.txt
+++ b/examples/device/audio_test/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(audio_test C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/audio_test_freertos/CMakeLists.txt b/examples/device/audio_test_freertos/CMakeLists.txt
index 6ce9e72fe..71d65eccc 100644
--- a/examples/device/audio_test_freertos/CMakeLists.txt
+++ b/examples/device/audio_test_freertos/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(audio_test_freertos C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example with FreeRTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} freertos)
+family_configure_device_example(${PROJECT_NAME} freertos)
diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt
index c9cdacad7..2da7808e7 100644
--- a/examples/device/audio_test_freertos/skip.txt
+++ b/examples/device/audio_test_freertos/skip.txt
@@ -16,3 +16,4 @@ family:broadcom_32bit
family:broadcom_64bit
board:stm32l0538disco
family:nuc121_125
+family:hpmicro
diff --git a/examples/device/audio_test_multi_rate/CMakeLists.txt b/examples/device/audio_test_multi_rate/CMakeLists.txt
index 6a7e68c3d..c17831cda 100644
--- a/examples/device/audio_test_multi_rate/CMakeLists.txt
+++ b/examples/device/audio_test_multi_rate/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(audio_test_multi_rate C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/board_test/CMakeLists.txt b/examples/device/board_test/CMakeLists.txt
index 9a604a732..bd7b8e0ca 100644
--- a/examples/device/board_test/CMakeLists.txt
+++ b/examples/device/board_test/CMakeLists.txt
@@ -2,13 +2,10 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(board_test C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
@@ -18,7 +15,7 @@ endif()
if (RTOS STREQUAL zephyr)
set(EXE_NAME app)
else()
- set(EXE_NAME ${PROJECT})
+ set(EXE_NAME ${PROJECT_NAME})
add_executable(${EXE_NAME})
endif()
diff --git a/examples/device/cdc_dual_ports/CMakeLists.txt b/examples/device/cdc_dual_ports/CMakeLists.txt
index 6a7e68c3d..697906b83 100644
--- a/examples/device/cdc_dual_ports/CMakeLists.txt
+++ b/examples/device/cdc_dual_ports/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(cdc_dual_ports C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/cdc_msc/CMakeLists.txt b/examples/device/cdc_msc/CMakeLists.txt
index b07f92342..293b497a7 100644
--- a/examples/device/cdc_msc/CMakeLists.txt
+++ b/examples/device/cdc_msc/CMakeLists.txt
@@ -1,15 +1,11 @@
cmake_minimum_required(VERSION 3.20)
-#set_property(GLOBAL PROPERTY USE_FOLDERS ON)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(cdc_msc C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
@@ -19,7 +15,7 @@ endif()
if (RTOS STREQUAL zephyr)
set(EXE_NAME app)
else()
- set(EXE_NAME ${PROJECT})
+ set(EXE_NAME ${PROJECT_NAME})
add_executable(${EXE_NAME})
endif()
diff --git a/examples/device/cdc_msc_freertos/CMakeLists.txt b/examples/device/cdc_msc_freertos/CMakeLists.txt
index f7636a07a..429000427 100644
--- a/examples/device/cdc_msc_freertos/CMakeLists.txt
+++ b/examples/device/cdc_msc_freertos/CMakeLists.txt
@@ -2,33 +2,30 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(cdc_msc_freertos C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example with FreeRTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} freertos)
+family_configure_device_example(${PROJECT_NAME} freertos)
diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt
index 69fc883e6..d90741df7 100644
--- a/examples/device/cdc_msc_freertos/skip.txt
+++ b/examples/device/cdc_msc_freertos/skip.txt
@@ -16,3 +16,4 @@ mcu:STM32L0
family:broadcom_32bit
family:broadcom_64bit
family:nuc121_125
+family:hpmicro
diff --git a/examples/device/cdc_uac2/CMakeLists.txt b/examples/device/cdc_uac2/CMakeLists.txt
index c8c797637..fb14dc184 100644
--- a/examples/device/cdc_uac2/CMakeLists.txt
+++ b/examples/device/cdc_uac2/CMakeLists.txt
@@ -2,23 +2,20 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(cdc_uac2 C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/uac2_app.c
@@ -26,13 +23,13 @@ target_sources(${PROJECT} PUBLIC
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example... see the corresponding function
# in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
# Uncomment me to enable UART based debugging
-# pico_enable_stdio_uart(${PROJECT} 1)
+# pico_enable_stdio_uart(${PROJECT_NAME} 1)
diff --git a/examples/device/dfu/CMakeLists.txt b/examples/device/dfu/CMakeLists.txt
index 3da8ee3df..61d169460 100644
--- a/examples/device/dfu/CMakeLists.txt
+++ b/examples/device/dfu/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(dfu C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/dfu_runtime/CMakeLists.txt b/examples/device/dfu_runtime/CMakeLists.txt
index 3da8ee3df..8f6df9f75 100644
--- a/examples/device/dfu_runtime/CMakeLists.txt
+++ b/examples/device/dfu_runtime/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(dfu_runtime C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/dynamic_configuration/CMakeLists.txt b/examples/device/dynamic_configuration/CMakeLists.txt
index 8a62d6ba2..4a1b67a69 100644
--- a/examples/device/dynamic_configuration/CMakeLists.txt
+++ b/examples/device/dynamic_configuration/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(dynamic_configuration C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/hid_boot_interface/CMakeLists.txt b/examples/device/hid_boot_interface/CMakeLists.txt
index 3da8ee3df..2fee46517 100644
--- a/examples/device/hid_boot_interface/CMakeLists.txt
+++ b/examples/device/hid_boot_interface/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(hid_boot_interface C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/hid_composite/CMakeLists.txt b/examples/device/hid_composite/CMakeLists.txt
index 3da8ee3df..f1ddbd125 100644
--- a/examples/device/hid_composite/CMakeLists.txt
+++ b/examples/device/hid_composite/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(hid_composite C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/hid_composite_freertos/CMakeLists.txt b/examples/device/hid_composite_freertos/CMakeLists.txt
index 6ce9e72fe..b52373011 100644
--- a/examples/device/hid_composite_freertos/CMakeLists.txt
+++ b/examples/device/hid_composite_freertos/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(hid_composite_freertos C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example with FreeRTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} freertos)
+family_configure_device_example(${PROJECT_NAME} freertos)
diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt
index 650bf355b..01990a5b4 100644
--- a/examples/device/hid_composite_freertos/skip.txt
+++ b/examples/device/hid_composite_freertos/skip.txt
@@ -14,3 +14,4 @@ mcu:VALENTYUSB_EPTRI
mcu:RAXXX
family:broadcom_32bit
family:broadcom_64bit
+family:hpmicro
diff --git a/examples/device/hid_generic_inout/CMakeLists.txt b/examples/device/hid_generic_inout/CMakeLists.txt
index 3da8ee3df..b363c161b 100644
--- a/examples/device/hid_generic_inout/CMakeLists.txt
+++ b/examples/device/hid_generic_inout/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(hid_generic_inout C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/hid_multiple_interface/CMakeLists.txt b/examples/device/hid_multiple_interface/CMakeLists.txt
index 3da8ee3df..f4a9895d5 100644
--- a/examples/device/hid_multiple_interface/CMakeLists.txt
+++ b/examples/device/hid_multiple_interface/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(hid_multiple_interface C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/midi_test/CMakeLists.txt b/examples/device/midi_test/CMakeLists.txt
index 6a7e68c3d..09fbf20f0 100644
--- a/examples/device/midi_test/CMakeLists.txt
+++ b/examples/device/midi_test/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(midi_test C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/midi_test_freertos/CMakeLists.txt b/examples/device/midi_test_freertos/CMakeLists.txt
index 6ce9e72fe..7e5d3e89e 100644
--- a/examples/device/midi_test_freertos/CMakeLists.txt
+++ b/examples/device/midi_test_freertos/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(midi_test_freertos C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example with FreeRTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} freertos)
+family_configure_device_example(${PROJECT_NAME} freertos)
diff --git a/examples/device/midi_test_freertos/skip.txt b/examples/device/midi_test_freertos/skip.txt
index 650bf355b..01990a5b4 100644
--- a/examples/device/midi_test_freertos/skip.txt
+++ b/examples/device/midi_test_freertos/skip.txt
@@ -14,3 +14,4 @@ mcu:VALENTYUSB_EPTRI
mcu:RAXXX
family:broadcom_32bit
family:broadcom_64bit
+family:hpmicro
diff --git a/examples/device/msc_dual_lun/CMakeLists.txt b/examples/device/msc_dual_lun/CMakeLists.txt
index 3955bfb49..72a55eebc 100644
--- a/examples/device/msc_dual_lun/CMakeLists.txt
+++ b/examples/device/msc_dual_lun/CMakeLists.txt
@@ -2,13 +2,10 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(msc_dual_lun C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
@@ -18,7 +15,7 @@ endif()
if (RTOS STREQUAL zephyr)
set(EXE_NAME app)
else()
- set(EXE_NAME ${PROJECT})
+ set(EXE_NAME ${PROJECT_NAME})
add_executable(${EXE_NAME})
endif()
diff --git a/examples/device/mtp/CMakeLists.txt b/examples/device/mtp/CMakeLists.txt
index e91eb8fd9..a9f2f1a90 100644
--- a/examples/device/mtp/CMakeLists.txt
+++ b/examples/device/mtp/CMakeLists.txt
@@ -2,13 +2,10 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(mtp C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
@@ -18,7 +15,7 @@ endif()
if (RTOS STREQUAL zephyr)
set(EXE_NAME app)
else()
- set(EXE_NAME ${PROJECT})
+ set(EXE_NAME ${PROJECT_NAME})
add_executable(${EXE_NAME})
endif()
diff --git a/examples/device/net_lwip_webserver/CMakeLists.txt b/examples/device/net_lwip_webserver/CMakeLists.txt
index 87b92f4dc..9c4349d24 100644
--- a/examples/device/net_lwip_webserver/CMakeLists.txt
+++ b/examples/device/net_lwip_webserver/CMakeLists.txt
@@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_LIST_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
# Prefer the tinyusb lwip
set(LWIP ${TOP}/lib/lwip)
@@ -14,25 +12,25 @@ if (NOT EXISTS ${LWIP}/src)
endif()
if (NOT EXISTS ${LWIP}/src)
- family_example_missing_dependency(${PROJECT} "lib/lwip")
+ family_example_missing_dependency(${PROJECT_NAME} "lib/lwip")
return()
endif()
-project(${PROJECT} C CXX ASM)
+project(net_lwip_webserver C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_LIST_DIR}/src/main.c
${CMAKE_CURRENT_LIST_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_LIST_DIR}/src
${LWIP}/src/include
${LWIP}/src/include/ipv4
@@ -41,14 +39,14 @@ target_include_directories(${PROJECT} PUBLIC
)
# lib/networking sources
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${TOP}/lib/networking/dhserver.c
${TOP}/lib/networking/dnserver.c
${TOP}/lib/networking/rndis_reports.c
)
# lwip sources
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${LWIP}/src/core/altcp.c
${LWIP}/src/core/altcp_alloc.c
${LWIP}/src/core/altcp_tcp.c
@@ -86,7 +84,7 @@ target_sources(${PROJECT} PUBLIC
# due to warnings from other net source, we need to prevent error from some of the warnings options
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
- target_compile_options(${PROJECT} PUBLIC
+ target_compile_options(${PROJECT_NAME} PUBLIC
-Wno-error=null-dereference
-Wno-error=conversion
-Wno-error=sign-conversion
@@ -98,4 +96,4 @@ endif ()
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/uac2_headset/CMakeLists.txt b/examples/device/uac2_headset/CMakeLists.txt
index ced98a909..52b88aac0 100644
--- a/examples/device/uac2_headset/CMakeLists.txt
+++ b/examples/device/uac2_headset/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(uac2_headset C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/uac2_speaker_fb/CMakeLists.txt b/examples/device/uac2_speaker_fb/CMakeLists.txt
index ced98a909..cddbf6a31 100644
--- a/examples/device/uac2_speaker_fb/CMakeLists.txt
+++ b/examples/device/uac2_speaker_fb/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(uac2_speaker_fb C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/usbtmc/CMakeLists.txt b/examples/device/usbtmc/CMakeLists.txt
index d2deb72d5..6181c303b 100644
--- a/examples/device/usbtmc/CMakeLists.txt
+++ b/examples/device/usbtmc/CMakeLists.txt
@@ -2,33 +2,30 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(usbtmc C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usbtmc_app.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/video_capture/CMakeLists.txt b/examples/device/video_capture/CMakeLists.txt
index 90788fa60..1f9b851ff 100644
--- a/examples/device/video_capture/CMakeLists.txt
+++ b/examples/device/video_capture/CMakeLists.txt
@@ -2,38 +2,35 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(video_capture C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
if (FORCE_READONLY)
-target_compile_definitions(${PROJECT} PRIVATE
+target_compile_definitions(${PROJECT_NAME} PRIVATE
CFG_EXAMPLE_VIDEO_READONLY
)
endif()
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/video_capture_2ch/CMakeLists.txt b/examples/device/video_capture_2ch/CMakeLists.txt
index 90788fa60..cb1785d1f 100644
--- a/examples/device/video_capture_2ch/CMakeLists.txt
+++ b/examples/device/video_capture_2ch/CMakeLists.txt
@@ -2,38 +2,35 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(video_capture_2ch C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
if (FORCE_READONLY)
-target_compile_definitions(${PROJECT} PRIVATE
+target_compile_definitions(${PROJECT_NAME} PRIVATE
CFG_EXAMPLE_VIDEO_READONLY
)
endif()
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/webusb_serial/CMakeLists.txt b/examples/device/webusb_serial/CMakeLists.txt
index ced98a909..3b214e7c9 100644
--- a/examples/device/webusb_serial/CMakeLists.txt
+++ b/examples/device/webusb_serial/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(webusb_serial C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c
index 50794bdba..155768b76 100644
--- a/examples/device/webusb_serial/src/main.c
+++ b/examples/device/webusb_serial/src/main.c
@@ -196,6 +196,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
tud_vendor_write_str("\r\nWebUSB interface connected\r\n");
tud_vendor_write_flush();
} else {
+ tud_vendor_write_clear(); // anything left in the buffer is now thrown out
blink_interval_ms = BLINK_MOUNTED;
}
diff --git a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt
index 6ae5b5766..38c678cf2 100644
--- a/examples/dual/host_hid_to_device_cdc/CMakeLists.txt
+++ b/examples/dual/host_hid_to_device_cdc/CMakeLists.txt
@@ -2,34 +2,31 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(host_hid_to_device_cdc C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_dual_usb_example(${PROJECT} noos)
+family_configure_dual_usb_example(${PROJECT_NAME} noos)
# due to warnings from Pico-PIO-USB
if (FAMILY STREQUAL rp2040)
- target_compile_options(${PROJECT} PUBLIC
+ target_compile_options(${PROJECT_NAME} PUBLIC
-Wno-error=shadow
-Wno-error=cast-align
-Wno-error=cast-qual
diff --git a/examples/dual/host_info_to_device_cdc/CMakeLists.txt b/examples/dual/host_info_to_device_cdc/CMakeLists.txt
index ad3c5ddf0..87b5336f1 100644
--- a/examples/dual/host_info_to_device_cdc/CMakeLists.txt
+++ b/examples/dual/host_info_to_device_cdc/CMakeLists.txt
@@ -2,39 +2,36 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(host_info_to_device_cdc C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_dual_usb_example(${PROJECT} ${RTOS})
+family_configure_dual_usb_example(${PROJECT_NAME} ${RTOS})
# due to warnings from Pico-PIO-USB
if (FAMILY STREQUAL rp2040)
- target_compile_options(${PROJECT} PUBLIC
+ target_compile_options(${PROJECT_NAME} PUBLIC
-Wno-error=shadow
-Wno-error=cast-align
-Wno-error=cast-qual
diff --git a/examples/host/bare_api/CMakeLists.txt b/examples/host/bare_api/CMakeLists.txt
index 0efe84b60..4993f93b9 100644
--- a/examples/host/bare_api/CMakeLists.txt
+++ b/examples/host/bare_api/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(bare_api C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT} noos)
+family_configure_host_example(${PROJECT_NAME} noos)
diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt
index cba58f8e8..f07d63f9d 100644
--- a/examples/host/bare_api/only.txt
+++ b/examples/host/bare_api/only.txt
@@ -1,3 +1,6 @@
+family:hpmicro
+family:samd21
+family:samd5x_e5x
mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
@@ -5,18 +8,22 @@ mcu:LPC177X_8X
mcu:LPC18XX
mcu:LPC40XX
mcu:LPC43XX
-mcu:MIMXRT1XXX
+mcu:MAX3421
mcu:MIMXRT10XX
mcu:MIMXRT11XX
-mcu:RP2040
+mcu:MIMXRT1XXX
mcu:MSP432E4
-mcu:RX65X
mcu:RAXXX
-mcu:MAX3421
+mcu:RP2040
+mcu:RW61X
+mcu:RX65X
+mcu:STM32C0
mcu:STM32F4
mcu:STM32F7
+mcu:STM32G0
+mcu:STM32H5
mcu:STM32H7
mcu:STM32H7RS
mcu:STM32N6
-family:samd21
-family:samd5x_e5x
+mcu:STM32U3
+mcu:STM32U5
diff --git a/examples/host/cdc_msc_hid/CMakeLists.txt b/examples/host/cdc_msc_hid/CMakeLists.txt
index e8928cda5..3098c37fa 100644
--- a/examples/host/cdc_msc_hid/CMakeLists.txt
+++ b/examples/host/cdc_msc_hid/CMakeLists.txt
@@ -2,23 +2,20 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(cdc_msc_hid C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c
${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
@@ -26,10 +23,10 @@ target_sources(${PROJECT} PUBLIC
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT} noos)
+family_configure_host_example(${PROJECT_NAME} noos)
diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt
index cba58f8e8..f07d63f9d 100644
--- a/examples/host/cdc_msc_hid/only.txt
+++ b/examples/host/cdc_msc_hid/only.txt
@@ -1,3 +1,6 @@
+family:hpmicro
+family:samd21
+family:samd5x_e5x
mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
@@ -5,18 +8,22 @@ mcu:LPC177X_8X
mcu:LPC18XX
mcu:LPC40XX
mcu:LPC43XX
-mcu:MIMXRT1XXX
+mcu:MAX3421
mcu:MIMXRT10XX
mcu:MIMXRT11XX
-mcu:RP2040
+mcu:MIMXRT1XXX
mcu:MSP432E4
-mcu:RX65X
mcu:RAXXX
-mcu:MAX3421
+mcu:RP2040
+mcu:RW61X
+mcu:RX65X
+mcu:STM32C0
mcu:STM32F4
mcu:STM32F7
+mcu:STM32G0
+mcu:STM32H5
mcu:STM32H7
mcu:STM32H7RS
mcu:STM32N6
-family:samd21
-family:samd5x_e5x
+mcu:STM32U3
+mcu:STM32U5
diff --git a/examples/host/cdc_msc_hid_freertos/CMakeLists.txt b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt
index 78b2784fe..3ceefb3f4 100644
--- a/examples/host/cdc_msc_hid_freertos/CMakeLists.txt
+++ b/examples/host/cdc_msc_hid_freertos/CMakeLists.txt
@@ -2,23 +2,20 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(cdc_msc_hid_freertos C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/cdc_app.c
${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
@@ -26,10 +23,10 @@ target_sources(${PROJECT} PUBLIC
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT} freertos)
+family_configure_host_example(${PROJECT_NAME} freertos)
diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt
index ef0a1ac96..b0460b362 100644
--- a/examples/host/cdc_msc_hid_freertos/only.txt
+++ b/examples/host/cdc_msc_hid_freertos/only.txt
@@ -1,19 +1,25 @@
+family:espressif
+family:samd21
+family:samd5x_e5x
mcu:LPC175X_6X
mcu:LPC177X_8X
mcu:LPC18XX
mcu:LPC40XX
mcu:LPC43XX
-mcu:MIMXRT1XXX
+mcu:MAX3421
mcu:MIMXRT10XX
mcu:MIMXRT11XX
+mcu:MIMXRT1XXX
mcu:MSP432E4
+mcu:RW61X
mcu:RX65X
-mcu:MAX3421
+mcu:STM32C0
mcu:STM32F4
mcu:STM32F7
+mcu:STM32G0
+mcu:STM32H5
mcu:STM32H7
mcu:STM32H7RS
mcu:STM32N6
-family:espressif
-family:samd21
-family:samd5x_e5x
+mcu:STM32U3
+mcu:STM32U5
diff --git a/examples/host/device_info/CMakeLists.txt b/examples/host/device_info/CMakeLists.txt
index 33953233d..9b96a8af8 100644
--- a/examples/host/device_info/CMakeLists.txt
+++ b/examples/host/device_info/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(device_info C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT} noos)
+family_configure_host_example(${PROJECT_NAME} noos)
diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt
index 61a08f68d..714c1078a 100644
--- a/examples/host/device_info/only.txt
+++ b/examples/host/device_info/only.txt
@@ -1,3 +1,7 @@
+family:espressif
+family:hpmicro
+family:samd21
+family:samd5x_e5x
mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
@@ -6,18 +10,21 @@ mcu:LPC18XX
mcu:LPC40XX
mcu:LPC43XX
mcu:MAX3421
-mcu:MIMXRT1XXX
mcu:MIMXRT10XX
mcu:MIMXRT11XX
+mcu:MIMXRT1XXX
mcu:MSP432E4
+mcu:RAXXX
mcu:RP2040
+mcu:RW61X
mcu:RX65X
-mcu:RAXXX
+mcu:STM32C0
mcu:STM32F4
mcu:STM32F7
+mcu:STM32G0
+mcu:STM32H5
mcu:STM32H7
mcu:STM32H7RS
mcu:STM32N6
-family:espressif
-family:samd21
-family:samd5x_e5x
+mcu:STM32U3
+mcu:STM32U5
diff --git a/examples/host/hid_controller/CMakeLists.txt b/examples/host/hid_controller/CMakeLists.txt
index fb5faf210..287e9fb7f 100644
--- a/examples/host/hid_controller/CMakeLists.txt
+++ b/examples/host/hid_controller/CMakeLists.txt
@@ -2,32 +2,29 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(hid_controller C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/hid_app.c
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT} noos)
+family_configure_host_example(${PROJECT_NAME} noos)
diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt
index cba58f8e8..8ec2f5cfe 100644
--- a/examples/host/hid_controller/only.txt
+++ b/examples/host/hid_controller/only.txt
@@ -1,3 +1,6 @@
+family:hpmicro
+family:samd21
+family:samd5x_e5x
mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
@@ -5,18 +8,21 @@ mcu:LPC177X_8X
mcu:LPC18XX
mcu:LPC40XX
mcu:LPC43XX
-mcu:MIMXRT1XXX
+mcu:MAX3421
mcu:MIMXRT10XX
mcu:MIMXRT11XX
-mcu:RP2040
+mcu:MIMXRT1XXX
mcu:MSP432E4
-mcu:RX65X
mcu:RAXXX
-mcu:MAX3421
+mcu:RP2040
+mcu:RW61X
+mcu:RX65X
mcu:STM32F4
mcu:STM32F7
+mcu:STM32G0
+mcu:STM32H5
mcu:STM32H7
mcu:STM32H7RS
mcu:STM32N6
-family:samd21
-family:samd5x_e5x
+mcu:STM32U3
+mcu:STM32U5
diff --git a/examples/host/midi_rx/CMakeLists.txt b/examples/host/midi_rx/CMakeLists.txt
index 33953233d..62bb89e95 100644
--- a/examples/host/midi_rx/CMakeLists.txt
+++ b/examples/host/midi_rx/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(midi_rx C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT} noos)
+family_configure_host_example(${PROJECT_NAME} noos)
diff --git a/examples/host/midi_rx/only.txt b/examples/host/midi_rx/only.txt
index 133a7c9a0..9d647a340 100644
--- a/examples/host/midi_rx/only.txt
+++ b/examples/host/midi_rx/only.txt
@@ -1,7 +1,10 @@
+family:hpmicro
+family:samd21
+family:samd5x_e5x
mcu:CH32V20X
+mcu:ESP32P4
mcu:ESP32S2
mcu:ESP32S3
-mcu:ESP32P4
mcu:KINETIS_KL
mcu:LPC175X_6X
mcu:LPC177X_8X
@@ -9,17 +12,21 @@ mcu:LPC18XX
mcu:LPC40XX
mcu:LPC43XX
mcu:MAX3421
-mcu:MIMXRT1XXX
mcu:MIMXRT10XX
mcu:MIMXRT11XX
+mcu:MIMXRT1XXX
mcu:MSP432E4
+mcu:RAXXX
mcu:RP2040
+mcu:RW61X
mcu:RX65X
-mcu:RAXXX
+mcu:STM32C0
mcu:STM32F4
mcu:STM32F7
+mcu:STM32G0
+mcu:STM32H5
mcu:STM32H7
mcu:STM32H7RS
mcu:STM32N6
-family:samd21
-family:samd5x_e5x
+mcu:STM32U3
+mcu:STM32U5
diff --git a/examples/host/msc_file_explorer/CMakeLists.txt b/examples/host/msc_file_explorer/CMakeLists.txt
index e9c15b7c1..21703030c 100644
--- a/examples/host/msc_file_explorer/CMakeLists.txt
+++ b/examples/host/msc_file_explorer/CMakeLists.txt
@@ -2,23 +2,20 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(msc_file_explorer C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_app.c
${TOP}/lib/fatfs/source/ff.c
@@ -34,7 +31,7 @@ if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
endif ()
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
${TOP}/lib/fatfs/source
${TOP}/lib/embedded-cli
@@ -42,4 +39,4 @@ target_include_directories(${PROJECT} PUBLIC
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT} noos)
+family_configure_host_example(${PROJECT_NAME} noos)
diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt
index cba58f8e8..f07d63f9d 100644
--- a/examples/host/msc_file_explorer/only.txt
+++ b/examples/host/msc_file_explorer/only.txt
@@ -1,3 +1,6 @@
+family:hpmicro
+family:samd21
+family:samd5x_e5x
mcu:CH32V20X
mcu:KINETIS_KL
mcu:LPC175X_6X
@@ -5,18 +8,22 @@ mcu:LPC177X_8X
mcu:LPC18XX
mcu:LPC40XX
mcu:LPC43XX
-mcu:MIMXRT1XXX
+mcu:MAX3421
mcu:MIMXRT10XX
mcu:MIMXRT11XX
-mcu:RP2040
+mcu:MIMXRT1XXX
mcu:MSP432E4
-mcu:RX65X
mcu:RAXXX
-mcu:MAX3421
+mcu:RP2040
+mcu:RW61X
+mcu:RX65X
+mcu:STM32C0
mcu:STM32F4
mcu:STM32F7
+mcu:STM32G0
+mcu:STM32H5
mcu:STM32H7
mcu:STM32H7RS
mcu:STM32N6
-family:samd21
-family:samd5x_e5x
+mcu:STM32U3
+mcu:STM32U5
diff --git a/examples/typec/power_delivery/CMakeLists.txt b/examples/typec/power_delivery/CMakeLists.txt
index 837b4996a..728221eb4 100644
--- a/examples/typec/power_delivery/CMakeLists.txt
+++ b/examples/typec/power_delivery/CMakeLists.txt
@@ -2,31 +2,28 @@ cmake_minimum_required(VERSION 3.20)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT} C CXX ASM)
+project(power_delivery C CXX ASM)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
# Espressif has its own cmake build system
if(FAMILY STREQUAL "espressif")
return()
endif()
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/hw/bsp/BoardPresets.json b/hw/bsp/BoardPresets.json
index 5df924138..440ef8733 100644
--- a/hw/bsp/BoardPresets.json
+++ b/hw/bsp/BoardPresets.json
@@ -235,6 +235,14 @@
"inherits": "default"
},
{
+ "name": "frdm_rw612",
+ "inherits": "default"
+ },
+ {
+ "name": "hpm6750evk2",
+ "inherits": "default"
+ },
+ {
"name": "itsybitsy_m0",
"inherits": "default"
},
@@ -363,10 +371,6 @@
"inherits": "default"
},
{
- "name": "metro_nrf52840",
- "inherits": "default"
- },
- {
"name": "mimxrt1010_evk",
"inherits": "default"
},
@@ -519,10 +523,6 @@
"inherits": "default"
},
{
- "name": "raspberry_pi_pico2_riscv",
- "inherits": "default"
- },
- {
"name": "raspberry_pi_pico_w",
"inherits": "default"
},
@@ -1229,6 +1229,16 @@
"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",
+ "configurePreset": "hpm6750evk2"
+ },
+ {
"name": "itsybitsy_m0",
"description": "Build preset for the itsybitsy_m0 board",
"configurePreset": "itsybitsy_m0"
@@ -1389,11 +1399,6 @@
"configurePreset": "metro_m7_1011_sd"
},
{
- "name": "metro_nrf52840",
- "description": "Build preset for the metro_nrf52840 board",
- "configurePreset": "metro_nrf52840"
- },
- {
"name": "mimxrt1010_evk",
"description": "Build preset for the mimxrt1010_evk board",
"configurePreset": "mimxrt1010_evk"
@@ -1584,11 +1589,6 @@
"configurePreset": "raspberry_pi_pico2"
},
{
- "name": "raspberry_pi_pico2_riscv",
- "description": "Build preset for the raspberry_pi_pico2_riscv board",
- "configurePreset": "raspberry_pi_pico2_riscv"
- },
- {
"name": "raspberry_pi_pico_w",
"description": "Build preset for the raspberry_pi_pico_w board",
"configurePreset": "raspberry_pi_pico_w"
@@ -2855,6 +2855,32 @@
]
},
{
+ "name": "frdm_rw612",
+ "steps": [
+ {
+ "type": "configure",
+ "name": "frdm_rw612"
+ },
+ {
+ "type": "build",
+ "name": "frdm_rw612"
+ }
+ ]
+ },
+ {
+ "name": "hpm6750evk2",
+ "steps": [
+ {
+ "type": "configure",
+ "name": "hpm6750evk2"
+ },
+ {
+ "type": "build",
+ "name": "hpm6750evk2"
+ }
+ ]
+ },
+ {
"name": "itsybitsy_m0",
"steps": [
{
@@ -3271,19 +3297,6 @@
]
},
{
- "name": "metro_nrf52840",
- "steps": [
- {
- "type": "configure",
- "name": "metro_nrf52840"
- },
- {
- "type": "build",
- "name": "metro_nrf52840"
- }
- ]
- },
- {
"name": "mimxrt1010_evk",
"steps": [
{
@@ -3778,19 +3791,6 @@
]
},
{
- "name": "raspberry_pi_pico2_riscv",
- "steps": [
- {
- "type": "configure",
- "name": "raspberry_pi_pico2_riscv"
- },
- {
- "type": "build",
- "name": "raspberry_pi_pico2_riscv"
- }
- ]
- },
- {
"name": "raspberry_pi_pico_w",
"steps": [
{
diff --git a/hw/bsp/at32f403a_407/family.cmake b/hw/bsp/at32f403a_407/family.cmake
index 498b89c1a..7aaa9ede8 100644
--- a/hw/bsp/at32f403a_407/family.cmake
+++ b/hw/bsp/at32f403a_407/family.cmake
@@ -61,6 +61,7 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/at32f403a_407/family.mk b/hw/bsp/at32f403a_407/family.mk
index c82d402ca..f458881a3 100644
--- a/hw/bsp/at32f403a_407/family.mk
+++ b/hw/bsp/at32f403a_407/family.mk
@@ -16,6 +16,7 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
diff --git a/hw/bsp/at32f413/family.cmake b/hw/bsp/at32f413/family.cmake
index 02692daf5..33718bd1c 100644
--- a/hw/bsp/at32f413/family.cmake
+++ b/hw/bsp/at32f413/family.cmake
@@ -61,6 +61,7 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/at32f413/family.mk b/hw/bsp/at32f413/family.mk
index 9c5d867de..abcd15d11 100644
--- a/hw/bsp/at32f413/family.mk
+++ b/hw/bsp/at32f413/family.mk
@@ -16,6 +16,7 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \
$(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \
diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake
index d8c7c5327..59a96f70d 100644
--- a/hw/bsp/ch32v20x/family.cmake
+++ b/hw/bsp/ch32v20x/family.cmake
@@ -93,6 +93,7 @@ function(family_configure_example TARGET RTOS)
${TOP}/src/portable/wch/dcd_ch32_usbfs.c
${TOP}/src/portable/wch/hcd_ch32_usbfs.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk
index 16fc537ac..7042ecbb7 100644
--- a/hw/bsp/ch32v20x/family.mk
+++ b/hw/bsp/ch32v20x/family.mk
@@ -47,6 +47,7 @@ SRC_C += \
src/portable/wch/dcd_ch32_usbfs.c \
src/portable/wch/hcd_ch32_usbfs.c \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(SDK_SRC_DIR)/Core/core_riscv.c \
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \
$(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \
diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake
index 5eadcdaa9..baa8422fe 100644
--- a/hw/bsp/family_support.cmake
+++ b/hw/bsp/family_support.cmake
@@ -207,11 +207,6 @@ function(family_add_subdirectory DIR)
endif()
endfunction()
-function(family_get_project_name OUTPUT_NAME DIR)
- get_filename_component(SHORT_NAME ${DIR} NAME)
- set(${OUTPUT_NAME} ${TINYUSB_FAMILY_PROJECT_NAME_PREFIX}${SHORT_NAME} PARENT_SCOPE)
-endfunction()
-
function(family_initialize_project PROJECT DIR)
# set output suffix to .elf (skip espressif and rp2040)
if(NOT FAMILY STREQUAL "espressif" AND NOT FAMILY STREQUAL "rp2040")
diff --git a/hw/bsp/family_support.mk b/hw/bsp/family_support.mk
index db410a657..7122a7764 100644
--- a/hw/bsp/family_support.mk
+++ b/hw/bsp/family_support.mk
@@ -131,8 +131,21 @@ ifdef CPU_CORE
include ${TOP}/examples/build_system/make/cpu/$(CPU_CORE).mk
endif
-# toolchain specific
-include ${TOP}/examples/build_system/make/toolchain/arm_$(TOOLCHAIN).mk
+# toolchain specific - select based on CPU architecture
+ifdef CPU_CORE
+ ifneq (,$(filter cortex% arm%,$(CPU_CORE)))
+ # ARM/Cortex architecture
+ include ${TOP}/examples/build_system/make/toolchain/arm_$(TOOLCHAIN).mk
+ else ifneq (,$(filter rv%,$(CPU_CORE)))
+ # RISC-V architecture
+ include ${TOP}/examples/build_system/make/toolchain/riscv_$(TOOLCHAIN).mk
+ else
+ $(error Unsupported CPU_CORE architecture: $(CPU_CORE). Must start with cortex, arm, or rv)
+ endif
+else
+ # Default to ARM if CPU_CORE not specified
+ include ${TOP}/examples/build_system/make/toolchain/arm_$(TOOLCHAIN).mk
+endif
#---------------------- FreeRTOS -----------------------
FREERTOS_SRC = lib/FreeRTOS-Kernel
diff --git a/hw/bsp/hpmicro/boards/hpm6750evk2/board.c b/hw/bsp/hpmicro/boards/hpm6750evk2/board.c
new file mode 100644
index 000000000..c281356e3
--- /dev/null
+++ b/hw/bsp/hpmicro/boards/hpm6750evk2/board.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 2025 HPMicro
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "board.h"
+#include "pinmux.h"
+#include "hpm_pmp_drv.h"
+#include "hpm_pllctl_drv.h"
+#include "hpm_clock_drv.h"
+#include "hpm_sysctl_drv.h"
+#include "hpm_pcfg_drv.h"
+#include "hpm_uart_drv.h"
+#include "hpm_gpio_drv.h"
+
+/**
+ * @brief FLASH configuration option definitions:
+ * option[0]:
+ * [31:16] 0xfcf9 - FLASH configuration option tag
+ * [15:4] 0 - Reserved
+ * [3:0] option words (exclude option[0])
+ * option[1]:
+ * [31:28] Flash probe type
+ * 0 - SFDP SDR / 1 - SFDP DDR
+ * 2 - 1-4-4 Read (0xEB, 24-bit address) / 3 - 1-2-2 Read(0xBB, 24-bit address)
+ * 4 - HyperFLASH 1.8V / 5 - HyperFLASH 3V
+ * 6 - OctaBus DDR (SPI -> OPI DDR)
+ * 8 - Xccela DDR (SPI -> OPI DDR)
+ * 10 - EcoXiP DDR (SPI -> OPI DDR)
+ * [27:24] Command Pads after Power-on Reset
+ * 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
+ * [23:20] Command Pads after Configuring FLASH
+ * 0 - SPI / 1 - DPI / 2 - QPI / 3 - OPI
+ * [19:16] Quad Enable Sequence (for the device support SFDP 1.0 only)
+ * 0 - Not needed
+ * 1 - QE bit is at bit 6 in Status Register 1
+ * 2 - QE bit is at bit1 in Status Register 2
+ * 3 - QE bit is at bit7 in Status Register 2
+ * 4 - QE bit is at bit1 in Status Register 2 and should be programmed by 0x31
+ * [15:8] Dummy cycles
+ * 0 - Auto-probed / detected / default value
+ * Others - User specified value, for DDR read, the dummy cycles should be 2 * cycles on FLASH datasheet
+ * [7:4] Misc.
+ * 0 - Not used
+ * 1 - SPI mode
+ * 2 - Internal loopback
+ * 3 - External DQS
+ * [3:0] Frequency option
+ * 1 - 30MHz / 2 - 50MHz / 3 - 66MHz / 4 - 80MHz / 5 - 100MHz / 6 - 120MHz / 7 - 133MHz / 8 - 166MHz
+ *
+ * option[2] (Effective only if the bit[3:0] in option[0] > 1)
+ * [31:20] Reserved
+ * [19:16] IO voltage
+ * 0 - 3V / 1 - 1.8V
+ * [15:12] Pin group
+ * 0 - 1st group / 1 - 2nd group
+ * [11:8] Connection selection
+ * 0 - CA_CS0 / 1 - CB_CS0 / 2 - CA_CS0 + CB_CS0 (Two FLASH connected to CA and CB respectively)
+ * [7:0] Drive Strength
+ * 0 - Default value
+ * option[3] (Effective only if the bit[3:0] in option[0] > 2, required only for the QSPI NOR FLASH that not supports
+ * JESD216)
+ * [31:16] reserved
+ * [15:12] Sector Erase Command Option, not required here
+ * [11:8] Sector Size Option, not required here
+ * [7:0] Flash Size Option
+ * 0 - 4MB / 1 - 8MB / 2 - 16MB
+ */
+#if defined(FLASH_XIP) && FLASH_XIP
+__attribute__ ((section(".nor_cfg_option"), used)) const uint32_t option[4] = {0xfcf90002, 0x00000007, 0xE, 0x0};
+#endif
+
+#if defined(FLASH_UF2) && FLASH_UF2
+ATTR_PLACE_AT(".uf2_signature") __attribute__((used)) const uint32_t uf2_signature = BOARD_UF2_SIGNATURE;
+#endif
+
+
+/* static function declarations */
+static void board_turnoff_rgb_led(void);
+static void init_uart_pins(UART_Type *ptr);
+static uint32_t board_init_uart_clock(UART_Type *ptr);
+static void init_gpio_pins(void);
+static void init_usb_pins(USB_Type *ptr);
+
+/* extern function definitions */
+void board_init_clock(void)
+{
+ uint32_t cpu0_freq = clock_get_frequency(clock_cpu0);
+ if (cpu0_freq == PLLCTL_SOC_PLL_REFCLK_FREQ) {
+ /* Configure the External OSC ramp-up time: ~9ms */
+ pllctl_xtal_set_rampup_time(HPM_PLLCTL, 32UL * 1000UL * 9U);
+
+ /* Select clock setting preset1 */
+ sysctl_clock_set_preset(HPM_SYSCTL, sysctl_preset_1);
+ }
+
+ /* Add clocks to group 0 */
+ clock_add_to_group(clock_cpu0, 0);
+ clock_add_to_group(clock_mchtmr0, 0);
+ clock_add_to_group(clock_axi0, 0);
+ clock_add_to_group(clock_axi1, 0);
+ clock_add_to_group(clock_axi2, 0);
+ clock_add_to_group(clock_ahb, 0);
+ clock_add_to_group(clock_xdma, 0);
+ clock_add_to_group(clock_hdma, 0);
+ clock_add_to_group(clock_xpi0, 0);
+ clock_add_to_group(clock_xpi1, 0);
+ clock_add_to_group(clock_ram0, 0);
+ clock_add_to_group(clock_ram1, 0);
+ clock_add_to_group(clock_lmm0, 0);
+ clock_add_to_group(clock_lmm1, 0);
+ clock_add_to_group(clock_gpio, 0);
+ clock_add_to_group(clock_mot0, 0);
+ clock_add_to_group(clock_mot1, 0);
+ clock_add_to_group(clock_mot2, 0);
+ clock_add_to_group(clock_mot3, 0);
+ clock_add_to_group(clock_synt, 0);
+ clock_add_to_group(clock_ptpc, 0);
+ /* Connect Group0 to CPU0 */
+ clock_connect_group_to_cpu(0, 0);
+
+ /* Add clocks to Group1 */
+ clock_add_to_group(clock_cpu1, 1);
+ clock_add_to_group(clock_mchtmr1, 1);
+ /* Connect Group1 to CPU1 */
+ clock_connect_group_to_cpu(1, 1);
+
+ /* Bump up DCDC voltage to 1275mv */
+ pcfg_dcdc_set_voltage(HPM_PCFG, 1275);
+ pcfg_dcdc_switch_to_dcm_mode(HPM_PCFG);
+
+ if (status_success != pllctl_init_int_pll_with_freq(HPM_PLLCTL, 0, BOARD_CPU_FREQ)) {
+ printf("Failed to set pll0_clk0 to %ldHz\n", BOARD_CPU_FREQ);
+ while (1) {
+ }
+ }
+
+ clock_set_source_divider(clock_cpu0, clk_src_pll0_clk0, 1);
+ clock_set_source_divider(clock_cpu1, clk_src_pll0_clk0, 1);
+ clock_update_core_clock();
+
+ clock_set_source_divider(clock_ahb, clk_src_pll1_clk1, 2); /*200m hz*/
+ clock_set_source_divider(clock_mchtmr0, clk_src_osc24m, 1);
+ clock_set_source_divider(clock_mchtmr1, clk_src_osc24m, 1);
+}
+
+void board_init_pmp(void)
+{
+ uint32_t start_addr;
+ uint32_t end_addr;
+ uint32_t length;
+ pmp_entry_t pmp_entry[16] = {0};
+ uint8_t index = 0;
+
+ /* Init noncachable memory */
+ extern uint32_t __noncacheable_start__[];
+ extern uint32_t __noncacheable_end__[];
+ start_addr = (uint32_t) __noncacheable_start__;
+ end_addr = (uint32_t) __noncacheable_end__;
+ length = end_addr - start_addr;
+ if (length > 0) {
+ /* Ensure the address and the length are power of 2 aligned */
+ assert((length & (length - 1U)) == 0U);
+ assert((start_addr & (length - 1U)) == 0U);
+ pmp_entry[index].pmp_addr = PMP_NAPOT_ADDR(start_addr, length);
+ pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
+ pmp_entry[index].pma_addr = PMA_NAPOT_ADDR(start_addr, length);
+ pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
+ index++;
+ }
+
+ /* Init share memory */
+ extern uint32_t __share_mem_start__[];
+ extern uint32_t __share_mem_end__[];
+ start_addr = (uint32_t)__share_mem_start__;
+ end_addr = (uint32_t)__share_mem_end__;
+ length = end_addr - start_addr;
+ if (length > 0) {
+ /* Ensure the address and the length are power of 2 aligned */
+ assert((length & (length - 1U)) == 0U);
+ assert((start_addr & (length - 1U)) == 0U);
+ pmp_entry[index].pmp_addr = PMP_NAPOT_ADDR(start_addr, length);
+ pmp_entry[index].pmp_cfg.val = PMP_CFG(READ_EN, WRITE_EN, EXECUTE_EN, ADDR_MATCH_NAPOT, REG_UNLOCK);
+ pmp_entry[index].pma_addr = PMA_NAPOT_ADDR(start_addr, length);
+ pmp_entry[index].pma_cfg.val = PMA_CFG(ADDR_MATCH_NAPOT, MEM_TYPE_MEM_NON_CACHE_BUF, AMO_EN);
+ index++;
+ }
+
+ pmp_config(&pmp_entry[0], index);
+}
+
+void board_init_console(void)
+{
+ uart_config_t config = {0};
+ uint32_t freq;
+
+ /* uart needs to configure pin function before enabling clock, otherwise the level change of
+ uart rx pin when configuring pin function will cause a wrong data to be received.
+ And a uart rx dma request will be generated by default uart fifo dma trigger level. */
+ init_uart_pins((UART_Type *) BOARD_CONSOLE_UART_BASE);
+
+ freq = board_init_uart_clock((UART_Type *)BOARD_CONSOLE_UART_BASE);
+
+ uart_default_config((UART_Type *)BOARD_CONSOLE_UART_BASE, &config);
+ config.src_freq_in_hz = freq;
+ config.baudrate = BOARD_CONSOLE_UART_BAUDRATE;
+ uart_init((UART_Type *)BOARD_CONSOLE_UART_BASE, &config);
+}
+
+void board_init_gpio_pins(void)
+{
+ init_gpio_pins();
+}
+
+void board_init_led_pins(void)
+{
+ board_turnoff_rgb_led();
+ init_led_pins_as_gpio();
+ gpio_set_pin_output_with_initial(BOARD_R_GPIO_CTRL, BOARD_R_GPIO_INDEX, BOARD_R_GPIO_PIN, BOARD_LED_OFF_LEVEL);
+ gpio_set_pin_output_with_initial(BOARD_G_GPIO_CTRL, BOARD_G_GPIO_INDEX, BOARD_G_GPIO_PIN, BOARD_LED_OFF_LEVEL);
+ gpio_set_pin_output_with_initial(BOARD_B_GPIO_CTRL, BOARD_B_GPIO_INDEX, BOARD_B_GPIO_PIN, BOARD_LED_OFF_LEVEL);
+}
+
+void board_init_usb(USB_Type *ptr)
+{
+ clock_name_t usb_clk = (ptr == HPM_USB0) ? clock_usb0 : clock_usb1;
+
+ init_usb_pins(ptr);
+ clock_add_to_group(usb_clk, 0);
+}
+
+/* static function definitions */
+static void board_turnoff_rgb_led(void)
+{
+ uint32_t pad_ctl = IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(BOARD_LED_OFF_LEVEL);
+ HPM_IOC->PAD[IOC_PAD_PB11].FUNC_CTL = IOC_PB11_FUNC_CTL_GPIO_B_11;
+ HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_GPIO_B_12;
+ HPM_IOC->PAD[IOC_PAD_PB13].FUNC_CTL = IOC_PB13_FUNC_CTL_GPIO_B_13;
+
+ HPM_IOC->PAD[IOC_PAD_PB11].PAD_CTL = pad_ctl;
+ HPM_IOC->PAD[IOC_PAD_PB12].PAD_CTL = pad_ctl;
+ HPM_IOC->PAD[IOC_PAD_PB13].PAD_CTL = pad_ctl;
+}
+
+static void init_uart_pins(UART_Type *ptr)
+{
+ if (ptr == HPM_UART0) {
+ init_uart0_pins();
+ } else if (ptr == HPM_UART2) {
+ init_uart2_pins();
+ } else if (ptr == HPM_UART13) {
+ init_uart13_pins();
+ } else if (ptr == HPM_PUART) {
+ init_puart_pins();
+ }
+}
+
+static uint32_t board_init_uart_clock(UART_Type *ptr)
+{
+ uint32_t freq = 0U;
+ if (ptr == HPM_UART0) {
+ clock_add_to_group(clock_uart0, 0);
+ freq = clock_get_frequency(clock_uart0);
+ } else if (ptr == HPM_UART6) {
+ clock_add_to_group(clock_uart6, 0);
+ freq = clock_get_frequency(clock_uart6);
+ } else if (ptr == HPM_UART13) {
+ clock_add_to_group(clock_uart13, 0);
+ freq = clock_get_frequency(clock_uart13);
+ } else if (ptr == HPM_UART14) {
+ clock_add_to_group(clock_uart14, 0);
+ freq = clock_get_frequency(clock_uart14);
+ } else {
+ /* Not supported */
+ }
+ return freq;
+}
+
+static void init_gpio_pins(void)
+{
+ init_gpio_pins_with_pull_up();
+#ifdef USING_GPIO0_FOR_GPIOZ
+ init_gpio_pins_using_gpio0();
+#endif
+}
+
+static void init_usb_pins(USB_Type *ptr)
+{
+ if (ptr == HPM_USB0) {
+ init_usb0_pins();
+ } else if (ptr == HPM_USB1) {
+ init_usb1_pins();
+ }
+}
diff --git a/hw/bsp/hpmicro/boards/hpm6750evk2/board.cmake b/hw/bsp/hpmicro/boards/hpm6750evk2/board.cmake
new file mode 100644
index 000000000..b15911cb5
--- /dev/null
+++ b/hw/bsp/hpmicro/boards/hpm6750evk2/board.cmake
@@ -0,0 +1,22 @@
+set(MCU_VARIANT HPM6750xVMx)
+set(JLINK_DEVICE ${MCU_VARIANT})
+
+set(JLINK_IF jtag)
+
+set(HPM_SOC ${SDK_DIR}/soc/HPM6700/HPM6750)
+set(HPM_IP_REGS ${SDK_DIR}/soc/HPM6700/ip)
+
+set(BOARD_FLASH_SIZE 16M)
+set(BOARD_STACK_SIZE 16K)
+set(BOARD_HEAP_SIZE 16K)
+
+set(HPM_PLLCTL_DRV_FILE hpm_pllctl_drv.c)
+
+function(update_board TARGET)
+ target_compile_definitions(${TARGET} PUBLIC
+ BOARD_TUD_RHPORT=0
+ BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
+ BOARD_TUH_RHPORT=1
+ BOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED
+ )
+endfunction()
diff --git a/hw/bsp/hpmicro/boards/hpm6750evk2/board.h b/hw/bsp/hpmicro/boards/hpm6750evk2/board.h
new file mode 100644
index 000000000..0636a4722
--- /dev/null
+++ b/hw/bsp/hpmicro/boards/hpm6750evk2/board.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2021-2025 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _HPM_BOARD_H
+#define _HPM_BOARD_H
+
+#include <stdio.h>
+#include "hpm_common.h"
+#include "hpm_soc.h"
+#include "hpm_soc_feature.h"
+#include "pinmux.h"
+
+#define BOARD_NAME "hpm6750evk2"
+
+#ifndef BOARD_RUNNING_CORE
+#define BOARD_RUNNING_CORE HPM_CORE0
+#endif
+
+#define BOARD_CPU_FREQ (816000000UL)
+
+/* console section */
+#if BOARD_RUNNING_CORE == HPM_CORE0
+ #define BOARD_CONSOLE_UART_BASE HPM_UART0
+ #define BOARD_CONSOLE_UART_CLK_NAME clock_uart0
+ #define BOARD_CONSOLE_UART_IRQ IRQn_UART0
+ #define BOARD_CONSOLE_UART_TX_DMA_REQ HPM_DMA_SRC_UART0_TX
+ #define BOARD_CONSOLE_UART_RX_DMA_REQ HPM_DMA_SRC_UART0_RX
+#else
+ #define BOARD_CONSOLE_UART_BASE HPM_UART13
+ #define BOARD_CONSOLE_UART_CLK_NAME clock_uart13
+ #define BOARD_CONSOLE_UART_IRQ IRQn_UART13
+ #define BOARD_CONSOLE_UART_TX_DMA_REQ HPM_DMA_SRC_UART13_TX
+ #define BOARD_CONSOLE_UART_RX_DMA_REQ HPM_DMA_SRC_UART13_RX
+#endif
+
+#define BOARD_CONSOLE_UART_BAUDRATE (115200UL)
+
+/* sdram section */
+#define BOARD_SDRAM_ADDRESS (0x40000000UL)
+#define BOARD_SDRAM_SIZE (32 * SIZE_1MB)
+#define BOARD_SDRAM_CS FEMC_SDRAM_CS0
+#define BOARD_SDRAM_PORT_SIZE FEMC_SDRAM_PORT_SIZE_32_BITS
+#define BOARD_SDRAM_COLUMN_ADDR_BITS FEMC_SDRAM_COLUMN_ADDR_9_BITS
+#define BOARD_SDRAM_REFRESH_COUNT (8192UL)
+#define BOARD_SDRAM_REFRESH_IN_MS (64UL)
+
+#define BOARD_FLASH_BASE_ADDRESS (0x80000000UL)
+#define BOARD_FLASH_SIZE (16 << 20)
+
+/* gpio section */
+#define BOARD_R_GPIO_CTRL HPM_GPIO0
+#define BOARD_R_GPIO_INDEX GPIO_DI_GPIOB
+#define BOARD_R_GPIO_PIN 11
+#define BOARD_G_GPIO_CTRL HPM_GPIO0
+#define BOARD_G_GPIO_INDEX GPIO_DI_GPIOB
+#define BOARD_G_GPIO_PIN 12
+#define BOARD_B_GPIO_CTRL HPM_GPIO0
+#define BOARD_B_GPIO_INDEX GPIO_DI_GPIOB
+#define BOARD_B_GPIO_PIN 13
+
+#define BOARD_LED_GPIO_CTRL HPM_GPIO0
+
+#define BOARD_LED_GPIO_INDEX GPIO_DI_GPIOB
+#define BOARD_LED_GPIO_PIN 12
+#define BOARD_LED_OFF_LEVEL 0
+#define BOARD_LED_ON_LEVEL 1
+
+#define BOARD_LED_TOGGLE_RGB 1
+
+#define BOARD_APP_GPIO_INDEX GPIO_DI_GPIOZ
+#define BOARD_APP_GPIO_PIN 2
+#define BOARD_BUTTON_PRESSED_VALUE 0
+
+#define USING_GPIO0_FOR_GPIOZ
+#ifndef USING_GPIO0_FOR_GPIOZ
+#define BOARD_APP_GPIO_CTRL HPM_BGPIO
+#define BOARD_APP_GPIO_IRQ IRQn_BGPIO
+#else
+#define BOARD_APP_GPIO_CTRL HPM_GPIO0
+#define BOARD_APP_GPIO_IRQ IRQn_GPIO0_Z
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* __cplusplus */
+
+
+void board_init_clock(void);
+void board_init_pmp(void);
+void board_init_console(void);
+void board_init_gpio_pins(void);
+void board_init_led_pins(void);
+void board_init_usb(USB_Type *ptr);
+void board_print_banner(void);
+void board_print_clock_freq(void);
+
+
+#if defined(__cplusplus)
+}
+#endif /* __cplusplus */
+#endif /* _HPM_BOARD_H */
diff --git a/hw/bsp/hpmicro/boards/hpm6750evk2/board.mk b/hw/bsp/hpmicro/boards/hpm6750evk2/board.mk
new file mode 100644
index 000000000..26981ce28
--- /dev/null
+++ b/hw/bsp/hpmicro/boards/hpm6750evk2/board.mk
@@ -0,0 +1,16 @@
+MCU_VARIANT = HPM6750xVMx
+JLINK_DEVICE = ${MCU_VARIANT}
+
+JLINK_IF = jtag
+
+HPM_SOC = $(SDK_DIR)/soc/HPM6700/HPM6750
+HPM_IP_REGS = $(SDK_DIR)/soc/HPM6700/ip
+
+BOARD_FLASH_SIZE = 16M
+BOARD_STACK_SIZE = 16K
+BOARD_HEAP_SIZE = 16K
+
+BOARD_TUD_RHPORT = 0
+BOARD_TUH_RHPORT = 1
+
+HPM_PLLCTL_DRV_FILE = hpm_pllctl_drv.c
diff --git a/hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.c b/hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.c
new file mode 100644
index 000000000..7554e3a76
--- /dev/null
+++ b/hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.c
@@ -0,0 +1,862 @@
+
+/*
+ * Copyright (c) 2025 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ *
+ * Automatically generated by HPM Pinmux Tool
+ *
+ *
+ * Note:
+ * PY and PZ IOs: if any SOC pin function needs to be routed to these IOs,
+ * besides of IOC, PIOC/BIOC needs to be configured SOC_GPIO_X_xx, so that
+ * expected SoC function can be enabled on these IOs.
+ */
+
+#include "pinmux.h"
+#include "board.h"
+#include "hpm_trgm_drv.h"
+
+
+/* PY port IO needs to configure PIOC as well */
+void init_uart0_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PY07].FUNC_CTL = IOC_PY07_FUNC_CTL_UART0_RXD;
+ HPM_PIOC->PAD[IOC_PAD_PY07].FUNC_CTL = PIOC_PY07_FUNC_CTL_SOC_PY_07;
+
+ HPM_IOC->PAD[IOC_PAD_PY06].FUNC_CTL = IOC_PY06_FUNC_CTL_UART0_TXD;
+ HPM_PIOC->PAD[IOC_PAD_PY06].FUNC_CTL = PIOC_PY06_FUNC_CTL_SOC_PY_06;
+}
+
+void init_uart2_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE16].FUNC_CTL = IOC_PE16_FUNC_CTL_UART2_TXD;
+
+ HPM_IOC->PAD[IOC_PAD_PE21].FUNC_CTL = IOC_PE21_FUNC_CTL_UART2_RXD;
+}
+
+/* PZ port IO needs to configure BIOC as well */
+void init_uart13_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PZ08].FUNC_CTL = IOC_PZ08_FUNC_CTL_UART13_RXD;
+ HPM_BIOC->PAD[IOC_PAD_PZ08].FUNC_CTL = BIOC_PZ08_FUNC_CTL_SOC_PZ_08;
+
+ HPM_IOC->PAD[IOC_PAD_PZ09].FUNC_CTL = IOC_PZ09_FUNC_CTL_UART13_TXD;
+ HPM_BIOC->PAD[IOC_PAD_PZ09].FUNC_CTL = BIOC_PZ09_FUNC_CTL_SOC_PZ_09;
+}
+
+void init_puart_pins(void)
+{
+ HPM_PIOC->PAD[IOC_PAD_PY06].FUNC_CTL = PIOC_PY06_FUNC_CTL_PUART_TXD;
+
+ HPM_PIOC->PAD[IOC_PAD_PY07].FUNC_CTL = PIOC_PY07_FUNC_CTL_PUART_RXD;
+}
+
+/*
+ * PZ port IO needs to configure BIOC as well.
+ * PZ08 and PZ09 need pull up.
+ * Errata: E00029:IOC PAD_CTL register write restrictions.
+ * When the PE bit is 1, bit [3] must be set to 1,
+ * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength).
+ */
+void init_uart13_pins_as_gpio(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PZ08].FUNC_CTL = IOC_PZ08_FUNC_CTL_GPIO_Z_08;
+ HPM_BIOC->PAD[IOC_PAD_PZ08].FUNC_CTL = BIOC_PZ08_FUNC_CTL_SOC_PZ_08;
+ HPM_IOC->PAD[IOC_PAD_PZ08].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ HPM_IOC->PAD[IOC_PAD_PZ09].FUNC_CTL = IOC_PZ09_FUNC_CTL_GPIO_Z_09;
+ HPM_BIOC->PAD[IOC_PAD_PZ09].FUNC_CTL = BIOC_PZ09_FUNC_CTL_SOC_PZ_09;
+}
+
+void init_lcd0_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PB03].FUNC_CTL = IOC_PB03_FUNC_CTL_DIS0_R_0;
+
+ HPM_IOC->PAD[IOC_PAD_PB04].FUNC_CTL = IOC_PB04_FUNC_CTL_DIS0_R_1;
+
+ HPM_IOC->PAD[IOC_PAD_PB00].FUNC_CTL = IOC_PB00_FUNC_CTL_DIS0_R_2;
+
+ HPM_IOC->PAD[IOC_PAD_PA31].FUNC_CTL = IOC_PA31_FUNC_CTL_DIS0_R_3;
+
+ HPM_IOC->PAD[IOC_PAD_PA26].FUNC_CTL = IOC_PA26_FUNC_CTL_DIS0_R_4;
+
+ HPM_IOC->PAD[IOC_PAD_PA21].FUNC_CTL = IOC_PA21_FUNC_CTL_DIS0_R_5;
+
+ HPM_IOC->PAD[IOC_PAD_PA27].FUNC_CTL = IOC_PA27_FUNC_CTL_DIS0_R_6;
+
+ HPM_IOC->PAD[IOC_PAD_PA28].FUNC_CTL = IOC_PA28_FUNC_CTL_DIS0_R_7;
+
+ HPM_IOC->PAD[IOC_PAD_PB06].FUNC_CTL = IOC_PB06_FUNC_CTL_DIS0_G_0;
+
+ HPM_IOC->PAD[IOC_PAD_PB01].FUNC_CTL = IOC_PB01_FUNC_CTL_DIS0_G_1;
+
+ HPM_IOC->PAD[IOC_PAD_PA22].FUNC_CTL = IOC_PA22_FUNC_CTL_DIS0_G_2;
+
+ HPM_IOC->PAD[IOC_PAD_PA23].FUNC_CTL = IOC_PA23_FUNC_CTL_DIS0_G_3;
+
+ HPM_IOC->PAD[IOC_PAD_PA29].FUNC_CTL = IOC_PA29_FUNC_CTL_DIS0_G_4;
+
+ HPM_IOC->PAD[IOC_PAD_PA24].FUNC_CTL = IOC_PA24_FUNC_CTL_DIS0_G_5;
+
+ HPM_IOC->PAD[IOC_PAD_PA30].FUNC_CTL = IOC_PA30_FUNC_CTL_DIS0_G_6;
+
+ HPM_IOC->PAD[IOC_PAD_PA25].FUNC_CTL = IOC_PA25_FUNC_CTL_DIS0_G_7;
+
+ HPM_IOC->PAD[IOC_PAD_PB05].FUNC_CTL = IOC_PB05_FUNC_CTL_DIS0_B_0;
+
+ HPM_IOC->PAD[IOC_PAD_PB07].FUNC_CTL = IOC_PB07_FUNC_CTL_DIS0_B_1;
+
+ HPM_IOC->PAD[IOC_PAD_PB02].FUNC_CTL = IOC_PB02_FUNC_CTL_DIS0_B_2;
+
+ HPM_IOC->PAD[IOC_PAD_PA16].FUNC_CTL = IOC_PA16_FUNC_CTL_DIS0_B_3;
+
+ HPM_IOC->PAD[IOC_PAD_PA12].FUNC_CTL = IOC_PA12_FUNC_CTL_DIS0_B_4;
+
+ HPM_IOC->PAD[IOC_PAD_PA17].FUNC_CTL = IOC_PA17_FUNC_CTL_DIS0_B_5;
+
+ HPM_IOC->PAD[IOC_PAD_PA13].FUNC_CTL = IOC_PA13_FUNC_CTL_DIS0_B_6;
+
+ HPM_IOC->PAD[IOC_PAD_PA18].FUNC_CTL = IOC_PA18_FUNC_CTL_DIS0_B_7;
+
+ HPM_IOC->PAD[IOC_PAD_PA20].FUNC_CTL = IOC_PA20_FUNC_CTL_DIS0_CLK;
+
+ HPM_IOC->PAD[IOC_PAD_PA15].FUNC_CTL = IOC_PA15_FUNC_CTL_DIS0_EN;
+
+ HPM_IOC->PAD[IOC_PAD_PA19].FUNC_CTL = IOC_PA19_FUNC_CTL_DIS0_HSYNC;
+
+ HPM_IOC->PAD[IOC_PAD_PA14].FUNC_CTL = IOC_PA14_FUNC_CTL_DIS0_VSYNC;
+
+ /* PWM */
+ HPM_IOC->PAD[IOC_PAD_PB10].FUNC_CTL = IOC_PB10_FUNC_CTL_GPIO_B_10;
+
+ /* RST */
+ HPM_IOC->PAD[IOC_PAD_PB16].FUNC_CTL = IOC_PB16_FUNC_CTL_GPIO_B_16;
+
+ HPM_IOC->PAD[IOC_PAD_PZ00].FUNC_CTL = IOC_PZ00_FUNC_CTL_GPIO_Z_00;
+ HPM_BIOC->PAD[IOC_PAD_PZ00].FUNC_CTL = BIOC_PZ00_FUNC_CTL_SOC_PZ_00;
+ HPM_IOC->PAD[IOC_PAD_PZ00].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+/*
+ * Errata: E00029:IOC PAD_CTL register write restrictions.
+ * When the PE bit is 1, bit [3] must be set to 1,
+ * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength).
+ */
+void init_cap_pins(void)
+{
+ /* CAP_INT */
+ HPM_IOC->PAD[IOC_PAD_PB08].FUNC_CTL = IOC_PB08_FUNC_CTL_GPIO_B_08;
+ HPM_IOC->PAD[IOC_PAD_PB08].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(1);
+
+ /* CAP_RST */
+ HPM_IOC->PAD[IOC_PAD_PB09].FUNC_CTL = IOC_PB09_FUNC_CTL_GPIO_B_09;
+ HPM_IOC->PAD[IOC_PAD_PB09].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(1);
+}
+
+/* PZ port IO needs to configure BIOC as well */
+void init_i2c0_pins_as_gpio(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PZ11].FUNC_CTL = IOC_PZ11_FUNC_CTL_GPIO_Z_11;
+ HPM_BIOC->PAD[IOC_PAD_PZ11].FUNC_CTL = BIOC_PZ11_FUNC_CTL_SOC_PZ_11;
+
+ HPM_IOC->PAD[IOC_PAD_PZ10].FUNC_CTL = IOC_PZ10_FUNC_CTL_GPIO_Z_10;
+ HPM_BIOC->PAD[IOC_PAD_PZ10].FUNC_CTL = BIOC_PZ10_FUNC_CTL_SOC_PZ_10;
+}
+
+/* PZ port IO needs to configure BIOC as well */
+void init_i2c0_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PZ11].FUNC_CTL = IOC_PZ11_FUNC_CTL_I2C0_SCL | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_BIOC->PAD[IOC_PAD_PZ11].FUNC_CTL = BIOC_PZ11_FUNC_CTL_SOC_PZ_11;
+ HPM_IOC->PAD[IOC_PAD_PZ11].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1);
+
+ HPM_IOC->PAD[IOC_PAD_PZ10].FUNC_CTL = IOC_PZ10_FUNC_CTL_I2C0_SDA | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_BIOC->PAD[IOC_PAD_PZ10].FUNC_CTL = BIOC_PZ10_FUNC_CTL_SOC_PZ_10;
+ HPM_IOC->PAD[IOC_PAD_PZ10].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1);
+}
+
+void init_femc_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PC01].FUNC_CTL = IOC_PC01_FUNC_CTL_FEMC_DQ_16;
+
+ HPM_IOC->PAD[IOC_PAD_PC00].FUNC_CTL = IOC_PC00_FUNC_CTL_FEMC_DQ_17;
+
+ HPM_IOC->PAD[IOC_PAD_PB31].FUNC_CTL = IOC_PB31_FUNC_CTL_FEMC_DQ_18;
+
+ HPM_IOC->PAD[IOC_PAD_PB30].FUNC_CTL = IOC_PB30_FUNC_CTL_FEMC_DQ_30;
+
+ HPM_IOC->PAD[IOC_PAD_PB29].FUNC_CTL = IOC_PB29_FUNC_CTL_FEMC_DQ_31;
+
+ HPM_IOC->PAD[IOC_PAD_PB28].FUNC_CTL = IOC_PB28_FUNC_CTL_FEMC_DQ_19;
+
+ HPM_IOC->PAD[IOC_PAD_PB27].FUNC_CTL = IOC_PB27_FUNC_CTL_FEMC_DQ_20;
+
+ HPM_IOC->PAD[IOC_PAD_PB26].FUNC_CTL = IOC_PB26_FUNC_CTL_FEMC_DQ_21;
+
+ HPM_IOC->PAD[IOC_PAD_PB25].FUNC_CTL = IOC_PB25_FUNC_CTL_FEMC_DQ_28;
+
+ HPM_IOC->PAD[IOC_PAD_PB24].FUNC_CTL = IOC_PB24_FUNC_CTL_FEMC_DQ_29;
+
+ HPM_IOC->PAD[IOC_PAD_PB23].FUNC_CTL = IOC_PB23_FUNC_CTL_FEMC_DQ_22;
+
+ HPM_IOC->PAD[IOC_PAD_PB22].FUNC_CTL = IOC_PB22_FUNC_CTL_FEMC_DQ_26;
+
+ HPM_IOC->PAD[IOC_PAD_PB21].FUNC_CTL = IOC_PB21_FUNC_CTL_FEMC_DQ_27;
+
+ HPM_IOC->PAD[IOC_PAD_PB20].FUNC_CTL = IOC_PB20_FUNC_CTL_FEMC_DQ_23;
+
+ HPM_IOC->PAD[IOC_PAD_PB19].FUNC_CTL = IOC_PB19_FUNC_CTL_FEMC_DQ_24;
+
+ HPM_IOC->PAD[IOC_PAD_PB18].FUNC_CTL = IOC_PB18_FUNC_CTL_FEMC_DQ_25;
+
+ HPM_IOC->PAD[IOC_PAD_PD13].FUNC_CTL = IOC_PD13_FUNC_CTL_FEMC_DQ_14;
+
+ HPM_IOC->PAD[IOC_PAD_PD12].FUNC_CTL = IOC_PD12_FUNC_CTL_FEMC_DQ_15;
+
+ HPM_IOC->PAD[IOC_PAD_PD10].FUNC_CTL = IOC_PD10_FUNC_CTL_FEMC_DQ_12;
+
+ HPM_IOC->PAD[IOC_PAD_PD09].FUNC_CTL = IOC_PD09_FUNC_CTL_FEMC_DQ_13;
+
+ HPM_IOC->PAD[IOC_PAD_PD08].FUNC_CTL = IOC_PD08_FUNC_CTL_FEMC_DQ_00;
+
+ HPM_IOC->PAD[IOC_PAD_PD07].FUNC_CTL = IOC_PD07_FUNC_CTL_FEMC_DQ_10;
+
+ HPM_IOC->PAD[IOC_PAD_PD06].FUNC_CTL = IOC_PD06_FUNC_CTL_FEMC_DQ_11;
+
+ HPM_IOC->PAD[IOC_PAD_PD05].FUNC_CTL = IOC_PD05_FUNC_CTL_FEMC_DQ_01;
+
+ HPM_IOC->PAD[IOC_PAD_PD04].FUNC_CTL = IOC_PD04_FUNC_CTL_FEMC_DQ_08;
+
+ HPM_IOC->PAD[IOC_PAD_PD03].FUNC_CTL = IOC_PD03_FUNC_CTL_FEMC_DQ_09;
+
+ HPM_IOC->PAD[IOC_PAD_PD02].FUNC_CTL = IOC_PD02_FUNC_CTL_FEMC_DQ_04;
+
+ HPM_IOC->PAD[IOC_PAD_PD01].FUNC_CTL = IOC_PD01_FUNC_CTL_FEMC_DQ_03;
+
+ HPM_IOC->PAD[IOC_PAD_PD00].FUNC_CTL = IOC_PD00_FUNC_CTL_FEMC_DQ_02;
+
+ HPM_IOC->PAD[IOC_PAD_PC29].FUNC_CTL = IOC_PC29_FUNC_CTL_FEMC_DQ_07;
+
+ HPM_IOC->PAD[IOC_PAD_PC28].FUNC_CTL = IOC_PC28_FUNC_CTL_FEMC_DQ_06;
+
+ HPM_IOC->PAD[IOC_PAD_PC27].FUNC_CTL = IOC_PC27_FUNC_CTL_FEMC_DQ_05;
+
+ /* SRAM #WE */
+ HPM_IOC->PAD[IOC_PAD_PC21].FUNC_CTL = IOC_PC21_FUNC_CTL_FEMC_A_11;
+
+ HPM_IOC->PAD[IOC_PAD_PC17].FUNC_CTL = IOC_PC17_FUNC_CTL_FEMC_A_09;
+
+ HPM_IOC->PAD[IOC_PAD_PC15].FUNC_CTL = IOC_PC15_FUNC_CTL_FEMC_A_10;
+
+ HPM_IOC->PAD[IOC_PAD_PC12].FUNC_CTL = IOC_PC12_FUNC_CTL_FEMC_A_08;
+
+ HPM_IOC->PAD[IOC_PAD_PC11].FUNC_CTL = IOC_PC11_FUNC_CTL_FEMC_A_07;
+
+ HPM_IOC->PAD[IOC_PAD_PC10].FUNC_CTL = IOC_PC10_FUNC_CTL_FEMC_A_06;
+
+ HPM_IOC->PAD[IOC_PAD_PC09].FUNC_CTL = IOC_PC09_FUNC_CTL_FEMC_A_01;
+
+ HPM_IOC->PAD[IOC_PAD_PC08].FUNC_CTL = IOC_PC08_FUNC_CTL_FEMC_A_00;
+
+ HPM_IOC->PAD[IOC_PAD_PC07].FUNC_CTL = IOC_PC07_FUNC_CTL_FEMC_A_05;
+
+ HPM_IOC->PAD[IOC_PAD_PC06].FUNC_CTL = IOC_PC06_FUNC_CTL_FEMC_A_04;
+
+ HPM_IOC->PAD[IOC_PAD_PC05].FUNC_CTL = IOC_PC05_FUNC_CTL_FEMC_A_03;
+
+ HPM_IOC->PAD[IOC_PAD_PC04].FUNC_CTL = IOC_PC04_FUNC_CTL_FEMC_A_02;
+
+ /* SRAM #ADV */
+ HPM_IOC->PAD[IOC_PAD_PC14].FUNC_CTL = IOC_PC14_FUNC_CTL_FEMC_BA1;
+
+ HPM_IOC->PAD[IOC_PAD_PC13].FUNC_CTL = IOC_PC13_FUNC_CTL_FEMC_BA0;
+
+ HPM_IOC->PAD[IOC_PAD_PC16].FUNC_CTL = IOC_PC16_FUNC_CTL_FEMC_DQS | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+
+ HPM_IOC->PAD[IOC_PAD_PC26].FUNC_CTL = IOC_PC26_FUNC_CTL_FEMC_CLK;
+
+ HPM_IOC->PAD[IOC_PAD_PC25].FUNC_CTL = IOC_PC25_FUNC_CTL_FEMC_CKE;
+
+ HPM_IOC->PAD[IOC_PAD_PC19].FUNC_CTL = IOC_PC19_FUNC_CTL_FEMC_CS_0;
+
+ HPM_IOC->PAD[IOC_PAD_PC18].FUNC_CTL = IOC_PC18_FUNC_CTL_FEMC_RAS;
+
+ HPM_IOC->PAD[IOC_PAD_PC23].FUNC_CTL = IOC_PC23_FUNC_CTL_FEMC_CAS;
+
+ HPM_IOC->PAD[IOC_PAD_PC24].FUNC_CTL = IOC_PC24_FUNC_CTL_FEMC_WE;
+
+ /* SRAM #LB */
+ HPM_IOC->PAD[IOC_PAD_PC30].FUNC_CTL = IOC_PC30_FUNC_CTL_FEMC_DM_0;
+
+ /* SRAM #UB */
+ HPM_IOC->PAD[IOC_PAD_PC31].FUNC_CTL = IOC_PC31_FUNC_CTL_FEMC_DM_1;
+
+ HPM_IOC->PAD[IOC_PAD_PC02].FUNC_CTL = IOC_PC02_FUNC_CTL_FEMC_DM_2;
+
+ HPM_IOC->PAD[IOC_PAD_PC03].FUNC_CTL = IOC_PC03_FUNC_CTL_FEMC_DM_3;
+
+ /* SRAM #CE */
+ HPM_IOC->PAD[IOC_PAD_PC20].FUNC_CTL = IOC_PC20_FUNC_CTL_FEMC_CS_1;
+
+ /* SRAM #OE */
+ HPM_IOC->PAD[IOC_PAD_PC22].FUNC_CTL = IOC_PC22_FUNC_CTL_FEMC_A_12;
+}
+
+/*
+ * Errata: E00029:IOC PAD_CTL register write restrictions.
+ * When the PE bit is 1, bit [3] must be set to 1,
+ * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength).
+ */
+void init_gpio_pins_with_pull_up(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_GPIO_B_12;
+ HPM_IOC->PAD[IOC_PAD_PB12].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(0);
+}
+
+/*
+ * PZ port IO needs to configure BIOC as well.
+ * Errata: E00029:IOC PAD_CTL register write restrictions.
+ * When the PE bit is 1, bit [3] must be set to 1,
+ * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength).
+ */
+void init_gpio_pins_using_gpio0(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PZ02].FUNC_CTL = IOC_PZ02_FUNC_CTL_GPIO_Z_02;
+ HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = BIOC_PZ02_FUNC_CTL_SOC_PZ_02;
+ HPM_IOC->PAD[IOC_PAD_PZ02].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+/*
+ * Errata: E00029:IOC PAD_CTL register write restrictions.
+ * When the PE bit is 1, bit [3] must be set to 1,
+ * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength).
+ */
+void init_spi2_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE31].FUNC_CTL = IOC_PE31_FUNC_CTL_SPI2_CSN;
+ HPM_IOC->PAD[IOC_PAD_PE31].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ HPM_IOC->PAD[IOC_PAD_PE30].FUNC_CTL = IOC_PE30_FUNC_CTL_SPI2_MOSI;
+ HPM_IOC->PAD[IOC_PAD_PE30].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08;
+
+ HPM_IOC->PAD[IOC_PAD_PE27].FUNC_CTL = IOC_PE27_FUNC_CTL_SPI2_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_IOC->PAD[IOC_PAD_PE27].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08;
+
+ HPM_IOC->PAD[IOC_PAD_PE28].FUNC_CTL = IOC_PE28_FUNC_CTL_SPI2_MISO;
+ HPM_IOC->PAD[IOC_PAD_PE28].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08;
+}
+
+/*
+ * Errata: E00029:IOC PAD_CTL register write restrictions.
+ * When the PE bit is 1, bit [3] must be set to 1,
+ * and DS can only be selected as 0b001 (low drive strength) or 0b110 (high drive strength).
+ */
+void init_spi2_pins_with_gpio_as_cs(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE27].FUNC_CTL = IOC_PE27_FUNC_CTL_SPI2_SCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_IOC->PAD[IOC_PAD_PE27].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08;
+
+ HPM_IOC->PAD[IOC_PAD_PE28].FUNC_CTL = IOC_PE28_FUNC_CTL_SPI2_MISO;
+ HPM_IOC->PAD[IOC_PAD_PE28].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08;
+
+ HPM_IOC->PAD[IOC_PAD_PE30].FUNC_CTL = IOC_PE30_FUNC_CTL_SPI2_MOSI;
+ HPM_IOC->PAD[IOC_PAD_PE30].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08;
+
+ HPM_IOC->PAD[IOC_PAD_PE31].FUNC_CTL = IOC_PE31_FUNC_CTL_GPIO_E_31;
+ HPM_IOC->PAD[IOC_PAD_PE31].PAD_CTL = IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+void init_gptmr3_pins(void)
+{
+ /* TMR3 compare 1 */
+ HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PE24_FUNC_CTL_GPTMR3_COMP_1;
+}
+
+void init_gptmr4_pins(void)
+{
+ /* TMR4 capture 1 */
+ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_GPTMR4_CAPT_1;
+}
+
+void init_gptmr5_pins(void)
+{
+ /* TMR5 compare 2 */
+ HPM_IOC->PAD[IOC_PAD_PD24].FUNC_CTL = IOC_PD24_FUNC_CTL_TRGM2_P_10;
+
+ /* TMR5 compare 3 */
+ HPM_IOC->PAD[IOC_PAD_PD23].FUNC_CTL = IOC_PD23_FUNC_CTL_TRGM2_P_11;
+
+ trgm_output_t trgm2_io_config0 = {0};
+ trgm2_io_config0.invert = 0;
+ trgm2_io_config0.type = trgm_output_same_as_input;
+ trgm2_io_config0.input = HPM_TRGM2_INPUT_SRC_GPTMR5_OUT2;
+ trgm_output_config(HPM_TRGM2, HPM_TRGM2_OUTPUT_SRC_TRGM2_P10, &trgm2_io_config0);
+
+ trgm_enable_io_output(HPM_TRGM2, 1 << 10);
+
+ trgm_output_t trgm2_io_config1 = {0};
+ trgm2_io_config1.invert = 0;
+ trgm2_io_config1.type = trgm_output_same_as_input;
+ trgm2_io_config1.input = HPM_TRGM2_INPUT_SRC_GPTMR5_OUT3;
+ trgm_output_config(HPM_TRGM2, HPM_TRGM2_OUTPUT_SRC_TRGM2_P11, &trgm2_io_config1);
+
+ trgm_enable_io_output(HPM_TRGM2, 1 << 11);
+}
+
+void init_hall_trgm_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PD16].FUNC_CTL = IOC_PD16_FUNC_CTL_TRGM2_P_06;
+
+ HPM_IOC->PAD[IOC_PAD_PD20].FUNC_CTL = IOC_PD20_FUNC_CTL_TRGM2_P_07;
+
+ HPM_IOC->PAD[IOC_PAD_PD25].FUNC_CTL = IOC_PD25_FUNC_CTL_TRGM2_P_08;
+}
+
+void init_qei_trgm_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PD19].FUNC_CTL = IOC_PD19_FUNC_CTL_TRGM2_P_09;
+
+ HPM_IOC->PAD[IOC_PAD_PD24].FUNC_CTL = IOC_PD24_FUNC_CTL_TRGM2_P_10;
+}
+
+void init_i2s0_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PF02].FUNC_CTL = IOC_PF02_FUNC_CTL_I2S0_RXD_2;
+
+ HPM_IOC->PAD[IOC_PAD_PF03].FUNC_CTL = IOC_PF03_FUNC_CTL_I2S0_MCLK;
+
+ HPM_IOC->PAD[IOC_PAD_PF04].FUNC_CTL = IOC_PF04_FUNC_CTL_I2S0_TXD_2;
+
+ HPM_IOC->PAD[IOC_PAD_PF06].FUNC_CTL = IOC_PF06_FUNC_CTL_I2S0_BCLK;
+
+ HPM_IOC->PAD[IOC_PAD_PF09].FUNC_CTL = IOC_PF09_FUNC_CTL_I2S0_FCLK;
+}
+
+/* PY port IO needs to configure PIOC */
+void init_dao_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PY08].FUNC_CTL = IOC_PY08_FUNC_CTL_DAOR_P;
+ HPM_PIOC->PAD[IOC_PAD_PY08].FUNC_CTL = PIOC_PY08_FUNC_CTL_SOC_PY_08;
+
+ HPM_IOC->PAD[IOC_PAD_PY09].FUNC_CTL = IOC_PY09_FUNC_CTL_DAOR_N;
+ HPM_PIOC->PAD[IOC_PAD_PY09].FUNC_CTL = PIOC_PY09_FUNC_CTL_SOC_PY_09;
+}
+
+/* PY port IO needs to configure PIOC */
+void init_pdm_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PY10].FUNC_CTL = IOC_PY10_FUNC_CTL_PDM0_CLK;
+ HPM_PIOC->PAD[IOC_PAD_PY10].FUNC_CTL = PIOC_PY10_FUNC_CTL_SOC_PY_10;
+
+ HPM_IOC->PAD[IOC_PAD_PY11].FUNC_CTL = IOC_PY11_FUNC_CTL_PDM0_D_0;
+ HPM_PIOC->PAD[IOC_PAD_PY11].FUNC_CTL = PIOC_PY11_FUNC_CTL_SOC_PY_11;
+}
+
+void init_vad_pins(void)
+{
+ HPM_PIOC->PAD[IOC_PAD_PY10].FUNC_CTL = PIOC_PY10_FUNC_CTL_VAD_CLK;
+
+ HPM_PIOC->PAD[IOC_PAD_PY11].FUNC_CTL = PIOC_PY11_FUNC_CTL_VAD_DAT;
+}
+
+void init_cam_pins(void)
+{
+ /* configure rst pin function, PY port IO needs to configure PIOC */
+ HPM_IOC->PAD[IOC_PAD_PY05].FUNC_CTL = IOC_PY05_FUNC_CTL_GPIO_Y_05;
+ HPM_PIOC->PAD[IOC_PAD_PY05].FUNC_CTL = PIOC_PY05_FUNC_CTL_SOC_PY_05;
+
+ HPM_IOC->PAD[IOC_PAD_PA07].FUNC_CTL = IOC_PA07_FUNC_CTL_CAM0_D_2;
+
+ HPM_IOC->PAD[IOC_PAD_PA03].FUNC_CTL = IOC_PA03_FUNC_CTL_CAM0_D_3;
+
+ HPM_IOC->PAD[IOC_PAD_PA08].FUNC_CTL = IOC_PA08_FUNC_CTL_CAM0_D_4;
+
+ HPM_IOC->PAD[IOC_PAD_PA09].FUNC_CTL = IOC_PA09_FUNC_CTL_CAM0_D_5;
+
+ HPM_IOC->PAD[IOC_PAD_PA00].FUNC_CTL = IOC_PA00_FUNC_CTL_CAM0_D_6;
+
+ HPM_IOC->PAD[IOC_PAD_PA04].FUNC_CTL = IOC_PA04_FUNC_CTL_CAM0_D_7;
+
+ HPM_IOC->PAD[IOC_PAD_PA01].FUNC_CTL = IOC_PA01_FUNC_CTL_CAM0_D_8;
+
+ HPM_IOC->PAD[IOC_PAD_PA02].FUNC_CTL = IOC_PA02_FUNC_CTL_CAM0_D_9;
+
+ HPM_IOC->PAD[IOC_PAD_PA10].FUNC_CTL = IOC_PA10_FUNC_CTL_CAM0_XCLK;
+
+ HPM_IOC->PAD[IOC_PAD_PA05].FUNC_CTL = IOC_PA05_FUNC_CTL_CAM0_HSYNC;
+
+ HPM_IOC->PAD[IOC_PAD_PA06].FUNC_CTL = IOC_PA06_FUNC_CTL_CAM0_VSYNC;
+
+ HPM_IOC->PAD[IOC_PAD_PA11].FUNC_CTL = IOC_PA11_FUNC_CTL_CAM0_PIXCLK;
+}
+
+void init_butn_pins(void)
+{
+ HPM_BIOC->PAD[IOC_PAD_PZ02].FUNC_CTL = BIOC_PZ02_FUNC_CTL_PBUTN;
+
+ HPM_BIOC->PAD[IOC_PAD_PZ03].FUNC_CTL = BIOC_PZ03_FUNC_CTL_WBUTN;
+
+ HPM_BIOC->PAD[IOC_PAD_PZ04].FUNC_CTL = BIOC_PZ04_FUNC_CTL_PLED;
+
+ HPM_BIOC->PAD[IOC_PAD_PZ05].FUNC_CTL = BIOC_PZ05_FUNC_CTL_WLED;
+}
+
+void init_acmp_pins(void)
+{
+ /* configure to ACMP_COMP_1(ALT16) function */
+ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_ACMP_COMP_1;
+
+ /* configure to CMP1_INP7 function */
+ HPM_IOC->PAD[IOC_PAD_PE23].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK;
+
+ /* configure to CMP1_INN6 function */
+ HPM_IOC->PAD[IOC_PAD_PE21].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK;
+}
+
+void init_enet0_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PF00].FUNC_CTL = IOC_PF00_FUNC_CTL_GPIO_F_00;
+
+ HPM_IOC->PAD[IOC_PAD_PE23].FUNC_CTL = IOC_PE23_FUNC_CTL_ETH0_MDIO;
+
+ HPM_IOC->PAD[IOC_PAD_PE22].FUNC_CTL = IOC_PE22_FUNC_CTL_ETH0_MDC;
+
+ HPM_IOC->PAD[IOC_PAD_PD31].FUNC_CTL = IOC_PD31_FUNC_CTL_ETH0_RXD_0;
+
+ HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_ETH0_RXD_1;
+
+ HPM_IOC->PAD[IOC_PAD_PE02].FUNC_CTL = IOC_PE02_FUNC_CTL_ETH0_RXD_2;
+
+ HPM_IOC->PAD[IOC_PAD_PE07].FUNC_CTL = IOC_PE07_FUNC_CTL_ETH0_RXD_3;
+
+ HPM_IOC->PAD[IOC_PAD_PE03].FUNC_CTL = IOC_PE03_FUNC_CTL_ETH0_RXCK;
+
+ HPM_IOC->PAD[IOC_PAD_PD30].FUNC_CTL = IOC_PD30_FUNC_CTL_ETH0_RXDV;
+
+ HPM_IOC->PAD[IOC_PAD_PE06].FUNC_CTL = IOC_PE06_FUNC_CTL_ETH0_TXD_0;
+
+ HPM_IOC->PAD[IOC_PAD_PD29].FUNC_CTL = IOC_PD29_FUNC_CTL_ETH0_TXD_1;
+
+ HPM_IOC->PAD[IOC_PAD_PD28].FUNC_CTL = IOC_PD28_FUNC_CTL_ETH0_TXD_2;
+
+ HPM_IOC->PAD[IOC_PAD_PE05].FUNC_CTL = IOC_PE05_FUNC_CTL_ETH0_TXD_3;
+
+ HPM_IOC->PAD[IOC_PAD_PE01].FUNC_CTL = IOC_PE01_FUNC_CTL_ETH0_TXCK;
+
+ HPM_IOC->PAD[IOC_PAD_PE00].FUNC_CTL = IOC_PE00_FUNC_CTL_ETH0_TXEN;
+}
+
+void init_enet1_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE26].FUNC_CTL = IOC_PE26_FUNC_CTL_GPIO_E_26;
+
+ HPM_IOC->PAD[IOC_PAD_PD11].FUNC_CTL = IOC_PD11_FUNC_CTL_ETH1_MDC;
+
+ HPM_IOC->PAD[IOC_PAD_PD14].FUNC_CTL = IOC_PD14_FUNC_CTL_ETH1_MDIO;
+
+ HPM_IOC->PAD[IOC_PAD_PE20].FUNC_CTL = IOC_PE20_FUNC_CTL_ETH1_RXD_0;
+
+ HPM_IOC->PAD[IOC_PAD_PE18].FUNC_CTL = IOC_PE18_FUNC_CTL_ETH1_RXD_1;
+
+ HPM_IOC->PAD[IOC_PAD_PE15].FUNC_CTL = IOC_PE15_FUNC_CTL_ETH1_RXDV;
+
+ HPM_IOC->PAD[IOC_PAD_PE19].FUNC_CTL = IOC_PE19_FUNC_CTL_ETH1_TXD_0;
+
+ HPM_IOC->PAD[IOC_PAD_PE17].FUNC_CTL = IOC_PE17_FUNC_CTL_ETH1_TXD_1;
+
+ HPM_IOC->PAD[IOC_PAD_PE14].FUNC_CTL = IOC_PE14_FUNC_CTL_ETH1_TXEN;
+
+ HPM_IOC->PAD[IOC_PAD_PE16].FUNC_CTL = IOC_PE16_FUNC_CTL_ETH1_REFCLK | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+}
+
+void init_pwm2_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PD28].FUNC_CTL = IOC_PD28_FUNC_CTL_PWM2_P_5;
+
+ HPM_IOC->PAD[IOC_PAD_PD29].FUNC_CTL = IOC_PD29_FUNC_CTL_PWM2_P_4;
+
+ HPM_IOC->PAD[IOC_PAD_PD30].FUNC_CTL = IOC_PD30_FUNC_CTL_PWM2_P_1;
+
+ HPM_IOC->PAD[IOC_PAD_PD31].FUNC_CTL = IOC_PD31_FUNC_CTL_PWM2_P_0;
+
+ HPM_IOC->PAD[IOC_PAD_PE03].FUNC_CTL = IOC_PE03_FUNC_CTL_PWM2_P_3;
+
+ HPM_IOC->PAD[IOC_PAD_PE04].FUNC_CTL = IOC_PE04_FUNC_CTL_PWM2_P_2;
+}
+
+void init_pwm3_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE17].FUNC_CTL = IOC_PE17_FUNC_CTL_PWM3_P_6;
+
+ HPM_IOC->PAD[IOC_PAD_PE18].FUNC_CTL = IOC_PE18_FUNC_CTL_PWM3_P_7;
+}
+
+void init_adc12_pins(void)
+{
+ /* ADC0.VIN11 */
+ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK;
+}
+
+void init_adc16_pins(void)
+{
+ /* ADC3.INA2 */
+ HPM_IOC->PAD[IOC_PAD_PE29].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK;
+}
+
+void init_adc_bldc_pins(void)
+{
+ /* ADC0.VINP7 */
+ HPM_IOC->PAD[IOC_PAD_PE21].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK;
+
+ /* ADC1.VINP10 */
+ HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK;
+
+ /* ADC2.VINP11 */
+ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK;
+}
+
+void init_usb0_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PF10].FUNC_CTL = IOC_PF10_FUNC_CTL_USB0_ID;
+
+ HPM_IOC->PAD[IOC_PAD_PF08].FUNC_CTL = IOC_PF08_FUNC_CTL_USB0_OC;
+}
+
+void init_usb1_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PF07].FUNC_CTL = IOC_PF07_FUNC_CTL_USB1_ID;
+
+ HPM_IOC->PAD[IOC_PAD_PF05].FUNC_CTL = IOC_PF05_FUNC_CTL_USB1_OC;
+}
+
+void init_can0_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PB15].FUNC_CTL = IOC_PB15_FUNC_CTL_CAN0_TXD;
+
+ HPM_IOC->PAD[IOC_PAD_PB17].FUNC_CTL = IOC_PB17_FUNC_CTL_CAN0_RXD;
+}
+
+void init_mcan0_transceiver_phy_pin(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PB14].FUNC_CTL = IOC_PB14_FUNC_CTL_GPIO_B_14;
+}
+
+void init_sdxc1_cmd_pin_enable_1v8_enable_opendrain(void)
+{
+ /* SDXC1.CMD */
+ HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_SDC1_CMD | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_OD_SET(1);
+}
+
+void init_sdxc1_cmd_pin_enable_1v8_disable_opendrain(void)
+{
+ /* SDXC1.CMD */
+ HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_SDC1_CMD | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_OD_SET(0);
+}
+
+void init_sdxc1_cmd_pin_disable_1v8_enable_opendrain(void)
+{
+ /* SDXC1.CMD */
+ HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_SDC1_CMD | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_OD_SET(1);
+}
+
+void init_sdxc1_cmd_pin_disable_1v8_disable_opendrain(void)
+{
+ /* SDXC1.CMD */
+ HPM_IOC->PAD[IOC_PAD_PD21].FUNC_CTL = IOC_PD21_FUNC_CTL_SDC1_CMD | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_IOC->PAD[IOC_PAD_PD21].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1) | IOC_PAD_PAD_CTL_OD_SET(0);
+}
+
+void init_sdxc1_cd_pin(void)
+{
+ /* SDXC1.CDN */
+ HPM_IOC->PAD[IOC_PAD_PD15].FUNC_CTL = IOC_PD15_FUNC_CTL_GPIO_D_15;
+ HPM_IOC->PAD[IOC_PAD_PD15].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+void init_sdxc1_clk_data_pins_enable_1v8(void)
+{
+ /* SDXC1.CLK */
+ HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_SDC1_CLK;
+ HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.DATA0 */
+ HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_SDC1_DATA_0;
+ HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+void init_sdxc1_clk_data_pins_disable_1v8(void)
+{
+ /* SDXC1.CLK */
+ HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_SDC1_CLK;
+ HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.DATA0 */
+ HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_SDC1_DATA_0;
+ HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+void init_sdxc1_clk_data_pins_width4_enable_1v8(void)
+{
+ /* SDXC1.DATA1 */
+ HPM_IOC->PAD[IOC_PAD_PD17].FUNC_CTL = IOC_PD17_FUNC_CTL_SDC1_DATA_1;
+ HPM_IOC->PAD[IOC_PAD_PD17].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.DATA2 */
+ HPM_IOC->PAD[IOC_PAD_PD27].FUNC_CTL = IOC_PD27_FUNC_CTL_SDC1_DATA_2;
+ HPM_IOC->PAD[IOC_PAD_PD27].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.DATA3 */
+ HPM_IOC->PAD[IOC_PAD_PD26].FUNC_CTL = IOC_PD26_FUNC_CTL_SDC1_DATA_3;
+ HPM_IOC->PAD[IOC_PAD_PD26].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.CLK */
+ HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_SDC1_CLK;
+ HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.DATA0 */
+ HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_SDC1_DATA_0;
+ HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+void init_sdxc1_clk_data_pins_width4_disable_1v8(void)
+{
+ /* SDXC1.DATA1 */
+ HPM_IOC->PAD[IOC_PAD_PD17].FUNC_CTL = IOC_PD17_FUNC_CTL_SDC1_DATA_1;
+ HPM_IOC->PAD[IOC_PAD_PD17].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.DATA2 */
+ HPM_IOC->PAD[IOC_PAD_PD27].FUNC_CTL = IOC_PD27_FUNC_CTL_SDC1_DATA_2;
+ HPM_IOC->PAD[IOC_PAD_PD27].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.DATA3 */
+ HPM_IOC->PAD[IOC_PAD_PD26].FUNC_CTL = IOC_PD26_FUNC_CTL_SDC1_DATA_3;
+ HPM_IOC->PAD[IOC_PAD_PD26].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.CLK */
+ HPM_IOC->PAD[IOC_PAD_PD22].FUNC_CTL = IOC_PD22_FUNC_CTL_SDC1_CLK;
+ HPM_IOC->PAD[IOC_PAD_PD22].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+
+ /* SDXC1.DATA0 */
+ HPM_IOC->PAD[IOC_PAD_PD18].FUNC_CTL = IOC_PD18_FUNC_CTL_SDC1_DATA_0;
+ HPM_IOC->PAD[IOC_PAD_PD18].PAD_CTL = IOC_PAD_PAD_CTL_MS_SET(0) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_DS_SET(6) | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+void init_sdxc1_pwr_pin(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PC20].FUNC_CTL = IOC_PC20_FUNC_CTL_GPIO_C_20;
+ HPM_IOC->PAD[IOC_PAD_PC20].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+void init_clk_obs_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PB02].FUNC_CTL = IOC_PB02_FUNC_CTL_SYSCTL_CLK_OBS_0;
+}
+
+void init_rgb_pwm_pins(void)
+{
+ /* Red */
+ HPM_IOC->PAD[IOC_PAD_PB11].FUNC_CTL = IOC_PB11_FUNC_CTL_TRGM1_P_01;
+
+ /* Green */
+ HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_TRGM0_P_06;
+
+ /* BLUE */
+ HPM_IOC->PAD[IOC_PAD_PB13].FUNC_CTL = IOC_PB13_FUNC_CTL_TRGM1_P_03;
+}
+
+void init_led_pins_as_gpio(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PB11].FUNC_CTL = IOC_PB11_FUNC_CTL_GPIO_B_11;
+
+ HPM_IOC->PAD[IOC_PAD_PB12].FUNC_CTL = IOC_PB12_FUNC_CTL_GPIO_B_12;
+
+ HPM_IOC->PAD[IOC_PAD_PB13].FUNC_CTL = IOC_PB13_FUNC_CTL_GPIO_B_13;
+}
+
+void init_enet_pps_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PF05].FUNC_CTL = IOC_PF05_FUNC_CTL_ETH0_EVTO_0;
+}
+
+void init_enet_pps_capture_pins(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_ETH0_EVTI_1;
+}
+
+void init_tamper_pins(void)
+{
+ HPM_BIOC->PAD[IOC_PAD_PZ08].FUNC_CTL = BIOC_PZ08_FUNC_CTL_TAMP_08 | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+
+ HPM_BIOC->PAD[IOC_PAD_PZ09].FUNC_CTL = BIOC_PZ09_FUNC_CTL_TAMP_09;
+
+ HPM_BIOC->PAD[IOC_PAD_PZ10].FUNC_CTL = BIOC_PZ10_FUNC_CTL_TAMP_10;
+}
+
+/* for uart_rx_line_status case, need to a gpio pin to sent break signal */
+void init_uart_break_signal_pin(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE31].FUNC_CTL = IOC_PE31_FUNC_CTL_GPIO_E_31;
+ HPM_IOC->PAD[IOC_PAD_PE31].PAD_CTL = IOC_PAD_PAD_CTL_DS_SET(1) | IOC_PAD_PAD_CTL_PE_SET(1) | 0x08 | IOC_PAD_PAD_CTL_PS_SET(1);
+}
+
+void init_gptmr3_channel_pin_as_output(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PE24_FUNC_CTL_GPTMR3_COMP_1;
+}
+
+void init_gptmr4_channel_pin_as_capture(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE25].FUNC_CTL = IOC_PE25_FUNC_CTL_GPTMR4_CAPT_1;
+}
+
+void init_gptmr5_channel2_pin_as_output(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PD24].FUNC_CTL = IOC_PD24_FUNC_CTL_TRGM2_P_10;
+
+ trgm_output_t trgm2_io_config0 = {0};
+ trgm2_io_config0.invert = 0;
+ trgm2_io_config0.type = trgm_output_same_as_input;
+ trgm2_io_config0.input = HPM_TRGM2_INPUT_SRC_GPTMR5_OUT2;
+ trgm_output_config(HPM_TRGM2, HPM_TRGM2_OUTPUT_SRC_TRGM2_P10, &trgm2_io_config0);
+
+ trgm_enable_io_output(HPM_TRGM2, 1 << 10);
+}
+
+void init_gptmr5_channel3_pin_as_output(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PD23].FUNC_CTL = IOC_PD23_FUNC_CTL_TRGM2_P_11;
+
+ trgm_output_t trgm2_io_config0 = {0};
+ trgm2_io_config0.invert = 0;
+ trgm2_io_config0.type = trgm_output_same_as_input;
+ trgm2_io_config0.input = HPM_TRGM2_INPUT_SRC_GPTMR5_OUT3;
+ trgm_output_config(HPM_TRGM2, HPM_TRGM2_OUTPUT_SRC_TRGM2_P11, &trgm2_io_config0);
+
+ trgm_enable_io_output(HPM_TRGM2, 1 << 11);
+}
+
+void init_clk_ref_pin(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE24].FUNC_CTL = IOC_PE24_FUNC_CTL_SOC_REF1;
+}
+
+void init_brownout_indicate_pin(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PE30].FUNC_CTL = IOC_PE30_FUNC_CTL_GPIO_E_30;
+}
+
+void board_init_i2c_eeprom_pin(void)
+{
+ HPM_IOC->PAD[IOC_PAD_PZ11].FUNC_CTL = IOC_PZ11_FUNC_CTL_I2C0_SCL | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_BIOC->PAD[IOC_PAD_PZ11].FUNC_CTL = BIOC_PZ11_FUNC_CTL_SOC_PZ_11;
+ HPM_IOC->PAD[IOC_PAD_PZ11].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1);
+
+ HPM_IOC->PAD[IOC_PAD_PZ10].FUNC_CTL = IOC_PZ10_FUNC_CTL_I2C0_SDA | IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
+ HPM_BIOC->PAD[IOC_PAD_PZ10].FUNC_CTL = BIOC_PZ10_FUNC_CTL_SOC_PZ_10;
+ HPM_IOC->PAD[IOC_PAD_PZ10].PAD_CTL = IOC_PAD_PAD_CTL_OD_SET(1);
+}
diff --git a/hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.h b/hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.h
new file mode 100644
index 000000000..460feded2
--- /dev/null
+++ b/hw/bsp/hpmicro/boards/hpm6750evk2/pinmux.h
@@ -0,0 +1,89 @@
+
+/*
+ * Copyright (c) 2025 HPMicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ *
+ * Automatically generated by HPM Pinmux Tool
+ *
+ *
+ * Note:
+ * PY and PZ IOs: if any SOC pin function needs to be routed to these IOs,
+ * besides of IOC, PIOC/BIOC needs to be configured SOC_GPIO_X_xx, so that
+ * expected SoC function can be enabled on these IOs.
+ */
+
+#ifndef HPM_PINMUX_H
+#define HPM_PINMUX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void init_uart0_pins(void);
+void init_uart2_pins(void);
+void init_uart13_pins(void);
+void init_puart_pins(void);
+void init_uart13_pins_as_gpio(void);
+void init_lcd0_pins(void);
+void init_cap_pins(void);
+void init_i2c0_pins_as_gpio(void);
+void init_i2c0_pins(void);
+void init_femc_pins(void);
+void init_gpio_pins_with_pull_up(void);
+void init_gpio_pins_using_gpio0(void);
+void init_spi2_pins(void);
+void init_spi2_pins_with_gpio_as_cs(void);
+void init_gptmr3_pins(void);
+void init_gptmr4_pins(void);
+void init_gptmr5_pins(void);
+void init_hall_trgm_pins(void);
+void init_qei_trgm_pins(void);
+void init_i2s0_pins(void);
+void init_dao_pins(void);
+void init_pdm_pins(void);
+void init_vad_pins(void);
+void init_cam_pins(void);
+void init_butn_pins(void);
+void init_acmp_pins(void);
+void init_enet0_pins(void);
+void init_enet1_pins(void);
+void init_pwm2_pins(void);
+void init_pwm3_pins(void);
+void init_adc12_pins(void);
+void init_adc16_pins(void);
+void init_adc_bldc_pins(void);
+void init_usb0_pins(void);
+void init_usb1_pins(void);
+void init_can0_pins(void);
+void init_mcan0_transceiver_phy_pin(void);
+void init_sdxc1_cmd_pin_enable_1v8_enable_opendrain(void);
+void init_sdxc1_cmd_pin_enable_1v8_disable_opendrain(void);
+void init_sdxc1_cmd_pin_disable_1v8_enable_opendrain(void);
+void init_sdxc1_cmd_pin_disable_1v8_disable_opendrain(void);
+void init_sdxc1_cd_pin(void);
+void init_sdxc1_clk_data_pins_enable_1v8(void);
+void init_sdxc1_clk_data_pins_disable_1v8(void);
+void init_sdxc1_clk_data_pins_width4_enable_1v8(void);
+void init_sdxc1_clk_data_pins_width4_disable_1v8(void);
+void init_sdxc1_pwr_pin(void);
+void init_clk_obs_pins(void);
+void init_rgb_pwm_pins(void);
+void init_led_pins_as_gpio(void);
+void init_enet_pps_pins(void);
+void init_enet_pps_capture_pins(void);
+void init_tamper_pins(void);
+void init_uart_break_signal_pin(void);
+void init_gptmr3_channel_pin_as_output(void);
+void init_gptmr4_channel_pin_as_capture(void);
+void init_gptmr5_channel2_pin_as_output(void);
+void init_gptmr5_channel3_pin_as_output(void);
+void init_clk_ref_pin(void);
+void init_brownout_indicate_pin(void);
+void board_init_i2c_eeprom_pin(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* HPM_PINMUX_H */
diff --git a/hw/bsp/hpmicro/family.c b/hw/bsp/hpmicro/family.c
new file mode 100644
index 000000000..ffec2523a
--- /dev/null
+++ b/hw/bsp/hpmicro/family.c
@@ -0,0 +1,115 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018, hathach (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.
+ */
+
+/* metadata:
+ manufacturer: HPMicro
+*/
+
+#include "bsp/board_api.h"
+#include "board.h"
+#include "hpm_clock_drv.h"
+#include "hpm_uart_drv.h"
+#include "hpm_gpio_drv.h"
+#include "hpm_romapi.h"
+
+
+//--------------------------------------------------------------------+
+// Board porting API
+//--------------------------------------------------------------------+
+
+// Initialize on-board peripherals : led, button, uart and USB
+void board_init(void) {
+ board_init_clock();
+ board_init_pmp();
+
+ board_init_usb(HPM_USB0);
+#ifdef HPM_USB1
+ board_init_usb(HPM_USB1);
+#endif
+
+ board_init_console();
+ board_init_gpio_pins();
+ board_init_led_pins();
+}
+
+//--------------------------------------------------------------------+
+// USB Interrupt Handler
+//--------------------------------------------------------------------+
+SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usb0)
+void isr_usb0(void) {
+ tusb_int_handler(0, true);
+}
+
+#ifdef HPM_USB1_BASE
+SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usb1)
+void isr_usb1(void) {
+ tusb_int_handler(1, true);
+}
+#endif
+
+void board_led_write(bool state) {
+ if (state) {
+ gpio_write_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN, BOARD_LED_ON_LEVEL);
+ } else {
+ gpio_write_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN, BOARD_LED_OFF_LEVEL);
+ }
+}
+
+uint32_t board_button_read(void) {
+ return (gpio_read_pin(BOARD_APP_GPIO_CTRL, BOARD_APP_GPIO_INDEX, BOARD_APP_GPIO_PIN) == BOARD_BUTTON_PRESSED_VALUE) ? 1 : 0;
+}
+
+// Get characters from UART. Return number of read bytes
+int board_uart_read(uint8_t *buf, int len) {
+ int count = 0;
+ hpm_stat_t status;
+
+ while (count < len) {
+ status = uart_try_receive_byte((UART_Type *)BOARD_CONSOLE_UART_BASE, (uint8_t *)&buf[count]);
+ if (status == status_success) {
+ count++;
+ } else {
+ break;
+ }
+ }
+
+ return count;
+}
+
+// Send characters to UART. Return number of sent bytes
+int board_uart_write(void const *buf, int len) {
+ uart_send_data((UART_Type *)BOARD_CONSOLE_UART_BASE, (uint8_t const *)buf, len);
+
+ return len;
+}
+
+#if CFG_TUSB_OS == OPT_OS_NONE
+// Get current milliseconds, must be implemented when no RTOS is used
+uint32_t board_millis(void) {
+ return (hpm_csr_get_core_cycle() / clock_get_core_clock_ticks_per_ms());
+}
+
+#endif
diff --git a/hw/bsp/hpmicro/family.cmake b/hw/bsp/hpmicro/family.cmake
new file mode 100644
index 000000000..1289859d3
--- /dev/null
+++ b/hw/bsp/hpmicro/family.cmake
@@ -0,0 +1,129 @@
+include_guard()
+
+set(SDK_DIR ${TOP}/hw/mcu/hpmicro/hpm_sdk)
+
+# include board specific
+include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake)
+
+# toolchain set up
+if (NOT DEFINED CMAKE_SYSTEM_CPU)
+ set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor")
+endif ()
+set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake)
+
+set(FAMILY_MCUS HPMICRO CACHE INTERNAL "")
+
+#------------------------------------
+# Startup & Linker script
+#------------------------------------
+if (NOT DEFINED LD_FILE_GNU)
+set(LD_FILE_GNU ${HPM_SOC}/toolchains/gcc/flash_xip.ld)
+endif ()
+set(LD_FILE_Clang ${LD_FILE_GNU})
+
+set(STARTUP_FILE_GNU ${HPM_SOC}/toolchains/gcc/start.S)
+set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
+
+#------------------------------------
+# Board Target
+#------------------------------------
+function(family_add_board BOARD_TARGET)
+ add_library(${BOARD_TARGET} STATIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/pinmux.c
+ ${HPM_SOC}/boot/hpm_bootheader.c
+ ${HPM_SOC}/toolchains/gcc/initfini.c
+ ${HPM_SOC}/toolchains/reset.c
+ ${HPM_SOC}/toolchains/trap.c
+ ${HPM_SOC}/system.c
+ ${HPM_SOC}/hpm_sysctl_drv.c
+ ${HPM_SOC}/hpm_clock_drv.c
+ ${HPM_SOC}/hpm_otp_drv.c
+ ${SDK_DIR}/arch/riscv/l1c/hpm_l1c_drv.c
+ ${SDK_DIR}/drivers/src/hpm_gpio_drv.c
+ ${SDK_DIR}/drivers/src/hpm_uart_drv.c
+ ${SDK_DIR}/drivers/src/hpm_usb_drv.c
+ ${SDK_DIR}/drivers/src/hpm_pcfg_drv.c
+ ${SDK_DIR}/drivers/src/hpm_pmp_drv.c
+ ${SDK_DIR}/drivers/src/${HPM_PLLCTL_DRV_FILE}
+ )
+
+ target_compile_definitions(${BOARD_TARGET} PUBLIC
+ FLASH_XIP
+ [=[CFG_TUD_MEM_SECTION=__attribute__((section(".noncacheable.non_init")))]=]
+ [=[CFG_TUH_MEM_SECTION=__attribute__((section(".noncacheable.non_init")))]=]
+ )
+
+ target_include_directories(${BOARD_TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}/board
+ ${HPM_SOC}
+ ${HPM_IP_REGS}
+ ${HPM_SOC}/boot
+ ${HPM_SOC}/toolchains
+ ${HPM_SOC}/toolchains/gcc
+ ${SDK_DIR}/arch
+ ${SDK_DIR}/arch/riscv/intc
+ ${SDK_DIR}/arch/riscv/l1c
+ ${SDK_DIR}/drivers/inc
+ )
+
+ update_board(${BOARD_TARGET})
+endfunction()
+
+#------------------------------------
+# Functions
+#------------------------------------
+function(family_configure_example TARGET RTOS)
+ family_configure_common(${TARGET} ${RTOS})
+ family_add_tinyusb(${TARGET} OPT_MCU_HPM)
+
+ target_sources(${TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
+ ${SDK_DIR}/utils/hpm_sbrk.c
+ ${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_${CMAKE_C_COMPILER_ID}}
+ )
+ target_include_directories(${TARGET} PUBLIC
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
+ ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
+ ${TOP}/src/portable/chipidea/ci_hs
+ )
+
+ if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
+ target_link_options(${TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ -nostartfiles
+ --specs=nosys.specs --specs=nano.specs
+ -Wl,--defsym,_flash_size=${BOARD_FLASH_SIZE}
+ -Wl,--defsym,_stack_size=${BOARD_STACK_SIZE}
+ -Wl,--defsym,_heap_size=${BOARD_HEAP_SIZE}
+ )
+ elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ target_link_options(${TARGET} PUBLIC
+ "LINKER:--script=${LD_FILE_GNU}"
+ -Wl,--defsym,_flash_size=${BOARD_FLASH_SIZE}
+ -Wl,--defsym,_stack_size=${BOARD_STACK_SIZE}
+ -Wl,--defsym,_heap_size=${BOARD_HEAP_SIZE}
+ )
+ 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
+ ${SDK_DIR}/utils/hpm_sbrk.c
+ PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes -Wno-cast-align -Wno-discarded-qualifiers"
+ )
+ endif ()
+ set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES
+ SKIP_LINTING ON
+ COMPILE_OPTIONS -w)
+
+ # Flashing
+ family_add_bin_hex(${TARGET})
+ family_flash_jlink(${TARGET})
+endfunction()
diff --git a/hw/bsp/hpmicro/family.mk b/hw/bsp/hpmicro/family.mk
new file mode 100644
index 000000000..f8cde55eb
--- /dev/null
+++ b/hw/bsp/hpmicro/family.mk
@@ -0,0 +1,74 @@
+SDK_DIR = hw/mcu/hpmicro/hpm_sdk
+
+include $(TOP)/$(BOARD_PATH)/board.mk
+
+CPU_CORE ?= rv32imac-ilp32
+
+# All source paths should be relative to the top level.
+LD_FILE = $(HPM_SOC)/toolchains/gcc/flash_xip.ld
+
+CFLAGS += \
+ -DFLASH_XIP \
+ -DCFG_TUSB_MCU=OPT_MCU_HPM \
+ -DCFG_TUD_MEM_SECTION='__attribute__((section(".noncacheable.non_init")))' \
+ -DCFG_TUH_MEM_SECTION='__attribute__((section(".noncacheable.non_init")))'
+
+ifdef BOARD_TUD_RHPORT
+CFLAGS += -DBOARD_TUD_RHPORT=$(BOARD_TUD_RHPORT)
+CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED
+endif
+
+ifdef BOARD_TUH_RHPORT
+CFLAGS += -DBOARD_TUH_RHPORT=$(BOARD_TUH_RHPORT)
+CFLAGS += -DBOARD_TUH_MAX_SPEED=OPT_MODE_HIGH_SPEED
+endif
+
+# mcu driver cause following warnings
+CFLAGS += -Wno-error=cast-align -Wno-error=double-promotion -Wno-error=discarded-qualifiers \
+ -Wno-error=undef -Wno-error=unused-parameter -Wno-error=redundant-decls
+
+LDFLAGS_GCC += \
+ -nostartfiles \
+ --specs=nosys.specs --specs=nano.specs
+
+LDFLAGS += -Wl,--defsym,_flash_size=$(BOARD_FLASH_SIZE)
+LDFLAGS += -Wl,--defsym,_stack_size=$(BOARD_STACK_SIZE)
+LDFLAGS += -Wl,--defsym,_heap_size=$(BOARD_HEAP_SIZE)
+
+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 \
+ ${BOARD_PATH}/board.c \
+ ${BOARD_PATH}/pinmux.c \
+ $(HPM_SOC)/boot/hpm_bootheader.c \
+ $(HPM_SOC)/toolchains/gcc/initfini.c \
+ $(HPM_SOC)/toolchains/reset.c \
+ $(HPM_SOC)/toolchains/trap.c \
+ $(HPM_SOC)/system.c \
+ $(HPM_SOC)/hpm_sysctl_drv.c \
+ $(HPM_SOC)/hpm_clock_drv.c \
+ $(HPM_SOC)/hpm_otp_drv.c \
+ $(SDK_DIR)/arch/riscv/l1c/hpm_l1c_drv.c \
+ $(SDK_DIR)/utils/hpm_sbrk.c \
+ $(SDK_DIR)/drivers/src/hpm_gpio_drv.c \
+ $(SDK_DIR)/drivers/src/hpm_uart_drv.c \
+ $(SDK_DIR)/drivers/src/hpm_usb_drv.c \
+ $(SDK_DIR)/drivers/src/hpm_pcfg_drv.c \
+ $(SDK_DIR)/drivers/src/hpm_pmp_drv.c \
+ $(SDK_DIR)/drivers/src/$(HPM_PLLCTL_DRV_FILE) \
+
+INC += \
+ $(TOP)/$(BOARD_PATH) \
+ $(TOP)/src/portable/chipidea/ci_hs \
+ $(TOP)/$(HPM_SOC) \
+ $(TOP)/$(HPM_IP_REGS) \
+ $(TOP)/$(HPM_SOC)/boot \
+ $(TOP)/$(HPM_SOC)/toolchains \
+ $(TOP)/$(HPM_SOC)/toolchains/gcc \
+ $(TOP)/$(SDK_DIR)/arch \
+ $(TOP)/$(SDK_DIR)/arch/riscv/intc \
+ $(TOP)/$(SDK_DIR)/arch/riscv/l1c \
+ $(TOP)/$(SDK_DIR)/drivers/inc \
+
+SRC_S += $(HPM_SOC)/toolchains/gcc/start.S
diff --git a/hw/bsp/imxrt/family.c b/hw/bsp/imxrt/family.c
index 18833da80..d54b41bdb 100644
--- a/hw/bsp/imxrt/family.c
+++ b/hw/bsp/imxrt/family.c
@@ -107,6 +107,13 @@ static void init_usb_phy(uint8_t usb_id) {
}
void board_init(void) {
+// make sure the dcache is on.
+#if defined(__DCACHE_PRESENT) && __DCACHE_PRESENT
+ if (SCB_CCR_DC_Msk != (SCB_CCR_DC_Msk & SCB->CCR)) {
+ SCB_EnableDCache();
+ }
+#endif
+
BOARD_InitBootPins();
BOARD_BootClockRUN();
SystemCoreClockUpdate();
@@ -237,21 +244,9 @@ uint32_t board_millis(void) {
}
#endif
-
-#ifndef __ICCARM__
-// Implement _start() since we use linker flag '-nostartfiles'.
-// Requires defined __STARTUP_CLEAR_BSS,
-extern int main(void);
-TU_ATTR_UNUSED void _start(void) {
- // called by startup code
- main();
- while (1) {}
-}
-
#ifdef __clang__
void _exit(int __status) {
(void) __status;
while (1) {}
}
#endif
-#endif
diff --git a/hw/bsp/imxrt/family.cmake b/hw/bsp/imxrt/family.cmake
index 11cc00983..d946b591d 100644
--- a/hw/bsp/imxrt/family.cmake
+++ b/hw/bsp/imxrt/family.cmake
@@ -44,7 +44,6 @@ function(family_add_board BOARD_TARGET)
${SDK_DIR}/drivers/lpuart/fsl_lpuart.c
${SDK_DIR}/drivers/ocotp/fsl_ocotp.c
${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT_WITH_CORE}.c
- ${SDK_DIR}/devices/${MCU_VARIANT}/xip/fsl_flexspi_nor_boot.c
${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c
)
@@ -56,11 +55,6 @@ function(family_add_board BOARD_TARGET)
endif()
endforeach()
- target_compile_definitions(${BOARD_TARGET} PUBLIC
- __STARTUP_CLEAR_BSS
- [=[CFG_TUSB_MEM_SECTION=__attribute__((section("NonCacheable")))]=]
- )
-
if (NOT M4 STREQUAL "1")
target_compile_definitions(${BOARD_TARGET} PUBLIC
XIP_EXTERNAL_FLASH=1
@@ -74,7 +68,6 @@ function(family_add_board BOARD_TARGET)
${CMSIS_DIR}/CMSIS/Core/Include
${SDK_DIR}/devices/${MCU_VARIANT}
${SDK_DIR}/devices/${MCU_VARIANT}/drivers
- #${SDK_DIR}/drivers/adc_12b1msps_sar
${SDK_DIR}/drivers/common
${SDK_DIR}/drivers/igpio
${SDK_DIR}/drivers/lpspi
@@ -92,12 +85,13 @@ function(family_configure_example TARGET RTOS)
family_configure_common(${TARGET} ${RTOS})
family_add_tinyusb(${TARGET} OPT_MCU_MIMXRT1XXX)
- target_sources(${TARGET} PUBLIC
+ target_sources(${TARGET} PRIVATE
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${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
+ ${SDK_DIR}/devices/${MCU_VARIANT}/xip/fsl_flexspi_nor_boot.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
@@ -105,26 +99,22 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD}
)
+ target_compile_definitions(${TARGET} PUBLIC
+ __START=main # required with -nostartfiles
+ __STARTUP_CLEAR_BSS
+ [=[CFG_TUSB_MEM_SECTION=__attribute__((section("NonCacheable")))]=]
+ )
if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_link_options(${TARGET} PUBLIC
"LINKER:--script=${LD_FILE_GNU}"
-nostartfiles
--specs=nosys.specs --specs=nano.specs
- # force linker to look for these symbols
- -Wl,-uimage_vector_table
- -Wl,-ug_boot_data
)
elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang")
- target_link_options(${TARGET} PUBLIC
- "LINKER:--script=${LD_FILE_GNU}"
- -Wl,-uimage_vector_table
- -Wl,-ug_boot_data
- )
+ target_link_options(${TARGET} PRIVATE "LINKER:--script=${LD_FILE_GNU}")
elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR")
- target_link_options(${TARGET} PUBLIC
- "LINKER:--config=${LD_FILE_IAR}"
- )
+ target_link_options(${TARGET} PRIVATE "LINKER:--config=${LD_FILE_IAR}")
endif ()
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
diff --git a/hw/bsp/imxrt/family.mk b/hw/bsp/imxrt/family.mk
index 353f64e57..42000671d 100644
--- a/hw/bsp/imxrt/family.mk
+++ b/hw/bsp/imxrt/family.mk
@@ -8,6 +8,7 @@ MCU_VARIANT_WITH_CORE = ${MCU_VARIANT}${MCU_CORE}
MCU_DIR = $(SDK_DIR)/devices/$(MCU_VARIANT)
CFLAGS += \
+ -D__START=main \
-D__STARTUP_CLEAR_BSS \
-DCFG_TUSB_MCU=OPT_MCU_MIMXRT1XXX \
-DCFG_TUSB_MEM_SECTION='__attribute__((section("NonCacheable")))' \
diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake
index 390d6072c..1602e35eb 100644
--- a/hw/bsp/rp2040/family.cmake
+++ b/hw/bsp/rp2040/family.cmake
@@ -296,7 +296,7 @@ function(family_configure_host_example TARGET RTOS)
# Pico-PIO-USB does not compile with all pico-sdk supported compilers, so check before enabling it
is_compiler_supported_by_pico_pio_usb(PICO_PIO_USB_COMPILER_SUPPORTED)
if (PICO_PIO_USB_COMPILER_SUPPORTED)
- family_add_pico_pio_usb(${PROJECT})
+ family_add_pico_pio_usb(${TARGET})
endif()
endif()
diff --git a/hw/bsp/rw61x/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/rw61x/FreeRTOSConfig/FreeRTOSConfig.h
new file mode 100644
index 000000000..281b4d40c
--- /dev/null
+++ b/hw/bsp/rw61x/FreeRTOSConfig/FreeRTOSConfig.h
@@ -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
diff --git a/hw/bsp/rw61x/boards/frdm_rw612/board.cmake b/hw/bsp/rw61x/boards/frdm_rw612/board.cmake
new file mode 100644
index 000000000..7d77956fa
--- /dev/null
+++ b/hw/bsp/rw61x/boards/frdm_rw612/board.cmake
@@ -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()
diff --git a/hw/bsp/rw61x/boards/frdm_rw612/board.h b/hw/bsp/rw61x/boards/frdm_rw612/board.h
new file mode 100644
index 000000000..fd9eec8b6
--- /dev/null
+++ b/hw/bsp/rw61x/boards/frdm_rw612/board.h
@@ -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
diff --git a/hw/bsp/rw61x/boards/frdm_rw612/board.mk b/hw/bsp/rw61x/boards/frdm_rw612/board.mk
new file mode 100644
index 000000000..c6a169b23
--- /dev/null
+++ b/hw/bsp/rw61x/boards/frdm_rw612/board.mk
@@ -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
diff --git a/hw/bsp/rw61x/boards/frdm_rw612/clock_config.c b/hw/bsp/rw61x/boards/frdm_rw612/clock_config.c
new file mode 100644
index 000000000..9ad78fe43
--- /dev/null
+++ b/hw/bsp/rw61x/boards/frdm_rw612/clock_config.c
@@ -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;
+}
diff --git a/hw/bsp/rw61x/boards/frdm_rw612/clock_config.h b/hw/bsp/rw61x/boards/frdm_rw612/clock_config.h
new file mode 100644
index 000000000..57e3bbb4d
--- /dev/null
+++ b/hw/bsp/rw61x/boards/frdm_rw612/clock_config.h
@@ -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_ */
diff --git a/hw/bsp/rw61x/boards/frdm_rw612/pin_mux.c b/hw/bsp/rw61x/boards/frdm_rw612/pin_mux.c
new file mode 100644
index 000000000..eba6b4123
--- /dev/null
+++ b/hw/bsp/rw61x/boards/frdm_rw612/pin_mux.c
@@ -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
+ **********************************************************************************************************************/
diff --git a/hw/bsp/rw61x/boards/frdm_rw612/pin_mux.h b/hw/bsp/rw61x/boards/frdm_rw612/pin_mux.h
new file mode 100644
index 000000000..c43b304d5
--- /dev/null
+++ b/hw/bsp/rw61x/boards/frdm_rw612/pin_mux.h
@@ -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
+ **********************************************************************************************************************/
diff --git a/hw/bsp/rw61x/family.c b/hw/bsp/rw61x/family.c
new file mode 100644
index 000000000..265d5fcc0
--- /dev/null
+++ b/hw/bsp/rw61x/family.c
@@ -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
diff --git a/hw/bsp/rw61x/family.cmake b/hw/bsp/rw61x/family.cmake
new file mode 100644
index 000000000..6782e87e3
--- /dev/null
+++ b/hw/bsp/rw61x/family.cmake
@@ -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()
diff --git a/hw/bsp/rw61x/family.mk b/hw/bsp/rw61x/family.mk
new file mode 100644
index 000000000..08eafddbc
--- /dev/null
+++ b/hw/bsp/rw61x/family.mk
@@ -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
diff --git a/hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld b/hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld
index 8acd49f9d..6c7e203f1 100644
--- a/hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld
+++ b/hw/bsp/stm32c0/boards/stm32c071nucleo/STM32C071RBTx_FLASH.ld
@@ -36,7 +36,7 @@
ENTRY(Reset_Handler)
_Min_Heap_Size = 0x200; /* required amount of heap */
-_Min_Stack_Size = 0x400; /* required amount of stack */
+_Min_Stack_Size = 0xc00; /* required amount of stack */
/* Memories definition */
MEMORY
diff --git a/hw/bsp/stm32c0/boards/stm32c071nucleo/board.cmake b/hw/bsp/stm32c0/boards/stm32c071nucleo/board.cmake
index 2a319a73c..ed70cffbf 100644
--- a/hw/bsp/stm32c0/boards/stm32c071nucleo/board.cmake
+++ b/hw/bsp/stm32c0/boards/stm32c071nucleo/board.cmake
@@ -2,6 +2,7 @@ set(MCU_VARIANT stm32c071xx)
set(JLINK_DEVICE stm32c071rb)
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32C071RBTx_FLASH.ld)
+set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/stm32c071xx_flash.icf)
function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
diff --git a/hw/bsp/stm32c0/boards/stm32c071nucleo/board.h b/hw/bsp/stm32c0/boards/stm32c071nucleo/board.h
index 751df2251..460b42a21 100644
--- a/hw/bsp/stm32c0/boards/stm32c071nucleo/board.h
+++ b/hw/bsp/stm32c0/boards/stm32c071nucleo/board.h
@@ -64,36 +64,30 @@
static inline void board_clock_init(void) {
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
- RCC_CRSInitTypeDef RCC_CRSInitStruct = {0};
+ RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
- /* -1- Enable HSIUSB48 Oscillator */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
- RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
+ __HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1);
+ /** Initializes the RCC Oscillators according to the specified parameters
+ * in the RCC_OscInitTypeDef structure.
+ */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
- /* -2- Initializes the CPU, AHB and APB buses clocks */
+ /** Initializes the CPU, AHB and APB buses clocks
+ */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSIUSB48;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
-
- __HAL_RCC_CRS_CLK_ENABLE();
-
- // Configures CRS
- RCC_CRSInitStruct.Prescaler = RCC_CRS_SYNC_DIV1;
- RCC_CRSInitStruct.Source = RCC_CRS_SYNC_SOURCE_USB;
- RCC_CRSInitStruct.Polarity = RCC_CRS_SYNC_POLARITY_RISING;
- RCC_CRSInitStruct.ReloadValue = __HAL_RCC_CRS_RELOADVALUE_CALCULATE(48000000,1000);
- RCC_CRSInitStruct.ErrorLimitValue = 34;
- RCC_CRSInitStruct.HSI48CalibrationValue = 32;
-
- HAL_RCCEx_CRSConfig(&RCC_CRSInitStruct);
+ PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
+ PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSE;
+ HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
}
-
#endif /* BOARD_H_ */
diff --git a/hw/bsp/stm32c0/boards/stm32c071nucleo/board.mk b/hw/bsp/stm32c0/boards/stm32c071nucleo/board.mk
index 67a9b59a8..fd22fc8d4 100644
--- a/hw/bsp/stm32c0/boards/stm32c071nucleo/board.mk
+++ b/hw/bsp/stm32c0/boards/stm32c071nucleo/board.mk
@@ -7,7 +7,7 @@ LD_FILE_GCC = $(BOARD_PATH)/STM32C071RBTx_FLASH.ld
# IAR
SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32c071xx.s
-LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32c071xx_flash.icf
+LD_FILE_IAR = $(BOARD_PATH)/stm32c071xx_flash.icf
# For flash-jlink target
JLINK_DEVICE = stm32c071rb
diff --git a/hw/bsp/stm32c0/boards/stm32c071nucleo/stm32c071xx_flash.icf b/hw/bsp/stm32c0/boards/stm32c071nucleo/stm32c071xx_flash.icf
new file mode 100644
index 000000000..684f41dc6
--- /dev/null
+++ b/hw/bsp/stm32c0/boards/stm32c071nucleo/stm32c071xx_flash.icf
@@ -0,0 +1,33 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20005FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0xc00;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
+
+export symbol __ICFEDIT_region_RAM_start__;
+export symbol __ICFEDIT_region_RAM_end__;
diff --git a/hw/bsp/stm32c0/family.c b/hw/bsp/stm32c0/family.c
index ba8b14dd1..e2ba47f45 100644
--- a/hw/bsp/stm32c0/family.c
+++ b/hw/bsp/stm32c0/family.c
@@ -37,13 +37,13 @@
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void USB_DRD_FS_IRQHandler(void) {
- tud_int_handler(0);
+ tusb_int_handler(0, true);
}
// Startup code generated by STM32CubeIDE uses USB_IRQHandler, while
// stm32c071xx.s from cmsis_device_c0 uses USB_DRD_FS_IRQHandler.
void USB_IRQHandler(void) {
- USB_DRD_FS_IRQHandler();
+ tusb_int_handler(0, true);
}
//--------------------------------------------------------------------+
diff --git a/hw/bsp/stm32c0/family.cmake b/hw/bsp/stm32c0/family.cmake
index 90d5322b7..dc1a2bb13 100644
--- a/hw/bsp/stm32c0/family.cmake
+++ b/hw/bsp/stm32c0/family.cmake
@@ -24,7 +24,6 @@ set(STARTUP_FILE_GNU ${ST_CMSIS}/Source/Templates/gcc/startup_${MCU_VARIANT}.s)
set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s)
set(LD_FILE_Clang ${LD_FILE_GNU})
-set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf)
#------------------------------------
# BOARD_TARGET
@@ -67,6 +66,8 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${TOP}/src/portable/st/typec/typec_stm32.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
diff --git a/hw/bsp/stm32c0/family.mk b/hw/bsp/stm32c0/family.mk
index bdb34454e..71209bf2e 100644
--- a/hw/bsp/stm32c0/family.mk
+++ b/hw/bsp/stm32c0/family.mk
@@ -29,6 +29,8 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
diff --git a/hw/bsp/stm32c0/stm32c0xx_hal_conf.h b/hw/bsp/stm32c0/stm32c0xx_hal_conf.h
index 678b6ee0d..874251c7f 100644
--- a/hw/bsp/stm32c0/stm32c0xx_hal_conf.h
+++ b/hw/bsp/stm32c0/stm32c0xx_hal_conf.h
@@ -92,7 +92,7 @@ extern "C" {
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
-#define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */
+#define HSE_VALUE (48000000U) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
diff --git a/hw/bsp/stm32f0/family.cmake b/hw/bsp/stm32f0/family.cmake
index ee73ae872..a926a9739 100644
--- a/hw/bsp/stm32f0/family.cmake
+++ b/hw/bsp/stm32f0/family.cmake
@@ -65,6 +65,7 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/stm32f0/family.mk b/hw/bsp/stm32f0/family.mk
index 9b8305874..b5efdcb8d 100644
--- a/hw/bsp/stm32f0/family.mk
+++ b/hw/bsp/stm32f0/family.mk
@@ -30,6 +30,7 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
diff --git a/hw/bsp/stm32f1/family.cmake b/hw/bsp/stm32f1/family.cmake
index 064f32096..9e94d86c6 100644
--- a/hw/bsp/stm32f1/family.cmake
+++ b/hw/bsp/stm32f1/family.cmake
@@ -62,6 +62,7 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/stm32f1/family.mk b/hw/bsp/stm32f1/family.mk
index ca95f2315..d4b6dfa6c 100644
--- a/hw/bsp/stm32f1/family.mk
+++ b/hw/bsp/stm32f1/family.mk
@@ -27,6 +27,7 @@ LDFLAGS_GCC += \
# ------------------------
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
${ST_CMSIS}/Source/Templates/system_stm32${ST_FAMILY}xx.c \
${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal.c \
${ST_HAL_DRIVER}/Src/stm32${ST_FAMILY}xx_hal_cortex.c \
diff --git a/hw/bsp/stm32f3/family.cmake b/hw/bsp/stm32f3/family.cmake
index 7c9e97e62..3cbb4e1cd 100644
--- a/hw/bsp/stm32f3/family.cmake
+++ b/hw/bsp/stm32f3/family.cmake
@@ -62,6 +62,7 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/stm32f3/family.mk b/hw/bsp/stm32f3/family.mk
index 13734583a..eb4a4e186 100644
--- a/hw/bsp/stm32f3/family.mk
+++ b/hw/bsp/stm32f3/family.mk
@@ -19,6 +19,7 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
diff --git a/hw/bsp/stm32g0/family.c b/hw/bsp/stm32g0/family.c
index 7b86aedb4..4b175b0ec 100644
--- a/hw/bsp/stm32g0/family.c
+++ b/hw/bsp/stm32g0/family.c
@@ -37,7 +37,7 @@
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void USB_UCPD1_2_IRQHandler(void) {
- tud_int_handler(0);
+ tusb_int_handler(0, true);
}
//--------------------------------------------------------------------+
diff --git a/hw/bsp/stm32g0/family.cmake b/hw/bsp/stm32g0/family.cmake
index 572f0e644..4b520a0e1 100644
--- a/hw/bsp/stm32g0/family.cmake
+++ b/hw/bsp/stm32g0/family.cmake
@@ -64,6 +64,8 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${TOP}/src/portable/st/typec/typec_stm32.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
diff --git a/hw/bsp/stm32g0/family.mk b/hw/bsp/stm32g0/family.mk
index d735ca92d..e376f7f06 100644
--- a/hw/bsp/stm32g0/family.mk
+++ b/hw/bsp/stm32g0/family.mk
@@ -29,6 +29,8 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
diff --git a/hw/bsp/stm32g4/family.cmake b/hw/bsp/stm32g4/family.cmake
index 7e8b319b8..85201ce61 100644
--- a/hw/bsp/stm32g4/family.cmake
+++ b/hw/bsp/stm32g4/family.cmake
@@ -62,6 +62,7 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${TOP}/src/portable/st/typec/typec_stm32.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
diff --git a/hw/bsp/stm32g4/family.mk b/hw/bsp/stm32g4/family.mk
index 0abd73532..a153194ce 100644
--- a/hw/bsp/stm32g4/family.mk
+++ b/hw/bsp/stm32g4/family.mk
@@ -29,6 +29,7 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
src/portable/st/typec/typec_stm32.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
diff --git a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.cmake b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.cmake
index 1a44c3f1d..5978758fc 100644
--- a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.cmake
+++ b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.cmake
@@ -6,4 +6,7 @@ function(update_board TARGET)
STM32H503xx
HSE_VALUE=24000000
)
+ target_compile_definitions(${BOARD_TARGET} PUBLIC
+ CFG_EXAMPLE_VIDEO_READONLY
+ )
endfunction()
diff --git a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h
index c8b5e31f5..9dd2b0466 100644
--- a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h
+++ b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.h
@@ -37,24 +37,33 @@
extern "C" {
#endif
-// LED
-#define LED_PORT GPIOA
-#define LED_PIN GPIO_PIN_5
-#define LED_STATE_ON 1
+#define PINID_LED 0
+#define PINID_BUTTON 1
+#define PINID_UART_TX 2
+#define PINID_UART_RX 3
-// Button
-#define BUTTON_PORT GPIOA
-#define BUTTON_PIN GPIO_PIN_0
-#define BUTTON_STATE_ACTIVE 0
-
-// UART Enable for STLink VCOM
-#define UART_DEV USART3
-#define UART_CLK_EN __USART3_CLK_ENABLE
-#define UART_GPIO_PORT GPIOA
-#define UART_GPIO_AF GPIO_AF13_USART3
-
-#define UART_TX_PIN GPIO_PIN_3
-#define UART_RX_PIN GPIO_PIN_4
+static board_pindef_t board_pindef[] = {
+ { // LED
+ .port = GPIOA,
+ .pin_init = { .Pin = GPIO_PIN_5, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0 },
+ .active_state = 1
+ },
+ { // Button
+ .port = GPIOA,
+ .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0 },
+ .active_state = 0
+ },
+ { // UART TX
+ .port = GPIOA,
+ .pin_init = { .Pin = GPIO_PIN_3, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = GPIO_AF13_USART3 },
+ .active_state = 0
+ },
+ { // UART RX
+ .port = GPIOA,
+ .pin_init = { .Pin = GPIO_PIN_4, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = GPIO_AF13_USART3 },
+ .active_state = 0
+ },
+};
//--------------------------------------------------------------------+
// RCC Clock
@@ -120,6 +129,15 @@ static inline void SystemClock_Config(void) {
__HAL_RCC_USB_CLK_ENABLE();
}
+static inline void board_init2(void) {
+ // Empty for this board
+}
+
+void board_vbus_set(uint8_t rhport, bool state) {
+ (void) rhport;
+ (void) state;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.mk b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.mk
index 0292353ae..497dd894e 100644
--- a/hw/bsp/stm32h5/boards/stm32h503nucleo/board.mk
+++ b/hw/bsp/stm32h5/boards/stm32h503nucleo/board.mk
@@ -3,6 +3,7 @@ MCU_VARIANT = stm32h503xx
CFLAGS += \
-DSTM32H503xx \
-DHSE_VALUE=24000000 \
+ -DCFG_EXAMPLE_VIDEO_READONLY \
# For flash-jlink target
JLINK_DEVICE = stm32h503rb
diff --git a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h
index adc3d751a..20c91f606 100644
--- a/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h
+++ b/hw/bsp/stm32h5/boards/stm32h563nucleo/board.h
@@ -37,24 +37,33 @@
extern "C" {
#endif
-// LED
-#define LED_PORT GPIOG
-#define LED_PIN GPIO_PIN_4
-#define LED_STATE_ON 1
+#define PINID_LED 0
+#define PINID_BUTTON 1
+#define PINID_UART_TX 2
+#define PINID_UART_RX 3
-// Button
-#define BUTTON_PORT GPIOA
-#define BUTTON_PIN GPIO_PIN_0
-#define BUTTON_STATE_ACTIVE 0
-
-// UART Enable for STLink VCOM
-#define UART_DEV USART1
-#define UART_CLK_EN __USART1_CLK_ENABLE
-#define UART_GPIO_PORT GPIOA
-#define UART_GPIO_AF GPIO_AF7_USART1
-
-#define UART_TX_PIN GPIO_PIN_9
-#define UART_RX_PIN GPIO_PIN_10
+static board_pindef_t board_pindef[] = {
+ { // LED
+ .port = GPIOG,
+ .pin_init = { .Pin = GPIO_PIN_4, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0 },
+ .active_state = 1
+ },
+ { // Button
+ .port = GPIOA,
+ .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0 },
+ .active_state = 0
+ },
+ { // UART TX
+ .port = GPIOA,
+ .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = GPIO_AF7_USART1 },
+ .active_state = 0
+ },
+ { // UART RX
+ .port = GPIOA,
+ .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = GPIO_AF7_USART1 },
+ .active_state = 0
+ },
+};
//--------------------------------------------------------------------+
// RCC Clock
@@ -128,6 +137,15 @@ static inline void SystemClock_Config(void) {
}
}
+static inline void board_init2(void) {
+ // Empty for this board
+}
+
+void board_vbus_set(uint8_t rhport, bool state) {
+ (void) rhport;
+ (void) state;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.cmake b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.cmake
index 92d6d98f0..76194ee91 100644
--- a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.cmake
+++ b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.cmake
@@ -5,4 +5,11 @@ function(update_board TARGET)
target_compile_definitions(${TARGET} PUBLIC
STM32H573xx
)
+ target_sources(${TARGET} PUBLIC
+ ${ST_TCPP0203}/tcpp0203.c
+ ${ST_TCPP0203}/tcpp0203_reg.c
+ )
+ target_include_directories(${TARGET} PUBLIC
+ ${ST_TCPP0203}
+ )
endfunction()
diff --git a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h
index d75114397..5788837ab 100644
--- a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h
+++ b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.h
@@ -37,24 +37,63 @@
extern "C" {
#endif
-// LED
-#define LED_PORT GPIOI
-#define LED_PIN GPIO_PIN_9
-#define LED_STATE_ON 1
+#include "tcpp0203.h"
-// Button
-#define BUTTON_PORT GPIOC
-#define BUTTON_PIN GPIO_PIN_13
-#define BUTTON_STATE_ACTIVE 1
+// VBUS Sense detection
+#define OTG_FS_VBUS_SENSE 1
+#define OTG_HS_VBUS_SENSE 0
-// UART Enable for STLink VCOM
-#define UART_DEV USART1
-#define UART_CLK_EN __USART1_CLK_ENABLE
-#define UART_GPIO_PORT GPIOA
-#define UART_GPIO_AF GPIO_AF7_USART1
+#define PINID_LED 0
+#define PINID_BUTTON 1
+#define PINID_UART_TX 2
+#define PINID_UART_RX 3
+#define PINID_TCPP0203_EN 4
+#define PINID_I2C_SCL 5
+#define PINID_I2C_SDA 6
+#define PINID_TCPP0203_INT 7
-#define UART_TX_PIN GPIO_PIN_9
-#define UART_RX_PIN GPIO_PIN_10
+static board_pindef_t board_pindef[] = {
+ { // LED
+ .port = GPIOI,
+ .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0 },
+ .active_state = 1
+ },
+ { // Button
+ .port = GPIOC,
+ .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0 },
+ .active_state = 1
+ },
+ { // UART TX
+ .port = GPIOA,
+ .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = GPIO_AF7_USART1 },
+ .active_state = 0
+ },
+ { // UART RX
+ .port = GPIOA,
+ .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = GPIO_AF7_USART1 },
+ .active_state = 0
+ },
+ { // TCPP0203 VCC_EN
+ .port = GPIOG,
+ .pin_init = { .Pin = GPIO_PIN_0, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_LOW, .Alternate = 0 },
+ .active_state = 1
+ },
+ { // I2C4 SCL
+ .port = GPIOB,
+ .pin_init = { .Pin = GPIO_PIN_8, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = GPIO_AF6_I2C4 },
+ .active_state = 0
+ },
+ { // I2C4 SDA
+ .port = GPIOB,
+ .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_OD, .Pull = GPIO_NOPULL, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = GPIO_AF6_I2C4 },
+ .active_state = 0
+ },
+ { // TCPP0203 INT
+ .port = GPIOG,
+ .pin_init = { .Pin = GPIO_PIN_1, .Mode = GPIO_MODE_IT_FALLING, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_FREQ_HIGH, .Alternate = 0 },
+ .active_state = 0
+ },
+};
//--------------------------------------------------------------------+
// RCC Clock
@@ -113,6 +152,89 @@ static inline void SystemClock_Config(void) {
__HAL_RCC_USB_CLK_ENABLE();
}
+//--------------------------------------------------------------------+
+// USB PD
+//--------------------------------------------------------------------+
+static I2C_HandleTypeDef i2c_handle = {
+ .Instance = I2C4,
+ .Init = {
+ .Timing = 0x20C0EDFF, // 100kHz @ 250MHz
+ .OwnAddress1 = 0,
+ .AddressingMode = I2C_ADDRESSINGMODE_7BIT,
+ .DualAddressMode = I2C_DUALADDRESS_DISABLE,
+ .OwnAddress2 = 0,
+ .OwnAddress2Masks = I2C_OA2_NOMASK,
+ .GeneralCallMode = I2C_GENERALCALL_DISABLE,
+ .NoStretchMode = I2C_NOSTRETCH_DISABLE,
+ }
+};
+static TCPP0203_Object_t tcpp0203_obj = { 0 };
+
+int32_t board_tcpp0203_init(void) {
+ // Enable TCPP0203 VCC (GPIO already configured in pindef array)
+ board_pindef_t* pindef = &board_pindef[PINID_TCPP0203_EN];
+ HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, GPIO_PIN_SET);
+
+ // Initialize I2C4 for TCPP0203 (GPIO already configured in pindef array)
+ __HAL_RCC_I2C4_CLK_ENABLE();
+ __HAL_RCC_I2C4_FORCE_RESET();
+ __HAL_RCC_I2C4_RELEASE_RESET();
+ if (HAL_I2C_Init(&i2c_handle) != HAL_OK) {
+ return HAL_ERROR;
+ }
+
+ // Enable interrupt for TCPP0203 FLGn (GPIO already configured in pindef array)
+ NVIC_SetPriority(EXTI1_IRQn, 12);
+ NVIC_EnableIRQ(EXTI1_IRQn);
+
+ return 0;
+}
+
+int32_t board_tcpp0203_deinit(void) {
+ return 0;
+}
+
+int32_t i2c_readreg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) {
+ TU_ASSERT (HAL_OK == HAL_I2C_Mem_Read(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000));
+ return 0;
+}
+
+int32_t i2c_writereg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) {
+ TU_ASSERT(HAL_OK == HAL_I2C_Mem_Write(&i2c_handle, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, 10000));
+ return 0;
+}
+
+static inline void board_init2(void) {
+ TCPP0203_IO_t io_ctx;
+
+ io_ctx.Address = TCPP0203_I2C_ADDRESS_X68;
+ io_ctx.Init = board_tcpp0203_init;
+ io_ctx.DeInit = board_tcpp0203_deinit;
+ io_ctx.ReadReg = i2c_readreg;
+ io_ctx.WriteReg = i2c_writereg;
+
+ TU_ASSERT(TCPP0203_RegisterBusIO(&tcpp0203_obj, &io_ctx) == TCPP0203_OK, );
+
+ TU_ASSERT(TCPP0203_Init(&tcpp0203_obj) == TCPP0203_OK, );
+
+ TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, );
+}
+
+void board_vbus_set(uint8_t rhport, bool state) {
+ (void) state;
+ if (rhport == 0) {
+ TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, TCPP0203_GD_PROVIDER_SWITCH_CLOSED) == TCPP0203_OK, );
+ }
+}
+
+void EXTI1_IRQHandler(void) {
+ __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_1);
+ if (tcpp0203_obj.IsInitialized) {
+ TU_ASSERT(TCPP0203_SetPowerMode(&tcpp0203_obj, TCPP0203_POWER_MODE_NORMAL) == TCPP0203_OK, );
+ TU_ASSERT(TCPP0203_SetGateDriverProvider(&tcpp0203_obj, TCPP0203_GD_PROVIDER_SWITCH_CLOSED) == TCPP0203_OK, );
+ }
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.mk b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.mk
index b24acf89f..49743e7cd 100644
--- a/hw/bsp/stm32h5/boards/stm32h573i_dk/board.mk
+++ b/hw/bsp/stm32h5/boards/stm32h573i_dk/board.mk
@@ -5,3 +5,10 @@ CFLAGS += \
# For flash-jlink target
JLINK_DEVICE = stm32h573ii
+
+SRC_C += \
+ $(ST_TCPP0203)/tcpp0203.c \
+ $(ST_TCPP0203)/tcpp0203_reg.c \
+
+INC += \
+ $(TOP)/$(ST_TCPP0203) \
diff --git a/hw/bsp/stm32h5/family.c b/hw/bsp/stm32h5/family.c
index 983944b1c..fdb12e44f 100644
--- a/hw/bsp/stm32h5/family.c
+++ b/hw/bsp/stm32h5/family.c
@@ -46,20 +46,38 @@
TU_ATTR_UNUSED static void Error_Handler(void) {
}
+typedef struct {
+ GPIO_TypeDef* port;
+ GPIO_InitTypeDef pin_init;
+ uint8_t active_state;
+} board_pindef_t;
+
#include "board.h"
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
void USB_DRD_FS_IRQHandler(void) {
- tud_int_handler(0);
+ tusb_int_handler(0, true);
}
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
#ifdef UART_DEV
-UART_HandleTypeDef UartHandle;
+static UART_HandleTypeDef UartHandle = {
+ .Instance = UART_DEV,
+ .Init = {
+ .BaudRate = CFG_BOARD_UART_BAUDRATE,
+ .WordLength = UART_WORDLENGTH_8B,
+ .StopBits = UART_STOPBITS_1,
+ .Parity = UART_PARITY_NONE,
+ .HwFlowCtl = UART_HWCONTROL_NONE,
+ .Mode = UART_MODE_TX_RX,
+ .OverSampling = UART_OVERSAMPLING_16,
+ .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT
+ }
+};
#endif
void board_init(void) {
@@ -95,51 +113,18 @@ void board_init(void) {
NVIC_SetPriority(USB_DRD_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);
#endif
- GPIO_InitTypeDef GPIO_InitStruct;
-
- // LED
- GPIO_InitStruct.Pin = LED_PIN;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(LED_PORT, &GPIO_InitStruct);
-
- board_led_write(false);
-
- // Button
- GPIO_InitStruct.Pin = BUTTON_PIN;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pull = BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN : GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
+ for (uint8_t i = 0; i < TU_ARRAY_SIZE(board_pindef); i++) {
+ HAL_GPIO_Init(board_pindef[i].port, &board_pindef[i].pin_init);
+ }
#ifdef UART_DEV
UART_CLK_EN();
-
- // UART
- GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
- GPIO_InitStruct.Alternate = UART_GPIO_AF;
- HAL_GPIO_Init(UART_GPIO_PORT, &GPIO_InitStruct);
-
- UartHandle = (UART_HandleTypeDef) {
- .Instance = UART_DEV,
- .Init.BaudRate = CFG_BOARD_UART_BAUDRATE,
- .Init.WordLength = UART_WORDLENGTH_8B,
- .Init.StopBits = UART_STOPBITS_1,
- .Init.Parity = UART_PARITY_NONE,
- .Init.HwFlowCtl = UART_HWCONTROL_NONE,
- .Init.Mode = UART_MODE_TX_RX,
- .Init.OverSampling = UART_OVERSAMPLING_16,
- .AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT
- };
HAL_UART_Init(&UartHandle);
#endif
// USB Pins TODO double check USB clock and pin setup
// Configure USB DM and DP pins. This is optional, and maintained only for user guidance.
+ GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12);
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
@@ -153,6 +138,12 @@ void board_init(void) {
#if defined (PWR_USBSCR_USB33DEN)
HAL_PWREx_EnableVddUSB();
#endif
+
+ board_init2();
+
+#if CFG_TUH_ENABLED
+ board_vbus_set(BOARD_TUH_RHPORT, 1);
+#endif
}
//--------------------------------------------------------------------+
@@ -160,12 +151,22 @@ void board_init(void) {
//--------------------------------------------------------------------+
void board_led_write(bool state) {
- GPIO_PinState pin_state = (GPIO_PinState) (state ? LED_STATE_ON : (1 - LED_STATE_ON));
- HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state);
+#ifdef PINID_LED
+ board_pindef_t* pindef = &board_pindef[PINID_LED];
+ GPIO_PinState pin_state = state == pindef->active_state ? GPIO_PIN_SET : GPIO_PIN_RESET;
+ HAL_GPIO_WritePin(pindef->port, pindef->pin_init.Pin, pin_state);
+#else
+ (void) state;
+#endif
}
uint32_t board_button_read(void) {
- return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
+#ifdef PINID_BUTTON
+ board_pindef_t* pindef = &board_pindef[PINID_BUTTON];
+ return pindef->active_state == HAL_GPIO_ReadPin(pindef->port, pindef->pin_init.Pin);
+#else
+ return 0;
+#endif
}
size_t board_get_unique_id(uint8_t id[], size_t max_len) {
diff --git a/hw/bsp/stm32h5/family.cmake b/hw/bsp/stm32h5/family.cmake
index 6e63c4072..a8780d165 100644
--- a/hw/bsp/stm32h5/family.cmake
+++ b/hw/bsp/stm32h5/family.cmake
@@ -5,6 +5,7 @@ set(ST_PREFIX stm32${ST_FAMILY}xx)
set(ST_HAL_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx_hal_driver)
set(ST_CMSIS ${TOP}/hw/mcu/st/cmsis_device_${ST_FAMILY})
+set(ST_TCPP0203 ${TOP}/hw/mcu/st/stm32-tcpp0203)
set(CMSIS_5 ${TOP}/lib/CMSIS_5)
# include board specific
@@ -26,7 +27,7 @@ set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU})
set(STARTUP_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/startup_${MCU_VARIANT}.s)
set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT_UPPER}_FLASH.ld)
set(LD_FILE_Clang ${LD_FILE_GNU})
-set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf)
+set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_flash.icf)
#------------------------------------
# BOARD_TARGET
@@ -44,6 +45,7 @@ function(family_add_board BOARD_TARGET)
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart.c
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_uart_ex.c
${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_dma.c
+ ${ST_HAL_DRIVER}/Src/${ST_PREFIX}_hal_i2c.c
)
target_include_directories(${BOARD_TARGET} PUBLIC
${CMAKE_CURRENT_FUNCTION_LIST_DIR}
@@ -66,6 +68,8 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${TOP}/src/portable/st/typec/typec_stm32.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
diff --git a/hw/bsp/stm32h5/family.mk b/hw/bsp/stm32h5/family.mk
index 792edb2bb..e34bb513e 100644
--- a/hw/bsp/stm32h5/family.mk
+++ b/hw/bsp/stm32h5/family.mk
@@ -1,6 +1,7 @@
ST_FAMILY = h5
ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY)
ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver
+ST_TCPP0203 = hw/mcu/st/stm32-tcpp0203
include $(TOP)/$(BOARD_PATH)/board.mk
CPU_CORE ?= cortex-m33
@@ -36,6 +37,8 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
@@ -46,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 += \
diff --git a/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld
index abf618233..169ac81b7 100644
--- a/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld
+++ b/hw/bsp/stm32h5/linker/STM32H503xx_FLASH.ld
@@ -46,7 +46,7 @@ MEMORY
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
-_Min_Stack_Size = 0x400; /* required amount of stack */
+_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Sections */
diff --git a/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld
index b799892c6..633fc280e 100644
--- a/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld
+++ b/hw/bsp/stm32h5/linker/STM32H523xx_FLASH.ld
@@ -46,7 +46,7 @@ MEMORY
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
-_Min_Stack_Size = 0x400; /* required amount of stack */
+_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Sections */
SECTIONS
diff --git a/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld
index dece7a003..4d010cf9e 100644
--- a/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld
+++ b/hw/bsp/stm32h5/linker/STM32H533xx_FLASH.ld
@@ -46,7 +46,7 @@ MEMORY
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
-_Min_Stack_Size = 0x400; /* required amount of stack */
+_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Sections */
SECTIONS
diff --git a/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld
index aee2774a4..aeb799d63 100644
--- a/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld
+++ b/hw/bsp/stm32h5/linker/STM32H562xx_FLASH.ld
@@ -46,7 +46,7 @@ MEMORY
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
-_Min_Stack_Size = 0x400; /* required amount of stack */
+_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Sections */
SECTIONS
diff --git a/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld
index 129ed5170..2e8d38319 100644
--- a/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld
+++ b/hw/bsp/stm32h5/linker/STM32H563xx_FLASH.ld
@@ -46,7 +46,7 @@ MEMORY
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
-_Min_Stack_Size = 0x400; /* required amount of stack */
+_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Sections */
SECTIONS
diff --git a/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld b/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld
index eb98f3163..dd00557c0 100644
--- a/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld
+++ b/hw/bsp/stm32h5/linker/STM32H573xx_FLASH.ld
@@ -46,7 +46,7 @@ MEMORY
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
_Min_Heap_Size = 0x200; /* required amount of heap */
-_Min_Stack_Size = 0x400; /* required amount of stack */
+_Min_Stack_Size = 0x1000; /* required amount of stack */
/* Sections */
SECTIONS
diff --git a/hw/bsp/stm32h5/linker/stm32h503xx_flash.icf b/hw/bsp/stm32h5/linker/stm32h503xx_flash.icf
new file mode 100644
index 000000000..c5b783b1a
--- /dev/null
+++ b/hw/bsp/stm32h5/linker/stm32h503xx_flash.icf
@@ -0,0 +1,32 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0801FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
+
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x1000;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/hw/bsp/stm32h5/linker/stm32h523xx_flash.icf b/hw/bsp/stm32h5/linker/stm32h523xx_flash.icf
new file mode 100644
index 000000000..dc97788ae
--- /dev/null
+++ b/hw/bsp/stm32h5/linker/stm32h523xx_flash.icf
@@ -0,0 +1,32 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20043FFF;
+
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x1000;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/hw/bsp/stm32h5/linker/stm32h562xx_flash.icf b/hw/bsp/stm32h5/linker/stm32h562xx_flash.icf
new file mode 100644
index 000000000..b399851a3
--- /dev/null
+++ b/hw/bsp/stm32h5/linker/stm32h562xx_flash.icf
@@ -0,0 +1,32 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF;
+
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x1000;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/hw/bsp/stm32h5/linker/stm32h563xx_flash.icf b/hw/bsp/stm32h5/linker/stm32h563xx_flash.icf
new file mode 100644
index 000000000..b399851a3
--- /dev/null
+++ b/hw/bsp/stm32h5/linker/stm32h563xx_flash.icf
@@ -0,0 +1,32 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF;
+
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x1000;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/hw/bsp/stm32h5/linker/stm32h573xx_flash.icf b/hw/bsp/stm32h5/linker/stm32h573xx_flash.icf
new file mode 100644
index 000000000..b399851a3
--- /dev/null
+++ b/hw/bsp/stm32h5/linker/stm32h573xx_flash.icf
@@ -0,0 +1,32 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x08000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x081FFFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2009FFFF;
+
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x1000;
+define symbol __ICFEDIT_size_heap__ = 0x200;
+/**** End of ICF editor section. ###ICF###*/
+
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK, block HEAP };
diff --git a/hw/bsp/stm32h5/stm32h5xx_hal_conf.h b/hw/bsp/stm32h5/stm32h5xx_hal_conf.h
index d017bb06b..b4c64d56e 100644
--- a/hw/bsp/stm32h5/stm32h5xx_hal_conf.h
+++ b/hw/bsp/stm32h5/stm32h5xx_hal_conf.h
@@ -43,7 +43,6 @@ extern "C" {
/* #define HAL_EXTI_MODULE_ENABLED */
/* #define HAL_FDCAN_MODULE_ENABLED */
/* #define HAL_HCD_MODULE_ENABLED */
-/* #define HAL_I2C_MODULE_ENABLED */
/* #define HAL_I2S_MODULE_ENABLED */
/* #define HAL_IWDG_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
@@ -65,6 +64,7 @@ extern "C" {
#define HAL_PWR_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
+#define HAL_I2C_MODULE_ENABLED
/* ########################## Register Callbacks selection ############################## */
/**
diff --git a/hw/bsp/stm32l0/family.cmake b/hw/bsp/stm32l0/family.cmake
index b6b0139a0..3f6622f71 100644
--- a/hw/bsp/stm32l0/family.cmake
+++ b/hw/bsp/stm32l0/family.cmake
@@ -66,6 +66,7 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/stm32l0/family.mk b/hw/bsp/stm32l0/family.mk
index 921b1b413..0ae881fdf 100644
--- a/hw/bsp/stm32l0/family.mk
+++ b/hw/bsp/stm32l0/family.mk
@@ -27,6 +27,7 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
diff --git a/hw/bsp/stm32l4/family.cmake b/hw/bsp/stm32l4/family.cmake
index 5bc28dd5d..b1659d47a 100644
--- a/hw/bsp/stm32l4/family.cmake
+++ b/hw/bsp/stm32l4/family.cmake
@@ -67,6 +67,7 @@ function(family_configure_example TARGET RTOS)
${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/stm32l4/family.mk b/hw/bsp/stm32l4/family.mk
index 01d059236..fd11fd226 100644
--- a/hw/bsp/stm32l4/family.mk
+++ b/hw/bsp/stm32l4/family.mk
@@ -34,6 +34,7 @@ SRC_C += \
src/portable/synopsys/dwc2/hcd_dwc2.c \
src/portable/synopsys/dwc2/dwc2_common.c \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
diff --git a/hw/bsp/stm32u0/family.cmake b/hw/bsp/stm32u0/family.cmake
index 4f9b03109..2d3819cba 100644
--- a/hw/bsp/stm32u0/family.cmake
+++ b/hw/bsp/stm32u0/family.cmake
@@ -67,6 +67,7 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/stm32u0/family.mk b/hw/bsp/stm32u0/family.mk
index d5a850050..5f25906d3 100644
--- a/hw/bsp/stm32u0/family.mk
+++ b/hw/bsp/stm32u0/family.mk
@@ -27,6 +27,7 @@ LDFLAGS_GCC += \
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \
diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c
index 0af497366..26d72d6a0 100644
--- a/hw/bsp/stm32u5/family.c
+++ b/hw/bsp/stm32u5/family.c
@@ -51,14 +51,21 @@ TU_ATTR_UNUSED static void Error_Handler(void) {
//--------------------------------------------------------------------+
// Forward USB interrupt events to TinyUSB IRQ Handler
//--------------------------------------------------------------------+
+#ifdef USB_DRD_FS
+void USB_IRQHandler(void) {
+ tusb_int_handler(0, true);
+}
+#endif
+#ifdef USB_OTG_FS
void OTG_FS_IRQHandler(void) {
- tud_int_handler(0);
+ tusb_int_handler(0, true);
}
-
+#endif
+#ifdef USB_OTG_HS
void OTG_HS_IRQHandler(void) {
- tud_int_handler(0);
+ tusb_int_handler(0, true);
}
-
+#endif
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
//--------------------------------------------------------------------+
diff --git a/hw/bsp/stm32u5/family.cmake b/hw/bsp/stm32u5/family.cmake
index 70e0c313c..58dc63ae3 100644
--- a/hw/bsp/stm32u5/family.cmake
+++ b/hw/bsp/stm32u5/family.cmake
@@ -66,6 +66,8 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c
${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c
${TOP}/src/portable/synopsys/dwc2/dwc2_common.c
diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk
index 3694b1ca0..47aed10a9 100644
--- a/hw/bsp/stm32u5/family.mk
+++ b/hw/bsp/stm32u5/family.mk
@@ -37,12 +37,10 @@ SRC_C += \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \
$(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c
-ifeq ($(MCU_VARIANT),stm32u545xx)
+ifneq ($(filter stm32u545xx stm32u535xx,$(MCU_VARIANT)),)
SRC_C += \
- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
-else ifeq ($(MCU_VARIANT),stm32u535xx)
-SRC_C += \
- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c
else
SRC_C += \
src/portable/synopsys/dwc2/dcd_dwc2.c \
diff --git a/hw/bsp/stm32wb/family.cmake b/hw/bsp/stm32wb/family.cmake
index 1a96e3d7e..6703a9b19 100644
--- a/hw/bsp/stm32wb/family.cmake
+++ b/hw/bsp/stm32wb/family.cmake
@@ -67,6 +67,7 @@ function(family_configure_example TARGET RTOS)
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c
${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+ ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c
${STARTUP_FILE_${CMAKE_C_COMPILER_ID}}
)
target_include_directories(${TARGET} PUBLIC
diff --git a/hw/bsp/stm32wb/family.mk b/hw/bsp/stm32wb/family.mk
index a80ff6f5b..0b1a51cec 100644
--- a/hw/bsp/stm32wb/family.mk
+++ b/hw/bsp/stm32wb/family.mk
@@ -20,6 +20,7 @@ LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs
SRC_C += \
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \
+ src/portable/st/stm32_fsdev/fsdev_common.c \
$(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}.c \
$(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \
$(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \
diff --git a/lib/rt-thread/SConscript b/lib/rt-thread/SConscript
index 99517a090..e7b6f2dc4 100644
--- a/lib/rt-thread/SConscript
+++ b/lib/rt-thread/SConscript
@@ -18,7 +18,8 @@ if GetDepend(["PKG_TINYUSB_DEVICE_ENABLE"]):
# BSP
if GetDepend(["SOC_FAMILY_STM32"]):
src += ["../../src/portable/synopsys/dwc2/dcd_dwc2.c",
- "../../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c"]
+ "../../src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c",
+ "../../src/portable/st/stm32_fsdev/fsdev_common.c"]
if GetDepend(["SOC_NRF52840"]):
src += ["../../src/portable/nordic/nrf5x/dcd_nrf5x.c"]
diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c
index 03cb51efe..6cb05307b 100644
--- a/src/class/audio/audio_device.c
+++ b/src/class/audio/audio_device.c
@@ -685,17 +685,17 @@ void audiod_init(void) {
switch (i) {
#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0
case 0:
- tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ, 1, true);
+ tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ, true);
break;
#endif
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0
case 1:
- tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ, 1, true);
+ tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ, true);
break;
#endif
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0
case 2:
- tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ, 1, true);
+ tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ, true);
break;
#endif
}
@@ -727,17 +727,17 @@ void audiod_init(void) {
switch (i) {
#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0
case 0:
- tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ, 1, true);
+ tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ, true);
break;
#endif
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0
case 1:
- tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ, 1, true);
+ tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ, true);
break;
#endif
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0
case 2:
- tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ, 1, true);
+ tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ, true);
break;
#endif
}
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index 32f6827b0..f19c4a327 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -828,7 +828,9 @@ static bool set_line_state_on_enum(cdch_interface_t *p_cdc, tuh_xfer_t *xfer) {
ENUM_SET_LINE_CONTROL,
ENUM_SET_LINE_COMPLETE,
};
+ #ifdef CFG_TUH_CDC_LINE_CODING_ON_ENUM
const uint8_t idx = get_idx_by_ptr(p_cdc);
+ #endif
const uintptr_t state = xfer->user_data;
switch (state) {
diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c
index 9972911e0..b8e6fec6f 100644
--- a/src/class/vendor/vendor_device.c
+++ b/src/class/vendor/vendor_device.c
@@ -160,6 +160,13 @@ uint32_t tud_vendor_n_write_available(uint8_t idx) {
vendord_interface_t *p_itf = &_vendord_itf[idx];
return tu_edpt_stream_write_available(&p_itf->stream.tx);
}
+
+bool tud_vendor_n_write_clear(uint8_t idx) {
+ TU_VERIFY(idx < CFG_TUD_VENDOR, 0);
+ vendord_interface_t *p_itf = &_vendord_itf[idx];
+ tu_edpt_stream_clear(&p_itf->stream.tx);
+ return true;
+}
#endif
//--------------------------------------------------------------------+
diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h
index d59c885d2..c3de4c49d 100644
--- a/src/class/vendor/vendor_device.h
+++ b/src/class/vendor/vendor_device.h
@@ -91,6 +91,9 @@ uint32_t tud_vendor_n_write_flush(uint8_t idx);
// Return number of bytes available for writing in TX FIFO
uint32_t tud_vendor_n_write_available(uint8_t idx);
+
+// Clear the transmit FIFO
+bool tud_vendor_n_write_clear(uint8_t idx);
#endif
// Write a null-terminated string to TX FIFO
@@ -148,6 +151,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_flush(void) {
TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_available(void) {
return tud_vendor_n_write_available(0);
}
+
+TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_write_clear(void) {
+ return tud_vendor_n_write_clear(0);
+}
#endif
// backward compatible
diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h
index d74760608..6ac1405f3 100644
--- a/src/common/tusb_common.h
+++ b/src/common/tusb_common.h
@@ -329,7 +329,7 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void *mem, uint16_
#endif
-// scatter read 4 bytes from two buffers. Parameter are not checked
+// scatter read 4 bytes from two buffers (LE). Parameter are not checked
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_scatter_read32(const uint8_t *buf1, uint8_t len1, const uint8_t *buf2,
uint8_t len2) {
uint32_t result = 0;
@@ -348,7 +348,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_scatter_read32(const uint8_t *bu
return result;
}
-// scatter write 4 bytes to two buffers. Parameter are not checked
+// scatter write 4 bytes (LE) to two buffers. Parameter are not checked
TU_ATTR_ALWAYS_INLINE static inline void tu_scatter_write32(uint32_t value, uint8_t *buf1, uint8_t len1,
uint8_t *buf2, uint8_t len2) {
for (uint8_t i = 0; i < len1; ++i) {
diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h
index e0e09f5ce..ba5b4afd1 100644
--- a/src/common/tusb_debug.h
+++ b/src/common/tusb_debug.h
@@ -117,12 +117,16 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3
}
}
- // not found return the key value in hex
+ #ifndef CFG_TUSB_DEBUG_PRINTF
+ // not found return the key value in hex if no custom printf is defined
static char not_found[11];
- if (snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long) key) <= 0) {
+ if (snprintf(not_found, sizeof(not_found), "0x%08lX", (unsigned long)key) <= 0) {
not_found[0] = 0;
}
return not_found;
+ #else
+ return "NotFound";
+ #endif
}
#endif // CFG_TUSB_DEBUG
diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c
index e97b6ccce..a92435912 100644
--- a/src/common/tusb_fifo.c
+++ b/src/common/tusb_fifo.c
@@ -59,7 +59,7 @@ TU_ATTR_ALWAYS_INLINE static inline void ff_unlock(osal_mutex_t mutex) {
//--------------------------------------------------------------------+
// Setup API
//--------------------------------------------------------------------+
-bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_size, bool overwritable) {
+bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, bool overwritable) {
// Limit index space to 2*depth - this allows for a fast "modulo" calculation
// but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable
// only if overflow happens once (important for unsupervised DMA applications)
@@ -72,7 +72,6 @@ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_si
f->buffer = (uint8_t *)buffer;
f->depth = depth;
- f->item_size = (uint16_t)(item_size & 0x7FFFu);
f->overwritable = overwritable;
f->rd_idx = 0u;
f->wr_idx = 0u;
@@ -114,172 +113,265 @@ void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) {
// Pull & Push
// copy data to/from fifo without updating read/write pointers
//--------------------------------------------------------------------+
-#ifdef CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
-// Copy to fifo from fixed address buffer (usually a rx register) with TU_FIFO_FIXED_ADDR_RW32 mode
-static void ff_push_fixed_addr_rw32(uint8_t *ff_buf, const volatile uint32_t *reg_rx, uint16_t len) {
- // Reading full available 32 bit words from const app address
- uint16_t full_words = len >> 2;
- while (full_words--) {
- const uint32_t tmp32 = *reg_rx;
- tu_unaligned_write32(ff_buf, tmp32);
- ff_buf += 4;
- }
+#if CFG_TUSB_FIFO_HWFIFO_API
+ #if CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE
+ #define HWFIFO_ADDR_NEXT_N(_hwfifo, _const, _n) _hwfifo = (_const volatile void *)((uintptr_t)(_hwfifo) + _n)
+ #else
+ #define HWFIFO_ADDR_NEXT_N(_hwfifo, _const, _n)
+ #endif
+
+ #define HWFIFO_ADDR_NEXT(_hwfifo, _const) HWFIFO_ADDR_NEXT_N(_hwfifo, _const, CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE)
- // Read the remaining 1-3 bytes from const app address
- const uint8_t bytes_rem = len & 0x03;
- if (bytes_rem) {
- const uint32_t tmp32 = *reg_rx;
- memcpy(ff_buf, &tmp32, bytes_rem);
+ #ifndef CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE
+static inline void stride_write(volatile void *hwfifo, const void *src, uint8_t data_stride) {
+ #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 4
+ if (data_stride == 4) {
+ *((volatile uint32_t *)hwfifo) = tu_unaligned_read32(src);
}
+ #endif
+ #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 2
+ if (data_stride == 2) {
+ *((volatile uint16_t *)hwfifo) = tu_unaligned_read16(src);
+ }
+ #endif
}
// Copy from fifo to fixed address buffer (usually a tx register) with TU_FIFO_FIXED_ADDR_RW32 mode
-static void ff_pull_fixed_addr_rw32(volatile uint32_t *reg_tx, const uint8_t *ff_buf, uint16_t len) {
- // Write full available 32 bit words to const address
- uint16_t full_words = len >> 2u;
- while (full_words--) {
- *reg_tx = tu_unaligned_read32(ff_buf);
- ff_buf += 4u;
+void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode) {
+ // Write full available 16/32 bit words to dest
+ const uint8_t data_stride = (access_mode != NULL) ? access_mode->data_stride : CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE;
+ while (len >= data_stride) {
+ stride_write(hwfifo, src, data_stride);
+ src += data_stride;
+ len -= data_stride;
+ HWFIFO_ADDR_NEXT(hwfifo, );
+ }
+
+ #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS
+ // 16-bit access is allowed for odd bytes
+ if (len >= 2) {
+ *((volatile uint16_t *)hwfifo) = tu_unaligned_read16(src);
+ src += 2;
+ len -= 2;
+ HWFIFO_ADDR_NEXT_N(hwfifo, , 2);
+ }
+ #endif
+
+ #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS
+ // 8-bit access is allowed for odd bytes
+ while (len > 0) {
+ *((volatile uint8_t *)hwfifo) = *src++;
+ len--;
+ HWFIFO_ADDR_NEXT_N(hwfifo, , 1);
}
+ #else
- // Write the remaining 1-3 bytes
- const uint8_t bytes_rem = len & 0x03;
- if (bytes_rem) {
- uint32_t tmp32 = 0u;
- memcpy(&tmp32, ff_buf, bytes_rem);
- *reg_tx = tmp32;
+ // Write odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit
+ if (len > 0) {
+ uint32_t tmp = 0u;
+ memcpy(&tmp, src, len);
+ stride_write(hwfifo, &tmp, data_stride);
+ HWFIFO_ADDR_NEXT(hwfifo, );
}
+ #endif
}
-#endif
+ #endif
-// send n items to fifo WITHOUT updating write pointer
-static void ff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr,
- tu_fifo_access_mode_t copy_mode) {
- const uint16_t lin_count = f->depth - wr_ptr;
- const uint16_t wrap_count = n - lin_count;
+ #ifndef CFG_TUSB_FIFO_HWFIFO_CUSTOM_READ
+static inline void stride_read(const volatile void *hwfifo, void *dest, uint8_t data_stride) {
+ (void)data_stride; // possible unused
+ #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 4
+ #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 4
+ if (data_stride == 4)
+ #endif
+ {
+ tu_unaligned_write32(dest, *((const volatile uint32_t *)hwfifo));
+ }
+ #endif
- uint16_t lin_bytes = lin_count * f->item_size;
- uint16_t wrap_bytes = wrap_count * f->item_size;
+ #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE & 2
+ #if CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE != 2
+ if (data_stride == 2)
+ #endif
+ {
+ tu_unaligned_write16(dest, *((const volatile uint16_t *)hwfifo));
+ }
+ #endif
+}
- // current buffer of fifo
- uint8_t *ff_buf = f->buffer + (wr_ptr * f->item_size);
+void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode) {
+ // Reading full available 16/32-bit hwfifo and write to fifo
+ const uint8_t data_stride = (access_mode != NULL) ? access_mode->data_stride : CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE;
+ while (len >= data_stride) {
+ stride_read(hwfifo, dest, data_stride);
+ dest += data_stride;
+ len -= data_stride;
+ HWFIFO_ADDR_NEXT(hwfifo, const);
+ }
- switch (copy_mode) {
- case TU_FIFO_INC_ADDR_RW8:
- if (n <= lin_count) {
- // Linear only
- memcpy(ff_buf, app_buf, n * f->item_size);
- } else {
- // Wrap around
- memcpy(ff_buf, app_buf, lin_bytes); // linear part
- memcpy(f->buffer, ((const uint8_t *)app_buf) + lin_bytes, wrap_bytes); // wrapped part
- }
- break;
+ #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS
+ // 16-bit access is allowed for odd bytes
+ if (len >= 2) {
+ tu_unaligned_write16(dest, *((const volatile uint16_t *)hwfifo));
+ dest += 2;
+ len -= 2;
+ HWFIFO_ADDR_NEXT_N(hwfifo, const, 2);
+ }
+ #endif
-#ifdef CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
- case TU_FIFO_FIXED_ADDR_RW32: {
- const volatile uint32_t *reg_rx = (volatile const uint32_t *)app_buf;
- if (n <= lin_count) {
- // Linear only
- ff_push_fixed_addr_rw32(ff_buf, reg_rx, n * f->item_size);
- } else {
- // Wrap around
+ #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS
+ // 8-bit access is allowed for odd bytes
+ while (len > 0) {
+ *dest++ = *((const volatile uint8_t *)hwfifo);
+ len--;
+ HWFIFO_ADDR_NEXT_N(hwfifo, const, 1);
+ }
+ #else
+ // Read odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit
+ if (len > 0) {
+ uint32_t tmp;
+ stride_read(hwfifo, &tmp, data_stride);
+ memcpy(dest, &tmp, len);
+ HWFIFO_ADDR_NEXT(hwfifo, const);
+ }
+ #endif
+}
+ #endif
+
+// push to sw fifo from hwfifo
+static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr,
+ const tu_hwfifo_access_t *access_mode) {
+ uint16_t lin_bytes = f->depth - wr_ptr;
+ uint16_t wrap_bytes = n - lin_bytes;
+ uint8_t *ff_buf = f->buffer + wr_ptr;
- // Write full words to linear part of buffer
- uint16_t lin_4n_bytes = lin_bytes & 0xFFFC;
- ff_push_fixed_addr_rw32(ff_buf, reg_rx, lin_4n_bytes);
- ff_buf += lin_4n_bytes;
+ const volatile void *hwfifo = (const volatile void *)app_buf;
+ if (n <= lin_bytes) {
+ // Linear only case
+ tu_hwfifo_read(hwfifo, ff_buf, n, access_mode);
+ } else {
+ // Wrap around case
- // There could be odd 1-3 bytes before the wrap-around boundary
- const uint8_t rem = lin_bytes & 0x03;
- if (rem > 0) {
- const uint8_t remrem = (uint8_t)tu_min16(wrap_bytes, 4 - rem);
- const uint32_t tmp32 = *reg_rx;
- tu_scatter_write32(tmp32, ff_buf, rem, f->buffer, remrem);
+ // Write full words to linear part of buffer
+ const uint8_t data_stride = access_mode->data_stride;
+ const uint32_t odd_mask = data_stride - 1;
+ uint16_t lin_even = lin_bytes & ~odd_mask;
+ tu_hwfifo_read(hwfifo, ff_buf, lin_even, access_mode);
+ HWFIFO_ADDR_NEXT_N(hwfifo, const, lin_even);
+ ff_buf += lin_even;
- wrap_bytes -= remrem;
- ff_buf = f->buffer + remrem; // wrap around
- } else {
- ff_buf = f->buffer; // wrap around to beginning
- }
+ // There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
+ // combine it with the wrapped part to form a full word for data stride
+ const uint8_t lin_odd = lin_bytes & odd_mask;
+ if (lin_odd > 0) {
+ const uint8_t wrap_odd = (uint8_t)tu_min16(wrap_bytes, data_stride - lin_odd);
+ uint8_t buf_temp[4];
+ tu_hwfifo_read(hwfifo, buf_temp, lin_odd + wrap_odd, access_mode);
+ HWFIFO_ADDR_NEXT(hwfifo, const);
- // Write data wrapped part
- if (wrap_bytes > 0) {
- ff_push_fixed_addr_rw32(ff_buf, reg_rx, wrap_bytes);
- }
+ for (uint8_t i = 0; i < lin_odd; ++i) {
+ ff_buf[i] = buf_temp[i];
+ }
+ for (uint8_t i = 0; i < wrap_odd; ++i) {
+ f->buffer[i] = buf_temp[lin_odd + i];
}
- break;
+
+ wrap_bytes -= wrap_odd;
+ ff_buf = f->buffer + wrap_odd; // wrap around
+ } else {
+ ff_buf = f->buffer; // wrap around to beginning
}
-#endif
- default:
- break; // unknown mode
+ // Write data wrapped part
+ if (wrap_bytes > 0) {
+ tu_hwfifo_read(hwfifo, ff_buf, wrap_bytes, access_mode);
+ }
}
}
-// get n items from fifo WITHOUT updating read pointer
-static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr, tu_fifo_access_mode_t copy_mode) {
- const uint16_t lin_count = f->depth - rd_ptr;
- const uint16_t wrap_count = n - lin_count; // only used if wrapped
+// pull from sw fifo to hwfifo
+static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr,
+ const tu_hwfifo_access_t *access_mode) {
+ uint16_t lin_bytes = f->depth - rd_ptr;
+ uint16_t wrap_bytes = n - lin_bytes; // only used if wrapped
+ const uint8_t *ff_buf = f->buffer + rd_ptr;
- uint16_t lin_bytes = lin_count * f->item_size;
- uint16_t wrap_bytes = wrap_count * f->item_size;
+ volatile void *hwfifo = (volatile void *)app_buf;
- // current buffer of fifo
- const uint8_t *ff_buf = f->buffer + (rd_ptr * f->item_size);
-
- switch (copy_mode) {
- case TU_FIFO_INC_ADDR_RW8:
- if (n <= lin_count) {
- // Linear only
- memcpy(app_buf, ff_buf, n * f->item_size);
- } else {
- // Wrap around
- memcpy(app_buf, ff_buf, lin_bytes); // linear part
- memcpy((uint8_t *)app_buf + lin_bytes, f->buffer, wrap_bytes); // wrapped part
- }
- break;
-
-#ifdef CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
- case TU_FIFO_FIXED_ADDR_RW32: {
- volatile uint32_t *reg_tx = (volatile uint32_t *)app_buf;
+ if (n <= lin_bytes) {
+ // Linear only case
+ tu_hwfifo_write(hwfifo, ff_buf, n, access_mode);
+ } else {
+ // Wrap around case
- if (n <= lin_count) {
- // Linear only
- ff_pull_fixed_addr_rw32(reg_tx, ff_buf, n * f->item_size);
- } else {
- // Wrap around case
+ // Read full words from linear part
+ const uint8_t data_stride = access_mode->data_stride;
+ const uint32_t odd_mask = data_stride - 1;
+ uint16_t lin_even = lin_bytes & ~odd_mask;
+ tu_hwfifo_write(hwfifo, ff_buf, lin_even, access_mode);
+ HWFIFO_ADDR_NEXT_N(hwfifo, , lin_even);
+ ff_buf += lin_even;
- // Read full words from linear part
- uint16_t lin_4n_bytes = lin_bytes & 0xFFFC;
- ff_pull_fixed_addr_rw32(reg_tx, ff_buf, lin_4n_bytes);
- ff_buf += lin_4n_bytes;
+ // There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
+ const uint8_t lin_odd = lin_bytes & odd_mask;
+ if (lin_odd > 0) {
+ const uint8_t wrap_odd = (uint8_t)tu_min16(wrap_bytes, data_stride - lin_odd);
- // There could be odd 1-3 bytes before the wrap-around boundary
- const uint8_t rem = lin_bytes & 0x03;
- if (rem > 0) {
- const uint8_t remrem = (uint8_t)tu_min16(wrap_bytes, 4 - rem);
- const uint32_t scatter32 = tu_scatter_read32(ff_buf, rem, f->buffer, remrem);
+ uint8_t buf_temp[4];
+ for (uint8_t i = 0; i < lin_odd; ++i) {
+ buf_temp[i] = ff_buf[i];
+ }
+ for (uint8_t i = 0; i < wrap_odd; ++i) {
+ buf_temp[lin_odd + i] = f->buffer[i];
+ }
- *reg_tx = scatter32;
+ tu_hwfifo_write(hwfifo, buf_temp, lin_odd + wrap_odd, access_mode);
+ HWFIFO_ADDR_NEXT(hwfifo, );
- wrap_bytes -= remrem;
- ff_buf = f->buffer + remrem; // wrap around
- } else {
- ff_buf = f->buffer; // wrap around to beginning
- }
+ wrap_bytes -= wrap_odd;
+ ff_buf = f->buffer + wrap_odd; // wrap around
+ } else {
+ ff_buf = f->buffer; // wrap around to beginning
+ }
- // Read data wrapped part
- if (wrap_bytes > 0) {
- ff_pull_fixed_addr_rw32(reg_tx, ff_buf, wrap_bytes);
- }
- }
- break;
+ // Read data wrapped part
+ if (wrap_bytes > 0) {
+ tu_hwfifo_write(hwfifo, ff_buf, wrap_bytes, access_mode);
}
+ }
+}
#endif
- default:
- break; // unknown mode
+// send n items to fifo WITHOUT updating write pointer
+static void ff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr) {
+ uint16_t lin_bytes = f->depth - wr_ptr;
+ uint16_t wrap_bytes = n - lin_bytes;
+ uint8_t *ff_buf = f->buffer + wr_ptr;
+
+ if (n <= lin_bytes) {
+ // Linear only case
+ memcpy(ff_buf, app_buf, n);
+ } else {
+ // Wrap around case
+ memcpy(ff_buf, app_buf, lin_bytes); // linear part
+ memcpy(f->buffer, ((const uint8_t *)app_buf) + lin_bytes, wrap_bytes); // wrapped part
+ }
+}
+
+// get n items from fifo WITHOUT updating read pointer
+static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr) {
+ uint16_t lin_bytes = f->depth - rd_ptr;
+ uint16_t wrap_bytes = n - lin_bytes; // only used if wrapped
+ const uint8_t *ff_buf = f->buffer + rd_ptr;
+
+ // single byte access
+ if (n <= lin_bytes) {
+ // Linear only
+ memcpy(app_buf, ff_buf, n);
+ } else {
+ // Wrap around
+ memcpy(app_buf, ff_buf, lin_bytes); // linear part
+ memcpy((uint8_t *)app_buf + lin_bytes, f->buffer, wrap_bytes); // wrapped part
}
}
@@ -332,7 +424,7 @@ static uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) {
// Works on local copies of w and r
// Must be protected by read mutex since in case of an overflow read pointer gets modified
uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx,
- tu_fifo_access_mode_t access_mode) {
+ const tu_hwfifo_access_t *access_mode) {
uint16_t count = tu_ff_overflow_count(f->depth, wr_idx, rd_idx);
if (count == 0) {
return 0; // nothing to peek
@@ -349,7 +441,16 @@ uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, ui
}
const uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);
- ff_pull_n(f, p_buffer, n, rd_ptr, access_mode);
+
+#if CFG_TUSB_FIFO_HWFIFO_API
+ if (access_mode != NULL) {
+ hwff_pull_n(f, p_buffer, n, rd_ptr, access_mode);
+ } else
+#endif
+ {
+ (void)access_mode;
+ ff_pull_n(f, p_buffer, n, rd_ptr);
+ }
return n;
}
@@ -357,13 +458,13 @@ uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, ui
// Read n items without removing it from the FIFO, correct read pointer if overflowed
uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n) {
ff_lock(f->mutex_rd);
- const uint16_t ret = tu_fifo_peek_n_access_mode(f, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_INC_ADDR_RW8);
+ const uint16_t ret = tu_fifo_peek_n_access_mode(f, p_buffer, n, f->wr_idx, f->rd_idx, NULL);
ff_unlock(f->mutex_rd);
return ret;
}
// Read n items from fifo with access mode
-uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, tu_fifo_access_mode_t access_mode) {
+uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, const tu_hwfifo_access_t *access_mode) {
ff_lock(f->mutex_rd);
// Peek the data: f->rd_idx might get modified in case of an overflow so we can not use a local variable
@@ -375,7 +476,8 @@ uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, tu_f
}
// Write n items to fifo with access mode
-uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, tu_fifo_access_mode_t access_mode) {
+uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n,
+ const tu_hwfifo_access_t *access_mode) {
if (n == 0) {
return 0;
}
@@ -401,8 +503,8 @@ uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n,
// function! Since it would end up in a race condition with read functions!
if (n >= f->depth) {
// Only copy last part
- if (access_mode == TU_FIFO_INC_ADDR_RW8) {
- buf8 += (n - f->depth) * f->item_size;
+ if (access_mode == NULL) {
+ buf8 += (n - f->depth);
} else {
// TODO should read from hw fifo to discard data, however reading an odd number could
// accidentally discard data.
@@ -437,7 +539,14 @@ uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n,
const uint16_t wr_ptr = idx2ptr(f->depth, wr_idx);
TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr);
- ff_push_n(f, buf8, n, wr_ptr, access_mode);
+#if CFG_TUSB_FIFO_HWFIFO_API
+ if (access_mode != NULL) {
+ hwff_push_n(f, buf8, n, wr_ptr, access_mode);
+ } else
+#endif
+ {
+ ff_push_n(f, buf8, n, wr_ptr);
+ }
f->wr_idx = advance_index(f->depth, wr_idx, n);
TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\r\n", f->wr_idx);
@@ -477,7 +586,7 @@ static bool ff_peek_local(tu_fifo_t *f, void *buf, uint16_t wr_idx, uint16_t rd_
}
const uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);
- memcpy(buf, f->buffer + (rd_ptr * f->item_size), f->item_size);
+ memcpy(buf, f->buffer + rd_ptr, 1);
return true;
}
@@ -512,7 +621,7 @@ bool tu_fifo_write(tu_fifo_t *f, const void *data) {
ret = false;
} else {
const uint16_t wr_ptr = idx2ptr(f->depth, wr_idx);
- memcpy(f->buffer + (wr_ptr * f->item_size), data, f->item_size);
+ memcpy(f->buffer + wr_ptr, data, 1);
f->wr_idx = advance_index(f->depth, wr_idx, 1);
ret = true;
}
diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h
index 2e2a0db6f..86ba59059 100644
--- a/src/common/tusb_fifo.h
+++ b/src/common/tusb_fifo.h
@@ -32,6 +32,25 @@
extern "C" {
#endif
+#include "common/tusb_common.h"
+#include "osal/osal.h"
+
+//--------------------------------------------------------------------+
+// Configuration
+//--------------------------------------------------------------------+
+// mutex is only needed for RTOS. For OS None, we don't get preempted
+#define CFG_FIFO_MUTEX OSAL_MUTEX_REQUIRED
+
+#define CFG_TUSB_FIFO_HWFIFO_API (CFG_TUD_EDPT_DEDICATED_HWFIFO || CFG_TUH_EDPT_DEDICATED_HWFIFO)
+
+#ifndef CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 0
+#endif
+
+#ifndef CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE
+ #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0
+#endif
+
// Due to the use of unmasked pointers, this FIFO does not suffer from losing
// one item slice. Furthermore, write and read operations are completely
// decoupled as write and read functions do not modify a common state. Henceforth,
@@ -41,17 +60,6 @@ extern "C" {
// read pointers can be updated from within a DMA ISR. Overflows are detectable
// within a certain number (see tu_fifo_overflow()).
-#include "common/tusb_common.h"
-#include "osal/osal.h"
-
-// mutex is only needed for RTOS
-// for OS None, we don't get preempted
-#define CFG_FIFO_MUTEX OSAL_MUTEX_REQUIRED
-
-#if CFG_TUD_EDPT_DEDICATED_HWFIFO || CFG_TUH_EDPT_DEDICATED_HWFIFO
- #define CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
-#endif
-
/* Write/Read "pointer" is in the range of: 0 .. depth - 1, and is used to get the fifo data.
* Write/Read "index" is always in the range of: 0 .. 2*depth-1
*
@@ -111,20 +119,16 @@ extern "C" {
typedef struct {
uint8_t *buffer; // buffer pointer
uint16_t depth; // max items
+ bool overwritable; // overwritable when full
+ // 1 byte padding here
- struct TU_ATTR_PACKED {
- uint16_t item_size : 15; // size of each item
- bool overwritable : 1; // ovwerwritable when full
- };
-
- volatile uint16_t wr_idx; // write index
+ volatile uint16_t wr_idx; // write index TODO maybe can drop volatile
volatile uint16_t rd_idx; // read index
#if OSAL_MUTEX_REQUIRED
osal_mutex_t mutex_wr;
osal_mutex_t mutex_rd;
#endif
-
} tu_fifo_t;
typedef struct {
@@ -134,29 +138,32 @@ typedef struct {
} linear, wrapped;
} tu_fifo_buffer_info_t;
-#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \
- { \
- .buffer = _buffer, \
- .depth = _depth, \
- .item_size = sizeof(_type), \
- .overwritable = _overwritable, \
+// Access mode for hardware fifo read/write
+typedef struct {
+ uint8_t data_stride;
+ uintptr_t param;
+} tu_hwfifo_access_t;
+
+#define TU_FIFO_INIT(_buffer, _depth, _overwritable) \
+ { \
+ .buffer = _buffer, \
+ .depth = _depth, \
+ .overwritable = _overwritable, \
}
-#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \
- uint8_t _name##_buf[_depth*sizeof(_type)]; \
- tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _type, _overwritable)
+#define TU_FIFO_DEF(_name, _depth, _overwritable) \
+ uint8_t _name##_buf[_depth]; \
+ tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _overwritable)
-// Write modes intended to allow special read and write functions to be able to
-// copy data to and from USB hardware FIFOs as needed for e.g. STM32s and others
-typedef enum {
- TU_FIFO_INC_ADDR_RW8, // increased address read/write by bytes - normal (default) mode
- TU_FIFO_FIXED_ADDR_RW32, // fixed address read/write by 4 bytes (word). Used for STM32 access into USB hardware FIFO
-} tu_fifo_access_mode_t;
+// Moving data from tusb_fifo <-> USB hardware FIFOs e.g. STM32s need to use a special stride mode which reads/writes
+// data in 2/4 byte chunks from/to a fixed address (USB FIFO register) instead of incrementing the address. For this use
+// read/write access_mode with stride_mode = true. The STRIDE DATA and ADDR stride must be configured with
+// CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE and CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE
//--------------------------------------------------------------------+
// Setup API
//--------------------------------------------------------------------+
-bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_size, bool overwritable);
+bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, bool overwritable);
void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
void tu_fifo_clear(tu_fifo_t *f);
@@ -191,7 +198,7 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
// peek() will correct/re-index read pointer in case of an overflowed fifo to form a full fifo
//--------------------------------------------------------------------+
uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx,
- tu_fifo_access_mode_t access_mode);
+ const tu_hwfifo_access_t *access_mode);
bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer);
uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n);
@@ -199,10 +206,10 @@ uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n);
// Read API
// peek() + advance read index
//--------------------------------------------------------------------+
-uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, tu_fifo_access_mode_t access_mode);
+uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, const tu_hwfifo_access_t *access_mode);
bool tu_fifo_read(tu_fifo_t *f, void *buffer);
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n) {
- return tu_fifo_read_n_access_mode(f, buffer, n, TU_FIFO_INC_ADDR_RW8);
+ return tu_fifo_read_n_access_mode(f, buffer, n, NULL);
}
// discard first n items from fifo i.e advance read pointer by n with mutex
@@ -212,12 +219,41 @@ uint16_t tu_fifo_discard_n(tu_fifo_t *f, uint16_t n);
//--------------------------------------------------------------------+
// Write API
//--------------------------------------------------------------------+
-uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, tu_fifo_access_mode_t access_mode);
+uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, const tu_hwfifo_access_t *access_mode);
bool tu_fifo_write(tu_fifo_t *f, const void *data);
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n) {
- return tu_fifo_write_n_access_mode(f, data, n, TU_FIFO_INC_ADDR_RW8);
+ return tu_fifo_write_n_access_mode(f, data, n, NULL);
+}
+
+//--------------------------------------------------------------------+
+// Hardware FIFO API
+// Special hardware FIFO/Buffer to hold USB data, usually requires certain access method these can be configured with
+// CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE (data width) and CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE (address increment)
+// Note: these usually has opposite direction (read/write) to/from our software FIFO (tu_fifo_t)
+//--------------------------------------------------------------------+
+TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_hwfifo_write_from_fifo(volatile void *hwfifo, tu_fifo_t *f, uint16_t n,
+ const tu_hwfifo_access_t *access_mode) {
+ const tu_hwfifo_access_t default_access = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE, .param = 0};
+ return tu_fifo_read_n_access_mode(f, (void *)(uintptr_t)hwfifo, n,
+ (access_mode != NULL) ? access_mode : &default_access);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_hwfifo_read_to_fifo(const volatile void *hwfifo, tu_fifo_t *f,
+ uint16_t n, const tu_hwfifo_access_t *access_mode) {
+ const tu_hwfifo_access_t default_access = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE, .param = 0};
+ return tu_fifo_write_n_access_mode(f, (const void *)(uintptr_t)hwfifo, n,
+ (access_mode != NULL) ? access_mode : &default_access);
}
+#if CFG_TUSB_FIFO_HWFIFO_API
+// read from hwfifo to buffer
+void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode);
+
+// write to hwfifo from buffer with access mode
+void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode);
+
+#endif
+
//--------------------------------------------------------------------+
// Internal Helper Local
// work on local copies of read/write indices in order to only access them once for re-entrancy
diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h
index 1e773bf96..1a4e517b7 100644
--- a/src/common/tusb_mcu.h
+++ b/src/common/tusb_mcu.h
@@ -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"
@@ -176,10 +184,15 @@
//--------------------------------------------------------------------+
// ST
//--------------------------------------------------------------------+
+#elif TU_CHECK_MCU(OPT_MCU_STM32C0)
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_STM32
+ #define CFG_TUSB_FSDEV_PMA_SIZE 2048u
+
#elif TU_CHECK_MCU(OPT_MCU_STM32F0)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+ #define CFG_TUSB_FSDEV_PMA_SIZE 1024u
#elif TU_CHECK_MCU(OPT_MCU_STM32F1)
// - F102, F103 use fsdev
@@ -195,7 +208,7 @@
defined(STM32F103xE) || defined(STM32F103xG)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+ #define CFG_TUSB_FSDEV_PMA_SIZE 512u
#else
#error "Unsupported STM32F1 mcu"
#endif
@@ -210,7 +223,16 @@
#elif TU_CHECK_MCU(OPT_MCU_STM32F3)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+
+ #if defined(STM32F302xB) || defined(STM32F302xC) || defined(STM32F303xB) || defined(STM32F303xC) || \
+ defined(STM32F373xC)
+ #define CFG_TUSB_FSDEV_PMA_SIZE 512u
+ #elif defined(STM32F302x6) || defined(STM32F302x8) || defined(STM32F302xD) || defined(STM32F302xE) || \
+ defined(STM32F303xD) || defined(STM32F303xE)
+ #define CFG_TUSB_FSDEV_PMA_SIZE 1024u
+ #else
+ #error "Unsupported STM32F3 mcu"
+ #endif
#elif TU_CHECK_MCU(OPT_MCU_STM32F4)
#define TUP_USBIP_DWC2
@@ -236,49 +258,63 @@
#define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE
#define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32
+#elif TU_CHECK_MCU(OPT_MCU_STM32G0)
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_STM32
+ #define CFG_TUSB_FSDEV_PMA_SIZE 2048u
+
+#elif TU_CHECK_MCU(OPT_MCU_STM32G4)
+ // Device controller
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_STM32
+ #define CFG_TUSB_FSDEV_PMA_SIZE 1024u
+
+ // TypeC controller
+ #define TUP_USBIP_TYPEC_STM32
+ #define TUP_TYPEC_RHPORTS_NUM 1
+
+#elif TU_CHECK_MCU(OPT_MCU_STM32H5)
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_STM32
+ #define CFG_TUSB_FSDEV_PMA_SIZE 2048u
+
#elif TU_CHECK_MCU(OPT_MCU_STM32H7)
- #include "stm32h7xx.h"
#define TUP_USBIP_DWC2
#define TUP_USBIP_DWC2_STM32
#define TUP_DCD_ENDPOINT_MAX 9
- #if __CORTEX_M == 7
+ #ifndef CORE_CM4
// Enable dcache if DMA is enabled
#define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE
#define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE
#define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32
#endif
-#elif TU_CHECK_MCU(OPT_MCU_STM32H5)
- #define TUP_USBIP_FSDEV
- #define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+#elif TU_CHECK_MCU(OPT_MCU_STM32H7RS, OPT_MCU_STM32N6)
+ #define TUP_USBIP_DWC2
+ #define TUP_USBIP_DWC2_STM32
-#elif TU_CHECK_MCU(OPT_MCU_STM32G4)
- // Device controller
- #define TUP_USBIP_FSDEV
- #define TUP_USBIP_FSDEV_STM32
+ // FS has 6, HS has 9
+ #define TUP_DCD_ENDPOINT_MAX 9
- // TypeC controller
- #define TUP_USBIP_TYPEC_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
- #define TUP_TYPEC_RHPORTS_NUM 1
+ // MCU with on-chip HS Phy
+ #define TUP_RHPORT_HIGHSPEED 1
-#elif TU_CHECK_MCU(OPT_MCU_STM32G0)
- #define TUP_USBIP_FSDEV
- #define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+ // Enable dcache if DMA is enabled
+ #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE
+ #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE
+ #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32
-#elif TU_CHECK_MCU(OPT_MCU_STM32C0)
+#elif TU_CHECK_MCU(OPT_MCU_STM32L0)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+ #define CFG_TUSB_FSDEV_PMA_SIZE 1024u
-#elif TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1)
+#elif TU_CHECK_MCU(OPT_MCU_STM32L1)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+ #define CFG_TUSB_FSDEV_PMA_SIZE 512u
#elif TU_CHECK_MCU(OPT_MCU_STM32L4)
// - L4x2, L4x3 use fsdev
@@ -295,28 +331,32 @@
defined(STM32L442xx) || defined(STM32L443xx) || defined(STM32L452xx) || defined(STM32L462xx)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+ #define CFG_TUSB_FSDEV_PMA_SIZE 1024u
#else
#error "Unsupported STM32L4 mcu"
#endif
-#elif TU_CHECK_MCU(OPT_MCU_STM32WB)
+#elif TU_CHECK_MCU(OPT_MCU_STM32L5)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+ #define CFG_TUSB_FSDEV_PMA_SIZE (1024u)
-#elif TU_CHECK_MCU(OPT_MCU_STM32WBA)
- #define TUP_USBIP_DWC2
- #define TUP_USBIP_DWC2_STM32
- #define TUP_DCD_ENDPOINT_MAX 9
- #define TUP_RHPORT_HIGHSPEED 1
+#elif TU_CHECK_MCU(OPT_MCU_STM32U0)
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_STM32
+ #define CFG_TUSB_FSDEV_PMA_SIZE 1024u
+
+#elif TU_CHECK_MCU(OPT_MCU_STM32U3)
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_STM32
+ #define CFG_TUSB_FSDEV_PMA_SIZE 2048u
#elif TU_CHECK_MCU(OPT_MCU_STM32U5)
+ // U535/545 use fsdev
#if defined(STM32U535xx) || defined(STM32U545xx)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
-
+ #define CFG_TUSB_FSDEV_PMA_SIZE 2048u
#else
#define TUP_USBIP_DWC2
#define TUP_USBIP_DWC2_STM32
@@ -331,35 +371,16 @@
#endif
#endif
-#elif TU_CHECK_MCU(OPT_MCU_STM32L5)
- #define TUP_USBIP_FSDEV
- #define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
-
-#elif TU_CHECK_MCU(OPT_MCU_STM32U0)
- #define TUP_USBIP_FSDEV
- #define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
-
-#elif TU_CHECK_MCU(OPT_MCU_STM32U3)
+#elif TU_CHECK_MCU(OPT_MCU_STM32WB)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
- #define TUP_DCD_ENDPOINT_MAX 8
+ #define CFG_TUSB_FSDEV_PMA_SIZE 1024u
-#elif TU_CHECK_MCU(OPT_MCU_STM32H7RS, OPT_MCU_STM32N6)
+#elif TU_CHECK_MCU(OPT_MCU_STM32WBA)
#define TUP_USBIP_DWC2
#define TUP_USBIP_DWC2_STM32
-
- // FS has 6, HS has 9
- #define TUP_DCD_ENDPOINT_MAX 9
-
- // MCU with on-chip HS Phy
- #define TUP_RHPORT_HIGHSPEED 1
-
- // Enable dcache if DMA is enabled
- #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE
- #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE
- #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32
+ #define TUP_DCD_ENDPOINT_MAX 9
+ #define TUP_RHPORT_HIGHSPEED 1
//--------------------------------------------------------------------+
// Sony
@@ -415,10 +436,6 @@
#define TUP_MCU_MULTIPLE_CORE 1
#endif
- // Disable slave if DMA is enabled
- #define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE
- #define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE
-
#elif TU_CHECK_MCU(OPT_MCU_ESP32P4)
#define TUP_USBIP_DWC2
#define TUP_USBIP_DWC2_ESP32
@@ -431,10 +448,6 @@
#define TUP_MCU_MULTIPLE_CORE 1
- // Disable slave if DMA is enabled
- #define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE
- #define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE
-
// Enable dcache if DMA is enabled
#define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE
#define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE
@@ -566,6 +579,7 @@
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_CH32
+ #define CFG_TUSB_FSDEV_PMA_SIZE 512u
// default to FSDEV for device
#if !defined(CFG_TUD_WCH_USBIP_USBFS)
@@ -611,15 +625,10 @@
//--------------------------------------------------------------------+
// ArteryTek
//--------------------------------------------------------------------+
-#elif TU_CHECK_MCU(OPT_MCU_AT32F403A_407)
+#elif TU_CHECK_MCU(OPT_MCU_AT32F403A_407, OPT_MCU_AT32F413)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_AT32
- #define TUP_DCD_ENDPOINT_MAX 8
-
-#elif TU_CHECK_MCU(OPT_MCU_AT32F413)
- #define TUP_USBIP_FSDEV
- #define TUP_USBIP_FSDEV_AT32
- #define TUP_DCD_ENDPOINT_MAX 8
+ #define CFG_TUSB_FSDEV_PMA_SIZE 512u
#elif TU_CHECK_MCU(OPT_MCU_AT32F415)
#define TUP_USBIP_DWC2
@@ -653,12 +662,21 @@
#define TUP_USBIP_DWC2_AT32
#define TUP_DCD_ENDPOINT_MAX 8
-#endif
-
//--------------------------------------------------------------------+
-// External USB controller
+// HPMicro
//--------------------------------------------------------------------+
+#elif TU_CHECK_MCU(OPT_MCU_HPM)
+ #define TUP_USBIP_CHIPIDEA_HS
+ #define TUP_USBIP_EHCI
+
+ #define TUP_DCD_ENDPOINT_MAX 16
+ #define TUP_RHPORT_HIGHSPEED 1
+ #define TU_ATTR_FAST_FUNC __attribute__((section(".fast")))
+
+#endif
+
+// External USB controller
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
#ifndef CFG_TUH_MAX3421_ENDPOINT_TOTAL
#define CFG_TUH_MAX3421_ENDPOINT_TOTAL (8 + 4 * (CFG_TUH_DEVICE_MAX - 1))
@@ -670,6 +688,10 @@
// Default Values
//--------------------------------------------------------------------+
+#if defined(TUP_USBIP_FSDEV)
+ #define TUP_DCD_ENDPOINT_MAX 8
+#endif
+
#ifndef TUP_MCU_MULTIPLE_CORE
#define TUP_MCU_MULTIPLE_CORE 0
#endif
diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h
index 587554e7f..c9e06361c 100644
--- a/src/common/tusb_verify.h
+++ b/src/common/tusb_verify.h
@@ -96,10 +96,12 @@
* - TU_VERIFY_1ARGS : return false if failed
* - TU_VERIFY_2ARGS : return provided value if failed
*------------------------------------------------------------------*/
-#define TU_VERIFY_DEFINE(_cond, _ret) \
- do { \
- if (!(_cond)) { return _ret; } \
- } while(0)
+#define TU_VERIFY_DEFINE(_cond, _ret) \
+ do { \
+ if (!(_cond)) { \
+ return _ret; \
+ } \
+ } while (0)
#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, false)
#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _ret)
diff --git a/src/device/usbd.c b/src/device/usbd.c
index e337a5000..1e21c667a 100644
--- a/src/device/usbd.c
+++ b/src/device/usbd.c
@@ -580,6 +580,8 @@ bool tud_deinit(uint8_t rhport) {
TU_LOG_USBD("USBD deinit on controller %u\r\n", rhport);
+ const uint8_t cfg_num = _usbd_dev.cfg_num;
+
// Deinit device controller driver
dcd_int_disable(rhport);
dcd_disconnect(rhport);
@@ -594,6 +596,10 @@ bool tud_deinit(uint8_t rhport) {
}
}
+ // Clear device data
+ tu_varclr(&_usbd_dev);
+ usbd_control_reset();
+
// Deinit device queue & task
osal_queue_delete(_usbd_q);
_usbd_q = NULL;
@@ -605,6 +611,11 @@ bool tud_deinit(uint8_t rhport) {
#endif
_usbd_rhport = RHPORT_INVALID;
+
+ if (cfg_num > 0) {
+ tud_umount_cb();
+ }
+
return true;
}
diff --git a/src/device/usbd.h b/src/device/usbd.h
index efde9377f..bd5a3c395 100644
--- a/src/device/usbd.h
+++ b/src/device/usbd.h
@@ -58,6 +58,7 @@ typedef union {
bool tud_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param);
// New API to replace tud_init() to init device stack on specific roothub port
+// Must be called in the same task/context as tud_task() if RTOS is used
bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init);
// Init device stack on roothub port
@@ -73,6 +74,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tud_init (uint8_t rhport) {
}
// Deinit device stack on roothub port
+// Must be called in the same task/context as tud_task() if RTOS is used
bool tud_deinit(uint8_t rhport);
// Check if device stack is already initialized
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 5b14a15cb..a725b7c8b 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -312,7 +312,8 @@ TU_ATTR_ALWAYS_INLINE static inline usbh_class_driver_t const *get_driver(uint8_
// Function Inline and Prototypes
//--------------------------------------------------------------------+
static bool enum_new_device(hcd_event_t* event);
-static void process_removed_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port);
+static void process_remove_event(hcd_event_t *event);
+static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port);
static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size);
static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
@@ -540,8 +541,8 @@ bool tuh_deinit(uint8_t rhport) {
hcd_deinit(rhport);
_usbh_data.controller_id = TUSB_INDEX_INVALID_8;
- // "unplug" all devices on this rhport (hub_addr = 0, hub_port = 0)
- process_removed_device(rhport, 0, 0);
+ // remove all devices on this rhport (hub_addr = 0, hub_port = 0)
+ remove_device_tree(rhport, 0, 0);
// deinit host stack if no controller is active
if (!tuh_inited()) {
@@ -605,6 +606,11 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
switch (event.event_id) {
case HCD_EVENT_DEVICE_ATTACH:
+ // Should we miss the hub detach event due to high traffic, Or due to physical debouncing, some devices can
+ // cause multiple attaches (actually reset) without detach event.
+ // Force remove currently mounted with the same bus info (rhport, hub addr, hub port) if exists
+ process_remove_event(&event);
+
// due to the shared control buffer, we must fully complete enumerating one device first.
// TODO better to have an separated queue for newly attached devices
if (_usbh_data.enumerating_daddr == TUSB_INDEX_INVALID_8) {
@@ -625,15 +631,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
case HCD_EVENT_DEVICE_REMOVE:
TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port);
- if (_usbh_data.enumerating_daddr == 0 &&
- event.rhport == _usbh_data.dev0_bus.rhport &&
- event.connection.hub_addr == _usbh_data.dev0_bus.hub_addr &&
- event.connection.hub_port == _usbh_data.dev0_bus.hub_port) {
- // dev0 is unplugged while enumerating (not yet assigned an address)
- usbh_device_close(_usbh_data.dev0_bus.rhport, 0);
- } else {
- process_removed_device(event.rhport, event.connection.hub_addr, event.connection.hub_port);
- }
+ process_remove_event(&event);
break;
case HCD_EVENT_XFER_COMPLETE: {
@@ -1321,8 +1319,22 @@ bool tuh_interface_set(uint8_t daddr, uint8_t itf_num, uint8_t itf_alt,
//--------------------------------------------------------------------+
// Detaching
//--------------------------------------------------------------------+
-// a device unplugged from rhport:hub_addr:hub_port
-static void process_removed_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) {
+
+// process detach event from rhport:hub_addr:hub_port
+static void process_remove_event(hcd_event_t *event) {
+ if (_usbh_data.enumerating_daddr == 0 &&
+ event->rhport == _usbh_data.dev0_bus.rhport &&
+ event->connection.hub_addr == _usbh_data.dev0_bus.hub_addr &&
+ event->connection.hub_port == _usbh_data.dev0_bus.hub_port) {
+ // dev0 is unplugged while enumerating (not yet assigned an address)
+ usbh_device_close(_usbh_data.dev0_bus.rhport, 0);
+ } else {
+ remove_device_tree(event->rhport, event->connection.hub_addr, event->connection.hub_port);
+ }
+}
+
+// remove a device at rhport:hub_addr:hub_port and all of its downstream
+static void remove_device_tree(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) {
// Find the all devices (star-network) under port that is unplugged
#if CFG_TUH_HUB
uint8_t removing_hubs[CFG_TUH_HUB] = { 0 };
@@ -1393,12 +1405,13 @@ static void process_removed_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub
// NOTE: due to the shared control buffer, we must complete enumerating
// one device before enumerating another one.
//--------------------------------------------------------------------+
-enum { // USB 2.0 specs 7.1.7 for timing
- ENUM_DEBOUNCING_DELAY_MS = 150, // T(ATTDB) minimum 100 ms for stable connection
- ENUM_RESET_ROOT_DELAY_MS = 50, // T(DRSTr) minimum 50 ms for reset from root port
- ENUM_RESET_HUB_DELAY_MS = 20, // T(DRST) 10-20 ms for hub reset
- ENUM_RESET_RECOVERY_DELAY_MS = 10, // T(RSTRCY) minimum 10 ms for reset recovery
- ENUM_SET_ADDRESS_RECOVERY_DELAY_MS = 2, // USB 2.0 Spec 9.2.6.3 min is 2 ms
+enum { // USB 2.0 specs 7.1.7 for timing
+ ENUM_DEBOUNCING_DELAY_MS = 150, // T(ATTDB) minimum 100 ms for stable connection
+ ENUM_RESET_ROOT_DELAY_MS = 50, // T(DRSTr) minimum 50 ms for reset from root port
+ ENUM_RESET_ROOT_POST_DELAY_MS = 2, // 2 ms delay after root port reset before getting speed/status
+ ENUM_RESET_HUB_DELAY_MS = 20, // T(DRST) 10-20 ms for hub reset
+ ENUM_RESET_RECOVERY_DELAY_MS = 10, // T(RSTRCY) minimum 10 ms for reset recovery
+ ENUM_SET_ADDRESS_RECOVERY_DELAY_MS = 2, // USB 2.0 Spec 9.2.6.3 min is 2 ms
};
enum {
@@ -1427,7 +1440,7 @@ enum {
static uint8_t enum_get_new_address(bool is_hub);
static bool enum_parse_configuration_desc (uint8_t dev_addr, tusb_desc_configuration_t const* desc_cfg);
-static void enum_full_complete(void);
+static void enum_full_complete(bool success);
static void process_enumeration(tuh_xfer_t* xfer);
// start a new enumeration process
@@ -1449,7 +1462,7 @@ static bool enum_new_device(hcd_event_t* event) {
if (!hcd_port_connect_status(dev0_bus->rhport)) {
TU_LOG_USBH("Device unplugged while debouncing\r\n");
- enum_full_complete();
+ enum_full_complete(false);
return true;
}
@@ -1457,10 +1470,11 @@ static bool enum_new_device(hcd_event_t* event) {
hcd_port_reset(dev0_bus->rhport);
tusb_time_delay_ms_api(ENUM_RESET_ROOT_DELAY_MS);
hcd_port_reset_end(dev0_bus->rhport);
+ tusb_time_delay_ms_api(ENUM_RESET_ROOT_POST_DELAY_MS);
if (!hcd_port_connect_status(dev0_bus->rhport)) {
// device unplugged while delaying
- enum_full_complete();
+ enum_full_complete(false);
return true;
}
@@ -1506,7 +1520,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
}
if (!retry) {
- enum_full_complete(); // complete as failed
+ enum_full_complete(false); // complete as failed
}
return;
}
@@ -1529,7 +1543,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
if (0 == port_status.status.connection) {
TU_LOG_USBH("Device unplugged from hub while debouncing\r\n");
- enum_full_complete();
+ enum_full_complete(false);
return;
}
@@ -1566,7 +1580,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
if (0 == port_status.status.connection) {
TU_LOG_USBH("Device unplugged from hub (not addressed yet)\r\n");
- enum_full_complete();
+ enum_full_complete(false);
return;
}
@@ -1582,7 +1596,11 @@ static void process_enumeration(tuh_xfer_t* xfer) {
// TODO probably doesn't need to open/close each enumeration
uint8_t const addr0 = 0;
- TU_ASSERT(usbh_edpt_control_open(addr0, 8),);
+ if (!usbh_edpt_control_open(addr0, 8)) {
+ // Stop enumeration gracefully
+ enum_full_complete(false);
+ TU_ASSERT(false,);
+ }
// Get first 8 bytes of device descriptor for control endpoint size
TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n");
@@ -1592,10 +1610,6 @@ static void process_enumeration(tuh_xfer_t* xfer) {
}
case ENUM_SET_ADDR: {
- // Due to physical debouncing, some devices can cause multiple attaches (actually reset) without detach event
- // Force remove currently mounted with the same bus info (rhport, hub addr, hub port) if exists
- process_removed_device(dev0_bus->rhport, dev0_bus->hub_addr, dev0_bus->hub_port);
-
const tusb_desc_device_t *desc_device = (const tusb_desc_device_t *) _usbh_epbuf.ctrl;
const uint8_t new_addr = enum_get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB);
TU_ASSERT(new_addr != 0,);
@@ -1620,7 +1634,12 @@ static void process_enumeration(tuh_xfer_t* xfer) {
usbh_device_close(dev0_bus->rhport, 0); // close dev0
- TU_ASSERT(usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0),); // open new control endpoint
+ if (!usbh_edpt_control_open(new_addr, new_dev->bMaxPacketSize0)) { // open new control endpoint
+ // Stop enumeration gracefully
+ clear_device(new_dev);
+ enum_full_complete(false);
+ TU_ASSERT(false,);
+ }
TU_LOG_USBH("Get Device Descriptor\r\n");
TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_epbuf.ctrl, sizeof(tusb_desc_device_t),
@@ -1774,6 +1793,12 @@ static void process_enumeration(tuh_xfer_t* xfer) {
TU_LOG_USBH("Device configured\r\n");
dev->configured = 1;
+ #if CFG_TUH_HUB
+ if (_usbh_data.dev0_bus.hub_addr != 0) {
+ hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr); // get next hub status
+ }
+ #endif
+
// Parse configuration & set up drivers
// driver_open() must not make any usb transfer
TU_ASSERT(enum_parse_configuration_desc(daddr, (tusb_desc_configuration_t*) _usbh_epbuf.ctrl),);
@@ -1787,7 +1812,7 @@ static void process_enumeration(tuh_xfer_t* xfer) {
}
default:
- enum_full_complete(); // stop enumeration if unknown state
+ enum_full_complete(false); // stop enumeration if unknown state
break;
}
}
@@ -1890,7 +1915,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) {
// all interface are configured
if (itf_num == CFG_TUH_INTERFACE_MAX) {
- enum_full_complete();
+ enum_full_complete(true);
if (is_hub_addr(dev_addr)) {
TU_LOG_USBH("HUB address = %u is mounted\r\n", dev_addr);
@@ -1901,12 +1926,14 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) {
}
}
-static void enum_full_complete(void) {
+static void enum_full_complete(bool success) {
+ (void)success;
// mark enumeration as complete
_usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8;
#if CFG_TUH_HUB
- if (_usbh_data.dev0_bus.hub_addr != 0) {
+ // Hub status is already requested in case of successful enumeration
+ if (_usbh_data.dev0_bus.hub_addr != 0 && !success) {
hub_edpt_status_xfer(_usbh_data.dev0_bus.hub_addr); // get next hub status
}
#endif
diff --git a/src/host/usbh.h b/src/host/usbh.h
index 4b6747848..d86efbcb2 100644
--- a/src/host/usbh.h
+++ b/src/host/usbh.h
@@ -95,18 +95,23 @@ enum {
TUH_CFGID_INVALID = 0,
TUH_CFGID_RPI_PIO_USB_CONFIGURATION = 100, // cfg_param: pio_usb_configuration_t
TUH_CFGID_MAX3421 = 200,
+ TUH_CFGID_FSDEV = 300,
};
typedef struct {
- uint8_t max_nak; // max NAK per endpoint per frame to save CPU/SPI bus usage
+ uint8_t max_nak; // max NAK per endpoint per frame to save CPU/SPI bus usage (0=unlimited)
uint8_t cpuctl; // R16: CPU Control Register
uint8_t pinctl; // R17: Pin Control Register. FDUPSPI bit is ignored
} tuh_configure_max3421_t;
+typedef struct {
+ uint8_t max_nak; // max NAK per endpoint per frame to save CPU usage (0=unlimited)
+} tuh_configure_fsdev_t;
+
typedef union {
// For TUH_CFGID_RPI_PIO_USB_CONFIGURATION use pio_usb_configuration_t
-
tuh_configure_max3421_t max3421;
+ tuh_configure_fsdev_t fsdev;
} tuh_configure_param_t;
//--------------------------------------------------------------------+
@@ -145,6 +150,7 @@ void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr);
bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param);
// New API to replace tuh_init() to init host stack on specific roothub port
+// Must be called in the same task/context as tuh_task() if RTOS is used
bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init);
// Init host stack
@@ -160,6 +166,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool tuh_init(uint8_t rhport) {
}
// Deinit host stack on rhport
+// Must be called in the same task/context as tuh_task() if RTOS is used
bool tuh_deinit(uint8_t rhport);
// Check if host stack is already initialized with any roothub ports
diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h
index 174136e38..6ab18ace8 100644
--- a/src/osal/osal_none.h
+++ b/src/osal/osal_none.h
@@ -157,21 +157,21 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd
typedef struct {
void (* interrupt_set)(bool enabled);
+ uint16_t item_size;
tu_fifo_t ff;
} osal_queue_def_t;
typedef osal_queue_def_t* osal_queue_t;
// _int_set is used as mutex in OS NONE (disable/enable USB ISR)
-#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
- uint8_t _name##_buf[_depth*sizeof(_type)]; \
- osal_queue_def_t _name = { \
- .interrupt_set = _int_set, \
- .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \
- }
+#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
+ uint8_t _name##_buf[_depth * sizeof(_type)]; \
+ osal_queue_def_t _name = {.interrupt_set = _int_set, \
+ .item_size = sizeof(_type), \
+ .ff = TU_FIFO_INIT(_name##_buf, _depth * sizeof(_type), false)}
TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) {
- (void) tu_fifo_clear(&qdef->ff);
+ tu_fifo_clear(&qdef->ff);
return (osal_queue_t) qdef;
}
@@ -184,7 +184,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v
(void) msec; // not used, always behave as msec = 0
qhdl->interrupt_set(false);
- const bool success = tu_fifo_read(&qhdl->ff, data);
+ const bool success = tu_fifo_read_n(&qhdl->ff, data, qhdl->item_size);
qhdl->interrupt_set(true);
return success;
@@ -195,7 +195,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void
qhdl->interrupt_set(false);
}
- const bool success = tu_fifo_write(&qhdl->ff, data);
+ const bool success = tu_fifo_write_n(&qhdl->ff, data, qhdl->item_size);
if (!in_isr) {
qhdl->interrupt_set(true);
diff --git a/src/osal/osal_pico.h b/src/osal/osal_pico.h
index f5385071a..79b728e9a 100644
--- a/src/osal/osal_pico.h
+++ b/src/osal/osal_pico.h
@@ -47,40 +47,39 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) {
// Spinlock API
//--------------------------------------------------------------------+
typedef critical_section_t osal_spinlock_t; // pico implement critical section with spinlock
-#define OSAL_SPINLOCK_DEF(_name, _int_set) \
- osal_spinlock_t _name
+#define OSAL_SPINLOCK_DEF(_name, _int_set) osal_spinlock_t _name
TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) {
critical_section_init(ctx);
}
TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) {
- (void) in_isr;
+ (void)in_isr;
critical_section_enter_blocking(ctx);
}
TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) {
- (void) in_isr;
+ (void)in_isr;
critical_section_exit(ctx);
}
//--------------------------------------------------------------------+
// Binary Semaphore API
//--------------------------------------------------------------------+
-typedef struct semaphore osal_semaphore_def_t, * osal_semaphore_t;
+typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t;
-TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) {
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) {
sem_init(semdef, 0, 255);
return semdef;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) {
- (void) semd_hdl;
+ (void)semd_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
- (void) in_isr;
+ (void)in_isr;
return sem_release(sem_hdl);
}
@@ -96,15 +95,15 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t s
// MUTEX API
// Within tinyusb, mutex is never used in ISR context
//--------------------------------------------------------------------+
-typedef struct mutex osal_mutex_def_t, * osal_mutex_t;
+typedef struct mutex osal_mutex_def_t, *osal_mutex_t;
-TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) {
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) {
mutex_init(mdef);
return mdef;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) {
- (void) mutex_hdl;
+ (void)mutex_hdl;
return true; // nothing to do
}
@@ -123,46 +122,45 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd
#include "common/tusb_fifo.h"
typedef struct {
- tu_fifo_t ff;
+ uint16_t item_size;
+ tu_fifo_t ff;
struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section
} osal_queue_def_t;
-typedef osal_queue_def_t* osal_queue_t;
+typedef osal_queue_def_t *osal_queue_t;
// role device/host is used by OS NONE for mutex (disable usb isr) only
-#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
- uint8_t _name##_buf[_depth*sizeof(_type)]; \
- osal_queue_def_t _name = { \
- .ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \
- }
+#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
+ uint8_t _name##_buf[_depth * sizeof(_type)]; \
+ osal_queue_def_t _name = {.item_size = sizeof(_type), .ff = TU_FIFO_INIT(_name##_buf, _depth * sizeof(_type), false)}
-TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) {
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) {
critical_section_init(&qdef->critsec);
- (void) tu_fifo_clear(&qdef->ff);
- return (osal_queue_t) qdef;
+ tu_fifo_clear(&qdef->ff);
+ return (osal_queue_t)qdef;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) {
- osal_queue_def_t* qdef = (osal_queue_def_t*) qhdl;
+ osal_queue_def_t *qdef = (osal_queue_def_t *)qhdl;
critical_section_deinit(&qdef->critsec);
return true;
}
-TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) {
- (void) msec; // not used, always behave as msec = 0
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) {
+ (void)msec; // not used, always behave as msec = 0
critical_section_enter_blocking(&qhdl->critsec);
- bool success = tu_fifo_read(&qhdl->ff, data);
+ bool success = tu_fifo_read_n(&qhdl->ff, data, qhdl->item_size);
critical_section_exit(&qhdl->critsec);
return success;
}
-TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const* data, bool in_isr) {
- (void) in_isr;
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, const void *data, bool in_isr) {
+ (void)in_isr;
critical_section_enter_blocking(&qhdl->critsec);
- bool success = tu_fifo_write(&qhdl->ff, data);
+ bool success = tu_fifo_write_n(&qhdl->ff, data, qhdl->item_size);
critical_section_exit(&qhdl->critsec);
return success;
diff --git a/src/portable/chipidea/ci_hs/ci_hs_hpm.h b/src/portable/chipidea/ci_hs/ci_hs_hpm.h
new file mode 100644
index 000000000..68211448c
--- /dev/null
+++ b/src/portable/chipidea/ci_hs/ci_hs_hpm.h
@@ -0,0 +1,54 @@
+/*
+ * 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_HPM_H_
+#define _CI_HS_HPM_H_
+
+#include "ci_hs_type.h"
+#include "hpm_soc.h"
+#include "hpm_interrupt.h"
+#include "hpm_usb_drv.h"
+
+static const ci_hs_controller_t _ci_controller[] =
+{
+ { .reg_base = HPM_USB0_BASE, .irqnum = IRQn_USB0},
+ #ifdef HPM_USB1_BASE
+ { .reg_base = HPM_USB1_BASE, .irqnum = IRQn_USB1},
+ #endif
+};
+
+#define CI_HS_REG(_port) ((ci_hs_regs_t*) _ci_controller[_port].reg_base)
+
+//------------- DCD -------------//
+#define CI_DCD_INT_ENABLE(_p) intc_m_enable_irq (_ci_controller[_p].irqnum)
+#define CI_DCD_INT_DISABLE(_p) intc_m_disable_irq(_ci_controller[_p].irqnum)
+
+//------------- HCD -------------//
+#define CI_HCD_INT_ENABLE(_p) intc_m_enable_irq (_ci_controller[_p].irqnum)
+#define CI_HCD_INT_DISABLE(_p) intc_m_disable_irq(_ci_controller[_p].irqnum)
+
+
+#endif
diff --git a/src/portable/chipidea/ci_hs/ci_hs_rw61x.h b/src/portable/chipidea/ci_hs/ci_hs_rw61x.h
new file mode 100644
index 000000000..114fe26c3
--- /dev/null
+++ b/src/portable/chipidea/ci_hs/ci_hs_rw61x.h
@@ -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
diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
index 4a5e5c91f..2bba32ada 100644
--- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
@@ -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"
@@ -55,6 +55,12 @@ bool dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
// MCX N9 only port 1 use this controller
#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
@@ -76,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 {
@@ -90,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
//--------------------------------------------------------------------+
@@ -117,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;
@@ -146,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
@@ -164,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
@@ -182,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;
}
@@ -214,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
@@ -222,92 +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)
+ usb_phy_init((USB_Type *)dcd_reg, false);
+ #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
- dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED;
-#endif
+ #if !TUD_OPT_HIGH_SPEED
+ dcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED;
+ #endif
+
+ #if TU_CHECK_MCU(OPT_MCU_HPM)
+ dcd_reg->PORTSC1 &= ~USB_PORTSC1_STS_MASK;
+ #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;
}
}
@@ -374,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));
}
@@ -471,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;
@@ -481,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);
@@ -523,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
}
@@ -586,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);
}
}
@@ -624,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);
+ }
}
}
@@ -709,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);
}
diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
index b5324a754..29ce0cd7f 100644
--- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
@@ -41,28 +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"
+
+#elif TU_CHECK_MCU(OPT_MCU_RW61X)
+
+ #include "ci_hs_rw61x.h"
#else
-#error "Unsupported MCUs"
+ #error "Unsupported MCUs"
#endif
//--------------------------------------------------------------------+
@@ -73,27 +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
+ usb_phy_init((USB_Type *)hcd_reg, true);
+ #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) {
diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c
index c33c970e4..9b2cf98be 100644
--- a/src/portable/ehci/ehci.c
+++ b/src/portable/ehci/ehci.c
@@ -40,10 +40,14 @@
#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
+#if TU_CHECK_MCU(OPT_MCU_HPM)
+#include "ci_hs_hpm.h"
+#endif
+
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
@@ -237,6 +241,14 @@ void hcd_port_reset(uint8_t rhport) {
// mask out Write-1-to-Clear bits
uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C;
+#if TU_CHECK_MCU(OPT_MCU_HPM)
+ if (usb_phy_get_line_state((USB_Type *)CI_HS_REG(rhport)) == usb_line_state2) {
+ portsc |= USB_PORTSC1_STS_MASK;
+ } else {
+ portsc &= ~USB_PORTSC1_STS_MASK;
+ }
+#endif
+
// EHCI Table 2-16 PortSC
// when software writes Port Reset bit to a one, it must also write a zero to the Port Enable bit.
portsc &= ~(EHCI_PORTSC_MASK_PORT_EANBLED);
diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c
index ad20d64bd..3827be318 100644
--- a/src/portable/mentor/musb/dcd_musb.c
+++ b/src/portable/mentor/musb/dcd_musb.c
@@ -170,68 +170,6 @@ TU_ATTR_ALWAYS_INLINE static inline void hwfifo_flush(musb_regs_t* musb, unsigne
}
}
-static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
-{
- volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo;
- uintptr_t addr = (uintptr_t)buf;
- while (len >= 4) {
- reg->u32 = *(uint32_t const *)addr;
- addr += 4;
- len -= 4;
- }
- if (len >= 2) {
- reg->u16 = *(uint16_t const *)addr;
- addr += 2;
- len -= 2;
- }
- if (len) {
- reg->u8 = *(uint8_t const *)addr;
- }
-}
-
-static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len)
-{
- volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo;
- uintptr_t addr = (uintptr_t)buf;
- while (len >= 4) {
- *(uint32_t *)addr = reg->u32;
- addr += 4;
- len -= 4;
- }
- if (len >= 2) {
- *(uint16_t *)addr = reg->u16;
- addr += 2;
- len -= 2;
- }
- if (len) {
- *(uint8_t *)addr = reg->u8;
- }
-}
-
-static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir)
-{
- static const struct {
- void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
- void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n);
- void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len);
- } ops[] = {
- /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet},
- /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet},
- };
- tu_fifo_buffer_info_t info;
- ops[dir].tu_fifo_get_info(f, &info);
- unsigned total_len = len;
- len = TU_MIN(total_len, info.linear.len);
- ops[dir].pipe_read_write(info.linear.ptr, fifo, len);
- unsigned rem = total_len - len;
- if (rem) {
- len = TU_MIN(rem, info.wrapped.len);
- ops[dir].pipe_read_write(info.wrapped.ptr, fifo, len);
- rem -= len;
- }
- ops[dir].tu_fifo_advance(f, total_len - rem);
-}
-
static void process_setup_packet(uint8_t rhport) {
musb_regs_t* musb_regs = MUSB_REGS(rhport);
@@ -277,9 +215,9 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr)
// TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem);
if (len) {
if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) {
- pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_IN);
+ tu_hwfifo_write_from_fifo(fifo_ptr, (tu_fifo_t *)buf, len, NULL);
} else {
- pipe_write_packet(buf, fifo_ptr, len);
+ tu_hwfifo_write(fifo_ptr, buf, len, NULL);
pipe->buf = buf + len;
}
pipe->remaining = rem - len;
@@ -308,9 +246,9 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr)
volatile void *fifo_ptr = &musb_regs->fifo[epnum];
if (len) {
if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) {
- pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_OUT);
+ tu_hwfifo_read_to_fifo(fifo_ptr, (tu_fifo_t *)buf, len, NULL);
} else {
- pipe_read_packet(buf, fifo_ptr, len);
+ tu_hwfifo_read(fifo_ptr, buf, len, NULL);
pipe->buf = buf + len;
}
pipe->remaining = rem - len;
@@ -378,7 +316,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_
const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes);
volatile void *fifo_ptr = &musb_regs->fifo[0];
if (dir_in) {
- pipe_write_packet(buffer, fifo_ptr, len);
+ tu_hwfifo_write(fifo_ptr, buffer, len, NULL);
_dcd.pipe0.buf = buffer + len;
_dcd.pipe0.length = len;
@@ -458,7 +396,7 @@ static void process_ep0(uint8_t rhport)
const unsigned rem = _dcd.pipe0.remaining;
const unsigned len = TU_MIN(TU_MIN(rem, 64), vld);
volatile void *fifo_ptr = &musb_regs->fifo[0];
- pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len);
+ tu_hwfifo_read(fifo_ptr, _dcd.pipe0.buf, len, NULL);
_dcd.pipe0.remaining = rem - len;
_dcd.remaining_ctrl -= len;
diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c
index 1faac2aa8..4115eecc5 100644
--- a/src/portable/microchip/samg/dcd_samg.c
+++ b/src/portable/microchip/samg/dcd_samg.c
@@ -437,7 +437,7 @@ void dcd_int_handler(uint8_t rhport)
// write to EP fifo
#if 0 // TODO support dcd_edpt_xfer_fifo
if (xfer->ff) {
- tu_fifo_read_n_access_mode(xfer->ff, (void *) &UDP->UDP_FDR[epnum], xact_len, TU_FIFO_FIXED_ADDR_RW32);
+ tu_fifo_read_n_access_mode(xfer->ff, (void *) &UDP->UDP_FDR[epnum], xact_len, true);
}
else
#endif
@@ -471,7 +471,7 @@ void dcd_int_handler(uint8_t rhport)
// Read from EP fifo
#if 0 // TODO support dcd_edpt_xfer_fifo API
if (xfer->ff) {
- tu_fifo_write_n_access_mode(xfer->ff, (const void *) &UDP->UDP_FDR[epnum], xact_len, TU_FIFO_FIXED_ADDR_RW32);
+ tu_fifo_write_n_access_mode(xfer->ff, (const void *) &UDP->UDP_FDR[epnum], xact_len, true);
}
else
#endif
diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c
index 91b876718..ca17d6251 100644
--- a/src/portable/nuvoton/nuc505/dcd_nuc505.c
+++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c
@@ -194,7 +194,7 @@ static void dcd_userEP_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep)
/* provided buffers are thankfully 32-bit aligned, allowing most data to be transferred as 32-bit */
#if 0 // TODO support dcd_edpt_xfer_fifo API
if (xfer->ff) {
- tu_fifo_read_n_access_mode(xfer->ff, (void *) (&ep->EPDAT_BYTE), bytes_now, TU_FIFO_FIXED_ADDR_RW32);
+ tu_fifo_read_n_access_mode(xfer->ff, (void *) (&ep->EPDAT_BYTE), bytes_now, true);
}
else
#endif
@@ -696,7 +696,7 @@ void dcd_int_handler(uint8_t rhport)
/* copy the data from the PC to the previously provided buffer */
#if 0 // TODO support dcd_edpt_xfer_fifo API
if (xfer->ff) {
- tu_fifo_write_n_access_mode(xfer->ff, (const void *) &ep->EPDAT_BYTE, tu_min16(available_bytes, xfer->total_bytes - xfer->out_bytes_so_far), TU_FIFO_FIXED_ADDR_RW32);
+ tu_fifo_write_n_access_mode(xfer->ff, (const void *) &ep->EPDAT_BYTE, tu_min16(available_bytes, xfer->total_bytes - xfer->out_bytes_so_far), true);
}
else
#endif
diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c
index 779c7bc3d..e2a51a5ca 100644
--- a/src/portable/renesas/rusb2/dcd_rusb2.c
+++ b/src/portable/renesas/rusb2/dcd_rusb2.c
@@ -30,25 +30,7 @@
#if CFG_TUD_ENABLED && defined(TUP_USBIP_RUSB2)
#include "device/dcd.h"
-#include "rusb2_type.h"
-
-#if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)
- #include "rusb2_rx.h"
-#elif TU_CHECK_MCU(OPT_MCU_RAXXX)
- #include "rusb2_ra.h"
- #if defined(RENESAS_CORTEX_M23)
- #define D0FIFO CFIFO
- #define D0FIFOSEL CFIFOSEL
- #define D0FIFOSEL_b CFIFOSEL_b
- #define D1FIFOSEL CFIFOSEL
- #define D1FIFOSEL_b CFIFOSEL_b
- #define D0FIFOCTR CFIFOCTR
- #define D0FIFOCTR_b CFIFOCTR_b
- #endif
-
-#else
- #error "Unsupported MCU"
-#endif
+#include "rusb2_common.h"
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM
@@ -161,106 +143,11 @@ static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) {
}
//--------------------------------------------------------------------+
-// Pipe FIFO
-//--------------------------------------------------------------------+
-
-// Write data buffer --> hw fifo
-static void pipe_write_packet(rusb2_reg_t * rusb, void *buf, volatile void *fifo, unsigned len)
-{
- (void) rusb;
-
- volatile uint16_t *ff16;
- volatile uint8_t *ff8;
-
- // Highspeed FIFO is 32-bit
- if ( rusb2_is_highspeed_reg(rusb) ) {
- // TODO 32-bit access for better performance
- ff16 = (volatile uint16_t*) ((uintptr_t) fifo+2);
- ff8 = (volatile uint8_t *) ((uintptr_t) fifo+3);
- }else {
- ff16 = (volatile uint16_t*) fifo;
- ff8 = ((volatile uint8_t*) fifo);
- }
-
- uint8_t const* buf8 = (uint8_t const*) buf;
-
- while (len >= 2) {
- *ff16 = tu_unaligned_read16(buf8);
- buf8 += 2;
- len -= 2;
- }
-
- if (len > 0) {
- *ff8 = *buf8;
- ++buf8;
- }
-}
-
-// Read data buffer <-- hw fifo
-static void pipe_read_packet(rusb2_reg_t * rusb, void *buf, volatile void *fifo, unsigned len)
-{
- (void) rusb;
-
- // TODO 16/32-bit access for better performance
-
- uint8_t *p = (uint8_t*)buf;
- volatile uint8_t *reg = (volatile uint8_t*)fifo; /* byte access is always at base register address */
- while (len--) *p++ = *reg;
-}
-
-// Write data sw fifo --> hw fifo
-static void pipe_write_packet_ff(rusb2_reg_t * rusb, tu_fifo_t *f, volatile void *fifo, uint16_t total_len) {
- tu_fifo_buffer_info_t info;
- tu_fifo_get_read_info(f, &info);
-
- uint16_t cnt_lin = tu_min16(total_len, info.linear.len);
- uint16_t cnt_wrap = tu_min16(total_len - cnt_lin, info.wrapped.len);
- uint16_t const cnt_written = cnt_lin + cnt_wrap;
-
- // Ensure only the last write is odd if total_len is odd
- if (cnt_wrap == 0) {
- pipe_write_packet(rusb, info.linear.ptr, fifo, cnt_lin);
- } else {
- pipe_write_packet(rusb, info.linear.ptr, fifo, cnt_lin & ~1);
-
- if (cnt_lin & 1) {
- uint8_t glue[2] = {info.linear.ptr[cnt_lin & ~1], info.wrapped.ptr[0]};
- pipe_write_packet(rusb, glue, fifo, 2);
- cnt_wrap--;
- info.wrapped.ptr++;
- }
-
- pipe_write_packet(rusb, info.wrapped.ptr, fifo, cnt_wrap);
- }
- tu_fifo_advance_read_pointer(f, cnt_written);
-}
-
-// Read data sw fifo <-- hw fifo
-static void pipe_read_packet_ff(rusb2_reg_t * rusb, tu_fifo_t *f, volatile void *fifo, uint16_t total_len) {
- tu_fifo_buffer_info_t info;
- tu_fifo_get_write_info(f, &info);
-
- uint16_t count = tu_min16(total_len, info.linear.len);
- pipe_read_packet(rusb, info.linear.ptr, fifo, count);
-
- uint16_t rem = total_len - count;
- if (rem) {
- rem = tu_min16(rem, info.wrapped.len);
- pipe_read_packet(rusb, info.wrapped.ptr, fifo, rem);
- count += rem;
- }
-
- tu_fifo_advance_write_pointer(f, count);
-}
-
-//--------------------------------------------------------------------+
// Pipe Transfer
//--------------------------------------------------------------------+
-
-static bool pipe0_xfer_in(rusb2_reg_t* rusb)
-{
- pipe_state_t *pipe = &_dcd.pipe[0];
- const unsigned rem = pipe->remaining;
+static bool pipe0_xfer_in(rusb2_reg_t *rusb) {
+ pipe_state_t *pipe = &_dcd.pipe[0];
+ const unsigned rem = pipe->remaining;
if (!rem) {
pipe->buf = NULL;
@@ -272,11 +159,25 @@ static bool pipe0_xfer_in(rusb2_reg_t* rusb)
void *buf = pipe->buf;
if (len) {
+ // uint16_t fifo_sel = RUSB2_CFIFOSEL_ISEL_WRITE | FIFOSEL_BIGEND;
+ tu_hwfifo_access_t access_mode;
+ access_mode.param = (uintptr_t)rusb;
+ //
+ if (rusb2_is_highspeed_reg(rusb)) {
+ // fifo_sel |= RUSB2_FIFOSEL_MBW_32BIT;
+ access_mode.data_stride = 4u;
+ } else {
+ // fifo_sel |= RUSB2_FIFOSEL_MBW_16BIT;
+ access_mode.data_stride = 2u;
+ }
+ // rusb->CFIFOSEL = fifo_sel;
+ // while (0 == (rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) {}
+
if (pipe->ff) {
- pipe_write_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len);
+ tu_hwfifo_write_from_fifo(&rusb->CFIFO, (tu_fifo_t *)buf, len, &access_mode);
} else {
- pipe_write_packet(rusb, buf, (volatile void*)&rusb->CFIFO, len);
- pipe->buf = (uint8_t*)buf + len;
+ tu_hwfifo_write(&rusb->CFIFO, buf, len, &access_mode);
+ pipe->buf = (uint8_t *)buf + len;
}
}
@@ -288,10 +189,9 @@ static bool pipe0_xfer_in(rusb2_reg_t* rusb)
return false;
}
-static bool pipe0_xfer_out(rusb2_reg_t* rusb)
-{
- pipe_state_t *pipe = &_dcd.pipe[0];
- const unsigned rem = pipe->remaining;
+static bool pipe0_xfer_out(rusb2_reg_t *rusb) {
+ pipe_state_t *pipe = &_dcd.pipe[0];
+ const unsigned rem = pipe->remaining;
const uint16_t mps = edpt0_max_packet_size(rusb);
const uint16_t vld = rusb->CFIFOCTR_b.DTLN;
@@ -299,11 +199,14 @@ static bool pipe0_xfer_out(rusb2_reg_t* rusb)
void *buf = pipe->buf;
if (len) {
+ tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u),
+ .param = (uintptr_t)rusb};
+
if (pipe->ff) {
- pipe_read_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len);
+ tu_hwfifo_read_to_fifo(&rusb->CFIFO, (tu_fifo_t *)buf, len, &access_mode);
} else {
- pipe_read_packet(rusb, buf, (volatile void*)&rusb->CFIFO, len);
- pipe->buf = (uint8_t*)buf + len;
+ tu_hwfifo_read(&rusb->CFIFO, buf, len, &access_mode);
+ pipe->buf = (uint8_t *)buf + len;
}
}
@@ -330,18 +233,27 @@ static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num)
return true;
}
- rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
- const uint16_t mps = edpt_max_packet_size(rusb, num);
+ const uint16_t fifo_sel = num | FIFOSEL_BIGEND;
+ const bool is_highspeed = rusb2_is_highspeed_reg(rusb);
+ if (is_highspeed) {
+ rusb->D0FIFOSEL = fifo_sel | RUSB2_FIFOSEL_MBW_32BIT;
+ } else {
+ rusb->D0FIFOSEL = fifo_sel | RUSB2_FIFOSEL_MBW_16BIT;
+ }
+
+ const uint16_t mps = edpt_max_packet_size(rusb, num);
pipe_wait_for_ready(rusb, num);
- const uint16_t len = tu_min16(rem, mps);
- void *buf = pipe->buf;
+ uint16_t len = tu_min16(rem, mps);
+ void *buf = pipe->buf;
if (len) {
+ tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u),
+ .param = (uintptr_t)rusb};
if (pipe->ff) {
- pipe_write_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len);
+ tu_hwfifo_write_from_fifo(&rusb->D0FIFO, (tu_fifo_t *)buf, len, &access_mode);
} else {
- pipe_write_packet(rusb, buf, (volatile void*)&rusb->D0FIFO, len);
- pipe->buf = (uint8_t*)buf + len;
+ tu_hwfifo_write(&rusb->D0FIFO, buf, len, &access_mode);
+ pipe->buf = (uint8_t *)buf + len;
}
}
@@ -362,7 +274,14 @@ static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num)
pipe_state_t *pipe = &_dcd.pipe[num];
const uint16_t rem = pipe->remaining;
- rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT;
+ uint16_t fifo_sel = num | FIFOSEL_BIGEND;
+ if (rusb2_is_highspeed_reg(rusb)) {
+ fifo_sel |= RUSB2_FIFOSEL_MBW_32BIT;
+ } else {
+ fifo_sel |= RUSB2_FIFOSEL_MBW_16BIT;
+ }
+ rusb->D0FIFOSEL = fifo_sel;
+
const uint16_t mps = edpt_max_packet_size(rusb, num);
pipe_wait_for_ready(rusb, num);
@@ -371,11 +290,13 @@ static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num)
void *buf = pipe->buf;
if (len) {
+ tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u),
+ .param = (uintptr_t)rusb};
if (pipe->ff) {
- pipe_read_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len);
+ tu_hwfifo_read_to_fifo(&rusb->D0FIFO, (tu_fifo_t *)buf, len, &access_mode);
} else {
- pipe_read_packet(rusb, buf, (volatile void*)&rusb->D0FIFO, len);
- pipe->buf = (uint8_t*)buf + len;
+ tu_hwfifo_read(&rusb->D0FIFO, buf, len, &access_mode);
+ pipe->buf = (uint8_t *)buf + len;
}
}
@@ -428,28 +349,29 @@ static void process_status_completion(uint8_t rhport)
dcd_event_xfer_complete(rhport, ep_addr, 0, XFER_RESULT_SUCCESS, true);
}
-static bool process_pipe0_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes)
-{
+static bool process_pipe0_xfer(rusb2_reg_t *rusb, int buffer_type, uint8_t ep_addr, void *buffer,
+ uint16_t total_bytes) {
+ uint16_t fifo_sel =
+ (rusb2_is_highspeed_reg(rusb) ? RUSB2_FIFOSEL_MBW_32BIT : RUSB2_FIFOSEL_MBW_16BIT) | FIFOSEL_BIGEND;
+
/* configure fifo direction and access unit settings */
- if ( ep_addr ) {
- /* IN, 2 bytes */
- rusb->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT |
- (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
- while ( !(rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ) {}
- } else {
- /* OUT, a byte */
- rusb->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT;
- while ( rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE ) {}
+ if (ep_addr != 0) {
+ // Control IN
+ fifo_sel |= RUSB2_CFIFOSEL_ISEL_WRITE;
+ }
+ rusb->CFIFOSEL = fifo_sel;
+ while ((rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) != (fifo_sel & RUSB2_CFIFOSEL_ISEL_WRITE)) {
+ // wait until ISEL_WRITE take effect
}
pipe_state_t *pipe = &_dcd.pipe[0];
- pipe->ff = buffer_type;
- pipe->length = total_bytes;
- pipe->remaining = total_bytes;
+ pipe->ff = buffer_type;
+ pipe->length = total_bytes;
+ pipe->remaining = total_bytes;
- if ( total_bytes ) {
+ if (total_bytes) {
pipe->buf = buffer;
- if ( ep_addr ) {
+ if (ep_addr) {
/* IN */
TU_ASSERT(rusb->DCPCTR_b.BSTS && (rusb->USBREQ & 0x80));
pipe0_xfer_in(rusb);
@@ -525,7 +447,7 @@ static bool process_edpt_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_add
static void process_pipe0_bemp(uint8_t rhport)
{
rusb2_reg_t* rusb = RUSB2_REG(rhport);
- bool completed = pipe0_xfer_in(rusb);
+ bool completed = pipe0_xfer_in(rusb);
if (completed) {
pipe_state_t *pipe = &_dcd.pipe[0];
dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN),
@@ -621,18 +543,20 @@ static void process_set_address(uint8_t rhport)
{
rusb2_reg_t* rusb = RUSB2_REG(rhport);
const uint16_t addr = rusb->USBADDR_b.USBADDR;
- if (!addr) return;
+ if (!addr) {
+ return;
+ }
const tusb_control_request_t setup_packet = {
#if defined(__CCRX__)
.bmRequestType = { 0 }, /* Note: CCRX needs the braces over this struct member */
-#else
- .bmRequestType = 0,
-#endif
- .bRequest = TUSB_REQ_SET_ADDRESS,
- .wValue = addr,
- .wIndex = 0,
- .wLength = 0,
+ #else
+ .bmRequestType = 0,
+ #endif
+ .bRequest = TUSB_REQ_SET_ADDRESS,
+ .wValue = addr,
+ .wIndex = 0,
+ .wLength = 0,
};
dcd_event_setup_received(rhport, (const uint8_t *) &setup_packet, true);
@@ -899,7 +823,6 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
{
(void) is_isr;
// USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1
- TU_ASSERT(ff->item_size == 1);
rusb2_reg_t* rusb = RUSB2_REG(rhport);
dcd_int_disable(rhport);
@@ -912,7 +835,9 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
{
volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr);
- if (!ctr) return;
+ if (!ctr) {
+ return;
+ }
dcd_int_disable(rhport);
const uint32_t pid = *ctr & 0x3;
*ctr = pid | RUSB2_PIPE_CTR_PID_STALL;
@@ -924,7 +849,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
{
rusb2_reg_t * rusb = RUSB2_REG(rhport);
volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr);
- if (!ctr) return;
+ if (!ctr) {
+ return;
+ }
dcd_int_disable(rhport);
*ctr = RUSB2_PIPE_CTR_SQCLR_Msk;
diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c
index 6f6d27d0e..4c3315044 100644
--- a/src/portable/renesas/rusb2/hcd_rusb2.c
+++ b/src/portable/renesas/rusb2/hcd_rusb2.c
@@ -31,17 +31,9 @@
#include "host/hcd.h"
#include "host/usbh.h"
-#include "rusb2_type.h"
+#include "rusb2_common.h"
-#if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)
- #include "rusb2_rx.h"
-#elif TU_CHECK_MCU(OPT_MCU_RAXXX)
- #include "rusb2_ra.h"
-#else
- #error "Unsupported MCU"
-#endif
-
-#define TU_RUSB2_HCD_DBG 2
+ #define TU_RUSB2_HCD_DBG 2
//--------------------------------------------------------------------+
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
@@ -76,12 +68,10 @@ typedef struct TU_ATTR_PACKED {
TU_ATTR_PACKED_END // End of definition of packed structs (used by the CCRX toolchain)
TU_ATTR_BIT_FIELD_ORDER_END
-typedef struct
-{
- bool need_reset; /* The device has not been reset after connection. */
+typedef struct {
pipe_state_t pipe[PIPE_COUNT];
- uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */
- uint8_t ctl_mps[5]; /* EP0 max packet size for each device */
+ uint8_t ep[4][2][15]; /* a lookup table for a pipe index from an endpoint address */
+ uint8_t ctl_mps[5]; /* EP0 max packet size for each device */
} hcd_data_t;
//--------------------------------------------------------------------+
@@ -166,29 +156,6 @@ static inline void pipe_wait_for_ready(rusb2_reg_t* rusb, unsigned num)
while (!rusb->D0FIFOCTR_b.FRDY) {}
}
-static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
-{
- // NOTE: unlike DCD, Highspeed 32-bit FIFO does not need to adjust the fifo address
- volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo;
- uintptr_t addr = (uintptr_t)buf;
- while (len >= 2) {
- reg->u16 = *(const uint16_t *)addr;
- addr += 2;
- len -= 2;
- }
- if (len) {
- reg->u8 = *(const uint8_t *)addr;
- ++addr;
- }
-}
-
-static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len)
-{
- uint8_t *p = (uint8_t*)buf;
- volatile uint8_t *reg = (volatile uint8_t*)fifo; /* byte access is always at base register address */
- while (len--) *p++ = *reg;
-}
-
static bool pipe0_xfer_in(rusb2_reg_t* rusb)
{
pipe_state_t *pipe = &_hcd.pipe[0];
@@ -199,8 +166,12 @@ static bool pipe0_xfer_in(rusb2_reg_t* rusb)
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
void *buf = pipe->buf;
if (len) {
+ tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u),
+ .param = (uintptr_t)rusb};
+
rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
- pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len);
+ // pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len);
+ tu_hwfifo_read(&rusb->CFIFO, buf, len, &access_mode);
pipe->buf = (uint8_t*)buf + len;
}
if (len < mps) {
@@ -227,7 +198,11 @@ static bool pipe0_xfer_out(rusb2_reg_t* rusb)
const unsigned len = TU_MIN(mps, rem);
void *buf = pipe->buf;
if (len) {
- pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len);
+ tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u),
+ .param = (uintptr_t)rusb};
+
+ // pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len);
+ tu_hwfifo_write(&rusb->CFIFO, buf, len, &access_mode);
pipe->buf = (uint8_t*)buf + len;
}
if (len < mps) {
@@ -242,14 +217,24 @@ static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num)
pipe_state_t *pipe = &_hcd.pipe[num];
const unsigned rem = pipe->remaining;
- rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT;
+ uint16_t fifo_sel = num | FIFOSEL_BIGEND;
+ if (rusb2_is_highspeed_reg(rusb)) {
+ fifo_sel |= RUSB2_FIFOSEL_MBW_32BIT;
+ } else {
+ fifo_sel |= RUSB2_FIFOSEL_MBW_16BIT;
+ }
+ rusb->D0FIFOSEL = fifo_sel;
+
const unsigned mps = edpt_max_packet_size(rusb, num);
pipe_wait_for_ready(rusb, num);
const unsigned vld = rusb->D0FIFOCTR_b.DTLN;
const unsigned len = TU_MIN(TU_MIN(rem, mps), vld);
void *buf = pipe->buf;
if (len) {
- pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len);
+ // pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len);
+ tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u),
+ .param = (uintptr_t)rusb};
+ tu_hwfifo_read(&rusb->D0FIFO, buf, len, &access_mode);
pipe->buf = (uint8_t*)buf + len;
}
if (len < mps) {
@@ -275,13 +260,23 @@ static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num)
return true;
}
- rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
+ uint16_t fifo_sel = num | FIFOSEL_BIGEND;
+ if (rusb2_is_highspeed_reg(rusb)) {
+ fifo_sel |= RUSB2_FIFOSEL_MBW_32BIT;
+ } else {
+ fifo_sel |= RUSB2_FIFOSEL_MBW_16BIT;
+ }
+ rusb->D0FIFOSEL = fifo_sel;
+
const unsigned mps = edpt_max_packet_size(rusb, num);
pipe_wait_for_ready(rusb, num);
const unsigned len = TU_MIN(rem, mps);
void *buf = pipe->buf;
if (len) {
- pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len);
+ // pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len);
+ tu_hwfifo_access_t access_mode = {.data_stride = (rusb2_is_highspeed_reg(rusb) ? 4u : 2u),
+ .param = (uintptr_t)rusb};
+ tu_hwfifo_write(&rusb->D0FIFO, buf, len, &access_mode);
pipe->buf = (uint8_t*)buf + len;
}
if (len < mps) {
@@ -296,18 +291,19 @@ static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num)
static bool process_pipe0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen)
{
(void)dev_addr;
-
rusb2_reg_t* rusb = RUSB2_REG(rhport);
const unsigned dir_in = tu_edpt_dir(ep_addr);
+ uint16_t fifo_sel =
+ (rusb2_is_highspeed_reg(rusb) ? RUSB2_FIFOSEL_MBW_32BIT : RUSB2_FIFOSEL_MBW_16BIT) | FIFOSEL_BIGEND;
+
/* configure fifo direction and access unit settings */
- if (dir_in) { /* IN, a byte */
- rusb->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT;
- while (rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ;
- } else { /* OUT, 2 bytes */
- rusb->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT |
- (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0);
- while (!(rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ;
+ if (dir_in == TUSB_DIR_OUT) {
+ fifo_sel |= RUSB2_CFIFOSEL_ISEL_WRITE;
+ }
+ rusb->CFIFOSEL = fifo_sel;
+ while ((rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) != (fifo_sel & RUSB2_CFIFOSEL_ISEL_WRITE)) {
+ // wait until ISEL_WRITE take effect
}
pipe_state_t *pipe = &_hcd.pipe[0];
@@ -535,13 +531,8 @@ void hcd_int_disable(uint8_t rhport) {
rusb2_int_disable(rhport);
}
-uint32_t hcd_frame_number(uint8_t rhport)
-{
- rusb2_reg_t* rusb = RUSB2_REG(rhport);
-
- /* The device must be reset at least once after connection
- * in order to start the frame counter. */
- if (_hcd.need_reset) hcd_port_reset(rhport);
+uint32_t hcd_frame_number(uint8_t rhport) {
+ rusb2_reg_t *rusb = RUSB2_REG(rhport);
return rusb->FRMNUM_b.FRNM;
}
@@ -550,32 +541,18 @@ uint32_t hcd_frame_number(uint8_t rhport)
*--------------------------------------------------------------------+*/
bool hcd_port_connect_status(uint8_t rhport) {
rusb2_reg_t* rusb = RUSB2_REG(rhport);
- return rusb->INTSTS1_b.ATTCH ? true : false;
+ const uint16_t line_state = rusb->SYSSTS0 & RUSB2_SYSSTS0_LNST_Msk;
+ return line_state == RUSB2_SYSSTS0_LNST_FS_J || line_state == RUSB2_SYSSTS0_LNST_FS_K;
}
void hcd_port_reset(uint8_t rhport) {
rusb2_reg_t* rusb = RUSB2_REG(rhport);
- rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK;
- while (rusb->DCPCTR_b.PBUSY) {}
-
- hcd_int_disable(rhport);
- rusb->DVSTCTR0_b.UACT = 0;
- if (rusb->DCPCTR_b.SUREQ) {
- rusb->DCPCTR_b.SUREQCLR = 1;
- }
- hcd_int_enable(rhport);
-
- /* Reset should be asserted 10-20ms. */
rusb->DVSTCTR0_b.USBRST = 1;
- for (volatile int i = 0; i < 2400000; ++i) {}
- rusb->DVSTCTR0_b.USBRST = 0;
-
- rusb->DVSTCTR0_b.UACT = 1;
- _hcd.need_reset = false;
}
void hcd_port_reset_end(uint8_t rhport) {
- (void) rhport;
+ rusb2_reg_t *rusb = RUSB2_REG(rhport);
+ rusb->DVSTCTR0_b.USBRST = 0;
}
tusb_speed_t hcd_port_speed_get(uint8_t rhport) {
@@ -584,7 +561,8 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport) {
case RUSB2_DVSTCTR0_RHST_HS: return TUSB_SPEED_HIGH;
case RUSB2_DVSTCTR0_RHST_FS: return TUSB_SPEED_FULL;
case RUSB2_DVSTCTR0_RHST_LS: return TUSB_SPEED_LOW;
- default: return TUSB_SPEED_INVALID;
+ default:
+ return TUSB_SPEED_INVALID;
}
}
@@ -802,7 +780,6 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) {
if (is1 & RUSB2_INTSTS1_ATTCH_Msk) {
rusb->DVSTCTR0_b.UACT = 1;
- _hcd.need_reset = true;
rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk;
hcd_event_device_attach(rhport, true);
}
diff --git a/src/portable/renesas/rusb2/rusb2_common.c b/src/portable/renesas/rusb2/rusb2_common.c
index 856f9714f..8addbe4c6 100644
--- a/src/portable/renesas/rusb2/rusb2_common.c
+++ b/src/portable/renesas/rusb2/rusb2_common.c
@@ -27,20 +27,19 @@
#include "tusb_option.h"
#if defined(TUP_USBIP_RUSB2) && (CFG_TUH_ENABLED || CFG_TUD_ENABLED)
+ #include "osal/osal.h"
+ #include "common/tusb_fifo.h"
-#include "rusb2_type.h"
+ #include "rusb2_common.h"
-#if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)
-#include "rusb2_rx.h"
-
-#elif TU_CHECK_MCU(OPT_MCU_RAXXX)
-#include "rusb2_ra.h"
+ #if TU_CHECK_MCU(OPT_MCU_RAXXX)
+ #include "rusb2_ra.h"
// USBFS_INT_IRQn and USBHS_USB_INT_RESUME_IRQn are generated by FSP
rusb2_controller_t rusb2_controller[] = {
- { .reg_base = R_USB_FS0_BASE, .irqnum = USBFS_INT_IRQn },
+ {.reg_base = R_USB_FS0_BASE, .irqnum = USBFS_INT_IRQn},
#ifdef RUSB2_SUPPORT_HIGHSPEED
- { .reg_base = R_USB_HS0_BASE, .irqnum = USBHS_USB_INT_RESUME_IRQn },
+ {.reg_base = R_USB_HS0_BASE, .irqnum = USBHS_USB_INT_RESUME_IRQn},
#endif
};
@@ -49,10 +48,69 @@ void tusb_rusb2_set_irqnum(uint8_t rhport, int32_t irqnum);
void tusb_rusb2_set_irqnum(uint8_t rhport, int32_t irqnum) {
rusb2_controller[rhport].irqnum = irqnum;
}
+ #endif
-#else
- #error "Unsupported MCU"
-#endif
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+static void hwfifo_set_mbw(rusb2_reg_t *rusb, uintptr_t hwfifo, uint16_t mbw) {
+ volatile uint16_t *fifo_sel;
+ if (hwfifo == (uintptr_t)&rusb->CFIFO) {
+ fifo_sel = &rusb->CFIFOSEL;
+ } else if (hwfifo == (uintptr_t)&rusb->D0FIFO) {
+ fifo_sel = &rusb->D0FIFOSEL;
+ } else if (hwfifo == (uintptr_t)&rusb->D1FIFO) {
+ fifo_sel = &rusb->D1FIFOSEL;
+ } else {
+ return;
+ }
+
+ *fifo_sel = (*fifo_sel & ~RUSB2_CFIFOSEL_MBW_Msk) | mbw;
+}
+
+// write to hwfifo from buffer with access mode
+void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode) {
+ rusb2_reg_t *rusb = (rusb2_reg_t *)access_mode->param;
+ const uint8_t *buf8 = (const uint8_t *)src;
+ volatile uint16_t *ff16;
+ volatile uint8_t *ff8;
+ const bool is_highspeed = rusb2_is_highspeed_reg(rusb);
+ if (is_highspeed) {
+ ff16 = (volatile uint16_t *)((uintptr_t)hwfifo + 2);
+ ff8 = (volatile uint8_t *)((uintptr_t)hwfifo + 3);
+ } else {
+ ff16 = (volatile uint16_t *)hwfifo;
+ ff8 = ((volatile uint8_t *)hwfifo);
+ }
+
+ // 32-bit access for highspeed
+ if (is_highspeed) {
+ volatile uint32_t *ff32 = (volatile uint32_t *)hwfifo;
+ while (len >= 4) {
+ *ff32 = tu_unaligned_read32(buf8);
+ buf8 += 4;
+ len -= 4;
+ }
+
+ if (len >= 2) {
+ // switch to 16-bit access
+ hwfifo_set_mbw(rusb, (uintptr_t)hwfifo, RUSB2_FIFOSEL_MBW_16BIT);
+ }
+ }
+
+ // 16-bit access
+ while (len >= 2) {
+ *ff16 = tu_unaligned_read16(buf8);
+ buf8 += 2;
+ len -= 2;
+ }
+
+ // 8-bit access does not need to change MBW
+ if (len > 0) {
+ *ff8 = *buf8;
+ ++buf8;
+ }
+}
#endif
diff --git a/src/portable/renesas/rusb2/rusb2_common.h b/src/portable/renesas/rusb2/rusb2_common.h
new file mode 100644
index 000000000..6b8c3d7f2
--- /dev/null
+++ b/src/portable/renesas/rusb2/rusb2_common.h
@@ -0,0 +1,58 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2025 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.
+ */
+#pragma once
+
+#include "common/tusb_common.h"
+#include "rusb2_type.h"
+
+#if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N)
+ #include "rusb2_rx.h"
+#elif TU_CHECK_MCU(OPT_MCU_RAXXX)
+ #include "rusb2_ra.h"
+
+ // Hack for D0FIFO definitions on RA Cortex-M23
+ #if defined(RENESAS_CORTEX_M23)
+ #define D0FIFO CFIFO
+ #define D0FIFOSEL CFIFOSEL
+ #define D0FIFOSEL_b CFIFOSEL_b
+ #define D1FIFOSEL CFIFOSEL
+ #define D1FIFOSEL_b CFIFOSEL_b
+ #define D0FIFOCTR CFIFOCTR
+ #define D0FIFOCTR_b CFIFOCTR_b
+ #endif
+
+#else
+ #error "Unsupported MCU"
+#endif
+
+
+//--------------------------------------------------------------------+
+// Common
+//--------------------------------------------------------------------+
+
+enum {
+ FIFOSEL_BIGEND = (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0)
+};
diff --git a/src/portable/renesas/rusb2/rusb2_type.h b/src/portable/renesas/rusb2/rusb2_type.h
index 71837d03c..21f116857 100644
--- a/src/portable/renesas/rusb2/rusb2_type.h
+++ b/src/portable/renesas/rusb2/rusb2_type.h
@@ -41,10 +41,9 @@ extern "C" {
#define _ccrx_evenaccess
#endif
-/*--------------------------------------------------------------------*/
-/* Register Definitions */
-/*--------------------------------------------------------------------*/
-
+//--------------------------------------------------------------------+
+// Register Definitions
+//--------------------------------------------------------------------+
/* Start of definition of packed structs (used by the CCRX toolchain) */
TU_ATTR_PACKED_BEGIN
TU_ATTR_BIT_FIELD_ORDER_BEGIN
@@ -1669,15 +1668,20 @@ TU_ATTR_BIT_FIELD_ORDER_END
/*--------------------------------------------------------------------*/
/* Register Bit Utils */
/*--------------------------------------------------------------------*/
-#define RUSB2_PIPE_CTR_PID_NAK (0U << RUSB2_PIPE_CTR_PID_Pos) /* NAK response */
-#define RUSB2_PIPE_CTR_PID_BUF (1U << RUSB2_PIPE_CTR_PID_Pos) /* BUF response (depends buffer state) */
-#define RUSB2_PIPE_CTR_PID_STALL (2U << RUSB2_PIPE_CTR_PID_Pos) /* STALL response */
-#define RUSB2_PIPE_CTR_PID_STALL2 (3U << RUSB2_PIPE_CTR_PID_Pos) /* Also STALL response */
+#define RUSB2_SYSSTS0_LNST_SE0 (0)
+#define RUSB2_SYSSTS0_LNST_FS_J (1u << RUSB2_SYSSTS0_LNST_Pos) /* Full-speed J state */
+#define RUSB2_SYSSTS0_LNST_FS_K (2u << RUSB2_SYSSTS0_LNST_Pos) /* Full-speed K state */
+#define RUSB2_SYSSTS0_LNST_LS_SE1 (3u << RUSB2_SYSSTS0_LNST_Pos) /* Low-speed SE1 state */
#define RUSB2_DVSTCTR0_RHST_LS (1U << RUSB2_DVSTCTR0_RHST_Pos) /* Low-speed connection */
#define RUSB2_DVSTCTR0_RHST_FS (2U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */
#define RUSB2_DVSTCTR0_RHST_HS (3U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */
+#define RUSB2_PIPE_CTR_PID_NAK (0U << RUSB2_PIPE_CTR_PID_Pos) /* NAK response */
+#define RUSB2_PIPE_CTR_PID_BUF (1U << RUSB2_PIPE_CTR_PID_Pos) /* BUF response (depends buffer state) */
+#define RUSB2_PIPE_CTR_PID_STALL (2U << RUSB2_PIPE_CTR_PID_Pos) /* STALL response */
+#define RUSB2_PIPE_CTR_PID_STALL2 (3U << RUSB2_PIPE_CTR_PID_Pos) /* Also STALL response */
+
#define RUSB2_DEVADD_USBSPD_LS (1U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Low-speed */
#define RUSB2_DEVADD_USBSPD_FS (2U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Full-speed */
diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
index 64046ce17..22a9e4af8 100644
--- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
+++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
@@ -108,22 +108,10 @@
#include "tusb_option.h"
-#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) && \
- !(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0)
+#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) && !(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0)
-#include "device/dcd.h"
-
-#if defined(TUP_USBIP_FSDEV_STM32)
- #include "fsdev_stm32.h"
-#elif defined(TUP_USBIP_FSDEV_CH32)
- #include "fsdev_ch32.h"
-#elif defined(TUP_USBIP_FSDEV_AT32)
- #include "fsdev_at32.h"
-#else
- #error "Unknown USB IP"
-#endif
-
-#include "fsdev_type.h"
+ #include "device/dcd.h"
+ #include "fsdev_common.h"
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
@@ -131,25 +119,25 @@
// One of these for every EP IN & OUT, uses a bit of RAM....
typedef struct {
- uint8_t *buffer;
+ uint8_t *buffer;
tu_fifo_t *ff;
- uint16_t total_len;
- uint16_t queued_len;
- uint16_t max_packet_size;
- uint8_t ep_idx; // index for USB_EPnR register
- bool iso_in_sending; // Workaround for ISO IN EP doesn't have interrupt mask
+ uint16_t total_len;
+ uint16_t queued_len;
+ uint16_t max_packet_size;
+ uint8_t ep_idx; // index for USB_EPnR register
+ bool iso_in_sending; // Workaround for ISO IN EP doesn't have interrupt mask
} xfer_ctl_t;
// EP allocator
typedef struct {
uint8_t ep_num;
uint8_t ep_type;
- bool allocated[2];
+ bool allocated[2];
} ep_alloc_t;
static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2];
static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT];
-static uint8_t remoteWakeCountdown; // When wake is requested
+static uint8_t remoteWakeCountdown; // When wake is requested
//--------------------------------------------------------------------+
// Prototypes
@@ -163,17 +151,12 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir);
// PMA allocation/access
static uint16_t ep_buf_ptr; ///< Points to first free memory location
static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf);
-static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type);
-static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes);
-static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes);
-
-static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes);
-static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes);
+static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type);
static void edpt0_open(uint8_t rhport);
TU_ATTR_ALWAYS_INLINE static inline void edpt0_prepare_setup(void) {
- btable_set_rx_bufsize(0, BTABLE_BUF_RX, 8);
+ btable_set_rx_bufsize(0, BTABLE_BUF_RX, 8);
}
//--------------------------------------------------------------------+
@@ -187,42 +170,22 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint8_t epnum, uint
//--------------------------------------------------------------------+
// Controller API
//--------------------------------------------------------------------+
-bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
- (void) rh_init;
- // Follow the RM mentions to use a special ordering of PDWN and FRES
- for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us
- asm("NOP");
- }
+bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) {
+ (void)rh_init;
- // Perform USB peripheral reset
- FSDEV_REG->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN;
- for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us
- asm("NOP");
- }
+ fsdev_core_reset();
- FSDEV_REG->CNTR &= ~USB_CNTR_PDWN;
-
- // Wait startup time, for F042 and F070, this is <= 1 us.
- for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us
- asm("NOP");
- }
FSDEV_REG->CNTR = 0; // Enable USB
-#if !defined(FSDEV_BUS_32BIT)
+ #if !defined(FSDEV_BUS_32BIT)
// BTABLE register does not exist any more on 32-bit bus devices
FSDEV_REG->BTABLE = FSDEV_BTABLE_BASE;
-#endif
+ #endif
- FSDEV_REG->ISTR = 0; // Clear pending interrupts
+ // Enable interrupts for device mode
+ FSDEV_REG->CNTR |=
+ USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_PMAOVRM;
- // Reset endpoints to disabled
- for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) {
- // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED.
- ep_write(i, 0u, false);
- }
-
- FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM |
- USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_PMAOVRM;
handle_bus_reset(rhport);
// Enable pull-up if supported
@@ -231,6 +194,14 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
return true;
}
+bool dcd_deinit(uint8_t rhport) {
+ (void)rhport;
+
+ fsdev_deinit();
+
+ return true;
+}
+
void dcd_sof_enable(uint8_t rhport, bool en) {
(void)rhport;
@@ -264,8 +235,8 @@ static void handle_bus_reset(uint8_t rhport) {
for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) {
// Clear EP allocation status
- ep_alloc_status[i].ep_num = 0xFF;
- ep_alloc_status[i].ep_type = 0xFF;
+ ep_alloc_status[i].ep_num = 0xFF;
+ ep_alloc_status[i].ep_type = 0xFF;
ep_alloc_status[i].allocated[0] = false;
ep_alloc_status[i].allocated[1] = false;
}
@@ -273,7 +244,7 @@ static void handle_bus_reset(uint8_t rhport) {
// Reset PMA allocation
ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT;
- edpt0_open(rhport); // open control endpoint (both IN & OUT)
+ edpt0_open(rhport); // open control endpoint (both IN & OUT)
FSDEV_REG->DADDR = USB_DADDR_EF; // Enable USB Function
}
@@ -282,8 +253,8 @@ static void handle_bus_reset(uint8_t rhport) {
static void handle_ctr_tx(uint32_t ep_id) {
uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
- uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD;
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN);
+ const uint8_t ep_num = ep_reg & USB_EPADDR_FIELD;
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN);
if (ep_is_iso(ep_reg)) {
// Ignore spurious interrupts that we don't schedule
@@ -293,11 +264,11 @@ static void handle_ctr_tx(uint32_t ep_id) {
return;
}
xfer->iso_in_sending = false;
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
uint8_t buf_id = (ep_reg & USB_EP_DTOG_TX) ? 0 : 1;
-#else
+ #else
uint8_t buf_id = BTABLE_BUF_TX;
-#endif
+ #endif
btable_set_count(ep_id, buf_id, 0);
}
@@ -310,17 +281,17 @@ static void handle_ctr_tx(uint32_t ep_id) {
static void handle_ctr_setup(uint32_t ep_id) {
uint16_t rx_count = btable_get_count(ep_id, BTABLE_BUF_RX);
- uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX);
- uint8_t setup_packet[8] TU_ATTR_ALIGNED(4);
+ uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX);
+ uint8_t setup_packet[8] TU_ATTR_ALIGNED(4);
- dcd_read_packet_memory(setup_packet, rx_addr, rx_count);
+ tu_hwfifo_read(PMA_BUF_AT(rx_addr), setup_packet, rx_count, NULL);
// Clear CTR RX if another setup packet arrived before this, it will be discarded
ep_write_clear_ctr(ep_id, TUSB_DIR_OUT);
// Setup packet should always be 8 bytes. If not, we probably missed the packet
if (rx_count == 8) {
- dcd_event_setup_received(0, (uint8_t*) setup_packet, true);
+ dcd_event_setup_received(0, (uint8_t *)setup_packet, true);
// Hardware should reset EP0 RX/TX to NAK and both toggle to 1
} else {
// Missed setup packet !!!
@@ -331,29 +302,30 @@ static void handle_ctr_setup(uint32_t ep_id) {
// Handle CTR interrupt for the RX/OUT direction
static void handle_ctr_rx(uint32_t ep_id) {
- uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
- uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD;
- bool const is_iso = ep_is_iso(ep_reg);
- xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT);
+ uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
+ const uint8_t ep_num = ep_reg & USB_EPADDR_FIELD;
+ const bool is_iso = ep_is_iso(ep_reg);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT);
uint8_t buf_id;
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
bool const dbl_buf = is_iso;
-#else
+ #else
bool const dbl_buf = false;
-#endif
+ #endif
if (dbl_buf) {
buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1;
} else {
buf_id = BTABLE_BUF_RX;
}
- uint16_t const rx_count = btable_get_count(ep_id, buf_id);
- uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id);
+ const uint16_t rx_count = btable_get_count(ep_id, buf_id);
+ uint16_t pma_addr = (uint16_t)btable_get_addr(ep_id, buf_id);
+ fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(pma_addr);
if (xfer->ff) {
- dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count);
+ tu_hwfifo_read_to_fifo(pma_buf, xfer->ff, rx_count, NULL);
} else {
- dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count);
+ tu_hwfifo_read(pma_buf, xfer->buffer + xfer->queued_len, rx_count, NULL);
}
xfer->queued_len += rx_count;
@@ -371,7 +343,7 @@ static void handle_ctr_rx(uint32_t ep_id) {
} else {
// Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always
if (!is_iso) {
- uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
+ const uint16_t cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt);
}
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits
@@ -431,18 +403,18 @@ void dcd_int_handler(uint8_t rhport) {
// loop to handle all pending CTR interrupts
while (FSDEV_REG->ISTR & USB_ISTR_CTR) {
// skip DIR bit, and use CTR TX/RX instead, since there is chance we have both TX/RX completed in one interrupt
- uint32_t const ep_id = FSDEV_REG->ISTR & USB_ISTR_EP_ID;
- uint32_t const ep_reg = ep_read(ep_id);
+ const uint32_t ep_id = FSDEV_REG->ISTR & USB_ISTR_EP_ID;
+ const uint32_t ep_reg = ep_read(ep_id);
if (ep_reg & USB_EP_CTR_RX) {
- #ifdef FSDEV_BUS_32BIT
+ #ifdef FSDEV_BUS_32BIT
/* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf
* https://www.st.com/resource/en/errata_sheet/es0587-stm32u535xx-and-stm32u545xx-device-errata-stmicroelectronics.pdf
* From H503/U535 errata: Buffer description table update completes after CTR interrupt triggers
* Description:
- * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses
- * have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct.
- * Workaround:
+ * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM
+ * accesses have completed. If the software responds quickly to the interrupt, the full buffer contents may not be
+ * correct. Workaround:
* - Software should ensure that a small delay is included before accessing the SRAM contents. This delay
* should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode
* - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code
@@ -453,9 +425,9 @@ void dcd_int_handler(uint8_t rhport) {
*/
volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver
while (cycle_count > 0U) {
- cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare)
+ cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare)
}
- #endif
+ #endif
if (ep_reg & USB_EP_SETUP) {
handle_ctr_setup(ep_id); // CTR will be clear after copied setup packet
@@ -483,14 +455,13 @@ void dcd_int_handler(uint8_t rhport) {
// Invoked when a control transfer's status stage is complete.
// May help DCD to prepare for next control transfer, this API is optional.
-void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) {
+void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t *request) {
(void)rhport;
if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE &&
- request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD &&
- request->bRequest == TUSB_REQ_SET_ADDRESS) {
- uint8_t const dev_addr = (uint8_t)request->wValue;
- FSDEV_REG->DADDR = (USB_DADDR_EF | dev_addr);
+ request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) {
+ const uint8_t dev_addr = (uint8_t)request->wValue;
+ FSDEV_REG->DADDR = (USB_DADDR_EF | dev_addr);
}
edpt0_prepare_setup();
@@ -501,15 +472,14 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req
* In case of double buffering, high 16bit is the address of 2nd buffer
* During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually.
*/
-static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf)
-{
- uint8_t blsize, num_block;
+static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf) {
+ uint8_t blsize, num_block;
uint16_t aligned_len = pma_align_buffer_size(len, &blsize, &num_block);
- (void) blsize;
- (void) num_block;
+ (void)blsize;
+ (void)num_block;
uint32_t addr = ep_buf_ptr;
- ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer
+ ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer
if (dbuf) {
addr |= ((uint32_t)ep_buf_ptr) << 16;
@@ -517,7 +487,7 @@ static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf)
}
// Verify packet buffer is not overflowed
- TU_ASSERT(ep_buf_ptr <= FSDEV_PMA_SIZE, 0xFFFF);
+ TU_ASSERT(ep_buf_ptr <= CFG_TUSB_FSDEV_PMA_SIZE, 0xFFFF);
return addr;
}
@@ -525,35 +495,32 @@ static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf)
/***
* Allocate hardware endpoint
*/
-static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
-{
- uint8_t const epnum = tu_edpt_number(ep_addr);
- uint8_t const dir = tu_edpt_dir(ep_addr);
+static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) {
+ const uint8_t epnum = tu_edpt_number(ep_addr);
+ const uint8_t dir = tu_edpt_dir(ep_addr);
for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
// Check if already allocated
- if (ep_alloc_status[i].allocated[dir] &&
- ep_alloc_status[i].ep_type == ep_type &&
+ if (ep_alloc_status[i].allocated[dir] && ep_alloc_status[i].ep_type == ep_type &&
ep_alloc_status[i].ep_num == epnum) {
return i;
}
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
bool const dbl_buf = ep_type == TUSB_XFER_ISOCHRONOUS;
-#else
+ #else
bool const dbl_buf = false;
-#endif
+ #endif
// If EP of current direction is not allocated
// For double-buffered mode both directions needs to be free
- if (!ep_alloc_status[i].allocated[dir] &&
- (!dbl_buf || !ep_alloc_status[i].allocated[dir ^ 1])) {
+ if (!ep_alloc_status[i].allocated[dir] && (!dbl_buf || !ep_alloc_status[i].allocated[dir ^ 1])) {
// Check if EP number is the same
if (ep_alloc_status[i].ep_num == 0xFF || ep_alloc_status[i].ep_num == epnum) {
// One EP pair has to be the same type
if (ep_alloc_status[i].ep_type == 0xFF || ep_alloc_status[i].ep_type == ep_type) {
- ep_alloc_status[i].ep_num = epnum;
- ep_alloc_status[i].ep_type = ep_type;
+ ep_alloc_status[i].ep_num = epnum;
+ ep_alloc_status[i].ep_type = ep_type;
ep_alloc_status[i].allocated[dir] = true;
return i;
@@ -567,16 +534,16 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type)
}
void edpt0_open(uint8_t rhport) {
- (void) rhport;
+ (void)rhport;
dcd_ep_alloc(0x0, TUSB_XFER_CONTROL);
dcd_ep_alloc(0x80, TUSB_XFER_CONTROL);
xfer_status[0][0].max_packet_size = CFG_TUD_ENDPOINT0_SIZE;
- xfer_status[0][0].ep_idx = 0;
+ xfer_status[0][0].ep_idx = 0;
xfer_status[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE;
- xfer_status[0][1].ep_idx = 0;
+ xfer_status[0][1].ep_idx = 0;
uint16_t pma_addr0 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false);
uint16_t pma_addr1 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false);
@@ -594,13 +561,13 @@ void edpt0_open(uint8_t rhport) {
ep_write(0, ep_reg, false);
}
-bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
+bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) {
(void)rhport;
- uint8_t const ep_addr = desc_ep->bEndpointAddress;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- const uint16_t packet_size = tu_edpt_packet_size(desc_ep);
- uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer);
+ const uint8_t ep_addr = desc_ep->bEndpointAddress;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ const uint16_t packet_size = tu_edpt_packet_size(desc_ep);
+ const uint8_t ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer);
TU_ASSERT(ep_idx < FSDEV_EP_COUNT);
uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK;
@@ -624,9 +591,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
uint16_t pma_addr = dcd_pma_alloc(packet_size, false);
btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
xfer->max_packet_size = packet_size;
- xfer->ep_idx = ep_idx;
+ xfer->ep_idx = ep_idx;
ep_change_status(&ep_reg, dir, EP_STAT_NAK);
ep_change_dtog(&ep_reg, dir, 0);
@@ -650,8 +617,8 @@ void dcd_edpt_close_all(uint8_t rhport) {
// Reset endpoint
ep_write(i, 0, false);
// Clear EP allocation status
- ep_alloc_status[i].ep_num = 0xFF;
- ep_alloc_status[i].ep_type = 0xFF;
+ ep_alloc_status[i].ep_num = 0xFF;
+ ep_alloc_status[i].ep_type = 0xFF;
ep_alloc_status[i].allocated[0] = false;
ep_alloc_status[i].allocated[1] = false;
}
@@ -665,46 +632,46 @@ void dcd_edpt_close_all(uint8_t rhport) {
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
(void)rhport;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- uint8_t const dir = tu_edpt_dir(ep_addr);
- uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS);
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const uint8_t dir = tu_edpt_dir(ep_addr);
+ const uint8_t ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS);
-#if CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP != 0
- uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true);
+ #if CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP != 0
+ uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true);
uint16_t pma_addr2 = pma_addr >> 16;
-#else
- uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, false);
+ #else
+ uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, false);
uint16_t pma_addr2 = pma_addr;
-#endif
+ #endif
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
btable_set_addr(ep_idx, 0, pma_addr);
btable_set_addr(ep_idx, 1, pma_addr2);
-#else
+ #else
btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr);
- (void) pma_addr2;
-#endif
+ (void)pma_addr2;
+ #endif
- xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir);
- xfer->ep_idx = ep_idx;
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ xfer->ep_idx = ep_idx;
return true;
}
-bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) {
+bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) {
(void)rhport;
- uint8_t const ep_addr = desc_ep->bEndpointAddress;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir);
+ const uint8_t ep_addr = desc_ep->bEndpointAddress;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- uint8_t const ep_idx = xfer->ep_idx;
+ const uint8_t ep_idx = xfer->ep_idx;
xfer->max_packet_size = tu_edpt_packet_size(desc_ep);
uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK;
ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX;
-#if FSDEV_USE_SBUF_ISO != 0
+ #if FSDEV_USE_SBUF_ISO != 0
ep_reg |= USB_EP_KIND;
ep_change_status(&ep_reg, dir, EP_STAT_DISABLED);
@@ -715,12 +682,12 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
} else {
ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX);
}
-#else
+ #else
ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED);
ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED);
ep_change_dtog(&ep_reg, dir, 0);
ep_change_dtog(&ep_reg, (tusb_dir_t)(1 - dir), 1);
-#endif
+ #endif
ep_write(ep_idx, ep_reg, true);
@@ -729,28 +696,29 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep)
// Currently, single-buffered, and only 64 bytes at a time (max)
static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
- uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
+ uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size);
uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR
- bool const is_iso = ep_is_iso(ep_reg);
+ const bool is_iso = ep_is_iso(ep_reg);
uint8_t buf_id;
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
bool const dbl_buf = is_iso;
-#else
+ #else
bool const dbl_buf = false;
-#endif
+ #endif
if (dbl_buf) {
buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0;
} else {
buf_id = BTABLE_BUF_TX;
}
- uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id);
+ uint16_t addr_ptr = (uint16_t)btable_get_addr(ep_ix, buf_id);
+ fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(addr_ptr);
if (xfer->ff) {
- dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len);
+ tu_hwfifo_write_from_fifo(pma_buf, xfer->ff, len, NULL);
} else {
- dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len);
+ tu_hwfifo_write(pma_buf, &(xfer->buffer[xfer->queued_len]), len, NULL);
}
xfer->queued_len += len;
@@ -765,10 +733,10 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
}
static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) {
- (void) rhport;
+ (void)rhport;
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- uint8_t const ep_idx = xfer->ep_idx;
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ const uint8_t ep_idx = xfer->ep_idx;
if (dir == TUSB_DIR_IN) {
dcd_transmit_packet(xfer, ep_idx);
@@ -778,11 +746,11 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) {
uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size);
-#if FSDEV_USE_SBUF_ISO == 0
+ #if FSDEV_USE_SBUF_ISO == 0
bool const dbl_buf = ep_is_iso(ep_reg);
-#else
+ #else
bool const dbl_buf = false;
-#endif
+ #endif
if (dbl_buf) {
btable_set_rx_bufsize(ep_idx, 0, cnt);
btable_set_rx_bufsize(ep_idx, 1, cnt);
@@ -797,29 +765,29 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) {
return true;
}
-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 ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+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 ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- xfer->buffer = buffer;
- xfer->ff = NULL;
- xfer->total_len = total_bytes;
+ xfer->buffer = buffer;
+ xfer->ff = NULL;
+ xfer->total_len = total_bytes;
xfer->queued_len = 0;
return edpt_xfer(rhport, ep_num, dir);
}
-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 ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+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 ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- xfer->buffer = NULL;
- xfer->ff = ff;
- xfer->total_len = total_bytes;
+ xfer->buffer = NULL;
+ xfer->ff = ff;
+ xfer->total_len = total_bytes;
xfer->queued_len = 0;
return edpt_xfer(rhport, ep_num, dir);
@@ -827,10 +795,10 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
(void)rhport;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- uint8_t const ep_idx = xfer->ep_idx;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ const uint8_t ep_idx = xfer->ep_idx;
uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir);
@@ -842,10 +810,10 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
(void)rhport;
- uint8_t const ep_num = tu_edpt_number(ep_addr);
- tusb_dir_t const dir = tu_edpt_dir(ep_addr);
- xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
- uint8_t const ep_idx = xfer->ep_idx;
+ const uint8_t ep_num = tu_edpt_number(ep_addr);
+ const tusb_dir_t dir = tu_edpt_dir(ep_addr);
+ xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir);
+ const uint8_t ep_idx = xfer->ep_idx;
uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits
ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir);
@@ -857,168 +825,22 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
ep_write(ep_idx, ep_reg, true);
}
-//--------------------------------------------------------------------+
-// PMA read/write
-//--------------------------------------------------------------------+
-
-// Write to packet memory area (PMA) from user memory
-// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
-// - Uses unaligned for RAM (since M0 cannot access unaligned address)
-static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) {
- if (nbytes == 0) return true;
- uint32_t n_write = nbytes / FSDEV_BUS_SIZE;
-
- fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst);
- const uint8_t *src8 = src;
-
- while (n_write--) {
- pma_buf->value = fsdevbus_unaligned_read(src8);
- src8 += FSDEV_BUS_SIZE;
- pma_buf++;
- }
-
- // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
- uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1);
- if (odd) {
- fsdev_bus_t temp = 0;
- for(uint16_t i = 0; i < odd; i++) {
- temp |= *src8++ << (i * 8);
- }
- pma_buf->value = temp;
- }
-
- return true;
+void dcd_int_enable(uint8_t rhport) {
+ fsdev_int_enable(rhport);
}
-// Read from packet memory area (PMA) to user memory.
-// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT
-// - Uses unaligned for RAM (since M0 cannot access unaligned address)
-static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) {
- if (nbytes == 0) return true;
- uint32_t n_read = nbytes / FSDEV_BUS_SIZE;
-
- fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src);
- uint8_t *dst8 = (uint8_t *)dst;
-
- while (n_read--) {
- fsdevbus_unaligned_write(dst8, (fsdev_bus_t ) pma_buf->value);
- dst8 += FSDEV_BUS_SIZE;
- pma_buf++;
- }
-
- // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit
- uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1);
- if (odd) {
- fsdev_bus_t temp = pma_buf->value;
- while (odd--) {
- *dst8++ = (uint8_t) (temp & 0xfful);
- temp >>= 8;
- }
- }
-
- return true;
+void dcd_int_disable(uint8_t rhport) {
+ fsdev_int_disable(rhport);
}
-// Write to PMA from FIFO
-static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) {
- if (wNBytes == 0) return true;
-
- // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
- tu_fifo_buffer_info_t info;
- tu_fifo_get_read_info(ff, &info);
-
- uint16_t cnt_lin = tu_min16(wNBytes, info.linear.len);
- uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.wrapped.len);
- uint16_t const cnt_total = cnt_lin + cnt_wrap;
-
- // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
- // last lin byte will be combined with wrapped part To ensure PMA is always access aligned
- uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1);
- uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1);
- uint8_t const *src8 = (uint8_t const*) info.linear.ptr;
-
- // write even linear part
- dcd_write_packet_memory(dst, src8, lin_even);
- dst += lin_even;
- src8 += lin_even;
-
- if (lin_odd == 0) {
- src8 = (uint8_t const*) info.wrapped.ptr;
- } else {
- // Combine last linear bytes + first wrapped bytes to form fsdev bus width data
- fsdev_bus_t temp = 0;
- uint16_t i;
- for(i = 0; i < lin_odd; i++) {
- temp |= *src8++ << (i * 8);
- }
-
- src8 = (uint8_t const*) info.wrapped.ptr;
- for(; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) {
- temp |= *src8++ << (i * 8);
- }
-
- dcd_write_packet_memory(dst, &temp, FSDEV_BUS_SIZE);
- dst += FSDEV_BUS_SIZE;
- }
-
- // write the rest of the wrapped part
- dcd_write_packet_memory(dst, src8, cnt_wrap);
-
- tu_fifo_advance_read_pointer(ff, cnt_total);
- return true;
+ #if defined(USB_BCDR_DPPU) || defined(SYSCFG_PMC_USB_PU)
+void dcd_connect(uint8_t rhport) {
+ fsdev_connect(rhport);
}
-// Read from PMA to FIFO
-static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) {
- if (wNBytes == 0) return true;
-
- // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
- // Check for first linear part
- tu_fifo_buffer_info_t info;
- tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO
-
- uint16_t cnt_lin = tu_min16(wNBytes, info.linear.len);
- uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.wrapped.len);
- uint16_t cnt_total = cnt_lin + cnt_wrap;
-
- // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
- // last lin byte will be combined with wrapped part To ensure PMA is always access aligned
-
- uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1);
- uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1);
- uint8_t *dst8 = (uint8_t *) info.linear.ptr;
-
- // read even linear part
- dcd_read_packet_memory(dst8, src, lin_even);
- dst8 += lin_even;
- src += lin_even;
-
- if (lin_odd == 0) {
- dst8 = (uint8_t *) info.wrapped.ptr;
- } else {
- // Combine last linear bytes + first wrapped bytes to form fsdev bus width data
- fsdev_bus_t temp;
- dcd_read_packet_memory(&temp, src, FSDEV_BUS_SIZE);
- src += FSDEV_BUS_SIZE;
-
- uint16_t i;
- for (i = 0; i < lin_odd; i++) {
- *dst8++ = (uint8_t) (temp & 0xfful);
- temp >>= 8;
- }
-
- dst8 = (uint8_t *) info.wrapped.ptr;
- for (; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) {
- *dst8++ = (uint8_t) (temp & 0xfful);
- temp >>= 8;
- }
- }
-
- // read the rest of the wrapped part
- dcd_read_packet_memory(dst8, src, cnt_wrap);
-
- tu_fifo_advance_write_pointer(ff, cnt_total);
- return true;
+void dcd_disconnect(uint8_t rhport) {
+ fsdev_disconnect(rhport);
}
+ #endif
#endif
diff --git a/src/portable/st/stm32_fsdev/fsdev_at32.h b/src/portable/st/stm32_fsdev/fsdev_at32.h
index deb1de2a8..e75430396 100644
--- a/src/portable/st/stm32_fsdev/fsdev_at32.h
+++ b/src/portable/st/stm32_fsdev/fsdev_at32.h
@@ -35,7 +35,6 @@
#endif
-#define FSDEV_PMA_SIZE (512u)
#define FSDEV_USE_SBUF_ISO 0
#define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL)
#define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL)
@@ -150,8 +149,6 @@
#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */
#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK)
-#include "fsdev_type.h"
-
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
@@ -168,7 +165,7 @@ enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
#error "Unsupported MCU"
#endif
-void dcd_int_enable(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) {
(void)rhport;
#if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413)
// AT32F403A/407 devices allow to remap the USB interrupt vectors from
@@ -187,7 +184,7 @@ void dcd_int_enable(uint8_t rhport) {
}
}
-void dcd_int_disable(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) {
(void)rhport;
#if (CFG_TUSB_MCU == OPT_MCU_AT32F403A_407) || (CFG_TUSB_MCU == OPT_MCU_AT32F413)
// AT32F403A/407 devices allow to remap the USB interrupt vectors from
@@ -206,20 +203,20 @@ void dcd_int_disable(uint8_t rhport) {
}
}
-void dcd_disconnect(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) {
(void) rhport;
/* disable usb phy */
- FSDEV_REG->CNTR |= USB_CNTR_PDWN;
+ *(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) |= USB_CNTR_PDWN;
/* D+ 1.5k pull-up disable, USB->cfg_bit.puo = TRUE; */
- *(uint32_t *)(FSDEV_REG_BASE+0x60) |= (1u<<1);
+ *(volatile uint32_t *)(FSDEV_REG_BASE+0x60) |= (1u<<1);
}
-void dcd_connect(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) {
(void) rhport;
/* enable usb phy */
- FSDEV_REG->CNTR &= ~USB_CNTR_PDWN;
+ *(volatile uint32_t*)(FSDEV_REG_BASE + 0x40) &= ~USB_CNTR_PDWN;
/* Dp 1.5k pull-up enable, USB->cfg_bit.puo = 0; */
- *(uint32_t *)(FSDEV_REG_BASE+0x60) &= ~(1u<<1);
+ *(volatile uint32_t *)(FSDEV_REG_BASE+0x60) &= ~(1u<<1);
}
#endif
diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h
index ceebb6dab..37ea7808e 100644
--- a/src/portable/st/stm32_fsdev/fsdev_ch32.h
+++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h
@@ -53,7 +53,6 @@
#pragma GCC diagnostic pop
#endif
-#define FSDEV_PMA_SIZE (512u)
#define FSDEV_USE_SBUF_ISO 0
#define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL)
#define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL)
@@ -168,7 +167,6 @@
#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */
#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK)
-
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
@@ -184,26 +182,26 @@ enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
#error "Unsupported MCU"
#endif
-void dcd_int_enable(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) {
(void)rhport;
for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) {
NVIC_EnableIRQ(fsdev_irq[i]);
}
}
-void dcd_int_disable(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) {
(void)rhport;
for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) {
NVIC_DisableIRQ(fsdev_irq[i]);
}
}
-void dcd_disconnect(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) {
(void) rhport;
EXTEN->EXTEN_CTR &= ~EXTEN_USBD_PU_EN;
}
-void dcd_connect(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) {
(void) rhport;
EXTEN->EXTEN_CTR |= EXTEN_USBD_PU_EN;
}
diff --git a/src/portable/st/stm32_fsdev/fsdev_common.c b/src/portable/st/stm32_fsdev/fsdev_common.c
new file mode 100644
index 000000000..4f127ae86
--- /dev/null
+++ b/src/portable/st/stm32_fsdev/fsdev_common.c
@@ -0,0 +1,116 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2024 Ha Thach (tinyusb.org)
+ * Copyright (c) 2025, HiFiPhile (Zixun LI)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+#include "tusb_option.h"
+
+#if defined(TUP_USBIP_FSDEV) && (CFG_TUH_ENABLED || CFG_TUD_ENABLED)
+
+#include "fsdev_common.h"
+
+//--------------------------------------------------------------------+
+// Global
+//--------------------------------------------------------------------+
+
+// Reset the USB Core
+void fsdev_core_reset(void) {
+ // Perform USB peripheral reset
+ FSDEV_REG->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN;
+ for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us
+ asm("NOP");
+ }
+
+ FSDEV_REG->CNTR &= ~USB_CNTR_PDWN;
+
+ // Wait startup time, for F042 and F070, this is <= 1 us.
+ for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us
+ asm("NOP");
+ }
+
+ // Clear pending interrupts
+ FSDEV_REG->ISTR = 0;
+}
+
+// De-initialize the USB Core
+void fsdev_deinit(void) {
+ // Disable all interrupts and force USB reset
+ FSDEV_REG->CNTR = USB_CNTR_FRES;
+
+ // Clear pending interrupts
+ FSDEV_REG->ISTR = 0;
+
+ // Put USB peripheral in power down mode
+ FSDEV_REG->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN;
+ for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us
+ asm("NOP");
+ }
+}
+
+//--------------------------------------------------------------------+
+// BTable Helper
+//--------------------------------------------------------------------+
+
+// Aligned buffer size according to hardware
+uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) {
+ /* The STM32 full speed USB peripheral supports only a limited set of
+ * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */
+ uint16_t block_in_bytes;
+ if (size > 62) {
+ block_in_bytes = 32;
+ *blsize = 1;
+ *num_block = tu_div_ceil(size, 32);
+ } else {
+ block_in_bytes = 2;
+ *blsize = 0;
+ *num_block = tu_div_ceil(size, 2);
+ }
+
+ return (*num_block) * block_in_bytes;
+}
+
+// Set RX buffer size
+void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount) {
+ uint8_t blsize, num_block;
+ (void) pma_align_buffer_size(wCount, &blsize, &num_block);
+
+ /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
+ uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10);
+ if (bl_nb == 0) {
+ // zlp but 0 is invalid value, set blsize to 1 (32 bytes)
+ // Note: lower value can cause PMAOVR on setup with ch32v203
+ bl_nb = 1 << 15;
+ }
+
+#ifdef FSDEV_BUS_32BIT
+ uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
+ count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu);
+ FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
+#else
+ FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb;
+#endif
+}
+
+#endif
diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_common.h
index cf36576bb..c53e345b0 100644
--- a/src/portable/st/stm32_fsdev/fsdev_type.h
+++ b/src/portable/st/stm32_fsdev/fsdev_common.h
@@ -1,8 +1,9 @@
/*
* The MIT License (MIT)
*
- * Copyright(c) N Conrad
- * Copyright(c) 2024, hathach (tinyusb.org)
+ * Copyright (c) N Conrad
+ * Copyright (c) 2024, hathach (tinyusb.org)
+ * Copyright (c) 2025, HiFiPhile (Zixun LI)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -25,53 +26,67 @@
* This file is part of the TinyUSB stack.
*/
-#ifndef TUSB_FSDEV_TYPE_H
-#define TUSB_FSDEV_TYPE_H
+#ifndef TUSB_FSDEV_COMMON_H
+#define TUSB_FSDEV_COMMON_H
-#ifdef __cplusplus
- extern "C" {
+#include "common/tusb_common.h"
+
+#if CFG_TUD_ENABLED
+ #include "device/dcd.h"
+#endif
+
+#if CFG_TUH_ENABLED
+ #include "host/hcd.h"
+#endif
+
+#if defined(TUP_USBIP_FSDEV_STM32)
+ #include "fsdev_stm32.h"
+#elif defined(TUP_USBIP_FSDEV_CH32)
+ #include "fsdev_ch32.h"
+#elif defined(TUP_USBIP_FSDEV_AT32)
+ #include "fsdev_at32.h"
+#else
+ #error "Unknown USB IP"
#endif
-#include "stdint.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it
// Both of these MUST be a multiple of 2, and are in byte units.
#ifndef FSDEV_BTABLE_BASE
-#define FSDEV_BTABLE_BASE 0U
+ #define FSDEV_BTABLE_BASE 0U
#endif
TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes");
-// FSDEV_PMA_SIZE is PMA buffer size in bytes.
+// CFG_TUSB_FSDEV_PMA_SIZE is PMA buffer size in bytes.
// - 512-byte devices, access with a stride of two words (use every other 16-bit address)
// - 1024-byte devices, access with a stride of one word (use every 16-bit address)
// - 2048-byte devices, access with 32-bit address
// For purposes of accessing the packet
-#if FSDEV_PMA_SIZE == 512
+#if CFG_TUSB_FSDEV_PMA_SIZE == 512
// 1x16 bit / word access scheme
#define FSDEV_PMA_STRIDE 2
#define pma_access_scheme TU_ATTR_ALIGNED(4)
-#elif FSDEV_PMA_SIZE == 1024
+#elif CFG_TUSB_FSDEV_PMA_SIZE == 1024
// 2x16 bit / word access scheme
- #define FSDEV_PMA_STRIDE 1
+ #define FSDEV_PMA_STRIDE 1
#define pma_access_scheme
-#elif FSDEV_PMA_SIZE == 2048
+#elif CFG_TUSB_FSDEV_PMA_SIZE == 2048
// 32 bit access scheme
#define FSDEV_BUS_32BIT
- #define FSDEV_PMA_STRIDE 1
+ #define FSDEV_PMA_STRIDE 1
#define pma_access_scheme
#endif
// The fsdev_bus_t type can be used for both register and PMA access necessities
#ifdef FSDEV_BUS_32BIT
- typedef uint32_t fsdev_bus_t;
- #define fsdevbus_unaligned_read(_addr) tu_unaligned_read32(_addr)
- #define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write32(_addr, _value)
+typedef uint32_t fsdev_bus_t;
#else
- typedef uint16_t fsdev_bus_t;
- #define fsdevbus_unaligned_read(_addr) tu_unaligned_read16(_addr)
- #define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write16(_addr, _value)
+typedef uint16_t fsdev_bus_t;
#endif
enum {
@@ -105,74 +120,77 @@ typedef union {
} ep32[FSDEV_EP_COUNT][2];
} fsdev_btable_t;
-TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct");
-TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM");
+TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT * 8 * FSDEV_PMA_STRIDE, "size is not correct");
+TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT * 8 <= CFG_TUSB_FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM");
-#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(FSDEV_BTABLE_BASE)))
+#define FSDEV_BTABLE ((volatile fsdev_btable_t *)(FSDEV_PMA_BASE + FSDEV_PMA_STRIDE * (FSDEV_BTABLE_BASE)))
typedef struct {
volatile pma_access_scheme fsdev_bus_t value;
} fsdev_pma_buf_t;
-#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(_addr)))
+#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t *)(FSDEV_PMA_BASE + FSDEV_PMA_STRIDE * (_addr)))
//--------------------------------------------------------------------+
// Registers Typedef
//--------------------------------------------------------------------+
// volatile 32-bit aligned
-#define _va32 volatile TU_ATTR_ALIGNED(4)
+#define _va32 volatile TU_ATTR_ALIGNED(4)
typedef struct {
struct {
_va32 fsdev_bus_t reg;
- }ep[FSDEV_EP_COUNT];
+ } ep[FSDEV_EP_COUNT];
- _va32 uint32_t RESERVED7[8]; // Reserved
- _va32 fsdev_bus_t CNTR; // 40: Control register
- _va32 fsdev_bus_t ISTR; // 44: Interrupt status register
- _va32 fsdev_bus_t FNR; // 48: Frame number register
- _va32 fsdev_bus_t DADDR; // 4C: Device address register
- _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only)
- _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only)
- _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only)
+ _va32 uint32_t RESERVED7[8]; // Reserved
+ _va32 fsdev_bus_t CNTR; // 40: Control register
+ _va32 fsdev_bus_t ISTR; // 44: Interrupt status register
+ _va32 fsdev_bus_t FNR; // 48: Frame number register
+ _va32 fsdev_bus_t DADDR; // 4C: Device address register
+ _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only)
+ _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only)
+ _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only)
} fsdev_regs_t;
TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset");
TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct");
-#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE)
+#define FSDEV_REG ((fsdev_regs_t *)FSDEV_REG_BASE)
#ifndef USB_EPTX_STAT
-#define USB_EPTX_STAT 0x0030U
+ #define USB_EPTX_STAT 0x0030U
#endif
#ifndef USB_EPRX_STAT
-#define USB_EPRX_STAT 0x3000U
+ #define USB_EPRX_STAT 0x3000U
#endif
#ifndef USB_EPTX_STAT_Pos
-#define USB_EPTX_STAT_Pos 4u
+ #define USB_EPTX_STAT_Pos 4u
#endif
#ifndef USB_EP_DTOG_TX_Pos
-#define USB_EP_DTOG_TX_Pos 6u
+ #define USB_EP_DTOG_TX_Pos 6u
#endif
#ifndef USB_EP_CTR_TX_Pos
-#define USB_EP_CTR_TX_Pos 7u
+ #define USB_EP_CTR_TX_Pos 7u
#endif
typedef enum {
EP_STAT_DISABLED = 0,
- EP_STAT_STALL = 1,
- EP_STAT_NAK = 2,
- EP_STAT_VALID = 3
-}ep_stat_t;
+ EP_STAT_STALL = 1,
+ EP_STAT_NAK = 2,
+ EP_STAT_VALID = 3
+} ep_stat_t;
+
+#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
+#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
-#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
-#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8)))
+#define CH_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
+#define CH_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 8 : 0)))
//--------------------------------------------------------------------+
// Endpoint Helper
@@ -186,13 +204,13 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) {
TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value, bool need_exclusive) {
if (need_exclusive) {
- dcd_int_disable(0);
+ fsdev_int_disable(0);
}
- FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value;
+ FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t)value;
if (need_exclusive) {
- dcd_int_enable(0);
+ fsdev_int_enable(0);
}
}
@@ -204,11 +222,11 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_write_clear_ctr(uint32_t ep_id, tusb
ep_write(ep_id, reg, false);
}
-TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) {
+TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t *reg, tusb_dir_t dir, ep_stat_t state) {
*reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
}
-TU_ATTR_ALWAYS_INLINE static inline void ep_change_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) {
+TU_ATTR_ALWAYS_INLINE static inline void ep_change_dtog(uint32_t *reg, tusb_dir_t dir, uint8_t state) {
*reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8)));
}
@@ -217,6 +235,35 @@ TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) {
}
//--------------------------------------------------------------------+
+// Channel Helper
+// - Direction is opposite to endpoint direction
+//--------------------------------------------------------------------+
+
+TU_ATTR_ALWAYS_INLINE static inline uint32_t ch_read(uint32_t ch_id) {
+ return ep_read(ch_id);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline void ch_write(uint32_t ch_id, uint32_t value, bool need_exclusive) {
+ ep_write(ch_id, value, need_exclusive);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline void ch_write_clear_ctr(uint32_t ch_id, tusb_dir_t dir) {
+ uint32_t reg = FSDEV_REG->ep[ch_id].reg;
+ reg |= USB_EP_CTR_TX | USB_EP_CTR_RX;
+ reg &= USB_EPREG_MASK;
+ reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 8 : 0)));
+ ep_write(ch_id, reg, false);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline void ch_change_status(uint32_t *reg, tusb_dir_t dir, ep_stat_t state) {
+ *reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 8 : 0)));
+}
+
+TU_ATTR_ALWAYS_INLINE static inline void ch_change_dtog(uint32_t *reg, tusb_dir_t dir, uint8_t state) {
+ *reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 8 : 0)));
+}
+
+//--------------------------------------------------------------------+
// BTable Helper
//--------------------------------------------------------------------+
@@ -230,8 +277,8 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uin
TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) {
#ifdef FSDEV_BUS_32BIT
- uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
- count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu);
+ uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
+ count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu);
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
#else
FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr;
@@ -250,58 +297,30 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t btable_get_count(uint32_t ep_id, ui
TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) {
#ifdef FSDEV_BUS_32BIT
- uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
- count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16);
+ uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
+ count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16);
FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
#else
- uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count;
- cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU);
+ uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count;
+ cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU);
FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt;
#endif
}
-/* Aligned buffer size according to hardware */
-TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) {
- /* The STM32 full speed USB peripheral supports only a limited set of
- * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */
- uint16_t block_in_bytes;
- if (size > 62) {
- block_in_bytes = 32;
- *blsize = 1;
- *num_block = tu_div_ceil(size, 32);
- } else {
- block_in_bytes = 2;
- *blsize = 0;
- *num_block = tu_div_ceil(size, 2);
- }
-
- return (*num_block) * block_in_bytes;
-}
-
-TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount) {
- uint8_t blsize, num_block;
- (void) pma_align_buffer_size(wCount, &blsize, &num_block);
+// Reset the USB Core
+void fsdev_core_reset(void);
- /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */
- uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10);
- if (bl_nb == 0) {
- // zlp but 0 is invalid value, set blsize to 1 (32 bytes)
- // Note: lower value can cause PMAOVR on setup with ch32v203
- bl_nb = 1 << 15;
- }
+// De-initialize the USB Core
+void fsdev_deinit(void);
-#ifdef FSDEV_BUS_32BIT
- uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr;
- count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu);
- FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr;
-#else
- FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb;
-#endif
+// Aligned buffer size according to hardware
+uint16_t pma_align_buffer_size(uint16_t size, uint8_t *blsize, uint8_t *num_block);
-}
+// Set RX buffer size
+void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount);
#ifdef __cplusplus
- }
+}
#endif
-#endif
+#endif /* TUSB_FSDEV_COMMON_H */
diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h
index e7a57aca0..02dba05a6 100644
--- a/src/portable/st/stm32_fsdev/fsdev_stm32.h
+++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h
@@ -32,10 +32,23 @@
#ifndef TUSB_FSDEV_STM32_H
#define TUSB_FSDEV_STM32_H
-#if CFG_TUSB_MCU == OPT_MCU_STM32F0
+#if CFG_TUSB_MCU == OPT_MCU_STM32C0
+ #include "stm32c0xx.h"
+ #define FSDEV_HAS_SBUF_ISO 1
+ #define USB USB_DRD_FS
+ #define USB_EP_CTR_RX USB_CHEP_VTRX
+ #define USB_EP_CTR_TX USB_CHEP_VTTX
+ #define USB_EPREG_MASK USB_CHEP_REG_MASK
+ #define USB_CNTR_FRES USB_CNTR_USBRST
+ #define USB_CNTR_RESUME USB_CNTR_L2RES
+ #define USB_ISTR_EP_ID USB_ISTR_IDN
+ #define USB_EPADDR_FIELD USB_CHEP_ADDR
+ #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
+ #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+
+#elif CFG_TUSB_MCU == OPT_MCU_STM32F0
#include "stm32f0xx.h"
- #define FSDEV_PMA_SIZE (1024u)
- #define FSDEV_REG_BASE USB_BASE
+ #define FSDEV_REG_BASE USB_BASE
#define FSDEV_HAS_SBUF_ISO 0
// F0x2 models are crystal-less
// All have internal D+ pull-up
@@ -44,29 +57,24 @@
#elif CFG_TUSB_MCU == OPT_MCU_STM32F1
#include "stm32f1xx.h"
- #define FSDEV_PMA_SIZE (512u)
#define FSDEV_HAS_SBUF_ISO 0
// NO internal Pull-ups
// *B, and *C: 2 x 16 bits/word
// F1 names this differently from the rest
- #define USB_CNTR_LPMODE USB_CNTR_LP_MODE
+ #define USB_CNTR_LPMODE USB_CNTR_LP_MODE
-#elif defined(STM32F302xB) || defined(STM32F302xC) || \
- defined(STM32F303xB) || defined(STM32F303xC) || \
- defined(STM32F373xC)
+#elif defined(STM32F302xB) || defined(STM32F302xC) || defined(STM32F303xB) || defined(STM32F303xC) || \
+ defined(STM32F373xC)
#include "stm32f3xx.h"
- #define FSDEV_PMA_SIZE (512u)
#define FSDEV_HAS_SBUF_ISO 0
// NO internal Pull-ups
// *B, and *C: 1 x 16 bits/word
// PMA dedicated to USB (no sharing with CAN)
-#elif defined(STM32F302x6) || defined(STM32F302x8) || \
- defined(STM32F302xD) || defined(STM32F302xE) || \
- defined(STM32F303xD) || defined(STM32F303xE)
+#elif defined(STM32F302x6) || defined(STM32F302x8) || defined(STM32F302xD) || defined(STM32F302xE) || \
+ defined(STM32F303xD) || defined(STM32F303xE)
#include "stm32f3xx.h"
- #define FSDEV_PMA_SIZE (1024u)
#define FSDEV_HAS_SBUF_ISO 0
// NO internal Pull-ups
// *6, *8, *D, and *E: 2 x 16 bits/word LPM Support
@@ -74,28 +82,32 @@
#elif CFG_TUSB_MCU == OPT_MCU_STM32L0
#include "stm32l0xx.h"
- #define FSDEV_PMA_SIZE (1024u)
#define FSDEV_HAS_SBUF_ISO 0
#elif CFG_TUSB_MCU == OPT_MCU_STM32L1
#include "stm32l1xx.h"
- #define FSDEV_PMA_SIZE (512u)
#define FSDEV_HAS_SBUF_ISO 0
-#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
- #include "stm32g4xx.h"
- #define FSDEV_PMA_SIZE (1024u)
+#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
+ #include "stm32l4xx.h"
+ #define FSDEV_HAS_SBUF_ISO 0
+
+#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
+ #include "stm32l5xx.h"
#define FSDEV_HAS_SBUF_ISO 0
+ #ifndef USB_PMAADDR
+ #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS))
+ #endif
+
#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
#include "stm32g0xx.h"
- #define FSDEV_PMA_SIZE (2048u)
- #define FSDEV_HAS_SBUF_ISO 1
- #define USB USB_DRD_FS
+ #define FSDEV_HAS_SBUF_ISO 1
+ #define USB USB_DRD_FS
- #define USB_EP_CTR_RX USB_EP_VTRX
- #define USB_EP_CTR_TX USB_EP_VTTX
- #define USB_EP_T_FIELD USB_CHEP_UTYPE
+ #define USB_EP_CTR_RX USB_EP_VTRX
+ #define USB_EP_CTR_TX USB_EP_VTTX
+ #define USB_EP_T_FIELD USB_CHEP_UTYPE
#define USB_EPREG_MASK USB_CHEP_REG_MASK
#define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
#define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
@@ -110,78 +122,20 @@
#define USB_ISTR_EP_ID USB_ISTR_IDN
#define USB_EPADDR_FIELD USB_CHEP_ADDR
#define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
- #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+ #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
-#elif CFG_TUSB_MCU == OPT_MCU_STM32C0
- #include "stm32c0xx.h"
- #define FSDEV_PMA_SIZE (2048u)
- #define FSDEV_HAS_SBUF_ISO 1
- #define USB USB_DRD_FS
- #define USB_EP_CTR_RX USB_CHEP_VTRX
- #define USB_EP_CTR_TX USB_CHEP_VTTX
- #define USB_EPREG_MASK USB_CHEP_REG_MASK
- #define USB_CNTR_FRES USB_CNTR_USBRST
- #define USB_CNTR_RESUME USB_CNTR_L2RES
- #define USB_ISTR_EP_ID USB_ISTR_IDN
- #define USB_EPADDR_FIELD USB_CHEP_ADDR
- #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
- #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+#elif CFG_TUSB_MCU == OPT_MCU_STM32G4
+ #include "stm32g4xx.h"
+ #define FSDEV_HAS_SBUF_ISO 0
#elif CFG_TUSB_MCU == OPT_MCU_STM32H5
#include "stm32h5xx.h"
- #define FSDEV_PMA_SIZE (2048u)
#define FSDEV_HAS_SBUF_ISO 1
- #define USB USB_DRD_FS
+ #define USB USB_DRD_FS
- #define USB_EP_CTR_RX USB_EP_VTRX
- #define USB_EP_CTR_TX USB_EP_VTTX
- #define USB_EP_T_FIELD USB_CHEP_UTYPE
- #define USB_EPREG_MASK USB_CHEP_REG_MASK
- #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
- #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
- #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1
- #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2
- #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1
- #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
- #define USB_EPRX_STAT USB_CH_RX_VALID
- #define USB_EPKIND_MASK USB_EP_KIND_MASK
- #define USB_CNTR_FRES USB_CNTR_USBRST
- #define USB_CNTR_RESUME USB_CNTR_L2RES
- #define USB_ISTR_EP_ID USB_ISTR_IDN
- #define USB_EPADDR_FIELD USB_CHEP_ADDR
- #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
- #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
-
-#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
- #include "stm32wbxx.h"
- #define FSDEV_PMA_SIZE (1024u)
- #define FSDEV_HAS_SBUF_ISO 0
- /* ST provided header has incorrect value of USB_PMAADDR */
- #define FSDEV_PMA_BASE USB1_PMAADDR
-
-#elif CFG_TUSB_MCU == OPT_MCU_STM32L4
- #include "stm32l4xx.h"
- #define FSDEV_PMA_SIZE (1024u)
- #define FSDEV_HAS_SBUF_ISO 0
-
-#elif CFG_TUSB_MCU == OPT_MCU_STM32L5
- #include "stm32l5xx.h"
- #define FSDEV_PMA_SIZE (1024u)
- #define FSDEV_HAS_SBUF_ISO 0
-
- #ifndef USB_PMAADDR
- #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS))
- #endif
-
-#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
- #include "stm32u5xx.h"
- #define FSDEV_PMA_SIZE (2048u)
- #define FSDEV_HAS_SBUF_ISO 1
- #define USB USB_DRD_FS
-
- #define USB_EP_CTR_RX USB_EP_VTRX
- #define USB_EP_CTR_TX USB_EP_VTTX
- #define USB_EP_T_FIELD USB_CHEP_UTYPE
+ #define USB_EP_CTR_RX USB_EP_VTRX
+ #define USB_EP_CTR_TX USB_EP_VTTX
+ #define USB_EP_T_FIELD USB_CHEP_UTYPE
#define USB_EPREG_MASK USB_CHEP_REG_MASK
#define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
#define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
@@ -200,7 +154,6 @@
#elif CFG_TUSB_MCU == OPT_MCU_STM32U0
#include "stm32u0xx.h"
- #define FSDEV_PMA_SIZE (1024u)
#define FSDEV_BUS_32BIT
#define FSDEV_HAS_SBUF_ISO 1
#define USB USB_DRD_FS
@@ -226,10 +179,9 @@
#elif CFG_TUSB_MCU == OPT_MCU_STM32U3
#include "stm32u3xx.h"
- #define FSDEV_PMA_SIZE (2048u)
#define FSDEV_BUS_32BIT
#define FSDEV_HAS_SBUF_ISO 1 // This is assumed to work but has not been tested...
- #define USB USB_DRD_FS
+ #define USB USB_DRD_FS
#define USB_EP_CTR_RX USB_EP_VTRX
#define USB_EP_CTR_TX USB_EP_VTTX
@@ -240,15 +192,45 @@
#define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1
#define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2
#define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1
- #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
- #define USB_EPRX_STAT USB_CH_RX_VALID
- #define USB_EPKIND_MASK USB_EP_KIND_MASK
- #define USB_CNTR_FRES USB_CNTR_USBRST
- #define USB_CNTR_RESUME USB_CNTR_L2RES
- #define USB_ISTR_EP_ID USB_ISTR_IDN
- #define USB_EPADDR_FIELD USB_CHEP_ADDR
- #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
- #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
+ #define USB_EPRX_STAT USB_CH_RX_VALID
+ #define USB_EPKIND_MASK USB_EP_KIND_MASK
+ #define USB_CNTR_FRES USB_CNTR_USBRST
+ #define USB_CNTR_RESUME USB_CNTR_L2RES
+ #define USB_ISTR_EP_ID USB_ISTR_IDN
+ #define USB_EPADDR_FIELD USB_CHEP_ADDR
+ #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
+ #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+
+#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
+ #include "stm32u5xx.h"
+ #define FSDEV_HAS_SBUF_ISO 1
+ #define USB USB_DRD_FS
+
+ #define USB_EP_CTR_RX USB_EP_VTRX
+ #define USB_EP_CTR_TX USB_EP_VTTX
+ #define USB_EP_T_FIELD USB_CHEP_UTYPE
+ #define USB_EPREG_MASK USB_CHEP_REG_MASK
+ #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK
+ #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK
+ #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1
+ #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2
+ #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1
+ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2
+ #define USB_EPRX_STAT USB_CH_RX_VALID
+ #define USB_EPKIND_MASK USB_EP_KIND_MASK
+ #define USB_CNTR_FRES USB_CNTR_USBRST
+ #define USB_CNTR_RESUME USB_CNTR_L2RES
+ #define USB_ISTR_EP_ID USB_ISTR_IDN
+ #define USB_EPADDR_FIELD USB_CHEP_ADDR
+ #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY
+ #define USB_CNTR_FSUSP USB_CNTR_SUSPEN
+
+#elif CFG_TUSB_MCU == OPT_MCU_STM32WB
+ #include "stm32wbxx.h"
+ #define FSDEV_HAS_SBUF_ISO 0
+ /* ST provided header has incorrect value of USB_PMAADDR */
+ #define FSDEV_PMA_BASE USB1_PMAADDR
#else
#error You are using an untested or unimplemented STM32 variant. Please update the driver.
@@ -299,7 +281,7 @@
// - Enable double buffering on devices with >1KB Packet Memory Area (PMA)
// to improve isochronous transfer reliability and performance
// - Disable on devices with limited PMA to conserve memory space
- #if FSDEV_PMA_SIZE > 1024u
+ #if CFG_TUSB_FSDEV_PMA_SIZE > 1024u
#define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 1
#else
#define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0
@@ -371,7 +353,7 @@ static const IRQn_Type fsdev_irq[] = {
};
enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) };
-void dcd_int_enable(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_enable(uint8_t rhport) {
(void)rhport;
// forces write to RAM before allowing ISR to execute
@@ -394,7 +376,7 @@ void dcd_int_enable(uint8_t rhport) {
}
}
-void dcd_int_disable(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) {
(void)rhport;
#if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP)
@@ -419,28 +401,27 @@ void dcd_int_disable(uint8_t rhport) {
// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU.
#if defined(USB_BCDR_DPPU)
-void dcd_disconnect(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) {
(void)rhport;
USB->BCDR &= ~(USB_BCDR_DPPU);
}
-void dcd_connect(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) {
(void)rhport;
USB->BCDR |= USB_BCDR_DPPU;
}
#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151
-void dcd_disconnect(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_disconnect(uint8_t rhport) {
(void)rhport;
SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU);
}
-void dcd_connect(uint8_t rhport) {
+TU_ATTR_ALWAYS_INLINE static inline void fsdev_connect(uint8_t rhport) {
(void)rhport;
SYSCFG->PMC |= SYSCFG_PMC_USB_PU;
}
#endif
-
#endif /* TUSB_FSDEV_STM32_H */
diff --git a/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
new file mode 100644
index 000000000..acdeccf6d
--- /dev/null
+++ b/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c
@@ -0,0 +1,878 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2025 HiFiPhile (Zixun LI)
+ *
+ * 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.
+ */
+
+/**********************************************
+ * This driver provides USB Host controller support for STM32 MCUs with "USB A"/"PCD"/"HCD" peripheral.
+ * This covers these MCU families:
+ *
+ * C0 2048 byte buffer; 32-bit bus; host mode
+ * G0 2048 byte buffer; 32-bit bus; host mode
+ * U3 2048 byte buffer; 32-bit bus; host mode
+ * H5 2048 byte buffer; 32-bit bus; host mode
+ * U535, U545 2048 byte buffer; 32-bit bus; host mode
+ *
+ */
+
+#include "tusb_option.h"
+
+#if CFG_TUH_ENABLED && defined(TUP_USBIP_FSDEV) && \
+ TU_CHECK_MCU(OPT_MCU_STM32C0, OPT_MCU_STM32G0, OPT_MCU_STM32H5, OPT_MCU_STM32U5)
+
+#include "host/hcd.h"
+#include "host/usbh.h"
+#include "fsdev_common.h"
+
+//--------------------------------------------------------------------+
+// MACRO CONSTANT TYPEDEF
+//--------------------------------------------------------------------+
+
+// Debug level for FSDEV
+#define FSDEV_DEBUG 3
+
+// Max number of endpoints application can open, can be larger than FSDEV_EP_COUNT
+#ifndef CFG_TUH_FSDEV_ENDPOINT_MAX
+ #define CFG_TUH_FSDEV_ENDPOINT_MAX 16u
+#endif
+
+TU_VERIFY_STATIC(CFG_TUH_FSDEV_ENDPOINT_MAX <= 255, "currently only use 8-bit for index");
+
+#if CFG_TUSB_MCU == OPT_MCU_STM32H5
+ #define CPU_FREQUENCY_MHZ 250U
+#elif CFG_TUSB_MCU == OPT_MCU_STM32U5
+ #define CPU_FREQUENCY_MHZ 160U
+#elif CFG_TUSB_MCU == OPT_MCU_STM32U3
+ #define CPU_FREQUENCY_MHZ 96U
+#elif CFG_TUSB_MCU == OPT_MCU_STM32G0
+ #define CPU_FREQUENCY_MHZ 64U
+#elif CFG_TUSB_MCU == OPT_MCU_STM32C0
+ #define CPU_FREQUENCY_MHZ 48U
+#else
+ #error "CPU_FREQUENCY_MHZ not defined for this STM32 MCU"
+#endif
+
+enum {
+ HCD_XFER_ERROR_MAX = 3,
+ HCD_XFER_NAK_MAX = 15,
+ HCD_XFER_NAK_DEFAULT = 3,
+};
+
+// Host driver struct for each opened endpoint
+typedef struct {
+ uint8_t *buffer;
+ uint16_t buflen;
+ uint16_t queued_len;
+ uint16_t max_packet_size;
+ uint8_t dev_addr;
+ uint8_t ep_addr;
+ uint8_t ep_type;
+ uint8_t interval;
+ struct TU_ATTR_PACKED {
+ uint8_t ls_pre : 1;
+ uint8_t allocated : 1;
+ uint8_t next_setup : 1;
+ uint8_t pid : 1;
+ };
+} hcd_endpoint_t;
+
+// Channel direction state
+typedef struct {
+ hcd_endpoint_t* edpt;
+ struct TU_ATTR_PACKED {
+ uint8_t allocated : 1;
+ uint8_t retry : 3;
+ uint8_t nak : 4; // Max NAK count in current frame
+ };
+} hcd_channel_dir_t;
+
+// Additional info for each channel when it is active
+typedef struct {
+ uint8_t dev_addr;
+ uint8_t ep_num;
+ uint8_t ep_type;
+ hcd_channel_dir_t out, in;
+} hcd_channel_t;
+
+static struct {
+ hcd_channel_t channel[FSDEV_EP_COUNT];
+ hcd_endpoint_t edpt[CFG_TUH_FSDEV_ENDPOINT_MAX];
+ bool connected;
+} _hcd_data;
+
+static tuh_configure_fsdev_t _tuh_cfg = {
+ .max_nak = HCD_XFER_NAK_DEFAULT,
+};
+
+//--------------------------------------------------------------------+
+// Prototypes
+//--------------------------------------------------------------------+
+
+static uint8_t endpoint_alloc(void);
+static uint8_t endpoint_find(uint8_t dev_addr, uint8_t ep_addr);
+static uint32_t hcd_pma_alloc(uint8_t channel, tusb_dir_t dir, uint16_t len);
+static uint8_t channel_alloc(uint8_t dev_addr, uint8_t ep_addr, uint8_t ep_type);
+static bool edpt_xfer_kickoff(uint8_t ep_id);
+static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir);
+static void edpoint_close(uint8_t ep_id);
+static void port_status_handler(uint8_t rhport, bool in_isr);
+static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir);
+static void ch_handle_nak(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir);
+static void ch_handle_stall(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir);
+static void ch_handle_error(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir);
+
+//--------------------------------------------------------------------+
+// Inline Functions
+//--------------------------------------------------------------------+
+
+static inline void endpoint_dealloc(hcd_endpoint_t* edpt) {
+ edpt->allocated = 0;
+}
+
+static inline void channel_dealloc(hcd_channel_t* ch, tusb_dir_t dir) {
+ if (dir == TUSB_DIR_OUT) {
+ ch->out.allocated = 0;
+ } else {
+ ch->in.allocated = 0;
+ }
+}
+
+// Write channel state in specified direction
+static inline void channel_write_status(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir, ep_stat_t state, bool need_exclusive) {
+ ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir);
+ ch_change_status(&ch_reg, dir, state);
+ ch_write(ch_id, ch_reg, need_exclusive);
+}
+
+static inline uint16_t channel_get_rx_count(uint8_t ch_id) {
+ /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf
+ * https://www.st.com/resource/en/errata_sheet/es0587-stm32u535xx-and-stm32u545xx-device-errata-stmicroelectronics.pdf
+ * From H503/U535 errata: Buffer description table update completes after CTR interrupt triggers
+ * Description:
+ * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses
+ * have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct.
+ * Workaround:
+ * - Software should ensure that a small delay is included before accessing the SRAM contents. This delay
+ * should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode
+ *
+ * Note: this errata may also apply to G0, U5, H5 etc.
+ *
+ * We choose the delay count based on max CPU frequency (in MHz) to ensure the delay is at least the required time.
+ */
+
+ uint32_t ch_reg = ch_read(ch_id);
+ if (FSDEV_REG->ISTR & USB_ISTR_LS_DCONN || ch_reg & USB_CHEP_LSEP) {
+ // Low speed mode: 6.4 us delay -> about 2 cycles per MHz
+ volatile uint32_t cycle_count = CPU_FREQUENCY_MHZ * 2U;
+ while (cycle_count > 0U) {
+ cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare)
+ }
+ } else {
+ // Full speed mode: 800 ns delay -> about 0.25 cycles per MHz
+ volatile uint32_t cycle_count = CPU_FREQUENCY_MHZ / 4U;
+ while (cycle_count > 0U) {
+ cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare)
+ }
+ }
+
+ return btable_get_count(ch_id, BTABLE_BUF_RX);
+}
+
+//--------------------------------------------------------------------+
+// Controller API
+//--------------------------------------------------------------------+
+
+// Optional HCD configuration, called by tuh_configure()
+bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) {
+ (void) rhport;
+ TU_VERIFY(cfg_id == TUH_CFGID_FSDEV && cfg_param != NULL);
+
+ tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param;
+ _tuh_cfg.max_nak = tu_min8(cfg->fsdev.max_nak, HCD_XFER_NAK_MAX);
+ return true;
+}
+
+// Initialize controller to host mode
+bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
+ (void) rh_init;
+
+ fsdev_core_reset();
+
+ FSDEV_REG->CNTR = USB_CNTR_HOST; // Enable USB in Host mode
+
+ tu_memclr(&_hcd_data, sizeof(_hcd_data));
+
+ // Enable interrupts for host mode
+ FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_CTRM | USB_CNTR_SOFM | USB_CNTR_SUSPM |
+ USB_CNTR_WKUPM | USB_CNTR_ERRM | USB_CNTR_PMAOVRM;
+
+ // Initialize port state
+ _hcd_data.connected = false;
+
+ fsdev_connect(rhport);
+
+ // If DCON_STAT is already set, the controller sometimes misses the initial connection interrupt
+ if (FSDEV_REG->ISTR & USB_ISTR_DCON_STAT) {
+ // Wait DP/DM stabilize time
+ volatile uint32_t cycle_count = CPU_FREQUENCY_MHZ / 4U;
+ while (cycle_count > 0U) {
+ cycle_count--;
+ }
+ port_status_handler(rhport, false);
+ }
+
+ return true;
+}
+
+bool hcd_deinit(uint8_t rhport) {
+ (void)rhport;
+
+ fsdev_disconnect(rhport);
+
+ fsdev_deinit();
+
+ return true;
+}
+
+//--------------------------------------------------------------------+
+// Interrupt Helper Functions
+//--------------------------------------------------------------------+
+
+static inline void sof_handler(void) {
+ // Reset NAK counters for all active channels
+ for (uint8_t ch_id = 0; ch_id < FSDEV_EP_COUNT; ch_id++) {
+ hcd_channel_t* channel = &_hcd_data.channel[ch_id];
+ if (channel->out.allocated) {
+ channel->out.nak = 0;
+ }
+ if (channel->in.allocated) {
+ channel->in.nak = 0;
+ }
+ }
+}
+
+static void port_status_handler(uint8_t rhport, bool in_isr) {
+ uint32_t const fnr_reg = FSDEV_REG->FNR;
+ uint32_t const istr_reg = FSDEV_REG->ISTR;
+ // SE0 detected USB Disconnected state
+ if ((fnr_reg & (USB_FNR_RXDP | USB_FNR_RXDM)) == 0U) {
+ _hcd_data.connected = false;
+ hcd_event_device_remove(rhport, in_isr);
+ return;
+ }
+
+ if (!_hcd_data.connected) {
+ // J-state or K-state detected & LastState=Disconnected
+ if (((fnr_reg & USB_FNR_RXDP) != 0U) || ((istr_reg & USB_ISTR_LS_DCONN) != 0U)) {
+ _hcd_data.connected = true;
+ hcd_event_device_attach(rhport, in_isr);
+ }
+ } else {
+ // J-state or K-state detected & lastState=Connected: a Missed disconnection is detected
+ if (((fnr_reg & USB_FNR_RXDP) != 0U) || ((istr_reg & USB_ISTR_LS_DCONN) != 0U)) {
+ _hcd_data.connected = false;
+ hcd_event_device_remove(rhport, in_isr);
+ }
+ }
+}
+
+// Handle ACK response
+static void ch_handle_ack(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
+ uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
+ uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
+
+ uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0));
+ if (ep_id == TUSB_INDEX_INVALID_8) {
+ return;
+ }
+
+ hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id];
+ hcd_channel_t *channel = &_hcd_data.channel[ch_id];
+
+ if (dir == TUSB_DIR_OUT) {
+ // OUT/TX direction
+ if (edpt->buflen != edpt->queued_len) {
+ // More data to send
+ uint16_t const len = tu_min16(edpt->buflen - edpt->queued_len, edpt->max_packet_size);
+ uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_TX);
+ tu_hwfifo_write(PMA_BUF_AT(pma_addr), &(edpt->buffer[edpt->queued_len]), len, NULL);
+ btable_set_count(ch_id, BTABLE_BUF_TX, len);
+ edpt->queued_len += len;
+ channel_write_status(ch_id, ch_reg, TUSB_DIR_OUT, EP_STAT_VALID, false);
+ channel->out.nak = 0;
+ } else {
+ // Transfer complete
+ channel_dealloc(channel, TUSB_DIR_OUT);
+ edpt->pid = (ch_reg & USB_CHEP_DTOG_TX) ? 1 : 0;
+ hcd_event_xfer_complete(daddr, ep_num, edpt->queued_len, XFER_RESULT_SUCCESS, true);
+ }
+ } else {
+ // IN/RX direction
+ uint16_t const rx_count = channel_get_rx_count(ch_id);
+ uint16_t pma_addr = (uint16_t) btable_get_addr(ch_id, BTABLE_BUF_RX);
+ tu_hwfifo_read(PMA_BUF_AT(pma_addr), edpt->buffer + edpt->queued_len, rx_count, NULL);
+ edpt->queued_len += rx_count;
+
+ if ((rx_count < edpt->max_packet_size) || (edpt->queued_len >= edpt->buflen)) {
+ // Transfer complete (short packet or all bytes received)
+ channel_dealloc(channel, TUSB_DIR_IN);
+ edpt->pid = (ch_reg & USB_CHEP_DTOG_RX) ? 1 : 0;
+ hcd_event_xfer_complete(daddr, ep_num | TUSB_DIR_IN_MASK, edpt->queued_len, XFER_RESULT_SUCCESS, true);
+ } else {
+ // More data expected
+ uint16_t const cnt = tu_min16(edpt->buflen - edpt->queued_len, edpt->max_packet_size);
+ btable_set_rx_bufsize(ch_id, BTABLE_BUF_RX, cnt);
+ channel_write_status(ch_id, ch_reg, TUSB_DIR_IN, EP_STAT_VALID, false);
+ channel->in.nak = 0;
+ }
+ }
+}
+
+// Handle NAK response
+static void ch_handle_nak(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
+ uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
+ uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
+
+ uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0));
+ if (ep_id == TUSB_INDEX_INVALID_8) return;
+
+ hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
+ // Retry non-periodic transfer immediately if NAK count not exceeded
+ // Periodic transfer will be retried by next frame automatically
+ if (edpt->ep_type == TUSB_XFER_CONTROL || edpt->ep_type == TUSB_XFER_BULK) {
+ hcd_channel_dir_t* channel_dir =
+ (dir == TUSB_DIR_OUT) ? &(_hcd_data.channel[ch_id].out) : &(_hcd_data.channel[ch_id].in);
+ if (channel_dir->nak < HCD_XFER_NAK_MAX) {
+ channel_dir->nak++;
+ }
+ if (channel_dir->nak < _tuh_cfg.max_nak || _tuh_cfg.max_nak == 0) {
+ channel_write_status(ch_id, ch_reg, dir, EP_STAT_VALID, false);
+ }
+ }
+}
+
+// Handle STALL response
+static void ch_handle_stall(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
+ uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
+ uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
+
+ uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0));
+ if (ep_id == TUSB_INDEX_INVALID_8) return;
+
+ hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
+ hcd_channel_t* channel = &_hcd_data.channel[ch_id];
+ channel_dealloc(channel, dir);
+
+ channel_write_status(ch_id, ch_reg, dir, EP_STAT_DISABLED, false);
+
+ hcd_event_xfer_complete(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0),
+ edpt->queued_len, XFER_RESULT_STALLED, true);
+}
+
+// Handle error response
+static void ch_handle_error(uint8_t ch_id, uint32_t ch_reg, tusb_dir_t dir) {
+ uint8_t const ep_num = ch_reg & USB_EPADDR_FIELD;
+ uint8_t const daddr = (ch_reg & USB_CHEP_DEVADDR_Msk) >> USB_CHEP_DEVADDR_Pos;
+
+ uint8_t ep_id = endpoint_find(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0));
+ if (ep_id == TUSB_INDEX_INVALID_8) return;
+
+ hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
+ hcd_channel_t* channel = &_hcd_data.channel[ch_id];
+
+ ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir);
+ ch_reg &= ~(dir == TUSB_DIR_OUT ? USB_CH_ERRTX : USB_CH_ERRRX);
+
+ hcd_channel_dir_t* channel_dir =
+ (dir == TUSB_DIR_OUT) ? &(_hcd_data.channel[ch_id].out) : &(_hcd_data.channel[ch_id].in);
+ if (channel_dir->retry < HCD_XFER_ERROR_MAX) {
+ // Retry
+ channel_dir->retry++;
+ ch_change_status(&ch_reg, dir, EP_STAT_VALID);
+ } else {
+ // Failed after retries
+ channel_dealloc(channel, dir);
+ ch_change_status(&ch_reg, dir, EP_STAT_DISABLED);
+ hcd_event_xfer_complete(daddr, ep_num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0),
+ edpt->queued_len, XFER_RESULT_FAILED, true);
+ }
+ ch_write(ch_id, ch_reg, false);
+}
+
+// Handle CTR interrupt for the TX/OUT direction
+static inline void handle_ctr_tx(uint32_t ch_id) {
+ uint32_t ch_reg = ch_read(ch_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
+ hcd_channel_t* channel = &_hcd_data.channel[ch_id];
+ TU_VERIFY(channel->out.allocated == 1,);
+
+ if ((ch_reg & USB_CH_ERRTX) == 0U) {
+ // No error
+ if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_ACK_SBUF) {
+ ch_handle_ack(ch_id, ch_reg, TUSB_DIR_OUT);
+ } else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_NAK) {
+ ch_handle_nak(ch_id, ch_reg, TUSB_DIR_OUT);
+ } else if ((ch_reg & USB_CH_TX_STTX) == USB_CH_TX_STALL) {
+ ch_handle_stall(ch_id, ch_reg, TUSB_DIR_OUT);
+ }
+ } else {
+ ch_handle_error(ch_id, ch_reg, TUSB_DIR_OUT);
+ }
+}
+
+// Handle CTR interrupt for the RX/IN direction
+static inline void handle_ctr_rx(uint32_t ch_id) {
+ uint32_t ch_reg = ch_read(ch_id) | USB_EP_CTR_TX | USB_EP_CTR_RX;
+ hcd_channel_t* channel = &_hcd_data.channel[ch_id];
+ TU_VERIFY(channel->in.allocated == 1,);
+
+ if ((ch_reg & USB_CH_ERRRX) == 0U) {
+ // No error
+ if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_ACK_SBUF) {
+ ch_handle_ack(ch_id, ch_reg, TUSB_DIR_IN);
+ } else if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_NAK) {
+ ch_handle_nak(ch_id, ch_reg, TUSB_DIR_IN);
+ } else if ((ch_reg & USB_CH_RX_STRX) == USB_CH_RX_STALL){
+ ch_handle_stall(ch_id, ch_reg, TUSB_DIR_IN);
+ }
+ } else {
+ ch_handle_error(ch_id, ch_reg, TUSB_DIR_IN);
+ }
+}
+
+// Interrupt Handler
+void hcd_int_handler(uint8_t rhport, bool in_isr) {
+ uint32_t int_status = FSDEV_REG->ISTR;
+
+ // Start of Frame
+ if (int_status & USB_ISTR_SOF) {
+ FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SOF;
+ sof_handler();
+ }
+
+ // Port Change Detected (Connection/Disconnection)
+ if (int_status & USB_ISTR_DCON) {
+ FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_DCON;
+ port_status_handler(rhport, in_isr);
+ }
+
+ // Handle transfer complete (CTR)
+ while (FSDEV_REG->ISTR & USB_ISTR_CTR) {
+ uint32_t const ch_id = FSDEV_REG->ISTR & USB_ISTR_EP_ID;
+ uint32_t const ch_reg = ch_read(ch_id);
+
+ if (ch_reg & USB_EP_CTR_RX) {
+ ch_write_clear_ctr(ch_id, TUSB_DIR_IN);
+ handle_ctr_rx(ch_id);
+ }
+
+ if (ch_reg & USB_EP_CTR_TX) {
+ ch_write_clear_ctr(ch_id, TUSB_DIR_OUT);
+ handle_ctr_tx(ch_id);
+ }
+ }
+
+ if (int_status & USB_ISTR_ERR) {
+ FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ERR;
+ // TODO: Handle error
+ }
+
+ if (int_status & USB_ISTR_PMAOVR) {
+ TU_BREAKPOINT();
+ FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR;
+ }
+}
+
+// Enable USB interrupt
+void hcd_int_enable(uint8_t rhport) {
+ fsdev_int_enable(rhport);
+}
+
+// Disable USB interrupt
+void hcd_int_disable(uint8_t rhport) {
+ fsdev_int_disable(rhport);
+}
+
+// Get frame number (1ms)
+uint32_t hcd_frame_number(uint8_t rhport) {
+ (void) rhport;
+ return FSDEV_REG->FNR & USB_FNR_FN;
+}
+
+//--------------------------------------------------------------------+
+// Port API
+//--------------------------------------------------------------------+
+
+// Get the current connect status of roothub port
+bool hcd_port_connect_status(uint8_t rhport) {
+ (void) rhport;
+ return _hcd_data.connected;
+}
+
+// Reset USB bus on the port
+void hcd_port_reset(uint8_t rhport) {
+ (void) rhport;
+ FSDEV_REG->CNTR |= USB_CNTR_FRES;
+}
+
+// Complete bus reset sequence
+void hcd_port_reset_end(uint8_t rhport) {
+ (void) rhport;
+ FSDEV_REG->CNTR &= ~USB_CNTR_FRES;
+}
+
+// Get port link speed
+tusb_speed_t hcd_port_speed_get(uint8_t rhport) {
+ (void) rhport;
+ if ((FSDEV_REG->ISTR & USB_ISTR_LS_DCONN) != 0U) {
+ return TUSB_SPEED_LOW;
+ } else {
+ return TUSB_SPEED_FULL;
+ }
+}
+
+// HCD closes all opened endpoints belonging to this device
+void hcd_device_close(uint8_t rhport, uint8_t dev_addr) {
+ (void) rhport;
+
+ // Close all endpoints for this device
+ for(uint32_t i = 0; i < CFG_TUH_FSDEV_ENDPOINT_MAX; i++) {
+ hcd_endpoint_t* edpt = &_hcd_data.edpt[i];
+ if (edpt->allocated == 1 && edpt->dev_addr == dev_addr) {
+ edpoint_close(i);
+ }
+ }
+
+}
+
+//--------------------------------------------------------------------+
+// Endpoints API
+//--------------------------------------------------------------------+
+
+// Open an endpoint
+bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc) {
+ (void) rhport;
+
+ uint8_t const ep_addr = ep_desc->bEndpointAddress;
+ uint16_t const packet_size = tu_edpt_packet_size(ep_desc);
+ uint8_t const ep_type = ep_desc->bmAttributes.xfer;
+
+ uint8_t const ep_id = endpoint_alloc();
+ TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8);
+
+ hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
+ edpt->dev_addr = dev_addr;
+ edpt->ep_addr = ep_addr;
+ edpt->ep_type = ep_type;
+ edpt->max_packet_size = packet_size;
+ edpt->interval = ep_desc->bInterval;
+ edpt->pid = 0;
+ edpt->ls_pre = (hcd_port_speed_get(rhport) == TUSB_SPEED_FULL && tuh_speed_get(dev_addr) == TUSB_SPEED_LOW) ? 1 : 0;
+
+ return true;
+}
+
+bool hcd_edpt_close(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+
+ uint8_t const ep_id = endpoint_find(dev_addr, ep_addr);
+ TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8);
+
+ edpoint_close(ep_id);
+
+ return true;
+}
+
+// Submit a transfer
+bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) {
+ (void) rhport;
+
+ TU_LOG(FSDEV_DEBUG, "hcd_edpt_xfer addr=%u ep=0x%02X len=%u\r\n", dev_addr, ep_addr, buflen);
+
+ uint8_t const ep_id = endpoint_find(dev_addr, ep_addr);
+ TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8);
+
+ hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id];
+
+ edpt->buffer = buffer;
+ edpt->buflen = buflen;
+ edpt->queued_len = 0;
+
+ uint8_t const ep_num = tu_edpt_number(ep_addr);
+ if (ep_num == 0) {
+ // update ep_dir since control endpoint can switch direction
+ edpt->ep_addr = ep_addr;
+ }
+
+ return edpt_xfer_kickoff(ep_id);
+}
+
+// Abort a queued transfer
+bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+
+ uint8_t const ep_id = endpoint_find(dev_addr, ep_addr);
+ TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8);
+ tusb_dir_t const dir = tu_edpt_dir(ep_addr);
+
+ for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
+ hcd_channel_t* channel = &_hcd_data.channel[i];
+ uint8_t const allocated = (dir == TUSB_DIR_OUT) ? channel->out.allocated : channel->in.allocated;
+
+ if (allocated == 1 &&
+ channel->dev_addr == dev_addr &&
+ channel->ep_num == tu_edpt_number(ep_addr)) {
+ channel_dealloc(channel, dir);
+ uint32_t ch_reg = ch_read(i) | USB_EP_CTR_TX | USB_EP_CTR_RX;
+ channel_write_status(i, ch_reg, dir, EP_STAT_DISABLED, true);
+ }
+ }
+
+ return true;
+}
+
+// Submit a special transfer to send 8-byte Setup Packet
+bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) {
+ (void) rhport;
+
+ uint8_t const ep_id = endpoint_find(dev_addr, 0);
+ TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8);
+
+ hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id];
+ edpt->next_setup = true;
+ edpt->pid = 0;
+
+ return hcd_edpt_xfer(rhport, dev_addr, 0, (uint8_t*)(uintptr_t) setup_packet, 8);
+}
+
+// Clear stall, data toggle is also reset to DATA0
+bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
+ (void) rhport;
+ (void) dev_addr;
+ (void) ep_addr;
+
+ uint8_t const ep_id = endpoint_find(dev_addr, 0);
+ TU_ASSERT(ep_id != TUSB_INDEX_INVALID_8);
+
+ hcd_endpoint_t *edpt = &_hcd_data.edpt[ep_id];
+ edpt->pid = 0;
+
+ return true;
+}
+
+//--------------------------------------------------------------------+
+// Helper Functions
+//--------------------------------------------------------------------+
+
+static uint8_t endpoint_alloc(void) {
+ for (uint32_t i = 0; i < CFG_TUH_FSDEV_ENDPOINT_MAX; i++) {
+ hcd_endpoint_t* edpt = &_hcd_data.edpt[i];
+ if (edpt->allocated == 0) {
+ edpt->allocated = 1;
+ return i;
+ }
+ }
+ return TUSB_INDEX_INVALID_8;
+}
+
+static uint8_t endpoint_find(uint8_t dev_addr, uint8_t ep_addr) {
+ uint8_t const ep_num = tu_edpt_number(ep_addr);
+ tusb_dir_t const ep_dir = tu_edpt_dir(ep_addr);
+
+ for (uint32_t i = 0; i < (uint32_t)CFG_TUH_FSDEV_ENDPOINT_MAX; i++) {
+ hcd_endpoint_t* edpt = &_hcd_data.edpt[i];
+ tusb_dir_t const dir = tu_edpt_dir(edpt->ep_addr);
+ uint8_t const num = tu_edpt_number(edpt->ep_addr);
+ // Match both ep_num and ep_dir, or match ep_num 0 (control endpoint)
+ if (edpt->allocated == 1 && edpt->dev_addr == dev_addr && num == ep_num &&
+ (dir == ep_dir || ep_num == 0)) {
+ return i;
+ }
+ }
+ return TUSB_INDEX_INVALID_8;
+}
+
+// close an opened endpoint
+static void edpoint_close(uint8_t ep_id) {
+ hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
+ endpoint_dealloc(edpt);
+
+ // disable active channel belong to this endpoint
+ for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
+ hcd_channel_t* channel = &_hcd_data.channel[i];
+ uint32_t ch_reg = ch_read(i) | USB_EP_CTR_TX | USB_EP_CTR_RX;
+ if (channel->out.allocated == 1 && channel->out.edpt == edpt) {
+ channel_dealloc(channel, TUSB_DIR_OUT);
+ channel_write_status(i, ch_reg, TUSB_DIR_OUT, EP_STAT_DISABLED, true);
+ }
+ if (channel->in.allocated == 1 && channel->in.edpt == edpt) {
+ channel_dealloc(channel, TUSB_DIR_IN);
+ channel_write_status(i, ch_reg, TUSB_DIR_IN, EP_STAT_DISABLED, true);
+ }
+ }
+}
+
+// Allocate PMA buffer
+static uint32_t hcd_pma_alloc(uint8_t channel, tusb_dir_t dir, uint16_t len) {
+ (void) len;
+ // Simple static allocation as we are unlikely to handle ISO endpoints in host mode
+ // We just give each channel two buffers of max packet size (64 bytes) for IN and OUT
+
+ uint16_t addr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT;
+ addr += channel * TUSB_EPSIZE_BULK_FS * 2 + (dir == TUSB_DIR_IN ? TUSB_EPSIZE_BULK_FS : 0);
+
+ TU_ASSERT(addr <= CFG_TUSB_FSDEV_PMA_SIZE, 0xFFFF);
+
+ return addr;
+}
+
+// Allocate hardware channel
+static uint8_t channel_alloc(uint8_t dev_addr, uint8_t ep_addr, uint8_t ep_type) {
+ uint8_t const ep_num = tu_edpt_number(ep_addr);
+ tusb_dir_t const dir = tu_edpt_dir(ep_addr);
+
+ // Find channel allocate for same ep_num but other direction
+ tusb_dir_t const other_dir = (dir == TUSB_DIR_IN) ? TUSB_DIR_OUT : TUSB_DIR_IN;
+ for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
+ uint8_t const allocated_dir = (dir == TUSB_DIR_OUT) ? _hcd_data.channel[i].out.allocated : _hcd_data.channel[i].in.allocated;
+ uint8_t const allocated_other = (other_dir == TUSB_DIR_OUT) ? _hcd_data.channel[i].out.allocated : _hcd_data.channel[i].in.allocated;
+ if (allocated_dir == 0 &&
+ allocated_other == 1 &&
+ _hcd_data.channel[i].dev_addr == dev_addr &&
+ _hcd_data.channel[i].ep_num == ep_num &&
+ _hcd_data.channel[i].ep_type == ep_type) {
+ if (dir == TUSB_DIR_OUT) {
+ _hcd_data.channel[i].out.allocated = 1;
+ _hcd_data.channel[i].out.retry = 0;
+ } else {
+ _hcd_data.channel[i].in.allocated = 1;
+ _hcd_data.channel[i].in.retry = 0;
+ }
+ return i;
+ }
+ }
+
+ // Find free channel
+ for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) {
+ if (_hcd_data.channel[i].out.allocated == 0 && _hcd_data.channel[i].in.allocated == 0) {
+ _hcd_data.channel[i].dev_addr = dev_addr;
+ _hcd_data.channel[i].ep_num = ep_num;
+ _hcd_data.channel[i].ep_type = ep_type;
+ if (dir == TUSB_DIR_OUT) {
+ _hcd_data.channel[i].out.allocated = 1;
+ _hcd_data.channel[i].out.retry = 0;
+ } else {
+ _hcd_data.channel[i].in.allocated = 1;
+ _hcd_data.channel[i].in.retry = 0;
+ }
+ return i;
+ }
+ }
+
+ // Allocation failed
+ return TUSB_INDEX_INVALID_8;
+}
+
+// kick-off transfer with an endpoint
+static bool edpt_xfer_kickoff(uint8_t ep_id) {
+ hcd_endpoint_t* edpt = &_hcd_data.edpt[ep_id];
+ uint8_t ch_id = channel_alloc(edpt->dev_addr, edpt->ep_addr, edpt->ep_type);
+ TU_ASSERT(ch_id != TUSB_INDEX_INVALID_8); // all channel are in used
+
+ tusb_dir_t const dir = tu_edpt_dir(edpt->ep_addr);
+ hcd_channel_t* channel = &_hcd_data.channel[ch_id];
+ if (dir == TUSB_DIR_OUT) {
+ channel->out.edpt = edpt;
+ } else {
+ channel->in.edpt = edpt;
+ }
+
+ return channel_xfer_start(ch_id, dir);
+}
+
+static bool channel_xfer_start(uint8_t ch_id, tusb_dir_t dir) {
+ hcd_channel_t* channel = &_hcd_data.channel[ch_id];
+ hcd_endpoint_t* edpt = (dir == TUSB_DIR_OUT) ? channel->out.edpt : channel->in.edpt;
+
+ uint32_t ch_reg = ch_read(ch_id) & ~USB_EPREG_MASK;
+ ch_reg |= tu_edpt_number(edpt->ep_addr) | edpt->dev_addr << USB_CHEP_DEVADDR_Pos |
+ USB_EP_CTR_TX | USB_EP_CTR_RX;
+
+ // Set type
+ switch (edpt->ep_type) {
+ case TUSB_XFER_BULK:
+ ch_reg |= USB_EP_BULK;
+ break;
+ case TUSB_XFER_INTERRUPT:
+ ch_reg |= USB_EP_INTERRUPT;
+ break;
+
+ case TUSB_XFER_CONTROL:
+ ch_reg |= USB_EP_CONTROL;
+ break;
+
+ default:
+ // Note: ISO endpoint is unsupported
+ TU_ASSERT(false);
+ }
+
+ /* Create a packet memory buffer area. */
+ uint16_t pma_addr = hcd_pma_alloc(ch_id, dir, edpt->max_packet_size);
+ btable_set_addr(ch_id, dir == TUSB_DIR_OUT ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr);
+
+ if (dir == TUSB_DIR_OUT) {
+ uint16_t const len = tu_min16(edpt->buflen - edpt->queued_len, edpt->max_packet_size);
+ tu_hwfifo_write(PMA_BUF_AT(pma_addr), &(edpt->buffer[edpt->queued_len]), len, NULL);
+ btable_set_count(ch_id, BTABLE_BUF_TX, len);
+
+ edpt->queued_len += len;
+ } else {
+ btable_set_rx_bufsize(ch_id, BTABLE_BUF_RX, edpt->max_packet_size);
+ }
+
+ if (edpt->ls_pre == 1) {
+ ch_reg |= USB_CHEP_LSEP;
+ } else {
+ ch_reg &= ~USB_CHEP_LSEP;
+ }
+
+ // Setup DATA/STATUS phase start with DATA1
+ if (tu_edpt_number(edpt->ep_addr) == 0) {
+ edpt->pid = 1;
+ }
+
+ if (edpt->next_setup) {
+ edpt->next_setup = false;
+ ch_reg |= USB_EP_SETUP;
+ edpt->pid = 0;
+ }
+
+ ch_change_status(&ch_reg, dir, EP_STAT_VALID);
+ ch_change_dtog(&ch_reg, dir, edpt->pid);
+ ch_reg &= USB_EPREG_MASK | CH_STAT_MASK(dir) | CH_DTOG_MASK(dir);
+ ch_write(ch_id, ch_reg, true);
+
+ return true;
+}
+
+#endif
diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c
index ba40498e6..44f7137f9 100644
--- a/src/portable/synopsys/dwc2/dcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/dcd_dwc2.c
@@ -98,10 +98,14 @@ TU_ATTR_ALWAYS_INLINE static inline bool edpt_is_enabled(dwc2_dep_t* dep) {
return (dep->ctl & EPCTL_EPENA) != 0;
}
-//--------------------------------------------------------------------
-// DMA
-//--------------------------------------------------------------------
-#if CFG_TUD_MEM_DCACHE_ENABLE
+ #if CFG_TUD_DWC2_SLAVE_ENABLE
+static uint16_t epin_write_tx_fifo(dwc2_regs_t *dwc2, uint8_t epnum);
+ #endif
+
+ //--------------------------------------------------------------------
+ // DMA
+ //--------------------------------------------------------------------
+ #if CFG_TUD_MEM_DCACHE_ENABLE
bool dcd_dcache_clean(const void* addr, uint32_t data_size) {
TU_VERIFY(addr && data_size);
return dwc2_dcache_clean(addr, data_size);
@@ -345,40 +349,6 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
}
}
-static uint16_t epin_write_tx_fifo(uint8_t rhport, uint8_t epnum) {
- dwc2_regs_t* dwc2 = DWC2_REG(rhport);
- dwc2_dep_t* const epin = &dwc2->ep[0][epnum];
- xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN);
-
- dwc2_ep_tsize_t tsiz = {.value = epin->tsiz};
- const uint16_t remain_packets = tsiz.packet_count;
-
- uint16_t total_bytes_written = 0;
- // Process every single packet (only whole packets can be written to fifo)
- for (uint16_t i = 0; i < remain_packets; i++) {
- tsiz.value = epin->tsiz;
- const uint16_t remain_bytes = (uint16_t) tsiz.xfer_size;
- const uint16_t xact_bytes = tu_min16(remain_bytes, xfer->max_size);
-
- // Check if dtxfsts has enough space available
- if (xact_bytes > ((epin->dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2)) {
- break;
- }
-
- // Push packet to Tx-FIFO
- if (xfer->ff) {
- volatile uint32_t* tx_fifo = dwc2->fifo[epnum];
- tu_fifo_read_n_access_mode(xfer->ff, (void *)(uintptr_t)tx_fifo, xact_bytes, TU_FIFO_FIXED_ADDR_RW32);
- total_bytes_written += xact_bytes;
- } else {
- dfifo_write_packet(dwc2, epnum, xfer->buffer, xact_bytes);
- xfer->buffer += xact_bytes;
- total_bytes_written += xact_bytes;
- }
- }
- return total_bytes_written;
-}
-
// Since this function returns void, it is not possible to return a boolean success message
// We must make sure that this function is not called when the EP is disabled
// Must be called from critical section
@@ -423,6 +393,7 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
}
}
+ #if CFG_TUD_DWC2_DMA_ENABLE
const bool is_dma = dma_device_enabled(dwc2);
if(is_dma) {
if (dir == TUSB_DIR_IN && total_bytes != 0) {
@@ -434,11 +405,14 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
if (epnum == 0) {
xfer->buffer += total_bytes;
}
- } else {
+ } else
+ #endif
+ {
+ #if CFG_TUD_DWC2_SLAVE_ENABLE
dep->diepctl = depctl.value; // enable endpoint
if (dir == TUSB_DIR_IN && total_bytes != 0) {
- const uint16_t xferred_bytes = epin_write_tx_fifo(rhport, epnum);
+ const uint16_t xferred_bytes = epin_write_tx_fifo(dwc2, epnum);
// Enable TXFE interrupt if there are still data to be sent
// EP0 only sends one packet at a time, so no need to check for EP0
@@ -446,6 +420,7 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
dwc2->diepempmsk |= (1u << epnum);
}
}
+ #endif
}
}
@@ -689,9 +664,6 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
// into the USB buffer!
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;
- // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1
- TU_ASSERT(ff->item_size == 1);
-
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir);
@@ -854,6 +826,39 @@ TU_ATTR_ALWAYS_INLINE static inline void print_doepint(uint32_t doepint) {
#endif
#if CFG_TUD_DWC2_SLAVE_ENABLE
+static uint16_t epin_write_tx_fifo(dwc2_regs_t *dwc2, uint8_t epnum) {
+ dwc2_dep_t *const epin = &dwc2->ep[0][epnum];
+ xfer_ctl_t *const xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN);
+
+ dwc2_ep_tsize_t tsiz = {.value = epin->tsiz};
+ const uint16_t remain_packets = tsiz.packet_count;
+
+ uint16_t total_bytes_written = 0;
+ // Process every single packet (only whole packets can be written to fifo)
+ for (uint16_t i = 0; i < remain_packets; i++) {
+ tsiz.value = epin->tsiz;
+ const uint16_t remain_bytes = (uint16_t)tsiz.xfer_size;
+ const uint16_t xact_bytes = tu_min16(remain_bytes, xfer->max_size);
+
+ // Check if dtxfsts has enough space available
+ if (xact_bytes > ((epin->dtxfsts & DTXFSTS_INEPTFSAV_Msk) << 2)) {
+ break;
+ }
+
+ // Push packet to Tx-FIFO
+ volatile uint32_t *tx_fifo = dwc2->fifo[epnum];
+ if (xfer->ff) {
+ tu_hwfifo_write_from_fifo(tx_fifo, xfer->ff, xact_bytes, NULL);
+ total_bytes_written += xact_bytes;
+ } else {
+ tu_hwfifo_write(tx_fifo, xfer->buffer, xact_bytes, NULL);
+ xfer->buffer += xact_bytes;
+ total_bytes_written += xact_bytes;
+ }
+ }
+ return total_bytes_written;
+}
+
// Process shared receive FIFO, this interrupt is only used in Slave mode
static void handle_rxflvl_irq(uint8_t rhport) {
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
@@ -893,9 +898,9 @@ static void handle_rxflvl_irq(uint8_t rhport) {
if (byte_count != 0) {
// Read packet off RxFIFO
if (xfer->ff != NULL) {
- tu_fifo_write_n_access_mode(xfer->ff, (const void *)(uintptr_t)rx_fifo, byte_count, TU_FIFO_FIXED_ADDR_RW32);
+ tu_hwfifo_read_to_fifo(rx_fifo, xfer->ff, byte_count, NULL);
} else {
- dfifo_read_packet(dwc2, xfer->buffer, byte_count);
+ tu_hwfifo_read(rx_fifo, xfer->buffer, byte_count, NULL);
xfer->buffer += byte_count;
}
}
@@ -967,7 +972,7 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
// - 64 bytes or
// - Half/Empty of TX FIFO size (configured by GAHBCFG.TXFELVL)
if (diepint_bm.txfifo_empty && tu_bit_test(dwc2->diepempmsk, epnum)) {
- epin_write_tx_fifo(rhport, epnum);
+ epin_write_tx_fifo(dwc2, epnum);
// Turn off TXFE if all bytes are written.
dwc2_ep_tsize_t tsiz = {.value = epin->tsiz};
diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c
index 980574e12..a7e6188df 100644
--- a/src/portable/synopsys/dwc2/dwc2_common.c
+++ b/src/portable/synopsys/dwc2/dwc2_common.c
@@ -264,58 +264,4 @@ bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma) {
//
// }
-//--------------------------------------------------------------------
-// DFIFO
-//--------------------------------------------------------------------
-// Read a single data packet from receive DFIFO
-void dfifo_read_packet(dwc2_regs_t* dwc2, uint8_t* dst, uint16_t len) {
- const volatile uint32_t* rx_fifo = dwc2->fifo[0];
-
- // Reading full available 32 bit words from fifo
- uint16_t word_count = len >> 2;
- while (word_count--) {
- tu_unaligned_write32(dst, *rx_fifo);
- dst += 4;
- }
-
- // Read the remaining 1-3 bytes from fifo
- const uint8_t bytes_rem = len & 0x03;
- if (bytes_rem != 0) {
- const uint32_t tmp = *rx_fifo;
- dst[0] = tu_u32_byte0(tmp);
- if (bytes_rem > 1) {
- dst[1] = tu_u32_byte1(tmp);
- }
- if (bytes_rem > 2) {
- dst[2] = tu_u32_byte2(tmp);
- }
- }
-}
-
-// Write a single data packet to DFIFO
-void dfifo_write_packet(dwc2_regs_t* dwc2, uint8_t fifo_num, const uint8_t* src, uint16_t len) {
- volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num];
-
- // Pushing full available 32 bit words to fifo
- uint16_t word_count = len >> 2;
- while (word_count--) {
- *tx_fifo = tu_unaligned_read32(src);
- src += 4;
- }
-
- // Write the remaining 1-3 bytes into fifo
- const uint8_t bytes_rem = len & 0x03;
- if (bytes_rem) {
- uint32_t tmp_word = src[0];
- if (bytes_rem > 1) {
- tmp_word |= (src[1] << 8);
- }
- if (bytes_rem > 2) {
- tmp_word |= (src[2] << 16);
- }
-
- *tx_fifo = tmp_word;
- }
-}
-
#endif
diff --git a/src/portable/synopsys/dwc2/hcd_dwc2.c b/src/portable/synopsys/dwc2/hcd_dwc2.c
index fc748c85f..c40703b09 100644
--- a/src/portable/synopsys/dwc2/hcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/hcd_dwc2.c
@@ -856,7 +856,7 @@ static void handle_rxflvl_irq(uint8_t rhport) {
hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id];
if (byte_count > 0) {
- dfifo_read_packet(dwc2, edpt->buffer + xfer->xferred_bytes, byte_count);
+ tu_hwfifo_read(dwc2->fifo[0], edpt->buffer + xfer->xferred_bytes, byte_count, NULL);
xfer->xferred_bytes += byte_count;
xfer->fifo_bytes = byte_count;
}
@@ -907,7 +907,7 @@ static bool handle_txfifo_empty(dwc2_regs_t* dwc2, bool is_periodic) {
return true;
}
- dfifo_write_packet(dwc2, ch_id, edpt->buffer + xfer->fifo_bytes, xact_bytes);
+ tu_hwfifo_write(dwc2->fifo[ch_id], edpt->buffer + xfer->fifo_bytes, xact_bytes, NULL);
xfer->fifo_bytes += xact_bytes;
}
}
diff --git a/src/tusb.c b/src/tusb.c
index 8117c3e3e..ed254a10b 100644
--- a/src/tusb.c
+++ b/src/tusb.c
@@ -316,7 +316,7 @@ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool ove
#endif
s->is_host = is_host;
- tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable);
+ tu_fifo_config(&s->ff, ff_buf, ff_bufsize, overwritable);
#if OSAL_MUTEX_REQUIRED
if (ff_buf != NULL && ff_bufsize > 0) {
diff --git a/src/tusb_option.h b/src/tusb_option.h
index 1dc920d84..08a0ba2ef 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -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
@@ -216,6 +217,9 @@
#define OPT_MCU_AT32F425 2505 ///< ArteryTek AT32F425
#define OPT_MCU_AT32F413 2506 ///< ArteryTek AT32F413
+// HPMicro
+#define OPT_MCU_HPM 2600 ///< HPMicro
+
// Check if configured MCU is one of listed
// Apply TU_MCU_IS_EQUAL with || as separator to list of input
#define TU_MCU_IS_EQUAL(_m) (CFG_TUSB_MCU == (_m))
@@ -268,16 +272,7 @@
//--------------------------------------------------------------------+
//------------- DWC2 -------------//
-// Slave mode for device
-#ifndef CFG_TUD_DWC2_SLAVE_ENABLE
- #ifndef CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT
- #define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT 1
- #endif
-
- #define CFG_TUD_DWC2_SLAVE_ENABLE CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT
-#endif
-
-// DMA for device
+// DMA mode for device
#ifndef CFG_TUD_DWC2_DMA_ENABLE
#ifndef CFG_TUD_DWC2_DMA_ENABLE_DEFAULT
#define CFG_TUD_DWC2_DMA_ENABLE_DEFAULT 0
@@ -286,16 +281,16 @@
#define CFG_TUD_DWC2_DMA_ENABLE CFG_TUD_DWC2_DMA_ENABLE_DEFAULT
#endif
-// Slave mode for host
-#ifndef CFG_TUH_DWC2_SLAVE_ENABLE
- #ifndef CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT
- #define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT 1
+// Slave mode for device
+#ifndef CFG_TUD_DWC2_SLAVE_ENABLE
+ #ifndef CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT
+ #define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE // disabled if DMA is enabled
#endif
- #define CFG_TUH_DWC2_SLAVE_ENABLE CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT
+ #define CFG_TUD_DWC2_SLAVE_ENABLE CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT
#endif
-// DMA for host
+// DMA mode for host
#ifndef CFG_TUH_DWC2_DMA_ENABLE
#ifndef CFG_TUH_DWC2_DMA_ENABLE_DEFAULT
#define CFG_TUH_DWC2_DMA_ENABLE_DEFAULT 0
@@ -304,14 +299,21 @@
#define CFG_TUH_DWC2_DMA_ENABLE CFG_TUH_DWC2_DMA_ENABLE_DEFAULT
#endif
-#if defined(TUP_USBIP_DWC2)
- #if CFG_TUD_DWC2_SLAVE_ENABLE && !CFG_TUD_DWC2_DMA_ENABLE
- #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
+// Slave mode for host
+#ifndef CFG_TUH_DWC2_SLAVE_ENABLE
+ #ifndef CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT
+ #define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE // disabled if DMA is enabled
#endif
- #if CFG_TUH_DWC2_SLAVE_ENABLE && !CFG_TUH_DWC2_DMA_ENABLE
- #define CFG_TUH_EDPT_DEDICATED_HWFIFO 1
- #endif
+ #define CFG_TUH_DWC2_SLAVE_ENABLE CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT
+#endif
+
+#if defined(TUP_USBIP_DWC2)
+ #define CFG_TUD_EDPT_DEDICATED_HWFIFO CFG_TUD_DWC2_SLAVE_ENABLE
+ #define CFG_TUH_EDPT_DEDICATED_HWFIFO CFG_TUH_DWC2_SLAVE_ENABLE
+
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32bit access
+ #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 // fixed hwfifo address
#endif
//------------- ChipIdea -------------//
@@ -352,16 +354,36 @@
//------------ FSDEV --------------//
#if defined(TUP_USBIP_FSDEV)
#define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
+
+ #if CFG_TUSB_FSDEV_PMA_SIZE == 512
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data
+ #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase
+ #elif CFG_TUSB_FSDEV_PMA_SIZE == 1024
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 2 // 16-bit data
+ #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 2 // 16-bit address increase
+ #elif CFG_TUSB_FSDEV_PMA_SIZE == 2048
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32-bit data
+ #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 4 // 32-bit address increase
+ #endif
#endif
//------------ MUSB --------------//
#if defined(TUP_USBIP_MUSB)
- #define CFG_TUD_EDPT_DEDICATED_HWFIFO 0 // need testing to enable
+ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE 4 // 32 bit data
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_16BIT_ACCESS // allow odd 16bit access
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS // allow odd 8bit access
+ #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0 // fixed hwfifo
+
#endif
//------------ RUSB2 --------------//
#if defined(TUP_USBIP_RUSB2)
- #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
+ #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
+ #define CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE (2 | (TUD_OPT_HIGH_SPEED ? 4 : 0)) // 16 bit and 32 bit data if highspeed
+ #define CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE 0
+ #define CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE // custom write since rusb2 can change access width 32 -> 16 and can write
+ // odd byte with byte access
#endif
//--------------------------------------------------------------------
diff --git a/test/fuzz/device/cdc/CMakeLists.txt b/test/fuzz/device/cdc/CMakeLists.txt
index c60f292b9..85094cfb1 100644
--- a/test/fuzz/device/cdc/CMakeLists.txt
+++ b/test/fuzz/device/cdc/CMakeLists.txt
@@ -2,28 +2,25 @@ cmake_minimum_required(VERSION 3.5)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT})
+project(cdc)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/test/fuzz/device/msc/CMakeLists.txt b/test/fuzz/device/msc/CMakeLists.txt
index 8bff217cb..6eb6c8c46 100644
--- a/test/fuzz/device/msc/CMakeLists.txt
+++ b/test/fuzz/device/msc/CMakeLists.txt
@@ -2,28 +2,25 @@ cmake_minimum_required(VERSION 3.5)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT})
+project(msc)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/test/fuzz/device/net/CMakeLists.txt b/test/fuzz/device/net/CMakeLists.txt
index 8bff217cb..84e92ad2f 100644
--- a/test/fuzz/device/net/CMakeLists.txt
+++ b/test/fuzz/device/net/CMakeLists.txt
@@ -2,28 +2,25 @@ cmake_minimum_required(VERSION 3.5)
include(${CMAKE_CURRENT_SOURCE_DIR}/../../../hw/bsp/family_support.cmake)
-# gets PROJECT name for the example (e.g. <BOARD>-<DIR_NAME>)
-family_get_project_name(PROJECT ${CMAKE_CURRENT_LIST_DIR})
-
-project(${PROJECT})
+project(net)
# Checks this example is valid for the family and initializes the project
-family_initialize_project(${PROJECT} ${CMAKE_CURRENT_LIST_DIR})
+family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR})
-add_executable(${PROJECT})
+add_executable(${PROJECT_NAME})
# Example source
-target_sources(${PROJECT} PUBLIC
+target_sources(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src/main.c
${CMAKE_CURRENT_SOURCE_DIR}/src/msc_disk.c
${CMAKE_CURRENT_SOURCE_DIR}/src/usb_descriptors.c
)
# Example include
-target_include_directories(${PROJECT} PUBLIC
+target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Configure compilation flags and libraries for the example without RTOS.
# See the corresponding function in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT} noos)
+family_configure_device_example(${PROJECT_NAME} noos)
diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json
index 6afcb2186..047d0879c 100644
--- a/test/hil/tinyusb.json
+++ b/test/hil/tinyusb.json
@@ -103,8 +103,9 @@
"name": "ra4m1_ek",
"uid": "152E163038303131393346E46F26574B",
"tests": {
- "device": true, "host": false, "dual": false,
- "skip": ["device/cdc_msc", "device/cdc_msc_freertos"]
+ "device": true,
+ "host": false,
+ "dual": false
},
"comment": "MSC is slow to enumerated #2602",
"flasher": {
diff --git a/test/unit-test/CMakeLists.txt b/test/unit-test/CMakeLists.txt
index 7172f5575..b44a91d57 100644
--- a/test/unit-test/CMakeLists.txt
+++ b/test/unit-test/CMakeLists.txt
@@ -113,7 +113,6 @@ add_ceedling_test(
${CEEDLING_WORKDIR}/../../src/common/tusb_fifo.c
""
)
-target_compile_definitions(test_fifo PRIVATE CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32=1)
add_ceedling_test(
test_usbd
diff --git a/test/unit-test/project.yml b/test/unit-test/project.yml
index d971d098d..be3fc3de0 100644
--- a/test/unit-test/project.yml
+++ b/test/unit-test/project.yml
@@ -128,7 +128,9 @@
:defines:
:test:
- _UNITY_TEST_
- - CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32
+ - CFG_TUD_EDPT_DEDICATED_HWFIFO=1
+ - CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE=6
+ - CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE=0
:release: []
# Enable to inject name of a test as a unique compilation symbol into its respective executable build.
diff --git a/test/unit-test/test/test_fifo.c b/test/unit-test/test/test_fifo.c
index 35bbeaa62..b9279cb25 100644
--- a/test/unit-test/test/test_fifo.c
+++ b/test/unit-test/test/test_fifo.c
@@ -32,7 +32,7 @@
#define FIFO_SIZE 64
uint8_t tu_ff_buf[FIFO_SIZE * sizeof(uint8_t)];
-tu_fifo_t tu_ff = TU_FIFO_INIT(tu_ff_buf, FIFO_SIZE, uint8_t, false);
+tu_fifo_t tu_ff = TU_FIFO_INIT(tu_ff_buf, FIFO_SIZE, false);
tu_fifo_t *ff = &tu_ff;
tu_fifo_buffer_info_t info;
@@ -40,6 +40,16 @@ tu_fifo_buffer_info_t info;
uint8_t test_data[4096];
uint8_t rd_buf[FIFO_SIZE];
+static const tu_hwfifo_access_t hwfifo_access_32 = {
+ .data_stride = 4,
+ .param = 0,
+};
+
+static const tu_hwfifo_access_t hwfifo_access_16 = {
+ .data_stride = 2,
+ .param = 0,
+};
+
void setUp(void) {
tu_fifo_clear(ff);
memset(&info, 0, sizeof(tu_fifo_buffer_info_t));
@@ -68,34 +78,6 @@ void test_normal(void) {
}
}
-void test_item_size(void) {
- uint8_t ff4_buf[FIFO_SIZE * sizeof(uint32_t)];
- tu_fifo_t ff4 = TU_FIFO_INIT(ff4_buf, FIFO_SIZE, uint32_t, false);
-
- uint32_t data4[2 * FIFO_SIZE];
- for (uint32_t i = 0; i < sizeof(data4) / 4; i++) {
- data4[i] = i;
- }
-
- // fill up fifo
- tu_fifo_write_n(&ff4, data4, FIFO_SIZE);
-
- uint32_t rd_buf4[FIFO_SIZE];
- uint16_t rd_count;
-
- // read 0 -> 4
- rd_count = tu_fifo_read_n(&ff4, rd_buf4, 5);
- TEST_ASSERT_EQUAL(5, rd_count);
- TEST_ASSERT_EQUAL_UINT32_ARRAY(data4, rd_buf4, rd_count); // 0 -> 4
-
- tu_fifo_write_n(&ff4, data4 + FIFO_SIZE, 5);
-
- // read all 5 -> 68
- rd_count = tu_fifo_read_n(&ff4, rd_buf4, FIFO_SIZE);
- TEST_ASSERT_EQUAL(FIFO_SIZE, rd_count);
- TEST_ASSERT_EQUAL_UINT32_ARRAY(data4 + 5, rd_buf4, rd_count); // 5 -> 68
-}
-
void test_read_n(void) {
uint16_t rd_count;
@@ -362,7 +344,7 @@ void test_rd_idx_wrap(void) {
uint8_t buf[10];
uint8_t dst[10];
- tu_fifo_config(&ff10, buf, 10, 1, 1);
+ tu_fifo_config(&ff10, buf, 10, 1);
uint16_t n;
@@ -431,7 +413,7 @@ void test_write_n_fixed_addr_rw32_nowrap(void) {
for (uint8_t n = 1; n <= 8; n++) {
tu_fifo_clear(ff);
- uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)&reg, n, TU_FIFO_FIXED_ADDR_RW32);
+ uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)&reg, n, &hwfifo_access_32);
TEST_ASSERT_EQUAL(n, written);
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
@@ -453,7 +435,7 @@ void test_write_n_fixed_addr_rw32_wrapped(void) {
ff->wr_idx = FIFO_SIZE - 3;
ff->rd_idx = FIFO_SIZE - 3;
- uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)&reg, n, TU_FIFO_FIXED_ADDR_RW32);
+ uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)&reg, n, &hwfifo_access_32);
TEST_ASSERT_EQUAL(n, written);
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
@@ -473,7 +455,7 @@ void test_read_n_fixed_addr_rw32_nowrap(void) {
tu_fifo_write_n(ff, pattern, 8);
uint32_t reg = 0;
- uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, &reg, n, TU_FIFO_FIXED_ADDR_RW32);
+ uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, &reg, n, &hwfifo_access_32);
TEST_ASSERT_EQUAL(n, read_cnt);
TEST_ASSERT_EQUAL(8 - n, tu_fifo_count(ff));
@@ -497,7 +479,7 @@ void test_read_n_fixed_addr_rw32_wrapped(void) {
}
uint32_t reg = 0;
- uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, &reg, n, TU_FIFO_FIXED_ADDR_RW32);
+ uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, &reg, n, &hwfifo_access_32);
TEST_ASSERT_EQUAL(n, read_cnt);
TEST_ASSERT_EQUAL(0, tu_fifo_count(ff));
@@ -505,6 +487,86 @@ void test_read_n_fixed_addr_rw32_wrapped(void) {
}
}
+void test_write_n_fixed_addr_rw16_nowrap(void) {
+ tu_fifo_clear(ff);
+
+ volatile uint16_t reg = 0x1122;
+ uint8_t expected[6] = {0x22, 0x11, 0x22, 0x11, 0x22, 0x11};
+
+ for (uint8_t n = 1; n <= 6; n++) {
+ tu_fifo_clear(ff);
+ uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)&reg, n, &hwfifo_access_16);
+ TEST_ASSERT_EQUAL(n, written);
+ TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
+
+ uint8_t out[6] = {0};
+ tu_fifo_read_n(ff, out, n);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, out, n);
+ }
+}
+
+void test_write_n_fixed_addr_rw16_wrapped(void) {
+ tu_fifo_clear(ff);
+
+ volatile uint16_t reg = 0xA1B2;
+ uint8_t expected[6] = {0xB2, 0xA1, 0xB2, 0xA1, 0xB2, 0xA1};
+
+ for (uint8_t n = 1; n <= 6; n++) {
+ tu_fifo_clear(ff);
+ // Position the fifo near the end so writes wrap
+ ff->wr_idx = FIFO_SIZE - 3;
+ ff->rd_idx = FIFO_SIZE - 3;
+
+ uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)&reg, n, &hwfifo_access_16);
+ TEST_ASSERT_EQUAL(n, written);
+ TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
+
+ uint8_t out[6] = {0};
+ tu_fifo_read_n(ff, out, n);
+ TEST_ASSERT_EQUAL_UINT8_ARRAY(expected, out, n);
+ }
+}
+
+void test_read_n_fixed_addr_rw16_nowrap(void) {
+ uint8_t pattern[6] = {0x10, 0x21, 0x32, 0x43, 0x54, 0x65};
+ uint16_t reg_expected[6] = {0x0010, 0x2110, 0x0032, 0x4332, 0x0054, 0x6554};
+
+ for (uint8_t n = 1; n <= 6; n++) {
+ tu_fifo_clear(ff);
+ tu_fifo_write_n(ff, pattern, 6);
+
+ uint16_t reg = 0;
+ uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, &reg, n, &hwfifo_access_16);
+ TEST_ASSERT_EQUAL(n, read_cnt);
+ TEST_ASSERT_EQUAL(6 - n, tu_fifo_count(ff));
+
+ TEST_ASSERT_EQUAL_HEX16(reg_expected[n - 1], reg);
+ }
+}
+
+void test_read_n_fixed_addr_rw16_wrapped(void) {
+ uint8_t pattern[6] = {0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5};
+ uint16_t reg_expected[6] = {0x00F0, 0xE1F0, 0x00D2, 0xC3D2, 0x00B4, 0xA5B4};
+
+ for (uint8_t n = 1; n <= 6; n++) {
+ tu_fifo_clear(ff);
+ ff->rd_idx = FIFO_SIZE - 1;
+ ff->wr_idx = (uint16_t)(ff->rd_idx + n);
+
+ for (uint8_t i = 0; i < n; i++) {
+ uint8_t idx = (uint8_t)((ff->rd_idx + i) % FIFO_SIZE);
+ ff->buffer[idx] = pattern[i];
+ }
+
+ uint16_t reg = 0;
+ uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, &reg, n, &hwfifo_access_16);
+ TEST_ASSERT_EQUAL(n, read_cnt);
+ TEST_ASSERT_EQUAL(0, tu_fifo_count(ff));
+
+ TEST_ASSERT_EQUAL_HEX16(reg_expected[n - 1], reg);
+ }
+}
+
void test_get_read_info_advanced_cases(void) {
tu_fifo_clear(ff);
diff --git a/tools/get_deps.py b/tools/get_deps.py
index 0d9c1a8f1..deacbb23b 100755
--- a/tools/get_deps.py
+++ b/tools/get_deps.py
@@ -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'],
@@ -144,7 +144,7 @@ deps_optional = {
'stm32h7'],
'hw/mcu/st/stm32-tcpp0203': ['https://github.com/STMicroelectronics/stm32-tcpp0203.git',
'9918655bff176ac3046ccf378b5c7bbbc6a38d15',
- 'stm32h7rs stm32n6'],
+ 'stm32h5 stm32h7rs stm32n6'],
'hw/mcu/st/stm32c0xx_hal_driver': ['https://github.com/STMicroelectronics/stm32c0xx_hal_driver.git',
'c283b143bef6bdaacf64240ee6f15eb61dad6125',
'stm32c0'],
@@ -244,9 +244,12 @@ deps_optional = {
'hw/mcu/artery/at32f413': ['https://github.com/ArteryTek/AT32F413_Firmware_Library.git',
'f6fe62dfec9fd40c5b63d92fc5ef2c2b5e77a450',
'at32f413'],
+ 'hw/mcu/hpmicro/hpm_sdk': ['https://github.com/hpmicro/hpm_sdk',
+ '8d2af741ecc4aaa82d7ee395dc1ce25d7070c3ff',
+ '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 '
diff --git a/tools/iar_template.ipcf b/tools/iar_template.ipcf
index 2581a4702..caddda826 100644
--- a/tools/iar_template.ipcf
+++ b/tools/iar_template.ipcf
@@ -217,7 +217,9 @@
</group>
<group name="src/portable/st/stm32_fsdev">
<path>$TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c</path>
- <path>$TUSB_DIR$/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h</path>
+ <path>$TUSB_DIR$/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c</path>
+ <path>$TUSB_DIR$/src/portable/st/stm32_fsdev/fsdev_common.c</path>
+ <path>$TUSB_DIR$/src/portable/st/stm32_fsdev/fsdev_common.h</path>
</group>
<group name="src/portable/st/typec">
<path>$TUSB_DIR$/src/portable/st/typec/typec_stm32.c</path>