/** * @brief usbd_cdc_Setup * Handle the CDC specific requests * @param pdev: instance * @param req: usb requests * @retval status */ static uint8_t usbd_cdc_msc_Setup (void *pdev, USB_SETUP_REQ *req) { uint16_t len=USB_CDC_MSC_DESC_SIZ; uint8_t *pbuf=usbd_cdc_msc_CfgDesc + 9; switch (req->bmRequest & USB_REQ_TYPE_MASK) { /* CDC Class Requests -------------------------------*/ case USB_REQ_TYPE_CLASS : switch (req->bRequest) { case BOT_GET_MAX_LUN : if((req->wValue == 0) && (req->wLength == 1) && ((req->bmRequest & 0x80) == 0x80)) { USBD_MSC_MaxLun = USBD_STORAGE_fops->GetMaxLun(); if(USBD_MSC_MaxLun > 0) { USBD_CtlSendData (pdev, &USBD_MSC_MaxLun, 1); } else { USBD_CtlError(pdev , req); return USBD_FAIL; } } else { USBD_CtlError(pdev , req); return USBD_FAIL; } break; case BOT_RESET : if((req->wValue == 0) && (req->wLength == 0) && ((req->bmRequest & 0x80) != 0x80)) { MSC_BOT_Reset(pdev); } else { USBD_CtlError(pdev , req); return USBD_FAIL; } break; // CDC default: /* Check if the request is a data setup packet */ if (req->wLength) { /* Check if the request is Device-to-Host */ if (req->bmRequest & 0x80) { /* Get the data to be sent to Host from interface layer */ APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength); /* Send the data to the host */ USBD_CtlSendData (pdev, CmdBuff, req->wLength); } else /* Host-to-Device requeset */ { /* Set the value of the current command to be processed */ cdcCmd = req->bRequest; cdcLen = req->wLength; /* Prepare the reception of the buffer over EP0 Next step: the received data will be managed in usbd_cdc_EP0_TxSent() function. */ USBD_CtlPrepareRx (pdev, CmdBuff, req->wLength); } } else /* No Data request */ { /* Transfer the command to the interface layer */ APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0); // check for DTE present changes - NEZ if (req->bRequest == SET_CONTROL_LINE_STATE) { USB_DTE_Present = req->wValue & 0x01; if (!USB_DTE_Present) { DCD_EP_Flush (pdev, CDC_IN_EP); USB_Tx_State = 0; } } } return USBD_OK; break; // default } break; // case USB_REQ_TYPE_CLASS /* Standard Requests -------------------------------*/ case USB_REQ_TYPE_STANDARD: switch (req->bRequest) { case USB_REQ_GET_DESCRIPTOR: if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE) { #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED pbuf = usbd_cdc_Desc; #else pbuf = usbd_cdc_msc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM); #endif len = MIN(USB_CDC_MSC_DESC_SIZ , req->wLength); } USBD_CtlSendData (pdev, pbuf, len); break; case USB_REQ_GET_INTERFACE : if ((uint8_t)req->wValue == CDC_IN_EP || (uint8_t)req->wValue == CDC_OUT_EP) { USBD_CtlSendData (pdev, (uint8_t *)&usbd_cdc_AltSet, 1); } else { USBD_CtlSendData (pdev, &USBD_MSC_AltSet, 1); break; } break; case USB_REQ_SET_INTERFACE : if ((uint8_t)req->wValue == CDC_IN_EP || (uint8_t)req->wValue == CDC_OUT_EP) { if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM) { usbd_cdc_AltSet = (uint8_t)(req->wValue); } else { /* Call the error management function (command will be nacked */ USBD_CtlError (pdev, req); } } else { USBD_MSC_AltSet = (uint8_t)(req->wValue); } break; case USB_REQ_CLEAR_FEATURE: /* Flush the FIFO and Clear the stall status */ DCD_EP_Flush(pdev, (uint8_t)req->wIndex); /* Re-activate the EP */ DCD_EP_Close (pdev , (uint8_t)req->wIndex); if((((uint8_t)req->wIndex) & 0x80) == 0x80) { DCD_EP_Open(pdev, ((uint8_t)req->wIndex), MSC_EPIN_SIZE, USB_OTG_EP_BULK); } else { DCD_EP_Open(pdev, ((uint8_t)req->wIndex), MSC_EPOUT_SIZE, USB_OTG_EP_BULK); } /* Handle BOT error */ MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); break; } } return USBD_OK; }
/** * @brief USBD_MSC_Setup * Handle the MSC specific requests * @param pdev: device instance * @param req: USB request * @retval status */ uint8_t USBD_MSC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_MSC_BOT_HandleTypeDef *hmsc = pdev->pClassData; switch (req->bmRequest & USB_REQ_TYPE_MASK) { /* Class request */ case USB_REQ_TYPE_CLASS : switch (req->bRequest) { case BOT_GET_MAX_LUN : if((req->wValue == 0) && (req->wLength == 1) && ((req->bmRequest & 0x80) == 0x80)) { hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); USBD_CtlSendData (pdev, (uint8_t *)&hmsc->max_lun, 1); } else { USBD_CtlError(pdev , req); return USBD_FAIL; } break; case BOT_RESET : if((req->wValue == 0) && (req->wLength == 0) && ((req->bmRequest & 0x80) != 0x80)) { MSC_BOT_Reset(pdev); } else { USBD_CtlError(pdev , req); return USBD_FAIL; } break; default: USBD_CtlError(pdev , req); return USBD_FAIL; } break; /* Interface & Endpoint request */ case USB_REQ_TYPE_STANDARD: switch (req->bRequest) { case USB_REQ_GET_INTERFACE : USBD_CtlSendData (pdev, (uint8_t *)&hmsc->interface, 1); break; case USB_REQ_SET_INTERFACE : hmsc->interface = (uint8_t)(req->wValue); break; case USB_REQ_CLEAR_FEATURE: /* Flush the FIFO and Clear the stall status */ USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); /* Re-activate the EP */ USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex); if((((uint8_t)req->wIndex) & 0x80) == 0x80) { if(pdev->dev_speed == USBD_SPEED_HIGH ) { /* Open EP IN */ USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); } else { /* Open EP IN */ USBD_LL_OpenEP(pdev, MSC_EPIN_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); } } else { if(pdev->dev_speed == USBD_SPEED_HIGH ) { /* Open EP IN */ USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_HS_PACKET); } else { /* Open EP IN */ USBD_LL_OpenEP(pdev, MSC_EPOUT_ADDR, USBD_EP_TYPE_BULK, MSC_MAX_FS_PACKET); } } /* Handle BOT error */ MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); break; } break; default: break; } return 0; }