/** * USB CDC class request handler. * This is an internal function. */ static void USB_VirtualCOM_HandleClassRequest() { USB_SetupPacket_t setupPacket; USBD_GetSetupPacket((uint8_t *) &setupPacket); if(setupPacket.bmRequestType & 0x80) { // Transfer direction: device to host switch(setupPacket.bRequest) { case USB_VCOM_REQ_GET_LINE_CODE: if(setupPacket.wIndex == USB_VCOM_INDEX) { // Copy line coding data to USB buffer USBD_MemCopy((uint8_t *) (USBD_BUF_BASE + USB_VCOM_CTRL_IN_BUF_BASE), (uint8_t *) &USB_VirtualCOM_lineCoding, USB_VirtualCOM_LineCoding_t_SIZE); } // Data stage USBD_SET_DATA1(USB_VCOM_CTRL_IN_EP); USBD_SET_PAYLOAD_LEN(USB_VCOM_CTRL_IN_EP, USB_VirtualCOM_LineCoding_t_SIZE); // Status stage USBD_PrepareCtrlOut(NULL, 0); break; default: // Setup error, stall the device USBD_SetStall(USB_VCOM_CTRL_IN_EP); USBD_SetStall(USB_VCOM_CTRL_OUT_EP); break; } } else { // Transfer direction: host to device switch(setupPacket.bRequest) { case USB_VCOM_REQ_SET_CONTROL_LINE_STATE: // Control signals are ignored // Status stage USBD_SET_DATA1(USB_VCOM_CTRL_IN_EP); USBD_SET_PAYLOAD_LEN(USB_VCOM_CTRL_IN_EP, 0); break; case USB_VCOM_REQ_SET_LINE_CODE: if(setupPacket.wIndex == USB_VCOM_INDEX) { // Prepare for line coding copy USBD_PrepareCtrlOut((uint8_t *) &USB_VirtualCOM_lineCoding, USB_VirtualCOM_LineCoding_t_SIZE); } // Status stage USBD_SET_DATA1(USB_VCOM_CTRL_IN_EP); USBD_SET_PAYLOAD_LEN(USB_VCOM_CTRL_IN_EP, 0); break; default: // Setup error, stall the device USBD_SetStall(USB_VCOM_CTRL_IN_EP); USBD_SetStall(USB_VCOM_CTRL_OUT_EP); break; } } }
void CCID_ClassRequest(void) { uint8_t buf[8]; USBD_GetSetupPacket(buf); if (buf[0] & 0x80) /* request data transfer direction */ { // Device to host switch (buf[1]) { case CCID_GET_CLOCK_FREQUENCIES: case CCID_GET_DATA_RATES: { uint8_t pData[1] = {0}; USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)), pData, sizeof(pData)); /* Data stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, sizeof(pData)); /* Status stage */ USBD_PrepareCtrlOut(0,0); break; } default: { /* Setup error, stall the device */ USBD_SetStall(0); break; } } } else { // Host to device switch (buf[1]) { case CCID_ABORT: { /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); break; } default: { // Stall /* Setup error, stall the device */ USBD_SetStall(0); break; } } } }
void PTR_ClassRequest(void) { uint8_t buf[8]; USBD_GetSetupPacket(buf); if (buf[0] & 0x80) { /* request data transfer direction */ // Device to host switch (buf[1]) { case GET_PORT_STATUS: { /* Data stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); /* Status stage */ USBD_PrepareCtrlOut(0,0); break; } default: { /* Setup error, stall the device */ USBD_SetStall(0); break; } } } else { // Host to device switch (buf[1]) { case SET_REPORT: { if (buf[3] == 3) { /* Request Type = Feature */ USBD_SET_DATA1(EP1); USBD_SET_PAYLOAD_LEN(EP1, 0); } break; } case SET_IDLE: { /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); break; } case SET_PROTOCOL: // { // break; // } default: { // Stall /* Setup error, stall the device */ USBD_SetStall(0); break; } } } }
//========================================================================= //----- (00002564) -------------------------------------------------------- __myevic__ void usbdClassRequest() { uint8_t token[8]; USBD_GetSetupPacket( token ); if ( ( token[0] & 0x1F ) == 1 ) { if (( dfStatus.vcom ) && ( token[4] == VCOM_INTERFACE )) { VCOM_ClassRequest( token ); return; } if (( dfStatus.storage ) && ( token[4] == MSC_INTERFACE )) { MSC_ClassRequest( token ); return; } } if( token[0] & 0x80 ) /* request data transfer direction */ { // Device to host switch ( token[1] ) { case GET_REPORT: case GET_IDLE: case GET_PROTOCOL: default: { /* Setup error, stall the device */ USBD_SetStall( EP0 ); USBD_SetStall( EP1 ); break; } } } else { // Host to device switch ( token[1] ) { case SET_REPORT: { if( token[3] == 3 ) { /* Request Type = Feature */ USBD_SET_DATA1( EP1 ); USBD_SET_PAYLOAD_LEN( EP1, 0 ); } break; } case SET_IDLE: { /* Status stage */ USBD_SET_DATA1( EP0 ); USBD_SET_PAYLOAD_LEN( EP0, 0 ); break; } case SET_PROTOCOL: default: { // Stall /* Setup error, stall the device */ USBD_SetStall( EP0 ); USBD_SetStall( EP1 ); break; } } } }
/** * @brief Process standard request * * @param None * * @return None * * @details Parse standard request and perform the corresponding action. * */ void USBD_StandardRequest(void) { /* clear global variables for new request */ g_usbd_CtrlInPointer = 0; g_usbd_CtrlInSize = 0; if(g_usbd_SetupPacket[0] & 0x80) /* request data transfer direction */ { // Device to host switch(g_usbd_SetupPacket[1]) { case GET_CONFIGURATION: { // Return current configuration setting /* Data stage */ M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbConfig; USBD_SET_DATA1(EP1); USBD_SET_PAYLOAD_LEN(EP1, 0); USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 1); /* Status stage */ USBD_PrepareCtrlOut(0, 0); DBG_PRINTF("Get configuration\n"); break; } case GET_DESCRIPTOR: { USBD_GetDescriptor(); break; } case GET_INTERFACE: { // Return current interface setting /* Data stage */ M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = g_usbd_UsbAltInterface; USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 1); /* Status stage */ USBD_PrepareCtrlOut(0, 0); DBG_PRINTF("Get interface\n"); break; } case GET_STATUS: { // Device if(g_usbd_SetupPacket[0] == 0x80) { uint8_t u8Tmp; u8Tmp = 0; if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x40) u8Tmp |= 1; // Self-Powered/Bus-Powered. if(g_usbd_sInfo->gu8ConfigDesc[7] & 0x20) u8Tmp |= (g_usbd_RemoteWakeupEn << 1); // Remote wake up M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = u8Tmp; } // Interface else if(g_usbd_SetupPacket[0] == 0x81) M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0; // Endpoint else if(g_usbd_SetupPacket[0] == 0x82) { uint8_t ep = g_usbd_SetupPacket[4] & 0xF; M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = USBD_GetStall(ep) ? 1 : 0; } M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0) + 1) = 0; /* Data stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 2); /* Status stage */ USBD_PrepareCtrlOut(0, 0); DBG_PRINTF("Get status\n"); break; } default: { /* Setup error, stall the device */ USBD_SET_EP_STALL(EP0); USBD_SET_EP_STALL(EP1); DBG_PRINTF("Unknown request. stall ctrl pipe.\n"); break; } } } else { // Host to device switch(g_usbd_SetupPacket[1]) { case CLEAR_FEATURE: { if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) { int32_t epNum, i; /* EP number stall is not allow to be clear in MSC class "Error Recovery Test". a flag: g_u32EpStallLock is added to support it */ epNum = g_usbd_SetupPacket[4] & 0xF; for(i = 0; i < USBD_MAX_EP; i++) { if(((USBD->EP[i].CFG & 0xF) == epNum) && ((g_u32EpStallLock & (1 << i)) == 0)) { USBD->EP[i].CFGP &= ~USBD_CFGP_SSTALL_Msk; DBG_PRINTF("Clr stall ep%d %x\n",i, USBD->EP[i].CFGP); } } } else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP) g_usbd_RemoteWakeupEn = 0; /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); DBG_PRINTF("Clear feature op %d\n", g_usbd_SetupPacket[2]); break; } case SET_ADDRESS: { g_usbd_UsbAddr = g_usbd_SetupPacket[2]; DBG_PRINTF("Set addr to %d\n", g_usbd_UsbAddr); // DATA IN for end of setup /* Status Stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); break; } case SET_CONFIGURATION: { g_usbd_UsbConfig = g_usbd_SetupPacket[2]; if(g_usbd_pfnSetConfigCallback) g_usbd_pfnSetConfigCallback(); // DATA IN for end of setup /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); DBG_PRINTF("Set config to %d\n", g_usbd_UsbConfig); break; } case SET_FEATURE: { if(g_usbd_SetupPacket[2] == FEATURE_ENDPOINT_HALT) { USBD_SetStall(g_usbd_SetupPacket[4] & 0xF); DBG_PRINTF("Set feature. stall ep %d\n", g_usbd_SetupPacket[4] & 0xF); } else if(g_usbd_SetupPacket[2] == FEATURE_DEVICE_REMOTE_WAKEUP) { g_usbd_RemoteWakeupEn = 1; DBG_PRINTF("Set feature. enable remote wakeup\n"); } /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); break; } case SET_INTERFACE: { g_usbd_UsbAltInterface = g_usbd_SetupPacket[2]; if(g_usbd_pfnSetInterface != NULL) g_usbd_pfnSetInterface(); /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); DBG_PRINTF("Set interface to %d\n", g_usbd_UsbAltInterface); break; } default: { /* Setup error, stall the device */ USBD_SET_EP_STALL(EP0); USBD_SET_EP_STALL(EP1); DBG_PRINTF("Unsupported request. stall ctrl pipe.\n"); break; } } } }
void HID_ClassRequest(void) { uint8_t buf[8]; USBD_GetSetupPacket(buf); if (buf[0] & 0x80) /* request data transfer direction */ { // Device to host switch (buf[1]) { case GET_LINE_CODE: { if (buf[4] == 0) /* VCOM-1 */ { USBD_MemCopy((uint8_t *)(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)), (uint8_t *)&gLineCoding, 7); } /* Data stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 7); /* Status stage */ USBD_PrepareCtrlOut(0,0); break; } case GET_REPORT: case GET_IDLE: case GET_PROTOCOL: default: { /* Setup error, stall the device */ USBD_SetStall(0); break; } } } else { // Host to device switch (buf[1]) { case SET_CONTROL_LINE_STATE: { if (buf[4] == 0) /* VCOM-1 */ { gCtrlSignal = buf[3]; gCtrlSignal = (gCtrlSignal << 8) | buf[2]; //printf("RTS=%d DTR=%d\n", (gCtrlSignal0 >> 1) & 1, gCtrlSignal0 & 1); } /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); break; } case SET_LINE_CODE: { //g_usbd_UsbConfig = 0100; if (buf[4] == 0) /* VCOM-1 */ USBD_PrepareCtrlOut((uint8_t *)&gLineCoding, 7); /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); // /* UART setting */ // if (buf[4] == 0) /* VCOM-1 */ // VCOM_LineCoding(0); break; } case SET_REPORT: { if(buf[3] == 2) { /* Request Type = Output */ USBD_SET_DATA1(EP1); USBD_SET_PAYLOAD_LEN(EP1, buf[6]); /* Trigger for HID Int in */ USBD_SET_PAYLOAD_LEN(EP5, 0); /* Status stage */ USBD_PrepareCtrlIn(0, 0); } break; } case SET_IDLE: { /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); break; } case SET_PROTOCOL: default: { // Stall /* Setup error, stall the device */ USBD_SetStall(0); break; } } } }
void HID_ClassRequest(void) { uint8_t buf[8]; USBD_GetSetupPacket(buf); if(buf[0] & 0x80) /* request data transfer direction */ { // Device to host switch(buf[1]) { case GET_REPORT: // { // break; // } case GET_IDLE: // { // break; // } case GET_PROTOCOL: // { // break; // } default: { /* Setup error, stall the device */ USBD_SetStall(0); break; } } } else { // Host to device switch(buf[1]) { case SET_REPORT: { if(buf[3] == 3) { /* Request Type = Feature */ USBD_SET_DATA1(EP1); USBD_SET_PAYLOAD_LEN(EP1, 0); } else if(buf[3] == 2) { /* Request Type = Output */ USBD_SET_DATA1(EP1); USBD_SET_PAYLOAD_LEN(EP1, buf[6]); /* Trigger for HID Int in */ USBD_SET_PAYLOAD_LEN(EP4, 0); /* Status stage */ USBD_PrepareCtrlIn(0, 0); } break; } case SET_IDLE: { /* Status stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); break; } case SET_PROTOCOL: // { // break; // } default: { // Stall /* Setup error, stall the device */ USBD_SetStall(0); break; } } } }
void MSC_ClassRequest(void) { uint8_t buf[8]; USBD_GetSetupPacket(buf); if (buf[0] & 0x80) /* request data transfer direction */ { // Device to host switch (buf[1]) { case GET_MAX_LUN: { /* Check interface number with cfg descriptor and check wValue = 0, wLength = 1 */ if ((((buf[3]<<8)+buf[2]) == 0) && (((buf[5]<<8)+buf[4]) == 0) && (((buf[7]<<8)+buf[6]) == 1)) { M8(USBD_BUF_BASE + USBD_GET_EP_BUF_ADDR(EP0)) = 0; /* Data stage */ USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 1); /* Status stage */ USBD_PrepareCtrlOut(0,0); } else /* Invalid Get MaxLun command */ { USBD_SetStall(0); } break; } default: { /* Setup error, stall the device */ USBD_SetStall(0); break; } } } else { // Host to device switch (buf[1]) { case BULK_ONLY_MASS_STORAGE_RESET: { /* Check interface number with cfg descriptor and check wValue = 0, wLength = 0 */ if ((((buf[3]<<8)+buf[2]) == 0) && (((buf[5]<<8)+buf[4]) == 0) && (((buf[7]<<8)+buf[6]) == 0)) { USBD_SET_DATA1(EP0); USBD_SET_PAYLOAD_LEN(EP0, 0); USBD_LockEpStall(0); /* Clear ready */ USBD->EP[EP2].CFG |= USBD_CFG_CLRRDY_Msk; USBD->EP[EP3].CFG |= USBD_CFG_CLRRDY_Msk; /* Prepare to receive the CBW */ g_u8EP3Ready = 0; g_u8BulkState = BULK_CBW; USBD_SET_DATA1(EP3); USBD_SET_EP_BUF_ADDR(EP3, g_u32BulkBuf0); USBD_SET_PAYLOAD_LEN(EP3, EP3_MAX_PKT_SIZE); } else /* Invalid Reset command */ { USBD_SetStall(0); } break; } default: { // Stall /* Setup error, stall the device */ USBD_SetStall(0); break; } } } }