[bsp/phytium] add xhci and pusb2 support with cherryusb port (#8355)

合入基于 CherryUSB 的 XCHI 和 PUSB2 驱动
This commit is contained in:
zhugengyu 2023-12-08 20:01:34 +08:00 committed by GitHub
parent 32342c6995
commit e843561e46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 729 additions and 6 deletions

View File

@ -1,4 +1,3 @@
# PHYTIUM BSP 说明
## 简介
@ -185,4 +184,4 @@ tftp> q
## 维护人信息
- huanghe: huanghe@phytium.com.cn
- zhugengyu: zhugengyu@phytium.com.cn
- zhugengyu: zhugengyu@phytium.com.cn

View File

@ -57,10 +57,12 @@ def install_phytium_sdk():
if os.path.exists(install_script_path):
subprocess.call(["rm","-rf", install_script_path])
try:
subprocess.call(["wget", "https://gitee.com/phytium_embedded/phytium-standalone-sdk/raw/Standalone-Sdk_RT-thread/phytium_standalone_sdk_install.py"])
except:
print("Please refer to the ./README and manual download phytium_standalone_sdk_install.py, place in current folder")
if not os.path.exists(install_script_path):
try:
subprocess.call(["wget", "https://gitee.com/phytium_embedded/phytium-standalone-sdk/raw/Standalone-Sdk_RT-thread/phytium_standalone_sdk_install.py"])
except:
print("Please refer to the ./README and manual download phytium_standalone_sdk_install.py, place in current folder")
if os.path.exists(install_script_path):
try:
subprocess.call(["python", install_script_path])

View File

@ -0,0 +1,131 @@
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
SECTIONS
{
_text_offset = 0x80000;
. = 0x80000000 + _text_offset;
.text :
{
PROVIDE(__text_start = .);
KEEP(*(.text.entrypoint))
*(.vectors)
*(.text)
*(.text.*)
*(.rodata)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.gnu.linkonce.t*)
. = ALIGN(8);
PROVIDE(__rt_utest_tc_tab_start = .);
KEEP(*(UtestTcTab))
PROVIDE(__rt_utest_tc_tab_end = .);
. = ALIGN(8);
PROVIDE(__fsymtab_start = .);
KEEP(*(FSymTab))
PROVIDE(__fsymtab_end = .);
. = ALIGN(8);
PROVIDE(__vsymtab_start = .);
KEEP(*(VSymTab))
PROVIDE(__vsymtab_end = .);
. = ALIGN(8);
. = ALIGN(8);
PROVIDE(__rtmsymtab_start = .);
KEEP(*(RTMSymTab))
PROVIDE(__rtmsymtab_end = .);
. = ALIGN(8);
PROVIDE(__rt_init_start = .);
KEEP(*(SORT(.rti_fn*)))
PROVIDE(__rt_init_end = .);
. = ALIGN(16);
PROVIDE(__rt_ofw_data_start = .);
KEEP(*(SORT(.rt_ofw_data.*)))
PROVIDE(__rt_ofw_data_end = .);
. = ALIGN(16);
PROVIDE(__text_end = .);
}
.eh_frame_hdr :
{
*(.eh_frame_hdr)
*(.eh_frame_entry)
}
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
. = ALIGN(8);
.data :
{
*(.data)
*(.data.*)
*(.data1)
*(.data1.*)
. = ALIGN(16);
_gp = ABSOLUTE(.);
*(.sdata)
*(.sdata.*)
*(.rel.local)
}
. = ALIGN(8);
.cherryusb (ALIGN(64)):
{
/* section information for usbh class */
__usbh_class_info_start__ = .;
KEEP(*(.usbh_class_info))
__usbh_class_info_end__ = .;
}
. = ALIGN(8);
.ctors :
{
PROVIDE(__ctors_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE(__ctors_end = .);
}
.dtors :
{
PROVIDE(__dtors_start = .);
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
PROVIDE(__dtors_end = .);
}
. = ALIGN(16);
.bss :
{
PROVIDE(__bss_noclean_start = .);
*(.bss.noclean.*)
PROVIDE(__bss_noclean_end = .);
. = ALIGN(8);
PROVIDE(__bss_start = .);
*(.bss)
*(.bss.*)
*(.dynbss)
*(COMMON)
. = ALIGN(8);
PROVIDE(__bss_end = .);
}
_end = .;
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
__data_size = SIZEOF(.data);
__bss_size = SIZEOF(.bss);
}

View File

@ -0,0 +1,108 @@
# CherryUSB 的使用
- CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的 USB 主从协议栈
- Phytium 系列 CPU 相关 BSP 通过 CherryUSB 支持下列功能
- 1. USB 主机XHCI, 可以识别 U 盘/鼠标/键盘等设备,但是设备需要插在主机侧的 USB 插槽上,暂不支持通过 HUB 扩展连接设备
- 2. USB 主机 (PUSB2), 可以识别 U 盘/鼠标/键盘等设备
- 3. USB 从机 (PUSB2), 可以将开发板作为一个 USB 设备U 盘)运行,连接 Windows/Ubuntu 等主机进行识别和访问
> 目前只在 AARCH64 RT-Thread 模式下测试过AARCH32 使用需要做少量修改RT-Smart 下使用需要修改链接脚本,增加虚拟内存空间适配
## 通过 Package 使用 CherryUSB
- 进入 bsp 目录下的 aarch64 或者 aarch32 目录,然后 scons --menuconfig 进入 Kconfig 配置界面,选择 `Enable usb host mode` -> `XHCI`,最后选中需要的主机侧设备驱动
![](../figures/cherryusb.png)
- 保存配置后,更新 Packages
```
source ~/.env/env.sh
pkgs --update
```
- 对于 XHCI, 相关的配置包括
![](../figures/cherryusb_xhci.png)
```
#define PKG_USING_CHERRYUSB
#define PKG_CHERRYUSB_HOST
#define PKG_CHERRYUSB_HOST_XHCI
#define PKG_CHERRYUSB_HOST_HID
#define PKG_CHERRYUSB_HOST_MSC
#define PKG_CHERRYUSB_HOST_TEMPLATE
#define PKG_USING_CHERRYUSB_LATEST_VERSION
```
- 对于 PUSB2相关的配置包括
![](../figures/pusb2_cherryusb.png)
- 主机模式
```
#define PKG_USING_CHERRYUSB
#define PKG_CHERRYUSB_HOST
#define PKG_CHERRYUSB_HOST_PUSB2
#define PKG_CHERRYUSB_HOST_HID
#define PKG_CHERRYUSB_HOST_MSC
#define PKG_CHERRYUSB_HOST_TEMPLATE
```
- 从机模式
```
#define PKG_USING_CHERRYUSB
#define PKG_CHERRYUSB_DEVICE
#define PKG_CHERRYUSB_DEVICE_FS
#define PKG_CHERRYUSB_DEVICE_PUSB2
#define PKG_CHERRYUSB_DEVICE_MSC
#define PKG_CHERRYUSB_DEVICE_MSC_STORAGE_TEMPLATE
#define PKG_USING_CHERRYUSB_LATEST_VERSION
```
- 更新成功后会出现目录 aarch64/packages/CherryUSB-latest
- 随后进行编译即可
## 测试 CherryUSB 功能
### USB3 (XHCI)
> CherryUSB 更新比较频繁,稳定使用 XHCI 功能可以使用最后一次变更功能的 commit 号
```
cd packages
rm ./CherryUSB-latest/ -rf
git clone https://github.com/cherry-embedded/CherryUSB.git ./CherryUSB-latest
cd ./CherryUSB-latest
git checkout aeffaea016f74cb5d6301b5ca5088c03e3dbe3a6
```
- 将 U 盘插入到 USB3 0 号控制器,然后输入命令 `usbh_initialize` 开始枚举设备
- 枚举完成后输入 `lsusb -t` 查看识别到的设备
![](../figures/xhci_0.png)
- 参考 CherryUSB 中的 demo 使用 USB 设备
### USB2 (PUSB2 主机模式)
> PUSB2 驱动欢迎联系 `opensource_embedded@phytium.com.cn` 获取
- 将 U 盘插入到 USB2 0 号控制器,然后输入命令 `usbh_initialize` 开始枚举设备
- 枚举完成后输入 `lsusb -t` 查看识别到的设备
![](../figures/pusb2_hid.png)
- 参考 CherryUSB 中的 demo 使用 USB 设备
### USB2 (PUSB2 从机模式)
> PUSB2 驱动欢迎联系 `opensource_embedded@phytium.com.cn` 获取
- 通过 USB 线连接开发板和主机 Windows 主机),然后输入命令 `msc_storage_init` 创建一个 USB 设备,等待连接的主机完成识别
> 在 RT-Thread 中,可以将 SD/eMMC 介质映射成一个 U 盘给上位机访问,上位机格式化 U 盘文件系统,可以将数据保存在 SD/eMMC 介质中
![](../figures/cherryusb_device.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@ -141,6 +141,22 @@ path += [cwd + '/port/fboard_port']
src += Glob(cwd+'/port/lwip_port/*.c')
path += [cwd + '/port/lwip_port']
## lwip port
src += Glob(cwd+'/port/lwip_port/*.c')
path += [cwd + '/port/lwip_port']
## cherryusb port
if GetDepend(['BSP_USING_XHCI']):
src += Glob(cwd +'/port/cherryusb_port/drv_xhci.c')
path += [cwd + '/port/cherryusb_port']
if GetDepend(['BSP_USING_PUSB2']):
if GetDepend(['PKG_CHERRYUSB_HOST_PUSB2']):
src += Glob(cwd +'/port/cherryusb_port/drv_pusb2_hc.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_PUSB2']):
src += Glob(cwd +'/port/cherryusb_port/drv_pusb2_dc.c')
path += [cwd + '/port/cherryusb_port']
# phytium ports rt-thread examples
PORT_DRV_DIR = cwd + '/examples'

