From 4d6b12c704b7acfbc6b473d98c1829f0befe4bc4 Mon Sep 17 00:00:00 2001 From: sakumisu <1203593632@qq.com> Date: Thu, 7 Aug 2025 21:11:19 +0800 Subject: [PATCH] docs: release v1.5.2 Signed-off-by: sakumisu <1203593632@qq.com> --- Kconfig.rttpkg | 5 +++- README.md | 42 +++++++++++++------------- README_zh.md | 42 +++++++++++++------------- VERSION | 2 +- common/usb_errno.h | 2 +- common/usb_version.h | 4 +-- docs/assets/sifli.jpg | Bin 0 -> 16492 bytes docs/source/conf.py | 4 +-- docs/source/quick_start/demo.rst | 49 +++++++++++++++++-------------- docs/source/version.rst | 16 +++++++++- idf_component.yml | 2 +- 11 files changed, 95 insertions(+), 73 deletions(-) create mode 100644 docs/assets/sifli.jpg diff --git a/Kconfig.rttpkg b/Kconfig.rttpkg index 7f7862ba..e5a0e430 100644 --- a/Kconfig.rttpkg +++ b/Kconfig.rttpkg @@ -465,12 +465,14 @@ if PKG_USING_CHERRYUSB choice prompt "Version" - default PKG_USING_CHERRYUSB_V010500 + default PKG_USING_CHERRYUSB_V010502 help Select the package version config PKG_USING_CHERRYUSB_LATEST_VERSION bool "latest" + config PKG_USING_CHERRYUSB_V010502 + bool "v1.5.2" config PKG_USING_CHERRYUSB_V010501 bool "v1.5.1" config PKG_USING_CHERRYUSB_V010500 @@ -488,6 +490,7 @@ if PKG_USING_CHERRYUSB config PKG_CHERRYUSB_VER string default "latest" if PKG_USING_CHERRYUSB_LATEST_VERSION + default "v1.5.2" if PKG_USING_CHERRYUSB_V010502 default "v1.5.1" if PKG_USING_CHERRYUSB_V010501 default "v1.5.0" if PKG_USING_CHERRYUSB_V010500 default "v1.4.3" if PKG_USING_CHERRYUSB_V010403 diff --git a/README.md b/README.md index 890e4bfb..2b570971 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ CherryUSB Host Stack has the following functions: - Support blocking transfers and asynchronous transfers - Support Composite Device - Multi-level HUB support, expandable up to 7 levels(Testing hub with 10 ports works well,only support dwc2/ehci/xhci/rp2040) -- Support Communication Device Class (CDC_ACM, CDC_ECM) +- Support Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM) - Support Human Interface Device (HID) - Support Mass Storage Class (MSC) - Support USB Video CLASS (UVC1.0, UVC1.5) @@ -143,7 +143,7 @@ Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affe #define CONFIG_USBHOST_MAX_EXTHUBS 1 #define CONFIG_USBHOST_MAX_EHPORTS 4 #define CONFIG_USBHOST_MAX_INTERFACES 8 -#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8 +#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2 #define CONFIG_USBHOST_MAX_ENDPOINTS 4 ``` @@ -189,24 +189,25 @@ TODO ## Demo Repo -| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status | +| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note | |:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:| -|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term | -|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term | -|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term | -|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term | -|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term | -|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term | -|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term | -|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term | -|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term | -|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term | -|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term | -|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb | -|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb | -|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD | -|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD | +|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official | +|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community | +|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official | +|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official | +|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official | +|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official | +|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing | +|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official | +|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official | +|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official | +|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community | +|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing | +|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing | +|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update | +|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official | +|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official | +|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update | ## Package Support @@ -228,5 +229,4 @@ CherryUSB discord: https://discord.com/invite/wFfvrSAey8. Thanks to the following companies for their support (in no particular order): - - + diff --git a/README_zh.md b/README_zh.md index 8e52f84b..64287a55 100644 --- a/README_zh.md +++ b/README_zh.md @@ -105,7 +105,7 @@ CherryUSB Host 协议栈当前实现以下功能: - 支持阻塞式传输和异步传输 - 支持复合设备 - 支持多级 HUB,最高可拓展到 7 级(目前测试 1拖 10 没有问题,仅支持 dwc2/ehci/xhci/rp2040) -- 支持 Communication Device Class (CDC_ACM, CDC_ECM) +- 支持 Communication Device Class (CDC_ACM, CDC_ECM, CDC_NCM) - 支持 Human Interface Device (HID) - 支持 Mass Storage Class (MSC) - Support USB Video CLASS (UVC1.0、UVC1.5) @@ -143,7 +143,7 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2,关闭 log) #define CONFIG_USBHOST_MAX_EXTHUBS 1 #define CONFIG_USBHOST_MAX_EHPORTS 4 #define CONFIG_USBHOST_MAX_INTERFACES 8 -#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 8 +#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 2 #define CONFIG_USBHOST_MAX_ENDPOINTS 4 ``` @@ -189,24 +189,25 @@ TODO ## 示例仓库 -| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Support status | +| Manufacturer | CHIP or Series | USB IP| Repo Url | Support version | Note | |:--------------------:|:------------------:|:-----:|:--------:|:------------------:|:-------------:| -|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Long-term | -|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Long-term | -|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Long-term | -|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Long-term | -|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Long-term | -|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term | -|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term | -|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term | -|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term | -|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Long-term | -|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Long-term | -|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term | -|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb | -|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb | -|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD | -|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD | +|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bouffalo_sdk](https://github.com/CherryUSB/bouffalo_sdk)|<= latest | Official | +|ST | STM32F1x/STM32F4/STM32H7 | fsdev/dwc2 |[stm32_repo](https://github.com/CherryUSB/cherryusb_stm32)|<= latest | Community | +|HPMicro | HPM6000/HPM5000 | hpm/ehci |[hpm_sdk](https://github.com/CherryUSB/hpm_sdk)|<= latest | Official | +|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/CherryUSB/cherryusb_es32)|<= latest | Official | +|Phytium | e2000 | pusb2/xhci |[phytium_repo](https://gitee.com/phytium_embedded/phytium-free-rtos-sdk)|>=1.4.0 | Official | +|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Official | +|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Official ongoing | +|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Official | +|Actionstech | ATS30xx | dwc2 |[action_zephyr_repo](https://github.com/CherryUSB/lv_port_actions_technology/tree/master/action_technology_sdk)|>=1.4.0 | Official | +|SiFli | SF32LB5x | musb |[SiFli_sdk](https://github.com/OpenSiFli/SiFli-SDK)|>=1.5.0 | Official | +|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Community | +|Nationstech | n32h4x | dwc2 |[nation_repo](https://github.com/CherryUSB/cherryusb_nation)|>=1.5.0 | Official ongoing | +|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-sdk](https://github.com/CherryUSB/pico-sdk)|<= latest | Official ongoing | +|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | no more update | +|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | Official | +|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | Official | +|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | no more update | ## 软件包支持 @@ -230,5 +231,4 @@ CherryUSB 微信群:与我联系后邀请加入 感谢以下企业支持(顺序不分先后): - - + diff --git a/VERSION b/VERSION index 5da4b386..7aa5f8b8 100644 --- a/VERSION +++ b/VERSION @@ -1,5 +1,5 @@ VERSION_MAJOR = 1 VERSION_MINOR = 5 -PATCHLEVEL = 1 +PATCHLEVEL = 2 VERSION_TWEAK = 0 EXTRAVERSION = 0 diff --git a/common/usb_errno.h b/common/usb_errno.h index 57f37c16..284020a2 100644 --- a/common/usb_errno.h +++ b/common/usb_errno.h @@ -15,7 +15,7 @@ #define USB_ERR_RANGE 7 #define USB_ERR_STALL 8 #define USB_ERR_BABBLE 9 -#define USB_ERR_NAK 10 +#define USB_ERR_NAK 10 /* only for dwc2 buffer dma mode */ #define USB_ERR_DT 11 #define USB_ERR_IO 12 #define USB_ERR_SHUTDOWN 13 diff --git a/common/usb_version.h b/common/usb_version.h index 41cae0e7..2d70bb4c 100644 --- a/common/usb_version.h +++ b/common/usb_version.h @@ -15,7 +15,7 @@ #undef CHERRYUSB_VERSION_STR #endif -#define CHERRYUSB_VERSION 0x010501 -#define CHERRYUSB_VERSION_STR "v1.5.1" +#define CHERRYUSB_VERSION 0x010502 +#define CHERRYUSB_VERSION_STR "v1.5.2" #endif \ No newline at end of file diff --git a/docs/assets/sifli.jpg b/docs/assets/sifli.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a74cf7d3d179809f57a1b6b56532710c1506461d GIT binary patch literal 16492 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 Y0aAAo%&+|Nhk#dKq?M&AfRKRy0i0B?