1 Reply Latest reply on Oct 1, 2020 11:33 PM by RashiV_61

    HID application not recognized when adding button support

    LuRi_4048741

      Hello everyone,

       

      I am doing an HID using FX3 micro. This application gets coordinates data from an I2C device. I used as a base MouseDemo project provided by SDK examples under Installation folder - \Cypress\EZ-USB FX3 SDK\1.3\firmware\hid_examples\cyfx3_hid. At first, I used the exact same descriptors as the example but I changed X and Y coordinate input from Relative to Absolute on the Report descriptor, as seen here:

       

      /* HID Report Descriptor */

      const uint8_t CyFxUSBReportDscr[] __attribute__ ((aligned (32))) =

      {

          0x05,0x01,                      /* Usage Page (Generic Desktop) */

          0x09,0x02,                      /* Usage (Mouse) */

          0xA1,0x01,                      /* Collection (Application) */

          0x09,0x01,                      /* Usage (Pointer) */

          0xA1,0x00,                      /* Collection (Physical) */

          0x05,0x01,                      /* Usage Page (Generic Desktop) */

          0x09,0x30,                      /* Usage (X) */

          0x09,0x31,                      /* Usage (Y) */   

          0x15,0x00,                      /* Logical Minimum (0) */

          0x25,0x7F,                      /* Logical Maximum (127) */

          0x75,0x08,                      /* Report Size (8) */       

          0x95,0x02,                      /* Report Count (2) */

          0x81,0x02,                      /* Input (Data, Value, Relative, Bit Field)  ------->>>> Changed here from 0x81,0x06 to 0x81 to 0x06*/

          0xC0,                           /* End Collection */

          0xC0                            /* End Collection */

      };

       

      For this descriptor, I had this Send_report function (very similar to the one on the example):

       

      /* Send Reports containing pre-defined patterns to Host through interrupt EP */

      CyU3PReturnStatus_t

      CyFxHidSendReport (

              void)

      {

          CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

          CyU3PDmaBuffer_t    outBuf;

          uint16_t i = 0;

       

       

          outBuf.buffer = 0;

          outBuf.status = 0;

          outBuf.size   = 2;

          outBuf.count  = 2;

       

       

          CyU3PDebugPrint (4, "Input Report \r\n");

       

       

          /* Loop until whole data is sent to Host */

          do

          {

              /* Retrieve Free Buffer */

              status = CyU3PDmaChannelGetBuffer (&glChHandleIntrCPU2U, &outBuf, 1000);

              if (status != CY_U3P_SUCCESS)

              {

                  CyU3PDmaChannelReset (&glChHandleIntrCPU2U);

                  CyU3PDmaChannelSetXfer (&glChHandleIntrCPU2U, 0);

       

       

                  status = CyU3PDmaChannelGetBuffer (&glChHandleIntrCPU2U, &outBuf, 1000);

                  if (status != CY_U3P_SUCCESS)

                      return status;

              }

                     

              /* Copy Report Data into the output buffer */

              //outBuf.buffer[0] = (uint8_t)(glMouseData[i]);

              //outBuf.buffer[1] = (uint8_t)(glMouseData[i + 1]);

       

       

              outBuf.buffer[0] = (uint8_t)(x);

              outBuf.buffer[1] = (uint8_t)(y);

       

       

              status = CyU3PDmaChannelCommitBuffer (&glChHandleIntrCPU2U, 2, 0);

              if (status != CY_U3P_SUCCESS)

              {

                  CyU3PDmaChannelReset (&glChHandleIntrCPU2U);

                  CyU3PDmaChannelSetXfer (&glChHandleIntrCPU2U, 0);

              }

       

       

              /* Wait for 2 msec after sending each packet */

              CyU3PDebugPrint (4, "Packet %d Status %d\r\n", i, status);               

              CyU3PBusyWait (2000);

       

       

              i += 2;

          }while (i != 2);

       

       

          return status;

      }

       

      This will give me the behavior I wanted as it moved the mouse cursor to the absolute coordinates the I2C device sent. Under device manager when using Windows, I see the device as follows:

       

       

       

      After trying that, I wanted to add click functionality to the already working mouse. For this, I changed the report descriptor to be like this:

       

      /* HID Report Descriptor */

      const uint8_t CyFxUSBReportDscr[] __attribute__ ((aligned (32))) =

      {

          0x05,0x01,                      /* Usage Page (Generic Desktop) */

          0x09,0x02,                      /* Usage (Mouse) */

          0xA1,0x01,                      /* Collection (Application) */

          0x09,0x01,                      /* Usage (Pointer) */

          0xA1,0x00,                      /* Collection (Physical) */

          0x05,0x09, /* Usage Page (button)*/

          0x19,0x01, /* Usage minimum (Button 1)*/

          0x29,0x03, /* Usage maximum (Button 3)*/

          0x15,0x00, /* Logical minimum (0)*/

          0x25,0x01, /* Logical maximum (1)*/

          0x95,0x03, /* Report count (3)*/

          0x75,0x01, /* Report size (1)*/

          0x81,0x02, /* Input (Data, Variable, Absolute)*/

          0x95,0x01, /* Report count(1)*/

          0x75,0x05, /* Report size(5)*/

          0x81,0x02, /* Input (Constant, Variable, Absolute)*/

          0x05,0x01,                      /* Usage Page (Generic Desktop) */

          0x09,0x30,                      /* Usage (X) */

          0x09,0x31,                      /* Usage (Y) */

          0x15,0x00,                      /* Logical Minimum (0) */

          0x25,0x7F,                      /* Logical Maximum (127) */

          0x75,0x08,                      /* Report Size (8) */

          0x95,0x02,                      /* Report Count (2) */

          0x81,0x02,                      /* Input (Data, Value, Relative, Bit Field) */

          0xC0,                           /* End Collection */

          0xC0                            /* End Collection */

      };

       

      For my understanding, now I have to send three bytes in this format:

       

       

      So my Send_Report function look like this:

       

       

      CyU3PReturnStatus_t

      CyFxHidSendReport (

              void)

      {

          CyU3PReturnStatus_t status = CY_U3P_SUCCESS;

          CyU3PDmaBuffer_t    outBuf;

          uint16_t i = 0;

       

          outBuf.buffer = 0;

          outBuf.status = 0;

          outBuf.size   = 4;

          outBuf.count  = 3;

       

          CyU3PDebugPrint (4, "Input Report \r\n");

       

          /* Loop until whole data is sent to Host */

          do

          {

              /* Retrieve Free Buffer */

              status = CyU3PDmaChannelGetBuffer (&glChHandleIntrCPU2U, &outBuf, 1000);

              if (status != CY_U3P_SUCCESS)

              {

                  CyU3PDmaChannelReset (&glChHandleIntrCPU2U);

                  CyU3PDmaChannelSetXfer (&glChHandleIntrCPU2U, 0);

       

       

                  status = CyU3PDmaChannelGetBuffer (&glChHandleIntrCPU2U, &outBuf, 1000);

                  if (status != CY_U3P_SUCCESS)

                      return status;

              }

       

       

              //CyU3PMemSet(outBuf.buffer , 0, 10);

              /* Copy Report Data into the output buffer */

              //outBuf.buffer[0] = (uint8_t)(glMouseData[i]);

              //outBuf.buffer[1] = (uint8_t)(glMouseData[i + 1]);

       

       

              outBuf.buffer[0] = (uint8_t)(0x01);

              outBuf.buffer[1] = (uint8_t)(x);

              outBuf.buffer[2] = (uint8_t)(y);

       

       

              status = CyU3PDmaChannelCommitBuffer (&glChHandleIntrCPU2U, 3, 0);

              if (status != CY_U3P_SUCCESS)

              {

                  CyU3PDmaChannelReset (&glChHandleIntrCPU2U);

                  CyU3PDmaChannelSetXfer (&glChHandleIntrCPU2U, 0);

              }

       

       

              /* Wait for 2 msec after sending each packet */

              CyU3PDebugPrint (4, "Packet %d Status %d\r\n", i, status);               

              CyU3PBusyWait (2000);

       

       

              i += 2;

          }while (i != 2);

       

       

          return status;

      }

       

      But when I flash the firmware, the device is seen like this:

       

       

      And shows this error:

       

       

      No movement is seen at all with this firmware.

       

      Attached you will find both projects. The program with no button support is "HID_touch-NoButton-Support.zip" and the program with no-working button support is "HID_touch-NoWorking-ButtonSupport.zip". I would really appreciate some help. Let me know if you need more information.

       

      Thanks,

      Luis

        • 1. Re: HID application not recognized when adding button support
          RashiV_61

          Hello Luis,

           

          Please modify the HID descriptors as follows:

          /* HID Descriptor (Mouse) */

              0x09,                          /* Descriptor size */

              CY_FX_USB_HID_DESC_TYPE,        /* Descriptor Type */

              0x10,0x11,                      /* HID Class Spec 11.1 */

              0x00,                          /* Target Country */

              0x01,                          /* Total HID Class Descriptors */

              0x22,                          /* Report Descriptor Type */

              0x32,0x00,                      /* Total Length of Report Descriptor */                // Length of report descriptors is 50 bytes

           

           

           

          Also, change the code in the cyfx3hid.c

                  /* Class specific descriptors such as HID Report descriptor need to handled by the callback. */

                  bReqType = ((setupdat0 & CY_U3P_USB_VALUE_MASK) >> 24);

                  if ((bRequest == CY_U3P_USB_SC_GET_DESCRIPTOR) && (bReqType == CY_FX_GET_REPORT_DESC))

                  {

                      isHandled = CyTrue;

           

                      status = CyU3PUsbSendEP0Data (0x32, (uint8_t *)CyFxUSBReportDscr);

                      if (status != CY_U3P_SUCCESS)

                      {

                          /* There was some error. We should try stalling EP0. */

                          CyU3PUsbStall(0, CyTrue, CyFalse);

                      }

           

          After these changes, you might get error code 10 with "A nonconstant main item was declared without a corresponding usage."

          This is caused because usage needs to be associated with the inputs that are declared as variable

          This error is caused because of this descriptor field 0x81,0x02, /* Input (Constant, Variable, Absolute)*/

          changing it to 0x81,0x01, /* Input (Constant, Variable, Absolute)*/ will solve the problem

           

           

           

          Regards,

          Rashi