Handle format change on UVC

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Handle format change on UVC

1,212 Views
MassimilianoPegaso
Contributor II

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.

Labels (1)
0 Kudos
Reply
4 Replies

1,179 Views
jingpan
NXP TechSupport
NXP TechSupport

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

1,173 Views
MassimilianoPegaso
Contributor II

Hi @jingpan,

thank you for your reply, I checked the USB traffic with wireshark and I think that the host send the correct command.

Immagine 2022-11-22 100855.png

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.

0 Kudos
Reply

1,153 Views
jingpan
NXP TechSupport
NXP TechSupport

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

0 Kudos
Reply

1,141 Views
MassimilianoPegaso
Contributor II

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.

0 Kudos
Reply