- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Rashi