1 Reply Latest reply on Nov 16, 2017 11:12 PM by decai.wang_2529456

    UVC and hid compositive device is unstable!

    decai.wang_2529456

      Dear SIr,

       

      I add hid  device to my CX3 UVC  code based  on Memo_CX3_UVC_HID_ButtonTrigger.zip.  I can see compositive device on my WIN10 system and also may send KEY to PC occasionally.

       

      But I found it is unstable, and then I review MouseDemo provided by SDK1.3.3 and add some error-recovery code, but it still cannot be stable

       

      1:  before UVC appstart is called, (amcap is not started) , gpio event  occurs and the first 'x' can be sent without error ,but no 'x' char is received by PC

       

      and in the following gpio event, HID key function is not working, ' Get Buffer 1 Failed  69', 69 is x045,that means ,

       

      CY_U3P_ERROR_TIMEOUT,               /**< Timeout on relevant operation. */

       

       

      2: after amcap is started , and video appears, gpio event occurs, the "x" char can be seen(I open a txt file, 'x" can be seen when I push the button), and then

       

      if amcap  is close, the hid key function ,return Get Buffer 1 Failed  69 again!

       

      3. Then when amcap is restarted, amcap is not working,no video appear, maybe HID error also destroy UVC state machine.

       

      4. HID endpoint and dma channel are created in CyCx3UvcAppInit(); which is started before main thread running.

       

       

      Can you give me some advice? the following code sections are much similar with CX3_UVC_HID_ButtonTrigger.zip. and add extra error recovery codes based on MouseDemo app provided by SDK1.3.3.

       

      Best regards!

       

      David

       

      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

       

      CyU3PDmaBuffer_t buf_p;

      uint8_t KeyBuf[6] ={0};

       

      uint32_t My_Hid_SendKey(uint8_t keybuf[])

      {

                CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

                status = CyU3PDmaChannelGetBuffer (&glChHandleHID, &buf_p, 1000);// see SDK1.3.3 mousedemo

                if (status != CY_U3P_SUCCESS)

                {    

                    CyU3PDebugPrint (4,"Get Buffer 1 Failed %x \n\r",status); //mady: Get the current buffer of the DMA Channel

       

       

                    CyU3PDmaChannelReset (&glChHandleHID); // see SDK1.3.3 mousedemo

                    CyU3PDmaChannelSetXfer (&glChHandleHID, 0); // see SDK1.3.3 mousedemo

       

       

                    status = CyU3PDmaChannelGetBuffer (&glChHandleHID, &buf_p, 1000);// see SDK1.3.3 mousedemo

                   if (status != CY_U3P_SUCCESS)

                        return status;

                    // esUVCAppErrorHandler (status);

                 }

                CyU3PThreadSleep (63);

               buf_p.buffer[0]=0x00;

               buf_p.buffer[1]=0x00;

               buf_p.buffer[2]=0x1b; //mady: Fill the contents of the buffer to send character 'x'

       

       

               buf_p.buffer[3]=0x00; //mady: 6 key press can be sent at a time. Here we send 'x' alone for key press.

               buf_p.buffer[4]=0x00; //0x1B is the code for 'x' (taken from HID usage table) we set the rest 5 key presses as none.

               buf_p.buffer[5]=0x00;

               buf_p.buffer[6]=0x00;

               buf_p.buffer[7]=0x00;

       

       

               status = CyU3PDmaChannelCommitBuffer (&glChHandleHID, 8, 0); //send 'x' to PC

               if (status != CY_U3P_SUCCESS)

               {

                    CyU3PDebugPrint (4,"Commit Buffer 1 Failed %x \n\r",status);   // see SDK1.3.3 mousedemo

                    CyU3PDmaChannelReset (&glChHandleHID); // see SDK1.3.3 mousedemo

                   CyU3PDmaChannelSetXfer (&glChHandleHID, 0); // see SDK1.3.3 mousedemo

               //return status;

              //     esUVCAppErrorHandler (status);

               }

               else{

                    //After sending 'x', we should tell the PC has the Key has been released. Other wise it will continuously print 'x'

                    status = CyU3PDmaChannelGetBuffer (&glChHandleHID, &buf_p, 1000); // see SDK1.3.3 MouseDemo

                   if (status != CY_U3P_SUCCESS)

                   {

                         CyU3PDebugPrint (4,"Get Buffer 2 Failed %x \n\r",status);

                         CyU3PDmaChannelReset (&glChHandleHID);

                         CyU3PDmaChannelSetXfer (&glChHandleHID, 0);

       

       

                            status = CyU3PDmaChannelGetBuffer (&glChHandleHID, &buf_p, 1000); // see SDK1.3.3 MouseDemo

                            if (status != CY_U3P_SUCCESS)

                                return status;

       

       

          //return status;

             // esUVCAppErrorHandler (status);

             }

              buf_p.buffer[0]=0x00;

                buf_p.buffer[1]=0x00;

                buf_p.buffer[2]=0x00;

                buf_p.buffer[3]=0x00;

                buf_p.buffer[4]=0x00; //Buffer with all zeros to tell PC that no key is pressed and all keys are released

                buf_p.buffer[5]=0x00;

                buf_p.buffer[6]=0x00;

                buf_p.buffer[7]=0x00;

       

       

                status = CyU3PDmaChannelCommitBuffer (&glChHandleHID, 8, 0);

                if (status != CY_U3P_SUCCESS)

                {

                     CyU3PDebugPrint (4,"Commit Buffer 2 Failed %x \n\r",status);

                     CyU3PDmaChannelReset (&glChHandleHID);

                     CyU3PDmaChannelSetXfer (&glChHandleHID, 0);

                //return status;

                //     esUVCAppErrorHandler (status);

                }

           }

          return status;

      }

       

       

      ////////////////////////////////////////////////////////////////////////////////////////////

      // HID Dmacallback, it seems just printing debug info

      //////////////////////////////////////////////////////////////////////////////////////////

      void

      CyFxHIDDmaCallback (

              CyU3PDmaChannel   *chHandle, /* Handle to the DMA channel. */

              CyU3PDmaCbType_t  type,      /* Callback type.             */

              CyU3PDmaCBInput_t *input)    /* Callback status.           */

      {

                CyU3PDmaBuffer_t buf_p;

                CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

       

       

                CyU3PDebugPrint (4, "CONS");

                CyU3PDebugPrint (1,"%d",cnt);

                CyU3PThreadSleep (64);

      //

      //     CyU3PThreadSleep (1000);

      //     CyU3PDeviceReset (0);

      //status = CyU3PDmaChannelGetBuffer (chHandle, &buf_p, CYU3P_NO_WAIT);

      // status = CyU3PDmaChannelCommitBuffer (chHandle, 8, 0);

      }

      /////////////////////////////////////////////////////////////////////////////////

      // HID endpoint  dma channel reate

      /////////////////////////////////////////////////////////////////////////////////

       

      #ifdef HID

              endPointConfig.enable = 1;

          endPointConfig.epType = CY_U3P_USB_EP_INTR;

          endPointConfig.pcktSize = 64;

          endPointConfig.isoPkts  = 0; /* KYS: Was 1 */

          endPointConfig.streams = 0 ;

          endPointConfig.burstLen = 1; /* KYS: Added */

       

          /* Configure the Endpoint */

          status = CyU3PSetEpConfig(0x85,&endPointConfig);

          if (status != CY_U3P_SUCCESS)

          {

          /* Error Handling */

          CyU3PDebugPrint (4, "USB Set Endpoint config failed, Error Code = %d\n",status);

          //CyFxAppErrorHandler(status);

          }

          else

          {

          CyU3PDebugPrint (2,"HID EP Created\n\r");

          }

       

          CyU3PUsbFlushEp (0x85);

       

          dmaCfg1.size = 64;

          dmaCfg1.count = 2;

          dmaCfg1.prodSckId = CY_U3P_CPU_SOCKET_PROD;

          dmaCfg1.consSckId = CY_U3P_UIB_SOCKET_CONS_5;

          dmaCfg1.dmaMode = CY_U3P_DMA_MODE_BYTE;

          dmaCfg1.notification = CY_U3P_DMA_CB_CONS_EVENT;   //Create a DMA Channel Betwwen CPU and USB to send Keyboard data to PC

          dmaCfg1.cb = CyFxHIDDmaCallback;

          dmaCfg1.prodHeader = 0;

          dmaCfg1.prodFooter = 0;

          dmaCfg1.consHeader = 0;

          dmaCfg1.prodAvailCount = 0;

       

       

          status = CyU3PDmaChannelCreate (&glChHandleHID,

                     CY_U3P_DMA_TYPE_MANUAL_OUT, &dmaCfg1);

       

       

          if (status != CY_U3P_SUCCESS)

          {

             CyU3PDebugPrint (4, "CyU3PDmaChannelCreateHID failed, Error code = %d %d\n", status,glChHandleHID.state);

             CyU3PDebugPrint(4, "  %x  ",glDmaSocketCtrl[CyU3PDmaGetIpNum (CY_U3P_UIB_SOCKET_CONS_0 | HID_EP)][CyU3PDmaGetSckNum (CY_U3P_UIB_SOCKET_CONS_0 | HID_EP)].singleHandle);

             CyCx3UvcAppErrorHandler (status);

          }

          else

          {

          CyU3PDebugPrint (2,"HID DMA Created\n\r");

          }

          status = CyU3PDmaChannelSetXfer (&glChHandleHID, 0);

          if (status != CY_U3P_SUCCESS)

                   {

          CyCx3UvcAppErrorHandler (status);

              }

         #endif