void    mvUsbCh9GetStatus(_usb_device_handle handle, boolean setup,
                         SETUP_STRUCT* ctrl_req)
{ /* Body */
    uint_8                  endpoint, direction;
    uint_16                 usb_status;
    USB_DEV_STATE_STRUCT*   usb_dev_ptr = (USB_DEV_STATE_STRUCT*)handle;

    ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_SETUP, "%s: setup=%d\n", __FUNCTION__, (int)setup);

    if(!setup)
        return;

    switch (ctrl_req->REQUESTTYPE)
    {
       case (REQ_DIR_IN | REQ_RECIP_DEVICE):
          /* Device request */
          _usb_device_get_status(handle, ARC_USB_STATUS_DEVICE, &usb_status);
          break;

       case (REQ_DIR_IN | REQ_RECIP_INTERFACE):
          /* Interface request */
          _usb_device_get_status(handle, ARC_USB_STATUS_INTERFACE, &usb_status);
          break;

       case (REQ_DIR_IN | REQ_RECIP_ENDPOINT):
          /* Endpoint request */
          endpoint = ctrl_req->INDEX & ARC_USB_STATUS_ENDPOINT_NUMBER_MASK;
          if( (ctrl_req->INDEX & (1 << REQ_DIR_OFFSET)) == REQ_DIR_IN)
            direction = ARC_USB_SEND;
          else
            direction = ARC_USB_RECV;

          usb_status = _usb_device_is_endpoint_stalled(handle, endpoint, direction);
          break;

       default:
          /* Unknown request */
           USB_printf("GetStatus: Unknown request type 0x%x\n", ctrl_req->REQUESTTYPE);
          _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
          return;
    } /* Endswitch */

    /* Send the requested data */
    *usb_dev_ptr->STATUS_PTR = USB_16BIT_LE(usb_status);
    _usb_device_send_data(handle, 0, (uint_8_ptr)usb_dev_ptr->STATUS_PTR, sizeof(uint_16));

    /* status phase */
    _usb_device_recv_data(handle, 0, NULL, 0);

    return;
} /* Endbody */
示例#2
0
/**************************************************************************//*!
 *
 * @name  _usb_device_set_status
 *
 * @brief The function saves status of endpoints as well as USB components.
 *
 * @param handle    : USB Device handle
 * @param component : USB component
 * @param setting   : Value to be set
 *
 * @return status
 *         USB_OK                : When Successfull
 *         USBERR_BAD_STATUS     : When error
 *
 ******************************************************************************
 * This function sets the endpoint as well USB component status which can be
 * retrieved by calling _usb_device_get_status. This function can be called by
 * Application as well as the DCI layer.
 *****************************************************************************/
