summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2025-12-16 20:47:15 +0100
committerHiFiPhile <[email protected]>2025-12-16 20:47:37 +0100
commitabf27bfa37f9e8bee49011eb91f7088287afa529 (patch)
treec8dd14cb0e839007cc612b105824f8b0eea48858
parentcb1873881e3cc51f522978e165748ad7ef7a7b0a (diff)
parent8a246db49f5ad52bd1c430e2796c0d363c4cdede (diff)
Merge remote-tracking branch 'tinyusb/master' into support-nxp-rw612
Signed-off-by: HiFiPhile <[email protected]>
-rwxr-xr-x.github/workflows/ci_set_matrix.py2
-rw-r--r--README.rst2
-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_freertos/skip.txt1
-rw-r--r--examples/device/audio_test_freertos/skip.txt1
-rw-r--r--examples/device/cdc_msc_freertos/skip.txt1
-rw-r--r--examples/device/hid_composite_freertos/skip.txt1
-rw-r--r--examples/device/midi_test_freertos/skip.txt1
-rw-r--r--examples/host/bare_api/only.txt1
-rw-r--r--examples/host/cdc_msc_hid/only.txt1
-rw-r--r--examples/host/device_info/only.txt1
-rw-r--r--examples/host/hid_controller/only.txt1
-rw-r--r--examples/host/midi_rx/only.txt1
-rw-r--r--examples/host/msc_file_explorer/only.txt1
-rw-r--r--hw/bsp/BoardPresets.json22
-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--src/common/tusb_mcu.h12
-rw-r--r--src/portable/chipidea/ci_hs/ci_hs_hpm.h54
-rw-r--r--src/portable/chipidea/ci_hs/dcd_ci_hs.c402
-rw-r--r--src/portable/chipidea/ci_hs/hcd_ci_hs.c41
-rw-r--r--src/portable/ehci/ehci.c12
-rw-r--r--src/tusb_option.h3
-rwxr-xr-xtools/get_deps.py3
34 files changed, 2064 insertions, 234 deletions
diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py
index dfe7e7780..b682da1a2 100755
--- a/.github/workflows/ci_set_matrix.py
+++ b/.github/workflows/ci_set_matrix.py
@@ -17,7 +17,7 @@ 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"],
diff --git a/README.rst b/README.rst
index 64cfbe312..58a9e393e 100644
--- a/README.rst
+++ b/README.rst
@@ -159,6 +159,8 @@ Supported CPUs
+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | |
+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
+| HPMicro | HPM6750 | ✔ | ✔ | ✔ | ci_hs, ehci | |
++--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+
| Infineon | XMC4500 | ✔ | ✔ | ✖ | dwc2 | |
+--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+
| MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | |
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_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_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/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/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/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/host/bare_api/only.txt b/examples/host/bare_api/only.txt
index 919e3d8d3..f07d63f9d 100644
--- a/examples/host/bare_api/only.txt
+++ b/examples/host/bare_api/only.txt
@@ -1,3 +1,4 @@
+family:hpmicro
family:samd21
family:samd5x_e5x
mcu:CH32V20X
diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt
index 919e3d8d3..f07d63f9d 100644
--- a/examples/host/cdc_msc_hid/only.txt
+++ b/examples/host/cdc_msc_hid/only.txt
@@ -1,3 +1,4 @@
+family:hpmicro
family:samd21
family:samd5x_e5x
mcu:CH32V20X
diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt
index 99574f7fc..714c1078a 100644
--- a/examples/host/device_info/only.txt
+++ b/examples/host/device_info/only.txt
@@ -1,4 +1,5 @@
family:espressif
+family:hpmicro
family:samd21
family:samd5x_e5x
mcu:CH32V20X
diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt
index 027e17eca..8ec2f5cfe 100644
--- a/examples/host/hid_controller/only.txt
+++ b/examples/host/hid_controller/only.txt
@@ -1,3 +1,4 @@
+family:hpmicro
family:samd21
family:samd5x_e5x
mcu:CH32V20X
diff --git a/examples/host/midi_rx/only.txt b/examples/host/midi_rx/only.txt
index ad419cc7e..9d647a340 100644
--- a/examples/host/midi_rx/only.txt
+++ b/examples/host/midi_rx/only.txt
@@ -1,3 +1,4 @@
+family:hpmicro
family:samd21
family:samd5x_e5x
mcu:CH32V20X
diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt
index 919e3d8d3..f07d63f9d 100644
--- a/examples/host/msc_file_explorer/only.txt
+++ b/examples/host/msc_file_explorer/only.txt
@@ -1,3 +1,4 @@
+family:hpmicro
family:samd21
family:samd5x_e5x
mcu:CH32V20X
diff --git a/hw/bsp/BoardPresets.json b/hw/bsp/BoardPresets.json
index 5fbc378d2..440ef8733 100644
--- a/hw/bsp/BoardPresets.json
+++ b/hw/bsp/BoardPresets.json
@@ -239,6 +239,10 @@
"inherits": "default"
},
{
+ "name": "hpm6750evk2",
+ "inherits": "default"
+ },
+ {
"name": "itsybitsy_m0",
"inherits": "default"
},
@@ -1230,6 +1234,11 @@
"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"
@@ -2859,6 +2868,19 @@
]
},
{
+ "name": "hpm6750evk2",
+ "steps": [
+ {
+ "type": "configure",
+ "name": "hpm6750evk2"
+ },
+ {
+ "type": "build",
+ "name": "hpm6750evk2"
+ }
+ ]
+ },
+ {
"name": "itsybitsy_m0",
"steps": [
{
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/src/common/tusb_mcu.h b/src/common/tusb_mcu.h
index 89316ee77..55f7e0b7c 100644
--- a/src/common/tusb_mcu.h
+++ b/src/common/tusb_mcu.h
@@ -661,6 +661,18 @@
#define TUP_USBIP_DWC2_AT32
#define TUP_DCD_ENDPOINT_MAX 8
+//--------------------------------------------------------------------+
+// 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
//--------------------------------------------------------------------+
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/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c
index 27298989c..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,9 @@ 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"
@@ -79,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 {
@@ -93,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
//--------------------------------------------------------------------+
@@ -120,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;
@@ -149,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
@@ -167,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
@@ -185,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;
}
@@ -217,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
@@ -225,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;
}
}
@@ -377,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));
}
@@ -474,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;
@@ -484,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);
@@ -526,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
}
@@ -589,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);
}
}
@@ -627,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);
+ }
}
}
@@ -712,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 fe2895f6a..29ce0cd7f 100644
--- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c
+++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c
@@ -41,31 +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"
+
+ #include "ci_hs_rw61x.h"
#else
-#error "Unsupported MCUs"
+ #error "Unsupported MCUs"
#endif
//--------------------------------------------------------------------+
@@ -76,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 e604a0360..9b2cf98be 100644
--- a/src/portable/ehci/ehci.c
+++ b/src/portable/ehci/ehci.c
@@ -44,6 +44,10 @@
#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/tusb_option.h b/src/tusb_option.h
index caf8c4156..64fe899db 100644
--- a/src/tusb_option.h
+++ b/src/tusb_option.h
@@ -217,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))
diff --git a/tools/get_deps.py b/tools/get_deps.py
index af5ad700e..deacbb23b 100755
--- a/tools/get_deps.py
+++ b/tools/get_deps.py
@@ -244,6 +244,9 @@ 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 rw61x mm32 msp432e4 nrf saml2x '