From 0da14e6546ee5ad8a4acdd9e383e20b9ab4627f3 Mon Sep 17 00:00:00 2001 From: songyanguang <345810377@qq.com> Date: Wed, 13 Aug 2025 20:00:06 +0800 Subject: [PATCH] Add usbd cdc --- Ubiquitous/XiZi_IIoT/board/ch569w/config.mk | 4 + .../board/ch569w/third_party_driver/Kconfig | 7 + .../board/ch569w/third_party_driver/Makefile | 6 +- .../third_party_driver/include/CH56x_usb20.h | 56 ++ .../third_party_driver/include/CH56x_usb30.h | 61 ++ .../include/CH56x_usb30_LIB.h | 482 ++++++++++ .../ch569w/third_party_driver/include/cdc.h | 27 + .../third_party_driver/include/connect_usb.h | 37 + .../ch569w/third_party_driver/usb/Kconfig | 6 + .../ch569w/third_party_driver/usb/Makefile | 5 + .../third_party_driver/usb/usbd/Kconfig | 3 + .../third_party_driver/usb/usbd/Makefile | 5 + .../usb/usbd/simulate_cdc/CDC/cdc.c | 337 +++++++ .../usb/usbd/simulate_cdc/Makefile | 3 + .../usb/usbd/simulate_cdc/USB20/CH56x_usb20.c | 756 ++++++++++++++++ .../usb/usbd/simulate_cdc/USB30/CH56x_usb30.c | 832 ++++++++++++++++++ .../USB30/libCH56x_USB30_device_lib.a | Bin 0 -> 44868 bytes .../usb/usbd/simulate_cdc/connect_cdc.c | 58 ++ 18 files changed, 2684 insertions(+), 1 deletion(-) create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb20.h create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30.h create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30_LIB.h create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/cdc.h create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_usb.h create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/CDC/cdc.c create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB20/CH56x_usb20.c create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/CH56x_usb30.c create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/libCH56x_USB30_device_lib.a create mode 100644 Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/connect_cdc.c diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/config.mk b/Ubiquitous/XiZi_IIoT/board/ch569w/config.mk index d87b3d1d1..6a4afcfce 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch569w/config.mk +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/config.mk @@ -17,3 +17,7 @@ export MCU = CH569W ifeq ($(CONFIG_BSP_USING_SERDES), y) export LINK_BOARD += $(KERNEL_ROOT)/board/ch569w/third_party_driver/serdes/libSERDES.a endif + +ifeq ($(CONFIG_BSP_USING_USBD), y) +export LINK_BOARD += $(KERNEL_ROOT)/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/libCH56x_USB30_device_lib.a +endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Kconfig index 0b8a591b2..1177c855b 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Kconfig @@ -20,6 +20,13 @@ menuconfig BSP_USING_SERDES source "$BSP_DIR/third_party_driver/serdes/Kconfig" endif +menuconfig BSP_USING_USB + bool "Using usb device" + default y + if BSP_USING_USB + source "$BSP_DIR/third_party_driver/usb/Kconfig" + endif + menuconfig BSP_USING_WDT bool "Using watchdog timer device" default n diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Makefile index 6cc73d828..0d445e3a7 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Makefile @@ -10,10 +10,14 @@ ifeq ($(CONFIG_BSP_USING_SPI),y) SRC_DIR += spi endif -ifeq ($(CONFIG_BSP_USING_SPI),y) +ifeq ($(CONFIG_BSP_USING_SERDES),y) SRC_DIR += serdes endif +ifeq ($(CONFIG_BSP_USING_USB),y) + SRC_DIR += usb +endif + ifeq ($(CONFIG_BSP_USING_WDT),y) SRC_DIR += wdt endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb20.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb20.h new file mode 100644 index 000000000..c9eebe5f7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb20.h @@ -0,0 +1,56 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb20.h +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef USB20_CH56X_USB20_H_ +#define USB20_CH56X_USB20_H_ +#include "CH56x_common.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* Global define */ +#define U20_MAXPACKET_LEN 512 +#define U20_UEP0_MAXSIZE 64 +#define PID_OUT 0 +#define PID_SOF 1 +#define PID_IN 2 + +/* Global Variable */ +typedef struct __attribute__((packed)) +{ + UINT8 dev_speed; + UINT8 dev_addr; + UINT8 dev_config_value; + UINT8 dev_sleep_status; + UINT8 dev_enum_status; +}DevInfo_Typedef; + + +extern const UINT8 hs_device_descriptor[]; +extern const UINT8 hs_config_descriptor[]; +extern const UINT8 hs_string_descriptor0[]; +extern const UINT8 hs_string_descriptor1[]; +extern const UINT8 hs_string_descriptor2[]; +extern const UINT8 hs_bos_descriptor[]; + +/* Function declaration */ +void USB20_Device_Init ( FunctionalState sta ); +UINT16 U20_NonStandard_Request_Deal(); +UINT16 U20_Standard_Request_Deal(); +UINT16 U20_Endp0_IN_Callback(void); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30.h new file mode 100644 index 000000000..8ef6d0217 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30.h @@ -0,0 +1,61 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb30.h +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef USB30_CH56X_USB30_H_ +#define USB30_CH56X_USB30_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "CH56x_common.h" + + +/* Global define */ +#define endpoint_1_OUT_burst_level 1 +#define endpoint_1_IN_burst_level 1 +#define endpoint_2_OUT_burst_level 1 +#define endpoint_2_IN_burst_level 1 + + +#define SIZE_DEVICE_DESC 18 +#define SIZE_CONFIG_DESC 85 +#define SIZE_STRING_LANGID 4 +#define SIZE_STRING_VENDOR 8 +#define SIZE_STRING_PRODUCT 38 +#define SIZE_STRING_SERIAL 22 +#define SIZE_BOS_DESC 22 +#define SIZE_STRING_OS 18 + +#define LINK_STA_1 (1<<0) +#define LINK_STA_3 (1<<2) +/* Global Variable */ +extern __attribute__ ((aligned(16))) UINT8 endp0RTbuff[512] __attribute__((section(".DMADATA"))); +extern __attribute__ ((aligned(16))) UINT8 endp1RTbuff[4096] __attribute__((section(".DMADATA"))); +extern __attribute__ ((aligned(16))) UINT8 endp2Rxbuff[4096] __attribute__((section(".DMADATA"))); +extern __attribute__ ((aligned(16))) UINT8 endp2Txbuff[4096] __attribute__((section(".DMADATA"))); + + +extern UINT8V Link_Sta; + +/* Function declaration */ +void USB30D_init(FunctionalState sta); +void TMR0_IRQHandler() __attribute__((interrupt())); +void LINK_IRQHandler() __attribute__((interrupt())); +void USBSS_IRQHandler(void) __attribute__((interrupt())); //USB3.0 interrupt service + +#ifdef __cplusplus +} +#endif + +#endif /* USER_USB30_DESC_H_ */ + + diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30_LIB.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30_LIB.h new file mode 100644 index 000000000..95c04564b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30_LIB.h @@ -0,0 +1,482 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb30_lib.h +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef USB30_CH56X_USB30_LIB_H_ +#define USB30_CH56X_USB30_LIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "CH56x_common.h" + +// link CFG +#define TERM_EN (1<<1) +#define PIPE_RESET (1<<3) +#define LFPS_RX_PD (1<<5) +#define CFG_EQ_EN (1<<6) +#define TX_SWING (1<<7) +#define DEEMPH_CFG (1<<8) + +#define POWER_MODE_0 ((UINT32)0x00000000) +#define POWER_MODE_1 ((UINT32)0x00000001) +#define POWER_MODE_2 ((UINT32)0x00000002) +#define POWER_MODE_3 ((UINT32)0x00000003) + +#define LINK_PRESENT (1<<0) +#define RX_WARM_RESET ((UINT32)1<<1) + +#define LINK_TXEQ (1<<6) +#define GO_DISABLED (1<<4) +#define POLLING_EN (1<<12) + +#define TX_HOT_RESET ((UINT32)1<<16) +#define RX_HOT_RESET ((UINT32)1<<24) + +#define TX_WARM_RESET ((UINT32)1<<8) +#define TX_Ux_EXIT ((UINT32)1<<9) +// link int flag +#define LINK_RDY_FLAG (1<<0) +#define LINK_RECOV_FLAG (1<<1) +#define LINK_INACT_FLAG (1<<2) +#define LINK_DISABLE_FLAG (1<<3) +#define LINK_GO_U3_FLAG (1<<4) +#define LINK_GO_U2_FLAG (1<<5) +#define LINK_GO_U1_FLAG (1<<6) +#define LINK_GO_U0_FLAG (1<<7) +#define LINK_U3_WAKE_FLAG (1<<8) +#define LINK_Ux_REJECT_FLAG (1<<9) +#define TERM_PRESENT_FLAG (1<<10) +#define LINK_TXEQ_FLAG (1<<11) +#define LINK_Ux_EXIT_FLAG (1<<12) +#define WARM_RESET_FLAG (1<<13) +#define U3_WAKEUP_FLAG (1<<14) +#define HOT_RESET_FLAG (1<<15) +#define LINK_RX_DET_FLAG (1<<20) + +#define EP0_R_EN (1<<0) +#define EP1_R_EN (1<<1) +#define EP2_R_EN (1<<2) +#define EP3_R_EN (1<<3) +#define EP4_R_EN (1<<4) +#define EP5_R_EN (1<<5) +#define EP6_R_EN (1<<6) +#define EP7_R_EN (1<<7) + +#define EP0_T_EN (1<<8) +#define EP1_T_EN (1<<9) +#define EP2_T_EN (1<<10) +#define EP3_T_EN (1<<11) +#define EP4_T_EN (1<<12) +#define EP5_T_EN (1<<13) +#define EP6_T_EN (1<<14) +#define EP7_T_EN (1<<15) + +#define USB_FORCE_RST (1<<2) +#define USB_ALL_CLR (1<<1) +// LMP +#define LMP_HP (0) +#define LMP_SUBTYPE_MASK (0xf<<5) +#define SET_LINK_FUNC (0x1<<5) +#define U2_INACT_TOUT (0x2<<5) +#define VENDOR_TEST (0x3<<5) +#define PORT_CAP (0x4<<5) +#define PORT_CFG (0x5<<5) +#define PORT_CFG_RES (0x6<<5) + +#define LINK_SPEED (1<<9) + +#define NUM_HP_BUF (4<<0) +#define DOWN_STREAM (1<<16) +#define UP_STREAM (2<<16) +#define TIE_BRK (1<<20) + +/**********device status***********/ +typedef enum _DEVICE_STATE +{ + UNCONNECTED, + ATTACHED, + POWERED, + SUSPENDED, + ADDRESSED, + CONFIGURED +} DEVICE_STATE; + +/**********standard request command***********/ +typedef struct __PACKED +{ + UINT8 bRequestType; + UINT8 bRequest; + UINT8 wValueL; + UINT8 wValueH; + UINT8 wIndexL; + UINT8 wIndexH; + UINT16 wLength; +} *PUSB_SETUP; + +#define UsbSetupBuf ((PUSB_SETUP)endp0RTbuff)//endpoint 0 + + +#define ENDP0_MAXPACK 512 + +// status response +#define NRDY 0 +#define ACK 0x01 +#define STALL 0x02 +#define INVALID 0x03 +// number of NUMP +#define NUMP_0 0x00 +#define NUMP_1 0x01 +#define NUMP_2 0x02 +#define NUMP_3 0x03 +#define NUMP_4 0x04 +#define NUMP_5 0x05 +#define NUMP_6 0x06 +/* USB endpoint direction */ +#define OUT 0x00 +#define IN 0x80 +/* USB endpoint serial number */ +#define ENDP_0 0x00 +#define ENDP_1 0x01 +#define ENDP_2 0x02 +#define ENDP_3 0x03 +#define ENDP_4 0x04 +#define ENDP_5 0x05 +#define ENDP_6 0x06 +#define ENDP_7 0x07 + +#define USB_DESCR_TYP_BOS 0x0f +#define USB_DESCR_UNSUPPORTED 0xffff +#define INVALID_REQ_CODE 0xFF + +/* string descriptor type */ +#ifndef USB_DESCR_STRING + #define USB_DESCR_LANGID_STRING 0x00 + #define USB_DESCR_VENDOR_STRING 0x01 + #define USB_DESCR_PRODUCT_STRING 0x02 + #define USB_DESCR_SERIAL_STRING 0x03 + #define USB_DESCR_OS_STRING 0xee +#endif + + +extern void USB30_Device_forceclr(); +/******************************************************************************* + * @fn USB30_Device_Init + * + * @brief USB3.0 Device initialization + * + * @return None + */ +extern UINT8 USB30_Device_Init(void); + +/******************************************************************************* + * @fn USB30_Lib_Getversion + * + * @brief USB3.0 Device Lib initialization + * + * @return None + */ +extern UINT8 USB30_Lib_Getversion(void); + +/******************************************************************************* + * @fn USB30_ISO_Setendp + * + * @brief Configure synchronization endpoint + * + * @return None + */ +extern void USB30_ISO_Setendp(UINT8 num,FunctionalState Status ); + +/******************************************************************************* + * @fn USB30_ISO_Setdelay( UINT32 dly ) + * + * @brief Set synchronization delay time + * + * @param dly - delay time + * + * @return None + */ +extern void USB30_ISO_Setdelay( UINT32 dly ); + +/******************************************************************************* + * @fn USB30_ITP_Enable + * + * @brief USB ITP enable + * + * @param Status - enable/disable + * + * @return None + */ +extern void USB30_ITP_Enable(FunctionalState Status); + +/******************************************************************************* + * @fn USB30_OUT_Status + * + * @brief Get the length of endpoint received data + * + * @param endp - Endpoint number + * nump - The remaining number of packets that can be received by the endpoint + * len - The length of data received by the endpoint. For burst transmission, + * it indicates the length of the last packet received by the endpoint. + * status - Indicates whether the host still has data packets to be distributed, + * 1 - the end of the burst received non-full packets, + * 0 - the host still has data packets to be distributed. + * + * @return None + */ +extern void USB30_OUT_Status(UINT8 endp,UINT8 *nump,UINT16 *len,UINT8 *status); + +/******************************************************************************* + * @fn USB30_OUT_Set + * + * @brief Endpoint receive settings + * + * @param endp - Set endpoint number + * nump - The remaining number of packets that can be received by the endpoint + * status - Endpoint Status :0-NRDY,1-ACK,2-STALL + * + * @return None + */ +extern void USB30_OUT_Set(UINT8 endp,UINT8 status,UINT8 nump); + +/******************************************************************************* + * @fn USB30_OUT_ClearIT + * + * @brief Clear the OUT transaction completion interrupt, and only keep the package serial number + * + * @param endp - Set endpoint number + * + * @return None + */ +extern void USB30_OUT_ClearIT(UINT8 endp); + +/******************************************************************************* + * @fn USB30_OUT_ClearPendingIT + * + * @brief Clear the OUT transaction completion interrupt, and keep other endpoint configurations + * + * @param endp - Set endpoint number + * + * @return None + */ +extern void USB30_OUT_ClearPendingIT(UINT8 endp); + +/******************************************************************************* + * @fn USB30_OUT_ITflag + * + * @brief Get the OUT transaction completion interrupt flag + * + * @param endp - Set endpoint number + * + * @return 1 - interrupt 0 - non-interrupt + */ +extern UINT8 USB30_OUT_ITflag(UINT8 endp); + +/******************************************************************************* + * @fn USB30_IN_Set + * + * @brief Endpoint sending settings + * + * @param endp - endpoint number + * lpf - end of burst: 1-enable 0-disable + * nump - The number of packets that the endpoint can send + * status - endpoint status: 0-NRDY,1-ACK,2-STALL + * TxLen - The data length of the last packet sent by the endpoint + * + * @return None + */ +extern void USB30_IN_Set(UINT8 endp,FunctionalState lpf,UINT8 status,UINT8 nump,UINT16 TxLen); + +/******************************************************************************* + * @fn USB30_IN_ClearPendingIT + * + * @brief Clear the IN transaction completion interrupt and keep the other configurations of the endpoint + * + * @param endp - endpoint number + * + * @return None + */ +extern void USB30_IN_ClearPendingIT(UINT8 endp); + +/******************************************************************************* + * @fn USB30_IN_ClearIT + * + * @brief Clear the IN transaction interrupt and the remaining status of the endpoint, + * and only retain the packet serial number. + * + * @param endp - endpoint number + * + * @return None + */ +extern void USB30_IN_ClearIT(UINT8 endp); + +/******************************************************************************* + * @fn USB30_IN_ITflagT + * + * @brief Get IN transaction completion interrupt flag + * + * @param endp - Set endpoint number + * + * @return None + */ +extern UINT8 USB30_IN_ITflag(UINT8 endp); + +/******************************************************************************* + * @fn USB30_IN_Nump + * + * @brief Get the remaining number of packets to be sent by the endpoint + * + * @param endp - endpoint number + * + * @return Remaining number of packets to be sent + */ +extern UINT8 USB30_IN_Nump(UINT8 endp); + +/******************************************************************************* + * @fn USB30_Send_ERDY + * + * @brief send ERDY packet + * + * @param endp - endpoint number + * nump - Number of packets received or sent by the endpoint + * + * @return None + */ +extern void USB30_Send_ERDY(UINT8 endp,UINT8 nump); + +/******************************************************************************* + * @fn USB30_Device_Setaddress + * + * @brief Set device address + * + * @param address - device address + * + * @return None + */ +extern void USB30_Device_Setaddress( UINT32 address ); + +/******************************************************************************* + * @fn USB30_IN_Nump + * + * @brief Get the remaining number of packets to be sent by the endpoint + * + * @return Control the length of data sent by the host when the transmission data stage is OUT + */ +extern UINT16 USB30_Setup_OutData(void); + +/******************************************************************************* + * @fn USB30_IRQHandler + * + * @brief USB30_IRQHandler + * + * @return None + */ +extern void USB30_IRQHandler(); + +/******************************************************************************* + * @fn USB30_StandardReq + * + * @brief USB device mode standard request command processing + * + * @return The length of data sent by the host request device + */ +extern UINT16 USB30_StandardReq(); + +/******************************************************************************* + * @fn USB30_NonStandardReq + * + * @brief USB device mode non-standard request command processing + * + * @return The length of data sent by the host request device + */ +extern UINT16 USB30_NonStandardReq(); + +/******************************************************************************* + * @fn EP0_IN_Callback + * + * @brief endpoint 0 IN Transfer completion callback function + * + * @return Data length + */ +extern UINT16 EP0_IN_Callback(); + +/******************************************************************************* + * @fn EP0_OUT_Callback + * + * @brief endpoint 0 OUT Transfer completion callback function + * + * @return None + */ +extern UINT16 EP0_OUT_Callback(); + +/******************************************************************************* + * @fn USB30_Setup_Status + * + * @brief Control transmission status stage + * + * @return None + */ +extern void USB30_Setup_Status(); + +/******************************************************************************* + * @fn USB30_ITP_Callback + * + * @brief ITP Callback function + * + * @return None + */ +extern void USB30_ITP_Callback(UINT32 ITPCounter); + +/******************************************************************************* + * @fn USB30_switch_pwr_mode + * + * @brief switch USB3.0 Power mode + * + * @return None + */ +extern void USB30_Switch_Powermode( UINT8 pwr_mode ); + +/******************************************************************************* + * @fn EPn_IN_Callback() + * + * @brief endpointN IN transaction callback function + * + * @return None + */ +extern void EP1_IN_Callback(void); +extern void EP2_IN_Callback(void); +extern void EP3_IN_Callback(void); +extern void EP4_IN_Callback(void); +extern void EP5_IN_Callback(void); +extern void EP6_IN_Callback(void); +extern void EP7_IN_Callback(void); + +/******************************************************************************* + * @fn EPn_IN_Callback() + * + * @brief endpointN OUT transaction callback function + * + * @return None + */ +extern void EP1_OUT_Callback(void); +extern void EP2_OUT_Callback(void); +extern void EP3_OUT_Callback(void); +extern void EP4_OUT_Callback(void); +extern void EP5_OUT_Callback(void); +extern void EP6_OUT_Callback(void); +extern void EP7_OUT_Callback(void); + +#ifdef __cplusplus +} +#endif + +#endif /* USB30_CH56X_USB30_LIB_H_ */ + diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/cdc.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/cdc.h new file mode 100644 index 000000000..107d17f02 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/cdc.h @@ -0,0 +1,27 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : cdc.h +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef CDC_CDC_H_ +#define CDC_CDC_H_ + + +extern volatile UINT16 USBByteCount; +extern volatile UINT16 USBBufOutPoint; +extern volatile UINT8 UploadPoint2_Busy; +extern volatile UINT8 DownloadPoint2_Busy; +extern volatile UINT16 Uart_Sendlenth; + +void CDC_Uart_Init( UINT32 baudrate ); +void TMR2_TimerInit1( void ); +void CDC_Uart_Deal( void ); +void CDC_Variable_Clear(void); + +#endif /* CDC_CDC_H_ */ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_usb.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_usb.h new file mode 100644 index 000000000..66e5c5f19 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_usb.h @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_usb.h +* @brief define aiit-arm32-board usb function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_USB_H +#define CONNECT_USB_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef BSP_USING_USBD_CDC +// TODO +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Kconfig new file mode 100644 index 000000000..5f473df64 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Kconfig @@ -0,0 +1,6 @@ +menuconfig BSP_USING_USBD + bool "Using usbd device" + default y + if BSP_USING_USBD + source "$BSP_DIR/third_party_driver/usb/usbd/Kconfig" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Makefile new file mode 100644 index 000000000..3358dc1a0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Makefile @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_BSP_USING_USBD),y) + SRC_DIR += usbd +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Kconfig new file mode 100644 index 000000000..31c0c6fd6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Kconfig @@ -0,0 +1,3 @@ +menuconfig BSP_USING_USBD_CDC + bool "Using usbd cdc device" + default y diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Makefile new file mode 100644 index 000000000..3ca5a9b37 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Makefile @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_BSP_USING_USBD_CDC),y) + SRC_DIR += simulate_cdc +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/CDC/cdc.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/CDC/cdc.c new file mode 100644 index 000000000..5b0ce329c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/CDC/cdc.c @@ -0,0 +1,337 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : cdc.c +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "CH56x_common.h" +#include "CH56x_usb30_LIB.h" +#include "CH56x_usb30.h" +#include "CH56x_usb20.h" +#include "cdc.h" + +/* Global define */ +#define UART_REV_LEN 1024 //uart receive buffer size +#define UART_TIMEOUT 1000 + +/* Global Variable */ +__attribute__ ((aligned(16))) UINT8 Receive_Uart_Buf[UART_REV_LEN] __attribute__((section(".DMADATA")));//uart receive buffer + +volatile UINT16 Uart_Input_Point = 0; //Circular buffer write pointer +volatile UINT16 Uart_Output_Point = 0; //Loop buffer fetch pointer +volatile UINT16 UartByteCount = 0; //The number of bytes remaining to be fetched in the current buffer +volatile UINT16 USBByteCount = 0; //Data received by USB endpoint +volatile UINT16 USBBufOutPoint = 0; //Get data pointer +volatile UINT8 UploadPoint2_Busy = 0; //Upload whether the endpoint is busy +volatile UINT8 DownloadPoint2_Busy = 0; //Download whether the endpoint is busy +volatile UINT16 Uart_Timecount = 0; //Timeout processing calculation time +volatile UINT16 Uart_Sendlenth = 0; //USB upload data length +/* Function declaration */ +void TMR2_IRQHandler (void) __attribute__((interrupt())); +void UART2_IRQHandler (void) __attribute__((interrupt())); + +/******************************************************************************* + * @fn CDC_Uart_Init + * + * @brief CDC UART initialization + * + * @param baudrate: UART2 communication baud rate. + * + * @return None + */ +void CDC_Uart_Init( UINT32 baudrate ) +{ + UINT32 x; + UINT32 t = FREQ_SYS; + x = 10 * t * 2 / 16 / baudrate; + x = ( x + 5 ) / 10; + R8_UART2_DIV = 1; + R16_UART2_DL = x; + R8_UART2_FCR = RB_FCR_FIFO_TRIG | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; + R8_UART2_LCR = RB_LCR_WORD_SZ; + R8_UART2_IER = RB_IER_TXD_EN; + + GPIOA_SetBits(GPIO_Pin_3); + GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PU_NSMT); + GPIOA_ModeCfg(GPIO_Pin_3, GPIO_Slowascent_PP_8mA); + UART2_ByteTrigCfg( UART_7BYTE_TRIG ); + UART2_INTCfg( ENABLE, RB_IER_RECV_RDY|RB_IER_LINE_STAT ); + PFIC_EnableIRQ( UART2_IRQn ); +} + + +/******************************************************************************* + * @fn TMR2_TimerInit1 + * + * @brief CDC timeout timer initialization + * + * @return None + */ +void TMR2_TimerInit1( void ) +{ + R32_TMR2_CNT_END = FREQ_SYS/100000; //10us + R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR; + R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN; + R8_TMR2_INTER_EN |= 0x01; + PFIC_EnableIRQ( TMR2_IRQn ); +} + +/******************************************************************************* + * @fn TMR2_IRQHandler + * + * @brief CDC timer interrupt function + * + * @return None + */ +void TMR2_IRQHandler( void ) +{ + if( R8_TMR2_INT_FLAG &0x01 ) + { + R8_TMR2_INT_FLAG = 0x01; + Uart_Timecount++; + } +} + +/******************************************************************************* + * @fn U30_CDC_UartRx_Deal + * + * @brief usb3.0 CDC serial port receiving data processing + * + * @return None + */ +void U30_CDC_UartRx_Deal( void ) +{ + if(!UploadPoint2_Busy) + { + Uart_Sendlenth = UartByteCount; + if(Uart_Sendlenth > 0) + { + if( (Uart_Sendlenth >= (UART_REV_LEN/2) && DownloadPoint2_Busy == 0 ) || Uart_Timecount > UART_TIMEOUT )//If the sent data overflows or times out, upload the data + { + if(Uart_Output_Point+Uart_Sendlenth>UART_REV_LEN)//Determine if the pointer to the stored data array is out of bounds + { + Uart_Sendlenth = UART_REV_LEN-Uart_Output_Point; + } + + if(Uart_Sendlenth > (UART_REV_LEN/2))//Limit sending length + { + Uart_Sendlenth = (UART_REV_LEN/2); + } + + UartByteCount -= Uart_Sendlenth;//Reduce the length of data to be sent + memcpy(endp2Txbuff,&Receive_Uart_Buf[Uart_Output_Point],Uart_Sendlenth);//Copy the data to be sent to the USB buffer + Uart_Output_Point+=Uart_Sendlenth;//Move buffer pointer + + if(Uart_Output_Point>=UART_REV_LEN) + { + Uart_Output_Point = 0; + } + + UploadPoint2_Busy = 1; + /* Start USB sending */ + USB30_IN_ClearIT( ENDP_2 ); + USB30_IN_Set( ENDP_2 , ENABLE , ACK , 1, Uart_Sendlenth); + USB30_Send_ERDY( ENDP_2 | IN , 1 ); + + Uart_Timecount = 0; + } + } + } +} + +/******************************************************************************* + * @fn U20_CDC_UartRx_Deal + * + * @brief usb2.0 CDC serial port receiving data processing + * + * @return None + */ +void U20_CDC_UartRx_Deal( void ) +{ + UINT16 i= 0; + if(!UploadPoint2_Busy) + { + Uart_Sendlenth = UartByteCount; + if(Uart_Sendlenth>0) + { + + if( (Uart_Sendlenth >= (UART_REV_LEN/4)) || Uart_Timecount > UART_TIMEOUT ) + { + if(Uart_Output_Point+Uart_Sendlenth>UART_REV_LEN) + { + Uart_Sendlenth = UART_REV_LEN - Uart_Output_Point; + } + if(Uart_Sendlenth > (UART_REV_LEN/4)) + { + Uart_Sendlenth = (UART_REV_LEN/4); + } + + UartByteCount -= Uart_Sendlenth; + memcpy(endp2Txbuff,&Receive_Uart_Buf[Uart_Output_Point],Uart_Sendlenth); + Uart_Output_Point+=Uart_Sendlenth; + if(Uart_Output_Point>=UART_REV_LEN) + { + Uart_Output_Point = 0; + } + + UploadPoint2_Busy = 1; + + R16_UEP2_T_LEN = Uart_Sendlenth; + R8_UEP2_TX_CTRL = (R8_UEP2_TX_CTRL & ~RB_UEP_TRES_MASK) | UEP_T_RES_ACK; + + Uart_Timecount = 0; + } + } + } +} + +/******************************************************************************* + * @fn U30_CDC_UartTx_Deal + * + * @brief usb3.0 CDC serial port sending data processing + * + * @return None + */ +void U30_CDC_UartTx_Deal( void ) +{ + static UINT16 i = 0; + + if(USBByteCount)//If there is any remaining data to be downloaded, it will be sent through the uart + { + UART2_SendString(&endp2Rxbuff[USBBufOutPoint++],1); + USBByteCount --; + } + + if( DownloadPoint2_Busy == 0 ) + { + if(USBByteCount == 0 && UploadPoint2_Busy == 0)//Allow Next Send + { + USBBufOutPoint = 0; + DownloadPoint2_Busy = 1; + USBSS->UEP2_RX_DMA = (UINT32)(UINT8 *)endp2Rxbuff; + USB30_OUT_ClearIT(ENDP_2); + USB30_OUT_Set( ENDP_2 , ACK , 1 ); + USB30_Send_ERDY( ENDP_2 | OUT , 1 ); + } + } +} + +/******************************************************************************* + * @fn U20_CDC_UartTx_Deal + * + * @brief usb2.0 CDC serial port sending data processing + * + * @return None + */ +void U20_CDC_UartTx_Deal( void ) +{ + static UINT16 i = 0; + if(USBByteCount) + { + UART2_SendString(&endp2Rxbuff[USBBufOutPoint++],1); + + USBByteCount--; + if(USBByteCount==0){ + USBBufOutPoint = 0; + R32_UEP2_RX_DMA = (UINT32)(UINT8 *)endp2Rxbuff; + R8_UEP2_RX_CTRL = (R8_UEP2_RX_CTRL &~RB_UEP_RRES_MASK)|UEP_R_RES_ACK; + } + } +} + +/******************************************************************************* + * @fn CDC_Uart_Deal + * + * @brief CDC processing function + * + * @return None + */ +void CDC_Uart_Deal( void ) +{ + if( Link_Sta == LINK_STA_1)//2.0 + { + U20_CDC_UartTx_Deal(); + U20_CDC_UartRx_Deal(); + } + else + { + U30_CDC_UartTx_Deal(); + U30_CDC_UartRx_Deal(); + } +} + +/******************************************************************************* + * @fn CDC_Variable_Clear + * + * @brief CDC variable initialization + * + * @return None + */ +void CDC_Variable_Clear(void){ + Uart_Input_Point = 0; + Uart_Output_Point = 0; + UartByteCount = 0; + USBByteCount = 0; + USBBufOutPoint = 0; + UploadPoint2_Busy = 0; + Uart_Timecount = 0; + Uart_Sendlenth = 0; +} + +/******************************************************************************* + * @fn UART2_IRQHandler + * + * @brief CDC serial port interrupt function + * + * @return None + */ +void UART2_IRQHandler(void) +{ + UINT8 i,rec_length; + UINT8 rec[7] = {0}; + + switch( UART2_GetITFlag() ) + { + case UART_II_LINE_STAT: //Line status error + printf("error:%x\n",R8_UART2_LSR); + break; + + case UART_II_RECV_RDY: //Data reaches the trigger point + for(rec_length = 0; rec_length < 7; rec_length++) + { + Receive_Uart_Buf[Uart_Input_Point++] = UART2_RecvByte(); + if(Uart_Input_Point>=UART_REV_LEN ) + { + Uart_Input_Point = 0; + } + } + UartByteCount += rec_length; + Uart_Timecount = 0; + + break; + case UART_II_RECV_TOUT: //Receive timeout + rec_length = UART2_RecvString(rec); + for(i = 0; i < rec_length ; i++) + { + Receive_Uart_Buf[Uart_Input_Point++] = rec[i]; + if(Uart_Input_Point>=UART_REV_LEN ) + { + Uart_Input_Point = 0; + } + } + UartByteCount += i; + Uart_Timecount = 0; + break; + + case UART_II_THR_EMPTY: //Send buffer empty + break; + + default: + break; + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/Makefile new file mode 100644 index 000000000..aba78b0ef --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_cdc.c USB20/CH56x_usb20.c USB30/CH56x_usb30.c CDC/cdc.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB20/CH56x_usb20.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB20/CH56x_usb20.c new file mode 100644 index 000000000..5d8204ec4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB20/CH56x_usb20.c @@ -0,0 +1,756 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb20.c +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "CH56x_common.h" +#include "CH56x_usb20.h" +#include "CH56x_usb30.h" +#include "CH56x_usb30_LIB.h" +#include "cdc.h" + +/* Global Variable */ +UINT32V U20_vitrul_buad = 115200; +UINT16V U20_EndpnMaxSize = 512; +UINT16V SetupReqLen=0; //Host request data length +UINT16V SetupLen = 0; //Data length actually sent or received in data phase +UINT32V seq_num = 0; +DevInfo_Typedef g_devInfo; +static UINT8V SetupReqType = 0; //Host request descriptor type +static UINT8V SetupReq = 0; //Host request descriptor type +static PUINT8 pDescr; +extern UINT8V Link_Sta; + +__attribute__ ((aligned(16))) UINT8 vendor_buff[16] __attribute__((section(".DMADATA"))); +/* Function declaration */ +void USBHS_IRQHandler(void) __attribute__((interrupt())); + +const UINT8 hs_device_descriptor[] = +{ + 0x12, // bLength + 0x01, // DEVICE descriptor type + 0x00, // 2.00 + 0x02, + 0x02, // device class + 0x00, // device sub-class + 0x00, // vendor specific protocol + 0x40, // max packet size 64B + 0x86, // vendor id-0x1A86(qinheng) + 0x1A, + 0x0c, // product id 0xfe0c + 0xfe, + 0x01, //bcdDevice 0x01 + 0x00, + 0x01, // manufacturer index string + 0x02, // product index string + 0x03, // serial number index string + 0x01 // number of configurations +}; + +const UINT8 hs_config_descriptor[] = +{ + 0x09, // length of this descriptor + 0x02, // CONFIGURATION (2) + 0x43, // total length includes endpoint descriptors (should be 1 more than last address) + 0x00, // total length high byte + 0x02, // number of interfaces + 0x01, // configuration value for this one + 0x00, // configuration - string is here, 0 means no string + 0x80, // attributes - bus powered, no wakeup + 0x32, // max power - 800 ma is 100 (64 hex) + + /*control interface*/ + 0x09, // length of the interface descriptor + 0x04, // INTERFACE (4) + 0x00, // Zero based index 0f this interface + 0x00, // Alternate setting value (?) + 0x01, // Number of endpoints (not counting 0) + 0x02, // Interface class, ff is vendor specific + 0x02, // Interface sub-class + 0x01, // Interface protocol + 0x00, // Index to string descriptor for this interface + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, + 0x01, + + 0x04, + 0x24, + 0x02, + 0x02, + + 0x05, + 0x24, + 0x06, + 0x00, + 0x01, + + + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x81, // endpoint direction (80 is in) and address + 0x03, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x40, // max packet size - 1024 bytes + 0x00, // max packet size - high + 0x01, // polling interval in milliseconds (1 for iso) + + + /*data interface*/ + 0x09, // length of the interface descriptor + 0x04, // INTERFACE (4) + 0x01, // Zero based index 0f this interface + 0x00, // Alternate setting value (?) + 0x02, // Number of endpoints (not counting 0) + 0x0a, // Interface class, ff is vendor specific + 0x00, // Interface sub-class + 0x00, // Interface protocol + 0x00, // Index to string descriptor for this interface + + //Endpoint 2 Descriptor + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x82, // endpoint direction (80 is in) and address + 0x02, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x02, // max packet size - high + 0x00, // polling interval in milliseconds (1 for iso) + + + //endp2_descriptor + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x02, // endpoint direction (00 is out) and address + 0x02, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x02, // max packet size - high + 0x00, // polling interval in milliseconds (1 for iso) + +}; + +/* Language Descriptor */ +const UINT8 hs_string_descriptor0[] = +{ + 0x04, // this descriptor length + 0x03, // descriptor type + 0x09, // Language ID 0 low byte + 0x04 // Language ID 0 high byte +}; + +/* Manufacturer Descriptor */ +const UINT8 hs_string_descriptor1[] = +{ + 0x08, // length of this descriptor + 0x03, + 'W', + 0x00, + 'C', + 0x00, + 'H', + 0x00 +}; + +/* Product Descriptor */ +const UINT8 hs_string_descriptor2[]= +{ + 38, //38 bytes + 0x03, //0x03 + 0x57, 0x00, //W + 0x43, 0x00, //C + 0x48, 0x00, //H + 0x20, 0x00, // + 0x55, 0x00, //U + 0x53, 0x00, //S + 0x42, 0x00, //B + 0x32, 0x00, //2 + 0x2e, 0x00, //. + 0x30, 0x00, //0 + 0x20, 0x00, // + 0x44, 0x00, //D + 0x45, 0x00, //E + 0x56, 0x00, //V + 0x49, 0x00, //I + 0x43, 0x00, //C + 0x45, 0x00, //E + 0x20, 0x00 // +}; + + +const UINT8 hs_bos_descriptor[] = +{ + 0x05, // length of this descriptor + 0x0f, // CONFIGURATION (2) + 0x16, // total length includes endpoint descriptors (should be 1 more than last address) + 0x00, // total length high byte + 0x02, // number of device cap + + 0x07, + 0x10, // DEVICE CAPABILITY type + 0x02, // USB2.0 EXTENSION + 0x02, + 0x00, + 0x00, + 0x00, + + 0x0a, // length of this descriptor + 0x10, // DEVICE CAPABILITY type + 0x03, // superspeed usb device capability + 0x00, // + 0x0e, // ss/hs/fs + 0x00, + 0x01, // the lowest speed is full speed + 0x0a, // u1 exit latency is 10us + 0xff, // u1 exit latency is 8us + 0x07 +}; + + + +/******************************************************************************* + * @fn USB20_Endp_Init + * + * @brief USB2.0 Endpoint initialization + * + * @return None + */ +void USB20_Endp_Init () // USBHS device endpoint initial +{ + R8_UEP4_1_MOD = RB_UEP1_TX_EN; + R8_UEP2_3_MOD = RB_UEP2_RX_EN | RB_UEP2_TX_EN ; + + R16_UEP0_MAX_LEN = 64; + R16_UEP1_MAX_LEN = 512; + R16_UEP2_MAX_LEN = 512; + + R32_UEP0_RT_DMA = (UINT32)(UINT8 *)endp0RTbuff; + R32_UEP1_TX_DMA = (UINT32)(UINT8 *)endp1RTbuff; + R32_UEP2_TX_DMA = (UINT32)(UINT8 *)endp2Txbuff; + R32_UEP2_RX_DMA = (UINT32)(UINT8 *)endp2Rxbuff; + + R16_UEP0_T_LEN = 0; + R8_UEP0_TX_CTRL = UEP_T_RES_NAK; + R8_UEP0_RX_CTRL = 0; + + R16_UEP1_T_LEN = 0; + R8_UEP1_TX_CTRL = UEP_T_RES_NAK ; + + R16_UEP2_T_LEN = U20_MAXPACKET_LEN; + R8_UEP2_TX_CTRL = UEP_T_RES_NAK | RB_UEP_T_TOG_0; + R8_UEP2_RX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_0; + +} + +/******************************************************************************* + * @fn USB20_Device_Init + * + * @brief USB2.0 Device initialization + * + * @param sta - ENABLE / DISABLE + * + * @return None + */ +void USB20_Device_Init ( FunctionalState sta ) // USBHS device initial +{ + UINT16 i; + UINT32 *p; + if(sta) + { + R8_USB_CTRL = 0; + R8_USB_CTRL = UCST_HS | RB_DEV_PU_EN | RB_USB_INT_BUSY |RB_USB_DMA_EN; + R8_USB_INT_EN = RB_USB_IE_SETUPACT | RB_USB_IE_TRANS | RB_USB_IE_SUSPEND |RB_USB_IE_BUSRST ; + USB20_Endp_Init(); + } + else + { + R8_USB_CTRL = RB_USB_CLR_ALL | RB_USB_RESET_SIE; + } +} + +/******************************************************************************* + * @fn USB20_Device_setaddress + * + * @brief USB2.0 Set device address + * + * @param address + * + * @return None + **/ +void USB20_Device_Setaddress( UINT32 address ) +{ + R8_USB_DEV_AD = address; // SET ADDRESS +} + +/******************************************************************************* + * @fn U20_NonStandard_Request_Deal + * + * @brief Non-standard request processing + * + * @return None + */ +UINT16 U20_NonStandard_Request_Deal() +{ + UINT16 len = 0; + switch( UsbSetupBuf->bRequest ) + { + /* Open the serial port and send the baud rate */ + case 0x20: + R8_UEP0_RX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_1; + break; + /* Read the current serial port configuration */ + case 0x21: + *(UINT32 *)&endp0RTbuff[0] = U20_vitrul_buad; + endp0RTbuff[4]=0x00;endp0RTbuff[5]=0x00;endp0RTbuff[6]=0x08; + len = 7; + break; + /* Close uart */ + case 0x22: + CDC_Variable_Clear(); + break; + case 0x02: + break; + default: + return USB_DESCR_UNSUPPORTED; + break; + } + return len; +} + +/******************************************************************************* + * @fn U20_Standard_Request_Deal + * + * @brief USB2.0 standard request deal + * + * @return None + */ +UINT16 U20_Standard_Request_Deal() +{ + UINT16 len = 0; + UINT8 endp_dir; + SetupLen = 0; + endp_dir = UsbSetupBuf->bRequestType & 0x80; + switch( SetupReq ) + { + case USB_GET_DESCRIPTOR: + { + switch( UsbSetupBuf->wValueH ) + { + case USB_DESCR_TYP_DEVICE: + pDescr = (UINT8 *)hs_device_descriptor; + SetupLen = ( SetupReqLen > sizeof(hs_device_descriptor) )? sizeof(hs_device_descriptor):SetupReqLen; + break; + case USB_DESCR_TYP_CONFIG: + pDescr = (UINT8 *)hs_config_descriptor; + SetupLen = ( SetupReqLen > sizeof(hs_config_descriptor) )? sizeof(hs_config_descriptor):SetupReqLen; + break; + case USB_DESCR_TYP_STRING: + switch( UsbSetupBuf->wValueL ) + { + case USB_DESCR_LANGID_STRING: + + pDescr = (UINT8 *)hs_string_descriptor0; + SetupLen = ( SetupReqLen > sizeof(hs_string_descriptor0) )? sizeof(hs_string_descriptor0):SetupReqLen; + break; + case USB_DESCR_VENDOR_STRING: + pDescr = (UINT8 *)hs_string_descriptor1; + SetupLen = ( SetupReqLen > sizeof(hs_string_descriptor1) )? sizeof(hs_string_descriptor1):SetupReqLen; + break; + case USB_DESCR_PRODUCT_STRING: + pDescr =(UINT8 *) hs_string_descriptor2; + SetupLen = ( SetupReqLen > sizeof(hs_string_descriptor2) )? sizeof(hs_string_descriptor2):SetupReqLen; + break; + case USB_DESCR_SERIAL_STRING: + break; + default: + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + break; + case USB_DESCR_TYP_BOS: + pDescr =(UINT8 *) hs_bos_descriptor; + SetupLen = ( SetupReqLen > sizeof(hs_bos_descriptor) )? sizeof(hs_bos_descriptor):SetupReqLen; + break; + + default : + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + } + break; + case USB_SET_ADDRESS: + g_devInfo.dev_addr = UsbSetupBuf->wValueL; + break; + case USB_GET_CONFIGURATION: + endp0RTbuff[ 0 ] = g_devInfo.dev_config_value; + SetupLen = 1; + break; + + case USB_SET_CONFIGURATION: + if( (R8_USB_SPD_TYPE & RB_USBSPEED_MASK) == UST_FS ) + { + U20_EndpnMaxSize = 64; + } + else if( (R8_USB_SPD_TYPE & RB_USBSPEED_MASK) == UST_LS ) + { + U20_EndpnMaxSize = 8; + } + g_devInfo.dev_config_value = UsbSetupBuf->wValueL; + g_devInfo.dev_enum_status = 0x01; + break; + case USB_CLEAR_FEATURE: + if( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) + { + switch( UsbSetupBuf->wIndexL ) + { + case 0x82: + R16_UEP2_T_LEN= 0; + R8_UEP2_TX_CTRL = UEP_T_RES_NAK | RB_UEP_T_TOG_0; + break; + case 0x02: + R8_UEP2_TX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_0; + break; + case 0x81: + R16_UEP1_T_LEN = 0; + R8_UEP1_TX_CTRL = UEP_T_RES_NAK | RB_UEP_T_TOG_0; + break; + case 0x01: + R8_UEP1_RX_CTRL = UEP_T_RES_ACK | RB_UEP_R_TOG_0; + break; + default: + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + } + else if( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE ) + { + if( ( UsbSetupBuf->wValueL ) == 1 ) + { + g_devInfo.dev_sleep_status &= ~0x01; + } + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + break; + case USB_SET_FEATURE: + if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x00 ) + { + if( UsbSetupBuf->wValueL == 0x01 ) + { + if( hs_config_descriptor[ 7 ] & 0x20 ) + { + g_devInfo.dev_sleep_status = 0x01; + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + } + else if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x02 ) + { + if( UsbSetupBuf->wValueL == 0x00 ) + { + switch( UsbSetupBuf->wIndexL ) + { + case 0x82: + R8_UEP2_TX_CTRL = ( R8_UEP2_TX_CTRL & ~RB_UEP_TRES_MASK ) | UEP_T_RES_STALL; + break; + + case 0x02: + R8_UEP2_RX_CTRL = ( R8_UEP2_RX_CTRL & ~RB_UEP_RRES_MASK ) | UEP_R_RES_STALL; + break; + + case 0x81: + R8_UEP1_TX_CTRL = ( R8_UEP1_TX_CTRL & ~RB_UEP_TRES_MASK ) | UEP_T_RES_STALL; + break; + + case 0x01: + R8_UEP1_RX_CTRL = ( R8_UEP1_RX_CTRL & ~RB_UEP_RRES_MASK ) | UEP_R_RES_STALL; + break; + + default: + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + break; + case USB_GET_INTERFACE: + break; + case USB_SET_INTERFACE: + break; + case USB_GET_STATUS: + endp0RTbuff[ 0 ] = 0x00; + endp0RTbuff[ 1 ] = 0x00; + SetupLen = 2; + if( UsbSetupBuf->wIndexL == 0x81 ) + { + if( ( R8_UEP1_TX_CTRL & RB_UEP_TRES_MASK ) == UEP_T_RES_STALL ) + { + endp0RTbuff[ 0 ] = 0x01; + SetupLen = 1; + } + } + else if( UsbSetupBuf->wIndexL == 0x01 ) + { + if( ( R8_UEP1_RX_CTRL & RB_UEP_RRES_MASK ) == UEP_R_RES_STALL ) + { + endp0RTbuff[ 0 ] = 0x01; + SetupLen = 1; + } + } + else if( UsbSetupBuf->wIndexL == 0x82 ) + { + if( ( R8_UEP2_TX_CTRL & RB_UEP_TRES_MASK ) == UEP_T_RES_STALL ) + { + endp0RTbuff[ 0 ] = 0x01; + SetupLen = 1; + } + } + else if( UsbSetupBuf->wIndexL == 0x02 ) + { + if( ( R8_UEP2_RX_CTRL & RB_UEP_RRES_MASK ) == UEP_R_RES_STALL ) + { + endp0RTbuff[ 0 ] = 0x01; + SetupLen = 1; + } + } + break; + default: + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + + if( (SetupLen != USB_DESCR_UNSUPPORTED) && (SetupLen != 0)) + { + len = ( SetupLen >= U20_UEP0_MAXSIZE ) ? U20_UEP0_MAXSIZE : SetupLen; + if(endp_dir) + { + memcpy( endp0RTbuff, pDescr, len ); + pDescr += len; + } + SetupLen -= len; + } + return len; +} + +/******************************************************************************* + * @fn USBHSD_IRQHandler + * + * @brief USB2.0 Interrupt Handler. + * + * @return None + */ +void USBHS_IRQHandler(void) //USBHS interrupt service +{ + UINT32 end_num; + UINT32 rx_token; + UINT16 ret_len,i; + UINT16 rxlen; + UINT8 *p8; + UINT8 int_flg; + UINT32 baudrate; + + int_flg = R8_USB_INT_FG; + if( int_flg & RB_USB_IF_SETUOACT ) //SETUP interrupt + { +#if 0 + printf("SETUP :"); + p8 = (UINT8 *)endp0RTbuff; + for(i=0; i<8; i++) { printf("%02x ", *p8++); } + printf("\n"); +#endif + SetupReqType = UsbSetupBuf->bRequestType; + SetupReq = UsbSetupBuf->bRequest; + SetupReqLen = UsbSetupBuf->wLength; //Data length + + /*Analyze host requests*/ + if((UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK) != USB_REQ_TYP_STANDARD) + { + ret_len = U20_NonStandard_Request_Deal(); + } + else + { + ret_len = U20_Standard_Request_Deal(); + } + if(ret_len == 0xFFFF) + { + R16_UEP0_T_LEN = 0; + R8_UEP0_TX_CTRL = UEP_T_RES_STALL ; + R8_UEP0_RX_CTRL = UEP_R_RES_STALL ; + } + else + { + R16_UEP0_T_LEN = ret_len; + R8_UEP0_TX_CTRL = UEP_T_RES_ACK | RB_UEP_T_TOG_1; + R8_UEP0_RX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_1; + } + R8_USB_INT_FG = RB_USB_IF_SETUOACT; // clear int flag + } + /*Transaction transfer complete interrupt*/ + else if( int_flg & RB_USB_IF_TRANSFER ) + { + end_num = R8_USB_INT_ST & 0xf; + rx_token = ( (R8_USB_INT_ST )>>4) & 0x3; +#if 0 + if( !(R8_USB_INT_ST & RB_USB_ST_TOGOK) ) + { + printf(" TOG MATCH FAIL : ENDP %x token %x \n", end_num, rx_token); + } +#endif + switch( end_num ) + { + case 0: + if( rx_token == PID_IN ) + { + ret_len = U20_Endp0_IN_Callback(); + if(ret_len == 0) + { + R8_UEP0_RX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_1; + R16_UEP0_T_LEN = 0; + R8_UEP0_TX_CTRL = 0; + } + else + { + R16_UEP0_T_LEN = ret_len; + R8_UEP0_TX_CTRL ^= RB_UEP_T_TOG_1; + R8_UEP0_TX_CTRL = ( R8_UEP0_TX_CTRL &~RB_UEP_TRES_MASK )| UEP_T_RES_ACK ; + } + } + else if( rx_token == PID_OUT ) + { + SetupLen -= SetupLen > R16_USB_RX_LEN ? R16_USB_RX_LEN :SetupLen; + if( SetupLen > 0 ) + { + R8_UEP0_RX_CTRL ^=RB_UEP_R_TOG_1; + R8_UEP0_RX_CTRL = ( R8_UEP0_RX_CTRL &~RB_UEP_RRES_MASK) | UEP_R_RES_ACK; + + } + else + { + R16_UEP0_T_LEN = 0; + R8_UEP0_TX_CTRL = UEP_T_RES_ACK | RB_UEP_T_TOG_1; + R8_UEP0_RX_CTRL = 0 ; + } + + /* save bauds */ + baudrate = endp0RTbuff[ 0 ]; + baudrate += ((UINT32)endp0RTbuff[ 1 ] << 8 ); + baudrate += ((UINT32)endp0RTbuff[ 2 ] << 16 ); + baudrate += ((UINT32)endp0RTbuff[ 3 ] << 24 ); + + U20_vitrul_buad = baudrate; + + CDC_Uart_Init(baudrate); + + } + break; + case 1: + break; + case 2: + if(rx_token == PID_IN) + { + R16_UEP2_T_LEN = 0; + R8_UEP2_TX_CTRL ^= RB_UEP_T_TOG_1; + R8_UEP2_TX_CTRL = (R8_UEP2_TX_CTRL & ~RB_UEP_TRES_MASK) | UEP_T_RES_NAK; + UploadPoint2_Busy = 0; + } + else if(rx_token == PID_OUT) + { + USBByteCount = R16_USB_RX_LEN; + R8_UEP2_RX_CTRL ^= RB_UEP_R_TOG_1; + R8_UEP2_RX_CTRL = (R8_UEP2_RX_CTRL &~RB_UEP_RRES_MASK) | UEP_R_RES_NAK; + } + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + case 7: + break; + default: + break; + + } + R8_USB_INT_FG = RB_USB_IF_TRANSFER; + } + else if( int_flg & RB_USB_IF_BUSRST ) + { + USB20_Endp_Init(); + USB20_Device_Setaddress( 0 ); + R8_USB_INT_FG = RB_USB_IF_BUSRST; + if( Link_Sta == LINK_STA_1 ) + { + PFIC_EnableIRQ(USBSS_IRQn); + PFIC_EnableIRQ(LINK_IRQn); + PFIC_EnableIRQ(TMR0_IRQn); + R8_TMR0_INTER_EN = 1; + TMR0_TimerInit( 67000000 ); + USB30D_init(ENABLE); + } + } + else if( int_flg & RB_USB_IF_SUSPEND ) + { + R8_USB_INT_FG = RB_USB_IF_SUSPEND; + } +} + +/******************************************************************************* + * @fn U20_Endp0_IN_Callback + * + * @brief U20_Endp0_IN_Callback Handler. + * + * @return None + */ +UINT16 U20_Endp0_IN_Callback(void) +{ + UINT16 len = 0; + switch(SetupReq) + { + case USB_GET_DESCRIPTOR: + len = SetupLen >= U20_UEP0_MAXSIZE ? U20_UEP0_MAXSIZE : SetupLen; + memcpy(endp0RTbuff, pDescr, len); + SetupLen -= len; + pDescr += len; + break; + case USB_SET_ADDRESS: + USB20_Device_Setaddress(g_devInfo.dev_addr); + break; + default: + break; + } + return len; +} + + diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/CH56x_usb30.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/CH56x_usb30.c new file mode 100644 index 000000000..0fc14fb61 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/CH56x_usb30.c @@ -0,0 +1,832 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb30.c +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "CH56x_common.h" +#include "CH56x_usb30_LIB.h" +#include "CH56x_usb20.h" +#include "CH56x_usb30.h" +#include "cdc.h" + +/* Global Variable */ +UINT8V Tx_Lmp_Port = 0; +UINT8V Link_Sta = 0; +UINT32V vitrul_buad = 115200; +static UINT32 SetupLen = 0; +static UINT8 SetupReqCode = 0; +static PUINT8 pDescr; +__attribute__ ((aligned(16))) UINT8 endp0RTbuff[512] __attribute__((section(".DMADATA"))); //Endpoint 0 data receiving and sending buffer +__attribute__ ((aligned(16))) UINT8 endp1RTbuff[4096] __attribute__((section(".DMADATA"))); //Endpoint 1 data receiving and sending buffer +__attribute__ ((aligned(16))) UINT8 endp2Rxbuff[4096] __attribute__((section(".DMADATA"))); //Endpoint 2 data receiving and sending buffer +__attribute__ ((aligned(16))) UINT8 endp2Txbuff[4096] __attribute__((section(".DMADATA"))); //Endpoint 2 data receiving and sending buffer + + +/*Superspeed device descriptor*/ +const UINT8 SS_DeviceDescriptor[] = +{ + 0x12, // bLength + 0x01, // DEVICE descriptor type + 0x00, // 3.00 + 0x03, + 0x02, // device class + 0x00, // device sub-class + 0x00, // vendor specific protocol + 0x09, // max packet size 512B + 0x86, // vendor id 0x1a86 + 0x1a, + 0x0c, // product id 0xfe0c + 0xfe, + 0x01, // bcdDevice + 0x00, + 0x01, // manufacturer index string + 0x02, // product index string + 0x03, // serial number index string + 0x01 // number of configurations +}; + +/*Superspeed Configuration Descriptor*/ +const UINT8 SS_ConfigDescriptor[] = +{ + 0x09, // length of this descriptor + 0x02, // CONFIGURATION (2) + 85, // total length includes endpoint descriptors (should be 1 more than last address) + 0x00, // total length high byte + 0x02, // number of interfaces + 0x01, // configuration value for this one + 0x00, // configuration - string is here, 0 means no string + 0x80, // attributes - bus powered, no wakeup + 0x64, // max power - 800 ma is 100 (64 hex) + + + 0x09, // length of the interface descriptor + 0x04, // INTERFACE (4) + 0x00, // Zero based index 0f this interface + 0x00, // Alternate setting value (?) + 0x01, // Number of endpoints (not counting 0) + 0x02, // Interface class, ff is vendor specific + 0x02, // Interface sub-class + 0x01, // Interface protocol + 0x00, // Index to string descriptor for this interface + + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, + 0x01, + + 0x04, + 0x24, + 0x02, + 0x02, + + 0x05, + 0x24, + 0x06, + 0x00, + 0x01, + + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x81, // endpoint direction (80 is in) and address + 0x03, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x04, // max packet size - high + 0x08, // polling interval in milliseconds (1 for iso) + + 0x06, // length of this endpoint compansion descriptor + 0x30, + 0x00, // max burst size + 0x00, // no stream + 0x00, + 0x00, + + 0x09, // length of the interface descriptor + 0x04, // INTERFACE (4) + 0x01, // Zero based index 0f this interface + 0x00, // Alternate setting value (?) + 0x02, // Number of endpoints (not counting 0) + 0x0a, // Interface class, ff is vendor specific + 0x00, // Interface sub-class + 0x00, // Interface protocol + 0x00, // Index to string descriptor for this interface + + //Endpoint 2 Descriptor + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x82, // endpoint direction (80 is in) and address + 0x02, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x04, // max packet size - high + 0x00, // polling interval in milliseconds (1 for iso) + + 0x06, // length of this endpoint compansion descriptor + 0x30, + 0x00, // max burst size + 0x00, // no stream + 0x00, + 0x00, + + //endp2_descriptor + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x02, // endpoint direction (00 is out) and address + 0x02, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x04, // max packet size - high + 0x00, // polling interval in milliseconds (1 for iso) + + 0x06, // length of this endpoint compansion descriptor + 0x30, + 0x00, // max burst size + 0x00, // no stream + 0x00, + 0x00 +}; + +/*String Descriptor Lang ID*/ +const UINT8 StringLangID[] = +{ + 0x04, // this descriptor length + 0x03, // descriptor type + 0x09, // Language ID 0 low byte + 0x04 // Language ID 0 high byte +}; + +/*String Descriptor Vendor*/ +const UINT8 StringVendor[] = +{ + 0x08, // length of this descriptor + 0x03, + 'W', + 0x00, + 'C', + 0x00, + 'H', + 0x00 +}; + + +/*String Descriptor Product*/ +const UINT8 StringProduct[]= +{ + 38, //38 bytes in length + 0x03, //Type code + 0x57, 0x00, //W + 0x43, 0x00, //C + 0x48, 0x00, //H + 0x20, 0x00, // + 0x55, 0x00, //U + 0x53, 0x00, //S + 0x42, 0x00, //B + 0x33, 0x00, //3 + 0x2e, 0x00, //. + 0x30, 0x00, //0 + 0x20, 0x00, // + 0x44, 0x00, //D + 0x45, 0x00, //E + 0x56, 0x00, //V + 0x49, 0x00, //I + 0x43, 0x00, //C + 0x45, 0x00, //E + 0x20, 0x00 +}; + +/*String Descriptor Serial*/ +UINT8 StringSerial[] = +{ + 0x16, // length of this descriptor + 0x03, + '0', + 0x00, + '1', + 0x00, + '2', + 0x00, + '3', + 0x00, + '4', + 0x00, + '5', + 0x00, + '6', + 0x00, + '7', + 0x00, + '8', + 0x00, + '9', + 0x00, +}; + +const UINT8 OSStringDescriptor[] = +{ + 0x12, // length of this descriptor + 0x03, + 'M', + 0x00, + 'S', + 0x00, + 'F', + 0x00, + 'T', + 0x00, + '1', + 0x00, + '0', + 0x00, + '0', + 0x00, + 0x01, + 0x00 +}; + +const UINT8 BOSDescriptor[] = +{ + 0x05, // length of this descriptor + 0x0f, // CONFIGURATION (2) + 0x16, // total length includes endpoint descriptors (should be 1 more than last address) + 0x00, // total length high byte + 0x02, // number of device cap + + //dev_cap_descriptor1 + 0x07, + 0x10, // DEVICE CAPABILITY type + 0x02, // USB2.0 EXTENSION + 0x06, + 0x00, + 0x00, + 0x00, + + //dev_cap_descriptor2 + 0x0a, // length of this descriptor + 0x10, // DEVICE CAPABILITY type + 0x03, // superspeed usb device capability + 0x00, // + 0x0e, // ss/hs/fs + 0x00, + 0x01, // the lowest speed is full speed + 0x0a, // u1 exit latency is 10us + 0xff, // u1 exit latency is 8us + 0x07 +}; + +/******************************************************************************* + * @fn USB30D_init + * + * @brief USB3.0 initialization + * + * @return None + */ +void USB30D_init(FunctionalState sta) { + UINT16 i,s; + if (sta) { + USB30_Device_Init(); + + USBSS->UEP0_DMA = (UINT32)(UINT8 *)endp0RTbuff; + USBSS->UEP1_TX_DMA = (UINT32)(UINT8 *)endp1RTbuff; + USBSS->UEP2_TX_DMA = (UINT32)(UINT8 *)endp2Txbuff; + USBSS->UEP2_RX_DMA = (UINT32)(UINT8 *)endp2Rxbuff; + + USBSS->UEP_CFG = EP0_R_EN | EP0_T_EN | EP1_T_EN | EP2_R_EN | EP2_T_EN;// set end point rx/tx enable + + USB30_OUT_Set(ENDP_2, ACK, 1); + + } + else { + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_CFG = PIPE_RESET | LFPS_RX_PD; + USBSS->LINK_CTRL = GO_DISABLED | POWER_MODE_3; + USBSS->LINK_INT_CTRL = 0; + USB30_Device_forceclr(); + } +} + +/******************************************************************************* + * @fn USB30_NonStandardReq + * + * @brief USB3.0 Nonstandard request processing function + * + * @return Length + */ +UINT16 USB30_NonStandardReq() { + UINT16 len = 0; + + SetupReqCode = UsbSetupBuf->bRequest; + SetupLen = UsbSetupBuf->wLength; + switch (SetupReqCode) { + + /* Open the serial port and send the baud rate */ + case 0x20: + USB30_OUT_Set(ENDP_0, ACK, 1 ); + break; + /* Read the current serial port configuration */ + case 0x21: + *(UINT32 *)&endp0RTbuff[50] = vitrul_buad; + endp0RTbuff[54]=0x00;endp0RTbuff[55]=0x00;endp0RTbuff[56]=0x08; + SetupLen = 7; + break; + /* Close uart */ + case 0x22: + CDC_Variable_Clear(); + break; + default: + printf("stall\n"); + SetupReqCode = INVALID_REQ_CODE; + return USB_DESCR_UNSUPPORTED; + break; + } + len = SetupLen >= ENDP0_MAXPACK ? ENDP0_MAXPACK : SetupLen; + memcpy(endp0RTbuff, &endp0RTbuff[50], len); + SetupLen -= len; + pDescr += len; + return len; +} + +/******************************************************************************* + * @fn USB30_StandardReq + * + * @brief USB3.0 Standard request + * + * @return Length + */ +UINT16 USB30_StandardReq() { + UINT16 len = 0; + + SetupReqCode = UsbSetupBuf->bRequest; + SetupLen = UsbSetupBuf->wLength; + + if (( UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK) != USB_REQ_TYP_STANDARD) + { + len= USB30_NonStandardReq(); + } + else + { + switch (SetupReqCode) { + case USB_GET_DESCRIPTOR: + switch (UsbSetupBuf->wValueH) { + case USB_DESCR_TYP_DEVICE: + if (SetupLen > SIZE_DEVICE_DESC) + SetupLen = SIZE_DEVICE_DESC; + pDescr = (PUINT8) SS_DeviceDescriptor; + break; + case USB_DESCR_TYP_CONFIG: + if (SetupLen > SIZE_CONFIG_DESC) + SetupLen = SIZE_CONFIG_DESC; + pDescr = (PUINT8) SS_ConfigDescriptor; + break; + case USB_DESCR_TYP_BOS: + if (SetupLen > SIZE_BOS_DESC) + SetupLen = SIZE_BOS_DESC; + pDescr = (PUINT8) BOSDescriptor; + break; + case USB_DESCR_TYP_STRING: + switch (UsbSetupBuf->wValueL) { + case USB_DESCR_LANGID_STRING: + if (SetupLen > SIZE_STRING_LANGID) + SetupLen = SIZE_STRING_LANGID; + pDescr = (PUINT8) StringLangID; + break; + case USB_DESCR_VENDOR_STRING: + if (SetupLen > SIZE_STRING_VENDOR) + SetupLen = SIZE_STRING_VENDOR; + pDescr = (PUINT8) StringVendor; + break; + case USB_DESCR_PRODUCT_STRING: + if (SetupLen > SIZE_STRING_PRODUCT) + SetupLen = SIZE_STRING_PRODUCT; + pDescr = (PUINT8) StringProduct; + break; + case USB_DESCR_SERIAL_STRING: + if (SetupLen > SIZE_STRING_SERIAL) + SetupLen = SIZE_STRING_SERIAL; + pDescr = (PUINT8) StringSerial; + break; + case USB_DESCR_OS_STRING: + if (SetupLen > SIZE_STRING_OS) + SetupLen = SIZE_STRING_OS; + pDescr = (PUINT8) OSStringDescriptor; + break; + default: + len = USB_DESCR_UNSUPPORTED; + SetupReqCode = INVALID_REQ_CODE; + break; + } + break; + default: + len = USB_DESCR_UNSUPPORTED; + SetupReqCode = INVALID_REQ_CODE; + break; + } + len = SetupLen >= ENDP0_MAXPACK ? ENDP0_MAXPACK : SetupLen; + memcpy(endp0RTbuff, pDescr, len); + SetupLen -= len; + pDescr += len; + break; + case USB_SET_ADDRESS: + SetupLen = UsbSetupBuf->wValueL; + break; + case 0x31: + SetupLen = UsbSetupBuf->wValueL; + break; + case 0x30: + break; + case USB_SET_CONFIGURATION: + break; + case USB_GET_STATUS: + len = 2; + endp0RTbuff[0] = 0x01; + endp0RTbuff[1] = 0x00; + SetupLen = 0; + break; + case USB_CLEAR_FEATURE: + switch(UsbSetupBuf->wIndexL){ + case 0x82: + USB30_IN_ClearIT( ENDP_2 ); + USB30_IN_Set( ENDP_2 , ENABLE , ACK , 1 , 0); + USB30_Send_ERDY( ENDP_2 | IN , 1 ); + break; + } + break; + case USB_SET_FEATURE: + break; + case USB_SET_INTERFACE: + break; + default: + len = USB_DESCR_UNSUPPORTED; + SetupReqCode = INVALID_REQ_CODE; + printf(" stall \n"); + break; + } + } + return len; +} + +/******************************************************************************* + * @fn EP0_IN_Callback + * + * @brief USB3.0 Endpoint 0 IN transaction callback + * + * @return Send length + */ +UINT16 EP0_IN_Callback(void) { + UINT16 len = 0; + switch (SetupReqCode) { + case USB_GET_DESCRIPTOR: + len = SetupLen >= ENDP0_MAXPACK ? ENDP0_MAXPACK : SetupLen; + memcpy(endp0RTbuff, pDescr, len); + SetupLen -= len; + pDescr += len; + break; + } + return len; +} + +/******************************************************************************* + * @fn EP0_OUT_Callback + * + * @brief USB3.0 Endpoint 0 OUT transaction callback + * + * @return Length + */ +UINT16 EP0_OUT_Callback() { + UINT32 baudrate; + + /* save bauds */ + baudrate = endp0RTbuff[ 0 ]; + baudrate += ((UINT32)endp0RTbuff[ 1 ] << 8 ); + baudrate += ((UINT32)endp0RTbuff[ 2 ] << 16 ); + baudrate += ((UINT32)endp0RTbuff[ 3 ] << 24 ); + + vitrul_buad = baudrate; + + CDC_Uart_Init(baudrate); + + return 0; +} + +/******************************************************************************* + * @fn USB30_Setup_Status + * + * @brief USB3.0 Control transfer status stage callback + * + * @return None + */ +void USB30_Setup_Status(void) { + switch (SetupReqCode) { + case USB_SET_ADDRESS: + USB30_Device_Setaddress(SetupLen); // SET ADDRESS + break; + case 0x31: + break; + } +} + +/******************************************************************************* + * @fn USBSS_IRQHandler + * + * @brief USB3.0 Interrupt Handler. + * + * @return None + */ +void USBSS_IRQHandler (void) //USBSS interrupt service +{ + USB30_IRQHandler(); +} + +/******************************************************************************* + * @fn TMR0_IRQHandler + * + * @brief USB3.0 Connection failure timeout processing + * + * @return None + */ +void TMR0_IRQHandler( ) +{ + R8_TMR0_INTER_EN |= 1; + PFIC_DisableIRQ(TMR0_IRQn); + R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR; + if(Link_Sta == LINK_STA_1 ) + { + Link_Sta =0; + PFIC_DisableIRQ(USBSS_IRQn); + PFIC_DisableIRQ(LINK_IRQn); + USB30D_init(DISABLE); + return; + } + if( Link_Sta != LINK_STA_3 ) + { + PFIC_DisableIRQ(USBSS_IRQn); + PFIC_DisableIRQ(LINK_IRQn); + USB30D_init(DISABLE); + R32_USB_CONTROL = 0; + PFIC_EnableIRQ(USBHS_IRQn); + USB20_Device_Init(ENABLE); + } + Link_Sta = LINK_STA_1; + return; +} + + +/******************************************************************************* + * @fn LINK_IRQHandler + * + * @brief USB3.0 Link Interrupt Handler. + * + * @return None + */ +void LINK_IRQHandler() //USBSS link interrupt service +{ + if(USBSS->LINK_INT_FLAG & LINK_Ux_EXIT_FLAG) // device enter U2 + { + USBSS->LINK_CFG = CFG_EQ_EN | TX_SWING | DEEMPH_CFG | TERM_EN; + USB30_Switch_Powermode(POWER_MODE_0); + USBSS->LINK_INT_FLAG = LINK_Ux_EXIT_FLAG; + } + if(USBSS->LINK_INT_FLAG & LINK_RDY_FLAG) // POLLING SHAKE DONE + { + USBSS->LINK_INT_FLAG = LINK_RDY_FLAG; + if(Tx_Lmp_Port) // LMP, TX PORT_CAP & RX PORT_CAP + { + USBSS->LMP_TX_DATA0 = LINK_SPEED | PORT_CAP | LMP_HP; + USBSS->LMP_TX_DATA1 = UP_STREAM | NUM_HP_BUF; + USBSS->LMP_TX_DATA2 = 0x0; + Tx_Lmp_Port = 0; + } + /*Successful USB3.0 communication*/ + Link_Sta = LINK_STA_3; + PFIC_DisableIRQ(TMR0_IRQn); + R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR; + R8_TMR0_INTER_EN = 0; + PFIC_DisableIRQ(USBHS_IRQn); + USB20_Device_Init(DISABLE); + } + + if(USBSS->LINK_INT_FLAG & LINK_INACT_FLAG) + { + Link_Sta = 0; + PFIC_EnableIRQ(USBSS_IRQn); + PFIC_EnableIRQ(LINK_IRQn); + PFIC_EnableIRQ(TMR0_IRQn); + R8_TMR0_INTER_EN = RB_TMR_IE_CYC_END; + TMR0_TimerInit( 67000000 ); + USB30D_init(ENABLE); + USBSS->LINK_INT_FLAG = LINK_INACT_FLAG; + USB30_Switch_Powermode(POWER_MODE_2); + } + if(USBSS->LINK_INT_FLAG & LINK_DISABLE_FLAG) // GO DISABLED + { + USBSS->LINK_INT_FLAG = LINK_DISABLE_FLAG; + Link_Sta = LINK_STA_1; + USB30D_init(DISABLE); + PFIC_DisableIRQ(USBSS_IRQn); + R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR; + R8_TMR0_INTER_EN = 0; + PFIC_DisableIRQ(TMR0_IRQn); + PFIC_EnableIRQ(USBHS_IRQn); + USB20_Device_Init(ENABLE); + } + if(USBSS->LINK_INT_FLAG & LINK_RX_DET_FLAG) + { + USBSS->LINK_INT_FLAG = LINK_RX_DET_FLAG; + USB30_Switch_Powermode(POWER_MODE_2); + } + if(USBSS->LINK_INT_FLAG & TERM_PRESENT_FLAG) // term present , begin POLLING + { + USBSS->LINK_INT_FLAG = TERM_PRESENT_FLAG; + if(USBSS->LINK_STATUS & LINK_PRESENT) + { + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_CTRL |= POLLING_EN; + } + else + { + USBSS->LINK_INT_CTRL = 0; + } + } + if(USBSS->LINK_INT_FLAG & LINK_TXEQ_FLAG) // POLLING SHAKE DONE + { + Tx_Lmp_Port = 1; + USBSS->LINK_INT_FLAG = LINK_TXEQ_FLAG; + USB30_Switch_Powermode(POWER_MODE_0); + } + if(USBSS->LINK_INT_FLAG & WARM_RESET_FLAG) + { + USBSS->LINK_INT_FLAG = WARM_RESET_FLAG; + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_CTRL |= TX_WARM_RESET; + while(USBSS->LINK_STATUS & RX_WARM_RESET); + USBSS->LINK_CTRL &= ~TX_WARM_RESET; + USB30_Device_Setaddress(0); + + } + if(USBSS->LINK_INT_FLAG & HOT_RESET_FLAG) //The host may send hot reset,Note the configuration of the endpoint + { + USBSS->USB_CONTROL |= 1 << 31; + USBSS->LINK_INT_FLAG = HOT_RESET_FLAG; // HOT RESET begin + USBSS->UEP0_TX_CTRL = 0; + USB30_IN_Set(ENDP_1, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_2, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_3, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_4, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_5, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_6, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_7, DISABLE, NRDY, 0, 0); + USB30_OUT_Set(ENDP_1, NRDY, 0); + USB30_OUT_Set(ENDP_2, NRDY, 0); + USB30_OUT_Set(ENDP_3, NRDY, 0); + USB30_OUT_Set(ENDP_4, NRDY, 0); + USB30_OUT_Set(ENDP_5, NRDY, 0); + USB30_OUT_Set(ENDP_6, NRDY, 0); + USB30_OUT_Set(ENDP_7, NRDY, 0); + + USB30_Device_Setaddress(0); + USBSS->LINK_CTRL &= ~TX_HOT_RESET; // HOT RESET end + } + if(USBSS->LINK_INT_FLAG & LINK_GO_U1_FLAG) // device enter U1 + { + USB30_Switch_Powermode(POWER_MODE_1); + USBSS->LINK_INT_FLAG = LINK_GO_U1_FLAG; + } + if(USBSS->LINK_INT_FLAG & LINK_GO_U2_FLAG) // device enter U2 + { + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_INT_FLAG = LINK_GO_U2_FLAG; + } + if(USBSS->LINK_INT_FLAG & LINK_GO_U3_FLAG) // device enter U2 + { + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_INT_FLAG = LINK_GO_U3_FLAG; + } +} + +/******************************************************************************* + * @fn EP2_OUT_Callback + * + * @brief USB3.0 endpoint2 out callback. + * + * @return None + */ +void EP2_OUT_Callback() +{ + UINT16 rx_len; + UINT8 nump; + UINT8 status; + USB30_OUT_Status(ENDP_2,&nump,&rx_len,&status); + + USBByteCount = rx_len; + USB30_OUT_ClearIT(ENDP_2); + USB30_OUT_Set( ENDP_2 , NRDY , 0 ); + + DownloadPoint2_Busy = 0; +} + +/******************************************************************************* + * @fn EP2_IN_Callback + * + * @brief USB3.0 endpoint2 in callback. + * + * @return None + */ +void EP2_IN_Callback() +{ + UINT8 nump; + USB30_IN_ClearIT( ENDP_2 ); + USB30_IN_Set( ENDP_2 , ENABLE , NRDY , 0 , 0); + UploadPoint2_Busy = 0; +} + + +/***************Endpointn IN Transaction Processing*******************/ +void EP1_IN_Callback() +{ + +} + +void EP3_IN_Callback() +{ + +} + + +void EP4_IN_Callback() +{ + +} + + +void EP5_IN_Callback() +{ + +} + + +void EP6_IN_Callback() +{ + +} + + +void EP7_IN_Callback() +{ + +} + + +/***************Endpointn OUT Transaction Processing*******************/ +void EP1_OUT_Callback() +{ + +} + +void EP3_OUT_Callback() +{ + +} + +void EP4_OUT_Callback() +{ + +} + + +void EP5_OUT_Callback() +{ + +} + + +void EP6_OUT_Callback() +{ + +} + + +void EP7_OUT_Callback() +{ + +} + +/******************************************************************************* + * @fn USB30_ITP_Callback + * + * @brief USB3.0 ITP callback function + * + * @return None + */ +void USB30_ITP_Callback(UINT32 ITPCounter) +{ + +} diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/libCH56x_USB30_device_lib.a b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/libCH56x_USB30_device_lib.a new file mode 100644 index 0000000000000000000000000000000000000000..eaf065736457199e6d770310212775f0992082c4 GIT binary patch literal 44868 zcmeHw34Bylp6;n6l?sRu5(LC(7Zh7F37w4u9NVdogd(gl35$w`P$>d-SSEz6pV)yA z5EP=u1r;4!o-nrKvlXq3qfG=!P!SheL9tt0Fx@`8M;$_9KbQA?XQ?_V5=Eb{b>5qk z->Lh3|MNe~J@?$RpPRuKl~wr{T-@_#?#?DHD?4j!_P8-=16-9-5FV_W0jA& zJ%tcY3(Z|SvMYWk1nn=6 zEBmV&AtLSii9-A>>@9PJ_&U3Nq!8c5-g~nUe>*#)czi}`X>jv?NlD9EL&}~OA1T# z7njYe3`pgv)ARC6i%W7!W)y3M=`%`7i>u43moKvg0h0te=T-*FstQUhcPS}E%nKJ+ zbaE&tnO|8}Vd9=vs#6peAmw4wWiSQPA|iw!GT3R$7cJGnAV8S~rON{UxOn-Zc>$B1 z#YkRheo@|~T2W^@^vlZ2s{+f+{T8oWSnXd>TDW9oplZ>Q@_<&a2voyIj#gb(4KM#_ zQeJe)#InWZm56F-{?dZQ)uqTK0}G~!(o%RXoiJfaj;|PGnN6fi(NrUrNXl}Hi;Pe~ zN~h{ar2+{v=~hsjqkT+OP)YMcLLw`A!@sZ z{1zzZknfrK)AFVl737)Fa*A>%hFQVX!Z4YbQ&a*ren#=wQeR=g^iug!N-9zD>Sfh| zMH2b~)nK`mOZ>kOc{2-33#OIi&aaSgDoYb(6y)dTeSqV>8UcH+yw#uFLI~mC>J414+yt7PZS3#1O94Ca?7g9MNy!vTxzNs zLwg#(eA%pp<<$#JAQKl>EGS+Y2$V}f!Ss@;uXJ=&n7%kr9PoD%OwSC zd?%KJTBoyXXI{8)aZzAV*;46ss(*=?SX@{jLr_Q;gu+=GOW-O&_%953`W-65rFT^I6RaS@HiYo(wr2^5XmQF2W zNy!V$SLKwVyt3*tSrjb=R*vIWqnKH;qJV!zq)a}!NF|%2B%Y=N8N*U)#g%0%0^!6+ z+BqgE>YSjEmK8=QnzYkzGOg218U;H{BeSD6veQB~sW%GtOovLQt|?5z*U{INaE$iLV-oaqWIEcb_xm>&tHOeTT=OU=dTLLieuKSJRgcK z3y*}-F~nq(JArL<$<(6M(vpRX0#)+qfTne(>78k6Y5wez;)NB9%PM7sWBcpQCB0ie zsik-o!Vy~}-F8VW%`HO#=p}M^85&b!)UpCT@6v9OZ3~eufTV7U-qmiBGENq_sx@U-2C(ho`+qr zo`+x`aK(A{E zx8*wW6DvlDZTqrY;vqlMvaO{D;$2s>X22!w&ir*XiO%?_bu|qG>KyNEY*?{eWV?j$ zzwHu1mvB6G+Yxd5bJ-h&H}kUB>MwfJBX){)HP2L>2nHd0>It(kRDBIQX)tUjH)hE5`sfpD-8#ZoqB{(m> zB`GKIh|A%LKPA>&_erg%=7hNGI^~z)hqcDXe(0RK^@^?W�KgF4?Z*(FprA`36^A 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 L@^a6v$1DFEsWG_~ literal 0 HcmV?d00001 diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/connect_cdc.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/connect_cdc.c new file mode 100644 index 000000000..c624dd333 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/connect_cdc.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 AIIT XUOS Lab + * XiUOS is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan + * PSL v2. You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY + * KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO + * NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the + * Mulan PSL v2 for more details. + */ + +/* + * @Note + * Example routine to emulate a simulate USB-CDC Device,Use UART2(PA2/PA3). +*/ + +#include "xizi.h" +#include "board.h" +#include "shell.h" + +#include "CH56x_common.h" +#include "CH56x_usb30.h" +#include "cdc.h" + + +/******************************************************************************* + * @fn main + * + * @brief main program + * + * @return None + */ +int UsbdCdcTest() +{ + KPrintf("UsbdCdcTest start\n"); + KPrintf("CH56x USB3.0 & USB2.0 device test(80MHz) !\n"); + + /* USB initialization */ + TMR2_TimerInit1(); + R32_USB_CONTROL = 0; + PFIC_EnableIRQ(USBSS_IRQn); + PFIC_EnableIRQ(LINK_IRQn); + PFIC_EnableIRQ(TMR0_IRQn); + R8_TMR0_INTER_EN = 1; + TMR0_TimerInit( 67000000 ); + USB30D_init(ENABLE); + KPrintf("UsbdCdcTest USB30D_init OK\n"); + + while(1) + { + CDC_Uart_Deal(); + } +} + + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + UsbdCdcTest, UsbdCdcTest, test usbd cdc);