Implementing Extension Unit Control in AN75779 Example Project - KBA219280

Version: **

 

Question:

How to implement Extension Unit control in the example project associated with AN75779?

 

Answer:

The Extension Unit is a method provided by the UVC specification to add vendor-specific building blocks to the specification.

Make the following modifications in example project associated with AN75579:

  1. Update the 16 byte GUID field of Extension Unit Descriptor in the cyfxuvcdscr.c file with the GUID generated using Visual Studio: Go to Tools > Create GUID. In the pop-up window, choose Registry Format. A GUID will be generated in the Result field.
  2. Update the Number of controls in this terminal field of Extension Unit Descriptor in the cyfxuvcdscr.c file depending on the number of Extension Unit controls to be implemented. Accordingly, update the bmControls field, which is a bitmap of the Extension Unit controls implemented. As an example, to implement four Extension Unit controls, the following is the Extension Unit Descriptor:  

    /* Extension Unit Descriptor */

      

            0x1C,                              /* Descriptor size */

      

            0x24,                              /* Class specific interface desc type */

      

            0x06,                              /* Extension Unit Descriptor type */

      

            0x03,                              /* ID of this terminal */

      

            0xB8,0x19,0x77,0x02                     /* 16 byte GUID. A unique GUID generated using
                                                                       Visual Studio has to be updated in this field*/

      

            0x7F,0xB0,0x67,0x45,

      

            0x88,0xB1,0x20,0x34,

      

            0x36,0xAD,0xBE,0x5D,

      

            0x04,                              /* Number of controls in this terminal */

      

            0x01,                              /* Number of input pins in this terminal */

      

            0x02,                              /* Source ID : 2 : Connected to Proc Unit */

      

            0x03,                              /* Size of controls field for this terminal : 3 bytes */

      

            0x0F,0x00,0x00,             /* bmControls */

      

            0x00,                              /* String desc index : Not used */

  3.  

    SET_CUR, GET_CUR requests for Extension Unit controls have to be handled in the UVCHandleExtensionUnitRqts() function of the uvc.c file. 

      

    For example:

      

    #define CONTROL_IN_EXTENSION_UNIT (uint16_t) (0x0100)

      

    static uint8_t current_value_extension_unit_control;

      

                 /* Handler for control requests addressed to the Extension Unit */

      

    static void UVCHandleExtensionUnitRqts (void)

      

    {

      

         CyU3PReturnStatus_t apiRetStatus = CY_U3P_SUCCESS;

      

         uint16_t readCount;

      

            switch(wValue) {

      

             case CONTROL_IN_EXTENSION_UNIT :

      

                 switch(bRequest) {

      

                    case CY_FX_USB_UVC_GET_DEF_REQ:

      

                    case CY_FX_USB_UVC_GET_MIN_REQ:

      

                      glEp0Buffer[0] = 1;

      

                      CyU3PUsbSendEP0Data (1, (uint8_t *)glEp0Buffer);

      

                    break;

      

                    case CY_FX_USB_UVC_GET_RES_REQ:

      

                         glEp0Buffer[0] = 1;

      

                         CyU3PUsbSendEP0Data (1, (uint8_t *)glEp0Buffer);

      

                    break;

      

                    case CY_FX_USB_UVC_GET_MAX_REQ:

      

                      glEp0Buffer[0] = 50;

      

                      CyU3PUsbSendEP0Data (1, (uint8_t *)glEp0Buffer);

      

                    break;

      

                    case CY_FX_USB_UVC_GET_CUR_REQ:

      

                                    glEp0Buffer[0] = current_value_extension_unit_control;

      

                      CyU3PUsbSendEP0Data (1, (uint8_t *)glEp0Buffer);

      

                    break;

      

                    case CY_FX_USB_UVC_GET_LEN_REQ:

      

                      glEp0Buffer[0] = 0x01;

      

                      glEp0Buffer[1] = 0x00;

      

                      CyU3PUsbSendEP0Data (2, (uint8_t *)glEp0Buffer);

      

                    break;

      

                    case CY_FX_USB_UVC_GET_INFO_REQ:

      

                        glEp0Buffer[0] = 3;                        /* GET/SET requests are supported. */

      

                        CyU3PUsbSendEP0Data (1, (uint8_t *)glEp0Buffer);

      

                    break;

      

                    case CY_FX_USB_UVC_SET_CUR_REQ:

      

                      apiRetStatus = CyU3PUsbGetEP0Data (CY_FX_UVC_MAX_PROBE_SETTING_ALIGNED,

      

                                                  glEp0Buffer, &readCount);

      

                      if (apiRetStatus == CY_U3P_SUCCESS) {

      

                          current_value_extension_unit_control = glEp0Buffer[0];

      

                      }

      

                             break;

      

               default:

      

                             CyU3PUsbStall (0, CyTrue, CyFalse);

      

                    break;

      

                    }

      

             break;

      

     default:

      

                 CyU3PUsbStall (0, CyTrue, CyFalse);

      

             break;

      

               }

      

    }

In addition to these firmware changes, you should modify the Host Application code.

For the Host Application code to implement UVC Extension Unit, refer to the following link from Microsoft:

https://msdn.microsoft.com/en-us/windows/hardware/drivers/stream/uvc-extension-unit-code-samples