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

LPC2148 USB HID problem

Hello, I have USB HID sample from NXP (ics.nxp.com/.../an10736.zip) and it work fine. Problem is the number of USB_HID_REPORT_OUT. When I set USB_HID_REPORT_OUT 1 it is working fine and data is recieved from OutReport[0].
Then I set USB_HID_REPORT_OUT 3 and when I need to read data from OutReport[1], then readed data are 0x00. When I look to the comunication with USBTrace, I see, that the data is sended from PC (0x01,0xF0,0x0F), but in OutReport[1] it isn't (it si 0x00). Have you got any idea, where is problem? Is here someone, who tested this sample?

Parents Reply Children
  • dear friends,

    I able to work with SetReport Out and In sucessfully;

    In my application PC will send some comnd say "START" and after that i(device) supposed to send around 2000 bytes through USB HID.

    can this is possible?
    how can i do this.

    one thing i notice that USB_HID_REPORT_IN and USB_HID_REPORT_OUT should have same number.
    is it right or i am making some mistake.

    thanks

  • > can this is possible?

    Yes we can :-)

    On the device side, an input report greater than 64 bytes is split into 64 bytes packets, and sent over the interrupt IN endpoint in turn. On the PC app, the entire report is retrieved with one "read" call.

    > one thing i notice that USB_HID_REPORT_IN and USB_HID_REPORT_OUT should have same number.
    > is it right or i am making some mistake.

    The size of input and output reports are independently defined in the report descriptor.



    1) Descriptors
    The report descriptor and the IN endpoint descriptor are modified, as follows,

    usbdesc.c
    #define HID_ReportCountS(x)   0x96,(x&0xFF),((x>>8)&0xFF)   // for 0x100 - 0xFFFF
    
    /* HID Report Descriptor */
    const BYTE HID_ReportDescriptor[] = {
      HID_UsagePageVendor(0x00),
      HID_Usage(0x01),
      HID_Collection(HID_Application),
        // ---------------- common globals ---------------
        HID_LogicalMin(0),
        HID_LogicalMaxS(255),
        HID_ReportSize(8),
        // ---------------- input report   ---------------
    #if USB_HID_REPORT_IN <= 0xFF
        HID_ReportCount(USB_HID_REPORT_IN),
    #else
        HID_ReportCountS(USB_HID_REPORT_IN),
    #endif
        HID_Usage(HID_USAGE_GENERIC_UNDEFINED),
        HID_Input(HID_Data | HID_Variable | HID_Absolute),
        // ---------------- output report  ---------------
        HID_ReportCount(USB_HID_REPORT_OUT),
        HID_Usage(HID_USAGE_GENERIC_UNDEFINED),
        HID_Output(HID_Data | HID_Variable | HID_Absolute),
      HID_EndCollection,
    };
    
    
    
    #define USB_MAX_PACKET_SIZE   64
    
    #if USB_HID_REPORT_IN > USB_MAX_PACKET_SIZE
      #define USB_HID_IN_EP_SIZE  USB_MAX_PACKET_SIZE
    #else
      #define USB_HID_IN_EP_SIZE  USB_HID_REPORT_IN
    #endif
    
    /* USB Configuration Descriptor */
    const BYTE USB_ConfigDescriptor[] = {
      ...
      ...
    /* Endpoint, HID Interrupt In */
      USB_ENDPOINT_DESC_SIZE,         /* bLength */
      USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType */
      USB_ENDPOINT_IN(1),             /* bEndpointAddress */
      USB_ENDPOINT_TYPE_INTERRUPT,    /* bmAttributes */
      WBVAL(USB_HID_IN_EP_SIZE),      /* wMaxPacketSize */   // <-------
      USB_HID_IN_INTERVAL,            /* bInterval - polling interval*/
      ...
      ...
    };
    

    2) Query - Reply over HID endpoints
    The original example puts input report repeatedly.
    We modify it, so that the input report is sent as reply, just when query comes over output report (either Set_Report( output ) or interrupt OUT EP). The large input report is split into 64 bytes packets.

    demo_delphi.c
    
    WORD hid_input_sent;         // holds next send position on the InReport[]
    
    void SendInputSplit( void ); // prototype
    
    /*
     *  Set HID Output Report <- OutReport. This function should be
     * defined by the user
     */
    
    void SetOutReport (void) {
    //   IOPIN1 = (IOPIN1 & ~LEDMSK) | (OutReport[0] << 16);
    
      switch ( OutReport[0] ) {
        case START:
          //
          // fill InReport[] with data here
          //
          hid_input_sent = 0;                             // send the first packet for reply
          SendInputSplit();
          break;
    
        default: break;
      }
    }
    
    void SendInputSplit( void )
    {
      WORD packet_size;
    
      if ( hid_input_sent >= USB_HID_REPORT_IN ) return;  // check if the last packet is sent or not
      packet_size = USB_HID_REPORT_IN - hid_input_sent;   // split into USB_MAX_PACKET_SIZE
      if ( packet_size > USB_MAX_PACKET_SIZE ) {
        packet_size = USB_MAX_PACKET_SIZE;
      }
      USB_WriteEP( 0x81, InReport + hid_input_sent, (BYTE)packet_size );
      hid_input_sent += packet_size;
    }
    
    
    
    usbuser.c
    /*
     *  USB Set Configuration Event Callback
     *   Called automatically on USB Set Configuration Request
     */
    
    #if USB_CONFIGURE_EVENT
    void USB_Configure_Event (void) {
    
      if (USB_Configuration) {                  /* Check if USB is configured */
           // comment these two lines, to stop continuous input report over the interrupt IN EP
    //    (*inptr)();
    //    USB_WriteEP(0x81, &InReport[0], USB_HID_REPORT_OUT);
    
        hid_input_sent = USB_HID_REPORT_IN;     // initialize USB context
      }
    }
    #endif
    
    
    
    /*
     *  USB Endpoint 1 Event Callback
     *   Called automatically on USB Endpoint 1 Event
     *    Parameter:       event
     */
    
    void USB_EndPoint1 (DWORD event) {
    
      switch (event) {
        case USB_EVT_IN:
           // comment these two lines, to stop continuous input report over the interrupt IN EP
    //      (*inptr)();
    //      USB_WriteEP(0x81, &InReport[0], USB_HID_REPORT_IN);
    
          SendInputSplit();                // send the second and later packet
          break;
    
        case USB_EVT_OUT:
          USB_ReadEP(0x01, &OutReport[0]);
          (*outptr)();
          break;
      }
    }
    

    Tsuneo

  • Thanks Tsuneo Chinzei,

    sorry for replying late; i were busy in my sisters wedding and not able to reply.

    I tried as per your instruction. it is working.
    but i having some doubt.

    in my application InReport[90]. USB_HID_REPORT_IN = 63
    my intention to read 90 bytes from device to PC.
    when sending "START" from PC to device.

    i got help from your concept.

    but i need to poll from PC side after every interval to get remainig bytes after once "START" or SetOutReport.

    I am using Keil's Utility HID_Client (VC++ 6 application) came with ARM toolchain. i alter it as per my need.

    again after every time polling it gives same data.
    that "hid_input_sent" gives only 63 bytes. not further bytes after polling it again.

    if you give me ur mail id. i will send you my entire workspace LPC2148 and VC++.

    thanks again for your valuable time.

  • Thanks Tsuneo Chinzei,

    sorry for replying late; i were busy in my sisters wedding and not able to reply.

    I tried as per your instruction. it is working.
    but i having some doubt.

    in my application InReport[90]. USB_HID_REPORT_IN = 63
    my intention to read 90 bytes from device to PC.
    when sending "START" from PC to device.

    i got help from your concept.

    but i need to poll from PC side after every interval to get remainig bytes after once "START" or SetOutReport.

    I am using Keil's Utility HID_Client (VC++ 6 application) came with ARM toolchain. i alter it as per my need.

    again after every time polling it gives same data.
    that "hid_input_sent" gives only 63 bytes. not further bytes after polling it again.

    if you give me ur mail id. i will send you my entire workspace LPC2148 and VC++.

    thanks again for your valuable time.

  • Thanks Tsuneo Chinzei,

    sorry for replying late; i were busy in my sisters wedding and not able to reply.

    I tried as per your instruction. it is working.
    but i having some doubt.

    in my application InReport[90]. USB_HID_REPORT_IN = 63
    my intention to read 90 bytes from device to PC.
    when sending "START" from PC to device.

    i got help from your concept.

    but i need to poll from PC side after every interval to get remainig bytes after once "START" or SetOutReport.

    I am using Keil's Utility HID_Client (VC++ 6 application) came with ARM toolchain. i alter it as per my need.

    again after every time polling it gives same data.
    that "hid_input_sent" gives only 63 bytes. not further bytes after polling it again.

    if you give me ur mail id. i will send you my entire workspace LPC2148 and VC++.

    thanks again for your valuable time.