Send I2C Commands to camera in Linux

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
RyTh_4740406
Level 1
Level 1
First like given

Would anyone know  how to pass an I2C command through V4L2 in a way that is equivalent to sending an I2C command via UVC in Windows? We want to make a GUI in QT on Linux that can have a “trigger” button. When pressed it will send I2C commands to the camera and represent a trigger.

Thank you,

Ryan

0 Likes
1 Solution

Hello Ryan,

The code snippet (of the host application)  shared by you can be implemented to send data to the UVC device via extension unit.

After the UVC device enumerates, the host application can be opened, get the handle of the appropriate  UVC device, and write_to_UVC_extension the needs to be called.

The buffer with the data can be sent through the extension unit by sending SET_CUR requests

01  04  55  35  D0  01  00  00 01  01 00

You can refer to the following links

librealsense: uvc-v4l2.cpp Source File

linux_camera_tool/uvc_extension_unit_ctrl.cpp at master · LI01/linux_camera_tool · GitHub

Note: As initially (during the enumeration), all the GET requests will be sen by the UVC driver addressing the extension unit control 0x10, each of those requests needs to be handled in the firmware.

You can test the firmware with the host application and let me know if some errors are seen. As mentioned in my previous response for debugging purpose or to check if the proper requests are sent by the host application, the debug prints can be added in the firmware.

Please let me know if any queries on this

Regards,

Rashi

Regards,
Rashi

View solution in original post

0 Likes
7 Replies
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

Hello Ryan,

To send a software trigger to the device from the host application UVC extension unit can be used. The Extension Unit is a method provided by the UVC specification to add vendor-specific building blocks to the specification.

For this, the device firmware should be modified to enable the UVC extension unit. The AN75779 firmware has a macro UVC_EXTENSION_UNIT. On enabling this macro the device will support the UVC extension unit. Necessary modifications will be required in the firmware to trigger the sensor on getting an extension unit request from the host.

Please refer to this weblink to understand more about Extension unit https://www.kernel.org/doc/html/v4.9/media/v4l-drivers/uvcvideo.html

KBA : FX3/CX3: UVC Extension Unit Application – KBA230466

Please let me know if any queries on this.

Regards,

Rashi

Regards,
Rashi
0 Likes

Hi RashiV_61,

Thank you for the information! If the UVC extension unit is enabled in the firmware, how would I go about writing to the extension unit using UVCIOC_CTRL_QUERY, with query=UVC_SET_CUR. unit=3, selector=0x10, and data as below:

01  04  55  35  D0  01  00  00 01  01 00

Would I be able to do this in QT? Do I need to modify the firmware? Any help on how to go about this process would be appreciated, thanks!

Best Regards,

Ryan

0 Likes

Hello Ryan,

Do I need to modify the firmware?

>>Please follow this KBA Implementing Extension Unit Control in AN75779 Example Project - KBA219280  for reference

The changes in the firmware:

- Extension unit needs to be enabled in the descriptor as mentioned in point 1 and 2 of the KBA

- The second change would be in uvc.c file (or main application file) where the requests sent from the host (through Extension Unit) needs to be handled.

From the KBA :

Terminal ID (of Extension Unit)  -  3    // 0x03,                              /* ID of this terminal */

Control selector - 0x01                           // #define CONTROL_IN_EXTENSION_UNIT (uint16_t) (0x0100)      // You can modify this as per you requirement

The data sent from the host can be received on the device via CY_FX_USB_UVC_SET_CUR_REQ where CyU3PUsbGetEP0Data is called to receive data through control endpoint.

>>You can share the firmware, after doing the above-mentioned changes, for us to verify.

You can refer to the firmware (with UVC extension Unit) attached to this application note https://www.cypress.com/documentation/application-notes/an75779-how-implement-image-sensor-interface...

Would I be able to do this in QT?

>> Unfortunately we do not have a sample QT application to communicate with the UVC extension Unit App. Please refer to  Download Linux Webcam Software - Qt Camera App  which supports Extension Unit control

Please let me know if any further queries on this

Regards,

Rashi

Regards,
Rashi

Thank you RashiV_61​!

