diff --git a/V203/usb/cdc/ch32v203/cdc_class.cpp b/V203/usb/cdc/ch32v203/cdc_class.cpp index f0ab469..cbb4925 100644 --- a/V203/usb/cdc/ch32v203/cdc_class.cpp +++ b/V203/usb/cdc/ch32v203/cdc_class.cpp @@ -188,437 +188,446 @@ void cdc_class::init() { USBFS_Device_Init( true ); while (!USBFS_DevEnumStatus); } +__always_inline void cdc_class::InTokenHandler(const uint8_t intst) { + switch ( intst & ( USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK ) ) { + /* end-point 0 data in interrupt */ + case USBFS_UIS_TOKEN_IN | DEF_UEP0: + if( USBFS_SetupReqLen == 0 ) { + USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG | USBFS_UEP_R_RES_ACK; + } + if ( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { + /* Non-standard request endpoint 0 Data upload */ + } else { + /* Standard request endpoint 0 Data upload */ + switch( USBFS_SetupReqCode ) { + case USB_GET_DESCRIPTOR: { + const uint16_t len = USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen; + memcpy( USBFS_EP0_Buf, pUSBFS_Descr, len ); + USBFS_SetupReqLen -= len; + pUSBFS_Descr += len; + USBFSD->UEP0_TX_LEN = len; + USBFSD->UEP0_TX_CTRL ^= USBFS_UEP_T_TOG; + } break; + case USB_SET_ADDRESS: + USBFSD->DEV_ADDR = (USBFSD->DEV_ADDR & USBFS_UDA_GP_BIT) | USBFS_DevAddr; + break; + default: + break; + } + } + break; + + /* end-point 1 data in interrupt */ + case ( USBFS_UIS_TOKEN_IN | DEF_UEP1 ): + USBFSD->UEP1_TX_CTRL ^= USBFS_UEP_T_TOG; + USBFSD->UEP1_TX_CTRL = (USBFSD->UEP1_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK; + USBFS_Endp_Busy[ DEF_UEP1 ] = 0; + break; + + /* end-point 3 data in interrupt */ + case ( USBFS_UIS_TOKEN_IN | DEF_UEP3 ): + USBFSD->UEP3_TX_CTRL ^= USBFS_UEP_T_TOG; + USBFSD->UEP3_TX_CTRL = (USBFSD->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK; + USBFS_Endp_Busy[ DEF_UEP3 ] = 0; + TxDataDeal (); + break; + + default : + break; + } +} +__always_inline void cdc_class::OutTokenHandler(const uint8_t intst) { + uint16_t len; + switch ( intst & ( USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK ) ) { + /* end-point 0 data out interrupt */ + case USBFS_UIS_TOKEN_OUT | DEF_UEP0: + len = USBFSD->RX_LEN; + (void) len; + if ( intst & USBFS_UIS_TOG_OK ) { + if ( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { + /* Non-standard request end-point 0 Data download */ + USBFS_SetupReqLen = 0; + /* Non-standard request end-point 0 Data download */ + if( USBFS_SetupReqCode == CDC_SET_LINE_CODING ) { + /* Save relevant parameters such as serial port baud rate */ + /* The downlinked data is processed in the endpoint 0 OUT packet, the 7 bytes of the downlink are, in order + 4 bytes: baud rate value: lowest baud rate byte, next lowest baud rate byte, next highest baud rate byte, highest baud rate byte. + 1 byte: number of stop bits (0: 1 stop bit; 1: 1.5 stop bit; 2: 2 stop bits). + 1 byte: number of parity bits (0: None; 1: Odd; 2: Even; 3: Mark; 4: Space). + 1 byte: number of data bits (5,6,7,8,16); */ + /* + Uart.Com_Cfg[ 0 ] = USBFS_EP0_Buf[ 0 ]; + Uart.Com_Cfg[ 1 ] = USBFS_EP0_Buf[ 1 ]; + Uart.Com_Cfg[ 2 ] = USBFS_EP0_Buf[ 2 ]; + Uart.Com_Cfg[ 3 ] = USBFS_EP0_Buf[ 3 ]; + Uart.Com_Cfg[ 4 ] = USBFS_EP0_Buf[ 4 ]; + Uart.Com_Cfg[ 5 ] = USBFS_EP0_Buf[ 5 ]; + Uart.Com_Cfg[ 6 ] = USBFS_EP0_Buf[ 6 ]; + Uart.Com_Cfg[ 7 ] = DEF_UARTx_RX_TIMEOUT; + + baudrate = USBFS_EP0_Buf[ 0 ]; + baudrate += ((uint32_t)USBFS_EP0_Buf[ 1 ] << 8 ); + baudrate += ((uint32_t)USBFS_EP0_Buf[ 2 ] << 16 ); + baudrate += ((uint32_t)USBFS_EP0_Buf[ 3 ] << 24 ); + Uart.Com_Cfg[ 7 ] = Uart.Rx_TimeOutMax; + + UART2_USB_Init( ); + */ + } + } else { + /* Standard request end-point 0 Data download */ + /* Add your code here */ + } + if( USBFS_SetupReqLen == 0 ) { + USBFSD->UEP0_TX_LEN = 0; + USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK; + } + } + break; + + /* end-point 1 data out interrupt */ + case USBFS_UIS_TOKEN_OUT | DEF_UEP2: { + USBFSD->UEP2_RX_CTRL ^= USBFS_UEP_R_TOG; + const uint32_t rlen = USBFSD->RX_LEN; + const char *ptr = reinterpret_cast (USBFS_EP2_Buf); + USBFSD->UEP2_RX_CTRL = (USBFSD->UEP2_RX_CTRL & ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_NAK; + Up (ptr, rlen); + USBFSD->UEP2_RX_CTRL = (USBFSD->UEP2_RX_CTRL & ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_NAK; + } break; + + default: + break; + } +} +void cdc_class::SetupTokenHandler() { + uint8_t errflag; + uint16_t len; + USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_NAK; + USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG|USBFS_UEP_R_RES_NAK; + /* Store All Setup Values */ + USBFS_SetupReqType = pUSBFS_SetupReqPak->bRequestType; + USBFS_SetupReqCode = pUSBFS_SetupReqPak->bRequest; + USBFS_SetupReqLen = pUSBFS_SetupReqPak->wLength; + USBFS_SetupReqValue = pUSBFS_SetupReqPak->wValue; + USBFS_SetupReqIndex = pUSBFS_SetupReqPak->wIndex; + len = 0; + errflag = 0; + if ( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { + /* usb non-standard request processing */ + if( USBFS_SetupReqType & USB_REQ_TYP_CLASS ) { + /* Class requests */ + switch( USBFS_SetupReqCode ) { + case CDC_GET_LINE_CODING: + // pUSBFS_Descr = (uint8_t *)&Uart.Com_Cfg[ 0 ]; + len = 7; + break; + + case CDC_SET_LINE_CODING: + break; + /* TODO: DTR - wValue & 1 */ + case CDC_SET_LINE_CTLSTE: { + const bool b = USBFS_SetupReqValue & 1; + Ready = b; + dtr << !b; + } break; + + case CDC_SEND_BREAK: + break; + + default: + errflag = 0xff; + break; + } + } else if ( USBFS_SetupReqType & USB_REQ_TYP_VENDOR ) { + /* Manufacturer request */ + } else { + errflag = 0xFF; + } + + /* Copy Descriptors to Endp0 DMA buffer */ + len = (USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE) ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen; + memcpy( USBFS_EP0_Buf, pUSBFS_Descr, len ); + pUSBFS_Descr += len; + } else { + /* usb standard request processing */ + switch( USBFS_SetupReqCode ) { + /* get device/configuration/string/report/... descriptors */ + case USB_GET_DESCRIPTOR: + switch( (uint8_t)( USBFS_SetupReqValue >> 8 ) ) { + /* get usb device descriptor */ + case USB_DESCR_TYP_DEVICE: + pUSBFS_Descr = MyDevDescr; + len = DEF_USBD_DEVICE_DESC_LEN; + break; + + /* get usb configuration descriptor */ + case USB_DESCR_TYP_CONFIG: + pUSBFS_Descr = MyCfgDescr; + len = DEF_USBD_CONFIG_DESC_LEN; + break; + + /* get usb string descriptor */ + case USB_DESCR_TYP_STRING: + switch( (uint8_t)( USBFS_SetupReqValue & 0xFF ) ) { + /* Descriptor 0, Language descriptor */ + case DEF_STRING_DESC_LANG: + pUSBFS_Descr = MyLangDescr; + len = DEF_USBD_LANG_DESC_LEN; + break; + + /* Descriptor 1, Manufacturers String descriptor */ + case DEF_STRING_DESC_MANU: + pUSBFS_Descr = MyManuInfo; + len = DEF_USBD_MANU_DESC_LEN; + break; + + /* Descriptor 2, Product String descriptor */ + case DEF_STRING_DESC_PROD: + pUSBFS_Descr = MyProdInfo; + len = DEF_USBD_PROD_DESC_LEN; + break; + + /* Descriptor 3, Serial-number String descriptor */ + case DEF_STRING_DESC_SERN: + pUSBFS_Descr = MySerNumInfo; + len = DEF_USBD_SN_DESC_LEN; + break; + + default: + errflag = 0xFF; + break; + } + break; + + default : + errflag = 0xFF; + break; + } + + /* Copy Descriptors to Endp0 DMA buffer */ + if( USBFS_SetupReqLen>len ) { + USBFS_SetupReqLen = len; + } + len = (USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE) ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen; + memcpy( USBFS_EP0_Buf, pUSBFS_Descr, len ); + pUSBFS_Descr += len; + break; + + /* Set usb address */ + case USB_SET_ADDRESS: + USBFS_DevAddr = (uint8_t)( USBFS_SetupReqValue & 0xFF ); + break; + + /* Get usb configuration now set */ + case USB_GET_CONFIGURATION: + USBFS_EP0_Buf[0] = USBFS_DevConfig; + if ( USBFS_SetupReqLen > 1 ) { + USBFS_SetupReqLen = 1; + } + break; + + /* Set usb configuration to use */ + case USB_SET_CONFIGURATION: + USBFS_DevConfig = (uint8_t)( USBFS_SetupReqValue & 0xFF ); + USBFS_DevEnumStatus = 0x01; + break; + + /* Clear or disable one usb feature */ + case USB_CLEAR_FEATURE: + if ( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE ) { + /* clear one device feature */ + if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_REMOTE_WAKEUP ) { + /* clear usb sleep status, device not prepare to sleep */ + USBFS_DevSleepStatus &= ~0x01; + } + } else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) { + /* Clear End-point Feature */ + if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_ENDP_HALT ) { + switch( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) ) { + case ( DEF_UEP_IN | DEF_UEP1 ): + /* Set End-point 1 IN NAK */ + USBFSD->UEP1_TX_CTRL = USBFS_UEP_T_RES_NAK; + break; + + case ( DEF_UEP_OUT | DEF_UEP2 ): + /* Set End-point 2 OUT ACK */ + USBFSD->UEP2_RX_CTRL = USBFS_UEP_R_RES_ACK; + break; + + case ( DEF_UEP_IN | DEF_UEP3 ): + /* Set End-point 3 IN NAK */ + USBFSD->UEP3_TX_CTRL = USBFS_UEP_T_RES_NAK; + break; + + default: + errflag = 0xFF; + break; + } + } else { + errflag = 0xFF; + } + } else { + errflag = 0xFF; + } + break; + + /* set or enable one usb feature */ + case USB_SET_FEATURE: + if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE ) { + /* Set Device Feature */ + if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_REMOTE_WAKEUP ) { + if( MyCfgDescr[ 7 ] & 0x20 ) { + /* Set Wake-up flag, device prepare to sleep */ + USBFS_DevSleepStatus |= 0x01; + } else { + errflag = 0xFF; + } + } else { + errflag = 0xFF; + } + } + else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) { + /* Set End-point Feature */ + if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_ENDP_HALT ) { + /* Set end-points status stall */ + switch( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) ) { + case ( DEF_UEP_IN | DEF_UEP1 ): + /* Set End-point 1 IN STALL */ + USBFSD->UEP1_TX_CTRL = ( USBFSD->UEP1_TX_CTRL & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_STALL; + break; + + case ( DEF_UEP_OUT | DEF_UEP2 ): + /* Set End-point 2 OUT STALL */ + USBFSD->UEP2_RX_CTRL = ( USBFSD->UEP2_RX_CTRL & ~USBFS_UEP_R_RES_MASK ) | USBFS_UEP_R_RES_STALL; + break; + + case ( DEF_UEP_IN | DEF_UEP3 ): + /* Set End-point 3 IN STALL */ + USBFSD->UEP3_TX_CTRL = ( USBFSD->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_STALL; + break; + + default: + errflag = 0xFF; + break; + } + } else { + errflag = 0xFF; + } + } else { + errflag = 0xFF; + } + break; + + /* This request allows the host to select another setting for the specified interface */ + case USB_GET_INTERFACE: + USBFS_EP0_Buf[0] = 0x00; + if ( USBFS_SetupReqLen > 1 ) { + USBFS_SetupReqLen = 1; + } + break; + + case USB_SET_INTERFACE: + break; + + /* host get status of specified device/interface/end-points */ + case USB_GET_STATUS: + USBFS_EP0_Buf[ 0 ] = 0x00; + USBFS_EP0_Buf[ 1 ] = 0x00; + if ( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE ) { + if( USBFS_DevSleepStatus & 0x01 ) { + USBFS_EP0_Buf[ 0 ] = 0x02; + } + } else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) { + switch( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) ) { + case ( DEF_UEP_IN | DEF_UEP1 ): + if( ( (USBFSD->UEP1_TX_CTRL) & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL ) { + USBFS_EP0_Buf[ 0 ] = 0x01; + } + break; + + case ( DEF_UEP_OUT | DEF_UEP2 ): + if( ( (USBFSD->UEP2_RX_CTRL) & USBFS_UEP_R_RES_MASK ) == USBFS_UEP_R_RES_STALL ) { + USBFS_EP0_Buf[ 0 ] = 0x01; + } + break; + + case ( DEF_UEP_IN | DEF_UEP3 ): + if( ( (USBFSD->UEP3_TX_CTRL) & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL ) { + USBFS_EP0_Buf[ 0 ] = 0x01; + } + break; + + default: + errflag = 0xFF; + break; + } + } else { + errflag = 0xFF; + } + + if( USBFS_SetupReqLen > 2 ) { + USBFS_SetupReqLen = 2; + } + + break; + + default: + errflag = 0xFF; + break; + } + } + /* errflag = 0xFF means a request not support or some errors occurred, else correct */ + if( errflag == 0xff) { + /* if one request not support, return stall */ + USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_STALL; + USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG|USBFS_UEP_R_RES_STALL; + } else { + /* end-point 0 data Tx/Rx */ + if( USBFS_SetupReqType & DEF_UEP_IN ) { + /* tx */ + len = (USBFS_SetupReqLen>DEF_USBD_UEP0_SIZE) ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen; + USBFS_SetupReqLen -= len; + USBFSD->UEP0_TX_LEN = len; + USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_ACK; + } else { + /* rx */ + if( USBFS_SetupReqLen == 0 ) { + USBFSD->UEP0_TX_LEN = 0; + USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_ACK; + } else { + USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG|USBFS_UEP_R_RES_ACK; + } + } + } +} + +__always_inline void cdc_class::TransferHandler() { + const uint8_t intst = USBFSD->INT_ST; + + switch (intst & USBFS_UIS_TOKEN_MASK) { + /* data-in stage processing */ + case USBFS_UIS_TOKEN_IN: + InTokenHandler(intst); + break; + /* data-out stage processing */ + case USBFS_UIS_TOKEN_OUT: + OutTokenHandler(intst); + break; + /* Setup stage processing */ + case USBFS_UIS_TOKEN_SETUP: + SetupTokenHandler(); + break; + default : + break; + } + USBFSD->INT_FG = USBFS_UIF_TRANSFER; +} void cdc_class::cdc_irq() { - uint8_t intflag, intst, errflag; - uint16_t len; - //uint32_t baudrate; - - intflag = USBFSD->INT_FG; - intst = USBFSD->INT_ST; + const uint8_t intflag = USBFSD->INT_FG; if( intflag & USBFS_UIF_TRANSFER ) { - switch (intst & USBFS_UIS_TOKEN_MASK) { - /* data-in stage processing */ - case USBFS_UIS_TOKEN_IN: - switch ( intst & ( USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK ) ) { - /* end-point 0 data in interrupt */ - case USBFS_UIS_TOKEN_IN | DEF_UEP0: - if( USBFS_SetupReqLen == 0 ) { - USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG | USBFS_UEP_R_RES_ACK; - } - if ( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { - /* Non-standard request endpoint 0 Data upload */ - } else { - /* Standard request endpoint 0 Data upload */ - switch( USBFS_SetupReqCode ) { - case USB_GET_DESCRIPTOR: - len = USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen; - memcpy( USBFS_EP0_Buf, pUSBFS_Descr, len ); - USBFS_SetupReqLen -= len; - pUSBFS_Descr += len; - USBFSD->UEP0_TX_LEN = len; - USBFSD->UEP0_TX_CTRL ^= USBFS_UEP_T_TOG; - break; - - case USB_SET_ADDRESS: - USBFSD->DEV_ADDR = (USBFSD->DEV_ADDR & USBFS_UDA_GP_BIT) | USBFS_DevAddr; - break; - - default: - break; - } - } - break; - - /* end-point 1 data in interrupt */ - case ( USBFS_UIS_TOKEN_IN | DEF_UEP1 ): - USBFSD->UEP1_TX_CTRL ^= USBFS_UEP_T_TOG; - USBFSD->UEP1_TX_CTRL = (USBFSD->UEP1_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK; - USBFS_Endp_Busy[ DEF_UEP1 ] = 0; - break; - - /* end-point 3 data in interrupt */ - case ( USBFS_UIS_TOKEN_IN | DEF_UEP3 ): - USBFSD->UEP3_TX_CTRL ^= USBFS_UEP_T_TOG; - USBFSD->UEP3_TX_CTRL = (USBFSD->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK; - USBFS_Endp_Busy[ DEF_UEP3 ] = 0; - TxDataDeal (); - break; - - default : - break; - } - break; - - /* data-out stage processing */ - case USBFS_UIS_TOKEN_OUT: - switch ( intst & ( USBFS_UIS_TOKEN_MASK | USBFS_UIS_ENDP_MASK ) ) { - /* end-point 0 data out interrupt */ - case USBFS_UIS_TOKEN_OUT | DEF_UEP0: - len = USBFSD->RX_LEN; - if ( intst & USBFS_UIS_TOG_OK ) { - if ( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { - /* Non-standard request end-point 0 Data download */ - USBFS_SetupReqLen = 0; - /* Non-standard request end-point 0 Data download */ - if( USBFS_SetupReqCode == CDC_SET_LINE_CODING ) { - /* Save relevant parameters such as serial port baud rate */ - /* The downlinked data is processed in the endpoint 0 OUT packet, the 7 bytes of the downlink are, in order - 4 bytes: baud rate value: lowest baud rate byte, next lowest baud rate byte, next highest baud rate byte, highest baud rate byte. - 1 byte: number of stop bits (0: 1 stop bit; 1: 1.5 stop bit; 2: 2 stop bits). - 1 byte: number of parity bits (0: None; 1: Odd; 2: Even; 3: Mark; 4: Space). - 1 byte: number of data bits (5,6,7,8,16); */ - /* - Uart.Com_Cfg[ 0 ] = USBFS_EP0_Buf[ 0 ]; - Uart.Com_Cfg[ 1 ] = USBFS_EP0_Buf[ 1 ]; - Uart.Com_Cfg[ 2 ] = USBFS_EP0_Buf[ 2 ]; - Uart.Com_Cfg[ 3 ] = USBFS_EP0_Buf[ 3 ]; - Uart.Com_Cfg[ 4 ] = USBFS_EP0_Buf[ 4 ]; - Uart.Com_Cfg[ 5 ] = USBFS_EP0_Buf[ 5 ]; - Uart.Com_Cfg[ 6 ] = USBFS_EP0_Buf[ 6 ]; - Uart.Com_Cfg[ 7 ] = DEF_UARTx_RX_TIMEOUT; - - baudrate = USBFS_EP0_Buf[ 0 ]; - baudrate += ((uint32_t)USBFS_EP0_Buf[ 1 ] << 8 ); - baudrate += ((uint32_t)USBFS_EP0_Buf[ 2 ] << 16 ); - baudrate += ((uint32_t)USBFS_EP0_Buf[ 3 ] << 24 ); - Uart.Com_Cfg[ 7 ] = Uart.Rx_TimeOutMax; - - UART2_USB_Init( ); - */ - } - } else { - /* Standard request end-point 0 Data download */ - /* Add your code here */ - } - if( USBFS_SetupReqLen == 0 ) { - USBFSD->UEP0_TX_LEN = 0; - USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK; - } - } - break; - - /* end-point 1 data out interrupt */ - case USBFS_UIS_TOKEN_OUT | DEF_UEP2: { - USBFSD->UEP2_RX_CTRL ^= USBFS_UEP_R_TOG; - const uint32_t rlen = USBFSD->RX_LEN; - const char *ptr = reinterpret_cast (USBFS_EP2_Buf); - USBFSD->UEP2_RX_CTRL = (USBFSD->UEP2_RX_CTRL & ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_NAK; - Up (ptr, rlen); - USBFSD->UEP2_RX_CTRL = (USBFSD->UEP2_RX_CTRL & ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_NAK; - } break; - - default: - break; - } - break; - - /* Setup stage processing */ - case USBFS_UIS_TOKEN_SETUP: - USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_NAK; - USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG|USBFS_UEP_R_RES_NAK; - /* Store All Setup Values */ - USBFS_SetupReqType = pUSBFS_SetupReqPak->bRequestType; - USBFS_SetupReqCode = pUSBFS_SetupReqPak->bRequest; - USBFS_SetupReqLen = pUSBFS_SetupReqPak->wLength; - USBFS_SetupReqValue = pUSBFS_SetupReqPak->wValue; - USBFS_SetupReqIndex = pUSBFS_SetupReqPak->wIndex; - len = 0; - errflag = 0; - if ( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD ) { - /* usb non-standard request processing */ - if( USBFS_SetupReqType & USB_REQ_TYP_CLASS ) { - /* Class requests */ - switch( USBFS_SetupReqCode ) { - case CDC_GET_LINE_CODING: - // pUSBFS_Descr = (uint8_t *)&Uart.Com_Cfg[ 0 ]; - len = 7; - break; - - case CDC_SET_LINE_CODING: - break; - /* TODO: DTR - wValue & 1 */ - case CDC_SET_LINE_CTLSTE: { - const bool b = USBFS_SetupReqValue & 1; - Ready = b; - dtr << !b; - } break; - - case CDC_SEND_BREAK: - break; - - default: - errflag = 0xff; - break; - } - } else if ( USBFS_SetupReqType & USB_REQ_TYP_VENDOR ) { - /* Manufacturer request */ - } else { - errflag = 0xFF; - } - - /* Copy Descriptors to Endp0 DMA buffer */ - len = (USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE) ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen; - memcpy( USBFS_EP0_Buf, pUSBFS_Descr, len ); - pUSBFS_Descr += len; - } else { - /* usb standard request processing */ - switch( USBFS_SetupReqCode ) { - /* get device/configuration/string/report/... descriptors */ - case USB_GET_DESCRIPTOR: - switch( (uint8_t)( USBFS_SetupReqValue >> 8 ) ) { - /* get usb device descriptor */ - case USB_DESCR_TYP_DEVICE: - pUSBFS_Descr = MyDevDescr; - len = DEF_USBD_DEVICE_DESC_LEN; - break; - - /* get usb configuration descriptor */ - case USB_DESCR_TYP_CONFIG: - pUSBFS_Descr = MyCfgDescr; - len = DEF_USBD_CONFIG_DESC_LEN; - break; - - /* get usb string descriptor */ - case USB_DESCR_TYP_STRING: - switch( (uint8_t)( USBFS_SetupReqValue & 0xFF ) ) { - /* Descriptor 0, Language descriptor */ - case DEF_STRING_DESC_LANG: - pUSBFS_Descr = MyLangDescr; - len = DEF_USBD_LANG_DESC_LEN; - break; - - /* Descriptor 1, Manufacturers String descriptor */ - case DEF_STRING_DESC_MANU: - pUSBFS_Descr = MyManuInfo; - len = DEF_USBD_MANU_DESC_LEN; - break; - - /* Descriptor 2, Product String descriptor */ - case DEF_STRING_DESC_PROD: - pUSBFS_Descr = MyProdInfo; - len = DEF_USBD_PROD_DESC_LEN; - break; - - /* Descriptor 3, Serial-number String descriptor */ - case DEF_STRING_DESC_SERN: - pUSBFS_Descr = MySerNumInfo; - len = DEF_USBD_SN_DESC_LEN; - break; - - default: - errflag = 0xFF; - break; - } - break; - - default : - errflag = 0xFF; - break; - } - - /* Copy Descriptors to Endp0 DMA buffer */ - if( USBFS_SetupReqLen>len ) { - USBFS_SetupReqLen = len; - } - len = (USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE) ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen; - memcpy( USBFS_EP0_Buf, pUSBFS_Descr, len ); - pUSBFS_Descr += len; - break; - - /* Set usb address */ - case USB_SET_ADDRESS: - USBFS_DevAddr = (uint8_t)( USBFS_SetupReqValue & 0xFF ); - break; - - /* Get usb configuration now set */ - case USB_GET_CONFIGURATION: - USBFS_EP0_Buf[0] = USBFS_DevConfig; - if ( USBFS_SetupReqLen > 1 ) { - USBFS_SetupReqLen = 1; - } - break; - - /* Set usb configuration to use */ - case USB_SET_CONFIGURATION: - USBFS_DevConfig = (uint8_t)( USBFS_SetupReqValue & 0xFF ); - USBFS_DevEnumStatus = 0x01; - break; - - /* Clear or disable one usb feature */ - case USB_CLEAR_FEATURE: - if ( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE ) { - /* clear one device feature */ - if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_REMOTE_WAKEUP ) { - /* clear usb sleep status, device not prepare to sleep */ - USBFS_DevSleepStatus &= ~0x01; - } - } else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) { - /* Clear End-point Feature */ - if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_ENDP_HALT ) { - switch( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) ) { - case ( DEF_UEP_IN | DEF_UEP1 ): - /* Set End-point 1 IN NAK */ - USBFSD->UEP1_TX_CTRL = USBFS_UEP_T_RES_NAK; - break; - - case ( DEF_UEP_OUT | DEF_UEP2 ): - /* Set End-point 2 OUT ACK */ - USBFSD->UEP2_RX_CTRL = USBFS_UEP_R_RES_ACK; - break; - - case ( DEF_UEP_IN | DEF_UEP3 ): - /* Set End-point 3 IN NAK */ - USBFSD->UEP3_TX_CTRL = USBFS_UEP_T_RES_NAK; - break; - - default: - errflag = 0xFF; - break; - } - } else { - errflag = 0xFF; - } - } else { - errflag = 0xFF; - } - break; - - /* set or enable one usb feature */ - case USB_SET_FEATURE: - if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE ) { - /* Set Device Feature */ - if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_REMOTE_WAKEUP ) { - if( MyCfgDescr[ 7 ] & 0x20 ) { - /* Set Wake-up flag, device prepare to sleep */ - USBFS_DevSleepStatus |= 0x01; - } else { - errflag = 0xFF; - } - } else { - errflag = 0xFF; - } - } - else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) { - /* Set End-point Feature */ - if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_ENDP_HALT ) { - /* Set end-points status stall */ - switch( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) ) { - case ( DEF_UEP_IN | DEF_UEP1 ): - /* Set End-point 1 IN STALL */ - USBFSD->UEP1_TX_CTRL = ( USBFSD->UEP1_TX_CTRL & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_STALL; - break; - - case ( DEF_UEP_OUT | DEF_UEP2 ): - /* Set End-point 2 OUT STALL */ - USBFSD->UEP2_RX_CTRL = ( USBFSD->UEP2_RX_CTRL & ~USBFS_UEP_R_RES_MASK ) | USBFS_UEP_R_RES_STALL; - break; - - case ( DEF_UEP_IN | DEF_UEP3 ): - /* Set End-point 3 IN STALL */ - USBFSD->UEP3_TX_CTRL = ( USBFSD->UEP3_TX_CTRL & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_STALL; - break; - - default: - errflag = 0xFF; - break; - } - } else { - errflag = 0xFF; - } - } else { - errflag = 0xFF; - } - break; - - /* This request allows the host to select another setting for the specified interface */ - case USB_GET_INTERFACE: - USBFS_EP0_Buf[0] = 0x00; - if ( USBFS_SetupReqLen > 1 ) { - USBFS_SetupReqLen = 1; - } - break; - - case USB_SET_INTERFACE: - break; - - /* host get status of specified device/interface/end-points */ - case USB_GET_STATUS: - USBFS_EP0_Buf[ 0 ] = 0x00; - USBFS_EP0_Buf[ 1 ] = 0x00; - if ( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE ) { - if( USBFS_DevSleepStatus & 0x01 ) { - USBFS_EP0_Buf[ 0 ] = 0x02; - } - } else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) { - switch( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) ) { - case ( DEF_UEP_IN | DEF_UEP1 ): - if( ( (USBFSD->UEP1_TX_CTRL) & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL ) { - USBFS_EP0_Buf[ 0 ] = 0x01; - } - break; - - case ( DEF_UEP_OUT | DEF_UEP2 ): - if( ( (USBFSD->UEP2_RX_CTRL) & USBFS_UEP_R_RES_MASK ) == USBFS_UEP_R_RES_STALL ) { - USBFS_EP0_Buf[ 0 ] = 0x01; - } - break; - - case ( DEF_UEP_IN | DEF_UEP3 ): - if( ( (USBFSD->UEP3_TX_CTRL) & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL ) { - USBFS_EP0_Buf[ 0 ] = 0x01; - } - break; - - default: - errflag = 0xFF; - break; - } - } else { - errflag = 0xFF; - } - - if( USBFS_SetupReqLen > 2 ) { - USBFS_SetupReqLen = 2; - } - - break; - - default: - errflag = 0xFF; - break; - } - } - /* errflag = 0xFF means a request not support or some errors occurred, else correct */ - if( errflag == 0xff) { - /* if one request not support, return stall */ - USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_STALL; - USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG|USBFS_UEP_R_RES_STALL; - } else { - /* end-point 0 data Tx/Rx */ - if( USBFS_SetupReqType & DEF_UEP_IN ) { - /* tx */ - len = (USBFS_SetupReqLen>DEF_USBD_UEP0_SIZE) ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen; - USBFS_SetupReqLen -= len; - USBFSD->UEP0_TX_LEN = len; - USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_ACK; - } else { - /* rx */ - if( USBFS_SetupReqLen == 0 ) { - USBFSD->UEP0_TX_LEN = 0; - USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_ACK; - } else { - USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_TOG|USBFS_UEP_R_RES_ACK; - } - } - } - break; - - default : - break; - } - USBFSD->INT_FG = USBFS_UIF_TRANSFER; + TransferHandler (); } else if( intflag & USBFS_UIF_BUS_RST ) { /* usb reset interrupt processing */ USBFS_DevConfig = 0; @@ -648,19 +657,20 @@ void cdc_class::cdc_irq() { } } void cdc_class::TxDataDeal() { - /* Asi by to mělo fungovat nějak přes frontu, ale zatím nevím jak to nastartovat */ + /* Asi by to mělo fungovat nějak přes frontu, ale zatím nevím jak to nastartovat, nepoužito */ } - +/* Pozor - funkce je blokující, lze použít jen v hlavní smyčce programu, ne v přerušení */ uint32_t cdc_class::Down (const char * data, const uint32_t len) { if ((!Ready) or (!USBFS_DevEnumStatus)) return 0; uint32_t rem = len; - const uint32_t max = 64; + const uint32_t max = DEF_USBD_ENDP3_SIZE; const uint8_t * ptr = reinterpret_cast (data); - delay_us(5'000); // zde se musí počkat, nevím proč, ale jinak to nechodí + // zde se musí počkat, nevím proč, ale jinak to nechodí + delay_us(1'000); // 1ms stačí pro odchod paketu po USB while (rem) { const uint32_t chunk = rem > max ? max : rem; if (USBFS_Endp_DataUp (DEF_UEP3, ptr, chunk, DEF_UEP_CPY_LOAD)) { - delay_us(1000); + delay_us(1'000); // čekej dokud je USBFS_Endp_Busy } else { ptr += chunk; rem -= chunk; diff --git a/V203/usb/cdc/ch32v203/cdc_class.h b/V203/usb/cdc/ch32v203/cdc_class.h index f535799..d2cd248 100644 --- a/V203/usb/cdc/ch32v203/cdc_class.h +++ b/V203/usb/cdc/ch32v203/cdc_class.h @@ -88,6 +88,10 @@ class cdc_class : public BaseLayer { void USBFS_Device_Endp_Init (); uint8_t USBFS_Endp_DataUp(uint8_t endp, const uint8_t *pbuf, uint16_t len, uint8_t mod); void TxDataDeal (); + void TransferHandler (); + void InTokenHandler (const uint8_t intst); + void OutTokenHandler (const uint8_t intst); + void SetupTokenHandler (); }; #endif // CDC_CLASS_H