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

USB superspeed peripherals Forum Discussions

LuRi_4048741
Level 1
Level 1

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);

        //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);

        //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

0 Likes
1 Solution
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

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

Regards,
Rashi

View solution in original post

0 Likes
1 Reply
Rashi_Vatsa
Moderator
Moderator
Moderator
5 likes given 500 solutions authored 1000 replies posted

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

Regards,
Rashi
0 Likes