Add usbd cdc
This commit is contained in:
parent
b175f77b10
commit
0da14e6546
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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_ */
|
||||
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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_ */
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
|||
ifeq ($(CONFIG_BSP_USING_USBD),y)
|
||||
SRC_DIR += usbd
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,3 @@
|
|||
menuconfig BSP_USING_USBD_CDC
|
||||
bool "Using usbd cdc device"
|
||||
default y
|
|
@ -0,0 +1,5 @@
|
|||
ifeq ($(CONFIG_BSP_USING_USBD_CDC),y)
|
||||
SRC_DIR += simulate_cdc
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
Binary file not shown.
|
@ -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);
|
Loading…
Reference in New Issue