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 000000000..eaf065736 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/libCH56x_USB30_device_lib.a differ 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);