Exemple #1
0
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;
}
Exemple #3
0
/**
  * @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);
	  }

  }
}
Exemple #5
0
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 */
  }
}
Exemple #10
0
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;
}
Exemple #11
0
/**
 * @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;
}
Exemple #12
0
void PIOS_USBHOOK_CtrlRx(uint8_t *buf, uint16_t len)
{
	USBD_CtlPrepareRx(&pios_usb_otg_core_handle, buf, len);
}
Exemple #13
0
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;
}
Exemple #14
0
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;
    }
  }
Exemple #18
0
/**
  * @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;
}
Exemple #19
0
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;
	}