Hi,
I need to handle format change on a UVC application, I saw the "video virtual camera" example on MCUXpresso but I don't understand where format canghe is handled.
The file virtual_camera.c has a receive buffer g_UsbDeviceVideoVirtualCamera.classRequestBuffer in function USB_DeviceVideoCallback, this buffer during change format command on USB is correctly filled concordly to USB command but the valiables g_UsbDeviceVideoVirtualCamera.probeStruct->bFormatIndex and g_UsbDeviceVideoVirtualCamera.commitStruct->bFormatIndex don't change as expected, that because function USB_DeviceVideoRequest is never call with USB_DEVICE_VIDEO_SET_CUR_VS_PROBE_CONTROL or USB_DEVICE_VIDEO_SET_CUR_VS_COMMIT_CONTROL.
I don't understand where and how change the code to handle correctly the format change.
Please let me know if you need more information.
Thanks,
M.P.
Hi @MassimilianoPegaso ,
The function USB_DeviceVideoVsProbeRequest() in usb_device_video.c switch by the bRequest field which is in Extension Unit Control Requests. It will set USB_DEVICE_VIDEO_SET_CUR_VS_PROBE_CONTROL and USB_DEVICE_VIDEO_GET_CUR_VS_PROBE_CONTROL.
So, I think this is because host doesn't send the command.
Regards,
Jing
Hi @jingpan,
thank you for your reply, I checked the USB traffic with wireshark and I think that the host send the correct command.
I followed the data flow and I saw that in the USB_DeviceVideoEvent() in usb_device_video.c manage differently USB_DEVICE_VIDEO_SET_REQUEST_INTERFACE and USB_DEVICE_VIDEO_GET_REQUEST_INTERFACE.
With USB_DEVICE_VIDEO_SET_REQUEST_INTERFACE the function USB_DeviceVideoCallback() in virtual_camera.c is called, it setup the receive buffer and return back, I followed the code execution and I saw that it perform the USB reading at USB_DeviceControlCallback() function in usb_device_ch9.c file.
After USB_DeviceControlCallback() execution in the buffer setting up before is present the same message shown in wireshark.
The code enter in USB_DeviceVideoVsProbeRequest() in usb_device_video.c only with USB_DEVICE_VIDEO_GET_REQUEST_INTERFACE.
Thank, regards,
M.P.
Hi,
It seems the demo never receive USB_DEVICE_VIDEO_REQUEST_CODE_SET_CUR request. If you put a breakpoint at line 1316 in usb_device_video.h, it won't break.
Regards,
Jing
Hi,
I have find a possible solution:
In function USB_DeviceControlCallback() on usb_device_ch9.c I changed
status = USB_DeviceRecvRequest(handle, USB_CONTROL_ENDPOINT, buffer, deviceSetup->wLength);
return status;
to
/* Prepare controlRequest to upper layer */
usb_device_control_request_struct_t controlRequest;
controlRequest.buffer = buffer;
controlRequest.isSetup = 0U;
controlRequest.setup = deviceSetup;
controlRequest.length = deviceSetup->wLength;
/* Prime an OUT transfer */
status = USB_DeviceRecvRequest(handle, USB_CONTROL_ENDPOINT, buffer, deviceSetup->wLength);
if(status != kStatus_USB_Success)
{
return status;
}
/* Send controlRequest to upper layer */
status = USB_DeviceClassCallback(handle, (uint32_t)kUSB_DeviceEventVendorRequest, &controlRequest);
return status;
Case kUSB_DeviceClassEventClassRequest/USB_DEVICE_VIDEO_SET_REQUEST_INTERFACE in USB_DeviceVideoEvent() in usb_device_video.c
In function USB_DeviceVideoEvent() on usb_device_video.c in subcase USB_DEVICE_VIDEO_SET_REQUEST_INTERFACE of kUSB_DeviceClassEventClassRequest case I changed
case USB_DEVICE_VIDEO_SET_REQUEST_INTERFACE:
if (0U != controlRequest->isSetup)
{
/* Get the buffer to receive the data sent from the host. */
if ((NULL != videoHandle->configStruct) && (NULL != videoHandle->configStruct->classCallback))
{
/*ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit*/
error = videoHandle->configStruct->classCallback(
(class_handle_t)videoHandle, kUSB_DeviceVideoEventClassRequestBuffer, controlRequest);
}
}
break;
to
case USB_DEVICE_VIDEO_SET_REQUEST_INTERFACE:
if (0U != controlRequest->isSetup)
{
/* Get the buffer to receive the data sent from the host. */
if ((NULL != videoHandle->configStruct) && (NULL != videoHandle->configStruct->classCallback))
{
/*ClassCallback is initialized in classInit of s_UsbDeviceClassInterfaceMap,
it is from the second parameter of classInit*/
error = videoHandle->configStruct->classCallback(
(class_handle_t)videoHandle, kUSB_DeviceVideoEventClassRequestBuffer, controlRequest);
}
}
else
{
if (videoHandle->streamInterfaceNumber == interface_index)
{
error = USB_DeviceVideoVsRequest(videoHandle, controlRequest);
}
}
break;
Thank, regards,
M.P.