7 Replies Latest reply on Aug 11, 2020 9:57 PM by RashiV_61

    Send I2C Commands to camera in Linux

    RyTh_4740406

      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

        • 1. Re: Send I2C Commands to camera in Linux
          RashiV_61

          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

           

          • 2. Re: Send I2C Commands to camera in Linux
            RyTh_4740406

            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

            • 3. Re: Send I2C Commands to camera in Linux
              RashiV_61

              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-using-ez-usb-fx3-us…

               

               

              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

               

               

               

               

               

               

              • 4. Re: Send I2C Commands to camera in Linux
                RyTh_4740406

                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?

                • 5. Re: Send I2C Commands to camera in Linux
                  RashiV_61

                  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

                  • 6. Re: Send I2C Commands to camera in Linux
                    RyTh_4740406

                    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

                    • 7. Re: Send I2C Commands to camera in Linux
                      RashiV_61

                      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