static uint8_t usbd_rndis_setup(void *pdev, USB_SETUP_REQ *req) { switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : if (req->wLength != 0) // is data setup packet? { /* Check if the request is Device-to-Host */ if (req->bmRequest & 0x80) { USBD_CtlSendData(pdev, encapsulated_buffer, ((rndis_generic_msg_t *)encapsulated_buffer)->MessageLength); } else /* Host-to-Device requeset */ { USBD_CtlPrepareRx(pdev, encapsulated_buffer, req->wLength); } } return USBD_OK; default: return USBD_OK; // USBD_CtlError (pdev, req); // return USBD_FAIL; } }
/** * @brief USBD_CDC_Setup * Handle the CDC specific requests * @param pdev: instance * @param req: usb requests * @retval status */ static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_CDC_HandleTypeDef *hcdc = pdev->pClassData; switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : if (req->wLength) { if (req->bmRequest & 0x80) { ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, (uint8_t *)hcdc->data, req->wLength); USBD_CtlSendData (pdev, (uint8_t *)hcdc->data, req->wLength); } else { hcdc->CmdOpCode = req->bRequest; hcdc->CmdLength = req->wLength; USBD_CtlPrepareRx (pdev, (uint8_t *)hcdc->data, req->wLength); } break; } } return USBD_OK; }
/** * @brief USBD_CDC_Setup * Handle the CDC specific requests * @param pdev: instance * @param req: usb requests * @retval status */ static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; static uint8_t ifalt = 0; switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : if (req->wLength) { if (req->bmRequest & 0x80) { ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, (uint8_t *)hcdc->data, req->wLength); USBD_CtlSendData (pdev, (uint8_t *)hcdc->data, req->wLength); } else { hcdc->CmdOpCode = req->bRequest; hcdc->CmdLength = req->wLength; USBD_CtlPrepareRx (pdev, (uint8_t *)hcdc->data, req->wLength); } } else { ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, (uint8_t*)req, 0); } break; case USB_REQ_TYPE_STANDARD: switch (req->bRequest) { case USB_REQ_GET_INTERFACE : USBD_CtlSendData (pdev, &ifalt, 1); break; case USB_REQ_SET_INTERFACE : break; } case USB_REQ_TYPE_VENDOR: return USBD_WinUSBComm_SetupVendor(pdev, req); default: break; } return USBD_OK; }
//PC SEND DATA TO uC static void VIDEO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req) { if (req->wLength) { /* Prepare the reception of the buffer over EP0 */ if(req->wValue == 256) { //Probe Request USBD_CtlPrepareRx (pdev, (uint8_t*)&videoProbeControl, req->wLength); } else if (req->wValue == 512) { //Commit Request USBD_CtlPrepareRx (pdev, (uint8_t*)&videoCommitControl, req->wLength); } } }
static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_CDC_HID_HandleTypeDef *handle = (USBD_CDC_HID_HandleTypeDef*) pdev->pClassData; static uint8_t ifalt = 0; switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : if (req->wLength) { if (req->bmRequest & 0x80) { CDC_Control_FS(req->bRequest, (uint8_t *)handle->data, req->wLength); USBD_CtlSendData (pdev, (uint8_t *)handle->data, req->wLength); } else { handle->CmdOpCode = req->bRequest; handle->CmdLength = (uint8_t)req->wLength; USBD_CtlPrepareRx (pdev, (uint8_t *)handle->data, req->wLength); } } else { CDC_Control_FS(req->bRequest, (uint8_t*)req, 0); } break; case USB_REQ_TYPE_STANDARD: switch (req->bRequest) { case USB_REQ_GET_INTERFACE : USBD_CtlSendData (pdev, &ifalt, 1); break; case USB_REQ_SET_INTERFACE : break; } default: break; } return USBD_OK; }
/** * @brief DFU_Download * Handles the DFU DNLOAD request. * @param pdev: device instance * @param req: pointer to the request structure * @retval None */ static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_DFU_HandleTypeDef *hdfu; hdfu = pdev->pClassData; /* Data setup request */ if (req->wLength > 0) { if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE)) { /* Update the global length and block number */ hdfu->wblock_num = req->wValue; hdfu->wlength = req->wLength; /* Update the state machine */ hdfu->dev_state = DFU_STATE_DNLOAD_SYNC; hdfu->dev_status[4] = hdfu->dev_state; /* Prepare the reception of the buffer over EP0 */ USBD_CtlPrepareRx (pdev, (uint8_t*)hdfu->buffer.d8, hdfu->wlength); } /* Unsupported state */ else { /* Call the error management function (command will be nacked */ USBD_CtlError (pdev, req); } } /* 0 Data DNLOAD request */ else { /* End of DNLOAD operation*/ if (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || hdfu->dev_state == DFU_STATE_IDLE ) { hdfu->manif_state = DFU_MANIFEST_IN_PROGRESS; hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; hdfu->dev_status[1] = 0; hdfu->dev_status[2] = 0; hdfu->dev_status[3] = 0; hdfu->dev_status[4] = hdfu->dev_state; } else { /* Call the error management function (command will be nacked */ USBD_CtlError (pdev, req); } } }
/** * @brief AUDIO_Req_SetCurrent * Handles the SET_CUR Audio control request. * @param pdev: instance * @param req: setup class request * @retval status */ static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req) { if (req->wLength) { /* Prepare the reception of the buffer over EP0 */ USBD_CtlPrepareRx (pdev, AudioCtl, req->wLength); /* Set the global variables indicating current request and its length to the function usbd_audio_EP0_RxReady() which will process the request */ AudioCtlCmd = AUDIO_REQ_SET_CUR; /* Set the request value */ AudioCtlLen = req->wLength; /* Set the request data length */ AudioCtlUnit = HIBYTE(req->wIndex); /* Set the request target unit */ } }
/** * @brief DFU_Req_DNLOAD * Handles the DFU DNLOAD request. * @param pdev: device instance * @param req: pointer to the request structure * @retval None */ static void DFU_Req_DNLOAD(void *pdev, USB_SETUP_REQ *req) { /* Data setup request */ if (req->wLength > 0) { if ((DeviceState == STATE_dfuIDLE) || (DeviceState == STATE_dfuDNLOAD_IDLE)) { /* Update the global length and block number */ wBlockNum = req->wValue; wlength = req->wLength; /* Update the state machine */ DeviceState = STATE_dfuDNLOAD_SYNC; DeviceStatus[4] = DeviceState; /* Prepare the reception of the buffer over EP0 */ USBD_CtlPrepareRx (pdev, (uint8_t*)MAL_Buffer, wlength); } /* Unsupported state */ else { /* Call the error management function (command will be nacked */ USBD_CtlError (pdev, req); } } /* 0 Data DNLOAD request */ else { /* End of DNLOAD operation*/ if (DeviceState == STATE_dfuDNLOAD_IDLE || DeviceState == STATE_dfuIDLE ) { Manifest_State = Manifest_In_Progress; DeviceState = STATE_dfuMANIFEST_SYNC; DeviceStatus[1] = 0; DeviceStatus[2] = 0; DeviceStatus[3] = 0; DeviceStatus[4] = DeviceState; } else { /* Call the error management function (command will be nacked */ USBD_CtlError (pdev, req); } } }
/** * @brief AUDIO_Req_SetCurrent * Handles the SET_CUR Audio control request. * @param pdev: instance * @param req: setup class request * @retval status */ static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_AUDIO_HandleTypeDef *haudio; haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData; if (req->wLength) { /* Prepare the reception of the buffer over EP0 */ USBD_CtlPrepareRx (pdev, haudio->control.data, req->wLength); haudio->control.cmd = AUDIO_REQ_SET_CUR; /* Set the request value */ haudio->control.len = req->wLength; /* Set the request data length */ haudio->control.unit = HIBYTE(req->wIndex); /* Set the request target unit */ } }
static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { USBD_CDC_HandleTypeDef *hcdc = context; unsigned index; for (index = 0; index < NUM_OF_CDC_UARTS; index++,hcdc++) { if (parameters[index].command_itf != req->wIndex) continue; switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : if (req->wLength) { if (req->bmRequest & 0x80) { CDC_Itf_Control(hcdc, req->bRequest, (uint8_t *)hcdc->SetupBuffer, req->wLength); USBD_CtlSendData (pdev, (uint8_t *)hcdc->SetupBuffer, req->wLength); } else { hcdc->CmdOpCode = req->bRequest; hcdc->CmdLength = req->wLength; USBD_CtlPrepareRx (pdev, (uint8_t *)hcdc->SetupBuffer, req->wLength); } } else { CDC_Itf_Control(hcdc, req->bRequest, NULL, 0); } break; default: break; } break; } return USBD_OK; }
/** * @brief USBD_CDC_Setup * Handle the CDC specific requests * @param pdev: instance * @param req: usb requests * @retval status */ static uint8_t USBD_CDC_Setup (void *pdev, USB_SETUP_REQ *req) { dbgwdg_feed(); uint16_t len=USB_CDC_DESC_SIZ; uint8_t *pbuf=USBD_CDC_ConfigDescriptor + 9; switch (req->bmRequest & USB_REQ_TYPE_MASK) { /* CDC Class Requests -------------------------------*/ case USB_REQ_TYPE_CLASS : /* Check if the request is a data setup packet */ if (req->wLength > 0) { /* Check if the request is Device-to-Host */ if (req->bmRequest & 0x80) { // nothing to do //VCP_Ctrl(req->bRequest, CmdBuff, req->wLength); if (req->bRequest == CDC_GET_LINE_CODING) { memcpy(USBD_CDC_CMD_Buff, &cdc_linecoding, req->wLength); } /* Send the data to the host */ USBD_CtlSendData (pdev, USBD_CDC_CMD_Buff, req->wLength); } else /* Host-to-Device request */ { /* Set the value of the current command to be processed */ // nothing to do //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, USBD_CDC_CMD_Buff, req->wLength); } } else { // nothing to do //VCP_Ctrl(req->bRequest, NULL, 0); USBD_CtlSendStatus(pdev); } return USBD_OK; /* Standard Requests -------------------------------*/ case USB_REQ_TYPE_STANDARD: switch (req->bRequest) { case USB_REQ_GET_DESCRIPTOR: if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE) { pbuf = USBD_CDC_ConfigDescriptor + 9 + (9 * USBD_ITF_MAX_NUM); len = MIN(USB_CDC_DESC_SIZ , req->wLength); } USBD_CtlSendData (pdev, pbuf, len); break; case USB_REQ_GET_INTERFACE : USBD_CtlSendData (pdev, (uint8_t *)&USBD_CDC_AltSet, 1); break; case USB_REQ_SET_INTERFACE : if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM) { USBD_CDC_AltSet = (uint8_t)(req->wValue); } else { USBD_CtlError (pdev, req); dbg_printf(DBGMODE_ERR, "CDC Stall, USB_REQ_SET_INTERFACE, unknown wValue 0x%04X, file " __FILE__ ":%d\r\n", req->wValue, __LINE__); } break; } default: USBD_CtlError (pdev, req); dbg_printf(DBGMODE_ERR, "CDC Stall, unknown bmRequest 0x%02X, file " __FILE__ ":%d\r\n", req->bmRequest, __LINE__); return USBD_FAIL; } return USBD_OK; }
void PIOS_USBHOOK_CtrlRx(uint8_t *buf, uint16_t len) { USBD_CtlPrepareRx(&pios_usb_otg_core_handle, buf, len); }
uint8_t HAL_USB_Handle_Vendor_Request(USB_SETUP_REQ* req, uint8_t dataStage) { uint8_t ret = USBD_OK; // Forward Microsoft vendor requests to Composite driver if (req != NULL && req->bRequest == 0xee && req->wIndex == 0x0004 && req->wValue == 0x0000) { return USBD_Composite_Handle_Msft_Request(&USB_OTG_dev, req); } if (USB_Vendor_Request_Callback == NULL) return USBD_FAIL; if (req != NULL) { USB_SetupRequest.bmRequestType = req->bmRequest; USB_SetupRequest.bRequest = req->bRequest; USB_SetupRequest.wValue = req->wValue; USB_SetupRequest.wIndex = req->wIndex; USB_SetupRequest.wLength = req->wLength; if (req->wLength) { // Setup request with data stage if (req->bmRequest & 0x80) { // Device -> Host if (req->wLength <= USBD_EP0_MAX_PACKET_SIZE) USB_SetupRequest.data = USB_SetupRequest_Data; else USB_SetupRequest.data = NULL; ret = USB_Vendor_Request_Callback(&USB_SetupRequest, USB_Vendor_Request_Ptr); if (ret == USBD_OK && USB_SetupRequest.data != NULL && USB_SetupRequest.wLength) { if (USB_SetupRequest.data != USB_SetupRequest_Data && USB_SetupRequest.wLength <= USBD_EP0_MAX_PACKET_SIZE) { // Don't use user buffer if wLength <= USBD_EP0_MAX_PACKET_SIZE // and copy into internal buffer memcpy(USB_SetupRequest_Data, USB_SetupRequest.data, USB_SetupRequest.wLength); } USBD_CtlSendData (&USB_OTG_dev, USB_SetupRequest_Data, USB_SetupRequest.wLength); } else { ret = USBD_FAIL; } } else { // Host -> Device USB_InSetupRequest = 1; if (req->wLength <= USBD_EP0_MAX_PACKET_SIZE) { // Use internal buffer USB_SetupRequest.data = USB_SetupRequest_Data; USBD_CtlPrepareRx(&USB_OTG_dev, USB_SetupRequest_Data, req->wLength); } else { // Try to request the buffer USB_SetupRequest.data = NULL; USB_Vendor_Request_Callback(&USB_SetupRequest, USB_Vendor_Request_Ptr); if (USB_SetupRequest.data != NULL && USB_SetupRequest.wLength >= req->wLength) { USB_SetupRequest.wLength = req->wLength; USBD_CtlPrepareRx(&USB_OTG_dev, USB_SetupRequest.data, req->wLength); } else { ret = USBD_FAIL; } } } } else { // Setup request without data stage USB_SetupRequest.data = NULL; ret = USB_Vendor_Request_Callback(&USB_SetupRequest, USB_Vendor_Request_Ptr); } } else if (dataStage && USB_InSetupRequest) { // Data stage completed USB_InSetupRequest = 0; ret = USB_Vendor_Request_Callback(&USB_SetupRequest, USB_Vendor_Request_Ptr); } else { ret = USBD_FAIL; } return ret ? USBD_FAIL : USBD_OK; }
uint8_t USBPTD_SetupStage(USB_OTG_CORE_HANDLE* pcore, USB_SETUP_REQ* req) { // store for later use from another function memcpy(USBPT_LastSetupPacket, pcore->dev.setup_packet, 24); // print for monitoring USBPT_printf("\b\r\n USBPT:SETUP:"); for (uint8_t i = 0; i < 8; i++) { USBPT_printf(" 0x%02X", USBPT_LastSetupPacket[i]); } USBPT_printf("\r\n"); // prepare to be sent to the device memcpy(USBPT_Dev->Control.setup.d8, USBPT_LastSetupPacket, 8); // set address must be handled explicitly if ((req->bmRequest & 0x7F) == (USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD) && req->bRequest == USB_REQ_SET_ADDRESS) { // let the internal code handle it for the device interface USBD_StdDevReq(pcore, req); // pass it to the downstream device USBH_CtlReq_Blocking(&USB_OTG_Core_host, USBPT_Dev, 0, 0, 100); USBD_CtlSendStatus(pcore); // modifiy our host channel to match USBPT_Dev->device_prop.address = (uint8_t)(req->wValue) & 0x7F; USBH_Modify_Channel (&USB_OTG_Core_host, USBPT_Dev->Control.hc_num_in, USBPT_Dev->device_prop.address, 0, 0, 0); USBH_Modify_Channel (&USB_OTG_Core_host, USBPT_Dev->Control.hc_num_out, USBPT_Dev->device_prop.address, 0, 0, 0); // modify all other channels to match for (uint8_t i = 0; i < USBPTH_MAX_LISTENERS; i++) { USBPTH_HC_EP_t* pl = &USBPTH_Listeners[i]; uint8_t hc = pl->hc; if (hc != 0 && hc != HC_ERROR) // if listener is actually allocated { USBH_EpDesc_TypeDef* epDesc = pl->epDesc; uint8_t epType = 0; if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_INTR) { epType = EP_TYPE_INTR; } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_BULK) { epType = EP_TYPE_BULK; } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_ISOC) { epType = EP_TYPE_ISOC; } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_CTRL) { epType = EP_TYPE_CTRL; } USBH_Modify_Channel( &USB_OTG_Core_host, USBPTH_Listeners[i].hc, USBPT_Dev->device_prop.address, USBPT_Dev->device_prop.speed, epType, USBPTH_Listeners[i].epDesc->wMaxPacketSize); } } // note: out direction channels are dynamically allocated only when needed // so we don't need to modify those channel addresses return USBD_OK; } // no data means we can just directly relay the data if (req->wLength == 0) { USBH_CtlReq_Blocking(&USB_OTG_Core_host, USBPT_Dev, 0, 0, 100); USBD_CtlSendStatus(pcore); return USBD_OK; } // there is extra data later USBPT_CtrlDataLen = req->wLength; if (USBPT_CtrlData != 0) free(USBPT_CtrlData); USBPT_CtrlData = malloc(USBPT_CtrlDataLen); USBH_Status status; // wait until previous req is finished delay_1ms_cnt = 100; while (delay_1ms_cnt > 0 && USBPT_Dev->Control.state != CTRL_COMPLETE && USBPT_Dev->Control.state != CTRL_IDLE && USBPT_Dev->Control.state != CTRL_ERROR && USBPT_Dev->Control.state != CTRL_STALLED); { status = USBH_HandleControl(&USB_OTG_Core_host, USBPT_Dev); } // finalize previous ctrl req if (USBPT_Dev->RequestState == CMD_WAIT) { USBH_CtlReq(&USB_OTG_Core_host, USBPT_Dev, 0 , 0 ); } // prepare new setup USBH_SubmitSetupRequest(USBPT_Dev, USBPT_CtrlData, USBPT_CtrlDataLen); USBPT_Dev->RequestState = CMD_WAIT; USBH_CtlSendSetup (&USB_OTG_Core_host, USBPT_Dev->Control.setup.d8, USBPT_Dev->Control.hc_num_out); USBPT_Dev->Control.state = CTRL_SETUP_WAIT; USBPT_Dev->Control.timer = HCD_GetCurrentFrame(pcore); USBPT_Dev->Control.timeout = 50; if ((req->bmRequest & 0x80) == 0) { // H2D // we need to obtain the data from EP0_RxReady first USBD_CtlPrepareRx (pcore, USBPT_CtrlData, USBPT_CtrlDataLen); return USBD_OK; } else { // D2H // wait for request to finish delay_1ms_cnt = 100; do { status = USBH_CtlReq(&USB_OTG_Core_host, USBPT_Dev, USBPT_CtrlData , USBPT_CtrlDataLen ); if (status == USBH_OK || status == USBH_FAIL || status == USBH_STALL || status == USBH_NOT_SUPPORTED) { break; } else { status = USBH_HandleControl(&USB_OTG_Core_host, USBPT_Dev); if (status == USBH_FAIL || status == USBH_STALL || status == USBH_NOT_SUPPORTED) { break; } } } while (delay_1ms_cnt > 0); if (delay_1ms_cnt == 0) { // timeout dbg_printf(DBGMODE_ERR, "USBPT Setup Timed Out \r\n"); USBD_CtlSendStatus(pcore); // we reply with nothing to simulate a timeout return USBH_OK; } else if (status == USBH_OK) { // all good, send back the data USBD_CtlSendData (pcore, USBPT_CtrlData, USBPT_CtrlDataLen); // handle config descriptors specially, we need to know what channels to open based on endpoints if ((req->bmRequest & 0x7F) == (USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD) && req->bRequest == USB_REQ_GET_DESCRIPTOR && req->wValue == USB_DESC_CONFIGURATION && req->wLength > USB_CONFIGURATION_DESC_SIZE) { // this is a full length configuration descriptor // we need this info to open as many D2H endpoints to channels USBH_ParseCfgDesc(&USBPT_Dev->device_prop.Cfg_Desc, USBPT_Dev->device_prop.Itf_Desc, USBPT_Dev->device_prop.Ep_Desc, USBPT_CtrlData, USBPT_CtrlDataLen); USBPTH_OutEPCnt = 0; USBPT_GeneralInDataLen = 0; for (uint8_t i = 0; i < USBPT_Dev->device_prop.Cfg_Desc.bNumInterfaces && i < USBH_MAX_NUM_INTERFACES; i++) { for (uint8_t j = 0; j < USBPT_Dev->device_prop.Itf_Desc[i].bNumEndpoints && j < USBH_MAX_NUM_ENDPOINTS; j++) { USBH_EpDesc_TypeDef* epDesc = &USBPT_Dev->device_prop.Ep_Desc[i][j]; for (uint8_t k = 0; k < USBPTH_MAX_LISTENERS; k++) { if ((epDesc->bEndpointAddress & USB_EP_DIR_MSK) == USB_D2H && USBPTH_Listeners[k].used == 0) { USBPTH_Listeners[k].epDesc = epDesc; uint8_t epType = 0; if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_INTR) { epType = EP_TYPE_INTR; } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_BULK) { epType = EP_TYPE_BULK; } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_ISOC) { epType = EP_TYPE_ISOC; } else if ((epDesc->bmAttributes & USB_EP_TYPE_INTR) == USB_EP_TYPE_CTRL) { epType = EP_TYPE_CTRL; } USBH_Open_Channel( &USB_OTG_Core_host, &(USBPTH_Listeners[k].hc), epDesc->bEndpointAddress, USBPT_Dev->device_prop.address, USBPT_Dev->device_prop.speed, epType, USBPTH_Listeners[k].epDesc->wMaxPacketSize); if (USBPTH_Listeners[k].hc >= 0) { USBPTH_Listeners[k].used = 1; DCD_EP_Open(&USB_OTG_Core_dev, epDesc->bEndpointAddress, epDesc->wMaxPacketSize, epType); if (epDesc->wMaxPacketSize > USBPT_GeneralInDataMax) { USBPT_GeneralInDataMax = epDesc->wMaxPacketSize; } } } } if ((epDesc->bEndpointAddress & 0x80) == USB_H2D) { USBPTH_OutEPCnt++; } } } if (USBPT_GeneralInData != 0) free(USBPT_GeneralInData); // release memory if previously allocated USBPT_GeneralInData = malloc(USBPT_GeneralInDataMax); // only allocate the memory we need if (USBPTH_OutEP != 0) free(USBPTH_OutEP); // release memory if previously allocated USBPTH_OutEP = malloc(sizeof(USBH_EpDesc_TypeDef*) * USBPTH_OutEPCnt); // only allocate the memory we need uint8_t ec = 0; for (uint8_t i = 0; i < USBPT_Dev->device_prop.Cfg_Desc.bNumInterfaces && i < USBH_MAX_NUM_INTERFACES; i++) { for (uint8_t j = 0; j < USBPT_Dev->device_prop.Itf_Desc[i].bNumEndpoints && j < USBH_MAX_NUM_ENDPOINTS; j++) { USBH_EpDesc_TypeDef* epDesc = &USBPT_Dev->device_prop.Ep_Desc[i][j]; if ((epDesc->bEndpointAddress & 0x80) == USB_H2D) { // only save the H2D direction endpoints USBPTH_OutEP[ec] = epDesc; ec++; } } } } return USBH_OK; } else { if (status == USBH_STALL || status == USBH_NOT_SUPPORTED) { dbg_printf(DBGMODE_ERR, "USBPT Setup Stalled \r\n"); USBD_CtlError(pcore , req); return USBH_OK; } } return USBD_OK; } dbg_printf(DBGMODE_ERR, "USBPT Setup Unhandled Error \r\n"); USBD_CtlError(pcore , req); return USBD_OK; }
void Process_USB_Set_Request(USB_SETUP_REQ *req) { if (req->wLength < BCKP_STRUCT_LENGTH + 2) USBD_CtlPrepareRx(&USB_OTG_dev,buffer,req->wLength); }
/** * @brief USBD_CUSTOM_HID_Setup * Handle the CUSTOM_HID specific requests * @param pdev: instance * @param req: usb requests * @retval status */ static uint8_t USBD_CUSTOM_HID_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { uint16_t len = 0; uint8_t *pbuf = NULL; USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : switch (req->bRequest) { case CUSTOM_HID_REQ_SET_PROTOCOL: hhid->Protocol = (uint8_t)(req->wValue); break; case CUSTOM_HID_REQ_GET_PROTOCOL: USBD_CtlSendData (pdev, (uint8_t *)&hhid->Protocol, 1); break; case CUSTOM_HID_REQ_SET_IDLE: hhid->IdleState = (uint8_t)(req->wValue >> 8); break; case CUSTOM_HID_REQ_GET_IDLE: USBD_CtlSendData (pdev, (uint8_t *)&hhid->IdleState, 1); break; case CUSTOM_HID_REQ_SET_REPORT: hhid->IsReportAvailable = 1; USBD_CtlPrepareRx (pdev, hhid->Report_buf, (uint8_t)(req->wLength)); break; default: USBD_CtlError (pdev, req); return USBD_FAIL; } break; case USB_REQ_TYPE_STANDARD: switch (req->bRequest) { case USB_REQ_GET_DESCRIPTOR: if( req->wValue >> 8 == CUSTOM_HID_REPORT_DESC) { len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE , req->wLength); pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->pReport; } else if( req->wValue >> 8 == CUSTOM_HID_DESCRIPTOR_TYPE) { pbuf = USBD_CUSTOM_HID_Desc; len = MIN(USB_CUSTOM_HID_DESC_SIZ , req->wLength); } USBD_CtlSendData (pdev, pbuf, len); break; case USB_REQ_GET_INTERFACE : USBD_CtlSendData (pdev, (uint8_t *)&hhid->AltSetting, 1); break; case USB_REQ_SET_INTERFACE : hhid->AltSetting = (uint8_t)(req->wValue); break; } }
/** * @brief USBD_HID_Setup * Handle the HID specific requests * @param pdev: instance * @param req: usb requests * @retval status */ uint8_t USBD_HID_Setup (void *pdev, USB_SETUP_REQ *req) { uint8_t USBD_HID_Report_LENGTH=0; uint16_t len = 0; uint8_t *pbuf = NULL; switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : switch (req->bRequest) { case HID_REQ_SET_PROTOCOL: USBD_HID_Protocol = (uint8_t)(req->wValue); break; case HID_REQ_GET_PROTOCOL: USBD_CtlSendData (pdev, (uint8_t *)&USBD_HID_Protocol, 1); break; case HID_REQ_SET_IDLE: USBD_HID_IdleState = (uint8_t)(req->wValue >> 8); break; case HID_REQ_GET_IDLE: USBD_CtlSendData (pdev, (uint8_t *)&USBD_HID_IdleState, 1); break; case HID_REQ_SET_REPORT: flag = 1; USBD_HID_Report_ID = (uint8_t)(req->wValue); USBD_HID_Report_LENGTH = (uint8_t)(req->wLength); USBD_CtlPrepareRx (pdev, Report_buf, USBD_HID_Report_LENGTH); break; default: USBD_CtlError (pdev, req); return USBD_FAIL; } break; case USB_REQ_TYPE_STANDARD: switch (req->bRequest) { case USB_REQ_GET_DESCRIPTOR: if( req->wValue >> 8 == HID_REPORT_DESC) { len = MIN(CUSTOMHID_SIZ_REPORT_DESC , req->wLength); pbuf = (uint8_t*)CustomHID_ReportDescriptor; } else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE) { pbuf = (uint8_t*)USBD_HID_CfgDesc + 0x12; len = MIN(USB_HID_DESC_SIZ , req->wLength); } USBD_CtlSendData (pdev, pbuf, len); break; case USB_REQ_GET_INTERFACE : USBD_CtlSendData (pdev, (uint8_t *)&USBD_HID_AltSet, 1); break; case USB_REQ_SET_INTERFACE : USBD_HID_AltSet = (uint8_t)(req->wValue); break; } }
/** * @brief usbd_cdc_Setup * Handle the CDC specific requests * @param pdev: instance * @param req: usb requests * @retval status */ static uint8_t usbd_cdc_Setup (void *pdev, USB_SETUP_REQ *req) { uint16_t len = 0; uint8_t *pbuf; switch (req->bmRequest & USB_REQ_TYPE_MASK) { /* CDC Class Requests -------------------------------*/ case USB_REQ_TYPE_CLASS : /* 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); } return USBD_OK; default: USBD_CtlError (pdev, req); return USBD_FAIL; /* 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_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM); #endif len = MIN(USB_CDC_DESC_SIZ , req->wLength); } USBD_CtlSendData (pdev, pbuf, len); break; case USB_REQ_GET_INTERFACE : USBD_CtlSendData (pdev, (uint8_t *)&usbd_cdc_AltSet, 1); break; case USB_REQ_SET_INTERFACE : 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); } break; } } return USBD_OK; }
uint8_t USBD_Dev_DS3_Setup (void *pcore , USB_SETUP_REQ *req) { dbgwdg_feed(); uint16_t len = 0; uint8_t *pbuf = NULL; // PS3 does a lot of USB_REQ_RECIPIENT_INTERFACE requests // code takes hints from gimx.fr if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE && (req->bmRequest & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_CLASS && (req->bmRequest & 0x80) == 0x80 && req->bRequest == 0x01 && req->wIndex == 0) { if (req->wValue == 0x0301) { USBD_CtlSendData (pcore, (uint8_t *)ds3_buf301, req->wLength); } else if (req->wValue == 0x03F2) { USBD_CtlSendData (pcore, (uint8_t *)ds3_buf3f2, req->wLength); } else if (req->wValue == 0x03F5) { memcpy(USBD_Dev_DS_bufTemp, ds3_buf3f5, req->wLength); if (USBD_Dev_DS3_buf3f5HasRead == 0) { USBD_Dev_DS3_buf3f5HasRead = 1; } else { memcpy(&(USBD_Dev_DS_bufTemp[2]), USBD_Dev_DS_masterBdaddr, 6); } USBD_CtlSendData (pcore, (uint8_t *)USBD_Dev_DS_bufTemp, req->wLength); } else if (req->wValue == 0x03EF) { memcpy(USBD_Dev_DS_bufTemp, ds3_buf3ef, req->wLength); USBD_Dev_DS_bufTemp[7] = USBD_Dev_DS3_3efByte6; USBD_CtlSendData (pcore, (uint8_t *)USBD_Dev_DS_bufTemp, req->wLength); } else if (req->wValue == 0x03F8) { memcpy(USBD_Dev_DS_bufTemp, ds3_buf3f8, req->wLength); USBD_Dev_DS_bufTemp[7] = USBD_Dev_DS3_3efByte6; // not known if required USBD_CtlSendData (pcore, (uint8_t *)USBD_Dev_DS_bufTemp, req->wLength); } else if (req->wValue == 0x03F7) { USBD_CtlSendData (pcore, (uint8_t *)ds3_buf3f7, req->wLength); } else { // should never reach here memset(USBD_Dev_DS_bufTemp, 0, 0x40); USBD_CtlSendData (pcore, (uint8_t *)USBD_Dev_DS_bufTemp, req->wLength); dbg_printf(DBGMODE_ERR, "Request with unknown wValue (0x%04X) from PS3\r\n", req->wValue); } return USBD_OK; } if ((req->bmRequest & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_INTERFACE && (req->bmRequest & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_CLASS && (req->bmRequest & 0x80) == 0x00 && req->bRequest == HID_REQ_SET_REPORT && req->wIndex == 0) { if (req->wValue == 0x03F5 || req->wValue == 0x03EF || req->wValue == 0x03F2 || req->wValue == 0x03F4) { USBD_Dev_DS_lastWValue = req->wValue; USBD_CtlPrepareRx (pcore, (uint8_t *)USBD_Dev_DS_bufTemp, req->wLength); return USBD_OK; } } if (req->bmRequest == 0x21 && req->bRequest == HID_REQ_SET_IDLE && req->wIndex == 0) { USBD_HID_IdleState = (uint8_t)(req->wValue >> 8); USBD_Dev_DS_lastWValue = req->wValue; USBD_CtlPrepareRx (pcore, (uint8_t *)USBD_Dev_DS_bufTemp, req->wLength); return USBD_OK; }