View File

@ -249,6 +249,28 @@ menu "On-chip Peripheral Drivers"
endchoice
endif
menuconfig BSP_USING_XHCI
bool "Enable USB3.0(XHCI)"
default n
select PKG_USING_CHERRYUSB
if BSP_USING_XHCI
config RT_USING_XHCI0
bool "Enable xhci0"
default y if BSP_USING_XHCI
endif
menuconfig BSP_USING_PUSB2
bool "Enable USB2.0(PUSB2)"
default n
select PKG_USING_CHERRYUSB
if BSP_USING_PUSB2
config RT_USING_PUSB20
bool "Enable pusb20"
default y if BSP_USING_PUSB2
endif
endmenu
menu "Board extended module Drivers"

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Email: opensource_embedded@phytium.com.cn
*
* Change Logs:
* Date Author Notes
* 2023-11-14 zhugengyu first version
*
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <rtdbg.h>
#if defined(BSP_USING_PUSB2) && defined(PKG_CHERRYUSB_DEVICE_PUSB2)
#include "board.h"
#include "interrupt.h"
#include "mm_aspace.h"
#ifdef RT_USING_SMART
#include "ioremap.h"
#endif
#include "usbd_core.h"
#include "fcpu_info.h"
struct usb_pusb2_config
{
rt_uint32_t id;
rt_ubase_t base_addr; /* virtual address */
rt_uint32_t irq;
rt_uint32_t irq_priority;
};
static struct usb_pusb2_config pusb2_config[1U] =
{
[FUSB2_ID_VHUB_0] =
{
.id = FUSB2_ID_VHUB_0,
.base_addr = FUSB2_0_VHUB_BASE_ADDR,
.irq = FUSB2_0_VHUB_IRQ_NUM,
.irq_priority = 0xd0,
},
};
/* cherry usb support unique instance yet */
#define PUSB2_DEVICE_ID FUSB2_ID_VHUB_0
extern void USBD_IRQHandler(void *);
static void usb_pusb2_interrupt_handler(rt_int32_t vector, void *args)
{
/* args not in use */
USBD_IRQHandler(args);
}
static void usb_pusb2_setup_interrupt(struct usb_pusb2_config *config)
{
RT_ASSERT(config);
rt_uint32_t irq_num = config->irq;
rt_uint32_t irq_priority = config->irq_priority;
rt_uint32_t cpu_id = 0;
GetCpuId((u32 *)&cpu_id);
rt_hw_interrupt_set_target_cpus(irq_num, cpu_id);
rt_hw_interrupt_set_priority(irq_num, irq_priority);
rt_hw_interrupt_install(irq_num, usb_pusb2_interrupt_handler, config, "pusb2");
rt_hw_interrupt_umask(irq_num);
}
/* implement cherryusb weak functions */
void usb_dc_low_level_init()
{
usb_pusb2_setup_interrupt(&pusb2_config[PUSB2_DEVICE_ID]);
}
void usb_dc_low_level_deinit(void)
{
}
void usb_assert(const char *filename, int linenum)
{
RT_ASSERT(0);
}
#endif

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Email: opensource_embedded@phytium.com.cn
*
* Change Logs:
* Date Author Notes
* 2023-11-14 zhugengyu first version
*
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <rtdbg.h>
#if defined(BSP_USING_PUSB2) && defined(PKG_CHERRYUSB_HOST_PUSB2)
#include "board.h"
#include "interrupt.h"
#include "mm_aspace.h"
#ifdef RT_USING_SMART
#include "ioremap.h"
#endif
#include "usbh_core.h"
#include "fcpu_info.h"
struct usb_pusb2_config
{
rt_uint32_t id;
rt_ubase_t base_addr; /* virtual address */
rt_uint32_t irq;
rt_uint32_t irq_priority;
};
static struct usb_pusb2_config pusb2_config[1U] =
{
[FUSB2_ID_VHUB_0] =
{
.id = FUSB2_ID_VHUB_0,
.base_addr = FUSB2_0_VHUB_BASE_ADDR,
.irq = FUSB2_0_VHUB_IRQ_NUM,
.irq_priority = 0xd0,
},
};
/* cherry usb support unique instance yet */
#define PUSB2_DEVICE_ID FUSB2_ID_VHUB_0
extern void USBH_IRQHandler(void *);
static void usb_pusb2_interrupt_handler(rt_int32_t vector, void *args)
{
/* args not in use */
USBH_IRQHandler(args);
}
static void usb_pusb2_setup_interrupt(struct usb_pusb2_config *config)
{
RT_ASSERT(config);
rt_uint32_t irq_num = config->irq;
rt_uint32_t irq_priority = config->irq_priority;
rt_uint32_t cpu_id = 0;
GetCpuId((u32 *)&cpu_id);
rt_hw_interrupt_set_target_cpus(irq_num, cpu_id);
rt_hw_interrupt_set_priority(irq_num, irq_priority);
rt_hw_interrupt_install(irq_num, usb_pusb2_interrupt_handler, config, "pusb2");
rt_hw_interrupt_umask(irq_num);
}
/* implement cherryusb weak functions */
void usb_hc_low_level_init()
{
usb_pusb2_setup_interrupt(&pusb2_config[PUSB2_DEVICE_ID]);
}
void usb_hc_low_level_deinit(void)
{
}
unsigned long usb_hc_get_register_base(void)
{
return pusb2_config[PUSB2_DEVICE_ID].base_addr;
}
void usb_assert(const char *filename, int linenum)
{
RT_ASSERT(0);
}
#endif

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Email: opensource_embedded@phytium.com.cn
*
* Change Logs:
* Date Author Notes
* 2023-11-13 zhugengyu first version
*
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <rtdbg.h>
#ifdef BSP_USING_XHCI
#include "board.h"
#include "interrupt.h"
#include "mm_aspace.h"
#ifdef RT_USING_SMART
#include "ioremap.h"
#endif
#include "usbh_core.h"
#include "fcpu_info.h"
struct usb_xhci_config
{
rt_uint32_t id;
rt_ubase_t base_addr; /* virtual address */
rt_uint32_t irq;
rt_uint32_t irq_priority;
};
static struct usb_xhci_config xhci_config[FUSB3_NUM] =
{
[FUSB3_ID_0] = {
.id = FUSB3_ID_0,
.base_addr = FUSB3_0_BASE_ADDR + FUSB3_XHCI_OFFSET,
.irq = FUSB3_0_IRQ_NUM,
.irq_priority = 0xd0,
},
[FUSB3_ID_1] = {
.id = FUSB3_ID_1,
.base_addr = FUSB3_1_BASE_ADDR + FUSB3_XHCI_OFFSET,
.irq = FUSB3_1_IRQ_NUM,
.irq_priority = 0xd0,
},
};
/* cherry usb support unique instance yet */
#define XHCI_DEVICE_ID CONFIG_USBHOST_XHCI_ID
extern void USBH_IRQHandler(void *);
static void usb_xhci_interrupt_handler(rt_int32_t vector, void *args)
{
/* args not in used */
USBH_IRQHandler(args);
}
static void usb_xhci_setup_interrupt(struct usb_xhci_config *config)
{
RT_ASSERT(config);
rt_uint32_t irq_num = config->irq;
rt_uint32_t irq_priority = config->irq_priority;
rt_uint32_t cpu_id = 0;
GetCpuId((u32 *)&cpu_id);
rt_hw_interrupt_set_target_cpus(irq_num, cpu_id);
rt_hw_interrupt_set_priority(irq_num, irq_priority);
rt_hw_interrupt_install(irq_num, usb_xhci_interrupt_handler, config, "xhci");
rt_hw_interrupt_umask(irq_num);
}
/* implement cherryusb weak functions */
void usb_hc_low_level_init(void)
{
usb_xhci_setup_interrupt(&xhci_config[XHCI_DEVICE_ID]);
}
unsigned long usb_hc_get_register_base(void)
{
return xhci_config[XHCI_DEVICE_ID].base_addr;
}
void usb_assert(const char *filename, int linenum)
{
RT_ASSERT(0);
}
#endif

