623 lines
26 KiB
C
623 lines
26 KiB
C
/*
|
|
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
|
|
* Copyright 2016,2019 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "usb_host_config.h"
|
|
#if ((defined USB_HOST_CONFIG_HUB) && (USB_HOST_CONFIG_HUB))
|
|
#include "usb_host.h"
|
|
#include "usb_host_hub.h"
|
|
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
/*!
|
|
* @brief hub control transfer callback.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostHubControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
|
|
|
|
/*!
|
|
* @brief hub interrupt in transfer callback.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostHubInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
|
|
|
|
/*!
|
|
* @brief USB_HostHubSendPortReset's transfer callback.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostHubResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
|
|
|
|
/*!
|
|
* @brief hub control transfer common code.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param requestType request type.
|
|
* @param request setup packet request field.
|
|
* @param wvalue setup packet wValue field.
|
|
* @param windex setup packet wIndex field.
|
|
* @param buffer the buffer pointer.
|
|
* @param bufferLength the buffer length.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @return kStatus_USB_Success or error codes.
|
|
*/
|
|
static usb_status_t USB_HostHubClassRequestCommon(usb_host_class_handle classHandle,
|
|
uint8_t requestType,
|
|
uint8_t request,
|
|
uint16_t wvalue,
|
|
uint16_t windex,
|
|
uint8_t *buffer,
|
|
uint16_t bufferLength,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam);
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
|
|
static void USB_HostHubControlCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
|
|
{
|
|
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
|
|
|
|
hubInstance->controlTransfer = NULL;
|
|
if (NULL != hubInstance->controlCallbackFn)
|
|
{
|
|
/* callback to application, callback function is initialized in the USB_HostPrinterControl,
|
|
USB_HostPrinterSetInterface
|
|
or USB_HostHubClassRequestCommon, but is the same function */
|
|
hubInstance->controlCallbackFn(hubInstance->controlCallbackParam, transfer->transferBuffer,
|
|
transfer->transferSofar, status); /* callback to application */
|
|
}
|
|
(void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
|
|
}
|
|
|
|
static void USB_HostHubInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
|
|
{
|
|
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
|
|
|
|
if (NULL != hubInstance->inCallbackFn)
|
|
{
|
|
/* callback to application, callback function is initialized in the USB_HostHubInterruptRecv */
|
|
hubInstance->inCallbackFn(hubInstance->inCallbackParam, transfer->transferBuffer, transfer->transferSofar,
|
|
status); /* callback to application */
|
|
}
|
|
(void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
|
|
}
|
|
|
|
static void USB_HostHubResetCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
|
|
{
|
|
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)param;
|
|
|
|
/* note: there is not callback to application, the re-enumeration will start automatically after reset. */
|
|
(void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
|
|
}
|
|
|
|
static usb_status_t USB_HostHubClassRequestCommon(usb_host_class_handle classHandle,
|
|
uint8_t requestType,
|
|
uint8_t request,
|
|
uint16_t wvalue,
|
|
uint16_t windex,
|
|
uint8_t *buffer,
|
|
uint16_t bufferLength,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
|
|
usb_host_transfer_t *transfer;
|
|
|
|
if (hubInstance->controlTransfer != NULL)
|
|
{
|
|
return kStatus_USB_Busy;
|
|
}
|
|
|
|
/* get transfer */
|
|
if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error to get transfer\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
|
|
/* save hub application callback */
|
|
hubInstance->controlCallbackFn = callbackFn;
|
|
hubInstance->controlCallbackParam = callbackParam;
|
|
|
|
/* initialize transfer */
|
|
transfer->transferBuffer = buffer;
|
|
transfer->transferLength = bufferLength;
|
|
transfer->callbackFn = USB_HostHubControlCallback;
|
|
transfer->callbackParam = hubInstance;
|
|
transfer->setupPacket->bmRequestType = requestType;
|
|
transfer->setupPacket->bRequest = request;
|
|
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(wvalue);
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(windex);
|
|
transfer->setupPacket->wLength = USB_SHORT_TO_LITTLE_ENDIAN(bufferLength);
|
|
|
|
/* send transfer */
|
|
if (USB_HostSendSetup(hubInstance->hostHandle, hubInstance->controlPipe, transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("Error in hid get report descriptor\r\n");
|
|
#endif
|
|
(void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
|
|
return kStatus_USB_Error;
|
|
}
|
|
hubInstance->controlTransfer = transfer; /* record the on-going setup transfer */
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
usb_status_t USB_HostHubInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
|
|
{
|
|
/* malloc the hub instance */
|
|
usb_host_hub_instance_t *hubInstance =
|
|
(usb_host_hub_instance_t *)OSA_MemoryAllocate(sizeof(usb_host_hub_instance_t));
|
|
uint32_t *temp;
|
|
uint32_t infoValue;
|
|
|
|
if (hubInstance == NULL)
|
|
{
|
|
return kStatus_USB_AllocFail;
|
|
}
|
|
|
|
#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
|
|
hubInstance->hubDescriptor = (uint8_t *)SDK_Malloc(7 + (USB_HOST_HUB_MAX_PORT >> 3) + 1, USB_CACHE_LINESIZE);
|
|
hubInstance->portStatusBuffer = (uint8_t *)SDK_Malloc(4, USB_CACHE_LINESIZE);
|
|
hubInstance->hubStatusBuffer = (uint8_t *)SDK_Malloc(4, USB_CACHE_LINESIZE);
|
|
hubInstance->hubBitmapBuffer = (uint8_t *)SDK_Malloc((USB_HOST_HUB_MAX_PORT >> 3) + 1, USB_CACHE_LINESIZE);
|
|
#endif
|
|
|
|
/* initialize hub instance structure */
|
|
hubInstance->deviceHandle = deviceHandle;
|
|
hubInstance->interfaceHandle = NULL;
|
|
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetHostHandle, &infoValue);
|
|
temp = (uint32_t *)infoValue;
|
|
hubInstance->hostHandle = (usb_host_handle)temp;
|
|
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceControlPipe, &infoValue);
|
|
temp = (uint32_t *)infoValue;
|
|
hubInstance->controlPipe = (usb_host_pipe_handle)temp;
|
|
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceLevel, &infoValue);
|
|
hubInstance->hubLevel = (uint8_t)infoValue;
|
|
|
|
*classHandle = hubInstance; /* return the hub class handle */
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
usb_status_t USB_HostHubSetInterface(usb_host_class_handle classHandle,
|
|
usb_host_interface_handle interfaceHandle,
|
|
uint8_t alternateSetting,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
usb_status_t status;
|
|
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
|
|
usb_host_interface_t *interface = (usb_host_interface_t *)interfaceHandle;
|
|
usb_descriptor_endpoint_t *epDesc = NULL;
|
|
usb_host_pipe_init_t pipeInit;
|
|
uint8_t epIndex;
|
|
|
|
if (classHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
hubInstance->interfaceHandle = interfaceHandle; /* save the interface handle */
|
|
|
|
/* notify the host driver that the interface is used by class */
|
|
status = USB_HostOpenDeviceInterface(hubInstance->deviceHandle, interfaceHandle);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
/* close opened hub interrupt pipe */
|
|
if (hubInstance->interruptPipe != NULL)
|
|
{
|
|
status = USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->interruptPipe, NULL);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when Cancel pipe\r\n");
|
|
#endif
|
|
}
|
|
status = USB_HostClosePipe(hubInstance->hostHandle, hubInstance->interruptPipe);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when close pipe\r\n");
|
|
#endif
|
|
}
|
|
hubInstance->interruptPipe = NULL;
|
|
}
|
|
|
|
/* open hub interrupt pipe */
|
|
for (epIndex = 0; epIndex < interface->epCount; ++epIndex)
|
|
{
|
|
epDesc = interface->epList[epIndex].epDesc;
|
|
if (((epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
|
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
|
|
((epDesc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
|
|
{
|
|
/* get pipe information from endpoint descriptor */
|
|
pipeInit.devInstance = hubInstance->deviceHandle;
|
|
pipeInit.pipeType = USB_ENDPOINT_INTERRUPT;
|
|
pipeInit.direction = USB_IN;
|
|
pipeInit.endpointAddress = (epDesc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
|
|
pipeInit.interval = epDesc->bInterval;
|
|
pipeInit.maxPacketSize = (uint16_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
|
|
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK));
|
|
pipeInit.numberPerUframe = (uint8_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(epDesc->wMaxPacketSize) &
|
|
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK));
|
|
pipeInit.nakCount = USB_HOST_CONFIG_MAX_NAK;
|
|
|
|
/* open hub interrupt in pipe */
|
|
status = USB_HostOpenPipe(hubInstance->hostHandle, &hubInstance->interruptPipe, &pipeInit);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("usb_host_hid_set_interface fail to open pipe\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* hub don't support alternatesetting that is not 0 */
|
|
if (alternateSetting == 0U)
|
|
{
|
|
if (callbackFn != NULL)
|
|
{
|
|
callbackFn(callbackParam, NULL, 0, kStatus_USB_Success);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("host don't support alternate setting\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
usb_status_t USB_HostHubDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
|
|
{
|
|
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
|
|
usb_status_t status = kStatus_USB_Success;
|
|
if (deviceHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
if (classHandle != NULL)
|
|
{
|
|
/* close opened hub interrupt pipe */
|
|
if (hubInstance->interruptPipe != NULL)
|
|
{
|
|
status = USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->interruptPipe, NULL);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when Cancel pipe\r\n");
|
|
#endif
|
|
}
|
|
status = USB_HostClosePipe(hubInstance->hostHandle, hubInstance->interruptPipe);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("hub close interrupt pipe error\r\n");
|
|
#endif
|
|
}
|
|
hubInstance->interruptPipe = NULL;
|
|
}
|
|
|
|
/* cancel control transfer if exist */
|
|
if ((hubInstance->controlPipe != NULL) && (hubInstance->controlTransfer != NULL))
|
|
{
|
|
status =
|
|
USB_HostCancelTransfer(hubInstance->hostHandle, hubInstance->controlPipe, hubInstance->controlTransfer);
|
|
}
|
|
|
|
/* notify host driver that the interface will not be used */
|
|
(void)USB_HostCloseDeviceInterface(deviceHandle, hubInstance->interfaceHandle);
|
|
#if ((defined(USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE)) && (USB_HOST_CONFIG_BUFFER_PROPERTY_CACHEABLE > 0U))
|
|
SDK_Free(hubInstance->hubDescriptor);
|
|
SDK_Free(hubInstance->portStatusBuffer);
|
|
SDK_Free(hubInstance->hubStatusBuffer);
|
|
SDK_Free(hubInstance->hubBitmapBuffer);
|
|
#endif
|
|
OSA_MemoryFree(hubInstance);
|
|
}
|
|
else
|
|
{
|
|
/* notify host driver that the interface will not be used */
|
|
(void)USB_HostCloseDeviceInterface(deviceHandle, NULL);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
usb_status_t USB_HostHubInterruptRecv(usb_host_class_handle classHandle,
|
|
uint8_t *buffer,
|
|
uint16_t bufferLength,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
|
|
usb_host_transfer_t *transfer;
|
|
|
|
if (classHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
/* get transfer */
|
|
if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error to get transfer\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
|
|
/* save hub application callback */
|
|
hubInstance->inCallbackFn = callbackFn;
|
|
hubInstance->inCallbackParam = callbackParam;
|
|
|
|
/* initialize transfer */
|
|
transfer->transferBuffer = buffer;
|
|
transfer->transferLength = bufferLength;
|
|
transfer->callbackFn = USB_HostHubInPipeCallback;
|
|
transfer->callbackParam = hubInstance;
|
|
|
|
/* call host driver API to receive data */
|
|
if (USB_HostRecv(hubInstance->hostHandle, hubInstance->interruptPipe, transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("failed to USB_HostRecv\r\n");
|
|
#endif
|
|
(void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
|
|
return kStatus_USB_Error;
|
|
}
|
|
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
usb_status_t USB_HostHubSendPortReset(usb_host_class_handle classHandle, uint8_t portNumber)
|
|
{
|
|
usb_host_hub_instance_t *hubInstance = (usb_host_hub_instance_t *)classHandle;
|
|
usb_host_transfer_t *transfer;
|
|
|
|
if (classHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
/* get transfer */
|
|
if (USB_HostMallocTransfer(hubInstance->hostHandle, &transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error to get transfer\r\n");
|
|
#endif
|
|
return kStatus_USB_Busy;
|
|
}
|
|
|
|
/* initialize transfer */
|
|
transfer->transferBuffer = NULL;
|
|
transfer->transferLength = 0;
|
|
transfer->callbackFn = USB_HostHubResetCallback;
|
|
transfer->callbackParam = hubInstance;
|
|
transfer->setupPacket->bmRequestType =
|
|
USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER;
|
|
transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_FEATURE;
|
|
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(PORT_RESET);
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(portNumber);
|
|
transfer->setupPacket->wLength = 0;
|
|
|
|
/* send the transfer */
|
|
if (USB_HostSendSetup(hubInstance->hostHandle, hubInstance->controlPipe, transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("Error in hid get report descriptor\r\n");
|
|
#endif
|
|
(void)USB_HostFreeTransfer(hubInstance->hostHandle, transfer);
|
|
return kStatus_USB_Error;
|
|
}
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/*!
|
|
* @brief hub get descriptor.
|
|
*
|
|
* This function implements get hub descriptor specific request.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param buffer the buffer pointer.
|
|
* @param bufferLength the buffer length.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success send successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_Busy There is no idle transfer.
|
|
* @retval kStatus_USB_Error pipe is not initialized.
|
|
* Or, send transfer fail, please reference to USB_HostSendSetup.
|
|
*/
|
|
usb_status_t USB_HostHubGetDescriptor(usb_host_class_handle classHandle,
|
|
uint8_t *buffer,
|
|
uint16_t bufferLength,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
return USB_HostHubClassRequestCommon(
|
|
classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_DEVICE,
|
|
USB_REQUEST_STANDARD_GET_DESCRIPTOR, 0x00, 0, buffer, bufferLength, callbackFn, callbackParam);
|
|
}
|
|
|
|
/*!
|
|
* @brief hub clear feature.
|
|
*
|
|
* This function implements clear hub feature specific request.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param buffer the buffer pointer.
|
|
* @param bufferLength the buffer length.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success send successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_Busy There is no idle transfer.
|
|
* @retval kStatus_USB_Error pipe is not initialized.
|
|
* Or, send transfer fail, please reference to USB_HostSendSetup.
|
|
*/
|
|
usb_status_t USB_HostHubClearFeature(usb_host_class_handle classHandle,
|
|
uint8_t feature,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
return USB_HostHubClassRequestCommon(classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS,
|
|
USB_REQUEST_STANDARD_CLEAR_FEATURE, feature, 0, NULL, 0, callbackFn,
|
|
callbackParam);
|
|
}
|
|
|
|
/*!
|
|
* @brief hub get status.
|
|
*
|
|
* This function implements get hub status specific request.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param buffer the buffer pointer.
|
|
* @param bufferLength the buffer length.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success send successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_Busy There is no idle transfer.
|
|
* @retval kStatus_USB_Error pipe is not initialized.
|
|
* Or, send transfer fail, please reference to USB_HostSendSetup.
|
|
*/
|
|
usb_status_t USB_HostHubGetStatus(usb_host_class_handle classHandle,
|
|
uint8_t *buffer,
|
|
uint16_t bufferLength,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
return USB_HostHubClassRequestCommon(classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS,
|
|
USB_REQUEST_STANDARD_GET_STATUS, 0, 0, buffer, bufferLength, callbackFn,
|
|
callbackParam);
|
|
}
|
|
|
|
/*!
|
|
* @brief hub set feature.
|
|
*
|
|
* This function implements set hub feature specific request.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param buffer the buffer pointer.
|
|
* @param bufferLength the buffer length.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success send successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_Busy There is no idle transfer.
|
|
* @retval kStatus_USB_Error pipe is not initialized.
|
|
* Or, send transfer fail, please reference to USB_HostSendSetup.
|
|
*/
|
|
usb_status_t USB_HostHubSetPortFeature(usb_host_class_handle classHandle,
|
|
uint8_t portNumber,
|
|
uint8_t feature,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
return USB_HostHubClassRequestCommon(
|
|
classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
|
|
USB_REQUEST_STANDARD_SET_FEATURE, feature, portNumber, NULL, 0, callbackFn, callbackParam);
|
|
}
|
|
|
|
/*!
|
|
* @brief hub clear port feature.
|
|
*
|
|
* This function implements clear hub port feature specific request.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param buffer the buffer pointer.
|
|
* @param bufferLength the buffer length.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success send successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_Busy There is no idle transfer.
|
|
* @retval kStatus_USB_Error pipe is not initialized.
|
|
* Or, send transfer fail, please reference to USB_HostSendSetup.
|
|
*/
|
|
usb_status_t USB_HostHubClearPortFeature(usb_host_class_handle classHandle,
|
|
uint8_t portNumber,
|
|
uint8_t feature,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
return USB_HostHubClassRequestCommon(
|
|
classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
|
|
USB_REQUEST_STANDARD_CLEAR_FEATURE, feature, portNumber, NULL, 0, callbackFn, callbackParam);
|
|
}
|
|
|
|
/*!
|
|
* @brief hub port get status.
|
|
*
|
|
* This function implements get hub port status specific request.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param buffer the buffer pointer.
|
|
* @param bufferLength the buffer length.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success send successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_Busy There is no idle transfer.
|
|
* @retval kStatus_USB_Error pipe is not initialized.
|
|
* Or, send transfer fail, please reference to USB_HostSendSetup.
|
|
*/
|
|
usb_status_t USB_HostHubGetPortStatus(usb_host_class_handle classHandle,
|
|
uint8_t portNumber,
|
|
uint8_t *buffer,
|
|
uint16_t bufferLength,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
return USB_HostHubClassRequestCommon(
|
|
classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_OTHER,
|
|
USB_REQUEST_STANDARD_GET_STATUS, 0, portNumber, buffer, bufferLength, callbackFn, callbackParam);
|
|
}
|
|
|
|
#endif /* USB_HOST_CONFIG_HUB */
|