void MSC_ClassRequest(void) { g_u8MscStart = 1; if (gUsbCmd.bmRequestType & 0x80) { /* request data transfer direction */ // Device to host switch (gUsbCmd.bRequest) { case GET_MAX_LUN: { // Return current configuration setting USBD_PrepareCtrlIn((uint8_t *)&g_u32MSCMaxLun, 1); USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_INTKIF_Msk); UBSD_ENABLE_CEP_INT(USBD_CEPINTEN_INTKIEN_Msk); break; } default: { /* Setup error, stall the device */ USBD_SET_CEP_STATE(USBD_CEPCTL_STALLEN_Msk); break; } } } else { // Host to device switch (gUsbCmd.bRequest) { case BULK_ONLY_MASS_STORAGE_RESET: { /* Status stage */ USBD_CLR_CEP_INT_FLAG(USBD_CEPINTSTS_STSDONEIF_Msk); USBD_SET_CEP_STATE(USB_CEPCTL_NAKCLR); UBSD_ENABLE_CEP_INT(USBD_CEPINTEN_STSDONEIEN_Msk); break; } default: { // Stall /* Setup error, stall the device */ USBD_SET_CEP_STATE(USBD_CEPCTL_STALLEN_Msk); break; } } } }
/** * @brief Process GetDescriptor request * * @param None * * @return None * * @details Parse GetDescriptor request and perform the corresponding action. * */ void USBD_GetDescriptor(void) { uint32_t u32Len; u32Len = 0; u32Len = g_usbd_SetupPacket[7]; u32Len <<= 8; u32Len += g_usbd_SetupPacket[6]; switch(g_usbd_SetupPacket[3]) { // Get Device Descriptor case DESC_DEVICE: { u32Len = Minimum(u32Len, LEN_DEVICE); DBG_PRINTF("Get device desc, %d\n", u32Len); USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8DevDesc, u32Len); USBD_PrepareCtrlOut(0, 0); break; } // Get Configuration Descriptor case DESC_CONFIG: { uint32_t u32TotalLen; u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3]; u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8); DBG_PRINTF("Get config desc len %d, acture len %d\n", u32Len, u32TotalLen); u32Len = Minimum(u32Len, u32TotalLen); DBG_PRINTF("Minimum len %d\n", u32Len); USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8ConfigDesc, u32Len); USBD_PrepareCtrlOut(0, 0); break; } // Get HID Descriptor case DESC_HID: { int32_t i32IfNum; int32_t i32TotalSize; int32_t i32Idx; uint8_t *pu8HidDesc; int32_t i32Size = 0; // Get total size of configuration descriptor i32TotalSize = g_usbd_sInfo->gu8ConfigDesc[3]; i32TotalSize = (i32TotalSize << 8) | g_usbd_sInfo->gu8ConfigDesc[2]; // Get requested HID interface i32IfNum = g_usbd_SetupPacket[4]; // Search specified HID descriptor in configuration descritpor pu8HidDesc = NULL; i32Idx = 1; do{ // Search interface first and check HID class code (0x3) and check requested interface number if((g_usbd_sInfo->gu8ConfigDesc[i32Idx] == DESC_INTERFACE) && (g_usbd_sInfo->gu8ConfigDesc[i32Idx+4] == 0x3) && (g_usbd_sInfo->gu8ConfigDesc[i32Idx+1] == i32IfNum)) { // Calculate the offset of the requested HID descriptor in configuration descriptor i32Idx = i32Idx-1+g_usbd_sInfo->gu8ConfigDesc[i32Idx-1]; pu8HidDesc = (uint8_t *)&g_usbd_sInfo->gu8ConfigDesc[i32Idx]; i32Size = pu8HidDesc[0]; DBG_PRINTF("HID desc at if=%d, offset=%d\n", i32IfNum, i32Idx); break; } else i32Idx += g_usbd_sInfo->gu8ConfigDesc[i32Idx-1]; // Seek to next descriptor }while(i32Idx < i32TotalSize); if(pu8HidDesc) { u32Len = Minimum(u32Len, i32Size); USBD_PrepareCtrlIn(pu8HidDesc, u32Len); USBD_PrepareCtrlOut(0, 0); } else { // No any HID descriptor found. Just stall. USBD_SET_EP_STALL(EP0); USBD_SET_EP_STALL(EP1); DBG_PRINTF("No HID desc found. stall ctrl pipe\n"); } break; } // Get Report Descriptor case DESC_HID_RPT: { uint32_t u32RptDescLen; uint8_t *pu8RptDesc; if(g_usbd_pfnGetHidReportCallback) pu8RptDesc = g_usbd_pfnGetHidReportCallback(g_usbd_SetupPacket[4] ,&u32RptDescLen); else { pu8RptDesc = (uint8_t *)g_usbd_sInfo->gu8HidReportDesc; u32RptDescLen = u32Len; } if(pu8RptDesc) { u32Len = Minimum(u32Len, u32RptDescLen); DBG_PRINTF("Get report desc %d\n", u32Len); USBD_PrepareCtrlIn(pu8RptDesc, u32Len); USBD_PrepareCtrlOut(0, 0); } else { USBD_SET_EP_STALL(EP0); USBD_SET_EP_STALL(EP1); DBG_PRINTF("No HID report. stall ctrl pipe\n"); } break; } // Get String Descriptor case DESC_STRING: { // Get String Descriptor if(g_usbd_SetupPacket[2] < 4) { u32Len = Minimum(u32Len, g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]][0]); DBG_PRINTF("Get string desc %d\n", u32Len); USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]], u32Len); USBD_PrepareCtrlOut(0, 0); break; } else { // Not support. Reply STALL. USBD_SET_EP_STALL(EP0); USBD_SET_EP_STALL(EP1); DBG_PRINTF("Unsupported string desc (%d). Stall ctrl pipe.\n", g_usbd_SetupPacket[2]); break; } } default: // Not support. Reply STALL. USBD_SET_EP_STALL(EP0); USBD_SET_EP_STALL(EP1); DBG_PRINTF("Unsupported get desc type. 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; } } } }
/** * @brief Process GetDescriptor request * * @param None * * @return None * * @details Parse GetDescriptor request and perform the corresponding action. * */ void USBD_GetDescriptor(void) { uint32_t u32Len; u32Len = 0; u32Len = g_usbd_SetupPacket[7]; u32Len <<= 8; u32Len += g_usbd_SetupPacket[6]; switch(g_usbd_SetupPacket[3]) { // Get Device Descriptor case DESC_DEVICE: { u32Len = Minimum(u32Len, LEN_DEVICE); DBG_PRINTF("Get device desc, %d\n", u32Len); USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8DevDesc, u32Len); break; } // Get Configuration Descriptor case DESC_CONFIG: { uint32_t u32TotalLen; u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[3]; u32TotalLen = g_usbd_sInfo->gu8ConfigDesc[2] + (u32TotalLen << 8); DBG_PRINTF("Get config desc len %d, acture len %d\n", u32Len, u32TotalLen); u32Len = Minimum(u32Len, u32TotalLen); DBG_PRINTF("Minimum len %d\n", u32Len); USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8ConfigDesc, u32Len); break; } // Get HID Descriptor case DESC_HID: { /* CV3.0 HID Class Descriptor Test, Need to indicate index of the HID Descriptor within gu8ConfigDescriptor, specifically HID Composite device. */ uint32_t u32ConfigDescOffset; // u32ConfigDescOffset is configuration descriptor offset (HID descriptor start index) u32Len = Minimum(u32Len, LEN_HID); DBG_PRINTF("Get HID desc, %d\n", u32Len); u32ConfigDescOffset = g_usbd_sInfo->gu32ConfigHidDescIdx[g_usbd_SetupPacket[4]]; USBD_PrepareCtrlIn((uint8_t *)&g_usbd_sInfo->gu8ConfigDesc[u32ConfigDescOffset], u32Len); break; } // Get Report Descriptor case DESC_HID_RPT: { DBG_PRINTF("Get HID report, %d\n", u32Len); u32Len = Minimum(u32Len, g_usbd_sInfo->gu32HidReportSize[g_usbd_SetupPacket[4]]); USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8HidReportDesc[g_usbd_SetupPacket[4]], u32Len); break; } // Get String Descriptor case DESC_STRING: { // Get String Descriptor if(g_usbd_SetupPacket[2] < 4) { u32Len = Minimum(u32Len, g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]][0]); DBG_PRINTF("Get string desc %d\n", u32Len); USBD_PrepareCtrlIn((uint8_t *)g_usbd_sInfo->gu8StringDesc[g_usbd_SetupPacket[2]], u32Len); break; } else { // Not support. Reply STALL. USBD_SET_EP_STALL(EP0); USBD_SET_EP_STALL(EP1); DBG_PRINTF("Unsupported string desc (%d). Stall ctrl pipe.\n", g_usbd_SetupPacket[2]); break; } } default: // Not support. Reply STALL. USBD_SET_EP_STALL(EP0); USBD_SET_EP_STALL(EP1); DBG_PRINTF("Unsupported get desc type. stall ctrl pipe\n"); break; } }