/*! * @brief USB configure endpoint function. * * This function configure endpoint status. * * @param handle The USB device handle. * @param ep Endpoint address. * @param status A flag to indicate whether to stall the endpoint. 1: stall, 0: unstall. * * @return A USB error code or kStatus_USB_Success. */ usb_status_t USB_DeviceConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status) { if (status) { return USB_DeviceStallEndpoint(handle, ep); } else { return USB_DeviceUnstallEndpoint(handle, ep); } }
/*! * @brief Handle set or clear device feature request. * * This function is used to handle set or clear device feature request. * * @param handle The device handle. It equals the value returned from USB_DeviceInit. * @param setup The pointer of the setup packet. * @param buffer It is an out parameter, is used to save the buffer address to response the host's request. * @param length It is an out parameter, the data length. * * @retval kStatus_USB_Success The requst is handled successfully. * @retval kStatus_USB_InvalidRequest The request can not be handle in current device state, * or, the request is unsupported. */ static usb_status_t USB_DeviceCh9SetClearFeature(usb_device_common_class_struct_t *classHandle, usb_setup_struct_t *setup, uint8_t **buffer, uint32_t *length) { usb_status_t error = kStatus_USB_InvalidRequest; uint8_t state; uint8_t isSet = 0U; USB_DeviceGetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); if ((kUSB_DeviceStateAddress != state) && (kUSB_DeviceStateConfigured != state)) { return error; } /* Identify the request is set or clear the feature. */ if (USB_REQUEST_STANDARD_SET_FEATURE == setup->bRequest) { isSet = 1U; } if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_DEVICE) { /* Set or Clear the device featrue. */ if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_REMOTE_WAKEUP == setup->wValue) { /* Set or Clear the device remote wakeup featrue. */ error = USB_DeviceClassCallback(classHandle->handle, kUSB_DeviceEventSetRemoteWakeup, &isSet); } #if (defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U)) && \ (defined(USB_DEVICE_CONFIG_EHCI_TEST_MODE) && (USB_DEVICE_CONFIG_EHCI_TEST_MODE > 0U)) else if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_DEVICE_TEST_MODE == setup->wValue) { state = kUSB_DeviceStateTestMode; error = USB_DeviceSetStatus(classHandle->handle, kUSB_DeviceStatusDeviceState, &state); } #endif else { } } else if ((setup->bmRequestType & USB_REQUEST_TYPE_RECIPIENT_MASK) == USB_REQUEST_TYPE_RECIPIENT_ENDPOINT) { /* Set or Clear the endpoint featrue. */ if (USB_REQUEST_STANDARD_FEATURE_SELECTOR_ENDPOINT_HALT == setup->wValue) { if (USB_CONTROL_ENDPOINT == (setup->wIndex & USB_ENDPOINT_NUMBER_MASK)) { /* Set or Clear the control endpoint status(halt or not). */ if (isSet) { USB_DeviceStallEndpoint(classHandle->handle, (uint8_t)setup->wIndex); } else { USB_DeviceUnstallEndpoint(classHandle->handle, (uint8_t)setup->wIndex); } } /* Set or Clear the endpoint status featrue. */ if (isSet) { error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventSetEndpointHalt, &setup->wIndex); } else { error = USB_DeviceClassEvent(classHandle->handle, kUSB_DeviceClassEventClearEndpointHalt, &setup->wIndex); } } else { } } else { } return error; }
usb_status_t USB_DeviceMscDiskConfigureEndpointStatus(usb_device_handle handle, uint8_t ep, uint8_t status) { usb_status_t error = kStatus_USB_Error; usb_device_msc_struct_t *mscHandle; mscHandle = &(g_deviceComposite->mscDisk.handle); if (status) { if ((USB_MSC_DISK_BULK_IN_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80U)) { if (mscHandle->inEndpointStallFlag == 0) { mscHandle->inEndpointStallFlag = 1; error = USB_DeviceStallEndpoint(handle, ep); } } else if ((USB_MSC_DISK_BULK_OUT_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80U)) { if (mscHandle->outEndpointStallFlag == 0) { mscHandle->outEndpointStallFlag = 1; error = USB_DeviceStallEndpoint(handle, ep); } } else { } } else { if ((USB_MSC_DISK_BULK_IN_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80U)) { if (mscHandle->inEndpointStallFlag == 1) { mscHandle->inEndpointStallFlag = 0; error = USB_DeviceUnstallEndpoint(handle, ep); } } else if ((USB_MSC_DISK_BULK_OUT_ENDPOINT == (ep & USB_ENDPOINT_NUMBER_MASK)) && (ep & 0x80U)) { if (mscHandle->outEndpointStallFlag == 1) { mscHandle->outEndpointStallFlag = 0; error = USB_DeviceUnstallEndpoint(handle, ep); } } else { } } if (((mscHandle->stallStatus == USB_DEVICE_MSC_STALL_IN_CSW) || (mscHandle->stallStatus == USB_DEVICE_MSC_STALL_IN_DATA)) && (mscHandle->performResetDoneFlag != 1)) { if (mscHandle->cswPrimeFlag == 1) { USB_DeviceCancel(handle, mscHandle->bulkInEndpoint); } USB_DeviceSendRequest(handle, mscHandle->bulkInEndpoint, (uint8_t *)&mscHandle->g_mscCsw, USB_DEVICE_MSC_CSW_LENGTH); mscHandle->cswPrimeFlag = 0; mscHandle->stallStatus = 0; } if ((mscHandle->performResetDoneFlag == 1) && (mscHandle->inEndpointStallFlag == 0) && (mscHandle->outEndpointStallFlag == 0)) { mscHandle->performResetDoneFlag = 0; if (mscHandle->cswPrimeFlag == 1) { USB_DeviceCancel(handle, mscHandle->bulkInEndpoint); } USB_DeviceRecvRequest(handle, mscHandle->bulkOutEndpoint, (uint8_t *)&mscHandle->g_mscCbw, USB_DEVICE_MSC_CBW_LENGTH); mscHandle->cswPrimeFlag = 0; mscHandle->stallStatus = 0; } return error; }