1171 lines
44 KiB
C
1171 lines
44 KiB
C
/*
|
|
* Copyright 2019 NXP
|
|
* All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include "usb_host_config.h"
|
|
#if ((defined USB_HOST_CONFIG_VIDEO) && (USB_HOST_CONFIG_VIDEO))
|
|
#include "usb_host.h"
|
|
#include "usb_host_video.h"
|
|
|
|
/*******************************************************************************
|
|
* Variables
|
|
******************************************************************************/
|
|
|
|
/*******************************************************************************
|
|
* Prototypes
|
|
******************************************************************************/
|
|
|
|
/*!
|
|
* @brief open video control interface.
|
|
*
|
|
* @param videoInstance video instance pointer.
|
|
*
|
|
* @return kStatus_USB_Success or error codes.
|
|
*/
|
|
static usb_status_t USB_HostVideoControlOpenInterface(usb_host_video_instance_struct_t *videoInstance);
|
|
|
|
/*!
|
|
* @brief open video stream interface.
|
|
*
|
|
* @param videoInstance video instance pointer.
|
|
*
|
|
* @return kStatus_USB_Success or error codes.
|
|
*/
|
|
static usb_status_t USB_HostVideoStreamOpenInterface(usb_host_video_instance_struct_t *videoInstance);
|
|
|
|
/*!
|
|
* @brief video control pipe transfer callback.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostVideoSetControlInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
|
|
|
|
/*!
|
|
* @brief video set interface callback, open pipes.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostVideoSetStreamInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
|
|
|
|
/*!
|
|
* @brief video control command transfer callback.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostVideoControlCommandCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
|
|
|
|
/*!
|
|
* @brief video stream iso in pipe transfer callback.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostVideoStreamIsoInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status);
|
|
|
|
/*!
|
|
* @brief video send control transfer common code.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param typeRequest setup packet request type.
|
|
* @param request setup packet request value.
|
|
* @param wvalue setup packet wvalue value.
|
|
* @param windex setup packet index value.
|
|
* @param wlength setup packet wlength value.
|
|
* @param data data buffer pointer will be transfer.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @return An error code or kStatus_USB_Success.
|
|
*/
|
|
static usb_status_t USB_HostVideoControl(usb_host_class_handle classHandle,
|
|
uint8_t typeRequest,
|
|
uint8_t request,
|
|
uint16_t wvalue,
|
|
uint16_t windex,
|
|
uint16_t wlength,
|
|
uint8_t *data,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam);
|
|
|
|
/*******************************************************************************
|
|
* Code
|
|
******************************************************************************/
|
|
/*!
|
|
* @brief open video control interface.
|
|
*
|
|
* @param videoInstance video instance pointer.
|
|
*
|
|
* @return kStatus_USB_Success or error codes.
|
|
*/
|
|
static usb_status_t USB_HostVideoControlOpenInterface(usb_host_video_instance_struct_t *videoInstance)
|
|
{
|
|
usb_status_t status;
|
|
uint8_t ep_index = 0U;
|
|
usb_host_pipe_init_t pipe_init;
|
|
usb_descriptor_endpoint_t *ep_desc = NULL;
|
|
usb_host_interface_t *interface_ptr;
|
|
void *temp;
|
|
if (videoInstance->interruptPipe != NULL)
|
|
{
|
|
status = USB_HostClosePipe(videoInstance->hostHandle, videoInstance->interruptPipe);
|
|
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when close pipe\r\n");
|
|
#endif
|
|
}
|
|
videoInstance->interruptPipe = NULL;
|
|
}
|
|
|
|
/* open interface pipes */
|
|
temp = (void *)videoInstance->controlIntfHandle;
|
|
interface_ptr = (usb_host_interface_t *)temp;
|
|
for (ep_index = 0U; ep_index < interface_ptr->epCount; ++ep_index)
|
|
{
|
|
ep_desc = interface_ptr->epList[ep_index].epDesc;
|
|
if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
|
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
|
|
((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_INTERRUPT))
|
|
{
|
|
pipe_init.devInstance = videoInstance->deviceHandle;
|
|
pipe_init.pipeType = USB_ENDPOINT_INTERRUPT;
|
|
pipe_init.direction = USB_IN;
|
|
pipe_init.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
|
|
pipe_init.interval = ep_desc->bInterval;
|
|
pipe_init.maxPacketSize = (uint16_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
|
|
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK));
|
|
pipe_init.numberPerUframe = (uint8_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
|
|
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK));
|
|
pipe_init.nakCount = USB_HOST_CONFIG_MAX_NAK;
|
|
|
|
videoInstance->interruptInPacketSize = pipe_init.maxPacketSize;
|
|
videoInstance->interruptInEpNum = pipe_init.endpointAddress;
|
|
status = USB_HostOpenPipe(videoInstance->hostHandle, &videoInstance->interruptPipe, &pipe_init);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("usb_host_video_control_set_interface fail to open pipe\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/*!
|
|
* @brief open video stream interface.
|
|
*
|
|
* @param videoInstance video instance pointer.
|
|
*
|
|
* @return kStatus_USB_Success or error codes.
|
|
*/
|
|
static usb_status_t USB_HostVideoStreamOpenInterface(usb_host_video_instance_struct_t *videoInstance)
|
|
{
|
|
usb_status_t status;
|
|
uint8_t ep_index = 0U;
|
|
usb_host_pipe_init_t pipe_init;
|
|
usb_descriptor_endpoint_t *ep_desc = NULL;
|
|
usb_host_interface_t *interface_ptr;
|
|
void *temp;
|
|
|
|
if (videoInstance->streamIsoInPipe != NULL)
|
|
{
|
|
status = USB_HostClosePipe(videoInstance->hostHandle, videoInstance->streamIsoInPipe);
|
|
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when close pipe\r\n");
|
|
#endif
|
|
}
|
|
videoInstance->streamIsoInPipe = NULL;
|
|
}
|
|
|
|
/* open interface pipes */
|
|
temp = (void *)videoInstance->streamIntfHandle;
|
|
interface_ptr = (usb_host_interface_t *)temp;
|
|
for (ep_index = 0U; ep_index < interface_ptr->epCount; ++ep_index)
|
|
{
|
|
ep_desc = interface_ptr->epList[ep_index].epDesc;
|
|
if (((ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_MASK) ==
|
|
USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_IN) &&
|
|
((ep_desc->bmAttributes & USB_DESCRIPTOR_ENDPOINT_ATTRIBUTE_TYPE_MASK) == USB_ENDPOINT_ISOCHRONOUS))
|
|
{
|
|
pipe_init.devInstance = videoInstance->deviceHandle;
|
|
pipe_init.pipeType = USB_ENDPOINT_ISOCHRONOUS;
|
|
pipe_init.direction = USB_IN;
|
|
pipe_init.endpointAddress = (ep_desc->bEndpointAddress & USB_DESCRIPTOR_ENDPOINT_ADDRESS_NUMBER_MASK);
|
|
pipe_init.interval = ep_desc->bInterval;
|
|
pipe_init.maxPacketSize = (uint16_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
|
|
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_SIZE_MASK));
|
|
pipe_init.numberPerUframe = (uint8_t)((USB_SHORT_FROM_LITTLE_ENDIAN_ADDRESS(ep_desc->wMaxPacketSize) &
|
|
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_MASK) >>
|
|
USB_DESCRIPTOR_ENDPOINT_MAXPACKETSIZE_MULT_TRANSACTIONS_SHFIT);
|
|
pipe_init.nakCount = USB_HOST_CONFIG_MAX_NAK;
|
|
|
|
videoInstance->isoInPacketSize = pipe_init.maxPacketSize;
|
|
videoInstance->isoInEpNum = pipe_init.endpointAddress;
|
|
status = USB_HostOpenPipe(videoInstance->hostHandle, &videoInstance->streamIsoInPipe, &pipe_init);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("usb_host_video_stream_set_interface fail to open pipe\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
}
|
|
}
|
|
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/*!
|
|
* @brief video control pipe transfer callback.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostVideoSetControlInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)param;
|
|
|
|
videoInstance->controlTransfer = NULL;
|
|
if (status == kStatus_USB_Success)
|
|
{
|
|
status = USB_HostVideoControlOpenInterface(videoInstance);
|
|
}
|
|
|
|
if (videoInstance->controlCallbackFn != NULL)
|
|
{
|
|
/* callback to application, callback function is initialized in the _USB_HostAudioControl,
|
|
USB_HostVideoStreamSetInterface
|
|
or USB_HostVideoControlSetInterface, but is the same function */
|
|
videoInstance->controlCallbackFn(videoInstance->controlCallbackParam, transfer->transferBuffer,
|
|
transfer->transferSofar, status);
|
|
}
|
|
(void)USB_HostFreeTransfer(videoInstance->hostHandle, transfer);
|
|
}
|
|
|
|
/*!
|
|
* @brief video set interface callback, open pipes.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostVideoSetStreamInterfaceCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)param;
|
|
|
|
videoInstance->controlTransfer = NULL;
|
|
if (status == kStatus_USB_Success)
|
|
{
|
|
status = USB_HostVideoStreamOpenInterface(videoInstance);
|
|
}
|
|
|
|
if (videoInstance->controlCallbackFn != NULL)
|
|
{
|
|
/* callback to application, callback function is initialized in the _USB_HostAudioControl,
|
|
USB_HostAudioStreamSetInterface
|
|
or USB_HostAudioControlSetInterface, but is the same function */
|
|
videoInstance->controlCallbackFn(videoInstance->controlCallbackParam, NULL, 0U, status);
|
|
}
|
|
(void)USB_HostFreeTransfer(videoInstance->hostHandle, transfer);
|
|
}
|
|
|
|
/*!
|
|
* @brief video control command transfer callback.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostVideoControlCommandCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)param;
|
|
|
|
if (videoInstance->controlCallbackFn != NULL)
|
|
{
|
|
/* callback to application, callback function is initialized in the USB_HostCdcControl,
|
|
USB_HostCdcSetControlInterface
|
|
or USB_HostCdcSetDataInterface, but is the same function */
|
|
videoInstance->controlCallbackFn(videoInstance->controlCallbackParam, transfer->transferBuffer,
|
|
transfer->transferSofar, status);
|
|
}
|
|
(void)USB_HostFreeTransfer(videoInstance->hostHandle, transfer);
|
|
}
|
|
|
|
/*!
|
|
* @brief video stream iso in pipe transfer callback.
|
|
*
|
|
* @param param callback parameter.
|
|
* @param transfer callback transfer.
|
|
* @param status transfer status.
|
|
*/
|
|
static void USB_HostVideoStreamIsoInPipeCallback(void *param, usb_host_transfer_t *transfer, usb_status_t status)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)param;
|
|
|
|
if (videoInstance->streamIsoInCallbackFn != NULL)
|
|
{
|
|
/* callback function is initialized in USB_HosVideoStreamRecv */
|
|
videoInstance->streamIsoInCallbackFn(videoInstance->streamIsoInCallbackParam, transfer->transferBuffer,
|
|
transfer->transferSofar, status);
|
|
}
|
|
(void)USB_HostFreeTransfer(videoInstance->hostHandle, transfer);
|
|
}
|
|
|
|
/*!
|
|
* @brief video send control transfer common code.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param typeRequest setup packet request type.
|
|
* @param request setup packet request value.
|
|
* @param wvalue setup packet wvalue value.
|
|
* @param windex setup packet index value.
|
|
* @param wlength setup packet wlength value.
|
|
* @param data data buffer pointer will be transfer.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @return An error code or kStatus_USB_Success.
|
|
*/
|
|
static usb_status_t USB_HostVideoControl(usb_host_class_handle classHandle,
|
|
uint8_t typeRequest,
|
|
uint8_t request,
|
|
uint16_t wvalue,
|
|
uint16_t windex,
|
|
uint16_t wlength,
|
|
uint8_t *data,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
usb_host_transfer_t *transfer;
|
|
|
|
if (classHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
/* malloc one transfer */
|
|
if (USB_HostMallocTransfer(videoInstance->hostHandle, &transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error to get transfer\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
/* save the application callback function */
|
|
videoInstance->controlCallbackFn = callbackFn;
|
|
videoInstance->controlCallbackParam = callbackParam;
|
|
|
|
transfer->transferBuffer = data;
|
|
transfer->transferLength = wlength;
|
|
transfer->callbackFn = USB_HostVideoControlCommandCallback;
|
|
transfer->callbackParam = videoInstance;
|
|
transfer->setupPacket->bmRequestType = typeRequest;
|
|
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(wlength);
|
|
|
|
if (USB_HostSendSetup(videoInstance->hostHandle, videoInstance->controlPipe, transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("failed for USB_HostSendSetup\r\n");
|
|
#endif
|
|
(void)USB_HostFreeTransfer(videoInstance->hostHandle, transfer);
|
|
return kStatus_USB_Error;
|
|
}
|
|
videoInstance->controlTransfer = transfer;
|
|
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/*!
|
|
* @brief set video class stream interface.
|
|
*
|
|
* This function bind the interface with the video instance.
|
|
*
|
|
* @param classHandle The class handle.
|
|
* @param interfaceHandle The interface handle.
|
|
* @param alternateSetting The alternate setting value.
|
|
* @param callbackFn This callback is called after this function completes.
|
|
* @param callbackParam The first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success The device is initialized successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_Busy There is no idle transfer.
|
|
* @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
|
|
* @retval kStatus_USB_Busy callback return status, there is no idle pipe.
|
|
* @retval kStatus_USB_TransferStall callback return status, the transfer is stall by device.
|
|
* @retval kStatus_USB_Error callback return status, open pipe fail, please reference to USB_HostOpenPipe.
|
|
*/
|
|
usb_status_t USB_HostVideoStreamSetInterface(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_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
usb_host_interface_t *interface_ptr;
|
|
usb_host_transfer_t *transfer;
|
|
usb_host_video_descriptor_union_t descUnion;
|
|
uint32_t length, ep = 0U;
|
|
uint32_t descLength = 0;
|
|
void *temp;
|
|
|
|
if (classHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidParameter;
|
|
}
|
|
|
|
videoInstance->streamIntfHandle = interfaceHandle;
|
|
|
|
status = USB_HostOpenDeviceInterface(videoInstance->deviceHandle, interfaceHandle); /* save the application callback function */
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
/* cancel transfers */
|
|
if (videoInstance->streamIsoInPipe != NULL)
|
|
{
|
|
status = USB_HostCancelTransfer(videoInstance->hostHandle, videoInstance->streamIsoInPipe, NULL);
|
|
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when cancel pipe\r\n");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* open interface pipes */
|
|
interface_ptr = (usb_host_interface_t *)interfaceHandle;
|
|
|
|
if (0U == alternateSetting)
|
|
{
|
|
descUnion.bufr = interface_ptr->interfaceExtension;
|
|
length = 0U;
|
|
while (length < interface_ptr->interfaceExtensionLength)
|
|
{
|
|
if (descUnion.common->bDescriptorType == USB_HOST_DESC_CS_INTERFACE)
|
|
{
|
|
if (descUnion.common->bData[0] == USB_HOST_DESC_SUBTYPE_VS_INPUT_HEADER)
|
|
{
|
|
temp = (void *)descUnion.bufr;
|
|
videoInstance->vsInputHeaderDesc = (usb_host_video_stream_input_header_desc_t *)temp;
|
|
break;
|
|
}
|
|
}
|
|
length += descUnion.common->bLength;
|
|
descUnion.bufr += descUnion.common->bLength;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
descUnion.bufr = interface_ptr->interfaceExtension;
|
|
length = 0U;
|
|
while (length < interface_ptr->interfaceExtensionLength)
|
|
{
|
|
if ((descUnion.common->bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE) &&
|
|
(descUnion.interface->bAlternateSetting == alternateSetting))
|
|
{
|
|
interface_ptr->epCount = descUnion.interface->bNumEndpoints;
|
|
break;
|
|
}
|
|
length += descUnion.common->bLength;
|
|
descUnion.bufr += descUnion.common->bLength;
|
|
}
|
|
|
|
while (ep < interface_ptr->epCount)
|
|
{
|
|
if (descUnion.common->bDescriptorType == USB_DESCRIPTOR_TYPE_ENDPOINT)
|
|
{
|
|
temp = (void *)descUnion.bufr;
|
|
interface_ptr->epList[ep].epDesc = (usb_descriptor_endpoint_t *)temp;
|
|
descLength = descUnion.common->bLength;
|
|
descUnion.bufr += descUnion.common->bLength;
|
|
|
|
if (USB_HOST_DESC_CS_ENDPOINT == descUnion.common->bDescriptorType)
|
|
{
|
|
interface_ptr->epList[ep].epExtension = descUnion.bufr;
|
|
interface_ptr->epList[ep].epExtensionLength = descUnion.common->bLength;
|
|
}
|
|
else
|
|
{
|
|
descUnion.bufr -= descLength;
|
|
}
|
|
ep++;
|
|
}
|
|
descUnion.bufr += descUnion.common->bLength;
|
|
}
|
|
}
|
|
|
|
if (alternateSetting == 0U) /* open interface directly */
|
|
{
|
|
if (callbackFn != NULL)
|
|
{
|
|
status = USB_HostVideoStreamOpenInterface(videoInstance);
|
|
callbackFn(callbackParam, NULL, 0U, kStatus_USB_Success);
|
|
}
|
|
}
|
|
else /* send setup transfer */
|
|
{
|
|
/* malloc one transfer */
|
|
if (USB_HostMallocTransfer(videoInstance->hostHandle, &transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error to get transfer\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
/* save the application callback function */
|
|
videoInstance->controlCallbackFn = callbackFn;
|
|
videoInstance->controlCallbackParam = callbackParam;
|
|
/* initialize transfer */
|
|
transfer->callbackFn = USB_HostVideoSetStreamInterfaceCallback;
|
|
transfer->callbackParam = videoInstance;
|
|
transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
|
|
transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
|
|
((usb_host_interface_t *)videoInstance->streamIntfHandle)->interfaceDesc->bInterfaceNumber);
|
|
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
|
|
transfer->setupPacket->wLength = 0;
|
|
transfer->transferBuffer = NULL;
|
|
transfer->transferLength = 0;
|
|
status = USB_HostSendSetup(videoInstance->hostHandle, videoInstance->controlPipe, transfer);
|
|
|
|
if (status == kStatus_USB_Success)
|
|
{
|
|
videoInstance->controlTransfer = transfer;
|
|
}
|
|
else
|
|
{
|
|
(void)USB_HostFreeTransfer(videoInstance->hostHandle, transfer);
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* @brief set control interface.
|
|
*
|
|
* This function bind the control interface with the video instance.
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param interfaceHandle the control interface handle.
|
|
* @param alternateSetting the alternate setting value.
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success The device is initialized successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_Busy There is no idle transfer.
|
|
* @retval kStatus_USB_Error send transfer fail, please reference to USB_HostSendSetup.
|
|
* @retval kStatus_USB_Busy callback return status, there is no idle pipe.
|
|
* @retval kStatus_USB_TransferStall callback return status, the transfer is stall by device.
|
|
* @retval kStatus_USB_Error callback return status, open pipe fail, please reference to USB_HostOpenPipe.
|
|
*/
|
|
usb_status_t USB_HostVideoControlSetInterface(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_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
usb_host_interface_t *interface_ptr;
|
|
usb_host_transfer_t *transfer;
|
|
usb_host_video_descriptor_union_t desc;
|
|
uint32_t length = 0U;
|
|
void *temp;
|
|
|
|
if (classHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidParameter;
|
|
}
|
|
videoInstance->controlIntfHandle = interfaceHandle;
|
|
interface_ptr = (usb_host_interface_t *)interfaceHandle;
|
|
|
|
status = USB_HostOpenDeviceInterface(videoInstance->deviceHandle, interfaceHandle); /* notify host driver the interface is open */
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
return status;
|
|
}
|
|
desc.bufr = interface_ptr->interfaceExtension;
|
|
|
|
length = 0U;
|
|
|
|
while (length < interface_ptr->interfaceExtensionLength)
|
|
{
|
|
if (((interface_ptr->interfaceDesc->bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE) &&
|
|
(interface_ptr->interfaceDesc->bAlternateSetting == alternateSetting)) ||
|
|
((desc.common->bDescriptorType == USB_DESCRIPTOR_TYPE_INTERFACE) &&
|
|
(desc.interface->bAlternateSetting == alternateSetting)))
|
|
{
|
|
break;
|
|
}
|
|
length += desc.common->bLength;
|
|
desc.bufr += desc.common->bLength;
|
|
}
|
|
while (length < interface_ptr->interfaceExtensionLength)
|
|
{
|
|
if (desc.common->bDescriptorType == USB_HOST_DESC_CS_INTERFACE)
|
|
{
|
|
temp = (void *)desc.bufr;
|
|
if (desc.common->bData[0] == USB_HOST_DESC_SUBTYPE_VC_HEADER)
|
|
{
|
|
videoInstance->vcHeaderDesc = (usb_host_video_ctrl_header_desc_t *)temp;
|
|
}
|
|
else if (desc.common->bData[0] == USB_HOST_DESC_SUBTYPE_VC_INPUT_TERMINAL)
|
|
{
|
|
videoInstance->vcInputTerminalDesc = (usb_host_video_ctrl_it_desc_t *)temp;
|
|
}
|
|
else if (desc.common->bData[0] == USB_HOST_DESC_SUBTYPE_VC_OUTPUT_TERMINAL)
|
|
{
|
|
videoInstance->vcOutputTerminalDesc = (usb_host_video_ctrl_ot_desc_t *)temp;
|
|
}
|
|
else if (desc.common->bData[0] == USB_HOST_DESC_SUBTYPE_VC_PROCESSING_UNIT)
|
|
{
|
|
videoInstance->vcProcessingUnitDesc = (usb_host_video_ctrl_pu_desc_t *)temp;
|
|
}
|
|
else
|
|
{
|
|
/*no action*/
|
|
}
|
|
}
|
|
length += desc.common->bLength;
|
|
desc.bufr += desc.common->bLength;
|
|
}
|
|
|
|
if (alternateSetting == 0U) /* open interface directly */
|
|
{
|
|
if (callbackFn != NULL)
|
|
{
|
|
status = USB_HostVideoControlOpenInterface(videoInstance);
|
|
callbackFn(callbackParam, NULL, 0U, kStatus_USB_Success);
|
|
}
|
|
}
|
|
else /* send setup transfer */
|
|
{
|
|
/* malloc one transfer */
|
|
if (USB_HostMallocTransfer(videoInstance->hostHandle, &transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error to get transfer\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
/* save the application callback function */
|
|
videoInstance->controlCallbackFn = callbackFn;
|
|
videoInstance->controlCallbackParam = callbackParam;
|
|
/* initialize transfer */
|
|
transfer->callbackFn = USB_HostVideoSetControlInterfaceCallback;
|
|
transfer->callbackParam = videoInstance;
|
|
transfer->setupPacket->bRequest = USB_REQUEST_STANDARD_SET_INTERFACE;
|
|
transfer->setupPacket->bmRequestType = USB_REQUEST_TYPE_RECIPIENT_INTERFACE;
|
|
transfer->setupPacket->wIndex = USB_SHORT_TO_LITTLE_ENDIAN(
|
|
((usb_host_interface_t *)videoInstance->controlIntfHandle)->interfaceDesc->bInterfaceNumber);
|
|
transfer->setupPacket->wValue = USB_SHORT_TO_LITTLE_ENDIAN(alternateSetting);
|
|
transfer->setupPacket->wLength = 0;
|
|
transfer->transferBuffer = NULL;
|
|
transfer->transferLength = 0;
|
|
status = USB_HostSendSetup(videoInstance->hostHandle, videoInstance->controlPipe, transfer);
|
|
|
|
if (status == kStatus_USB_Success)
|
|
{
|
|
videoInstance->controlTransfer = transfer;
|
|
}
|
|
else
|
|
{
|
|
(void)USB_HostFreeTransfer(videoInstance->hostHandle, transfer);
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* @brief video stream receive data.
|
|
*
|
|
* This function implements video receiving data.
|
|
*
|
|
* @param classHandle The class handle.
|
|
* @param buffer The buffer pointer.
|
|
* @param bufferLen 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 Receive request 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_HostRecv.
|
|
*/
|
|
usb_status_t USB_HosVideoStreamRecv(usb_host_class_handle classHandle,
|
|
uint8_t *buffer,
|
|
uint32_t bufferLen,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
usb_host_transfer_t *transfer;
|
|
|
|
if (classHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
if (videoInstance->streamIsoInPipe == NULL)
|
|
{
|
|
return kStatus_USB_Error;
|
|
}
|
|
|
|
/* malloc one transfer */
|
|
if (USB_HostMallocTransfer(videoInstance->hostHandle, &transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error to get transfer\r\n");
|
|
#endif
|
|
return kStatus_USB_Error;
|
|
}
|
|
/* save the application callback function */
|
|
videoInstance->streamIsoInCallbackFn = callbackFn;
|
|
videoInstance->streamIsoInCallbackParam = callbackParam;
|
|
transfer->transferBuffer = buffer;
|
|
transfer->transferLength = bufferLen;
|
|
transfer->callbackFn = USB_HostVideoStreamIsoInPipeCallback;
|
|
transfer->callbackParam = videoInstance;
|
|
|
|
if (USB_HostRecv(videoInstance->hostHandle, videoInstance->streamIsoInPipe, transfer) != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("failed to USB_HostRecv\r\n");
|
|
#endif
|
|
(void)USB_HostFreeTransfer(videoInstance->hostHandle, transfer);
|
|
return kStatus_USB_Error;
|
|
}
|
|
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/*!
|
|
* @brief initialize the video instance.
|
|
*
|
|
* This function allocate the resource for video instance.
|
|
*
|
|
* @param deviceHandle the device handle.
|
|
* @param classHandle return class handle.
|
|
*
|
|
* @retval kStatus_USB_Success The device is initialized successfully.
|
|
* @retval kStatus_USB_AllocFail Allocate memory fail.
|
|
*/
|
|
usb_status_t USB_HostVideoInit(usb_device_handle deviceHandle, usb_host_class_handle *classHandle)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance =
|
|
(usb_host_video_instance_struct_t *)OSA_MemoryAllocate(sizeof(usb_host_video_instance_struct_t));
|
|
uint32_t info_value;
|
|
uint32_t *temp;
|
|
if (videoInstance == NULL)
|
|
{
|
|
return kStatus_USB_AllocFail;
|
|
}
|
|
|
|
/* initialize video instance */
|
|
videoInstance->deviceHandle = deviceHandle;
|
|
videoInstance->controlIntfHandle = NULL;
|
|
videoInstance->streamIntfHandle = NULL;
|
|
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetHostHandle, &info_value);
|
|
temp = (uint32_t *)info_value;
|
|
videoInstance->hostHandle = (usb_host_handle)temp;
|
|
(void)USB_HostHelperGetPeripheralInformation(deviceHandle, (uint32_t)kUSB_HostGetDeviceControlPipe, &info_value);
|
|
temp = (uint32_t *)info_value;
|
|
videoInstance->controlPipe = (usb_host_pipe_handle)temp;
|
|
|
|
*classHandle = videoInstance;
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/*!
|
|
* @brief de-initialize the video instance.
|
|
*
|
|
* This function release the resource for video instance.
|
|
*
|
|
* @param deviceHandle the device handle.
|
|
* @param classHandle the class handle.
|
|
*
|
|
* @retval kStatus_USB_Success The device is de-initialized successfully.
|
|
*/
|
|
usb_status_t USB_HostVideoDeinit(usb_device_handle deviceHandle, usb_host_class_handle classHandle)
|
|
{
|
|
usb_status_t status;
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
|
|
if (deviceHandle == NULL)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
if (classHandle != NULL)
|
|
{
|
|
/* cancel transfers */
|
|
if (videoInstance->streamIsoInPipe != NULL)
|
|
{
|
|
status = USB_HostCancelTransfer(videoInstance->hostHandle, videoInstance->streamIsoInPipe, NULL);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when cancel pipe\r\n");
|
|
#endif
|
|
}
|
|
status = USB_HostClosePipe(videoInstance->hostHandle, videoInstance->streamIsoInPipe);
|
|
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when close pipe\r\n");
|
|
#endif
|
|
}
|
|
videoInstance->streamIsoInPipe = NULL;
|
|
}
|
|
|
|
(void)USB_HostCloseDeviceInterface(deviceHandle, videoInstance->streamIntfHandle);
|
|
|
|
/* cancel transfers */
|
|
if (videoInstance->interruptPipe != NULL)
|
|
{
|
|
status = USB_HostCancelTransfer(videoInstance->hostHandle, videoInstance->interruptPipe, NULL);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when cancel pipe\r\n");
|
|
#endif
|
|
}
|
|
status = USB_HostClosePipe(videoInstance->hostHandle, videoInstance->interruptPipe);
|
|
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when close pipe\r\n");
|
|
#endif
|
|
}
|
|
videoInstance->interruptPipe = NULL;
|
|
}
|
|
/* cancel transfers */
|
|
if ((videoInstance->controlPipe != NULL) && (videoInstance->controlTransfer != NULL))
|
|
{
|
|
status = USB_HostCancelTransfer(videoInstance->hostHandle, videoInstance->controlPipe,
|
|
videoInstance->controlTransfer);
|
|
if (status != kStatus_USB_Success)
|
|
{
|
|
#ifdef HOST_ECHO
|
|
usb_echo("error when cancel pipe\r\n");
|
|
#endif
|
|
}
|
|
}
|
|
(void)USB_HostCloseDeviceInterface(deviceHandle, videoInstance->controlIntfHandle);
|
|
OSA_MemoryFree(videoInstance);
|
|
}
|
|
else
|
|
{
|
|
(void)USB_HostCloseDeviceInterface(deviceHandle, NULL);
|
|
}
|
|
|
|
return kStatus_USB_Success;
|
|
}
|
|
|
|
/*!
|
|
* @brief get video stream format descriptor.
|
|
*
|
|
* This function implements get video stream format descriptor.
|
|
*
|
|
* @param classHandle The class handle.
|
|
* @param subType The descriptor subtype.
|
|
* @param descriptor The pointer of specific format descriptor.
|
|
*
|
|
* @retval kStatus_USB_Success Get video stream format descriptor request successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_InvalidParameter The descriptor is NULL pointer.
|
|
*
|
|
*/
|
|
usb_status_t USB_HostVideoStreamGetFormatDescriptor(usb_host_class_handle classHandle,
|
|
uint8_t subType,
|
|
void **descriptor)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
usb_host_interface_t *interface_ptr;
|
|
usb_host_video_descriptor_union_t descUnion;
|
|
uint32_t length = 0U;
|
|
|
|
if (NULL == classHandle)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
/* get the steam interface handle */
|
|
interface_ptr = (usb_host_interface_t *)videoInstance->streamIntfHandle;
|
|
|
|
descUnion.bufr = interface_ptr->interfaceExtension;
|
|
length = 0U;
|
|
while (length < interface_ptr->interfaceExtensionLength)
|
|
{
|
|
if (descUnion.common->bDescriptorType == USB_HOST_DESC_CS_INTERFACE)
|
|
{
|
|
if (descUnion.common->bData[0] == subType)
|
|
{
|
|
*descriptor = descUnion.bufr;
|
|
return kStatus_USB_Success;
|
|
;
|
|
}
|
|
}
|
|
length += descUnion.common->bLength;
|
|
descUnion.bufr += descUnion.common->bLength;
|
|
}
|
|
|
|
return kStatus_USB_Error;
|
|
}
|
|
|
|
/*!
|
|
* @brief get specific video stream frame descriptor.
|
|
*
|
|
* This function implements get specific video stream frame descriptor.
|
|
*
|
|
* @param classHandle The class handle.
|
|
* @param formatDescriptor The frame descriptor pointer.
|
|
* @param index The specific frame descriptor id
|
|
* @param descriptor The pointer of specific frame descriptor.
|
|
*
|
|
* @retval kStatus_USB_Success Get video stream frame descriptor request successfully.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_InvalidParameter The descriptor is NULL pointer.
|
|
*
|
|
*/
|
|
usb_status_t USB_HostVideoStreamGetFrameDescriptor(
|
|
usb_host_class_handle classHandle, void *formatDescriptor, uint8_t subType, uint8_t frameIndex, void **descriptor)
|
|
{
|
|
usb_host_video_stream_payload_format_common_desc_t *formatDesc =
|
|
(usb_host_video_stream_payload_format_common_desc_t *)formatDescriptor;
|
|
usb_host_video_descriptor_union_t desc;
|
|
uint32_t i = 0U;
|
|
uint8_t frameCount = 0U;
|
|
|
|
if (NULL == classHandle)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
|
|
if ((formatDesc == NULL) || (formatDesc->bDescriptorType != USB_HOST_DESC_CS_INTERFACE))
|
|
{
|
|
return kStatus_USB_InvalidParameter;
|
|
}
|
|
|
|
frameCount = formatDesc->bNumFrameDescriptors;
|
|
desc.bufr = (void *)formatDesc;
|
|
desc.bufr += desc.common->bLength;
|
|
|
|
while (i <= frameCount)
|
|
{
|
|
if ((desc.video_frame_common->bDescriptorType == USB_HOST_DESC_CS_INTERFACE) &&
|
|
(desc.video_frame_common->bDescriptorSubtype == subType))
|
|
{
|
|
if (desc.video_frame_common->bFrameIndex == frameIndex)
|
|
{
|
|
*descriptor = (void *)desc.bufr;
|
|
return kStatus_USB_Success;
|
|
}
|
|
}
|
|
i++;
|
|
desc.bufr += desc.common->bLength;
|
|
}
|
|
|
|
return kStatus_USB_Error;
|
|
}
|
|
|
|
/*!
|
|
* @brief video set probe.
|
|
*
|
|
* This function implements the Video class-specific request (set probe).
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param request setup packet request value.
|
|
* @param probe video probe data
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success Request successful.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_InvalidParameter The interface descriptor is NULL pointer.
|
|
*/
|
|
usb_status_t USB_HostVideoSetProbe(usb_host_class_handle classHandle,
|
|
uint8_t request,
|
|
uint8_t *probe,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
usb_host_interface_t *streamInterface;
|
|
usb_status_t status;
|
|
streamInterface = (usb_host_interface_t *)videoInstance->streamIntfHandle;
|
|
|
|
if (NULL == streamInterface)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
if (NULL == streamInterface->interfaceDesc)
|
|
{
|
|
return kStatus_USB_InvalidParameter;
|
|
}
|
|
status = USB_HostVideoControl(
|
|
classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
|
|
request, (uint16_t)(USB_HOST_VS_PROBE_CONTROL << 8UL), streamInterface->interfaceDesc->bInterfaceNumber, 26U,
|
|
probe, callbackFn, callbackParam);
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* @brief video get probe.
|
|
*
|
|
* This function implements the Video class-specific request (get probe).
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param request setup packet request value.
|
|
* @param probe video probe data
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success Request successful.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_InvalidParameter The interface descriptor is NULL pointer.
|
|
*/
|
|
usb_status_t USB_HostVideoGetProbe(usb_host_class_handle classHandle,
|
|
uint8_t request,
|
|
uint8_t *probe,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
usb_host_interface_t *streamInterface;
|
|
usb_status_t status;
|
|
streamInterface = (usb_host_interface_t *)videoInstance->streamIntfHandle;
|
|
if (NULL == streamInterface)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
if (NULL == streamInterface->interfaceDesc)
|
|
{
|
|
return kStatus_USB_InvalidParameter;
|
|
}
|
|
status = USB_HostVideoControl(
|
|
classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
|
|
request, (uint16_t)(USB_HOST_VS_PROBE_CONTROL << 8UL), streamInterface->interfaceDesc->bInterfaceNumber, 26U,
|
|
probe, callbackFn, callbackParam);
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* @brief video get commit.
|
|
*
|
|
* This function implements the Video class-specific request (get commit).
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param request setup packet request value.
|
|
* @param probe video probe data
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success Request successful.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_InvalidParameter The interface descriptor is NULL pointer.
|
|
*/
|
|
usb_status_t USB_HostVideoGetCommit(usb_host_class_handle classHandle,
|
|
uint8_t brequest,
|
|
uint8_t *probe,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
usb_host_interface_t *streamInterface;
|
|
usb_status_t status;
|
|
streamInterface = (usb_host_interface_t *)videoInstance->streamIntfHandle;
|
|
if (NULL == streamInterface)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
if (NULL == streamInterface->interfaceDesc)
|
|
{
|
|
return kStatus_USB_InvalidParameter;
|
|
}
|
|
status = USB_HostVideoControl(
|
|
classHandle, USB_REQUEST_TYPE_DIR_IN | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
|
|
brequest, (uint16_t)(USB_HOST_VS_COMMIT_CONTROL << 8UL), streamInterface->interfaceDesc->bInterfaceNumber, 26U,
|
|
probe, callbackFn, callbackParam);
|
|
return status;
|
|
}
|
|
|
|
/*!
|
|
* @brief video set commit.
|
|
*
|
|
* This function implements the Video class-specific request (set commit).
|
|
*
|
|
* @param classHandle the class handle.
|
|
* @param request setup packet request value.
|
|
* @param probe video probe data
|
|
* @param callbackFn this callback is called after this function completes.
|
|
* @param callbackParam the first parameter in the callback function.
|
|
*
|
|
* @retval kStatus_USB_Success Request successful.
|
|
* @retval kStatus_USB_InvalidHandle The classHandle is NULL pointer.
|
|
* @retval kStatus_USB_InvalidParameter The interface descriptor is NULL pointer.
|
|
*/
|
|
usb_status_t USB_HostVideoSetCommit(usb_host_class_handle classHandle,
|
|
uint8_t brequest,
|
|
uint8_t *probe,
|
|
transfer_callback_t callbackFn,
|
|
void *callbackParam)
|
|
{
|
|
usb_host_video_instance_struct_t *videoInstance = (usb_host_video_instance_struct_t *)classHandle;
|
|
usb_host_interface_t *streamInterface;
|
|
usb_status_t status;
|
|
streamInterface = (usb_host_interface_t *)videoInstance->streamIntfHandle;
|
|
if (NULL == streamInterface)
|
|
{
|
|
return kStatus_USB_InvalidHandle;
|
|
}
|
|
if (NULL == streamInterface->interfaceDesc)
|
|
{
|
|
return kStatus_USB_InvalidParameter;
|
|
}
|
|
status = USB_HostVideoControl(
|
|
classHandle, USB_REQUEST_TYPE_DIR_OUT | USB_REQUEST_TYPE_TYPE_CLASS | USB_REQUEST_TYPE_RECIPIENT_INTERFACE,
|
|
brequest, (uint16_t)(USB_HOST_VS_COMMIT_CONTROL << 8UL), streamInterface->interfaceDesc->bInterfaceNumber, 26U,
|
|
probe, callbackFn, callbackParam);
|
|
return status;
|
|
}
|
|
|
|
#endif
|