summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsakumisu <[email protected]>2022-02-06 16:41:03 +0800
committersakumisu <[email protected]>2022-02-06 17:05:47 +0800
commit595548f54800e58d68e310d72b40bd660e50a473 (patch)
tree4d97049602b73a189209ff2b39b54b6847051a3c
parent652ad58dcc2a84190ebbbb0b8374457bef710510 (diff)
update ch32 port and demo
-rw-r--r--demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.cproject60
-rw-r--r--demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.settings/org.eclipse.core.resources.prefs2
-rw-r--r--demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/User/main.c20
-rw-r--r--port/ch32/usb_ch32_reg.h520
-rw-r--r--port/ch32/usb_ch32_usbfs_reg.h339
-rw-r--r--port/ch32/usb_ch32_usbhs_reg.h559
-rw-r--r--port/ch32/usb_dc.c632
-rw-r--r--port/ch32/usb_dc_usbfs.c632
-rw-r--r--port/ch32/usb_dc_usbhs.c432
9 files changed, 2030 insertions, 1166 deletions
diff --git a/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.cproject b/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.cproject
index 367d9fd0..b8bee5ab 100644
--- a/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.cproject
+++ b/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.cproject
@@ -113,8 +113,66 @@
</tool>
</toolChain>
</folderInfo>
+ <folderInfo id="ilg.gnumcueclipse.managedbuild.cross.riscv.config.elf.release.1008047074.1608037824" name="/" resourcePath="usb_stack">
+ <toolChain id="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release.1355118778" name="RISC-V Cross GCC" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.toolchain.elf.release" unusedChildren="">
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1311852988.1827731043" name="Create flash image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createflash.1311852988"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1983282875.261574045" name="Create extended listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.createlisting.1983282875"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1000761142.1449191625" name="Print size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.addtools.printsize.1000761142"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.514997414.62589629" name="Optimization Level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.level.514997414"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1008570639.1138171069" name="Message length (-fmessage-length=0)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.messagelength.1008570639"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.467272439.841996487" name="'char' is signed (-fsigned-char)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.signedchar.467272439"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.2047756949.2094870101" name="Function sections (-ffunction-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.functionsections.2047756949"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.207613650.2078028990" name="Data sections (-fdata-sections)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.optimization.datasections.207613650"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1204865254.1461634648" name="Debug level" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.level.1204865254"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.867779652.7851577" name="Debug format" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.debugging.format.867779652"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1900297968.651162519" name="Architecture" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.base.1900297968"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.387605487.469837311" name="Integer ABI" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.abi.integer.387605487"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1509705449.1343515539" name="Multiply extension (RVM)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.multiply.1509705449"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1038505275.423168161" name="Compressed extension (RVC)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.compressed.1038505275"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1218760634.191441910" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.name.1218760634"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.103341323.1176515369" name="Prefix" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.prefix.103341323"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.487601824.1139013934" name="C compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.c.487601824"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1062130429.375904980" name="C++ compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.cpp.1062130429"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1194282993.1694850409" name="Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.ar.1194282993"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1529355265.1646329212" name="Hex/Bin converter" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objcopy.1529355265"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1053750745.583504760" name="Listing generator" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.objdump.1053750745"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1441326233.1174468917" name="Size command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.size.1441326233"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.550105535.635115370" name="Build command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.make.550105535"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.719280496.245734444" name="Remove command" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.command.rm.719280496"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.226017994.1770786464" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.toolchain.id.226017994"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1590833110.1653510027" name="Atomic extension (RVA)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.target.isa.atomic.1590833110"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused.1961191588.76488276" name="Warn on various unused elements (-Wunused)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.unused.1961191588"/>
+ <option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized.929829166.535284113" name="Warn on uninitialized variables (-Wuninitialised)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.warnings.uninitialized.929829166"/>
+ <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform" isAbstract="false" osList="all" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.targetPlatform"/>
+ <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1124871619" name="GNU RISC-V Cross Assembler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.1244756189">
+ <inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input.624939772" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.assembler.input"/>
+ </tool>
+ <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.572721643" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187">
+ <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.1587883816" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Debug}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/usb_stack/osal}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Core}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/User}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/Peripheral/inc}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/usb_stack/core}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/usb_stack/common}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/usb_stack/class/cdc}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/usb_stack/class/hid}&quot;"/>
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/usb_stack/class/msc}&quot;"/>
+ </option>
+ <inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input.1682157822" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.input"/>
+ </tool>
+ <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.677227819" name="GNU RISC-V Cross C++ Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.compiler.1610882921"/>
+ <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.327936707" name="GNU RISC-V Cross C Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.1620074387"/>
+ <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.552738443" name="GNU RISC-V Cross C++ Linker" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.cpp.linker.1947503520"/>
+ <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.262736942" name="GNU RISC-V Cross Archiver" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.archiver.1292785366"/>
+ <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1094988561" name="GNU RISC-V Cross Create Flash Image" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createflash.1801165667"/>
+ <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1469275119" name="GNU RISC-V Cross Create Listing" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.createlisting.1356766765"/>
+ <tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.1975079441" name="GNU RISC-V Cross Print Size" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.printsize.712424314"/>
+ </toolChain>
+ </folderInfo>
<sourceEntries>
- <entry excluding="usb_stack/LICENSE|usb_stack/README_zh.md|usb_stack/README.md|usb_stack/SConscript|usb_stack/class/hub|usb_stack/demo|usb_stack/docs|usb_stack/packet capture|usb_stack/port/fsdev|usb_stack/port/mm32|usb_stack/port/stm32|usb_stack/port/synopsys|usb_stack/port/template|usb_stack/port/bouffalolab|Startup|Peripheral|Ld|Debug|Core" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+ <entry excluding="usb_stack/port/ch32/usb_dc_usbhs.c|usb_stack/class/hid/usbh_hid.h|usb_stack/class/hid/usbh_hid.c|usb_stack/class/msc/usbh_msc.h|usb_stack/class/msc/usbh_msc.c|usb_stack/class/cdc/usbd_cdc_rndis.c|usb_stack/class/cdc/usbh_cdc_acm.h|usb_stack/class/cdc/usbh_cdc_acm.c|usb_stack/port/nrf5x|usb_stack/port/musb|usb_stack/port/samd|usb_stack/port/ehci|usb_stack/core/usbh_core.h|usb_stack/osal|usb_stack/core/usbh_core.c|usb_stack/LICENSE|usb_stack/README_zh.md|usb_stack/README.md|usb_stack/SConscript|usb_stack/class/hub|usb_stack/demo|usb_stack/docs|usb_stack/packet capture|usb_stack/port/fsdev|usb_stack/port/mm32|usb_stack/port/stm32|usb_stack/port/synopsys|usb_stack/port/template|usb_stack/port/bouffalolab|Startup|Peripheral|Ld|Debug|Core" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Debug"/>
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Ld"/>
diff --git a/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.settings/org.eclipse.core.resources.prefs b/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.settings/org.eclipse.core.resources.prefs
index 44376de8..cd7dddfa 100644
--- a/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.settings/org.eclipse.core.resources.prefs
+++ b/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/.settings/org.eclipse.core.resources.prefs
@@ -1,2 +1,2 @@
eclipse.preferences.version=1
-encoding//usb_stack/port/ch32/usb_dc.c=UTF-8
+encoding//usb_stack/port/ch32/usb_ch32_usbhs_reg.h=UTF-8
diff --git a/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/User/main.c b/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/User/main.c
index 02152457..12fc0c13 100644
--- a/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/User/main.c
+++ b/demo/ch32/ch32v307/USB/USBFS/DEVICE/cdc_acm/User/main.c
@@ -155,23 +155,19 @@ void usb_dc_low_level_init(void)
RCC_USBHSConfig(RCC_USBPLL_Div2);
RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M);
RCC_USBHSPHYPLLALIVEcmd(ENABLE);
+#ifdef CONFIG_USB_HS
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE);
+#else
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE);
+#endif
Delay_Us(100);
-
- EXTEN->EXTEN_CTR |= EXTEN_USBD_PU_EN;
-
- GPIO_InitTypeDef GPIO_InitTypdefStruct = { 0 };
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
- GPIO_InitTypdefStruct.GPIO_Pin = GPIO_Pin_15;
- GPIO_InitTypdefStruct.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitTypdefStruct.GPIO_Speed = GPIO_Speed_50MHz;
-
- GPIO_Init(GPIOB, &GPIO_InitTypdefStruct);
-
+#ifndef CONFIG_USB_HS
+ //EXTEN->EXTEN_CTR |= EXTEN_USBD_PU_EN;
NVIC_EnableIRQ(OTG_FS_IRQn);
+#else
+ NVIC_EnableIRQ( USBHS_IRQn );
+#endif
}
volatile uint8_t dtr_enable = 0;
diff --git a/port/ch32/usb_ch32_reg.h b/port/ch32/usb_ch32_reg.h
deleted file mode 100644
index c48cf2cd..00000000
--- a/port/ch32/usb_ch32_reg.h
+++ /dev/null
@@ -1,520 +0,0 @@
-#ifndef _USB_CH32_REG_H
-#define _USB_CH32_REG_H
-
-#define __IO volatile /* defines 'read / write' permissions */
-
-/* USBHS Registers */
-typedef struct
-{
- __IO uint8_t CONTROL;
- __IO uint8_t HOST_CTRL;
- __IO uint8_t INT_EN;
- __IO uint8_t DEV_AD;
- __IO uint16_t FRAME_NO;
- __IO uint8_t SUSPEND;
- __IO uint8_t RESERVED0;
- __IO uint8_t SPEED_TYPE;
- __IO uint8_t MIS_ST;
- __IO uint8_t INT_FG;
- __IO uint8_t INT_ST;
- __IO uint16_t RX_LEN;
- __IO uint16_t RESERVED1;
- __IO uint32_t ENDP_CONFIG;
- __IO uint32_t ENDP_TYPE;
- __IO uint32_t BUF_MODE;
- __IO uint32_t UEP0_DMA;
- __IO uint32_t UEP1_RX_DMA;
- __IO uint32_t UEP2_RX_DMA;
- __IO uint32_t UEP3_RX_DMA;
- __IO uint32_t UEP4_RX_DMA;
- __IO uint32_t UEP5_RX_DMA;
- __IO uint32_t UEP6_RX_DMA;
- __IO uint32_t UEP7_RX_DMA;
- __IO uint32_t UEP8_RX_DMA;
- __IO uint32_t UEP9_RX_DMA;
- __IO uint32_t UEP10_RX_DMA;
- __IO uint32_t UEP11_RX_DMA;
- __IO uint32_t UEP12_RX_DMA;
- __IO uint32_t UEP13_RX_DMA;
- __IO uint32_t UEP14_RX_DMA;
- __IO uint32_t UEP15_RX_DMA;
- __IO uint32_t UEP1_TX_DMA;
- __IO uint32_t UEP2_TX_DMA;
- __IO uint32_t UEP3_TX_DMA;
- __IO uint32_t UEP4_TX_DMA;
- __IO uint32_t UEP5_TX_DMA;
- __IO uint32_t UEP6_TX_DMA;
- __IO uint32_t UEP7_TX_DMA;
- __IO uint32_t UEP8_TX_DMA;
- __IO uint32_t UEP9_TX_DMA;
- __IO uint32_t UEP10_TX_DMA;
- __IO uint32_t UEP11_TX_DMA;
- __IO uint32_t UEP12_TX_DMA;
- __IO uint32_t UEP13_TX_DMA;
- __IO uint32_t UEP14_TX_DMA;
- __IO uint32_t UEP15_TX_DMA;
- __IO uint16_t UEP0_MAX_LEN;
- __IO uint16_t RESERVED2;
- __IO uint16_t UEP1_MAX_LEN;
- __IO uint16_t RESERVED3;
- __IO uint16_t UEP2_MAX_LEN;
- __IO uint16_t RESERVED4;
- __IO uint16_t UEP3_MAX_LEN;
- __IO uint16_t RESERVED5;
- __IO uint16_t UEP4_MAX_LEN;
- __IO uint16_t RESERVED6;
- __IO uint16_t UEP5_MAX_LEN;
- __IO uint16_t RESERVED7;
- __IO uint16_t UEP6_MAX_LEN;
- __IO uint16_t RESERVED8;
- __IO uint16_t UEP7_MAX_LEN;
- __IO uint16_t RESERVED9;
- __IO uint16_t UEP8_MAX_LEN;
- __IO uint16_t RESERVED10;
- __IO uint16_t UEP9_MAX_LEN;
- __IO uint16_t RESERVED11;
- __IO uint16_t UEP10_MAX_LEN;
- __IO uint16_t RESERVED12;
- __IO uint16_t UEP11_MAX_LEN;
- __IO uint16_t RESERVED13;
- __IO uint16_t UEP12_MAX_LEN;
- __IO uint16_t RESERVED14;
- __IO uint16_t UEP13_MAX_LEN;
- __IO uint16_t RESERVED15;
- __IO uint16_t UEP14_MAX_LEN;
- __IO uint16_t RESERVED16;
- __IO uint16_t UEP15_MAX_LEN;
- __IO uint16_t RESERVED17;
- __IO uint16_t UEP0_TX_LEN;
- __IO uint8_t UEP0_TX_CTRL;
- __IO uint8_t UEP0_RX_CTRL;
- __IO uint16_t UEP1_TX_LEN;
- __IO uint8_t UEP1_TX_CTRL;
- __IO uint8_t UEP1_RX_CTRL;
- __IO uint16_t UEP2_TX_LEN;
- __IO uint8_t UEP2_TX_CTRL;
- __IO uint8_t UEP2_RX_CTRL;
- __IO uint16_t UEP3_TX_LEN;
- __IO uint8_t UEP3_TX_CTRL;
- __IO uint8_t UEP3_RX_CTRL;
- __IO uint16_t UEP4_TX_LEN;
- __IO uint8_t UEP4_TX_CTRL;
- __IO uint8_t UEP4_RX_CTRL;
- __IO uint16_t UEP5_TX_LEN;
- __IO uint8_t UEP5_TX_CTRL;
- __IO uint8_t UEP5_RX_CTRL;
- __IO uint16_t UEP6_TX_LEN;
- __IO uint8_t UEP6_TX_CTRL;
- __IO uint8_t UEP6_RX_CTRL;
- __IO uint16_t UEP7_TX_LEN;
- __IO uint8_t UEP7_TX_CTRL;
- __IO uint8_t UEP7_RX_CTRL;
- __IO uint16_t UEP8_TX_LEN;
- __IO uint8_t UEP8_TX_CTRL;
- __IO uint8_t UEP8_RX_CTRL;
- __IO uint16_t UEP9_TX_LEN;
- __IO uint8_t UEP9_TX_CTRL;
- __IO uint8_t UEP9_RX_CTRL;
- __IO uint16_t UEP10_TX_LEN;
- __IO uint8_t UEP10_TX_CTRL;
- __IO uint8_t UEP10_RX_CTRL;
- __IO uint16_t UEP11_TX_LEN;
- __IO uint8_t UEP11_TX_CTRL;
- __IO uint8_t UEP11_RX_CTRL;
- __IO uint16_t UEP12_TX_LEN;
- __IO uint8_t UEP12_TX_CTRL;
- __IO uint8_t UEP12_RX_CTRL;
- __IO uint16_t UEP13_TX_LEN;
- __IO uint8_t UEP13_TX_CTRL;
- __IO uint8_t UEP13_RX_CTRL;
- __IO uint16_t UEP14_TX_LEN;
- __IO uint8_t UEP14_TX_CTRL;
- __IO uint8_t UEP14_RX_CTRL;
- __IO uint16_t UEP15_TX_LEN;
- __IO uint8_t UEP15_TX_CTRL;
- __IO uint8_t UEP15_RX_CTRL;
-} USBHSD_TypeDef;
-
-typedef struct __attribute__((packed))
-{
- __IO uint8_t CONTROL;
- __IO uint8_t HOST_CTRL;
- __IO uint8_t INT_EN;
- __IO uint8_t DEV_AD;
- __IO uint16_t FRAME_NO;
- __IO uint8_t SUSPEND;
- __IO uint8_t RESERVED0;
- __IO uint8_t SPEED_TYPE;
- __IO uint8_t MIS_ST;
- __IO uint8_t INT_FG;
- __IO uint8_t INT_ST;
- __IO uint16_t RX_LEN;
- __IO uint16_t RESERVED1;
- __IO uint32_t HOST_EP_CONFIG;
- __IO uint32_t HOST_EP_TYPE;
- __IO uint32_t RESERVED2;
- __IO uint32_t RESERVED3;
- __IO uint32_t RESERVED4;
- __IO uint32_t HOST_RX_DMA;
- __IO uint32_t RESERVED5;
- __IO uint32_t RESERVED6;
- __IO uint32_t RESERVED7;
- __IO uint32_t RESERVED8;
- __IO uint32_t RESERVED9;
- __IO uint32_t RESERVED10;
- __IO uint32_t RESERVED11;
- __IO uint32_t RESERVED12;
- __IO uint32_t RESERVED13;
- __IO uint32_t RESERVED14;
- __IO uint32_t RESERVED15;
- __IO uint32_t RESERVED16;
- __IO uint32_t RESERVED17;
- __IO uint32_t RESERVED18;
- __IO uint32_t RESERVED19;
- __IO uint32_t HOST_TX_DMA;
- __IO uint32_t RESERVED20;
- __IO uint32_t RESERVED21;
- __IO uint32_t RESERVED22;
- __IO uint32_t RESERVED23;
- __IO uint32_t RESERVED24;
- __IO uint32_t RESERVED25;
- __IO uint32_t RESERVED26;
- __IO uint32_t RESERVED27;
- __IO uint32_t RESERVED28;
- __IO uint32_t RESERVED29;
- __IO uint32_t RESERVED30;
- __IO uint32_t RESERVED31;
- __IO uint32_t RESERVED32;
- __IO uint32_t RESERVED33;
- __IO uint16_t HOST_RX_MAX_LEN;
- __IO uint16_t RESERVED34;
- __IO uint32_t RESERVED35;
- __IO uint32_t RESERVED36;
- __IO uint32_t RESERVED37;
- __IO uint32_t RESERVED38;
- __IO uint32_t RESERVED39;
- __IO uint32_t RESERVED40;
- __IO uint32_t RESERVED41;
- __IO uint32_t RESERVED42;
- __IO uint32_t RESERVED43;
- __IO uint32_t RESERVED44;
- __IO uint32_t RESERVED45;
- __IO uint32_t RESERVED46;
- __IO uint32_t RESERVED47;
- __IO uint32_t RESERVED48;
- __IO uint32_t RESERVED49;
- __IO uint8_t HOST_EP_PID;
- __IO uint8_t RESERVED50;
- __IO uint8_t RESERVED51;
- __IO uint8_t HOST_RX_CTRL;
- __IO uint16_t HOST_TX_LEN;
- __IO uint8_t HOST_TX_CTRL;
- __IO uint8_t RESERVED52;
- __IO uint16_t HOST_SPLIT_DATA;
-} USBHSH_TypeDef;
-
-
-/* USBOTG_FS Registers */
-typedef struct
-{
- __IO uint8_t BASE_CTRL;
- __IO uint8_t UDEV_CTRL;
- __IO uint8_t INT_EN;
- __IO uint8_t DEV_ADDR;
- __IO uint8_t Reserve0;
- __IO uint8_t MIS_ST;
- __IO uint8_t INT_FG;
- __IO uint8_t INT_ST;
- __IO uint16_t RX_LEN;
- __IO uint16_t Reserve1;
- __IO uint8_t UEP4_1_MOD;
- __IO uint8_t UEP2_3_MOD;
- __IO uint8_t UEP5_6_MOD;
- __IO uint8_t UEP7_MOD;
- __IO uint32_t UEP0_DMA;
- __IO uint32_t UEP1_DMA;
- __IO uint32_t UEP2_DMA;
- __IO uint32_t UEP3_DMA;
- __IO uint32_t UEP4_DMA;
- __IO uint32_t UEP5_DMA;
- __IO uint32_t UEP6_DMA;
- __IO uint32_t UEP7_DMA;
- __IO uint16_t UEP0_TX_LEN;
- __IO uint8_t UEP0_TX_CTRL;
- __IO uint8_t UEP0_RX_CTRL;
- __IO uint16_t UEP1_TX_LEN;
- __IO uint8_t UEP1_TX_CTRL;
- __IO uint8_t UEP1_RX_CTRL;
- __IO uint16_t UEP2_TX_LEN;
- __IO uint8_t UEP2_TX_CTRL;
- __IO uint8_t UEP2_RX_CTRL;
- __IO uint16_t UEP3_TX_LEN;
- __IO uint8_t UEP3_TX_CTRL;
- __IO uint8_t UEP3_RX_CTRL;
- __IO uint16_t UEP4_TX_LEN;
- __IO uint8_t UEP4_TX_CTRL;
- __IO uint8_t UEP4_RX_CTRL;
- __IO uint16_t UEP5_TX_LEN;
- __IO uint8_t UEP5_TX_CTRL;
- __IO uint8_t UEP5_RX_CTRL;
- __IO uint16_t UEP6_TX_LEN;
- __IO uint8_t UEP6_TX_CTRL;
- __IO uint8_t UEP6_RX_CTRL;
- __IO uint16_t UEP7_TX_LEN;
- __IO uint8_t UEP7_TX_CTRL;
- __IO uint8_t UEP7_RX_CTRL;
- __IO uint32_t Reserve2;
- __IO uint32_t OTG_CR;
- __IO uint32_t OTG_SR;
-}USBOTG_FS_TypeDef;
-
-typedef struct __attribute__((packed))
-{
- __IO uint8_t BASE_CTRL;
- __IO uint8_t HOST_CTRL;
- __IO uint8_t INT_EN;
- __IO uint8_t DEV_ADDR;
- __IO uint8_t Reserve0;
- __IO uint8_t MIS_ST;
- __IO uint8_t INT_FG;
- __IO uint8_t INT_ST;
- __IO uint16_t RX_LEN;
- __IO uint16_t Reserve1;
- __IO uint8_t Reserve2;
- __IO uint8_t HOST_EP_MOD;
- __IO uint16_t Reserve3;
- __IO uint32_t Reserve4;
- __IO uint32_t Reserve5;
- __IO uint32_t HOST_RX_DMA;
- __IO uint32_t HOST_TX_DMA;
- __IO uint32_t Reserve6;
- __IO uint32_t Reserve7;
- __IO uint32_t Reserve8;
- __IO uint32_t Reserve9;
- __IO uint32_t Reserve10;
- __IO uint16_t Reserve11;
- __IO uint16_t HOST_SETUP;
- __IO uint8_t HOST_EP_PID;
- __IO uint8_t Reserve12;
- __IO uint8_t Reserve13;
- __IO uint8_t HOST_RX_CTRL;
- __IO uint16_t HOST_TX_LEN;
- __IO uint8_t HOST_TX_CTRL;
- __IO uint8_t Reserve14;
- __IO uint32_t Reserve15;
- __IO uint32_t Reserve16;
- __IO uint32_t Reserve17;
- __IO uint32_t Reserve18;
- __IO uint32_t Reserve19;
- __IO uint32_t OTG_CR;
- __IO uint32_t OTG_SR;
-}USBOTGH_FS_TypeDef;
-
-#define USBFS_BASE ((uint32_t)0x50000000)
-#define USBHS_BASE (((uint32_t))(0x40000000+0x23400))
-
-#define USBHSD ((USBHSD_TypeDef *) USBHS_BASE)
-#define USBHSH ((USBHSH_TypeDef *) USBHS_BASE)
-#define USBOTG_FS ((USBOTG_FS_TypeDef *)USBFS_BASE)
-#define USBOTG_H_FS ((USBOTGH_FS_TypeDef *)USBFS_BASE)
-
-/******************************************************************************/
-/* USBOTG_FS DEVICE USB_CONTROL */
-/* BASE USB_CTRL */
-#define USBHD_BASE_CTRL (USBOTG_FS->BASE_CTRL) // USB base control
-#define USBHD_UC_HOST_MODE 0x80 // enable USB host mode: 0=device mode, 1=host mode
-#define USBHD_UC_LOW_SPEED 0x40 // enable USB low speed: 0=12Mbps, 1=1.5Mbps
-#define USBHD_UC_DEV_PU_EN 0x20 // USB device enable and internal pullup resistance enable
-#define USBHD_UC_SYS_CTRL1 0x20 // USB system control high bit
-#define USBHD_UC_SYS_CTRL0 0x10 // USB system control low bit
-#define USBHD_UC_SYS_CTRL_MASK 0x30 // bit mask of USB system control
-// UC_HOST_MODE & UC_SYS_CTRL1 & UC_SYS_CTRL0: USB system control
-// 0 00: disable USB device and disable internal pullup resistance
-// 0 01: enable USB device and disable internal pullup resistance, need external pullup resistance
-// 0 1x: enable USB device and enable internal pullup resistance
-// 1 00: enable USB host and normal status
-// 1 01: enable USB host and force UDP/UDM output SE0 state
-// 1 10: enable USB host and force UDP/UDM output J state
-// 1 11: enable USB host and force UDP/UDM output resume or K state
-#define USBHD_UC_INT_BUSY 0x08 // enable automatic responding busy for device mode or automatic pause for host mode during interrupt flag UIF_TRANSFER valid
-#define USBHD_UC_RESET_SIE 0x04 // force reset USB SIE, need software clear
-#define USBHD_UC_CLR_ALL 0x02 // force clear FIFO and count of USB
-#define USBHD_UC_DMA_EN 0x01 // DMA enable and DMA interrupt enable for USB
-/* DEVICE USB_CTRL */
-#define USBHD_UDEV_CTRL (USBOTG_FS->UDEV_CTRL) // USB device physical prot control
-#define USBHD_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
-#define USBHD_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
-#define USBHD_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
-#define USBHD_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed
-#define USBHD_UD_GP_BIT 0x02 // general purpose bit
-#define USBHD_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable
-/* USB INT EN */
-#define USBHD_INT_EN (USBOTG_FS->INT_EN) // USB interrupt enable
-#define USBHD_UIE_DEV_SOF 0x80 // enable interrupt for SOF received for USB device mode
-#define USBHD_UIE_DEV_NAK 0x40 // enable interrupt for NAK responded for USB device mode
-#define USBHD_UIE_FIFO_OV 0x10 // enable interrupt for FIFO overflow
-#define USBHD_UIE_HST_SOF 0x08 // enable interrupt for host SOF timer action for USB host mode
-#define USBHD_UIE_SUSPEND 0x04 // enable interrupt for USB suspend or resume event
-#define USBHD_UIE_TRANSFER 0x02 // enable interrupt for USB transfer completion
-#define USBHD_UIE_DETECT 0x01 // enable interrupt for USB device detected event for USB host mode
-#define USBHD_UIE_BUS_RST 0x01 // enable interrupt for USB bus reset event for USB device mode
-/* USB_DEV_ADDR */
-#define USBHD_DEV_ADDR (USBOTG_FS->DEV_ADDR) // USB device address
-#define USBHD_UDA_GP_BIT 0x80 // general purpose bit
-#define USBHD_USB_ADDR_MASK 0x7F // bit mask for USB device address
-/* USBOTG_FS DEVICE USB_STATUS */
-/* USB_MIS_ST */
-#define USBHD_MIS_ST (USBOTG_FS->MIS_ST) // USB miscellaneous status
-#define USBHD_UMS_SOF_PRES 0x80 // RO, indicate host SOF timer presage status
-#define USBHD_UMS_SOF_ACT 0x40 // RO, indicate host SOF timer action status for USB host
-#define USBHD_UMS_SIE_FREE 0x20 // RO, indicate USB SIE free status
-#define USBHD_UMS_R_FIFO_RDY 0x10 // RO, indicate USB receiving FIFO ready status (not empty)
-#define USBHD_UMS_BUS_RESET 0x08 // RO, indicate USB bus reset status
-#define USBHD_UMS_SUSPEND 0x04 // RO, indicate USB suspend status
-#define USBHD_UMS_DM_LEVEL 0x02 // RO, indicate UDM level saved at device attached to USB host
-#define USBHD_UMS_DEV_ATTACH 0x01 // RO, indicate device attached status on USB host
-/* USB_INT_FG */
-#define USBHD_INT_FG (USBOTG_FS->INT_FG) // USB interrupt flag
-#define USBHD_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received
-#define USBHD_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
-#define USBHD_U_SIE_FREE 0x20 // RO, indicate USB SIE free status
-#define USBHD_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
-#define USBHD_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
-#define USBHD_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
-#define USBHD_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
-#define USBHD_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
-#define USBHD_UIF_BUS_RST 0x01 // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
-/* USB_INT_ST */
-#define USBHD_INT_ST (USBOTG_FS->INT_ST) // USB interrupt flag
-#define USBHD_UIS_IS_SETUP 0x80 // RO, indicate current USB transfer is setup received for USB device mode
-#define USBHD_UIS_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received for USB device mode
-#define USBHD_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
-#define USBHD_UIS_TOKEN1 0x20 // RO, current token PID code bit 1 received for USB device mode
-#define USBHD_UIS_TOKEN0 0x10 // RO, current token PID code bit 0 received for USB device mode
-#define USBHD_UIS_TOKEN_MASK 0x30 // RO, bit mask of current token PID code received for USB device mode
-#define USBHD_UIS_TOKEN_OUT 0x00
-#define USBHD_UIS_TOKEN_SOF 0x10
-#define USBHD_UIS_TOKEN_IN 0x20
-#define USBHD_UIS_TOKEN_SETUP 0x30
-// UIS_TOKEN1 & UIS_TOKEN0: current token PID code received for USB device mode
-// 00: OUT token PID received
-// 01: SOF token PID received
-// 10: IN token PID received
-// 11: SETUP token PID received
-#define USBHD_UIS_ENDP_MASK 0x0F // RO, bit mask of current transfer endpoint number for USB device mode
-/* USB_RX_LEN */
-#define USBHD_RX_LEN (USBOTG_FS->Rx_Len) // USB receiving length
-/* USB_BUF_MOD */
-#define USBHD_UEP4_1_MOD (USBOTG_FS->UEP4_1_MOD) // endpoint 4/1 mode
-#define USBHD_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT)
-#define USBHD_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN)
-#define USBHD_UEP1_BUF_MOD 0x10 // buffer mode of USB endpoint 1
-// UEPn_RX_EN & UEPn_TX_EN & UEPn_BUF_MOD: USB endpoint 1/2/3 buffer mode, buffer start address is UEPn_DMA
-// 0 0 x: disable endpoint and disable buffer
-// 1 0 0: 64 bytes buffer for receiving (OUT endpoint)
-// 1 0 1: dual 64 bytes buffer by toggle bit bUEP_R_TOG selection for receiving (OUT endpoint), total=128bytes
-// 0 1 0: 64 bytes buffer for transmittal (IN endpoint)
-// 0 1 1: dual 64 bytes buffer by toggle bit bUEP_T_TOG selection for transmittal (IN endpoint), total=128bytes
-// 1 1 0: 64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes
-// 1 1 1: dual 64 bytes buffer by bUEP_R_TOG selection for receiving (OUT endpoint) + dual 64 bytes buffer by bUEP_T_TOG selection for transmittal (IN endpoint), total=256bytes
-#define USBHD_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT)
-#define USBHD_UEP4_TX_EN 0x04 // enable USB endpoint 4 transmittal (IN)
-// UEP4_RX_EN & UEP4_TX_EN: USB endpoint 4 buffer mode, buffer start address is UEP0_DMA
-// 0 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
-// 1 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint), total=128bytes
-// 0 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=128bytes
-// 1 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
-// + 64 bytes buffer for endpoint 4 receiving (OUT endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=192bytes
-
-#define USBHD_UEP2_3_MOD (USBOTG_FS->UEP2_3_MOD) // endpoint 2/3 mode
-#define USBHD_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT)
-#define USBHD_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN)
-#define USBHD_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3
-#define USBHD_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT)
-#define USBHD_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN)
-#define USBHD_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2
-
-#define USBHD_UEP5_6_MOD (USBOTG_FS->UEP5_6_MOD) // endpoint 5/6 mode
-#define USBHD_UEP6_RX_EN 0x80 // enable USB endpoint 6 receiving (OUT)
-#define USBHD_UEP6_TX_EN 0x40 // enable USB endpoint 6 transmittal (IN)
-#define USBHD_UEP6_BUF_MOD 0x10 // buffer mode of USB endpoint 6
-#define USBHD_UEP5_RX_EN 0x08 // enable USB endpoint 5 receiving (OUT)
-#define USBHD_UEP5_TX_EN 0x04 // enable USB endpoint 5 transmittal (IN)
-#define USBHD_UEP5_BUF_MOD 0x01 // buffer mode of USB endpoint 5
-
-#define USBHD_UEP7_MOD (USBOTG_FS->UEP7_MOD) // endpoint 7 mode
-#define USBHD_UEP7_RX_EN 0x08 // enable USB endpoint 7 receiving (OUT)
-#define USBHD_UEP7_TX_EN 0x04 // enable USB endpoint 7 transmittal (IN)
-#define USBHD_UEP7_BUF_MOD 0x01 // buffer mode of USB endpoint 7
-/* USB_DMA */
-#define USBHD_UEP0_DMA (USBOTG_FS->UEP0_DMA) // endpoint 0 DMA buffer address
-#define USBHD_UEP1_DMA (USBOTG_FS->UEP1_DMA) // endpoint 1 DMA buffer address
-#define USBHD_UEP2_DMA (USBOTG_FS->UEP2_DMA) // endpoint 2 DMA buffer address
-#define USBHD_UEP3_DMA (USBOTG_FS->UEP3_DMA) // endpoint 3 DMA buffer address
-#define USBHD_UEP4_DMA (USBOTG_FS->UEP4_DMA) // endpoint 4 DMA buffer address
-#define USBHD_UEP5_DMA (USBOTG_FS->UEP5_DMA) // endpoint 5 DMA buffer address
-#define USBHD_UEP6_DMA (USBOTG_FS->UEP6_DMA) // endpoint 6 DMA buffer address
-#define USBHD_UEP7_DMA (USBOTG_FS->UEP7_DMA) // endpoint 7 DMA buffer address
-/* USB_EP_CTRL */
-#define USBHD_UEP0_T_LEN (USBOTG_FS->UEP0_TX_LEN) // endpoint 0 transmittal length
-#define USBHD_UEP0_TX_CTRL (USBOTG_FS->UEP0_TX_CTRL) // endpoint 0 control
-#define USBHD_UEP0_RX_CTRL (USBOTG_FS->UEP0_RX_CTRL) // endpoint 0 control
-
-#define USBHD_UEP1_T_LEN (USBOTG_FS->UEP1_TX_LEN) // endpoint 1 transmittal length
-#define USBHD_UEP1_TX_CTRL (USBOTG_FS->UEP1_TX_CTRL) // endpoint 1 control
-#define USBHD_UEP1_RX_CTRL (USBOTG_FS->UEP1_RX_CTRL) // endpoint 1 control
-
-#define USBHD_UEP2_T_LEN (USBOTG_FS->UEP2_TX_LEN) // endpoint 2 transmittal length
-#define USBHD_UEP2_TX_CTRL (USBOTG_FS->UEP2_TX_CTRL) // endpoint 2 control
-#define USBHD_UEP2_RX_CTRL (USBOTG_FS->UEP2_RX_CTRL) // endpoint 2 control
-
-#define USBHD_UEP3_T_LEN (USBOTG_FS->UEP3_TX_LEN) // endpoint 3 transmittal length
-#define USBHD_UEP3_TX_CTRL (USBOTG_FS->UEP3_TX_CTRL) // endpoint 3 control
-#define USBHD_UEP3_RX_CTRL (USBOTG_FS->UEP3_RX_CTRL) // endpoint 3 control
-
-#define USBHD_UEP4_T_LEN (USBOTG_FS->UEP4_TX_LEN) // endpoint 4 transmittal length
-#define USBHD_UEP4_TX_CTRL (USBOTG_FS->UEP4_TX_CTRL) // endpoint 4 control
-#define USBHD_UEP4_RX_CTRL (USBOTG_FS->UEP4_RX_CTRL) // endpoint 4 control
-
-#define USBHD_UEP5_T_LEN (USBOTG_FS->UEP5_TX_LEN) // endpoint 5 transmittal length
-#define USBHD_UEP5_TX_CTRL (USBOTG_FS->UEP5_TX_CTRL) // endpoint 5 control
-#define USBHD_UEP5_RX_CTRL (USBOTG_FS->UEP5_RX_CTRL) // endpoint 5 control
-
-#define USBHD_UEP6_T_LEN (USBOTG_FS->UEP6_TX_LEN) // endpoint 6 transmittal length
-#define USBHD_UEP6_TX_CTRL (USBOTG_FS->UEP6_TX_CTRL) // endpoint 6 control
-#define USBHD_UEP6_RX_CTRL (USBOTG_FS->UEP6_RX_CTRL) // endpoint 6 control
-
-#define USBHD_UEP7_T_LEN (USBOTG_FS->UEP7_TX_LEN) // endpoint 7 transmittal length
-#define USBHD_UEP7_TX_CTRL (USBOTG_FS->UEP7_TX_CTRL) // endpoint 7 control
-#define USBHD_UEP7_RX_CTRL (USBOTG_FS->UEP7_RX_CTRL) // endpoint 7 control
-
-#define USBHD_UEP_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
-#define USBHD_UEP_R_TOG 0x04 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
-#define USBHD_UEP_T_TOG 0x04 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
-
-#define USBHD_UEP_R_RES1 0x02 // handshake response type high bit for USB endpoint X receiving (OUT)
-#define USBHD_UEP_R_RES0 0x01 // handshake response type low bit for USB endpoint X receiving (OUT)
-#define USBHD_UEP_R_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X receiving (OUT)
-#define USBHD_UEP_R_RES_ACK 0x00
-#define USBHD_UEP_R_RES_TOUT 0x01
-#define USBHD_UEP_R_RES_NAK 0x02
-#define USBHD_UEP_R_RES_STALL 0x03
-// RB_UEP_R_RES1 & RB_UEP_R_RES0: handshake response type for USB endpoint X receiving (OUT)
-// 00: ACK (ready)
-// 01: no response, time out to host, for non-zero endpoint isochronous transactions
-// 10: NAK (busy)
-// 11: STALL (error)
-#define USBHD_UEP_T_RES1 0x02 // handshake response type high bit for USB endpoint X transmittal (IN)
-#define USBHD_UEP_T_RES0 0x01 // handshake response type low bit for USB endpoint X transmittal (IN)
-#define USBHD_UEP_T_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN)
-#define USBHD_UEP_T_RES_ACK 0x00
-#define USBHD_UEP_T_RES_TOUT 0x01
-#define USBHD_UEP_T_RES_NAK 0x02
-#define USBHD_UEP_T_RES_STALL 0x03
-// bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN)
-// 00: DATA0 or DATA1 then expecting ACK (ready)
-// 01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions
-// 10: NAK (busy)
-// 11: TALL (error)
-
-#endif
diff --git a/port/ch32/usb_ch32_usbfs_reg.h b/port/ch32/usb_ch32_usbfs_reg.h
new file mode 100644
index 00000000..ca8e487a
--- /dev/null
+++ b/port/ch32/usb_ch32_usbfs_reg.h
@@ -0,0 +1,339 @@
+#ifndef _USB_CH32_USBFS_REG_H
+#define _USB_CH32_USBFS_REG_H
+
+#define __IO volatile /* defines 'read / write' permissions */
+
+/* USBOTG_FS Registers */
+typedef struct
+{
+ __IO uint8_t BASE_CTRL;
+ __IO uint8_t UDEV_CTRL;
+ __IO uint8_t INT_EN;
+ __IO uint8_t DEV_ADDR;
+ __IO uint8_t Reserve0;
+ __IO uint8_t MIS_ST;
+ __IO uint8_t INT_FG;
+ __IO uint8_t INT_ST;
+ __IO uint16_t RX_LEN;
+ __IO uint16_t Reserve1;
+ __IO uint8_t UEP4_1_MOD;
+ __IO uint8_t UEP2_3_MOD;
+ __IO uint8_t UEP5_6_MOD;
+ __IO uint8_t UEP7_MOD;
+ __IO uint32_t UEP0_DMA;
+ __IO uint32_t UEP1_DMA;
+ __IO uint32_t UEP2_DMA;
+ __IO uint32_t UEP3_DMA;
+ __IO uint32_t UEP4_DMA;
+ __IO uint32_t UEP5_DMA;
+ __IO uint32_t UEP6_DMA;
+ __IO uint32_t UEP7_DMA;
+ __IO uint16_t UEP0_TX_LEN;
+ __IO uint8_t UEP0_TX_CTRL;
+ __IO uint8_t UEP0_RX_CTRL;
+ __IO uint16_t UEP1_TX_LEN;
+ __IO uint8_t UEP1_TX_CTRL;
+ __IO uint8_t UEP1_RX_CTRL;
+ __IO uint16_t UEP2_TX_LEN;
+ __IO uint8_t UEP2_TX_CTRL;
+ __IO uint8_t UEP2_RX_CTRL;
+ __IO uint16_t UEP3_TX_LEN;
+ __IO uint8_t UEP3_TX_CTRL;
+ __IO uint8_t UEP3_RX_CTRL;
+ __IO uint16_t UEP4_TX_LEN;
+ __IO uint8_t UEP4_TX_CTRL;
+ __IO uint8_t UEP4_RX_CTRL;
+ __IO uint16_t UEP5_TX_LEN;
+ __IO uint8_t UEP5_TX_CTRL;
+ __IO uint8_t UEP5_RX_CTRL;
+ __IO uint16_t UEP6_TX_LEN;
+ __IO uint8_t UEP6_TX_CTRL;
+ __IO uint8_t UEP6_RX_CTRL;
+ __IO uint16_t UEP7_TX_LEN;
+ __IO uint8_t UEP7_TX_CTRL;
+ __IO uint8_t UEP7_RX_CTRL;
+ __IO uint32_t Reserve2;
+ __IO uint32_t OTG_CR;
+ __IO uint32_t OTG_SR;
+} USBOTG_FS_TypeDef;
+
+typedef struct __attribute__((packed)) {
+ __IO uint8_t BASE_CTRL;
+ __IO uint8_t HOST_CTRL;
+ __IO uint8_t INT_EN;
+ __IO uint8_t DEV_ADDR;
+ __IO uint8_t Reserve0;
+ __IO uint8_t MIS_ST;
+ __IO uint8_t INT_FG;
+ __IO uint8_t INT_ST;
+ __IO uint16_t RX_LEN;
+ __IO uint16_t Reserve1;
+ __IO uint8_t Reserve2;
+ __IO uint8_t HOST_EP_MOD;
+ __IO uint16_t Reserve3;
+ __IO uint32_t Reserve4;
+ __IO uint32_t Reserve5;
+ __IO uint32_t HOST_RX_DMA;
+ __IO uint32_t HOST_TX_DMA;
+ __IO uint32_t Reserve6;
+ __IO uint32_t Reserve7;
+ __IO uint32_t Reserve8;
+ __IO uint32_t Reserve9;
+ __IO uint32_t Reserve10;
+ __IO uint16_t Reserve11;
+ __IO uint16_t HOST_SETUP;
+ __IO uint8_t HOST_EP_PID;
+ __IO uint8_t Reserve12;
+ __IO uint8_t Reserve13;
+ __IO uint8_t HOST_RX_CTRL;
+ __IO uint16_t HOST_TX_LEN;
+ __IO uint8_t HOST_TX_CTRL;
+ __IO uint8_t Reserve14;
+ __IO uint32_t Reserve15;
+ __IO uint32_t Reserve16;
+ __IO uint32_t Reserve17;
+ __IO uint32_t Reserve18;
+ __IO uint32_t Reserve19;
+ __IO uint32_t OTG_CR;
+ __IO uint32_t OTG_SR;
+} USBOTGH_FS_TypeDef;
+
+#define USBFS_BASE ((uint32_t)0x50000000)
+
+#define USBFS_DEVICE ((USBOTG_FS_TypeDef *)USBFS_BASE)
+#define USBFS_HOST ((USBOTGH_FS_TypeDef *)USBFS_BASE)
+
+/******************* GLOBAL ******************/
+
+/* BASE USB_CTRL */
+#define USBFS_BASE_CTRL_OFFSET 0x00 // USB base control
+#define USBFS_UC_HOST_MODE 0x80 // enable USB host mode: 0=device mode, 1=host mode
+#define USBFS_UC_LOW_SPEED 0x40 // enable USB low speed: 0=12Mbps, 1=1.5Mbps
+#define USBFS_UC_DEV_PU_EN 0x20 // USB device enable and internal pullup resistance enable
+#define USBFS_UC_SYS_CTRL1 0x20 // USB system control high bit
+#define USBFS_UC_SYS_CTRL0 0x10 // USB system control low bit
+#define USBFS_UC_SYS_CTRL_MASK 0x30 // bit mask of USB system control
+// UC_HOST_MODE & UC_SYS_CTRL1 & UC_SYS_CTRL0: USB system control
+// 0 00: disable USB device and disable internal pullup resistance
+// 0 01: enable USB device and disable internal pullup resistance, need external pullup resistance
+// 0 1x: enable USB device and enable internal pullup resistance
+// 1 00: enable USB host and normal status
+// 1 01: enable USB host and force UDP/UDM output SE0 state
+// 1 10: enable USB host and force UDP/UDM output J state
+// 1 11: enable USB host and force UDP/UDM output resume or K state
+#define USBFS_UC_INT_BUSY 0x08 // enable automatic responding busy for device mode or automatic pause for host mode during interrupt flag UIF_TRANSFER valid
+#define USBFS_UC_RESET_SIE 0x04 // force reset USB SIE, need software clear
+#define USBFS_UC_CLR_ALL 0x02 // force clear FIFO and count of USB
+#define USBFS_UC_DMA_EN 0x01 // DMA enable and DMA interrupt enable for USB
+
+/* USB INT EN */
+#define USBFS_INT_EN_OFFSET 0x02
+#define USBFS_UIE_DEV_SOF 0x80 // enable interrupt for SOF received for USB device mode
+#define USBFS_UIE_DEV_NAK 0x40 // enable interrupt for NAK responded for USB device mode
+#define USBFS_UIE_FIFO_OV 0x10 // enable interrupt for FIFO overflow
+#define USBFS_UIE_HST_SOF 0x08 // enable interrupt for host SOF timer action for USB host mode
+#define USBFS_UIE_SUSPEND 0x04 // enable interrupt for USB suspend or resume event
+#define USBFS_UIE_TRANSFER 0x02 // enable interrupt for USB transfer completion
+#define USBFS_UIE_DETECT 0x01 // enable interrupt for USB device detected event for USB host mode
+#define USBFS_UIE_BUS_RST 0x01 // enable interrupt for USB bus reset event for USB device mode
+/* USB_DEV_ADDR */
+#define USBFS_DEV_ADDR_OFFSET 0x03
+#define USBFS_UDA_GP_BIT 0x80 // general purpose bit
+#define USBFS_USB_ADDR_MASK 0x7F // bit mask for USB device address
+
+/* USB_STATUS */
+#define USBFS_USB_STATUS_OFFSET 0x04
+
+/* USB_MIS_ST */
+#define USBFS_MIS_ST_OFFSET 0x05
+#define USBFS_UMS_SOF_PRES 0x80 // RO, indicate host SOF timer presage status
+#define USBFS_UMS_SOF_ACT 0x40 // RO, indicate host SOF timer action status for USB host
+#define USBFS_UMS_SIE_FREE 0x20 // RO, indicate USB SIE free status
+#define USBFS_UMS_R_FIFO_RDY 0x10 // RO, indicate USB receiving FIFO ready status (not empty)
+#define USBFS_UMS_BUS_RESET 0x08 // RO, indicate USB bus reset status
+#define USBFS_UMS_SUSPEND 0x04 // RO, indicate USB suspend status
+#define USBFS_UMS_DM_LEVEL 0x02 // RO, indicate UDM level saved at device attached to USB host
+#define USBFS_UMS_DEV_ATTACH 0x01 // RO, indicate device attached status on USB host
+
+/* USB_INT_FG */
+#define USBFS_INT_FG_OFFSET 0x06
+#define USBFS_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received
+#define USBFS_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
+#define USBFS_U_SIE_FREE 0x20 // RO, indicate USB SIE free status
+#define USBFS_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
+#define USBFS_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
+#define USBFS_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
+#define USBFS_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
+#define USBFS_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
+#define USBFS_UIF_BUS_RST 0x01 // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
+
+/* USB_INT_ST */
+#define USBFS_INT_ST_OFFSET 0x07
+#define USBFS_UIS_IS_SETUP 0x80 // RO, indicate current USB transfer is setup received for USB device mode
+#define USBFS_UIS_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received for USB device mode
+#define USBFS_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
+#define USBFS_UIS_TOKEN1 0x20 // RO, current token PID code bit 1 received for USB device mode
+#define USBFS_UIS_TOKEN0 0x10 // RO, current token PID code bit 0 received for USB device mode
+#define USBFS_UIS_TOKEN_MASK 0x30 // RO, bit mask of current token PID code received for USB device mode
+#define USBFS_UIS_TOKEN_OUT 0x00
+#define USBFS_UIS_TOKEN_SOF 0x10
+#define USBFS_UIS_TOKEN_IN 0x20
+#define USBFS_UIS_TOKEN_SETUP 0x30
+// UIS_TOKEN1 & UIS_TOKEN0: current token PID code received for USB device mode
+// 00: OUT token PID received
+// 01: SOF token PID received
+// 10: IN token PID received
+// 11: SETUP token PID received
+#define USBFS_UIS_ENDP_MASK 0x0F // RO, bit mask of current transfer endpoint number for USB device mode
+/* USB_RX_LEN */
+#define USBFS_RX_LEN_OFFSET 0x08
+
+/******************* DEVICE ******************/
+
+/* UDEV_CTRL */
+#define USBFS_UDEV_CTRL_OFFSET 0x01
+#define USBFS_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
+#define USBFS_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
+#define USBFS_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
+#define USBFS_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed
+#define USBFS_UD_GP_BIT 0x02 // general purpose bit
+#define USBFS_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable
+
+/* UEP4_1_MOD */
+#define USBFS_UEP4_1_MOD_OFFSET 0x0C
+#define USBFS_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT)
+#define USBFS_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN)
+#define USBFS_UEP1_BUF_MOD 0x10 // buffer mode of USB endpoint 1
+// UEPn_RX_EN & UEPn_TX_EN & UEPn_BUF_MOD: USB endpoint 1/2/3 buffer mode, buffer start address is UEPn_DMA
+// 0 0 x: disable endpoint and disable buffer
+// 1 0 0: 64 bytes buffer for receiving (OUT endpoint)
+// 1 0 1: dual 64 bytes buffer by toggle bit bUEP_R_TOG selection for receiving (OUT endpoint), total=128bytes
+// 0 1 0: 64 bytes buffer for transmittal (IN endpoint)
+// 0 1 1: dual 64 bytes buffer by toggle bit bUEP_T_TOG selection for transmittal (IN endpoint), total=128bytes
+// 1 1 0: 64 bytes buffer for receiving (OUT endpoint) + 64 bytes buffer for transmittal (IN endpoint), total=128bytes
+// 1 1 1: dual 64 bytes buffer by bUEP_R_TOG selection for receiving (OUT endpoint) + dual 64 bytes buffer by bUEP_T_TOG selection for transmittal (IN endpoint), total=256bytes
+#define USBFS_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT)
+#define USBFS_UEP4_TX_EN 0x04 // enable USB endpoint 4 transmittal (IN)
+// UEP4_RX_EN & UEP4_TX_EN: USB endpoint 4 buffer mode, buffer start address is UEP0_DMA
+// 0 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
+// 1 0: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 receiving (OUT endpoint), total=128bytes
+// 0 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=128bytes
+// 1 1: single 64 bytes buffer for endpoint 0 receiving & transmittal (OUT & IN endpoint)
+// + 64 bytes buffer for endpoint 4 receiving (OUT endpoint) + 64 bytes buffer for endpoint 4 transmittal (IN endpoint), total=192bytes
+
+/* UEP2_3_MOD */
+#define USBFS_UEP2_3_MOD_OFFSET 0x0D
+#define USBFS_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT)
+#define USBFS_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN)
+#define USBFS_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3
+#define USBFS_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT)
+#define USBFS_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN)
+#define USBFS_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2
+
+/* UEP5_6_MOD */
+#define USBFS_UEP5_6_MOD_OFFSET 0x0E
+#define USBFS_UEP6_RX_EN 0x80 // enable USB endpoint 6 receiving (OUT)
+#define USBFS_UEP6_TX_EN 0x40 // enable USB endpoint 6 transmittal (IN)
+#define USBFS_UEP6_BUF_MOD 0x10 // buffer mode of USB endpoint 6
+#define USBFS_UEP5_RX_EN 0x08 // enable USB endpoint 5 receiving (OUT)
+#define USBFS_UEP5_TX_EN 0x04 // enable USB endpoint 5 transmittal (IN)
+#define USBFS_UEP5_BUF_MOD 0x01 // buffer mode of USB endpoint 5
+
+/* UEP7_MOD */
+#define USBFS_UEP7_MOD_OFFSET 0x0F
+#define USBFS_UEP7_RX_EN 0x08 // enable USB endpoint 7 receiving (OUT)
+#define USBFS_UEP7_TX_EN 0x04 // enable USB endpoint 7 transmittal (IN)
+#define USBFS_UEP7_BUF_MOD 0x01 // buffer mode of USB endpoint 7
+
+/* USB_DMA */
+#define USBFS_UEPx_DMA_OFFSET(n) (0x10 + 4 * (n)) // endpoint x DMA buffer address
+#define USBFS_UEP0_DMA_OFFSET 0x10 // endpoint 0 DMA buffer address
+#define USBFS_UEP1_DMA_OFFSET 0x14 // endpoint 1 DMA buffer address
+#define USBFS_UEP2_DMA_OFFSET 0x18 // endpoint 2 DMA buffer address
+#define USBFS_UEP3_DMA_OFFSET 0x1c // endpoint 3 DMA buffer address
+#define USBFS_UEP4_DMA_OFFSET 0x20 // endpoint 4 DMA buffer address
+#define USBFS_UEP5_DMA_OFFSET 0x24 // endpoint 5 DMA buffer address
+#define USBFS_UEP6_DMA_OFFSET 0x28 // endpoint 6 DMA buffer address
+#define USBFS_UEP7_DMA_OFFSET 0x2c // endpoint 7 DMA buffer address
+/* USB_EP_CTRL */
+#define USBFS_UEPx_T_LEN_OFFSET(n) (0x30 + 4 * (n)) // endpoint x DMA buffer address
+#define USBFS_UEPx_TX_CTRL_OFFSET(n) (0x30 + 4 * (n) + 2) // endpoint x DMA buffer address
+#define USBFS_UEPx_RX_CTRL_OFFSET(n) (0x30 + 4 * (n) + 3) // endpoint x DMA buffer address
+
+#define USBFS_UEP_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
+#define USBFS_UEP_R_TOG 0x04 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
+#define USBFS_UEP_T_TOG 0x04 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
+
+#define USBFS_UEP_R_RES1 0x02 // handshake response type high bit for USB endpoint X receiving (OUT)
+#define USBFS_UEP_R_RES0 0x01 // handshake response type low bit for USB endpoint X receiving (OUT)
+#define USBFS_UEP_R_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X receiving (OUT)
+#define USBFS_UEP_R_RES_ACK 0x00
+#define USBFS_UEP_R_RES_TOUT 0x01
+#define USBFS_UEP_R_RES_NAK 0x02
+#define USBFS_UEP_R_RES_STALL 0x03
+// RB_UEP_R_RES1 & RB_UEP_R_RES0: handshake response type for USB endpoint X receiving (OUT)
+// 00: ACK (ready)
+// 01: no response, time out to host, for non-zero endpoint isochronous transactions
+// 10: NAK (busy)
+// 11: STALL (error)
+#define USBFS_UEP_T_RES1 0x02 // handshake response type high bit for USB endpoint X transmittal (IN)
+#define USBFS_UEP_T_RES0 0x01 // handshake response type low bit for USB endpoint X transmittal (IN)
+#define USBFS_UEP_T_RES_MASK 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN)
+#define USBFS_UEP_T_RES_ACK 0x00
+#define USBFS_UEP_T_RES_TOUT 0x01
+#define USBFS_UEP_T_RES_NAK 0x02
+#define USBFS_UEP_T_RES_STALL 0x03
+// bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN)
+// 00: DATA0 or DATA1 then expecting ACK (ready)
+// 01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions
+// 10: NAK (busy)
+// 11: TALL (error)
+
+/******************* HOST ******************/
+
+#define USBFS_UHOST_CTRL_OFFSET 0x01 // USB host physical prot control
+#define USBFS_UH_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
+#define USBFS_UH_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
+#define USBFS_UH_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
+#define USBFS_UH_LOW_SPEED 0x04 // enable USB port low speed: 0=full speed, 1=low speed
+#define USBFS_UH_BUS_RESET 0x02 // control USB bus reset: 0=normal, 1=force bus reset
+#define USBFS_UH_PORT_EN 0x01 // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
+
+#define USBFS_UH_EP_MOD_OFFSET USBFS_UEP2_3_MOD_OFFSET
+#define USBFS_UH_EP_TX_EN 0x40 // enable USB host OUT endpoint transmittal
+#define USBFS_UH_EP_TBUF_MOD 0x10 // buffer mode of USB host OUT endpoint
+// bUH_EP_TX_EN & bUH_EP_TBUF_MOD: USB host OUT endpoint buffer mode, buffer start address is UH_TX_DMA
+// 0 x: disable endpoint and disable buffer
+// 1 0: 64 bytes buffer for transmittal (OUT endpoint)
+// 1 1: dual 64 bytes buffer by toggle bit bUH_T_TOG selection for transmittal (OUT endpoint), total=128bytes
+#define USBFS_UH_EP_RX_EN 0x08 // enable USB host IN endpoint receiving
+#define USBFS_UH_EP_RBUF_MOD 0x01 // buffer mode of USB host IN endpoint
+// bUH_EP_RX_EN & bUH_EP_RBUF_MOD: USB host IN endpoint buffer mode, buffer start address is UH_RX_DMA
+// 0 x: disable endpoint and disable buffer
+// 1 0: 64 bytes buffer for receiving (IN endpoint)
+// 1 1: dual 64 bytes buffer by toggle bit bUH_R_TOG selection for receiving (IN endpoint), total=128bytes
+
+#define USBFS_UH_RX_DMA_OFFSET USBFS_UEPx_DMA_OFFSET(2) // host rx endpoint buffer high address
+#define USBFS_UH_TX_DMA_OFFSET USBFS_UEPx_DMA_OFFSET(3) // host tx endpoint buffer high address
+
+#define USBFS_UH_SETUP_OFFSET USBFS_UEPx_TX_CTRL_OFFSET(1)
+#define USBFS_UH_PRE_PID_EN 0x0400 // USB host PRE PID enable for low speed device via hub
+#define USBFS_UH_SOF_EN 0x04 // USB host automatic SOF enable
+
+#define USBFS_UH_EP_PID_OFFSET USBFS_UEPx_T_LEN_OFFSET(2)
+#define USBFS_UH_TOKEN_MASK 0xF0 // bit mask of token PID for USB host transfer
+#define USBFS_UH_ENDP_MASK 0x0F // bit mask of endpoint number for USB host transfer
+
+#define USBFS_UH_RX_CTRL_OFFSET USBFS_UEPx_RX_CTRL_OFFSET(2) // host receiver endpoint control
+#define USBFS_UH_R_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
+#define USBFS_UH_R_TOG 0x04 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
+#define USBFS_UH_R_RES 0x01 // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
+
+#define USBFS_UH_TX_LEN_OFFSET USBFS_UEPx_T_LEN_OFFSET(3)
+
+#define USBFS_UH_TX_CTRL_OFFSET USBFS_UEPx_TX_CTRL_OFFSET(3) // host transmittal endpoint control
+#define USBFS_UH_T_AUTO_TOG 0x08 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
+#define USBFS_UH_T_TOG 0x04 // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
+#define USBFS_UH_T_RES 0x01 // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions
+
+#endif
diff --git a/port/ch32/usb_ch32_usbhs_reg.h b/port/ch32/usb_ch32_usbhs_reg.h
new file mode 100644
index 00000000..3cf382cf
--- /dev/null
+++ b/port/ch32/usb_ch32_usbhs_reg.h
@@ -0,0 +1,559 @@
+#ifndef _USB_CH32_USBHS_REG_H
+#define _USB_CH32_USBHS_REG_H
+
+#define __IO volatile /* defines 'read / write' permissions */
+
+/* USBHS Registers */
+typedef struct
+{
+ __IO uint8_t CONTROL;
+ __IO uint8_t HOST_CTRL;
+ __IO uint8_t INT_EN;
+ __IO uint8_t DEV_AD;
+ __IO uint16_t FRAME_NO;
+ __IO uint8_t SUSPEND;
+ __IO uint8_t RESERVED0;
+ __IO uint8_t SPEED_TYPE;
+ __IO uint8_t MIS_ST;
+ __IO uint8_t INT_FG;
+ __IO uint8_t INT_ST;
+ __IO uint16_t RX_LEN;
+ __IO uint16_t RESERVED1;
+ __IO uint32_t ENDP_CONFIG;
+ __IO uint32_t ENDP_TYPE;
+ __IO uint32_t BUF_MODE;
+ __IO uint32_t UEP0_DMA;
+ __IO uint32_t UEP1_RX_DMA;
+ __IO uint32_t UEP2_RX_DMA;
+ __IO uint32_t UEP3_RX_DMA;
+ __IO uint32_t UEP4_RX_DMA;
+ __IO uint32_t UEP5_RX_DMA;
+ __IO uint32_t UEP6_RX_DMA;
+ __IO uint32_t UEP7_RX_DMA;
+ __IO uint32_t UEP8_RX_DMA;
+ __IO uint32_t UEP9_RX_DMA;
+ __IO uint32_t UEP10_RX_DMA;
+ __IO uint32_t UEP11_RX_DMA;
+ __IO uint32_t UEP12_RX_DMA;
+ __IO uint32_t UEP13_RX_DMA;
+ __IO uint32_t UEP14_RX_DMA;
+ __IO uint32_t UEP15_RX_DMA;
+ __IO uint32_t UEP1_TX_DMA;
+ __IO uint32_t UEP2_TX_DMA;
+ __IO uint32_t UEP3_TX_DMA;
+ __IO uint32_t UEP4_TX_DMA;
+ __IO uint32_t UEP5_TX_DMA;
+ __IO uint32_t UEP6_TX_DMA;
+ __IO uint32_t UEP7_TX_DMA;
+ __IO uint32_t UEP8_TX_DMA;
+ __IO uint32_t UEP9_TX_DMA;
+ __IO uint32_t UEP10_TX_DMA;
+ __IO uint32_t UEP11_TX_DMA;
+ __IO uint32_t UEP12_TX_DMA;
+ __IO uint32_t UEP13_TX_DMA;
+ __IO uint32_t UEP14_TX_DMA;
+ __IO uint32_t UEP15_TX_DMA;
+ __IO uint16_t UEP0_MAX_LEN;
+ __IO uint16_t RESERVED2;
+ __IO uint16_t UEP1_MAX_LEN;
+ __IO uint16_t RESERVED3;
+ __IO uint16_t UEP2_MAX_LEN;
+ __IO uint16_t RESERVED4;
+ __IO uint16_t UEP3_MAX_LEN;
+ __IO uint16_t RESERVED5;
+ __IO uint16_t UEP4_MAX_LEN;
+ __IO uint16_t RESERVED6;
+ __IO uint16_t UEP5_MAX_LEN;
+ __IO uint16_t RESERVED7;
+ __IO uint16_t UEP6_MAX_LEN;
+ __IO uint16_t RESERVED8;
+ __IO uint16_t UEP7_MAX_LEN;
+ __IO uint16_t RESERVED9;
+ __IO uint16_t UEP8_MAX_LEN;
+ __IO uint16_t RESERVED10;
+ __IO uint16_t UEP9_MAX_LEN;
+ __IO uint16_t RESERVED11;
+ __IO uint16_t UEP10_MAX_LEN;
+ __IO uint16_t RESERVED12;
+ __IO uint16_t UEP11_MAX_LEN;
+ __IO uint16_t RESERVED13;
+ __IO uint16_t UEP12_MAX_LEN;
+ __IO uint16_t RESERVED14;
+ __IO uint16_t UEP13_MAX_LEN;
+ __IO uint16_t RESERVED15;
+ __IO uint16_t UEP14_MAX_LEN;
+ __IO uint16_t RESERVED16;
+ __IO uint16_t UEP15_MAX_LEN;
+ __IO uint16_t RESERVED17;
+ __IO uint16_t UEP0_TX_LEN;
+ __IO uint8_t UEP0_TX_CTRL;
+ __IO uint8_t UEP0_RX_CTRL;
+ __IO uint16_t UEP1_TX_LEN;
+ __IO uint8_t UEP1_TX_CTRL;
+ __IO uint8_t UEP1_RX_CTRL;
+ __IO uint16_t UEP2_TX_LEN;
+ __IO uint8_t UEP2_TX_CTRL;
+ __IO uint8_t UEP2_RX_CTRL;
+ __IO uint16_t UEP3_TX_LEN;
+ __IO uint8_t UEP3_TX_CTRL;
+ __IO uint8_t UEP3_RX_CTRL;
+ __IO uint16_t UEP4_TX_LEN;
+ __IO uint8_t UEP4_TX_CTRL;
+ __IO uint8_t UEP4_RX_CTRL;
+ __IO uint16_t UEP5_TX_LEN;
+ __IO uint8_t UEP5_TX_CTRL;
+ __IO uint8_t UEP5_RX_CTRL;
+ __IO uint16_t UEP6_TX_LEN;
+ __IO uint8_t UEP6_TX_CTRL;
+ __IO uint8_t UEP6_RX_CTRL;
+ __IO uint16_t UEP7_TX_LEN;
+ __IO uint8_t UEP7_TX_CTRL;
+ __IO uint8_t UEP7_RX_CTRL;
+ __IO uint16_t UEP8_TX_LEN;
+ __IO uint8_t UEP8_TX_CTRL;
+ __IO uint8_t UEP8_RX_CTRL;
+ __IO uint16_t UEP9_TX_LEN;
+ __IO uint8_t UEP9_TX_CTRL;
+ __IO uint8_t UEP9_RX_CTRL;
+ __IO uint16_t UEP10_TX_LEN;
+ __IO uint8_t UEP10_TX_CTRL;
+ __IO uint8_t UEP10_RX_CTRL;
+ __IO uint16_t UEP11_TX_LEN;
+ __IO uint8_t UEP11_TX_CTRL;
+ __IO uint8_t UEP11_RX_CTRL;
+ __IO uint16_t UEP12_TX_LEN;
+ __IO uint8_t UEP12_TX_CTRL;
+ __IO uint8_t UEP12_RX_CTRL;
+ __IO uint16_t UEP13_TX_LEN;
+ __IO uint8_t UEP13_TX_CTRL;
+ __IO uint8_t UEP13_RX_CTRL;
+ __IO uint16_t UEP14_TX_LEN;
+ __IO uint8_t UEP14_TX_CTRL;
+ __IO uint8_t UEP14_RX_CTRL;
+ __IO uint16_t UEP15_TX_LEN;
+ __IO uint8_t UEP15_TX_CTRL;
+ __IO uint8_t UEP15_RX_CTRL;
+} USBHSD_TypeDef;
+
+typedef struct __attribute__((packed)) {
+ __IO uint8_t CONTROL;
+ __IO uint8_t HOST_CTRL;
+ __IO uint8_t INT_EN;
+ __IO uint8_t DEV_AD;
+ __IO uint16_t FRAME_NO;
+ __IO uint8_t SUSPEND;
+ __IO uint8_t RESERVED0;
+ __IO uint8_t SPEED_TYPE;
+ __IO uint8_t MIS_ST;
+ __IO uint8_t INT_FG;
+ __IO uint8_t INT_ST;
+ __IO uint16_t RX_LEN;
+ __IO uint16_t RESERVED1;
+ __IO uint32_t HOST_EP_CONFIG;
+ __IO uint32_t HOST_EP_TYPE;
+ __IO uint32_t RESERVED2;
+ __IO uint32_t RESERVED3;
+ __IO uint32_t RESERVED4;
+ __IO uint32_t HOST_RX_DMA;
+ __IO uint32_t RESERVED5;
+ __IO uint32_t RESERVED6;
+ __IO uint32_t RESERVED7;
+ __IO uint32_t RESERVED8;
+ __IO uint32_t RESERVED9;
+ __IO uint32_t RESERVED10;
+ __IO uint32_t RESERVED11;
+ __IO uint32_t RESERVED12;
+ __IO uint32_t RESERVED13;
+ __IO uint32_t RESERVED14;
+ __IO uint32_t RESERVED15;
+ __IO uint32_t RESERVED16;
+ __IO uint32_t RESERVED17;
+ __IO uint32_t RESERVED18;
+ __IO uint32_t RESERVED19;
+ __IO uint32_t HOST_TX_DMA;
+ __IO uint32_t RESERVED20;
+ __IO uint32_t RESERVED21;
+ __IO uint32_t RESERVED22;
+ __IO uint32_t RESERVED23;
+ __IO uint32_t RESERVED24;
+ __IO uint32_t RESERVED25;
+ __IO uint32_t RESERVED26;
+ __IO uint32_t RESERVED27;
+ __IO uint32_t RESERVED28;
+ __IO uint32_t RESERVED29;
+ __IO uint32_t RESERVED30;
+ __IO uint32_t RESERVED31;
+ __IO uint32_t RESERVED32;
+ __IO uint32_t RESERVED33;
+ __IO uint16_t HOST_RX_MAX_LEN;
+ __IO uint16_t RESERVED34;
+ __IO uint32_t RESERVED35;
+ __IO uint32_t RESERVED36;
+ __IO uint32_t RESERVED37;
+ __IO uint32_t RESERVED38;
+ __IO uint32_t RESERVED39;
+ __IO uint32_t RESERVED40;
+ __IO uint32_t RESERVED41;
+ __IO uint32_t RESERVED42;
+ __IO uint32_t RESERVED43;
+ __IO uint32_t RESERVED44;
+ __IO uint32_t RESERVED45;
+ __IO uint32_t RESERVED46;
+ __IO uint32_t RESERVED47;
+ __IO uint32_t RESERVED48;
+ __IO uint32_t RESERVED49;
+ __IO uint8_t HOST_EP_PID;
+ __IO uint8_t RESERVED50;
+ __IO uint8_t RESERVED51;
+ __IO uint8_t HOST_RX_CTRL;
+ __IO uint16_t HOST_TX_LEN;
+ __IO uint8_t HOST_TX_CTRL;
+ __IO uint8_t RESERVED52;
+ __IO uint16_t HOST_SPLIT_DATA;
+} USBHSH_TypeDef;
+
+#define USBHS_BASE ((uint32_t)(0x40000000 + 0x23400))
+
+#define USBHS_DEVICE ((USBHSD_TypeDef *)USBHS_BASE)
+#define USBHS_HOST ((USBHSH_TypeDef *)USBHS_BASE)
+
+/******************* GLOBAL ******************/
+
+// USB CONTROL
+#define USBHS_CONTROL_OFFSET 0x00
+#define USBHS_DMA_EN (1 << 0)
+#define USBHS_ALL_CLR (1 << 1)
+#define USBHS_FORCE_RST (1 << 2)
+#define USBHS_INT_BUSY_EN (1 << 3)
+#define USBHS_DEV_PU_EN (1 << 4)
+#define USBHS_SPEED_MASK (3 << 5)
+#define USBHS_FULL_SPEED (0 << 5)
+#define USBHS_HIGH_SPEED (1 << 5)
+#define USBHS_LOW_SPEED (2 << 5)
+#define USBHS_HOST_MODE (1 << 7)
+
+// USB_INT_EN
+#define USBHS_INT_EN_OFFSET 0x02
+#define USBHS_BUS_RST_EN (1 << 0)
+#define USBHS_DETECT_EN (1 << 0)
+#define USBHS_TRANSFER_EN (1 << 1)
+#define USBHS_SUSPEND_EN (1 << 2)
+#define USBHS_SOF_ACT_EN (1 << 3)
+#define USBHS_FIFO_OV_EN (1 << 4)
+#define USBHS_SETUP_ACT_EN (1 << 5)
+#define USBHS_ISO_ACT_EN (1 << 6)
+#define USBHS_DEV_NAK_EN (1 << 7)
+
+// USB DEV AD
+#define USBHS_DEV_AD_OFFSET 0x03
+// USB FRAME_NO
+#define USBHS_FRAME_NO_OFFSET 0x04
+// USB SUSPEND
+#define USBHS_SUSPEND_OFFSET 0x06
+#define USBHS_DEV_REMOTE_WAKEUP (1 << 2)
+#define USBHS_LINESTATE_MASK (2 << 4) /* Read Only */
+
+// RESERVED0
+
+// USB SPEED TYPE
+#define USBHS_SPEED_TYPE_OFFSET 0x08
+#define USBSPEED_MASK (0x03)
+
+// USB_MIS_ST
+#define USBHS_MIS_ST_OFFSET 0x09
+#define USBHS_SPLIT_CAN (1 << 0)
+#define USBHS_ATTACH (1 << 1)
+#define USBHS_SUSPEND (1 << 2)
+#define USBHS_BUS_RESET (1 << 3)
+#define USBHS_R_FIFO_RDY (1 << 4)
+#define USBHS_SIE_FREE (1 << 5)
+#define USBHS_SOF_ACT (1 << 6)
+#define USBHS_SOF_PRES (1 << 7)
+
+// INT_FLAG
+#define USBHS_INT_FLAG_OFFSET 0x0A
+#define USBHS_BUS_RST_FLAG (1 << 0)
+#define USBHS_DETECT_FLAG (1 << 0)
+#define USBHS_TRANSFER_FLAG (1 << 1)
+#define USBHS_SUSPEND_FLAG (1 << 2)
+#define USBHS_HST_SOF_FLAG (1 << 3)
+#define USBHS_FIFO_OV_FLAG (1 << 4)
+#define USBHS_SETUP_FLAG (1 << 5)
+#define USBHS_ISO_ACT_FLAG (1 << 6)
+
+// INT_ST
+#define USBHS_INT_ST_OFFSET 0x0B
+#define USBHS_DEV_UIS_IS_NAK (1 << 7)
+#define USBHS_DEV_UIS_TOG_OK (1 << 6)
+#define MASK_UIS_TOKEN (3 << 4)
+#define MASK_UIS_ENDP (0x0F)
+#define MASK_UIS_H_RES (0x0F)
+
+#define USBHS_TOGGLE_OK (0x40)
+#define USBHS_HOST_RES (0x0f)
+
+//USB_RX_LEN
+#define USBHS_RX_LEN_OFFSET 0x0C
+/******************* DEVICE ******************/
+
+//UEP_CONFIG
+#define USBHS_UEP_CONFIG_OFFSET 0x10
+#define USBHS_EP0_T_EN (1 << 0)
+#define USBHS_EP0_R_EN (1 << 16)
+
+#define USBHS_EP1_T_EN (1 << 1)
+#define USBHS_EP1_R_EN (1 << 17)
+
+#define USBHS_EP2_T_EN (1 << 2)
+#define USBHS_EP2_R_EN (1 << 18)
+
+#define USBHS_EP3_T_EN (1 << 3)
+#define USBHS_EP3_R_EN (1 << 19)
+
+#define USBHS_EP4_T_EN (1 << 4)
+#define USBHS_EP4_R_EN (1 << 20)
+
+#define USBHS_EP5_T_EN (1 << 5)
+#define USBHS_EP5_R_EN (1 << 21)
+
+#define USBHS_EP6_T_EN (1 << 6)
+#define USBHS_EP6_R_EN (1 << 22)
+
+#define USBHS_EP7_T_EN (1 << 7)
+#define USBHS_EP7_R_EN (1 << 23)
+
+#define USBHS_EP8_T_EN (1 << 8)
+#define USBHS_EP8_R_EN (1 << 24)
+
+#define USBHS_EP9_T_EN (1 << 9)
+#define USBHS_EP9_R_EN (1 << 25)
+
+#define USBHS_EP10_T_EN (1 << 10)
+#define USBHS_EP10_R_EN (1 << 26)
+
+#define USBHS_EP11_T_EN (1 << 11)
+#define USBHS_EP11_R_EN (1 << 27)
+
+#define USBHS_EP12_T_EN (1 << 12)
+#define USBHS_EP12_R_EN (1 << 28)
+
+#define USBHS_EP13_T_EN (1 << 13)
+#define USBHS_EP13_R_EN (1 << 29)
+
+#define USBHS_EP14_T_EN (1 << 14)
+#define USBHS_EP14_R_EN (1 << 30)
+
+#define USBHS_EP15_T_EN (1 << 15)
+#define USBHS_EP15_R_EN (1 << 31)
+
+//UEP_TYPE
+#define USBHS_UEP_TYPE_OFFSET 0x14
+#define USBHS_EP0_T_TYP (1 << 0)
+#define USBHS_EP0_R_TYP (1 << 16)
+
+#define USBHS_EP1_T_TYP (1 << 1)
+#define USBHS_EP1_R_TYP (1 << 17)
+
+#define USBHS_EP2_T_TYP (1 << 2)
+#define USBHS_EP2_R_TYP (1 << 18)
+
+#define USBHS_EP3_T_TYP (1 << 3)
+#define USBHS_EP3_R_TYP (1 << 19)
+
+#define USBHS_EP4_T_TYP (1 << 4)
+#define USBHS_EP4_R_TYP (1 << 20)
+
+#define USBHS_EP5_T_TYP (1 << 5)
+#define USBHS_EP5_R_TYP (1 << 21)
+
+#define USBHS_EP6_T_TYP (1 << 6)
+#define USBHS_EP6_R_TYP (1 << 22)
+
+#define USBHS_EP7_T_TYP (1 << 7)
+#define USBHS_EP7_R_TYP (1 << 23)
+
+#define USBHS_EP8_T_TYP (1 << 8)
+#define USBHS_EP8_R_TYP (1 << 24)
+
+#define USBHS_EP9_T_TYP (1 << 8)
+#define USBHS_EP9_R_TYP (1 << 25)
+
+#define USBHS_EP10_T_TYP (1 << 10)
+#define USBHS_EP10_R_TYP (1 << 26)
+
+#define USBHS_EP11_T_TYP (1 << 11)
+#define USBHS_EP11_R_TYP (1 << 27)
+
+#define USBHS_EP12_T_TYP (1 << 12)
+#define USBHS_EP12_R_TYP (1 << 28)
+
+#define USBHS_EP13_T_TYP (1 << 13)
+#define USBHS_EP13_R_TYP (1 << 29)
+
+#define USBHS_EP14_T_TYP (1 << 14)
+#define USBHS_EP14_R_TYP (1 << 30)
+
+#define USBHS_EP15_T_TYP (1 << 15)
+#define USBHS_EP15_R_TYP (1 << 31)
+
+/* BUF_MOD UEP1~15 */
+#define USBHS_BUF_MOD_OFFSET 0x18
+#define USBHS_EP0_BUF_MOD (1 << 0)
+#define USBHS_EP0_ISO_BUF_MOD (1 << 16)
+
+#define USBHS_EP1_BUF_MOD (1 << 1)
+#define USBHS_EP1_ISO_BUF_MOD (1 << 17)
+
+#define USBHS_EP2_BUF_MOD (1 << 2)
+#define USBHS_EP2_ISO_BUF_MOD (1 << 18)
+
+#define USBHS_EP3_BUF_MOD (1 << 3)
+#define USBHS_EP3_ISO_BUF_MOD (1 << 19)
+
+#define USBHS_EP4_BUF_MOD (1 << 4)
+#define USBHS_EP4_ISO_BUF_MOD (1 << 20)
+
+#define USBHS_EP5_BUF_MOD (1 << 5)
+#define USBHS_EP5_ISO_BUF_MOD (1 << 21)
+
+#define USBHS_EP6_BUF_MOD (1 << 6)
+#define USBHS_EP6_ISO_BUF_MOD (1 << 22)
+
+#define USBHS_EP7_BUF_MOD (1 << 7)
+#define USBHS_EP7_ISO_BUF_MOD (1 << 23)
+
+#define USBHS_EP8_BUF_MOD (1 << 8)
+#define USBHS_EP8_ISO_BUF_MOD (1 << 24)
+
+#define USBHS_EP9_BUF_MOD (1 << 9)
+#define USBHS_EP9_ISO_BUF_MOD (1 << 25)
+
+#define USBHS_EP10_BUF_MOD (1 << 10)
+#define USBHS_EP10_ISO_BUF_MOD (1 << 26)
+
+#define USBHS_EP11_BUF_MOD (1 << 11)
+#define USBHS_EP11_ISO_BUF_MOD (1 << 27)
+
+#define USBHS_EP12_BUF_MOD (1 << 12)
+#define USBHS_EP12_ISO_BUF_MOD (1 << 28)
+
+#define USBHS_EP13_BUF_MOD (1 << 13)
+#define USBHS_EP13_ISO_BUF_MOD (1 << 29)
+
+#define USBHS_EP14_BUF_MOD (1 << 14)
+#define USBHS_EP14_ISO_BUF_MOD (1 << 30)
+
+#define USBHS_EP15_BUF_MOD (1 << 15)
+#define USBHS_EP15_ISO_BUF_MOD (1 << 31)
+//USBHS_EPn_T_EN USBHS_EPn_R_EN USBHS_EPn_BUF_MOD 锟斤拷锟斤拷锟斤拷锟斤拷UEPn_DMA为锟斤拷始锟斤拷址锟缴碉拷锟斤拷锟斤拷锟斤拷锟�
+// 0 0 x 锟剿点被锟斤拷锟矫o拷未锟矫碉拷UEPn_*_DMA锟斤拷锟斤拷锟斤拷锟斤拷
+// 1 0 0 锟斤拷锟秸o拷OUT锟斤拷锟斤拷锟斤拷锟斤拷锟阶碉拷址为UEPn_RX_DMA
+// 1 0 1 bUEPn_RX_TOG[0]=0,使锟矫伙拷锟斤拷锟斤拷UEPn_RX_DMA锟斤拷bUEPn_RX_TOG[0]=1,使锟矫伙拷锟斤拷锟斤拷UEPn_TX_DMA
+// 0 1 0 锟斤拷锟斤拷(IN)锟斤拷锟斤拷锟斤拷锟阶碉拷址为UEPn_TX_DMA锟斤拷
+// 0 1 1 bUEPn_TX_TOG[0]=0,使锟矫伙拷锟斤拷锟斤拷UEPn_TX_DMA锟斤拷bUEPn_TX_TOG[0]=1,使锟矫伙拷锟斤拷锟斤拷UEPn_RX_DMA
+
+/* USB0_DMA */
+#define USBHS_UEP0_DMA_OFFSET(n) (0x1C) // endpoint 0 DMA buffer address
+
+/* USBX_RX_DMA */
+#define USBHS_UEPx_RX_DMA_OFFSET(n) (0x1C + 4 * (n)) // endpoint x DMA buffer address
+
+#define USBHS_UEPx_TX_DMA_OFFSET(n) (0x58 + 4 * (n)) // endpoint x DMA buffer address
+
+#define USBHS_UEPx_MAX_LEN_OFFSET(n) (0x98 + 4 * (n)) // endpoint x DMA buffer address
+
+#define USBHS_UEPx_T_LEN_OFFSET(n) (0xD8 + 4 * (n)) // endpoint x DMA buffer address
+#define USBHS_UEPx_TX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 2) // endpoint x DMA buffer address
+#define USBHS_UEPx_RX_CTRL_OFFSET(n) (0xD8 + 4 * (n) + 3) // endpoint x DMA buffer address
+
+// UEPn_T_LEN
+#define USBHS_EP_T_LEN_MASK (0x7FF)
+
+//UEPn_TX_CTRL
+#define USBHS_EP_T_RES_MASK (3 << 0)
+#define USBHS_EP_T_RES_ACK (0 << 0)
+#define USBHS_EP_T_RES_NYET (1 << 0)
+#define USBHS_EP_T_RES_NAK (2 << 0)
+#define USBHS_EP_T_RES_STALL (3 << 0)
+
+#define USBHS_EP_T_TOG_MASK (3 << 3)
+#define USBHS_EP_T_TOG_0 (0 << 3)
+#define USBHS_EP_T_TOG_1 (1 << 3)
+#define USBHS_EP_T_TOG_2 (2 << 3)
+#define USBHS_EP_T_TOG_M (3 << 3)
+
+#define USBHS_EP_T_AUTOTOG (1 << 5)
+
+//UEPn_RX_CTRL
+#define USBHS_EP_R_RES_MASK (3 << 0)
+#define USBHS_EP_R_RES_ACK (0 << 0)
+#define USBHS_EP_R_RES_NYET (1 << 0)
+#define USBHS_EP_R_RES_NAK (2 << 0)
+#define USBHS_EP_R_RES_STALL (3 << 0)
+
+#define USBHS_EP_R_TOG_MASK (3 << 3)
+#define USBHS_EP_R_TOG_0 (0 << 3)
+#define USBHS_EP_R_TOG_1 (1 << 3)
+#define USBHS_EP_R_TOG_2 (2 << 3)
+#define USBHS_EP_R_TOG_M (3 << 3)
+
+#define USBHS_EP_R_AUTOTOG (1 << 5)
+
+#define USBHS_TOG_MATCH (1 << 6)
+
+/******************* HOST ******************/
+// USB HOST_CTRL
+#define USBHS_SEND_BUS_RESET (1 << 0)
+#define USBHS_SEND_BUS_SUSPEND (1 << 1)
+#define USBHS_SEND_BUS_RESUME (1 << 2)
+#define USBHS_REMOTE_WAKE (1 << 3)
+#define USBHS_PHY_SUSPENDM (1 << 4)
+#define USBHS_UH_SOFT_FREE (1 << 6)
+#define USBHS_SEND_SOF_EN (1 << 7)
+
+//UH_CONFIG
+#define USBHS_HOST_TX_EN (1 << 3)
+#define USBHS_HOST_RX_EN (1 << 18)
+
+// HOST_EP_TYPE
+#define USBHS_ENDP_TX_ISO (1 << 3)
+#define USBHS_ENDP_RX_ISO (1 << (16 + 2))
+
+// R32_UH_EP_PID
+#define USBHS_HOST_MASK_TOKEN (0x0f)
+#define USBHS_HOST_MASK_ENDP (0x0f << 4)
+
+//R8_UH_RX_CTRL
+#define USBHS_EP_R_RES_MASK (3 << 0)
+#define USBHS_EP_R_RES_ACK (0 << 0)
+#define USBHS_EP_R_RES_NYET (1 << 0)
+#define USBHS_EP_R_RES_NAK (2 << 0)
+#define USBHS_EP_R_RES_STALL (3 << 0)
+
+#define USBHS_UH_R_RES_NO (1 << 2)
+#define USBHS_UH_R_TOG_1 (1 << 3)
+#define USBHS_UH_R_TOG_2 (2 << 3)
+#define USBHS_UH_R_TOG_3 (3 << 3)
+#define USBHS_UH_R_TOG_AUTO (1 << 5)
+#define USBHS_UH_R_DATA_NO (1 << 6)
+//R8_UH_TX_CTRL
+#define USBHS_UH_T_RES_MASK (3 << 0)
+#define USBHS_UH_T_RES_ACK (0 << 0)
+#define USBHS_UH_T_RES_NYET (1 << 0)
+#define USBHS_UH_T_RES_NAK (2 << 0)
+#define USBHS_UH_T_RES_STALL (3 << 0)
+
+#define USBHS_UH_T_RES_NO (1 << 2)
+#define USBHS_UH_T_TOG_1 (1 << 3)
+#define USBHS_UH_T_TOG_2 (2 << 3)
+#define USBHS_UH_T_TOG_3 (3 << 3)
+#define USBHS_UH_T_TOG_AUTO (1 << 5)
+#define USBHS_UH_T_DATA_NO (1 << 6)
+
+// 00: OUT, 01:SOF, 10:IN, 11:SETUP
+#define PID_OUT 0
+#define PID_SOF 1
+#define PID_IN 2
+#define PID_SETUP 3
+
+#endif
diff --git a/port/ch32/usb_dc.c b/port/ch32/usb_dc.c
deleted file mode 100644
index 26f0f813..00000000
--- a/port/ch32/usb_dc.c
+++ /dev/null
@@ -1,632 +0,0 @@
-#include "usbd_core.h"
-#include "usb_ch32_reg.h"
-
-#ifndef USB_NUM_BIDIR_ENDPOINTS
-#define USB_NUM_BIDIR_ENDPOINTS 8
-#endif
-
-/* Endpoint state */
-struct usb_dc_ep_state {
- /** Endpoint max packet size */
- uint16_t ep_mps;
- /** Endpoint Transfer Type.
- * May be Bulk, Interrupt, Control or Isochronous
- */
- uint8_t ep_type;
- uint8_t ep_stalled; /** Endpoint stall flag */
-};
-
-/* Driver state */
-struct usb_dc_config_priv {
- uint8_t dev_addr;
- struct usb_dc_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/
- struct usb_dc_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
-} usb_dc_cfg;
-
-// clang-format off
-/* Endpoint Buffer */
-__attribute__ ((aligned(4))) uint8_t EP0_DatabufHD[64]; //ep0(64)
-__attribute__ ((aligned(4))) uint8_t EP1_DatabufHD[64+64]; //ep1_out(64)+ep1_in(64)
-__attribute__ ((aligned(4))) uint8_t EP2_DatabufHD[64+64]; //ep2_out(64)+ep2_in(64)
-__attribute__ ((aligned(4))) uint8_t EP3_DatabufHD[64+64]; //ep3_out(64)+ep3_in(64)
-__attribute__ ((aligned(4))) uint8_t EP4_DatabufHD[64+64]; //ep4_out(64)+ep4_in(64)
-__attribute__ ((aligned(4))) uint8_t EP5_DatabufHD[64+64]; //ep5_out(64)+ep5_in(64)
-__attribute__ ((aligned(4))) uint8_t EP6_DatabufHD[64+64]; //ep6_out(64)+ep6_in(64)
-__attribute__ ((aligned(4))) uint8_t EP7_DatabufHD[64+64]; //ep7_out(64)+ep7_in(64)
-// clang-format on
-
-void OTG_FS_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
-
-volatile uint8_t mps_over_flag = 0;
-
-__WEAK void usb_dc_low_level_init(void)
-{
-}
-
-__WEAK void usb_dc_low_level_deinit(void)
-{
-}
-
-int usb_dc_init(void)
-{
- memset(&usb_dc_cfg, 0, sizeof(struct usb_dc_config_priv));
-
- usb_dc_low_level_init();
-
- USBOTG_FS->BASE_CTRL = 0x00;
-
- USBOTG_FS->UEP4_1_MOD = USBHD_UEP4_RX_EN | USBHD_UEP4_TX_EN | USBHD_UEP1_RX_EN | USBHD_UEP1_TX_EN;
- USBOTG_FS->UEP2_3_MOD = USBHD_UEP2_RX_EN | USBHD_UEP2_TX_EN | USBHD_UEP3_RX_EN | USBHD_UEP3_TX_EN;
- USBOTG_FS->UEP5_6_MOD = USBHD_UEP5_RX_EN | USBHD_UEP5_TX_EN | USBHD_UEP6_RX_EN | USBHD_UEP6_TX_EN;
- USBOTG_FS->UEP7_MOD = USBHD_UEP7_RX_EN | USBHD_UEP7_TX_EN;
-
- USBOTG_FS->UEP0_DMA = (uint32_t)EP0_DatabufHD;
- USBOTG_FS->UEP1_DMA = (uint32_t)EP1_DatabufHD;
- USBOTG_FS->UEP2_DMA = (uint32_t)EP2_DatabufHD;
- USBOTG_FS->UEP3_DMA = (uint32_t)EP3_DatabufHD;
- USBOTG_FS->UEP4_DMA = (uint32_t)EP4_DatabufHD;
- USBOTG_FS->UEP5_DMA = (uint32_t)EP5_DatabufHD;
- USBOTG_FS->UEP6_DMA = (uint32_t)EP6_DatabufHD;
- USBOTG_FS->UEP7_DMA = (uint32_t)EP7_DatabufHD;
-
- USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP1_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP2_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP3_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP4_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP5_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP6_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP7_RX_CTRL = USBHD_UEP_R_RES_ACK;
-
- USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP1_TX_LEN = 0;
- USBOTG_FS->UEP2_TX_LEN = 0;
- USBOTG_FS->UEP3_TX_LEN = 0;
- USBOTG_FS->UEP4_TX_LEN = 0;
- USBOTG_FS->UEP5_TX_LEN = 0;
- USBOTG_FS->UEP6_TX_LEN = 0;
- USBOTG_FS->UEP7_TX_LEN = 0;
-
- USBOTG_FS->UEP1_TX_CTRL = USBHD_UEP_T_RES_NAK | USBHD_UEP_AUTO_TOG;
- USBOTG_FS->UEP2_TX_CTRL = USBHD_UEP_T_RES_NAK | USBHD_UEP_AUTO_TOG;
- USBOTG_FS->UEP3_TX_CTRL = USBHD_UEP_T_RES_NAK | USBHD_UEP_AUTO_TOG;
- USBOTG_FS->UEP4_TX_CTRL = USBHD_UEP_T_RES_NAK | USBHD_UEP_AUTO_TOG;
- USBOTG_FS->UEP5_TX_CTRL = USBHD_UEP_T_RES_NAK | USBHD_UEP_AUTO_TOG;
- USBOTG_FS->UEP6_TX_CTRL = USBHD_UEP_T_RES_NAK | USBHD_UEP_AUTO_TOG;
- USBOTG_FS->UEP7_TX_CTRL = USBHD_UEP_T_RES_NAK | USBHD_UEP_AUTO_TOG;
-
- USBOTG_FS->INT_FG = 0xFF;
- USBOTG_FS->INT_EN = USBHD_UIE_SUSPEND | USBHD_UIE_BUS_RST | USBHD_UIE_TRANSFER;
- USBOTG_FS->DEV_ADDR = 0x00;
-
- USBOTG_FS->BASE_CTRL = USBHD_UC_DEV_PU_EN | USBHD_UC_INT_BUSY | USBHD_UC_DMA_EN;
- USBOTG_FS->UDEV_CTRL = USBHD_UD_PD_DIS | USBHD_UD_PORT_EN;
- return 0;
-}
-
-void usb_dc_deinit(void)
-{
-}
-
-int usbd_set_address(const uint8_t addr)
-{
- if (addr == 0) {
- USBOTG_FS->DEV_ADDR = (USBOTG_FS->DEV_ADDR & USBHD_UDA_GP_BIT) | 0;
- }
- usb_dc_cfg.dev_addr = addr;
- return 0;
-}
-
-int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
-{
- uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
-
- if (USB_EP_DIR_IS_OUT(ep_cfg->ep_addr)) {
- usb_dc_cfg.out_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
- usb_dc_cfg.out_ep[ep_idx].ep_type = ep_cfg->ep_type;
- } else {
- usb_dc_cfg.in_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
- usb_dc_cfg.in_ep[ep_idx].ep_type = ep_cfg->ep_type;
- }
- return 0;
-}
-int usbd_ep_close(const uint8_t ep)
-{
- return 0;
-}
-int usbd_ep_set_stall(const uint8_t ep)
-{
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
-
- if (USB_EP_DIR_IS_OUT(ep)) {
- switch (ep_idx) {
- case 0:
- USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_TOG | USBHD_UEP_R_RES_STALL;
- break;
- case 1:
- USBOTG_FS->UEP1_RX_CTRL = (USBOTG_FS->UEP1_RX_CTRL &= ~USBHD_UEP_R_RES_MASK) | USBHD_UEP_R_RES_STALL;
- break;
- case 2:
- USBOTG_FS->UEP2_RX_CTRL = (USBOTG_FS->UEP2_RX_CTRL &= ~USBHD_UEP_R_RES_MASK) | USBHD_UEP_R_RES_STALL;
- break;
- case 3:
- USBOTG_FS->UEP3_RX_CTRL = (USBOTG_FS->UEP3_RX_CTRL &= ~USBHD_UEP_R_RES_MASK) | USBHD_UEP_R_RES_STALL;
- break;
- case 4:
- USBOTG_FS->UEP4_RX_CTRL = (USBOTG_FS->UEP4_RX_CTRL &= ~USBHD_UEP_R_RES_MASK) | USBHD_UEP_R_RES_STALL;
- break;
- case 5:
- USBOTG_FS->UEP5_RX_CTRL = (USBOTG_FS->UEP5_RX_CTRL &= ~USBHD_UEP_R_RES_MASK) | USBHD_UEP_R_RES_STALL;
- break;
- case 6:
- USBOTG_FS->UEP6_RX_CTRL = (USBOTG_FS->UEP6_RX_CTRL &= ~USBHD_UEP_R_RES_MASK) | USBHD_UEP_R_RES_STALL;
- break;
- case 7:
- USBOTG_FS->UEP7_RX_CTRL = (USBOTG_FS->UEP7_RX_CTRL &= ~USBHD_UEP_R_RES_MASK) | USBHD_UEP_R_RES_STALL;
- break;
- default:
- break;
- }
-
- } else {
- switch (ep_idx) {
- case 0:
- USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_TOG | USBHD_UEP_T_RES_STALL;
- break;
- case 1:
- USBOTG_FS->UEP1_TX_CTRL = (USBOTG_FS->UEP1_TX_CTRL &= ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_STALL;
- break;
- case 2:
- USBOTG_FS->UEP2_TX_CTRL = (USBOTG_FS->UEP2_TX_CTRL &= ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_STALL;
- break;
- case 3:
- USBOTG_FS->UEP3_TX_CTRL = (USBOTG_FS->UEP3_TX_CTRL &= ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_STALL;
- break;
- case 4:
- USBOTG_FS->UEP4_TX_CTRL = (USBOTG_FS->UEP4_TX_CTRL &= ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_STALL;
- break;
- case 5:
- USBOTG_FS->UEP5_TX_CTRL = (USBOTG_FS->UEP5_TX_CTRL &= ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_STALL;
- break;
- case 6:
- USBOTG_FS->UEP6_TX_CTRL = (USBOTG_FS->UEP6_TX_CTRL &= ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_STALL;
- break;
- case 7:
- USBOTG_FS->UEP7_TX_CTRL = (USBOTG_FS->UEP7_TX_CTRL &= ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_STALL;
- break;
- default:
- break;
- }
- }
-
- return 0;
-}
-
-int usbd_ep_clear_stall(const uint8_t ep)
-{
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
-
- if (USB_EP_DIR_IS_OUT(ep)) {
- switch (ep_idx) {
- case 0:
-
- break;
- case 1:
- USBOTG_FS->UEP1_RX_CTRL = (USBOTG_FS->UEP1_RX_CTRL & ~(USBHD_UEP_R_TOG | USBHD_UEP_R_RES_MASK)) | USBHD_UEP_R_RES_ACK;
- break;
- case 2:
- USBOTG_FS->UEP2_RX_CTRL = (USBOTG_FS->UEP2_RX_CTRL & ~(USBHD_UEP_R_TOG | USBHD_UEP_R_RES_MASK)) | USBHD_UEP_R_RES_ACK;
- break;
- case 3:
- USBOTG_FS->UEP3_RX_CTRL = (USBOTG_FS->UEP3_RX_CTRL & ~(USBHD_UEP_R_TOG | USBHD_UEP_R_RES_MASK)) | USBHD_UEP_R_RES_ACK;
- break;
- case 4:
- USBOTG_FS->UEP4_RX_CTRL = (USBOTG_FS->UEP4_RX_CTRL & ~(USBHD_UEP_R_TOG | USBHD_UEP_R_RES_MASK)) | USBHD_UEP_R_RES_ACK;
- break;
- case 5:
- USBOTG_FS->UEP5_RX_CTRL = (USBOTG_FS->UEP5_RX_CTRL & ~(USBHD_UEP_R_TOG | USBHD_UEP_R_RES_MASK)) | USBHD_UEP_R_RES_ACK;
- break;
- case 6:
- USBOTG_FS->UEP6_RX_CTRL = (USBOTG_FS->UEP6_RX_CTRL & ~(USBHD_UEP_R_TOG | USBHD_UEP_R_RES_MASK)) | USBHD_UEP_R_RES_ACK;
- break;
- case 7:
- USBOTG_FS->UEP7_RX_CTRL = (USBOTG_FS->UEP7_RX_CTRL & ~(USBHD_UEP_R_TOG | USBHD_UEP_R_RES_MASK)) | USBHD_UEP_R_RES_ACK;
- break;
- default:
- break;
- }
-
- } else {
- switch (ep_idx) {
- case 0:
-
- break;
- case 1:
- USBOTG_FS->UEP1_TX_CTRL = (USBOTG_FS->UEP1_TX_CTRL & ~(USBHD_UEP_T_TOG | USBHD_UEP_T_RES_MASK)) | USBHD_UEP_T_RES_NAK;
- break;
- case 2:
- USBOTG_FS->UEP2_TX_CTRL = (USBOTG_FS->UEP2_TX_CTRL & ~(USBHD_UEP_T_TOG | USBHD_UEP_T_RES_MASK)) | USBHD_UEP_T_RES_NAK;
- break;
- case 3:
- USBOTG_FS->UEP3_TX_CTRL = (USBOTG_FS->UEP3_TX_CTRL & ~(USBHD_UEP_T_TOG | USBHD_UEP_T_RES_MASK)) | USBHD_UEP_T_RES_NAK;
- break;
- case 4:
- USBOTG_FS->UEP4_TX_CTRL = (USBOTG_FS->UEP4_TX_CTRL & ~(USBHD_UEP_T_TOG | USBHD_UEP_T_RES_MASK)) | USBHD_UEP_T_RES_NAK;
- break;
- case 5:
- USBOTG_FS->UEP5_TX_CTRL = (USBOTG_FS->UEP5_TX_CTRL & ~(USBHD_UEP_T_TOG | USBHD_UEP_T_RES_MASK)) | USBHD_UEP_T_RES_NAK;
- break;
- case 6:
- USBOTG_FS->UEP6_TX_CTRL = (USBOTG_FS->UEP6_TX_CTRL & ~(USBHD_UEP_T_TOG | USBHD_UEP_T_RES_MASK)) | USBHD_UEP_T_RES_NAK;
- break;
- case 7:
- USBOTG_FS->UEP7_TX_CTRL = (USBOTG_FS->UEP7_TX_CTRL & ~(USBHD_UEP_T_TOG | USBHD_UEP_T_RES_MASK)) | USBHD_UEP_T_RES_NAK;
- break;
- default:
- break;
- }
- }
- return 0;
-}
-int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
-{
- return 0;
-}
-
-int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *ret_bytes)
-{
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
-
- if (!data && data_len) {
- return -1;
- }
-
- if (!data_len) {
- switch (ep_idx) {
- case 0:
- USBOTG_FS->UEP0_TX_LEN = 0;
- break;
- case 1:
- USBOTG_FS->UEP1_TX_LEN = 0;
- USBOTG_FS->UEP1_TX_CTRL = (USBOTG_FS->UEP1_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 2:
- USBOTG_FS->UEP2_TX_LEN = 0;
- USBOTG_FS->UEP2_TX_CTRL = (USBOTG_FS->UEP2_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 3:
- USBOTG_FS->UEP3_TX_LEN = 0;
- USBOTG_FS->UEP3_TX_CTRL = (USBOTG_FS->UEP3_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 4:
- USBOTG_FS->UEP4_TX_LEN = 0;
- USBOTG_FS->UEP4_TX_CTRL = (USBOTG_FS->UEP4_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 5:
- USBOTG_FS->UEP5_TX_LEN = 0;
- USBOTG_FS->UEP5_TX_CTRL = (USBOTG_FS->UEP5_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 6:
- USBOTG_FS->UEP6_TX_LEN = 0;
- USBOTG_FS->UEP6_TX_CTRL = (USBOTG_FS->UEP6_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 7:
- USBOTG_FS->UEP7_TX_LEN = 0;
- USBOTG_FS->UEP7_TX_CTRL = (USBOTG_FS->UEP7_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- default:
- break;
- }
-
- return 0;
- }
-
- if (data_len > usb_dc_cfg.in_ep[ep_idx].ep_mps) {
- data_len = usb_dc_cfg.in_ep[ep_idx].ep_mps;
-
- if (ep_idx == 0) {
- mps_over_flag = 1;
- }
- }
-
- switch (ep_idx) {
- case 0:
- memcpy(&EP0_DatabufHD[0], data, data_len);
- USBOTG_FS->UEP0_TX_LEN = data_len;
- break;
- case 1:
- memcpy(&EP1_DatabufHD[64], data, data_len);
- USBOTG_FS->UEP1_TX_LEN = data_len;
- USBOTG_FS->UEP1_TX_CTRL = (USBOTG_FS->UEP1_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 2:
- memcpy(&EP2_DatabufHD[64], data, data_len);
- USBOTG_FS->UEP2_TX_LEN = data_len;
- USBOTG_FS->UEP2_TX_CTRL = (USBOTG_FS->UEP2_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 3:
- memcpy(&EP3_DatabufHD[64], data, data_len);
- USBOTG_FS->UEP3_TX_LEN = data_len;
- USBOTG_FS->UEP3_TX_CTRL = (USBOTG_FS->UEP3_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 4:
- memcpy(&EP4_DatabufHD[64], data, data_len);
- USBOTG_FS->UEP4_TX_LEN = data_len;
- USBOTG_FS->UEP4_TX_CTRL = (USBOTG_FS->UEP4_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 5:
- memcpy(&EP5_DatabufHD[64], data, data_len);
- USBOTG_FS->UEP5_TX_LEN = data_len;
- USBOTG_FS->UEP5_TX_CTRL = (USBOTG_FS->UEP5_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 6:
- memcpy(&EP6_DatabufHD[64], data, data_len);
- USBOTG_FS->UEP6_TX_LEN = data_len;
- USBOTG_FS->UEP6_TX_CTRL = (USBOTG_FS->UEP6_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- case 7:
- memcpy(&EP7_DatabufHD[64], data, data_len);
- USBOTG_FS->UEP7_TX_LEN = data_len;
- USBOTG_FS->UEP7_TX_CTRL = (USBOTG_FS->UEP7_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_ACK;
- break;
- default:
- break;
- }
-
- if (ret_bytes) {
- *ret_bytes = data_len;
- }
-
- return 0;
-}
-
-int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *read_bytes)
-{
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
- uint32_t read_count;
-
- if (!data && max_data_len) {
- return -1;
- }
-
- if (!max_data_len) {
- return 0;
- }
-
- read_count = USBOTG_FS->RX_LEN;
- read_count = MIN(read_count, max_data_len);
-
- switch (ep_idx) {
- case 0:
- if ((max_data_len == 8) && !read_bytes) {
- read_count = 8;
- memcpy(data, &EP0_DatabufHD[0], 8);
- } else {
- memcpy(data, &EP0_DatabufHD[0], read_count);
- }
- break;
- case 1:
- memcpy(data, &EP1_DatabufHD[0], read_count);
- break;
- case 2:
- memcpy(data, &EP2_DatabufHD[0], read_count);
- break;
- case 3:
- memcpy(data, &EP3_DatabufHD[0], read_count);
- break;
- case 4:
- memcpy(data, &EP4_DatabufHD[0], read_count);
- break;
- case 5:
- memcpy(data, &EP5_DatabufHD[0], read_count);
- break;
- case 6:
- memcpy(data, &EP6_DatabufHD[0], read_count);
- break;
- case 7:
- memcpy(data, &EP7_DatabufHD[0], read_count);
- break;
- default:
- break;
- }
-
- if (read_bytes) {
- *read_bytes = read_count;
- }
-
- return 0;
-}
-
-/*********************************************************************
- * @fn OTG_FS_IRQHandler
- *
- * @brief This function handles OTG_FS exception.
- *
- * @return none
- */
-void OTG_FS_IRQHandler(void)
-{
- uint8_t intflag = 0;
-
- intflag = USBOTG_FS->INT_FG;
-
- if (intflag & USBHD_UIF_TRANSFER) {
- switch (USBOTG_FS->INT_ST & USBHD_UIS_TOKEN_MASK) {
- case USBHD_UIS_TOKEN_SETUP:
- USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_TOG | USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_TOG | USBHD_UEP_R_RES_ACK;
-
- usbd_event_notify_handler(USBD_EVENT_SETUP_NOTIFY, NULL);
-
- USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_TOG | USBHD_UEP_T_RES_ACK;
- USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_TOG | USBHD_UEP_R_RES_ACK;
- break;
-
- case USBHD_UIS_TOKEN_IN:
- switch (USBOTG_FS->INT_ST & (USBHD_UIS_TOKEN_MASK | USBHD_UIS_ENDP_MASK)) {
- case USBHD_UIS_TOKEN_IN:
-
- usbd_event_notify_handler(USBD_EVENT_EP0_IN_NOTIFY, NULL);
- if (usb_dc_cfg.dev_addr > 0) {
- USBOTG_FS->DEV_ADDR = (USBOTG_FS->DEV_ADDR & USBHD_UDA_GP_BIT) | usb_dc_cfg.dev_addr;
- usb_dc_cfg.dev_addr = 0;
- }
-
- if (mps_over_flag) {
- mps_over_flag = 0;
- USBOTG_FS->UEP0_TX_CTRL ^= USBHD_UEP_T_TOG;
- } else {
- USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_RES_ACK;
- }
- break;
-
- case USBHD_UIS_TOKEN_IN | 1:
- USBOTG_FS->UEP1_TX_CTRL = (USBOTG_FS->UEP1_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP1_TX_CTRL ^= USBHD_UEP_T_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(1 | 0x80));
- break;
-
- case USBHD_UIS_TOKEN_IN | 2:
- USBOTG_FS->UEP2_TX_CTRL = (USBOTG_FS->UEP2_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP2_TX_CTRL ^= USBHD_UEP_T_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(2 | 0x80));
- break;
-
- case USBHD_UIS_TOKEN_IN | 3:
- USBOTG_FS->UEP3_TX_CTRL = (USBOTG_FS->UEP3_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP3_TX_CTRL ^= USBHD_UEP_T_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(3 | 0x80));
- break;
-
- case USBHD_UIS_TOKEN_IN | 4:
- USBOTG_FS->UEP4_TX_CTRL = (USBOTG_FS->UEP4_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP4_TX_CTRL ^= USBHD_UEP_T_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(4 | 0x80));
- break;
-
- case USBHD_UIS_TOKEN_IN | 5:
- USBOTG_FS->UEP5_TX_CTRL = (USBOTG_FS->UEP5_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP5_TX_CTRL ^= USBHD_UEP_T_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(5 | 0x80));
- break;
-
- case USBHD_UIS_TOKEN_IN | 6:
- USBOTG_FS->UEP6_TX_CTRL = (USBOTG_FS->UEP6_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP6_TX_CTRL ^= USBHD_UEP_T_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(6 | 0x80));
- break;
-
- case USBHD_UIS_TOKEN_IN | 7:
- USBOTG_FS->UEP7_TX_CTRL = (USBOTG_FS->UEP7_TX_CTRL & ~USBHD_UEP_T_RES_MASK) | USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP7_TX_CTRL ^= USBHD_UEP_T_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(7 | 0x80));
- break;
-
- default:
- break;
- }
- break;
-
- case USBHD_UIS_TOKEN_OUT:
- switch (USBOTG_FS->INT_ST & (USBHD_UIS_TOKEN_MASK | USBHD_UIS_ENDP_MASK)) {
- case USBHD_UIS_TOKEN_OUT:
- usbd_event_notify_handler(USBD_EVENT_EP0_OUT_NOTIFY, NULL);
- break;
-
- case USBHD_UIS_TOKEN_OUT | 1:
- if (USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK) {
- USBOTG_FS->UEP1_RX_CTRL ^= USBHD_UEP_R_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(1 & 0x7f));
- }
- break;
-
- case USBHD_UIS_TOKEN_OUT | 2:
- if (USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK) {
- USBOTG_FS->UEP2_RX_CTRL ^= USBHD_UEP_R_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(2 & 0x7f));
- }
- break;
-
- case USBHD_UIS_TOKEN_OUT | 3:
- if (USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK) {
- USBOTG_FS->UEP3_RX_CTRL ^= USBHD_UEP_R_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(3 & 0x7f));
- }
- break;
-
- case USBHD_UIS_TOKEN_OUT | 4:
- if (USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK) {
- USBOTG_FS->UEP4_RX_CTRL ^= USBHD_UEP_R_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(4 & 0x7f));
- }
- break;
-
- case USBHD_UIS_TOKEN_OUT | 5:
- if (USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK) {
- USBOTG_FS->UEP5_RX_CTRL ^= USBHD_UEP_R_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(5 & 0x7f));
- }
- break;
-
- case USBHD_UIS_TOKEN_OUT | 6:
- if (USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK) {
- USBOTG_FS->UEP6_RX_CTRL ^= USBHD_UEP_R_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(6 & 0x7f));
- }
- break;
-
- case USBHD_UIS_TOKEN_OUT | 7:
- if (USBOTG_FS->INT_ST & USBHD_UIS_TOG_OK) {
- USBOTG_FS->UEP7_RX_CTRL ^= USBHD_UEP_R_TOG;
- usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(7 & 0x7f));
- }
- break;
- }
-
- break;
-
- case USBHD_UIS_TOKEN_SOF:
-
- break;
-
- default:
- break;
- }
-
- USBOTG_FS->INT_FG = USBHD_UIF_TRANSFER;
- } else if (intflag & USBHD_UIF_BUS_RST) {
- USBOTG_FS->DEV_ADDR = 0;
-
- USBOTG_FS->UEP0_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP1_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP2_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP3_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP4_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP5_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP6_RX_CTRL = USBHD_UEP_R_RES_ACK;
- USBOTG_FS->UEP7_RX_CTRL = USBHD_UEP_R_RES_ACK;
-
- USBOTG_FS->UEP0_TX_CTRL = USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP1_TX_CTRL = USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP2_TX_CTRL = USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP3_TX_CTRL = USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP4_TX_CTRL = USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP5_TX_CTRL = USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP6_TX_CTRL = USBHD_UEP_T_RES_NAK;
- USBOTG_FS->UEP7_TX_CTRL = USBHD_UEP_T_RES_NAK;
-
- usbd_event_notify_handler(USBD_EVENT_RESET, NULL);
-
- USBOTG_FS->INT_FG |= USBHD_UIF_BUS_RST;
- } else if (intflag & USBHD_UIF_SUSPEND) {
- if (USBOTG_FS->MIS_ST & USBHD_UMS_SUSPEND) {
- ;
- } else {
- ;
- }
- USBOTG_FS->INT_FG = USBHD_UIF_SUSPEND;
- } else {
- USBOTG_FS->INT_FG = intflag;
- }
-}
diff --git a/port/ch32/usb_dc_usbfs.c b/port/ch32/usb_dc_usbfs.c
new file mode 100644
index 00000000..63840d6b
--- /dev/null
+++ b/port/ch32/usb_dc_usbfs.c
@@ -0,0 +1,632 @@
+#include "usbd_core.h"
+#include "usb_ch32_usbfs_reg.h"
+
+#ifndef USB_NUM_BIDIR_ENDPOINTS
+#define USB_NUM_BIDIR_ENDPOINTS 8
+#endif
+
+/* Endpoint state */
+struct usb_dc_ep_state {
+ /** Endpoint max packet size */
+ uint16_t ep_mps;
+ /** Endpoint Transfer Type.
+ * May be Bulk, Interrupt, Control or Isochronous
+ */
+ uint8_t ep_type;
+ uint8_t ep_stalled; /** Endpoint stall flag */
+};
+
+/* Driver state */
+struct usb_dc_config_priv {
+ uint8_t dev_addr;
+ struct usb_dc_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/
+ struct usb_dc_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
+} usb_dc_cfg;
+
+// clang-format off
+/* Endpoint Buffer */
+__attribute__ ((aligned(4))) uint8_t EP0_DatabufHD[64]; //ep0(64)
+__attribute__ ((aligned(4))) uint8_t EP1_DatabufHD[64+64]; //ep1_out(64)+ep1_in(64)
+__attribute__ ((aligned(4))) uint8_t EP2_DatabufHD[64+64]; //ep2_out(64)+ep2_in(64)
+__attribute__ ((aligned(4))) uint8_t EP3_DatabufHD[64+64]; //ep3_out(64)+ep3_in(64)
+__attribute__ ((aligned(4))) uint8_t EP4_DatabufHD[64+64]; //ep4_out(64)+ep4_in(64)
+__attribute__ ((aligned(4))) uint8_t EP5_DatabufHD[64+64]; //ep5_out(64)+ep5_in(64)
+__attribute__ ((aligned(4))) uint8_t EP6_DatabufHD[64+64]; //ep6_out(64)+ep6_in(64)
+__attribute__ ((aligned(4))) uint8_t EP7_DatabufHD[64+64]; //ep7_out(64)+ep7_in(64)
+// clang-format on
+
+void OTG_FS_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+
+volatile uint8_t mps_over_flag = 0;
+
+__WEAK void usb_dc_low_level_init(void)
+{
+}
+
+__WEAK void usb_dc_low_level_deinit(void)
+{
+}
+
+int usb_dc_init(void)
+{
+ memset(&usb_dc_cfg, 0, sizeof(struct usb_dc_config_priv));
+
+ usb_dc_low_level_init();
+
+ USBFS_DEVICE->BASE_CTRL = 0x00;
+
+ USBFS_DEVICE->UEP4_1_MOD = USBFS_UEP4_RX_EN | USBFS_UEP4_TX_EN | USBFS_UEP1_RX_EN | USBFS_UEP1_TX_EN;
+ USBFS_DEVICE->UEP2_3_MOD = USBFS_UEP2_RX_EN | USBFS_UEP2_TX_EN | USBFS_UEP3_RX_EN | USBFS_UEP3_TX_EN;
+ USBFS_DEVICE->UEP5_6_MOD = USBFS_UEP5_RX_EN | USBFS_UEP5_TX_EN | USBFS_UEP6_RX_EN | USBFS_UEP6_TX_EN;
+ USBFS_DEVICE->UEP7_MOD = USBFS_UEP7_RX_EN | USBFS_UEP7_TX_EN;
+
+ USBFS_DEVICE->UEP0_DMA = (uint32_t)EP0_DatabufHD;
+ USBFS_DEVICE->UEP1_DMA = (uint32_t)EP1_DatabufHD;
+ USBFS_DEVICE->UEP2_DMA = (uint32_t)EP2_DatabufHD;
+ USBFS_DEVICE->UEP3_DMA = (uint32_t)EP3_DatabufHD;
+ USBFS_DEVICE->UEP4_DMA = (uint32_t)EP4_DatabufHD;
+ USBFS_DEVICE->UEP5_DMA = (uint32_t)EP5_DatabufHD;
+ USBFS_DEVICE->UEP6_DMA = (uint32_t)EP6_DatabufHD;
+ USBFS_DEVICE->UEP7_DMA = (uint32_t)EP7_DatabufHD;
+
+ USBFS_DEVICE->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP1_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP2_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP3_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP4_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP5_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP6_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP7_RX_CTRL = USBFS_UEP_R_RES_ACK;
+
+ USBFS_DEVICE->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP1_TX_LEN = 0;
+ USBFS_DEVICE->UEP2_TX_LEN = 0;
+ USBFS_DEVICE->UEP3_TX_LEN = 0;
+ USBFS_DEVICE->UEP4_TX_LEN = 0;
+ USBFS_DEVICE->UEP5_TX_LEN = 0;
+ USBFS_DEVICE->UEP6_TX_LEN = 0;
+ USBFS_DEVICE->UEP7_TX_LEN = 0;
+
+ USBFS_DEVICE->UEP1_TX_CTRL = USBFS_UEP_T_RES_NAK | USBFS_UEP_AUTO_TOG;
+ USBFS_DEVICE->UEP2_TX_CTRL = USBFS_UEP_T_RES_NAK | USBFS_UEP_AUTO_TOG;
+ USBFS_DEVICE->UEP3_TX_CTRL = USBFS_UEP_T_RES_NAK | USBFS_UEP_AUTO_TOG;
+ USBFS_DEVICE->UEP4_TX_CTRL = USBFS_UEP_T_RES_NAK | USBFS_UEP_AUTO_TOG;
+ USBFS_DEVICE->UEP5_TX_CTRL = USBFS_UEP_T_RES_NAK | USBFS_UEP_AUTO_TOG;
+ USBFS_DEVICE->UEP6_TX_CTRL = USBFS_UEP_T_RES_NAK | USBFS_UEP_AUTO_TOG;
+ USBFS_DEVICE->UEP7_TX_CTRL = USBFS_UEP_T_RES_NAK | USBFS_UEP_AUTO_TOG;
+
+ USBFS_DEVICE->INT_FG = 0xFF;
+ USBFS_DEVICE->INT_EN = USBFS_UIE_SUSPEND | USBFS_UIE_BUS_RST | USBFS_UIE_TRANSFER;
+ USBFS_DEVICE->DEV_ADDR = 0x00;
+
+ USBFS_DEVICE->BASE_CTRL = USBFS_UC_DEV_PU_EN | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN;
+ USBFS_DEVICE->UDEV_CTRL = USBFS_UD_PD_DIS | USBFS_UD_PORT_EN;
+ return 0;
+}
+
+void usb_dc_deinit(void)
+{
+}
+
+int usbd_set_address(const uint8_t addr)
+{
+ if (addr == 0) {
+ USBFS_DEVICE->DEV_ADDR = (USBFS_DEVICE->DEV_ADDR & USBFS_UDA_GP_BIT) | 0;
+ }
+ usb_dc_cfg.dev_addr = addr;
+ return 0;
+}
+
+int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
+
+ if (USB_EP_DIR_IS_OUT(ep_cfg->ep_addr)) {
+ usb_dc_cfg.out_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
+ usb_dc_cfg.out_ep[ep_idx].ep_type = ep_cfg->ep_type;
+ } else {
+ usb_dc_cfg.in_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
+ usb_dc_cfg.in_ep[ep_idx].ep_type = ep_cfg->ep_type;
+ }
+ return 0;
+}
+int usbd_ep_close(const uint8_t ep)
+{
+ return 0;
+}
+int usbd_ep_set_stall(const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ switch (ep_idx) {
+ case 0:
+ USBFS_DEVICE->UEP0_RX_CTRL = USBFS_UEP_R_TOG | USBFS_UEP_R_RES_STALL;
+ break;
+ case 1:
+ USBFS_DEVICE->UEP1_RX_CTRL = (USBFS_DEVICE->UEP1_RX_CTRL &= ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_STALL;
+ break;
+ case 2:
+ USBFS_DEVICE->UEP2_RX_CTRL = (USBFS_DEVICE->UEP2_RX_CTRL &= ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_STALL;
+ break;
+ case 3:
+ USBFS_DEVICE->UEP3_RX_CTRL = (USBFS_DEVICE->UEP3_RX_CTRL &= ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_STALL;
+ break;
+ case 4:
+ USBFS_DEVICE->UEP4_RX_CTRL = (USBFS_DEVICE->UEP4_RX_CTRL &= ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_STALL;
+ break;
+ case 5:
+ USBFS_DEVICE->UEP5_RX_CTRL = (USBFS_DEVICE->UEP5_RX_CTRL &= ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_STALL;
+ break;
+ case 6:
+ USBFS_DEVICE->UEP6_RX_CTRL = (USBFS_DEVICE->UEP6_RX_CTRL &= ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_STALL;
+ break;
+ case 7:
+ USBFS_DEVICE->UEP7_RX_CTRL = (USBFS_DEVICE->UEP7_RX_CTRL &= ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_STALL;
+ break;
+ default:
+ break;
+ }
+
+ } else {
+ switch (ep_idx) {
+ case 0:
+ USBFS_DEVICE->UEP0_TX_CTRL = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_STALL;
+ break;
+ case 1:
+ USBFS_DEVICE->UEP1_TX_CTRL = (USBFS_DEVICE->UEP1_TX_CTRL &= ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_STALL;
+ break;
+ case 2:
+ USBFS_DEVICE->UEP2_TX_CTRL = (USBFS_DEVICE->UEP2_TX_CTRL &= ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_STALL;
+ break;
+ case 3:
+ USBFS_DEVICE->UEP3_TX_CTRL = (USBFS_DEVICE->UEP3_TX_CTRL &= ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_STALL;
+ break;
+ case 4:
+ USBFS_DEVICE->UEP4_TX_CTRL = (USBFS_DEVICE->UEP4_TX_CTRL &= ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_STALL;
+ break;
+ case 5:
+ USBFS_DEVICE->UEP5_TX_CTRL = (USBFS_DEVICE->UEP5_TX_CTRL &= ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_STALL;
+ break;
+ case 6:
+ USBFS_DEVICE->UEP6_TX_CTRL = (USBFS_DEVICE->UEP6_TX_CTRL &= ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_STALL;
+ break;
+ case 7:
+ USBFS_DEVICE->UEP7_TX_CTRL = (USBFS_DEVICE->UEP7_TX_CTRL &= ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_STALL;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int usbd_ep_clear_stall(const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ switch (ep_idx) {
+ case 0:
+
+ break;
+ case 1:
+ USBFS_DEVICE->UEP1_RX_CTRL = (USBFS_DEVICE->UEP1_RX_CTRL & ~(USBFS_UEP_R_TOG | USBFS_UEP_R_RES_MASK)) | USBFS_UEP_R_RES_ACK;
+ break;
+ case 2:
+ USBFS_DEVICE->UEP2_RX_CTRL = (USBFS_DEVICE->UEP2_RX_CTRL & ~(USBFS_UEP_R_TOG | USBFS_UEP_R_RES_MASK)) | USBFS_UEP_R_RES_ACK;
+ break;
+ case 3:
+ USBFS_DEVICE->UEP3_RX_CTRL = (USBFS_DEVICE->UEP3_RX_CTRL & ~(USBFS_UEP_R_TOG | USBFS_UEP_R_RES_MASK)) | USBFS_UEP_R_RES_ACK;
+ break;
+ case 4:
+ USBFS_DEVICE->UEP4_RX_CTRL = (USBFS_DEVICE->UEP4_RX_CTRL & ~(USBFS_UEP_R_TOG | USBFS_UEP_R_RES_MASK)) | USBFS_UEP_R_RES_ACK;
+ break;
+ case 5:
+ USBFS_DEVICE->UEP5_RX_CTRL = (USBFS_DEVICE->UEP5_RX_CTRL & ~(USBFS_UEP_R_TOG | USBFS_UEP_R_RES_MASK)) | USBFS_UEP_R_RES_ACK;
+ break;
+ case 6:
+ USBFS_DEVICE->UEP6_RX_CTRL = (USBFS_DEVICE->UEP6_RX_CTRL & ~(USBFS_UEP_R_TOG | USBFS_UEP_R_RES_MASK)) | USBFS_UEP_R_RES_ACK;
+ break;
+ case 7:
+ USBFS_DEVICE->UEP7_RX_CTRL = (USBFS_DEVICE->UEP7_RX_CTRL & ~(USBFS_UEP_R_TOG | USBFS_UEP_R_RES_MASK)) | USBFS_UEP_R_RES_ACK;
+ break;
+ default:
+ break;
+ }
+
+ } else {
+ switch (ep_idx) {
+ case 0:
+
+ break;
+ case 1:
+ USBFS_DEVICE->UEP1_TX_CTRL = (USBFS_DEVICE->UEP1_TX_CTRL & ~(USBFS_UEP_T_TOG | USBFS_UEP_T_RES_MASK)) | USBFS_UEP_T_RES_NAK;
+ break;
+ case 2:
+ USBFS_DEVICE->UEP2_TX_CTRL = (USBFS_DEVICE->UEP2_TX_CTRL & ~(USBFS_UEP_T_TOG | USBFS_UEP_T_RES_MASK)) | USBFS_UEP_T_RES_NAK;
+ break;
+ case 3:
+ USBFS_DEVICE->UEP3_TX_CTRL = (USBFS_DEVICE->UEP3_TX_CTRL & ~(USBFS_UEP_T_TOG | USBFS_UEP_T_RES_MASK)) | USBFS_UEP_T_RES_NAK;
+ break;
+ case 4:
+ USBFS_DEVICE->UEP4_TX_CTRL = (USBFS_DEVICE->UEP4_TX_CTRL & ~(USBFS_UEP_T_TOG | USBFS_UEP_T_RES_MASK)) | USBFS_UEP_T_RES_NAK;
+ break;
+ case 5:
+ USBFS_DEVICE->UEP5_TX_CTRL = (USBFS_DEVICE->UEP5_TX_CTRL & ~(USBFS_UEP_T_TOG | USBFS_UEP_T_RES_MASK)) | USBFS_UEP_T_RES_NAK;
+ break;
+ case 6:
+ USBFS_DEVICE->UEP6_TX_CTRL = (USBFS_DEVICE->UEP6_TX_CTRL & ~(USBFS_UEP_T_TOG | USBFS_UEP_T_RES_MASK)) | USBFS_UEP_T_RES_NAK;
+ break;
+ case 7:
+ USBFS_DEVICE->UEP7_TX_CTRL = (USBFS_DEVICE->UEP7_TX_CTRL & ~(USBFS_UEP_T_TOG | USBFS_UEP_T_RES_MASK)) | USBFS_UEP_T_RES_NAK;
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
+{
+ return 0;
+}
+
+int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *ret_bytes)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (!data && data_len) {
+ return -1;
+ }
+
+ if (!data_len) {
+ switch (ep_idx) {
+ case 0:
+ USBFS_DEVICE->UEP0_TX_LEN = 0;
+ break;
+ case 1:
+ USBFS_DEVICE->UEP1_TX_LEN = 0;
+ USBFS_DEVICE->UEP1_TX_CTRL = (USBFS_DEVICE->UEP1_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 2:
+ USBFS_DEVICE->UEP2_TX_LEN = 0;
+ USBFS_DEVICE->UEP2_TX_CTRL = (USBFS_DEVICE->UEP2_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 3:
+ USBFS_DEVICE->UEP3_TX_LEN = 0;
+ USBFS_DEVICE->UEP3_TX_CTRL = (USBFS_DEVICE->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 4:
+ USBFS_DEVICE->UEP4_TX_LEN = 0;
+ USBFS_DEVICE->UEP4_TX_CTRL = (USBFS_DEVICE->UEP4_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 5:
+ USBFS_DEVICE->UEP5_TX_LEN = 0;
+ USBFS_DEVICE->UEP5_TX_CTRL = (USBFS_DEVICE->UEP5_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 6:
+ USBFS_DEVICE->UEP6_TX_LEN = 0;
+ USBFS_DEVICE->UEP6_TX_CTRL = (USBFS_DEVICE->UEP6_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 7:
+ USBFS_DEVICE->UEP7_TX_LEN = 0;
+ USBFS_DEVICE->UEP7_TX_CTRL = (USBFS_DEVICE->UEP7_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
+ if (data_len > usb_dc_cfg.in_ep[ep_idx].ep_mps) {
+ data_len = usb_dc_cfg.in_ep[ep_idx].ep_mps;
+
+ if (ep_idx == 0) {
+ mps_over_flag = 1;
+ }
+ }
+
+ switch (ep_idx) {
+ case 0:
+ memcpy(&EP0_DatabufHD[0], data, data_len);
+ USBFS_DEVICE->UEP0_TX_LEN = data_len;
+ break;
+ case 1:
+ memcpy(&EP1_DatabufHD[64], data, data_len);
+ USBFS_DEVICE->UEP1_TX_LEN = data_len;
+ USBFS_DEVICE->UEP1_TX_CTRL = (USBFS_DEVICE->UEP1_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 2:
+ memcpy(&EP2_DatabufHD[64], data, data_len);
+ USBFS_DEVICE->UEP2_TX_LEN = data_len;
+ USBFS_DEVICE->UEP2_TX_CTRL = (USBFS_DEVICE->UEP2_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 3:
+ memcpy(&EP3_DatabufHD[64], data, data_len);
+ USBFS_DEVICE->UEP3_TX_LEN = data_len;
+ USBFS_DEVICE->UEP3_TX_CTRL = (USBFS_DEVICE->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 4:
+ memcpy(&EP4_DatabufHD[64], data, data_len);
+ USBFS_DEVICE->UEP4_TX_LEN = data_len;
+ USBFS_DEVICE->UEP4_TX_CTRL = (USBFS_DEVICE->UEP4_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 5:
+ memcpy(&EP5_DatabufHD[64], data, data_len);
+ USBFS_DEVICE->UEP5_TX_LEN = data_len;
+ USBFS_DEVICE->UEP5_TX_CTRL = (USBFS_DEVICE->UEP5_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 6:
+ memcpy(&EP6_DatabufHD[64], data, data_len);
+ USBFS_DEVICE->UEP6_TX_LEN = data_len;
+ USBFS_DEVICE->UEP6_TX_CTRL = (USBFS_DEVICE->UEP6_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ case 7:
+ memcpy(&EP7_DatabufHD[64], data, data_len);
+ USBFS_DEVICE->UEP7_TX_LEN = data_len;
+ USBFS_DEVICE->UEP7_TX_CTRL = (USBFS_DEVICE->UEP7_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK;
+ break;
+ default:
+ break;
+ }
+
+ if (ret_bytes) {
+ *ret_bytes = data_len;
+ }
+
+ return 0;
+}
+
+int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *read_bytes)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ uint32_t read_count;
+
+ if (!data && max_data_len) {
+ return -1;
+ }
+
+ if (!max_data_len) {
+ return 0;
+ }
+
+ read_count = USBFS_DEVICE->RX_LEN;
+ read_count = MIN(read_count, max_data_len);
+
+ switch (ep_idx) {
+ case 0:
+ if ((max_data_len == 8) && !read_bytes) {
+ read_count = 8;
+ memcpy(data, &EP0_DatabufHD[0], 8);
+ } else {
+ memcpy(data, &EP0_DatabufHD[0], read_count);
+ }
+ break;
+ case 1:
+ memcpy(data, &EP1_DatabufHD[0], read_count);
+ break;
+ case 2:
+ memcpy(data, &EP2_DatabufHD[0], read_count);
+ break;
+ case 3:
+ memcpy(data, &EP3_DatabufHD[0], read_count);
+ break;
+ case 4:
+ memcpy(data, &EP4_DatabufHD[0], read_count);
+ break;
+ case 5:
+ memcpy(data, &EP5_DatabufHD[0], read_count);
+ break;
+ case 6:
+ memcpy(data, &EP6_DatabufHD[0], read_count);
+ break;
+ case 7:
+ memcpy(data, &EP7_DatabufHD[0], read_count);
+ break;
+ default:
+ break;
+ }
+
+ if (read_bytes) {
+ *read_bytes = read_count;
+ }
+
+ return 0;
+}
+
+/*********************************************************************
+ * @fn OTG_FS_IRQHandler
+ *
+ * @brief This function handles OTG_FS exception.
+ *
+ * @return none
+ */
+void OTG_FS_IRQHandler(void)
+{
+ uint8_t intflag = 0;
+
+ intflag = USBFS_DEVICE->INT_FG;
+
+ if (intflag & USBFS_UIF_TRANSFER) {
+ switch (USBFS_DEVICE->INT_ST & USBFS_UIS_TOKEN_MASK) {
+ case USBFS_UIS_TOKEN_SETUP:
+ USBFS_DEVICE->UEP0_TX_CTRL = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP0_RX_CTRL = USBFS_UEP_R_TOG | USBFS_UEP_R_RES_ACK;
+
+ usbd_event_notify_handler(USBD_EVENT_SETUP_NOTIFY, NULL);
+
+ USBFS_DEVICE->UEP0_TX_CTRL = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK;
+ USBFS_DEVICE->UEP0_RX_CTRL = USBFS_UEP_R_TOG | USBFS_UEP_R_RES_ACK;
+ break;
+
+ case USBFS_UIS_TOKEN_IN:
+ switch (USBFS_DEVICE->INT_ST & (USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK)) {
+ case USBFS_UIS_TOKEN_IN:
+
+ usbd_event_notify_handler(USBD_EVENT_EP0_IN_NOTIFY, NULL);
+ if (usb_dc_cfg.dev_addr > 0) {
+ USBFS_DEVICE->DEV_ADDR = (USBFS_DEVICE->DEV_ADDR & USBFS_UDA_GP_BIT) | usb_dc_cfg.dev_addr;
+ usb_dc_cfg.dev_addr = 0;
+ }
+
+ if (mps_over_flag) {
+ mps_over_flag = 0;
+ USBFS_DEVICE->UEP0_TX_CTRL ^= USBFS_UEP_T_TOG;
+ } else {
+ USBFS_DEVICE->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ }
+ break;
+
+ case USBFS_UIS_TOKEN_IN | 1:
+ USBFS_DEVICE->UEP1_TX_CTRL = (USBFS_DEVICE->UEP1_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP1_TX_CTRL ^= USBFS_UEP_T_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(1 | 0x80));
+ break;
+
+ case USBFS_UIS_TOKEN_IN | 2:
+ USBFS_DEVICE->UEP2_TX_CTRL = (USBFS_DEVICE->UEP2_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP2_TX_CTRL ^= USBFS_UEP_T_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(2 | 0x80));
+ break;
+
+ case USBFS_UIS_TOKEN_IN | 3:
+ USBFS_DEVICE->UEP3_TX_CTRL = (USBFS_DEVICE->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP3_TX_CTRL ^= USBFS_UEP_T_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(3 | 0x80));
+ break;
+
+ case USBFS_UIS_TOKEN_IN | 4:
+ USBFS_DEVICE->UEP4_TX_CTRL = (USBFS_DEVICE->UEP4_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP4_TX_CTRL ^= USBFS_UEP_T_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(4 | 0x80));
+ break;
+
+ case USBFS_UIS_TOKEN_IN | 5:
+ USBFS_DEVICE->UEP5_TX_CTRL = (USBFS_DEVICE->UEP5_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP5_TX_CTRL ^= USBFS_UEP_T_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(5 | 0x80));
+ break;
+
+ case USBFS_UIS_TOKEN_IN | 6:
+ USBFS_DEVICE->UEP6_TX_CTRL = (USBFS_DEVICE->UEP6_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP6_TX_CTRL ^= USBFS_UEP_T_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(6 | 0x80));
+ break;
+
+ case USBFS_UIS_TOKEN_IN | 7:
+ USBFS_DEVICE->UEP7_TX_CTRL = (USBFS_DEVICE->UEP7_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP7_TX_CTRL ^= USBFS_UEP_T_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(7 | 0x80));
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case USBFS_UIS_TOKEN_OUT:
+ switch (USBFS_DEVICE->INT_ST & (USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK)) {
+ case USBFS_UIS_TOKEN_OUT:
+ usbd_event_notify_handler(USBD_EVENT_EP0_OUT_NOTIFY, NULL);
+ break;
+
+ case USBFS_UIS_TOKEN_OUT | 1:
+ if (USBFS_DEVICE->INT_ST & USBFS_UIS_TOG_OK) {
+ USBFS_DEVICE->UEP1_RX_CTRL ^= USBFS_UEP_R_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(1 & 0x7f));
+ }
+ break;
+
+ case USBFS_UIS_TOKEN_OUT | 2:
+ if (USBFS_DEVICE->INT_ST & USBFS_UIS_TOG_OK) {
+ USBFS_DEVICE->UEP2_RX_CTRL ^= USBFS_UEP_R_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(2 & 0x7f));
+ }
+ break;
+
+ case USBFS_UIS_TOKEN_OUT | 3:
+ if (USBFS_DEVICE->INT_ST & USBFS_UIS_TOG_OK) {
+ USBFS_DEVICE->UEP3_RX_CTRL ^= USBFS_UEP_R_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(3 & 0x7f));
+ }
+ break;
+
+ case USBFS_UIS_TOKEN_OUT | 4:
+ if (USBFS_DEVICE->INT_ST & USBFS_UIS_TOG_OK) {
+ USBFS_DEVICE->UEP4_RX_CTRL ^= USBFS_UEP_R_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(4 & 0x7f));
+ }
+ break;
+
+ case USBFS_UIS_TOKEN_OUT | 5:
+ if (USBFS_DEVICE->INT_ST & USBFS_UIS_TOG_OK) {
+ USBFS_DEVICE->UEP5_RX_CTRL ^= USBFS_UEP_R_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(5 & 0x7f));
+ }
+ break;
+
+ case USBFS_UIS_TOKEN_OUT | 6:
+ if (USBFS_DEVICE->INT_ST & USBFS_UIS_TOG_OK) {
+ USBFS_DEVICE->UEP6_RX_CTRL ^= USBFS_UEP_R_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(6 & 0x7f));
+ }
+ break;
+
+ case USBFS_UIS_TOKEN_OUT | 7:
+ if (USBFS_DEVICE->INT_ST & USBFS_UIS_TOG_OK) {
+ USBFS_DEVICE->UEP7_RX_CTRL ^= USBFS_UEP_R_TOG;
+ usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(7 & 0x7f));
+ }
+ break;
+ }
+
+ break;
+
+ case USBFS_UIS_TOKEN_SOF:
+
+ break;
+
+ default:
+ break;
+ }
+
+ USBFS_DEVICE->INT_FG = USBFS_UIF_TRANSFER;
+ } else if (intflag & USBFS_UIF_BUS_RST) {
+ USBFS_DEVICE->DEV_ADDR = 0;
+
+ USBFS_DEVICE->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP1_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP2_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP3_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP4_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP5_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP6_RX_CTRL = USBFS_UEP_R_RES_ACK;
+ USBFS_DEVICE->UEP7_RX_CTRL = USBFS_UEP_R_RES_ACK;
+
+ USBFS_DEVICE->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP1_TX_CTRL = USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP2_TX_CTRL = USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP3_TX_CTRL = USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP4_TX_CTRL = USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP5_TX_CTRL = USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP6_TX_CTRL = USBFS_UEP_T_RES_NAK;
+ USBFS_DEVICE->UEP7_TX_CTRL = USBFS_UEP_T_RES_NAK;
+
+ usbd_event_notify_handler(USBD_EVENT_RESET, NULL);
+
+ USBFS_DEVICE->INT_FG |= USBFS_UIF_BUS_RST;
+ } else if (intflag & USBFS_UIF_SUSPEND) {
+ if (USBFS_DEVICE->MIS_ST & USBFS_UMS_SUSPEND) {
+ ;
+ } else {
+ ;
+ }
+ USBFS_DEVICE->INT_FG = USBFS_UIF_SUSPEND;
+ } else {
+ USBFS_DEVICE->INT_FG = intflag;
+ }
+}
diff --git a/port/ch32/usb_dc_usbhs.c b/port/ch32/usb_dc_usbhs.c
new file mode 100644
index 00000000..1a3a85a2
--- /dev/null
+++ b/port/ch32/usb_dc_usbhs.c
@@ -0,0 +1,432 @@
+#include "usbd_core.h"
+#include "usb_ch32_usbhs_reg.h"
+
+#ifndef USB_NUM_BIDIR_ENDPOINTS
+#define USB_NUM_BIDIR_ENDPOINTS 8
+#endif
+
+/* Endpoint state */
+struct usb_dc_ep_state {
+ /** Endpoint max packet size */
+ uint16_t ep_mps;
+ /** Endpoint Transfer Type.
+ * May be Bulk, Interrupt, Control or Isochronous
+ */
+ uint8_t ep_type;
+ uint8_t ep_stalled; /** Endpoint stall flag */
+};
+
+/* Driver state */
+struct usb_dc_config_priv {
+ uint8_t dev_addr;
+ struct usb_dc_ep_state in_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< IN endpoint parameters*/
+ struct usb_dc_ep_state out_ep[USB_NUM_BIDIR_ENDPOINTS]; /*!< OUT endpoint parameters */
+} usb_dc_cfg;
+
+// clang-format off
+/* Endpoint Buffer */
+__attribute__ ((aligned(4))) uint8_t EP0_DatabufHD[64]; //ep0(64)
+__attribute__ ((aligned(4))) uint8_t EP1_DatabufHD[512+512]; //ep1_out(64)+ep1_in(64)
+__attribute__ ((aligned(4))) uint8_t EP2_DatabufHD[512+512]; //ep2_out(64)+ep2_in(64)
+// clang-format on
+
+void USBHS_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
+
+volatile uint8_t mps_over_flag = 0;
+volatile uint8_t USBHS_Dev_Endp0_Tog = 0x01; /* USB2.0�����豸�˵�0ͬ����־ */
+
+__WEAK void usb_dc_low_level_init(void)
+{
+}
+
+__WEAK void usb_dc_low_level_deinit(void)
+{
+}
+
+int usb_dc_init(void)
+{
+ memset(&usb_dc_cfg, 0, sizeof(struct usb_dc_config_priv));
+
+ usb_dc_low_level_init();
+
+ USBHS_DEVICE->HOST_CTRL = 0x00;
+ USBHS_DEVICE->HOST_CTRL = USBHS_SUSPEND_EN;
+
+ USBHS_DEVICE->CONTROL = 0;
+#if 1
+ USBHS_DEVICE->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED;
+#else
+ USBHS_DEVICE->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED;
+#endif
+
+ USBHS_DEVICE->INT_EN = 0;
+ USBHS_DEVICE->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN;
+
+ /* ALL endpoint enable */
+ USBHS_DEVICE->ENDP_CONFIG = 0xffffffff;
+
+ USBHS_DEVICE->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN | USBHS_EP1_T_EN | USBHS_EP2_T_EN | USBHS_EP1_R_EN | USBHS_EP2_R_EN;
+ USBHS_DEVICE->ENDP_TYPE = 0x00;
+ USBHS_DEVICE->BUF_MODE = 0x00;
+
+ USBHS_DEVICE->UEP0_MAX_LEN = 64;
+ USBHS_DEVICE->UEP1_MAX_LEN = 512;
+ USBHS_DEVICE->UEP2_MAX_LEN = 512;
+ USBHS_DEVICE->UEP3_MAX_LEN = 512;
+ USBHS_DEVICE->UEP4_MAX_LEN = 512;
+ USBHS_DEVICE->UEP5_MAX_LEN = 512;
+ USBHS_DEVICE->UEP6_MAX_LEN = 512;
+ USBHS_DEVICE->UEP7_MAX_LEN = 512;
+ USBHS_DEVICE->UEP8_MAX_LEN = 512;
+ USBHS_DEVICE->UEP9_MAX_LEN = 512;
+ USBHS_DEVICE->UEP10_MAX_LEN = 512;
+ USBHS_DEVICE->UEP11_MAX_LEN = 512;
+ USBHS_DEVICE->UEP12_MAX_LEN = 512;
+ USBHS_DEVICE->UEP13_MAX_LEN = 512;
+ USBHS_DEVICE->UEP14_MAX_LEN = 512;
+ USBHS_DEVICE->UEP15_MAX_LEN = 512;
+
+ USBHS_DEVICE->UEP0_DMA = (uint32_t)EP0_DatabufHD;
+ USBHS_DEVICE->UEP1_TX_DMA = (uint32_t)&EP1_DatabufHD[512];
+ USBHS_DEVICE->UEP1_RX_DMA = (uint32_t)&EP1_DatabufHD[0];
+ USBHS_DEVICE->UEP2_TX_DMA = (uint32_t)&EP2_DatabufHD[512];
+ USBHS_DEVICE->UEP2_RX_DMA = (uint32_t)&EP2_DatabufHD[0];
+
+ USBHS_DEVICE->UEP0_TX_LEN = 0;
+ USBHS_DEVICE->UEP0_TX_CTRL = USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP1_TX_LEN = 0;
+ USBHS_DEVICE->UEP1_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP1_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP2_TX_LEN = 0;
+ USBHS_DEVICE->UEP2_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP2_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP3_TX_LEN = 0;
+ USBHS_DEVICE->UEP3_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP3_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP4_TX_LEN = 0;
+ USBHS_DEVICE->UEP4_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP4_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP5_TX_LEN = 0;
+ USBHS_DEVICE->UEP5_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP5_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP6_TX_LEN = 0;
+ USBHS_DEVICE->UEP6_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP6_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP7_TX_LEN = 0;
+ USBHS_DEVICE->UEP7_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP7_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP8_TX_LEN = 0;
+ USBHS_DEVICE->UEP8_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP8_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP9_TX_LEN = 0;
+ USBHS_DEVICE->UEP9_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP9_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP10_TX_LEN = 0;
+ USBHS_DEVICE->UEP10_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP10_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP11_TX_LEN = 0;
+ USBHS_DEVICE->UEP11_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP11_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP12_TX_LEN = 0;
+ USBHS_DEVICE->UEP12_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP12_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP13_TX_LEN = 0;
+ USBHS_DEVICE->UEP13_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP13_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP14_TX_LEN = 0;
+ USBHS_DEVICE->UEP14_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP14_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->UEP15_TX_LEN = 0;
+ USBHS_DEVICE->UEP15_TX_CTRL = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
+ USBHS_DEVICE->UEP15_RX_CTRL = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK;
+
+ USBHS_DEVICE->CONTROL |= USBHS_DEV_PU_EN;
+
+ return 0;
+}
+
+void usb_dc_deinit(void)
+{
+}
+
+int usbd_set_address(const uint8_t addr)
+{
+ if (addr == 0) {
+ USBHS_DEVICE->DEV_AD = addr & 0xff;
+ }
+ usb_dc_cfg.dev_addr = addr;
+ return 0;
+}
+
+int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
+
+ if (USB_EP_DIR_IS_OUT(ep_cfg->ep_addr)) {
+ usb_dc_cfg.out_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
+ usb_dc_cfg.out_ep[ep_idx].ep_type = ep_cfg->ep_type;
+ } else {
+ usb_dc_cfg.in_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
+ usb_dc_cfg.in_ep[ep_idx].ep_type = ep_cfg->ep_type;
+ }
+ return 0;
+}
+int usbd_ep_close(const uint8_t ep)
+{
+ return 0;
+}
+int usbd_ep_set_stall(const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ switch (ep_idx) {
+ case 0:
+ USBHS_DEVICE->UEP0_RX_CTRL = USBHS_EP_R_RES_STALL;
+ break;
+ case 1:
+ USBHS_DEVICE->UEP1_RX_CTRL = (USBHS_DEVICE->UEP1_RX_CTRL & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_STALL;
+ break;
+ case 2:
+ USBHS_DEVICE->UEP2_RX_CTRL = (USBHS_DEVICE->UEP2_RX_CTRL & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_STALL;
+ break;
+ default:
+ break;
+ }
+
+ } else {
+ switch (ep_idx) {
+ case 0:
+ USBHS_DEVICE->UEP0_TX_LEN = 0;
+ USBHS_DEVICE->UEP0_TX_CTRL = USBHS_EP_T_RES_STALL;
+ break;
+ case 1:
+ USBHS_DEVICE->UEP1_TX_CTRL = (USBHS_DEVICE->UEP1_TX_CTRL & ~USBHS_EP_T_RES_MASK) | USBHS_EP_T_RES_STALL;
+ break;
+ case 2:
+ USBHS_DEVICE->UEP2_TX_CTRL = (USBHS_DEVICE->UEP2_TX_CTRL & ~USBHS_EP_T_RES_MASK) | USBHS_EP_T_RES_STALL;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int usbd_ep_clear_stall(const uint8_t ep)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (USB_EP_DIR_IS_OUT(ep)) {
+ switch (ep_idx) {
+ case 0:
+
+ break;
+ case 1:
+ /* SET Endp1 Rx to USBHS_EP_R_RES_NAK;USBHS_EP_R_TOG_0 */
+ USBHS_DEVICE->UEP1_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0;
+ break;
+ case 2:
+ /* SET Endp2 Rx to USBHS_EP_R_RES_ACK;USBHS_EP_R_TOG_0 */
+ USBHS_DEVICE->UEP2_TX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0;
+ break;
+ default:
+ break;
+ }
+
+ } else {
+ switch (ep_idx) {
+ case 0:
+
+ break;
+ case 1:
+ /* SET Endp1 Tx to USBHS_EP_T_RES_NAK;USBHS_EP_T_TOG_0;len = 0 */
+ USBHS_DEVICE->UEP1_TX_LEN = 0;
+ USBHS_DEVICE->UEP1_TX_CTRL = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0;
+ break;
+ case 2:
+ /* SET Endp2 Tx to USBHS_EP_T_RES_NAK;USBHS_EP_T_TOG_0;len = 0 */
+ USBHS_DEVICE->UEP2_TX_LEN = 0;
+ USBHS_DEVICE->UEP2_TX_CTRL = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0;
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+}
+int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
+{
+ return 0;
+}
+
+int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *ret_bytes)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+
+ if (!data && data_len) {
+ return -1;
+ }
+
+ if (!data_len) {
+ switch (ep_idx) {
+ case 0:
+ USBHS_DEVICE->UEP0_TX_LEN = 0;
+ USBHS_DEVICE->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | USBHS_EP_T_TOG_1;
+ break;
+ case 1:
+ USBHS_DEVICE->UEP1_TX_LEN = 0;
+ break;
+ case 2:
+ USBHS_DEVICE->UEP2_TX_LEN = 0;
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+ }
+
+ if (data_len > usb_dc_cfg.in_ep[ep_idx].ep_mps) {
+ data_len = usb_dc_cfg.in_ep[ep_idx].ep_mps;
+ }
+
+ switch (ep_idx) {
+ case 0:
+ memcpy(&EP0_DatabufHD[0], data, data_len);
+ USBHS_DEVICE->UEP0_TX_LEN = data_len;
+ USBHS_DEVICE->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_0 : USBHS_EP_T_TOG_1);
+ USBHS_Dev_Endp0_Tog ^= 1;
+ break;
+ case 1:
+ memcpy(&EP1_DatabufHD[512], data, data_len);
+ USBHS_DEVICE->UEP1_TX_LEN = data_len;
+ USBHS_DEVICE->UEP1_TX_CTRL = (USBHS_DEVICE->UEP1_TX_CTRL & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_LEN_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_ACK;
+ //USBHS_DEVICE->UEP1_TX_CTRL |= ( USBHS_Endp1_T_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0 );
+ break;
+ case 2:
+ memcpy(&EP2_DatabufHD[512], data, data_len);
+ USBHS_DEVICE->UEP2_TX_LEN = data_len;
+ USBHS_DEVICE->UEP2_TX_CTRL = (USBHS_DEVICE->UEP2_TX_CTRL & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_LEN_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_ACK;
+ //USBHS_DEVICE->UEP2_TX_CTRL |= ( USBHS_Endp2_T_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0 );
+ break;
+ default:
+ break;
+ }
+
+ if (ret_bytes) {
+ *ret_bytes = data_len;
+ }
+
+ return 0;
+}
+
+int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *read_bytes)
+{
+ uint8_t ep_idx = USB_EP_GET_IDX(ep);
+ uint32_t read_count;
+
+ if (!data && max_data_len) {
+ return -1;
+ }
+
+ if (!max_data_len) {
+ return 0;
+ }
+
+ read_count = USBHS_DEVICE->RX_LEN;
+ read_count = MIN(read_count, max_data_len);
+
+ switch (ep_idx) {
+ case 0:
+ if ((max_data_len == 8) && !read_bytes) {
+ read_count = 8;
+ memcpy(data, &EP0_DatabufHD[0], 8);
+ } else {
+ memcpy(data, &EP0_DatabufHD[0], read_count);
+ }
+ break;
+ case 1:
+ memcpy(data, &EP1_DatabufHD[0], read_count);
+ break;
+ case 2:
+ memcpy(data, &EP2_DatabufHD[0], read_count);
+ break;
+ default:
+ break;
+ }
+
+ if (read_bytes) {
+ *read_bytes = read_count;
+ }
+
+ return 0;
+}
+
+/*********************************************************************
+ * @fn USBHS_IRQHandler
+ *
+ * @brief This function handles OTG_FS exception.
+ *
+ * @return none
+ */
+void USBHS_IRQHandler(void)
+{
+ uint32_t end_num, rx_token;
+ uint8_t intflag = 0;
+
+ intflag = USBHS_DEVICE->INT_FG;
+
+ if (intflag & USBHS_TRANSFER_FLAG) {
+ end_num = (USBHS_DEVICE->INT_ST) & MASK_UIS_ENDP;
+ rx_token = (((USBHS_DEVICE->INT_ST) & MASK_UIS_TOKEN) >> 4) & 0x03;
+ if (end_num == 0) {
+ if (rx_token == PID_IN) {
+ usbd_event_notify_handler(USBD_EVENT_EP0_IN_NOTIFY, NULL);
+ if (usb_dc_cfg.dev_addr > 0) {
+ USBHS_DEVICE->DEV_AD = usb_dc_cfg.dev_addr & 0xff;
+ usb_dc_cfg.dev_addr = 0;
+ }
+ } else if (rx_token == PID_OUT) {
+ usbd_event_notify_handler(USBD_EVENT_EP0_OUT_NOTIFY, NULL);
+ USBHS_DEVICE->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_1;
+ }
+ } else if (end_num == 1) {
+ if (rx_token == PID_IN) {
+ //USBHS_Endp1_Up_Flag = 0x00;
+ /* Ĭ�ϻ�NAK */
+ USBHS_DEVICE->UEP1_TX_CTRL = (USBHS_DEVICE->UEP1_TX_CTRL & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0;
+ } else if (rx_token == PID_OUT) {
+ }
+ } else if (end_num == 2) {
+ if (rx_token == PID_IN) {
+ } else if (rx_token == PID_OUT) {
+ }
+ }
+ USBHS_DEVICE->INT_FG = USBHS_TRANSFER_FLAG;
+ } else if (intflag & USBHS_SETUP_FLAG) {
+ usbd_event_notify_handler(USBD_EVENT_SETUP_NOTIFY, NULL);
+ USBHS_DEVICE->INT_FG = USBHS_SETUP_FLAG;
+ } else if (intflag & USBHS_DETECT_FLAG) {
+ usbd_event_notify_handler(USBD_EVENT_RESET, NULL);
+ USBHS_DEVICE->INT_FG = USBHS_DETECT_FLAG;
+ }
+ printf("reset\r\n");
+}