This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

USBHID InReport more than a single byte

Hi everyone!

I've read lots of threads on this forum (with lot of Tsuneo Chinzei's really interesting posts) about this issue, but I'm still stuck with a problem.
I'm using an NXP LPC1788. I've tested the USBHID demo with HIDClient.exe on the PC side. Everything works fine.
I've wrote a simple C++ console program that made a single write/read operation, based on HIDClient.exe code, and everything is fine again.
Now, I need to send/receive 8 bytes instead of a single one. I've started modifying firmware and sofware, following hints on this forum, and at the end I'm able to output 8 bytes, but not to get 8 byte in input.

I've changed the HID_ReportDescriptor structure like this:

const uint8_t HID_ReportDescriptor[] = {
  HID_UsagePageVendor(0x00),
  HID_Usage(0x01),
  HID_Collection(HID_Application),
  HID_UsagePage(HID_USAGE_PAGE_DEV_CONTROLS),
  HID_LogicalMin(0),
  HID_LogicalMax(255),
  HID_ReportCount(8),
  HID_ReportSize(8),
  HID_Usage(1),
  HID_Input(HID_Data | HID_Variable | HID_Absolute),
  HID_UsagePage(HID_USAGE_PAGE_DEV_CONTROLS),
  HID_Usage(1),
  HID_LogicalMin(0),
  HID_LogicalMax(255),
  HID_ReportCount(8),
  HID_ReportSize(8),
  HID_Output(HID_Data | HID_Variable | HID_Absolute),
  HID_EndCollection,
};


I've redefined the InReport and OutReport variables as arrays of size 8, that will be copied/pasted on the EP0Buf array using a for loop (in single byte mode it's a simple assignation).
I didn't change the wMaxPacketSize in the USB_ConfigDescriptor (so it's set to 4), because changing the value causes error in the output process, too.

Here is the source of the C++ console application that perform a single write/read:

#define MSG_SIZE      9

#include <windows.h>
#include <stdio.h>
#include "HID.h"

int main()
{
  BYTE outReport[MSG_SIZE];
  BYTE inReport[IN_MSG_SIZE];
  DWORD cnt;
  int totDevices;
  char  buf[256];

  outReport[0] = 0;
  inReport [0] = 0;

  // Check for all connected devices
  HID_Init();
  totDevices = HID_FindDevices();
  printf("%d Devices found\n", totDevices);
  if(totDevices < 1)
  {
    return 1;
  }
  for(int i = 0; i < totDevices; i++) {
    if (!HID_GetName(i, buf, sizeof(buf))) {
      sprintf(buf, "Device %d", i);
    }
    printf("%d: %s\n", i, buf);
  }

  // Open the first device
  printf("Open device 0...");
  if(!HID_Open(0))
  {
    printf("Can't open device 0\n");
    return 2;
  }
  printf("OK\n");

  // Perform a write test
  printf("Write test...");
  outReport[1] = 0;
  if(!HID_Write(outReport, MSG_SIZE*sizeof(BYTE), &cnt))
  {
    printf("write error\n");
    return 3;
  }
  printf("OK\n");

  // Perform a read test
  printf("Read test...");
  if(!HID_Read(inReport, IN_MSG_SIZE*sizeof(BYTE), &cnt))
  {
    printf("read error\n");
    return 4;
  }
  printf("OK\n");

  // Close device
  printf("Close device...");
  HID_Close();
  HID_UnInit();
  printf("OK");

  return 0;

}


Write process goes well.
The software get locked during the read process.

I've tested the firmware with the SimpleHIDWrite.exe tool and it works fine. So it seems more a software problem than a firmware one.

What could be worng?
Is there someone that was able to tx/rx more that a single byte using a C++ interface?
And is it correct to use arrays of size FIRMWARE_SIZE+1 on the software side? (HIDClient.exe uses arrays of size 2 to tx/rx a single byte. If I define arrays of size 8, write and read process fails, but didn't lock)

Thank to everyone!
Massimo

0