/**************************************************************************//*! * * @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); }