#include "cdc_class.h" #include "system.h" static cdc_class * pInstance = nullptr; /* Interrupt Service Routine Declaration*/ extern "C" void USBFS_IRQHandler(void) __attribute__((interrupt)); void USBFS_IRQHandler () { if (pInstance) pInstance->cdc_irq(); } /* USB_Device_clock_source */ #define RCC_USBCLKSource_PLLCLK_Div1 ((uint8_t)0x00) #define RCC_USBCLKSource_PLLCLK_Div2 ((uint8_t)0x01) #define RCC_USBCLKSource_PLLCLK_Div3 ((uint8_t)0x02) #define RCC_AHBPeriph_USBFS ((uint32_t)0x00001000) #define RCC_AHBPeriph_OTG_FS RCC_AHBPeriph_USBFS enum FunctionalState {DISABLE = 0, ENABLE}; static void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource) { RCC.CFGR0.B.USBPRE = RCC_USBCLKSource; } static void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState) { if (NewState != DISABLE) { RCC.AHBPCENR.R |= RCC_AHBPeriph; } else { RCC.AHBPCENR.R &= ~RCC_AHBPeriph; } } /********************************************************************* * @fn USBFS_RCC_Init * * @brief Initializes the usbfs clock configuration. * * @return none */ static void USBFS_RCC_Init( void ) { if( SystemCoreClock == 144000000 ) { RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div3 ); } else if( SystemCoreClock == 96000000 ) { RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div2 ); } else if( SystemCoreClock == 48000000 ) { RCC_USBCLKConfig( RCC_USBCLKSource_PLLCLK_Div1 ); } RCC_AHBPeriphClockCmd( RCC_AHBPeriph_USBFS, ENABLE ); } /********************************************************************* * @fn USBFS_Device_Endp_Init * * @brief Initializes USB device endpoints. * * @return none */ void cdc_class::USBFS_Device_Endp_Init( void ) { USBFSD->UEP4_1_MOD = USBFS_UEP1_TX_EN; USBFSD->UEP2_3_MOD = USBFS_UEP2_RX_EN|USBFS_UEP3_TX_EN; USBFSD->UEP0_DMA = (size_t)USBFS_EP0_Buf; USBFSD->UEP1_DMA = (size_t)USBFS_EP1_Buf; USBFSD->UEP2_DMA = (size_t)USBFS_EP2_Buf; USBFSD->UEP3_DMA = (size_t)USBFS_EP3_Buf; USBFSD->UEP0_RX_CTRL = USBFS_UEP_R_RES_ACK; USBFSD->UEP2_RX_CTRL = USBFS_UEP_R_RES_ACK; USBFSD->UEP1_TX_LEN = 0; USBFSD->UEP3_TX_LEN = 0; USBFSD->UEP0_TX_CTRL = USBFS_UEP_T_RES_NAK; USBFSD->UEP1_TX_CTRL = USBFS_UEP_T_RES_NAK; USBFSD->UEP3_TX_CTRL = USBFS_UEP_T_RES_NAK; /* Clear End-points Busy Status */ for(uint8_t i=0; iBASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL; delay_us( 10 ); USBFSH->BASE_CTRL = 0x00; USBFSD->INT_EN = USBFS_UIE_SUSPEND | USBFS_UIE_BUS_RST | USBFS_UIE_TRANSFER; USBFSD->BASE_CTRL = USBFS_UC_DEV_PU_EN | USBFS_UC_INT_BUSY | USBFS_UC_DMA_EN; USBFS_Device_Endp_Init( ); USBFSD->UDEV_CTRL = USBFS_UD_PD_DIS | USBFS_UD_PORT_EN; NVIC.EnableIRQ( USBFS_IRQn ); } else { USBFSH->BASE_CTRL = USBFS_UC_RESET_SIE | USBFS_UC_CLR_ALL; delay_us( 10 ); USBFSD->BASE_CTRL = 0x00; NVIC.DisableIRQ( USBFS_IRQn ); } dtr << true; } /********************************************************************* * @fn USBFS_Endp_DataUp * * @brief USBFS device data upload * * @return none */ uint8_t cdc_class::USBFS_Endp_DataUp(uint8_t endp, const uint8_t * pbuf, uint16_t len, uint8_t mod) { uint8_t endp_mode; uint8_t buf_load_offset; /* DMA config, endp_ctrl config, endp_len config */ if( (endp>=DEF_UEP1) && (endp<=DEF_UEP7) ) { if( USBFS_Endp_Busy[ endp ] == 0 ) { if( (endp == DEF_UEP1) || (endp == DEF_UEP4) ) { /* endp1/endp4 */ endp_mode = USBFSD_UEP_MOD(0); if( endp == DEF_UEP1 ) { endp_mode = (uint8_t)(endp_mode>>4); } } else if( (endp == DEF_UEP2) || (endp == DEF_UEP3) ) { /* endp2/endp3 */ endp_mode = USBFSD_UEP_MOD(1); if( endp == DEF_UEP3 ) { endp_mode = (uint8_t)(endp_mode>>4); } } else if( (endp == DEF_UEP5) || (endp == DEF_UEP6) ) { /* endp5/endp6 */ endp_mode = USBFSD_UEP_MOD(2); if( endp == DEF_UEP6 ) { endp_mode = (uint8_t)(endp_mode>>4); } } else { /* endp7 */ endp_mode = USBFSD_UEP_MOD(3); } if( endp_mode & USBFSD_UEP_TX_EN ) { if( endp_mode & USBFSD_UEP_RX_EN ) { buf_load_offset = 64; } else { buf_load_offset = 0; } if( buf_load_offset == 0 ) { if( mod == DEF_UEP_DMA_LOAD ) { /* DMA mode */ USBFSD_UEP_DMA(endp) = (uint16_t)(size_t)pbuf; } else { /* copy mode */ memcpy( USBFSD_UEP_BUF(endp), pbuf, len ); } } else { memcpy( USBFSD_UEP_BUF(endp)+buf_load_offset, pbuf, len ); } /* Set end-point busy */ USBFS_Endp_Busy[ endp ] = 0x01; /* tx length */ USBFSD_UEP_TLEN(endp) = len; /* response ack */ USBFSD_UEP_CTRL(endp) = (USBFSD_UEP_CTRL(endp) & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_ACK; } } else { return 1; } } else { return 1; } return 0; } cdc_class::cdc_class() noexcept : BaseLayer(), dtr (GPIOA, 0), Ready(false) { pInstance = this; USBFS_DevConfig = 0; USBFS_DevAddr = 0; USBFS_DevSleepStatus = 0; USBFS_DevEnumStatus = 0; } void cdc_class::init() { delay_init(); USBFS_RCC_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_ACK; } 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() { const uint8_t intflag = USBFSD->INT_FG; if( intflag & USBFS_UIF_TRANSFER ) { TransferHandler (); } else if( intflag & USBFS_UIF_BUS_RST ) { /* usb reset interrupt processing */ USBFS_DevConfig = 0; USBFS_DevAddr = 0; USBFS_DevSleepStatus = 0; USBFS_DevEnumStatus = 0; USBFSD->DEV_ADDR = 0; USBFS_Device_Endp_Init( ); //UART2_ParaInit( 1 ); USBFSD->INT_FG = USBFS_UIF_BUS_RST; } else if( intflag & USBFS_UIF_SUSPEND ) { USBFSD->INT_FG = USBFS_UIF_SUSPEND; delay_us(10); /* usb suspend interrupt processing */ if ( USBFSD->MIS_ST & USBFS_UMS_SUSPEND ) { USBFS_DevSleepStatus |= 0x02; if( USBFS_DevSleepStatus == 0x03 ) { /* Handling usb sleep here */ } } else { USBFS_DevSleepStatus &= ~0x02; } } else { /* other interrupts */ USBFSD->INT_FG = intflag; } } void cdc_class::TxDataDeal() { /* 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 = DEF_USBD_ENDP3_SIZE; const uint8_t * ptr = reinterpret_cast (data); while (rem) { const uint32_t chunk = rem > max ? max : rem; if (USBFS_Endp_DataUp (DEF_UEP3, ptr, chunk, DEF_UEP_CPY_LOAD)) { delay_us(10); // čekej dokud je USBFS_Endp_Busy } else { ptr += chunk; rem -= chunk; } } return len; }