View File

@ -0,0 +1,156 @@
/*
* Copyright (c) 2022, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef CHERRYUSB_CONFIG_H
#define CHERRYUSB_CONFIG_H
#include <rtthread.h>
#define CHERRYUSB_VERSION 0x001002
/* ================ USB common Configuration ================ */
#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__)
#define usb_malloc(size) rt_malloc(size)
#define usb_free(ptr) rt_free(ptr)
#define usb_align(align, size) rt_malloc_align(size, align)
#ifndef CONFIG_USB_DBG_LEVEL
#define CONFIG_USB_DBG_LEVEL USB_DBG_ERROR
#endif
/* Enable print with color */
#define CONFIG_USB_PRINTF_COLOR_ENABLE
/* data align size when use dma */
#ifndef CONFIG_USB_ALIGN_SIZE
#define CONFIG_USB_ALIGN_SIZE 4
#endif
/* attribute data into no cache ram */
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
/* ================= USB Device Stack Configuration ================ */
/* Ep0 max transfer buffer, specially for receiving data from ep0 out */
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512
/* Setup packet log for debug */
#define CONFIG_USBDEV_SETUP_LOG_PRINT
/* Check if the input descriptor is correct */
#define CONFIG_USBDEV_DESC_CHECK
#ifndef CONFIG_USB_ERROR_USE_SYSTEM
#define CONFIG_USB_ERROR_USE_SYSTEM
#endif
/* Enable test mode */
// #define CONFIG_USBDEV_TEST_MODE
#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
#endif
#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
#endif
#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING
#define CONFIG_USBDEV_MSC_PRODUCT_STRING ""
#endif
#ifndef CONFIG_USBDEV_MSC_VERSION_STRING
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
#endif
#define CONFIG_USBDEV_MSC_THREAD
#ifndef CONFIG_USBDEV_MSC_PRIO
#define CONFIG_USBDEV_MSC_PRIO 4
#endif
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
#define CONFIG_USBDEV_MSC_STACKSIZE 8192
#endif
#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
#endif
#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1536
#endif
#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID
#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff
#endif
#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC
#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB"
#endif
#define CONFIG_USBDEV_RNDIS_USING_LWIP
/* ================ USB HOST Stack Configuration ================== */
#define CONFIG_USBHOST_MAX_RHPORTS 1
#define CONFIG_USBHOST_MAX_EXTHUBS 1
#define CONFIG_USBHOST_MAX_EHPORTS 4
#define CONFIG_USBHOST_MAX_INTERFACES 6
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 1
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
#define CONFIG_USBHOST_MAX_CDC_ACM_CLASS 4
#define CONFIG_USBHOST_MAX_HID_CLASS 4
#define CONFIG_USBHOST_MAX_MSC_CLASS 2
#define CONFIG_USBHOST_MAX_AUDIO_CLASS 1
#define CONFIG_USBHOST_MAX_VIDEO_CLASS 1
#define CONFIG_USBHOST_DEV_NAMELEN 16
#ifndef CONFIG_USBHOST_PSC_PRIO
#define CONFIG_USBHOST_PSC_PRIO 4
#endif
#ifndef CONFIG_USBHOST_PSC_STACKSIZE
#define CONFIG_USBHOST_PSC_STACKSIZE 81920
#endif
// #define CONFIG_USBHOST_GET_STRING_DESC
// #define CONFIG_USBHOST_MSOS_ENABLE
#define CONFIG_USBHOST_MSOS_VENDOR_CODE 0x00
/* Ep0 max transfer buffer */
#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
#endif
#ifndef CONFIG_USBHOST_MSC_TIMEOUT
#define CONFIG_USBHOST_MSC_TIMEOUT 5000
#endif
/* ================ USB Device Port Configuration ================*/
/* ================ USB Host Port Configuration ==================*/
#define CONFIG_USBHOST_PIPE_NUM 10
/* ================ XHCI Configuration ================ */
#if defined(PKG_CHERRYUSB_HOST_XHCI)
#define CONFIG_USBHOST_XHCI
#define CONFIG_USBHOST_XHCI_ID 0U
#endif
/* ================ PUSB2 Configuration ================ */
#if defined(PKG_CHERRYUSB_HOST_PUSB2) || defined(PKG_CHERRYUSB_DEVICE_PUSB2)
#define CONFIG_USBDEV_PUSB2_CTRL_ID 0U
#define CONFIG_USBDEV_PUSB2_CTRL_NUM 1U
#endif
#endif