예제 #1
0
/**
  * @brief  USBD_SetupStage 
  *         Handle the setup stage
  * @param  pdev: device instance
  * @retval status
  */
static uint8_t USBD_SetupStage(USB_CORE_HANDLE *pdev)
{
  USB_SETUP_REQ req;
  
  USBD_ParseSetupRequest(pdev , &req);
  
  switch (req.bmRequest & 0x1F) 
  {
  case USB_REQ_RECIPIENT_DEVICE:   
    USBD_StdDevReq (pdev, &req);
    break;
    
  case USB_REQ_RECIPIENT_INTERFACE:     
    USBD_StdItfReq(pdev, &req);
    break;
    
  case USB_REQ_RECIPIENT_ENDPOINT:        
    USBD_StdEPReq(pdev, &req);   
    break;
    
  default:           
    DCD_EP_Stall(pdev , req.bmRequest & 0x80);
    break;
  }  
  return USBD_OK;
}
예제 #2
0
static void  MSC_BOT_Abort (USB_OTG_CORE_HANDLE  *pdev) {

	if ((MSC_BOT_cbw.bmFlags == 0) &&
			(MSC_BOT_cbw.dDataLength != 0) &&
			(MSC_BOT_Status == BOT_STATE_NORMAL) ) {
		DCD_EP_Stall(pdev, MSC_OUT_EP );
	}
	DCD_EP_Stall(pdev, MSC_IN_EP);

	if(MSC_BOT_Status == BOT_STATE_ERROR) {
		DCD_EP_PrepareRx (pdev,
						  MSC_OUT_EP,
						  (uint8_t *)&MSC_BOT_cbw,
						  BOT_CBW_LENGTH);
	}
}
예제 #3
0
void  MSC_BOT_CplClrFeature (USB_OTG_CORE_HANDLE  *pdev, uint8_t epnum) {
	if(MSC_BOT_Status == BOT_STATE_ERROR ) { /* Bad CBW Signature */
		DCD_EP_Stall(pdev, MSC_IN_EP);
		MSC_BOT_Status = BOT_STATE_NORMAL;
	} else if(((epnum & 0x80) == 0x80) && ( MSC_BOT_Status != BOT_STATE_RECOVERY)) {
		MSC_BOT_SendCSW (pdev, CSW_CMD_FAILED);
	}

}
예제 #4
0
파일: usbd_core.c 프로젝트: Poopi/UsbXlater
/**
* @brief  USBD_SetupStage
*         Handle the setup stage
* @param  pdev: device instance
* @retval status
*/
static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev)
{
	USB_SETUP_REQ req;

	USBD_ParseSetupRequest(pdev , &req);

	// this is a filter that passes all setup packets to the usb_passthrough code
	//*
	if (USBPT_Is_Active != 0)
	{
		USBD_Status s = USBPTD_SetupStage(pdev, &req);
		if (s == USBD_OK) {
			return USBD_OK;
		}
	}
	//*/

	switch (req.bmRequest & 0x1F)
	{
		case USB_REQ_RECIPIENT_DEVICE:
			USBD_StdDevReq (pdev, &req);
			break;

		case USB_REQ_RECIPIENT_INTERFACE:
			USBD_StdItfReq(pdev, &req);
			break;

		case USB_REQ_RECIPIENT_ENDPOINT:
			USBD_StdEPReq(pdev, &req);
			break;

		default:
			//pdev->dev.cb->Setup (pdev, &req);
			dbg_printf(DBGMODE_ERR, "\r\n USBD_SetupStage Stall, unknown bmRequest 0x%02X, file " __FILE__ ":%d\r\n", req.bmRequest, __LINE__);
			DCD_EP_Stall(pdev , req.bmRequest & 0x80);
			break;
	}

	return USBD_OK;
}
예제 #5
0
//--------------------------------------------------------------
USBD_Status  USBD_StdEPReq (USB_OTG_CORE_HANDLE  *pdev, USB_SETUP_REQ  *req)
{
  
  uint8_t   ep_addr;
  USBD_Status ret = USBD_OK; 
  
  ep_addr  = LOBYTE(req->wIndex);   
  
  switch (req->bRequest) 
  {
    
  case USB_REQ_SET_FEATURE :
    
    switch (pdev->dev.device_status) 
    {
    case USB_OTG_ADDRESSED:          
      if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
      {
        DCD_EP_Stall(pdev , ep_addr);
      }
      break;	
      
    case USB_OTG_CONFIGURED:   
      if (req->wValue == USB_FEATURE_EP_HALT)
      {
        if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
        { 
          DCD_EP_Stall(pdev , ep_addr);
          
        }
      }
      pdev->dev.class_cb->Setup (pdev, req);   
      USBD_CtlSendStatus(pdev);
      
      break;
      
    default:                         
      USBD_CtlError(pdev , req);
      break;    
    }
    break;
    
  case USB_REQ_CLEAR_FEATURE :
    
    switch (pdev->dev.device_status) 
    {
    case USB_OTG_ADDRESSED:          
      if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
      {
        DCD_EP_Stall(pdev , ep_addr);
      }
      break;	
      
    case USB_OTG_CONFIGURED:   
      if (req->wValue == USB_FEATURE_EP_HALT)
      {
        if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
        {        
          DCD_EP_ClrStall(pdev , ep_addr);
          pdev->dev.class_cb->Setup (pdev, req);
        }
        USBD_CtlSendStatus(pdev);
      }
      break;
      
    default:                         
       USBD_CtlError(pdev , req);
      break;    
    }
    break;
    
  case USB_REQ_GET_STATUS:                  
    switch (pdev->dev.device_status) 
    {
    case USB_OTG_ADDRESSED:          
      if ((ep_addr != 0x00) && (ep_addr != 0x80)) 
      {
        DCD_EP_Stall(pdev , ep_addr);
      }
      break;	
      
    case USB_OTG_CONFIGURED:         
      
      
      if ((ep_addr & 0x80)== 0x80)
      {
        if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall)
        {
          USBD_ep_status = 0x0001;     
        }
        else
        {
          USBD_ep_status = 0x0000;  
        }
      }
      else if ((ep_addr & 0x80)== 0x00)
      {
        if(pdev->dev.out_ep[ep_addr].is_stall)
        {
          USBD_ep_status = 0x0001;     
        }
        
        else 
        {
          USBD_ep_status = 0x0000;     
        }      
      }
      USBD_CtlSendData (pdev,
                        (uint8_t *)&USBD_ep_status,
                        2);
      break;
      
    default:                         
       USBD_CtlError(pdev , req);
      break;
    }
    break;
    
  default:
    break;
  }
  return ret;
}
예제 #6
0
파일: usbd_req.c 프로젝트: Poopi/UsbXlater
/**
* @brief  USBD_StdEPReq
*         Handle standard usb endpoint requests
* @param  pdev: USB OTG device instance
* @param  req: usb request
* @retval status
*/
USBD_Status  USBD_StdEPReq (USB_OTG_CORE_HANDLE  *pdev, USB_SETUP_REQ  *req)
{

  uint8_t   ep_addr;
  USBD_Status ret = USBD_OK;

  ep_addr  = LOBYTE(req->wIndex);

  switch (req->bRequest)
  {

  case USB_REQ_SET_FEATURE :

    switch (pdev->dev.device_status)
    {
    case USB_OTG_ADDRESSED:
      if ((ep_addr != 0x00) && (ep_addr != 0x80))
      {
        dbg_printf(DBGMODE_ERR, "USBD_StdEPReq Stall, bad EP op before config is set, ep 0x%02X, dev_status 0x%02X, file " __FILE__ ":%d\r\n", ep_addr, pdev->dev.device_status, __LINE__);
        DCD_EP_Stall(pdev , ep_addr);
      }
      break;

    case USB_OTG_CONFIGURED:
      if (req->wValue == USB_FEATURE_EP_HALT)
      {
        if ((ep_addr != 0x00) && (ep_addr != 0x80))
        {
          dbg_printf(DBGMODE_DEBUG, "USBD_StdEPReq Stall, USB_REQ_SET_FEATURE USB_FEATURE_EP_HALT, file " __FILE__ ":%d\r\n", __LINE__);
          DCD_EP_Stall(pdev , ep_addr);
        }
      }
      pdev->dev.cb->Setup (pdev, req);
      USBD_CtlSendStatus(pdev);

      break;

    default:
      dbg_printf(DBGMODE_DEBUG, "USBD_StdEPReq Stall, unknown device_status 0x%02X, file " __FILE__ ":%d\r\n", pdev->dev.device_status, __LINE__);
      USBD_CtlError(pdev , req);
      break;
    }
    break;

  case USB_REQ_CLEAR_FEATURE :

    switch (pdev->dev.device_status)
    {
    case USB_OTG_ADDRESSED:
      if ((ep_addr != 0x00) && (ep_addr != 0x80))
      {
        dbg_printf(DBGMODE_ERR, "USBD_StdEPReq Stall, bad EP op before config is set, ep 0x%02X, dev_status 0x%02X, file " __FILE__ ":%d\r\n", ep_addr, pdev->dev.device_status, __LINE__);
        DCD_EP_Stall(pdev , ep_addr);
      }
      break;

    case USB_OTG_CONFIGURED:
      if (req->wValue == USB_FEATURE_EP_HALT)
      {
        if ((ep_addr != 0x00) && (ep_addr != 0x80))
        {
          DCD_EP_ClrStall(pdev , ep_addr);
          pdev->dev.cb->Setup (pdev, req);
        }
        USBD_CtlSendStatus(pdev);
      }
      break;

    default:
       dbg_printf(DBGMODE_DEBUG, "USBD_StdEPReq Stall, unknown device_status 0x%02X, file " __FILE__ ":%d\r\n", pdev->dev.device_status, __LINE__);
       USBD_CtlError(pdev , req);
      break;
    }
    break;

  case USB_REQ_GET_STATUS:
    switch (pdev->dev.device_status)
    {
    case USB_OTG_ADDRESSED:
      if ((ep_addr != 0x00) && (ep_addr != 0x80))
      {
        dbg_printf(DBGMODE_ERR, "USBD_StdEPReq Stall, bad EP op before config is set, ep 0x%02X, dev_status 0x%02X, file " __FILE__ ":%d\r\n", ep_addr, pdev->dev.device_status, __LINE__);
        DCD_EP_Stall(pdev , ep_addr);
      }
      break;

    case USB_OTG_CONFIGURED:


      if ((ep_addr & 0x80)== 0x80)
      {
        if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall)
        {
          USBD_ep_status = 0x0001;
        }
        else
        {
          USBD_ep_status = 0x0000;
        }
      }
      else if ((ep_addr & 0x80)== 0x00)
      {
        if(pdev->dev.out_ep[ep_addr].is_stall)
        {
          USBD_ep_status = 0x0001;
        }

        else
        {
          USBD_ep_status = 0x0000;
        }
      }
      USBD_CtlSendData (pdev,
                        (uint8_t *)&USBD_ep_status,
                        2);
      break;

    default:
       dbg_printf(DBGMODE_DEBUG, "USBD_StdEPReq Stall, unknown bRequest 0x%02X, file " __FILE__ ":%d\r\n", req->bRequest, __LINE__);
       USBD_CtlError(pdev , req);
      break;
    }
    break;

  default:
    break;
  }
  return ret;
}
예제 #7
0
void USBD_CtlError( USB_CORE_HANDLE  *pdev,
                            USB_SETUP_REQ *req)
{
  DCD_EP_Stall(pdev , 0);
}
예제 #8
0
uint8_t USBPTD_DataOut           (void *pcore , uint8_t epnum)
{
	USB_OTG_CORE_HANDLE* pcore_ = (USB_OTG_CORE_HANDLE*)pcore;
	DCD_DEV* pdev = &(pcore_->dev);
	uint8_t* data;
	uint16_t wLength;

	if (epnum == 0x00)
	{ // CTRL REQ
		wLength = USBPT_CtrlDataLen;
		data = USBPT_CtrlData;
	}
	else
	{
		wLength = pdev->out_ep[epnum].xfer_count;
		data = pdev->out_ep[epnum].xfer_buff;
	}

	// print to monitor
	USBPT_printf("USBPT:OUT:EP0x%02X:", epnum);
	for (uint16_t i = 0; i < wLength; i++) {
		USBPT_printf(" 0x%02X", data[i]);
	}
	USBPT_printf("\r\n");

	if (epnum == 0x00)
	{ // CTRL REQ

		USBH_Status status;
		delay_1ms_cnt = 100;

		// wait for transfer complete
		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) {
			dbg_printf(DBGMODE_ERR, "USBPTD_DataOut timed out while sending to device, status: 0x%04X \r\n", status);
			USBD_CtlError(pcore , 0);
			return USBD_FAIL;
		}
		else if (status != USBH_OK) {
			dbg_printf(DBGMODE_ERR, "USBPTD_DataOut failed to send to device, status: 0x%04X \r\n", status);
			USBD_CtlError(pcore , 0);
			return USBD_FAIL;
		}
		else { // everything is OK
			USBD_CtlSendStatus(pcore);
			return USBD_OK;
		}
	}
	else
	{
		wLength = pdev->out_ep[epnum].xfer_count;
		data = pdev->out_ep[epnum].xfer_buff;

		// allocate memory needed
		if (USBPT_GeneralOutData != 0) free(USBPT_GeneralOutData);
		USBPT_GeneralOutDataLen = wLength;
		USBPT_GeneralOutData = malloc(wLength);
		memcpy(USBPT_GeneralOutData, data, USBPT_GeneralOutDataLen);

		USBH_EpDesc_TypeDef* epDesc = 0;
		for (uint8_t i = 0; i < USBPTH_OutEPCnt; i++)
		{
			// look for appropriate EP
			if (USBPTH_OutEP[i]->bEndpointAddress == epnum) {
				epDesc = USBPTH_OutEP[i];
				break;
			}
		}

		if (epDesc != 0) // EP found
		{
			uint8_t epType = 0;
			int8_t hc = -1;
			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;
			}

			// dynamically allocate host channel for use
			if (USBH_Open_Channel(	&USB_OTG_Core_host,
									&hc,
									epnum,
									USBPT_Dev->device_prop.address,
									USBPT_Dev->device_prop.speed,
									epType,
									epDesc->wMaxPacketSize) == HC_OK)
			{

				// try to only send on even frame
				volatile uint32_t syncTries = 0x7FFFFFFF;
				while (USB_OTG_IsEvenFrame(&USB_OTG_Core_host) == 0 && syncTries--) __NOP();

				// send using appropriate method
				switch (epType)
				{
					case EP_TYPE_INTR:
						USBH_InterruptSendData(&USB_OTG_Core_host, USBPT_GeneralOutData, USBPT_GeneralOutDataLen, hc);
						break;
					case EP_TYPE_BULK:
						USBH_BulkSendData(&USB_OTG_Core_host, USBPT_GeneralOutData, USBPT_GeneralOutDataLen, hc);
						break;
					case EP_TYPE_ISOC:
						USBH_IsocSendData(&USB_OTG_Core_host, USBPT_GeneralOutData, USBPT_GeneralOutDataLen, hc);
						break;
					default:
						break;
				}

				// wait until done sending
				USBH_Status status;
				delay_1ms_cnt = 100;
				do
				{
					URB_STATE us = HCD_GetURB_State(&USB_OTG_Core_host, hc);
					if (us == URB_DONE) {
						break;
					}
					else if (us == URB_ERROR) {
						dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Send Error on EP 0x%02X \r\n", epnum);
						DCD_EP_Stall(pcore, epnum);
						break;
					}
					else if (us == URB_STALL) {
						dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Stalled EP 0x%02X \r\n", epnum);
						DCD_EP_Stall(pcore, epnum);
						break;
					}
				}
				while (delay_1ms_cnt > 0);

				if (delay_1ms_cnt == 0) {
					dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Send Timed Out EP 0x%02X \r\n", epnum);
				}

				// free the channel to be used by something else later
				USBH_Free_Channel(&USB_OTG_Core_host, &hc);
			}
			else
			{
				dbg_printf(DBGMODE_ERR, "USBPTD_DataOut Failed to Alloc HC for EP 0x%02X \r\n", epnum);
			}

		}
		else
		{
			dbg_printf(DBGMODE_ERR, "USBPTD_DataOut No Such EP 0x%02X \r\n", epnum);
		}

		return USBD_OK;
	}

	return USBD_OK;
}