usb hid using lpc 1768

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

usb hid using lpc 1768

1,889 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by dipali on Tue Jun 03 00:09:21 MST 2014
I am using lpc1768 as usb hid device and have my own java code at pc side for user interface.I want to send/receive data to pc more than 64 bytes.I have changed keil sample program and I am able to out 512 bytes from HOST(pc) to HID(my LPC 1768 board).Also my HID (LPC 1768 can transmit) upto 64 bytes to HOST successfully. I have changed original code as follows
usb_cfg.h
<pre>
#define POWERDOWN_MODE_USB_WAKEUP0

#define USB_POWER           0
#define USB_IF_NUM          1
#define USB_EP_NUM          32
#define USB_MAX_PACKET0     64                        <----------------
#define USB_DMA             0
#define USB_DMA_EP          0x00000000

</pre>

changed size of in report buffer and out report buffer in demo.c
<pre>
demo.c.c
#defineOP_BUFFER_SIZE512
uint8_t InReport[OP_BUFFER_SIZE];                /* HID Input Report    */
                                            /*   Bit0   : Buttons  */
                                            /*   Bit1..7: Reserved */

uint8_t OutReport[OP_BUFFER_SIZE];                             /* HID Out Report      */

void SetOutReport (void) {
unsigned char ch;
  static unsigned long led_mask[] = { 1<<28, 1<<29, 1UL<<31, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6 };
  if (OutReport[15] < 'A')
  LPC_GPIO1->FIOPIN |= led_mask[1];
else
  LPC_GPIO1->FIOPIN &= ~led_mask[1];
memcpy(InReport,OutReport,sizeof(InReport));
for(ch = 0; ch < 64; ch++)
InReport[ch] = OutReport[ch + 248];     <--------------- for debugging only

}

</pre>

<pre>
usbdesc.c

#define HID_INPUT_REPORT_BYTES       64              /* size of report in Bytes */
#define HID_OUTPUT_REPORT_BYTES      64              /* size of report in Bytes */
#define HID_FEATURE_REPORT_BYTES     64              /* size of report in Bytes */

const uint8_t HID_ReportDescriptor[] = {
  HID_UsagePageVendor(0x00),
  HID_Usage(0x01),
  HID_Collection(HID_Application),

    HID_UsagePage(HID_USAGE_PAGE_KEYBOARD),      <------------
    HID_UsageMin(1),
    HID_UsageMax(200),
    HID_LogicalMin(1),
    HID_LogicalMax(200),                         <---------------I wnat values between 1 to 200
    HID_ReportCount(USB_MAX_PACKET0),            <-----------If i change this value to more than 64 bytes device not detected
    HID_ReportSize(8),                           <-----------data of 8 bytes
    HID_Input(HID_Data | HID_Variable | HID_Absolute),
  
//host output and controller input working
    HID_UsagePage(HID_USAGE_PAGE_LED),
    HID_Usage(HID_USAGE_LED_GENERIC_INDICATOR),
HID_LogicalMin(0),
    HID_LogicalMax(255),                         <--------------------
    HID_ReportCountS(OP_BUFFER_SIZE),//output data from host more than 255 bytes
HID_ReportSize(8),//field size 8 bits
    HID_Output(HID_Data | HID_Variable | HID_Absolute),
  HID_EndCollection,
};


const uint8_t USB_ConfigDescriptor[] = {
/* Configuration 1 */
  USB_CONFIGUARTION_DESC_SIZE,       /* bLength */
  USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
  WBVAL(                             /* wTotalLength */
    USB_CONFIGUARTION_DESC_SIZE +
    USB_INTERFACE_DESC_SIZE     +
    HID_DESC_SIZE               +
    USB_ENDPOINT_DESC_SIZE
  ),
  0x01,                              /* bNumInterfaces */
  0x01,                              /* bConfigurationValue */
  0x00,                              /* iConfiguration */
  USB_CONFIG_BUS_POWERED /*|*/       /* bmAttributes */
/*USB_CONFIG_REMOTE_WAKEUP*/,
  USB_CONFIG_POWER_MA(100),          /* bMaxPower */
/* Interface 0, Alternate Setting 0, HID Class */
  USB_INTERFACE_DESC_SIZE,           /* bLength */
  USB_INTERFACE_DESCRIPTOR_TYPE,     /* bDescriptorType */
  0x00,                              /* bInterfaceNumber */
  0x00,                              /* bAlternateSetting */
  0x01,                              /* bNumEndpoints */
  USB_DEVICE_CLASS_HUMAN_INTERFACE,  /* bInterfaceClass */
  HID_SUBCLASS_NONE,                 /* bInterfaceSubClass */
  HID_PROTOCOL_NONE,                 /* bInterfaceProtocol */
  0x04,                              /* iInterface */
/* HID Class Descriptor */
/* HID_DESC_OFFSET = 0x0012 */
  HID_DESC_SIZE,                     /* bLength */
  HID_HID_DESCRIPTOR_TYPE,           /* bDescriptorType */
  WBVAL(0x0100), /* 1.00 */          /* bcdHID */
  0x00,                              /* bCountryCode */
  0x01,                              /* bNumDescriptors */
  HID_REPORT_DESCRIPTOR_TYPE,        /* bDescriptorType */
  WBVAL(HID_REPORT_DESC_SIZE),       /* wDescriptorLength */
/* 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_MAX_PACKET0),//+USB_MAX_PACKET0+USB_MAX_PACKET0+USB_MAX_PACKET0+USB_MAX_PACKET0+USB_MAX_PACKET0+USB_MAX_PACKET0+USB_MAX_PACKET0),             /* wMaxPacketSize */
0x1,          /* 32ms */          /* bInterval */
/* Terminator */
  0                                  /* bLength */
};