When you say "The data sent from the host can be received on the device via CY_FX_USB_UVC_SET_CUR_REQ where CyU3PUsbGetEP0Data is called to receive data through control endpoint."

     - How would I get CY_FX_USB_UVC_SET_CUR_REQ to be called? I see in uvc.c it is in switch/cases. Do I need to edit the firmware's case where CY_FX_USB_UVC_SET_CUR_REQ gets called and send the data in there?

     - Or would I have to do it from an another program where for example I would do such (buffer would be the data in an array):

struct uvc_xu_control_query xu_query;

static void write_to_UVC_extension(int fd, int property_id, int length, unsigned char* buffer){

    CLEAR(xu_query);
    xu_query.unit = 3;               //has to be unit 3
    xu_query.query = UVC_SET_CUR;     //request code to send to the device
    xu_query.size = length;
    xu_query.selector = property_id; //0x10
    xu_query.data = buffer;          //control buffer
    if(ioctl(fd, UVCIOC_CTRL_QUERY, &xu_query) != 0)
        error_handle();
}

Also are the changes made in Implementing Extension Unit Control in AN75779 Example Project - KBA219280 for windows support and not Linux?

0 Likes
lock attach
Attachments are accessible only for community members.

Hello Ryan,

Please let me know if the data is to be sent from host > device or Device>Host.

The SET/GET requests will be sent from the host application.

In the firmware:

If the data is to be sent from device > host.

So, when GET_CUR request is sent from the host, the data can be sent in response to this request (from device > host)

case CY_FX_USB_UVC_GET_CUR_REQ:

                            CyU3PUsbSendEP0Data (5, (uint8_t *)glEp0Buffer);    \\ data to be sent from device to host

case CY_FX_USB_UVC_SET_CUR_REQ:

                  apiRetStatus = CyU3PUsbGetEP0Data (CY_FX_UVC_MAX_PROBE_SETTING_ALIGN glEp0Buffer, &readCount); \\ Data received form the host

Initially, you can just put some debug prints to check if the host is sending the requests addressing the extension unit and if the requests are proper then you can add the custom code to the firmware.

UVCHandleExtensionUnitRqts (

        void)

{

#ifdef UVC_EXTENSION_UNIT

    CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;

    uint16_t readCount;

    CyBool_t sendData = CyFalse;

;

#endif

    CyU3PDebugPrint(4, "wValue = %d , bRequest = %d\r\n",wValue,bRequest);

...}

Please find the attached Wirehshark traces (USB traces) which will give you the idea about the data transfers done via the UVC extension unit.

Note: The traces are taken where the firmware supports 11 controls. So initially some set of SET/GET requests will happen  (during the enumeration of the device) and later host application can talk to the device via Extension unit through SET/GET request.

Check packets from serial no: 2265

Regards,

Rashi

Regards,
Rashi

RashiV_61​,

The data is to be sent from the host to the device in order to simulate a trigger of the camera. Writing this data to the device should allow the camera to trigger:

01  04  55  35  D0  01  00  00 01  01 00

I believe all changes to the firmware that you have mentioned have been implemented. We are just struggling on how to write a console app in Linux in order to send that data to the device.

For example, a program that would simply enumerate the camera, and write the data to the extension unit, signaling a trigger inside the camera.

Thank you for all your help,

Ryan

0 Likes

Hello Ryan,

The code snippet (of the host application)  shared by you can be implemented to send data to the UVC device via extension unit.

After the UVC device enumerates, the host application can be opened, get the handle of the appropriate  UVC device, and write_to_UVC_extension the needs to be called.

The buffer with the data can be sent through the extension unit by sending SET_CUR requests

01  04  55  35  D0  01  00  00 01  01 00

You can refer to the following links

librealsense: uvc-v4l2.cpp Source File

linux_camera_tool/uvc_extension_unit_ctrl.cpp at master · LI01/linux_camera_tool · GitHub

Note: As initially (during the enumeration), all the GET requests will be sen by the UVC driver addressing the extension unit control 0x10, each of those requests needs to be handled in the firmware.

You can test the firmware with the host application and let me know if some errors are seen. As mentioned in my previous response for debugging purpose or to check if the proper requests are sent by the host application, the debug prints can be added in the firmware.

Please let me know if any queries on this

Regards,

Rashi

Regards,
Rashi
0 Likes