usbx
usbx copied to clipboard
I coudn't able to find uvc device class support sample application in usbx
Describe the bug Actually I am trying to give uvc device class support, I am looking for any sample application or any document to understand the flow of UVC.
Can anyone help on this.
Please also mention any information which could help others to understand the problem you're facing:
- I am using target board as cortex m55
- release version 6.2.0
To use UVC on device side, following things need to be done:
- Prepare descriptors (passed to stack as "framework"), .e.g., a simulated video camera:
/* Define device payloadwork. */
#define W(d) UX_DW0(d), UX_DW1(d)
#define DW(d) UX_DW0(d), UX_DW1(d), UX_DW2(d), UX_DW3(d)
#define GUID_YUY2 0x59,0x55,0x59,0x32, 0x00,0x00, 0x10,0x00, 0x80,0x00, 0x00,0xAA,0x00,0x38,0x9B,0x71 /* 32595559-0000-0010-8000-00AA00389B71 */
#define _DEVICE_DESCRIPTOR() \
/* --------------------------------------- Device Descriptor */ \
/* 0 bLength, bDescriptorType */ 18, 0x01, \
/* 2 bcdUSB */ W(0x200), \
/* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0xEF, 0x02, 0x01, \
/* 7 bMaxPacketSize0 */ 64, \
/* 8 idVendor, idProduct */ 0x84, 0x84, 0x01, 0x00, \
/* 12 bcdDevice */ UX_DW0(0x100),UX_DW1(0x100), \
/* 14 iManufacturer, iProduct, iSerialNumber */ 0, 0, 0, \
/* 17 bNumConfigurations */ 1,
#define _DEVICE_QUALIFIER_DESCRIPTOR() \
/* ----------------------------- Device Qualifier Descriptor */ \
/* 0 bLength, bDescriptorType */ 10, 0x06, \
/* 2 bcdUSB */ W(0x200), \
/* 4 bDeviceClass, bDeviceSubClass, bDeviceProtocol */ 0xEF, 0x02, 0x01, \
/* 7 bMaxPacketSize0 */ 8, \
/* 8 bNumConfigurations */ 1, \
/* 9 bReserved */ 0,
#define _CONFIGURE_DESCRIPTOR(total_len,n_ifc,cfg_v) \
/* -------------------------------- Configuration Descriptor */ \
/* 0 bLength, bDescriptorType */ 9, 0x02, \
/* 2 wTotalLength */ W(total_len), \
/* 4 bNumInterfaces, bConfigurationValue */ (n_ifc), (cfg_v), \
/* 6 iConfiguration */ 0, \
/* 7 bmAttributes, bMaxPower */ 0x80, 50,
#define _IAD_DESCRIPTOR(ifc_0,ifc_cnt,cls,sub,protocol) \
/* ------------------------ Interface Association Descriptor */ \
/* 0 bLength, bDescriptorType */ 8, 0x0B, \
/* 2 bFirstInterface, bInterfaceCount */ (ifc_0), (ifc_cnt), \
/* 4 bFunctionClass, bFunctionSubClass, bFunctionProtocol */ (cls), (sub), (protocol), \
/* 7 iFunction */ 0,
#define _INTERFACE_DESCRIPTOR(ifc,alt,n_ep,cls,sub,protocol) \
/* ------------------------------------ Interface Descriptor */ \
/* 0 bLength, bDescriptorType */ 9, 0x04, \
/* 2 bInterfaceNumber, bAlternateSetting */ (ifc), (alt), \
/* 4 bNumEndpoints */ (n_ep), \
/* 5 bInterfaceClass, bInterfaceSubClass, bInterfaceProtocol */ (cls), (sub), (protocol), \
/* 8 iInterface */ 0,
#define _ENDPOINT_DESCRIPTOR(addr,attr,pkt_siz,interval) \
/* ------------------------------------- Endpoint Descriptor */ \
/* 0 bLength, bDescriptorType */ 7, 0x05, \
/* 2 bEndpointAddress, bmAttributes */ (addr), (attr), \
/* 4 wMaxPacketSize, bInterval */ W(pkt_siz), (interval),
#define _VC_DESCRIPTORS_LEN (13+17+9+13)
#define _VC_DESCRIPTORS() \
/*--------------------------- Class VC Interface Descriptor (VC_HEADER). */ \
13, 0x24, 0x01, W(0x110), \
W(_VC_DESCRIPTORS_LEN), /* wTotalLength. */ \
DW(UX_DEMO_CLOCK_FREQUENCY), /* dwClockFrequency. */ \
1, /* bInCollection. */ \
1, /* BaInterfaceNr(1). */ \
/*--------------------------- Input Terminal (VC_INPUT_TERMINAL, Camera) */ \
17, 0x24, 0x02, \
0x01, /* bTerminalID, ITT_CAMERA */ \
W(0x201), /* wTerminalType */ \
0x00, 0x00, W(0), W(0), W(0), \
0x02, W(0), /* bControlSize, bmControls */ \
/*---------------------------- Output Terminal (VC_OUTPUT_TERMINAL, USB) */ \
9, 0x24, 0x03, \
0x02, /* bTerminalID */ \
W(0x0101), /* wTerminalType, TT_STREAMING */ \
0x00, 0x05/* bSourceID */, 0x00, \
/*--------------------------------- Processing Unit (VC_PROCESSING_UNIT) */ \
13, 0x24, 0x05, \
0x05, /* bUnitID */ \
0x01, /* bSourceID */ \
W(0), /* wMaxMultiplier */ \
3, 0x00, 0x00, 0x00, /* bControlSize, bmControls */ \
0, /* iProcessing */ \
0x00, /* bmVideoStandards */ \
#define _VS_FORMAT_DESCRIPTORS_UNCOMPRESSED_LEN (27+30)
#define _VS_FORMAT_DESCRIPTORS_UNCOMPRESSED() \
/*------------------------------- VS Format Descriptor (VS_FORMAT_UNCOMPRESSED) */ \
27, 0x24, 0x04, \
0x01, /* bFormatIndex */ \
0x01, /* bNumFrameDescriptors */ \
GUID_YUY2, /* YUY2 : YUV 4:2:2 */ \
16, /* bBitsPerPixel */ \
0x01, /* bDefaultFrameIndex */ \
0x00, 0x00, \
0x00, /* bmInterlaceFlags */ \
0x00, /* bCopyProtect */ \
/*--------------------------------- VS Frame Descriptor (VS_FRAME_UNCOMPRESSED) */ \
30, 0x24, 0x05, \
0x01, /* bFrameIndex */ \
0x00, /* bmCapabilities */ \
W(176), W(144), /* wWidth, wHeight */ \
DW(912384), DW(912384), /* dwMinBitRate, dwMaxBitRate */ \
DW(UX_DEMO_FRAME_DATA_SIZE), /* dwMaxVideoFrameBufSize */ \
DW(UX_DEMO_FRAME_INTERVAL), /* dwDefaultFrameInterval */ \
0x01, /* bFrameIntervalType */ \
DW(UX_DEMO_FRAME_INTERVAL), /* dwMinFrameInterval(1) */
#define _VS_IN_DESCRIPTORS_LEN (14+_VS_FORMAT_DESCRIPTORS_UNCOMPRESSED_LEN)
#define _VS_IN_DESCRIPTORS() \
/*------------------------- Class VS Header Descriptor (VS_INPUT_HEADER) */ \
14, 0x24, 0x01, \
0X01, /* bNumFormats */ \
W(_VS_IN_DESCRIPTORS_LEN), /* wTotalLength */ \
0x81, /* bEndpointAddress */ \
0x00, \
0x02, /* bTerminalLink */ \
0x00, /* bStillCaptureMethod */ \
0x00, 0x00, /* bTriggerSupport, bTriggerUsage */ \
0x01, 0x00, /* bControlSize, bmaControls */ \
_VS_FORMAT_DESCRIPTORS_UNCOMPRESSED()
#define _VS_OUT_DESCRIPTORS_LEN (11+_VS_FORMAT_DESCRIPTORS_UNCOMPRESSED_LEN)
#define _VS_OUT_DESCRIPTORS() \
/*------------------------- Class VS Header Descriptor (VS_OUTPUT_HEADER) */ \
11, 0x24, 0x02, \
0x01, /* bNumFormats */ \
W(_VS_OUT_DESCRIPTORS_LEN), /* wTotalLength */ \
0x02, /* bEndpointAddress */ \
0x00, \
0x03, /* bTerminalLink */ \
0x01, 0x00, /* bControlSize, bmaControls */ \
_VS_FORMAT_DESCRIPTORS_UNCOMPRESSED()
#define _CONFIGURE_DESCRIPTORS_LEN (9+ 8+ 9+_VC_DESCRIPTORS_LEN+ 9+_VS_IN_DESCRIPTORS_LEN+9+7)
#if UX_SLAVE_REQUEST_CONTROL_MAX_LENGTH < _CONFIGURE_DESCRIPTORS_LEN
#error Please increase control request buffer size
#endif
#if UX_SLAVE_REQUEST_DATA_MAX_LENGTH < UX_DEMO_MAX_PAYLOAD_SIZE
#error Please increase endpoint data buffer size
#endif
unsigned char device_payloadwork_full_speed[] = {
_DEVICE_DESCRIPTOR()
_CONFIGURE_DESCRIPTOR(_CONFIGURE_DESCRIPTORS_LEN,2,1)
_IAD_DESCRIPTOR(0,2,0x0E,0x03,0x00)
_INTERFACE_DESCRIPTOR(0,0,0,0x0E,0x01,0x00)
_VC_DESCRIPTORS()
_INTERFACE_DESCRIPTOR(1,0,0,0x0E,0x02,0x00)
_VS_IN_DESCRIPTORS()
_INTERFACE_DESCRIPTOR(1,1,1,0x0E,0x02,0x00)
_ENDPOINT_DESCRIPTOR(0x81,0x05,UX_DEMO_ENDPOINT_SIZE,UX_DEMO_ENDPOINT_INTERVAL_FS)
};
#define DEVICE_FRAMEWORK_LENGTH_FULL_SPEED sizeof(device_payloadwork_full_speed)
unsigned char device_payloadwork_high_speed[] = {
_DEVICE_DESCRIPTOR()
_DEVICE_QUALIFIER_DESCRIPTOR()
_CONFIGURE_DESCRIPTOR(_CONFIGURE_DESCRIPTORS_LEN,2,1)
_IAD_DESCRIPTOR(0,2,0x0E,0x03,0x00)
_INTERFACE_DESCRIPTOR(0,0,0,0x0E,0x01,0x00)
_VC_DESCRIPTORS()
_INTERFACE_DESCRIPTOR(1,0,0,0x0E,0x02,0x00)
_VS_IN_DESCRIPTORS()
_INTERFACE_DESCRIPTOR(1,1,1,0x0E,0x02,0x00)
_ENDPOINT_DESCRIPTOR(0x81,0x05,UX_DEMO_ENDPOINT_SIZE,UX_DEMO_ENDPOINT_INTERVAL_HS)
};
#define DEVICE_FRAMEWORK_LENGTH_HIGH_SPEED sizeof(device_payloadwork_high_speed)
- Setup video stream and video, e.g., for upper simulated camera:
/* Set the parameters for Video streams. */
video_stream_parameter[0].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_change = demo_video_write_change;
video_stream_parameter[0].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_payload_done = demo_video_write_done;
video_stream_parameter[0].ux_device_class_video_stream_parameter_max_payload_buffer_nb = UX_DEMO_PAYLOAD_BUFFER_NB;
video_stream_parameter[0].ux_device_class_video_stream_parameter_max_payload_buffer_size = UX_DEMO_MAX_PAYLOAD_SIZE;
video_stream_parameter[0].ux_device_class_video_stream_parameter_thread_entry = ux_device_class_video_write_thread_entry;
/* Set the parameters for Video device. */
video_parameter.ux_device_class_video_parameter_streams_nb = 1;
video_parameter.ux_device_class_video_parameter_streams = video_stream_parameter;
video_parameter.ux_device_class_video_parameter_callbacks.ux_slave_class_video_instance_activate = demo_video_instance_activate;
video_parameter.ux_device_class_video_parameter_callbacks.ux_slave_class_video_instance_deactivate = demo_video_instance_deactivate;
video_parameter.ux_device_class_video_parameter_callbacks.ux_device_class_video_request = demo_video_vc_request_process;
video_stream_parameter[0].ux_device_class_video_stream_parameter_callbacks.ux_device_class_video_stream_request = demo_video_vs_request_process;
/* Initialize the device Video class. This class owns interfaces starting with 0. */
status = ux_device_stack_class_register(_ux_system_device_class_video_name, ux_device_class_video_entry,
1, 0, &video_parameter);
callback.ux_device_class_video_stream_change
: callback invoked if host select interface alternate setting (0 to close video stream, other value to open video stream in specific data rate)
callbacks.ux_device_class_video_stream_payload_done
: callback invoked when a video frame is sent to host (example here is video camera)
_max_payload_buffer_nb
and _max_payload_buffer_size
: passed to stack to create a ring buffer to caching payloads, the size is usually the max possible isochronous endpoint size.
_thread_entry
: ux_device_class_video_write_thread_entry
for camera (device sending data to host).
At least stream request should be assigned, since application should handle some request (following the request is simply accepted, but in real application video parameters should be applied and returned in specific format):
UINT demo_video_vs_request_process(UX_DEVICE_CLASS_VIDEO_STREAM *stream, UX_SLAVE_TRANSFER *transfer)
{
UINT status = UX_ERROR;
UCHAR bRequest;
USHORT wValue_CS; /* In high byte. */
USHORT wLength;
UCHAR *data;
/* Decode setup packet. */
bRequest = transfer -> ux_slave_transfer_request_setup[UX_SETUP_REQUEST];
wValue_CS = transfer -> ux_slave_transfer_request_setup[UX_SETUP_VALUE + 1];
wLength = ux_utility_short_get(transfer -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH);
data = transfer -> ux_slave_transfer_request_data_pointer;
/* Check CS. */
switch(wValue_CS)
{
case UX_DEVICE_CLASS_VIDEO_VS_PROBE_CONTROL:
switch(bRequest)
{
case UX_DEVICE_CLASS_VIDEO_SET_CUR:
/* Simply accept without change setting. */
status = UX_SUCCESS;
break;
case UX_DEVICE_CLASS_VIDEO_GET_CUR:
case UX_DEVICE_CLASS_VIDEO_GET_MIN:
case UX_DEVICE_CLASS_VIDEO_GET_MAX:
/* Simply send our data back (first 26 bytes). */
/* Check request length. */
if (wLength < 26)
break;
/* Copy data for transfer. */
ux_utility_memory_copy(data, video_probe_commit_buffer, 26);
/* Transfer request. */
status = ux_device_stack_transfer_request(transfer, 26, wLength);
break;
default:
break;
}
break;
case UX_DEVICE_CLASS_VIDEO_VS_COMMIT_CONTROL:
/* Simply accept request. */
status = UX_SUCCESS;
break;
/* CS not supported now. */
default:
break;
}
return(status);
}
- After host activate the stream (change callback with none-zero alternate setting), in application payload buffer can be filled to streaming data,
ux_device_class_video_write_payload_get
is used to get data buffer to fill things andux_device_class_video_write_payload_commit
is used to commit the filled buffer. Background transfer is started onceux_device_class_video_transmission_start
is called. Once a payload is sent there is a callback to let application to fill more buffer .
static VOID demo_video_write_a_payload(UX_DEVICE_CLASS_VIDEO_STREAM *stream)
{
UCHAR *buffer;
ULONG buffer_length, length;
UX_DEVICE_CLASS_VIDEO_PAYLOAD_HEADER *header;
UCHAR *data;
UCHAR *frame_data;
/* If disabled, no write. */
if (video_payload_data_length == 0)
return;
/* Get payload buffer. */
ux_device_class_video_write_payload_get(stream, &buffer, &buffer_length);
header = (UX_DEVICE_CLASS_VIDEO_PAYLOAD_HEADER *)buffer;
data = buffer + UX_DEMO_PAYLOAD_HEADER_SIZE;
/* Get frame data buffer. */
frame_data = video_frame_buffer + video_frame_write_pos;
/* Calculate data length. */
length = video_frame_buffer_size - video_frame_write_pos;
if (length > video_payload_data_length)
length = video_payload_data_length;
/* Fill data. */
ux_utility_memory_copy(data, frame_data, length);
/* Fill payload header (no PTS nor SCR, total 10 bytes). */
header -> bHeaderLength = UX_DEMO_PAYLOAD_HEADER_SIZE;
header -> bmHeaderInfo.value = video_frame_count & 0x1; /* FID @ B0 */
header -> bmHeaderInfo.bm.bEOH = 1;
/* Move write pos. */
video_frame_write_pos += length;
if (video_frame_write_pos >= video_frame_buffer_size)
{
/* EOF. */
header -> bmHeaderInfo.bm.bEOF = 1;
video_frame_write_pos = 0;
/* A frame sent. */
video_frame_count ++;
}
/* Commit payload buffer. */
ux_device_class_video_write_payload_commit(stream, length + UX_DEMO_PAYLOAD_HEADER_SIZE);
}
VOID demo_video_write_change(UX_DEVICE_CLASS_VIDEO_STREAM *stream, ULONG alternate_setting)
{
INT i;
/* Stop video payload loop back if stream closed. */
if (alternate_setting == 0)
{
video_payload_data_length = 0;
return;
}
/* Payload data length: exclude header. */
video_payload_data_length = ux_device_class_video_max_payload_length(stream);
video_payload_data_length -= UX_DEMO_PAYLOAD_HEADER_SIZE;
/* Frame not started. */
video_frame_write_pos = 0;
/* Write buffers until achieve threadshold. */
for (i = 0; i < UX_DEMO_TRANSMIT_START_THRESHOLD; i ++)
demo_video_write_a_payload(stream);
ux_device_class_video_transmission_start(stream);
}
VOID demo_video_write_done(UX_DEVICE_CLASS_VIDEO_STREAM *stream, ULONG length)
{
/* Invoked when a payload sent to host, currently no use for loop back. */
(void)stream;
(void)length;
if (length)
{
/* A payload sent. */
video_payload_count ++;
/* Prepare next payload. */
demo_video_write_a_payload(stream);
}
}
Hi @xiaocq2001 , Thank you so much for detailed information.
Hi @xiaocq2001 ,
I have one doubt that, as you explained _max_payload_buffer_nb and _max_payload_buffer_size both the variables size would be same as Isochrnous endpoint size..? if I give both sizes as Isocronous endpoint size, class registration was failing because it requires almost 1MB memory, i have less memory on my device. memory_size = stream -> ux_device_class_video_stream_payload_buffer_size * stream_parameter -> ux_device_class_video_stream_parameter_max_payload_buffer_nb; Could you please confirm that.
Thanks Mahesh Avula
_buffer_size is max endpoint size, _buffer_nb is number of payloads buffered.
Thank you so much @xiaocq2001
Hi @xiaocq2001 ,
Note: 1
Below are descriptors for video class driver which i have prepared, with these descriptors, Isochrnous endpoint is not creating because of this endpoint is associated with video stream interface with alternate setting =1, I have gone through code and found that my device not getting UX_SET_INTERFACE request from host machine(Ubuntu 18.04)
Could you please help on this issue, if i am doing anything wrong here.
UCHAR device_framework_high_speed[] = {
/*
Device descriptor 18 bytes
0x00 bDeviceClass: base class, the class code will be defining in interface descriptor
*/
0x12, 0x01, 0x00, 0x00,
0xEF, 0x02, 0x01, 0x40,
0x25, 0x05, 0xa7, 0xa4,
0x00, 0x01, 0x01, 0x02,
0x03, 0x01,
/* Configuration descriptor 9 bytes */
0x09, 0x02, 0xb5, 0x00, 0x02, 0x01, 0x00, 0xC0, 0x01,
/* Interface association descriptor */
0x08, 0x0b, 0x00,
0x02, 0x0E, 0x03, 0x00, 0x00,
/* interface_descriptor UVC_control */
0x09, 0x04, 0x00, 0x00, 0x01, 0x0E, 0x01, 0x00, 0x00,
/* Class-specific VC Interface Header Descriptor */
0x0d,0x24,0x01,0x10,0x01,0x34,0x00,0x00,0x00,0x00,0x00,0x01, 0x01,
/* Input Terminal (VC_INPUT_TERMINAL, Camera) */
0x11,0x24,0x02,0x01,0x01,0x02,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,
/* Output Terminal (VC_OUTPUT_TERMINAL, USB) */
0x09, 0x24, 0x03, 0x02,0x01,0x01,0x00,0x05,0x00,
/* Processing Unit (VC_PROCESSING_UNIT) */
0x0d, 0x24, 0x05,0x05,0x01,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,
/* interrupt endpoint_descriptor for uvc_control 7 bytes */
0x07,0x05,0x83,0x03,0x08,0x00,0x08,
/* Interface Descriptor for UVC streaming where altsetting = 0 */
0x09, 0x04, 0x01, 0x00, 0x00, 0x0e, 0x02, 0x00, 0x00,
/* Class Video streaming input Header Descriptor (VS_INPUT_HEADER) */
0x0e,0x24,0x01,0x01,0x47,00,0x81,0x00,0x02,0x00,0x00,0x00,0x01,0x00,
/* VS Format Descriptor (VS_FORMAT_UNCOMPRESSED) */
0x1b,0x24,0x04,0x01,0x01,0x59,0x55,0x59,0x32, 0x00,0x00, 0x10,0x00, 0x80,0x00, 0x00,0xAA,0x00,0x38,0x9B,0x71,0x10,0x01,0x00,0x00,0x00,0x00,
/* VS Frame Descriptor (VS_FRAME_UNCOMPRESSED) */
0x1e,0x24, 0x05,0x01, 0x00,0x00,0x1e,0x00,0x1e,0x00,0xec,0x0d,0x00,0x00,0xec,0x0d,0x00,0x00,0x8c,0x0a,0x00,0x00,0x64,0x00,0x00,0x01,0x00,0x64,0x00,0x00,
/* Interface Descriptor for UVC streaming where altsetting = 1 */
0x09, 0x04, 0x01, 0x01, 0x01, 0x0e, 0x02, 0x00, 0x00,
/* Isochronous IN endpoint descriptor for UVC streaming */
0x07, 0x05, 0x85, 0x05, 0x00, 0x04, 0x01,
}
Note: 2
When I run my application I have collected dmesg logs at host side(ubuntu18.04) and attaching here. node has not created for video class driver in /dev/ directory.
[18159350.110416] usb 1-4.4.4.2: new high-speed USB device number 78 using xhci_hcd [18159350.210765] usb 1-4.4.4.2: config 1 interface 1 altsetting 1 endpoint 0x85 has an invalid bInterval 0, changing to 7 [18159350.211131] usb 1-4.4.4.2: New USB device found, idVendor=0525, idProduct=a4a7 [18159350.211132] usb 1-4.4.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [18159350.211133] usb 1-4.4.4.2: Product: Devkit [18159350.211134] usb 1-4.4.4.2: Manufacturer: AlifSemiconductor [18159350.211152] usb 1-4.4.4.2: SerialNumber: 1200 [18159350.274379] uvcvideo: Found UVC 1.10 device Devkit (0525:a4a7) [18159360.538136] uvcvideo: UVC non compliance - GET_DEF(PROBE) not supported. Enabling workaround. [18159365.657965] uvcvideo: Failed to query (129) UVC probe control : -110 (exp. 34). [18159365.657966] uvcvideo: Failed to initialize the device (-5).
Regards, Mahesh
[18159360.538136] uvcvideo: UVC non compliance - GET_DEF(PROBE) not supported. Enabling workaround. [18159365.657965] uvcvideo: Failed to query (129) UVC probe control : -110 (exp. 34). [18159365.657966] uvcvideo: Failed to initialize the device (-5).
It seems the UVC requests are not handled correctly. From the log, GET_DEF(PROBE) is requested but not answered correctly. Please check the VS request callback (demo_video_vs_request_process in previous example), maybe you can try to handle GET_DEF, like following:
switch(wValue_CS)
{
case UX_DEVICE_CLASS_VIDEO_VS_PROBE_CONTROL:
switch(bRequest)
{
case UX_DEVICE_CLASS_VIDEO_SET_CUR:
/* Simply accept without change setting. */
status = UX_SUCCESS;
break;
case UX_DEVICE_CLASS_VIDEO_GET_DEF: // <- when GET_DEF requsted
case UX_DEVICE_CLASS_VIDEO_GET_CUR:
case UX_DEVICE_CLASS_VIDEO_GET_MIN:
case UX_DEVICE_CLASS_VIDEO_GET_MAX:
/* Simply send our data back (first 26 bytes). */
Hi @xiaocq2001 , Thank you so much for your inputs,
Actually VS request callback is not getting invoking because VS request callback get invoke only when UX_SET_INTERFACE request comes from the host machine, but here my device not getting UX_SET_INTERFACE request.
could you please explain that when device suppose to get UX_SET_INTERFACE from host.
Regards Mahesh Avula
Usually UX_SET_INTERFACE is received when there is host application using the video camera, e.g., open a camera application that can preview the video input.
@xiaocq2001 , Thank you for the quick replay.
Is host application for receive video stream data from device..?,
Yes. When host application starts receiving video stream data, the alternate setting is selected to indicate consuming USB bus bandwidth, then the ISO transfer starts to transfer video stream. When host application stops receiving video stream the interface alternate setting is back to 0 to reduce USB bus bandwidth consumed.
@xiaocq2001 , got it and thank you so much,
But still I have some doubt that as per the usbx stack When UX_SET_INTERFACE request comes from host then only Isochronous endpoint will be created and VS request callback get invoked , demo_video_vs_request_process will set the probe control and commit control right..?
Once this process is completed then device will start send video streaming data to the host right..?
could you please correct above points.
Regards Mahesh Avula
Usually host set alternate setting to 0 and use VS request to probe control and commit control. Then host set interface to expected alternate setting and streaming data.
Hi @xiaocq2001 ,
Got it and thank you so much.
Hi @xiaocq2001 ,
host setting alternate setting to 0 and VS request callback getting invoking to probe control and commit control,
I can see these two requests UX_DEVICE_CLASS_VIDEO_GET_DEF and UX_DEVICE_CLASS_VIDEO_GET_CUR, my device is receiving from host.
UINT demo_video_vs_request_process(UX_DEVICE_CLASS_VIDEO_STREAM *stream, UX_SLAVE_TRANSFER *transfer) {
UINT status = UX_ERROR; UCHAR bRequest; USHORT wValue_CS; /* In high byte. */ USHORT wLength; UCHAR *data;
/* Decode setup packet. */
bRequest = transfer -> ux_slave_transfer_request_setup[UX_SETUP_REQUEST];
wValue_CS = transfer -> ux_slave_transfer_request_setup[UX_SETUP_VALUE + 1];
wLength = ux_utility_short_get(transfer -> ux_slave_transfer_request_setup + UX_SETUP_LENGTH);
data = transfer -> ux_slave_transfer_request_data_pointer;
/* Check CS. */
switch(wValue_CS)
{
case UX_DEVICE_CLASS_VIDEO_VS_PROBE_CONTROL:
switch(bRequest)
{
case UX_DEVICE_CLASS_VIDEO_SET_CUR:
/* Simply accept without change setting. */
status = UX_SUCCESS;
break;
case UX_DEVICE_CLASS_VIDEO_GET_CUR:
case UX_DEVICE_CLASS_VIDEO_GET_MIN:
case UX_DEVICE_CLASS_VIDEO_GET_MAX:
/* Simply send our data back (first 26 bytes). */
/* Check request length. */
if (wLength < 26)
break;
/* Copy data for transfer. */
ux_utility_memory_copy(**data**, video_probe_commit_buffer, 26);
**here, what is the video_probe_commit_buffer ..? also we are not passing data pointer to any function below, could you please explain this**
/* Transfer request. */
status = ux_device_stack_transfer_request(transfer, 26, wLength);
break;
default:
break;
}
break;
case UX_DEVICE_CLASS_VIDEO_VS_COMMIT_CONTROL:
/* Simply accept request. */
status = UX_SUCCESS;
break;
/* CS not supported now. */
default:
break;
}
return(status);
}
could you please help on this
Regards Mahesh Avula
This is my testing data for you to reference:
/* APP specific probe/commit settings. */
static UCHAR video_probe_commit_buffer[48] = {
W(0x0000), /* bmHint */
1, /* bFormatIndex */
1, /* bFrameIndex */
DW(UX_DEMO_FRAME_INTERVAL), /* dwFrameInterval */
W(0), /* wKeyFrameRate */
W(0), /* wPFrameRate */
W(0), /* wCompQuality */
W(0), /* wCompWindowSize */
W(0), /* wDelay */
DW(UX_DEMO_FRAME_DATA_SIZE), /* dwMaxVideoFrameSize */
DW(UX_DEMO_MAX_PAYLOAD_SIZE), /* dwMaxPayloadTransferSize */
DW(UX_DEMO_CLOCK_FREQUENCY), /* dwClockFrequency */
0x03, /* bmFramingInfo */
1, /* bPreferedVersion */
1, /* bMinVersion */
1, /* bMaxVersion */
0, /* bUsage */
0, /* bBitDepthLuma */
0x00, /* bmSettings */
0, /* bMaxNumberOfRefFramesPlus1 */
W(0x0000), /* bmRateControlModes */
W(0), W(0), W(0), W(0) /* bmLayoutPerStream */
};
For details about the structure and fields, please refer to USB Video spec.
@xiaocq2001 , Thank you so much, We need to send this structure info to the host when probe and commit request comes right..? could you please share usbx video class driver sample application, so that it will be easy to understand,
Hi @xiaocq2001 , My device is enumerated at host and created node (/dev/video0)for it, I really thank you for your support.
One doubt that, from where ux_device_class_video_write_thread_entry get invoke, and could you please share any azure usbx documents for video stream data tranfer flow.
Regards Mahesh Avula
ux_device_class_video_write_thread_entry
is passed to stack to start a thread to send data in FIFO to host, the FIFO is created from parameters passed in register function.
When you need to add data to FIFO, use ux_device_class_video_write_payload_get
to get buffer to fill and use ux_device_class_video_write_payload_commit
to commit to transfer.
BTW, which board are you working on for now?
Hi @xiaocq2001, Thanks for your support, I am using ASIC Board(with arm coretx m55 processor). I was bit struggling to write video class application , earlier I have given support for CDC-ACM class support and that was working fine.
Regards Mahesh Avula
Hi @xiaocq2001 ,
Is there any open source host application for UVC driver to validate, or could you please suggest how the host application would be..?
Regards Mahesh
Here is an example (on ST NUCLEO-H723ZG) that you can reference: https://github.com/STMicroelectronics/x-cube-azrtos-h7/tree/main/Projects/NUCLEO-H723ZG/Applications/USBX/Ux_Device_Video
Hi @xiaocq2001 ,
Thank you so much for all your inputs
Hi @xiaocq2001 ,
I am using host application as VLC media player to stream the data from the device, but device not receiving SET_INTERFACE request with the alternate setting is selected to 1.
I have observed one thing at host side while running VLC media player , i have collected dmesg logs that i am posting here.
[20125207.047025] usb 1-4.4.4.2: new high-speed USB device number 65 using xhci_hcd [20125207.147717] usb 1-4.4.4.2: New USB device found, idVendor=0525, idProduct=a4a7 [20125207.147719] usb 1-4.4.4.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3 [20125207.147720] usb 1-4.4.4.2: Product: Devkit [20125207.147721] usb 1-4.4.4.2: Manufacturer: AlifSemiconductor [20125207.147722] usb 1-4.4.4.2: SerialNumber: 1200 [20125207.272416] uvcvideo: Found UVC 1.10 device Devkit (0525:a4a7) [20125207.644515] input: Devkit as /devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4.4/1-4.4.4/1-4.4.4.2/1-4.4.4.2:1.0/input/input36 [20125207.650508] kauditd_printk_skb: 8 callbacks suppressed [20125207.650511] audit: type=1400 audit(1680155724.219:25407): apparmor="DENIED" operation="open" profile="snap.notepad-plus-plus.notepad-plus-plus" name="/sys/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4.4/1-4.4.4/1-4.4.4.2/busnum" pid=18819 comm="winedevice.exe" requested_mask="r" denied_mask="r" fsuid=1002 ouid=0 [20125207.721901] audit: type=1400 audit(1680155724.291:25408): apparmor="DENIED" operation="open" profile="snap.notepad-plus-plus.notepad-plus-plus" name="/sys/devices/pci0000:00/0000:00:14.0/usb1/1-4/1-4.4/1-4.4.4/1-4.4.4.2/busnum" pid=18819 comm="winedevice.exe" requested_mask="r" denied_mask="r" fsuid=1002 ouid=0 [20125330.019469] uvcvideo: Failed to set UVC probe control : -110 (exp. 34). [20125335.139257] uvcvideo: Failed to set UVC commit control : -110 (exp. 34). [20125340.259294] uvcvideo: Failed to set UVC probe control : -110 (exp. 34). [20125345.379047] uvcvideo: Failed to set UVC probe control : -110 (exp. 34). [20125345.782295] uvcvideo: Failed to set UVC probe control : -71 (exp. 34). [20125345.785626] uvcvideo: Failed to set UVC probe control : -71 (exp. 34). [20125345.785684] uvcvideo: Failed to set UVC probe control : -71 (exp. 34). root@alif:/home/mahesh#
Could you please help on this.
Regards Mahesh Avula
[20125330.019469] uvcvideo: Failed to set UVC probe control : -110 (exp. 34). [20125335.139257] uvcvideo: Failed to set UVC commit control : -110 (exp. 34). [20125340.259294] uvcvideo: Failed to set UVC probe control : -110 (exp. 34). [20125345.379047] uvcvideo: Failed to set UVC probe control : -110 (exp. 34). [20125345.782295] uvcvideo: Failed to set UVC probe control : -71 (exp. 34). [20125345.785626] uvcvideo: Failed to set UVC probe control : -71 (exp. 34). [20125345.785684] uvcvideo: Failed to set UVC probe control : -71 (exp. 34). I usually test video device under windows. But from upper log, it seems host send probe requests to device but fail. Maybe you can check if the VS control request callback in application is called and correct answer is reported to host.
Hi @xiaocq2001 , Thank you for your inputs
[20125330.019469] uvcvideo: Failed to set UVC probe control : -110 (exp. 34). [20125335.139257] uvcvideo: Failed to set UVC commit control : -110 (exp. 34). [20125340.259294] uvcvideo: Failed to set UVC probe control : -110 (exp. 34). [20125345.379047] uvcvideo: Failed to set UVC probe control : -110 (exp. 34). [20125345.782295] uvcvideo: Failed to set UVC probe control : -71 (exp. 34). [20125345.785626] uvcvideo: Failed to set UVC probe control : -71 (exp. 34). [20125345.785684] uvcvideo: Failed to set UVC probe control : -71 (exp. 34).
These errors I have resolved, now i could see video probe control requests and commit control requests are comming also device also responding back to host.
Host application as VLC media player sending UX_SET_INTERFACE request after(video probe control requests and commit control) with the alternate setting is selected to 0, but host app suppose to send UX_SET_INTERFACE request with the alternate setting is selected to 1. I am attching screenshot for reference.
.
could you please help on this.
Regards Mahesh Avula
Hi @xiaocq2001 ,
One more thing I have observed that when we run host application as VLC media player , I could see below error that to not immediatly after running VLC media player after some time this error is comming.
could you please help on this.
Regards Mahesh Avula
Hi @xiaocq2001 ,
I am have tested usb video class driver on window machine and used host application as VLC media player, sending UX_SET_INTERFACE request after(video probe control requests and commit control) with the alternate setting is selected to 0, but host app suppose to send UX_SET_INTERFACE request with the alternate setting is selected to 1 to use USB bandwidth to stream data. I would say that behaviour of my application is same on Windows machine as well as Linux machine, could you please help on this to move further, I am not understanding where it's going wrong.
Regards Mahesh Avula
Here is something under windows for you to reference:
The USB traces as a whole:
Get Cur/Max/Min content:
@xiaocq2001 , Thank you so much for your inputs.