</pre>

I want to go further and want to IN more than 64 bytes can anyone help me.
I have referred some forum but changing my code according to that cause problems like
1.If i change report descriptor sometimes HOST cannot detect the device
2.My java code goes goes for timeout while reading more than 64 bytes.


does Anyone know an application at PC side to verify my HID code?
Labels (1)
0 Kudos
Reply
1 Reply

1,138 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Tsuneo on Sun Jun 08 07:00:13 MST 2014

Quote:
I have changed keil sample program


Do you mean USBHID example in mcb1700.code_.bundle.lpc17xx.keil_.zip on this LPCware page?
MCB1700 Sample Code Bundle for LPC17xx Peripherals using Keil's MDK-ARM
http://www.lpcware.com/content/nxpfile/mcb1700-sample-code-bundle-lpc17xx-peripherals-using-keils-md...


Quote:
I am able to out 512 bytes from HOST(pc) to HID(my LPC 1768 board).Also my HID (LPC 1768 can transmit) upto 64 bytes to HOST successfully.


This HID example doesn’t have interrupt OUT endpoint (EP).
And then, the output report is transferred differently from the input report.
- output report: Set_Report request over the default EP
- input report: over the interrupt IN EP

As the handler for Set_Report request on the firmware allows greater transfer size, more than single packet (64 bytes), you may easily implement such large size of transfer. But for the transfer over the interrupt IN EP, the original code supposes just single packet.


Quote:
I want to go further and want to IN more than 64 bytes


Modify interrupt IN EP handler, so that it can process a sequence of packets.

usbuser.c

#define HID_INT_IN_EP_SIZE    64

uint32_t   hid_in_remain;
uint8_t *  hid_in_ptr;
uint32_t   hid_in_busy;

/*
 *  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 */
//    GetInReport();                      // <--- delete these two lines
//    USB_WriteEP(HID_EP_IN, &InReport, sizeof(InReport));

    hid_in_remain = 0;
    hid_in_busy = FALSE;
  }
}
#endif


/*
 *  USB Endpoint 1 Event Callback
 *   Called automatically on USB Endpoint 1 Event
 *    Parameter:       event
 */

void USB_EndPoint1 (uint32_t event) {
  uint32_t packet_len;

  switch (event) {
    case USB_EVT_IN:
      if ( hid_in_remain != 0 ) {
        packet_len = (hid_in_remain > HID_INT_IN_EP_SIZE) ? HID_INT_IN_EP_SIZE : hid_in_remain;
        USB_WriteEP(HID_EP_IN, hid_in_ptr, packet_len);
        hid_in_remain -= packet_len;
        hid_in_ptr    += packet_len;
      } else {
        hid_in_busy = FALSE;
      }
      break;
  }
}

uint32_t hid_send_in_report( uint8_t * buf, uint32_t size )
{
  if ( hid_in_busy ) return FALSE;
  hid_in_busy   = TRUE;
  hid_in_remain = size;
  hid_in_ptr    = buf;
  LPC_USB->EpIntSet = 1<< EPAdr( HID_EP_IN );   // force interrupt to call the ISR
  return TRUE;
}


To send an input report, call above hid_send_in_report()


Quote:
1.If i change report descriptor sometimes HOST cannot detect the device


I recommend you HID Descriptor Tool on the USB.org, instead of fiddling macros
http://www.usb.org/developers/hidpage/dt2_4.zip
The GUI of this tool is dull, but it can verify (parse) your report descriptor.
To output the report descriptor to a file,
- File menu > Save as > File type: header file
I believe this is the simplest report descriptor, which satisfies your requirement.
const uint8_t HID_ReportDescriptor[] = {
    0x06, 0x00, 0xff,              // USAGE_PAGE (Vendor Defined Page 1)
    0x09, 0x01,                    // USAGE (Vendor Usage  1)
    0xa1, 0x01,                    // COLLECTION (Application)
                                   // --- common globals ---
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x75, 0x08,                    //   REPORT_SIZE (8)
                                   // --- input report ---
    0x09, 0x01,                    //   USAGE (Vendor Usage  1)
    0x96, 0x00, 0x01,              //   REPORT_COUNT (256)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
                                   // --- output report ---
    0x09, 0x01,                    //   USAGE (Vendor Usage  1)
    0x96, 0x00, 0x02,              //   REPORT_COUNT (512)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
    0xc0                           // END_COLLECTION
};


Tsuneo
0 Kudos
Reply