/***************************************************************************//**
 * @brief       Processes Standard Request (Chapter 9 Command)
 * @return      Status of request (type @ref USB_Status_TypeDef)
 * @note        This function takes no parameters, but it uses the setup command
 *              stored in @ref myUsbDevice.setup.
 ******************************************************************************/
USB_Status_TypeDef USBDCH9_SetupCmd(void)
{
  USB_Status_TypeDef status = USB_STATUS_OK;

  switch (myUsbDevice.setup.bRequest)
  {
    case GET_STATUS:
      status = GetStatus();
      break;

    case CLEAR_FEATURE:
      status = ClearFeature();
      break;

    case SET_FEATURE:
      status = SetFeature();
      break;

    case SET_ADDRESS:
      status = SetAddress();
      break;

    case GET_DESCRIPTOR:
      status = GetDescriptor();
      break;

    case GET_CONFIGURATION:
      status = GetConfiguration();
      break;

    case SET_CONFIGURATION:
      status = SetConfiguration();
      break;

    case GET_INTERFACE:
      status = GetInterface();
      break;

    case SET_INTERFACE:
      status = SetInterface();
      break;

//    case GET_MS_DESCRIPTOR:
//    	status = HandleMsRequest();
//    	break;

    default:
      status = USB_STATUS_REQ_ERR;
      break;
  }

  // Reset index to 0 in case one of the above commands modified it
  USB_SetIndex(0);

  // If the command resulted in an error, send a procedural stall
  if (status == USB_STATUS_REQ_ERR)
  {
    SendEp0Stall();
  }

  return status;
}
Esempio n. 2
0
/***************************************************************************//**
 * @brief       Handles Endpoint 0 transfer interrupt
 ******************************************************************************/
static void handleUsbEp0Int(void)
{
  USB_SetIndex(0);

  if (USB_Ep0SentStall() || USB_GetSetupEnd())
  {
    USB_Ep0ClearSentStall();
    USB_ServicedSetupEnd();
    myUsbDevice.ep0.state = D_EP_IDLE;
    myUsbDevice.ep0.misc.c = 0;
  }
  if (USB_Ep0OutPacketReady())
  {
    if (myUsbDevice.ep0.misc.bits.waitForRead == true)
    {
      myUsbDevice.ep0.misc.bits.outPacketPending = true;
    }
    else if (myUsbDevice.ep0.state == D_EP_IDLE)
    {
      myUsbDevice.ep0String.c = USB_STRING_DESCRIPTOR_UTF16LE;
      USB_ReadFIFOSetup();

      // Vendor unique, Class or Standard setup commands override?
#if SLAB_USB_SETUP_CMD_CB
      if (USBD_SetupCmdCb(&myUsbDevice.setup) == USB_STATUS_REQ_UNHANDLED)
      {
#endif
      if (myUsbDevice.setup.bmRequestType.Type == USB_SETUP_TYPE_STANDARD)
      {
        USBDCH9_SetupCmd();
      }
      else
      {
        SendEp0Stall();
      }
#if SLAB_USB_SETUP_CMD_CB
    }
    else
    {
      // If in-packet but callback didn't setup a USBD_Read and we are expecting a data byte then
      // we need to wait for the read to be setup and nack packets till USBD_Read is called.
      if ((myUsbDevice.setup.bmRequestType.Direction == USB_SETUP_DIR_OUT)
          && (myUsbDevice.ep0.state != D_EP_RECEIVING)
          && (myUsbDevice.setup.wLength)
          )
      {
        myUsbDevice.ep0.misc.bits.waitForRead = true;
      }
    }
#endif
    }
    else if (myUsbDevice.ep0.state == D_EP_RECEIVING)
    {
      handleUsbEp0Rx();
    }
    else
    {
      myUsbDevice.ep0.misc.bits.outPacketPending = true;
    }
  }
  if ((myUsbDevice.ep0.state == D_EP_TRANSMITTING) && (USB_Ep0InPacketReady() == 0))
  {
    handleUsbEp0Tx();
  }
}