uint_8 _usb_device_set_status(
    _usb_device_handle    handle,       /* [IN] USB Device handle */
    uint_8                component,    /* [IN] USB Component status to set */
    uint_8                setting       /* [IN] Status to set */
)
{
    /* get the endpoint number from component input variable */
    uint_8 ep_num = (uint_8)(component & USB_STATUS_ENDPOINT_NUMBER_MASK);
    UNUSED (handle)

    if((component <= USB_STATUS_TEST_MODE) &&
        (component >= USB_STATUS_DEVICE_STATE))
    {
        /*
           Set the corresponding component setting
           -1 as components start from 1
        */
        g_usb_component_status[component-1] = setting;
    }
    else if ((component & USB_STATUS_ENDPOINT) &&
        (ep_num < MAX_SUPPORTED_ENDPOINTS))
    {
        uint_8 direction =
            (uint_8)((component >> USB_COMPONENT_DIRECTION_SHIFT) &
            USB_COMPONENT_DIRECTION_MASK);
        /* HALT Endpoint */
        if(setting == USB_STATUS_STALLED)
        {
        	_usb_device_stall_endpoint(handle, ep_num, direction);
        }
        else if((setting == USB_STATUS_IDLE) &&
            (g_usb_ep_status[ep_num] == USB_STATUS_STALLED))
        {
        	_usb_device_unstall_endpoint(handle, ep_num, direction);

            if(ep_num == CONTROL_ENDPOINT)
            {
                direction = (uint_8)((direction == USB_SEND)?
                    (USB_RECV):(USB_SEND));
                _usb_device_unstall_endpoint(handle, ep_num, direction);
            }
        }
        /* Set the corresponding endpoint setting */
        g_usb_ep_status[ep_num] = setting;
    }
void    mvUsbCh9ClearFeature(_usb_device_handle handle, boolean setup,
                            SETUP_STRUCT* setup_ptr)
{ /* Body */
    uint_8   endpoint, direction;
    uint_16  usb_status;

    ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_SETUP, "%s: setup=%d\n", __FUNCTION__, (int)setup);

    _usb_device_get_status(handle, ARC_USB_STATUS_DEVICE_STATE, &usb_status);
    if ((usb_status != ARC_USB_STATE_CONFIG) && (usb_status != ARC_USB_STATE_ADDRESS))
    {
        USB_printf("ClearFeature: Wrong USB state %d\n", usb_status);
        _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
        return;
    } /* Endif */

    if(!setup)
        return;

    switch (setup_ptr->REQUESTTYPE)
    {
        case (REQ_DIR_OUT | REQ_RECIP_DEVICE):
            /* DEVICE */
            switch(setup_ptr->VALUE)
            {
                case DEVICE_REMOTE_WAKEUP:
                    /* clear remote wakeup */
                    _usb_device_get_status(handle, ARC_USB_STATUS_DEVICE, &usb_status);
                    usb_status &= ~ARC_USB_REMOTE_WAKEUP;
                    _usb_device_set_status(handle, ARC_USB_STATUS_DEVICE, usb_status);
                    USB_printf("Clear REMOTE_WAKEUP feature\n");
                    break;

                case DEVICE_TEST_MODE:
                    /* Exit Test Mode */
                    _usb_device_set_status(handle, ARC_USB_STATUS_TEST_MODE, 0);
                    break;

                default:
                    USB_printf("ClearFeature: Unknown Device feature %d\n",
                                setup_ptr->VALUE);
                    _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                    return;
            } /* Endif */
            break;

        case (REQ_DIR_OUT | REQ_RECIP_ENDPOINT):
            /* ENDPOINT */
            if (setup_ptr->VALUE != ENDPOINT_HALT)
            {
                USB_printf("ClearFeature: Wrong Endpoint feature %d\n",
                            setup_ptr->VALUE);
                _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                return;
            } /* Endif */

            endpoint = setup_ptr->INDEX & ARC_USB_STATUS_ENDPOINT_NUMBER_MASK;
            if( (setup_ptr->INDEX & (1 << REQ_DIR_OFFSET)) == REQ_DIR_IN)
                direction = ARC_USB_SEND;
            else
                direction = ARC_USB_RECV;

            _usb_device_unstall_endpoint(handle, endpoint, direction);
            break;

        default:
            USB_printf("ClearFeature: Unknown REQUEST_TYPE %d\n",
                                setup_ptr->REQUESTTYPE);

            _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
            return;
    } /* Endswitch */

    /* status phase */
    _usb_device_send_data(handle, 0, 0, 0);
}
void    mvUsbCh9SetFeature(_usb_device_handle handle, boolean setup,
                          SETUP_STRUCT* setup_ptr)
{
   uint_16                  usb_status;
   uint_8                   endpoint, direction;
   USB_DEV_STATE_STRUCT*    usb_dev_ptr = (USB_DEV_STATE_STRUCT*)handle;

   ARC_DEBUG_TRACE(ARC_DEBUG_FLAG_SETUP, "%s: setup=%d\n", __FUNCTION__, (int)setup);

   if (setup)
   {
      switch (setup_ptr->REQUESTTYPE)
      {
         case (REQ_DIR_OUT | REQ_RECIP_DEVICE):
            /* DEVICE */
            switch (setup_ptr->VALUE)
            {
               case DEVICE_REMOTE_WAKEUP:
                  /* set remote wakeup */
                  _usb_device_get_status(handle, ARC_USB_STATUS_DEVICE, &usb_status);
                  usb_status |= ARC_USB_REMOTE_WAKEUP;
                  _usb_device_set_status(handle, ARC_USB_STATUS_DEVICE, usb_status);
                  USB_printf("Set REMOTE_WAKEUP feature\n");
                  break;

               case DEVICE_TEST_MODE:
                  /* Test Mode */
                  if( (setup_ptr->INDEX & 0x00FF) || (usb_dev_ptr->SPEED != ARC_USB_SPEED_HIGH) )
                  {
                     USB_printf("SetFeature: Wrong Test mode parameters: mode=%d, speed=%d\n",
                                (setup_ptr->INDEX & 0x00FF), usb_dev_ptr->SPEED);
                     _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                     return;
                  } /* Endif */

                  _usb_device_get_status(handle, ARC_USB_STATUS_DEVICE_STATE, &usb_status);
                  if( (usb_status == ARC_USB_STATE_CONFIG)  ||
                      (usb_status == ARC_USB_STATE_ADDRESS) ||
                      (usb_status == ARC_USB_STATE_DEFAULT))
                  {
                      /* wait with Set Test mode */
                      ENTER_TEST_MODE = TRUE;
                      test_mode_index = (setup_ptr->INDEX & 0xFF00);
                      USB_printf("SetFeature: Prepare for Test mode 0x%x\n", test_mode_index);
                  }
                  else
                  {
                     USB_printf("SetFeature: Wrong USB state for Test mode: state=%d\n",
                                usb_status);
                     _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                     return;
                  } /* Endif */
                  break;

               default:
                    USB_printf("SetFeature: Unknown Device feature %d\n",
                                setup_ptr->VALUE);
                  _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                  return;
            } /* Endswitch */
            break;

         case (REQ_DIR_OUT | REQ_RECIP_ENDPOINT):
            /* ENDPOINT */
            if (setup_ptr->VALUE != ENDPOINT_HALT)
            {
                USB_printf("SetFeature: Unknown Endpoint feature %d\n",
                            setup_ptr->VALUE);
                _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
                return;
            } /* Endif */

            endpoint = setup_ptr->INDEX & ARC_USB_STATUS_ENDPOINT_NUMBER_MASK;
            if( (setup_ptr->INDEX & (1 << REQ_DIR_OFFSET)) == REQ_DIR_IN)
                direction = ARC_USB_SEND;
            else
                direction = ARC_USB_RECV;

            _usb_device_stall_endpoint(handle, endpoint, direction);
            break;

         default:
            USB_printf("SetFeature: Unknown REQUEST_TYPE %d\n",
                       setup_ptr->REQUESTTYPE);

            _usb_device_stall_endpoint(handle, 0, ARC_USB_RECV);
            return;
      } /* Endswitch */

      /* status phase */
      _usb_device_send_data(handle, 0, 0, 0);
   }
   else
   {
      if (ENTER_TEST_MODE)
      {
         /* Enter Test Mode */
          USB_printf("SetFeature: Activate Test mode 0x%x\n", test_mode_index);
         _usb_device_set_status(handle, ARC_USB_STATUS_TEST_MODE, test_mode_index);
      } /* Endif */
   } /* Endif */
}