Exemple #1
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);
}