#include stdio.h #include stdlib.h #include unistd.h #include string.h #include strings.h #include signal.h #include errno.h #include fcntl.h #include pthread.h #include sys/types.h #include sys/wait.h #include sys/stat.h #include sys/ipc.h #include sys/sem.h #include sys/shm.h #include sys/msg.h #include sys/socket.h #include arpa/inet.h #include <linux/hiddev.h> #include <sys/ioctl.h> #include <time.h> typedef uint8_t u8; typedef int8_t s8; typedef uint16_t u16; typedef int16_t s16; typedef uint32_t u32; typedef int32_t s32; int termflag=1; /* path es del tipo "/dev/usb/hiddevN" */ int hidOpen(char * path) { return open(path, O_RDWR); } int hidClose(int fd) { return close(fd); } int hidGetVendorProduct(int fd, u16 * vid, u16 * pid) { struct hiddev_devinfo hidinfo; if(ioctl(fd, HIDIOCGDEVINFO, &hidinfo)<0) { perror("hid-ioctl-devinfo"); return -1; } *vid = hidinfo.vendor; *pid = hidinfo.product; return 0; } int hidGetStringDesc(int fd, int index, char * s) { struct hiddev_string_descriptor devstr; devstr.index = index; if(ioctl(fd, HIDIOCGSTRING, &devstr)<0) { perror("hid-ioctl-string"); return -1; } strncpy(s, devstr.value, HID_STRING_SIZE); return 0; } int hidGetInReport(int fd, uint8_t * data, int len) { struct hiddev_report_info rinfo; struct hiddev_field_info finfo; struct hiddev_usage_ref uref; int i,j,ret; rinfo.report_type = HID_REPORT_TYPE_INPUT; rinfo.report_id = HID_REPORT_ID_FIRST; ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo); if(ret<0) { perror("hid-ioctl-inrepinfo"); return -1; } // Get Fields for (i = 0; i < rinfo.num_fields; i++) { finfo.report_type = rinfo.report_type; finfo.report_id = rinfo.report_id; finfo.field_index = i; ioctl(fd, HIDIOCGFIELDINFO, &finfo); // Get usages printf("(IN Max Usage: %d) ", finfo.maxusage); //si len es menor que finfo.maxusage, leer solamente len bytes if(len < finfo.maxusage) finfo.maxusage = len; for (j = 0; j < finfo.maxusage; j++) { uref.report_type = finfo.report_type; uref.report_id = finfo.report_id; uref.field_index = i; uref.usage_index = j; ioctl(fd, HIDIOCGUCODE, &uref); ioctl(fd, HIDIOCGUSAGE, &uref); data[j] = uref.value; } } return finfo.maxusage; } int hidSetOutReport(int fd, uint8_t * data, int len) { struct hiddev_usage_ref uref; struct hiddev_report_info rinfo; struct hiddev_field_info finfo; int i,j,ret; rinfo.report_type = HID_REPORT_TYPE_OUTPUT; rinfo.report_id = HID_REPORT_ID_FIRST; ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo); if(ret<0) { perror("hid-ioctl-outrepinfo"); return -1; } // Get Fields for (i = 0; i < rinfo.num_fields; i++) { finfo.report_type = rinfo.report_type; finfo.report_id = rinfo.report_id; finfo.field_index = i; ioctl(fd, HIDIOCGFIELDINFO, &finfo); // Get usages printf("(OUT Max Usage: %d) ", finfo.maxusage); // si len es menor a finfo.maxusage, mando len bytes y completo con ceros if(len < finfo.maxusage) finfo.maxusage = len; for (j = 0; j < finfo.maxusage; j++) { uref.report_type = finfo.report_type; uref.report_id = finfo.report_id; uref.field_index = i; uref.usage_index = j; uref.value = data[j]; ioctl(fd,HIDIOCSUSAGE, &uref); } //send report ret = ioctl(fd,HIDIOCSREPORT,&rinfo); if(ret<0) { perror("ioctl-setout"); return -1; } } return finfo.maxusage; } void sigint_handler(int s) { termflag=0; } //pasar el argumento tipo /dev/usb/hiddev0 int main (int argc, char **argv) { int fd = -1; if ((fd = hidOpen("/dev/usb/hiddev0")) < 0) { perror("hidopen"); exit(1); } u16 vid, pid; hidGetVendorProduct(fd, &vid, &pid); printf("VID:%04X PID:%04X\n", vid, pid); char str[HID_STRING_SIZE]= ""; hidGetStringDesc(fd, 0x01, str); printf("Manuf:%s\n", str); hidGetStringDesc(fd, 0x02, str); printf("Prod:%s\n", str); uint8_t data[100] = {1,2,3,4,5,6,7,8}; int i, ret; ret = hidGetInReport(fd, data, 8); printf("IN: "); for(i=0; i<100; i++) printf("0x%02X ", data); printf("\n"); *data = 1; hidSetOutReport(fd, data, 1); sleep(1); *data = 0; hidSetOutReport(fd, data, 1); printf("Fin.\n"); hidClose(fd); return 0; } |
/* * @brief HID generic example * * @note * Copyright(C) NXP Semiconductors, 2013 * All rights reserved. * * @par * Software that is described herein is for illustrative purposes only * which provides customers with programming information regarding the * LPC products. This software is supplied "AS IS" without any warranties of * any kind, and NXP Semiconductors and its licensor disclaim any and * all warranties, express or implied, including all implied warranties of * merchantability, fitness for a particular purpose and non-infringement of * intellectual property rights. NXP Semiconductors assumes no responsibility * or liability for the use of the software, conveys no license or rights under any * patent, copyright, mask work right, or any other intellectual property rights in * or to any products. NXP Semiconductors reserves the right to make changes * in the software without notification. NXP Semiconductors also makes no * representation or warranty that such application will be suitable for the * specified use without further testing or modification. * * @par * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, under NXP Semiconductors' and its * licensor's relevant copyrights in the software, without fee, provided that it * is used in conjunction with NXP Semiconductors microcontrollers. This * copyright, permission, and disclaimer notice must appear in all copies of * this code. */ #include "board.h" #include <stdio.h> #include <string.h> #include "app_usbd_cfg.h" #include "hid_generic.h" /***************************************************************************** * Private types/enumerations/variables ****************************************************************************/ /***************************************************************************** * Public types/enumerations/variables ****************************************************************************/ static USBD_HANDLE_T g_hUsb; extern const USBD_HW_API_T hw_api; extern const USBD_CORE_API_T core_api; extern const USBD_HID_API_T hid_api; /* Since this example only uses HID class link functions for that class only */ static const USBD_API_T g_usbApi = { &hw_api, &core_api, 0, 0, &hid_api, 0, 0, 0x02221101, }; const USBD_API_T *g_pUsbApi = &g_usbApi; /***************************************************************************** * Private functions ****************************************************************************/ /* Initialize pin and clocks for USB port */ static void usb_pin_clk_init(void) { /* enable USB PLL and clocks */ Chip_USB_Init(); /* enable USB 1 port on the board */ Board_USBD_Init(1); } /***************************************************************************** * Public functions ****************************************************************************/ /** * @briefHandle interrupt from USB * @returnNothing */ void USB_IRQHandler(void) { USBD_API->hw->ISR(g_hUsb); } /* Find the address of interface descriptor for given class type. */ USB_INTERFACE_DESCRIPTOR *find_IntfDesc(const uint8_t *pDesc, uint32_t intfClass) { USB_COMMON_DESCRIPTOR *pD; USB_INTERFACE_DESCRIPTOR *pIntfDesc = 0; uint32_t next_desc_adr; pD = (USB_COMMON_DESCRIPTOR *) pDesc; next_desc_adr = (uint32_t) pDesc; while (pD->bLength) { /* is it interface descriptor */ if (pD->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) { pIntfDesc = (USB_INTERFACE_DESCRIPTOR *) pD; /* did we find the right interface descriptor */ if (pIntfDesc->bInterfaceClass == intfClass) { break; } } pIntfDesc = 0; next_desc_adr = (uint32_t) pD + pD->bLength; pD = (USB_COMMON_DESCRIPTOR *) next_desc_adr; } return pIntfDesc; } /** * @briefmain routine for blinky example * @returnFunction should not exit. */ int main(void) { USBD_API_INIT_PARAM_T usb_param; USB_CORE_DESCS_T desc; ErrorCode_t ret = LPC_OK; /* Initialize board and chip */ SystemCoreClockUpdate(); Board_Init(); /* enable clocks and pinmux */ usb_pin_clk_init(); /* initialize call back structures */ memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T)); usb_param.usb_reg_base = LPC_USB_BASE + 0x200; usb_param.max_num_ep = 2; usb_param.mem_base = USB_STACK_MEM_BASE; usb_param.mem_size = USB_STACK_MEM_SIZE; /* Set the USB descriptors */ desc.device_desc = (uint8_t *) USB_DeviceDescriptor; desc.string_desc = (uint8_t *) USB_StringDescriptor; /* Note, to pass USBCV test full-speed only devices should have both * descriptor arrays point to same location and device_qualifier set * to 0. */ desc.high_speed_desc = USB_FsConfigDescriptor; desc.full_speed_desc = USB_FsConfigDescriptor; desc.device_qualifier = 0; /* USB Initialization */ ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param); if (ret == LPC_OK) { ret = usb_hid_init(g_hUsb, (USB_INTERFACE_DESCRIPTOR *) &USB_FsConfigDescriptor[sizeof(USB_CONFIGURATION_DESCRIPTOR)], &usb_param.mem_base, &usb_param.mem_size); if (ret == LPC_OK) { /* enable USB interrupts */ NVIC_EnableIRQ(USB_IRQn); /* now connect */ USBD_API->hw->Connect(g_hUsb, 1); } } while (1) { __WFI(); } } |
/* * @brief HID example USB descriptors * * @note * Copyright(C) NXP Semiconductors, 2013 * All rights reserved. * * @par * Software that is described herein is for illustrative purposes only * which provides customers with programming information regarding the * LPC products. This software is supplied "AS IS" without any warranties of * any kind, and NXP Semiconductors and its licensor disclaim any and * all warranties, express or implied, including all implied warranties of * merchantability, fitness for a particular purpose and non-infringement of * intellectual property rights. NXP Semiconductors assumes no responsibility * or liability for the use of the software, conveys no license or rights under any * patent, copyright, mask work right, or any other intellectual property rights in * or to any products. NXP Semiconductors reserves the right to make changes * in the software without notification. NXP Semiconductors also makes no * representation or warranty that such application will be suitable for the * specified use without further testing or modification. * * @par * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, under NXP Semiconductors' and its * licensor's relevant copyrights in the software, without fee, provided that it * is used in conjunction with NXP Semiconductors microcontrollers. This * copyright, permission, and disclaimer notice must appear in all copies of * this code. */ #include "app_usbd_cfg.h" /***************************************************************************** * Private types/enumerations/variables ****************************************************************************/ /***************************************************************************** * Public types/enumerations/variables ****************************************************************************/ #define HID_INPUT_REPORT_BYTES 1/* size of report in Bytes */ #define HID_OUTPUT_REPORT_BYTES 1/* size of report in Bytes */ #define HID_FEATURE_REPORT_BYTES 1/* size of report in Bytes */ /** * HID Report Descriptor */ const uint8_t HID_ReportDescriptor[] = { HID_UsagePageVendor(0x00), HID_Usage(0x01), HID_Collection(HID_Application), HID_LogicalMin(0),/* value range: 0 - 0xFF */ HID_LogicalMaxS(0xFF), HID_ReportSize(8),/* 8 bits */ HID_ReportCount(HID_INPUT_REPORT_BYTES), HID_Usage(0x01), HID_Input(HID_Data | HID_Variable | HID_Absolute), HID_ReportCount(HID_OUTPUT_REPORT_BYTES), HID_Usage(0x01), HID_Output(HID_Data | HID_Variable | HID_Absolute), HID_ReportCount(HID_FEATURE_REPORT_BYTES), HID_Usage(0x01), HID_Feature(HID_Data | HID_Variable | HID_Absolute), HID_EndCollection, }; const uint16_t HID_ReportDescSize = sizeof(HID_ReportDescriptor); /** * USB Standard Device Descriptor */ ALIGNED(4) const uint8_t USB_DeviceDescriptor[] = { USB_DEVICE_DESC_SIZE,/* bLength */ USB_DEVICE_DESCRIPTOR_TYPE,/* bDescriptorType */ WBVAL(0x0200),/* bcdUSB 2.0 */ 0x00,/* bDeviceClass */ 0x00,/* bDeviceSubClass */ 0x00,/* bDeviceProtocol */ USB_MAX_PACKET0,/* bMaxPacketSize0 */ WBVAL(0x1FC9),/* idVendor */ WBVAL(0x0081),/* idProduct */ WBVAL(0x0100),/* bcdDevice */ 0x01,/* iManufacturer */ 0x02,/* iProduct */ 0x03,/* iSerialNumber */ 0x01/* bNumConfigurations */ }; /** * USB FSConfiguration Descriptor * All Descriptors (Configuration, Interface, Endpoint, Class, Vendor) */ ALIGNED(4) uint8_t USB_FsConfigDescriptor[] = { /* Configuration 1 */ USB_CONFIGURATION_DESC_SIZE,/* bLength */ USB_CONFIGURATION_DESCRIPTOR_TYPE,/* bDescriptorType */ WBVAL(/* wTotalLength */ USB_CONFIGURATION_DESC_SIZE + USB_INTERFACE_DESC_SIZE + HID_DESC_SIZE + USB_ENDPOINT_DESC_SIZE + USB_ENDPOINT_DESC_SIZE ), 0x01,/* bNumInterfaces */ 0x01,/* bConfigurationValue */ 0x00,/* iConfiguration */ USB_CONFIG_SELF_POWERED,/* bmAttributes */ 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 */ 0x02,/* 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(0x0111),/* bcdHID : 1.11*/ 0x00,/* bCountryCode */ 0x01,/* bNumDescriptors */ HID_REPORT_DESCRIPTOR_TYPE,/* bDescriptorType */ WBVAL(sizeof(HID_ReportDescriptor)),/* wDescriptorLength */ /* Endpoint, HID Interrupt In */ USB_ENDPOINT_DESC_SIZE,/* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE,/* bDescriptorType */ HID_EP_IN,/* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT,/* bmAttributes */ WBVAL(0x0004),/* wMaxPacketSize */ 0x20,/* 16ms */ /* bInterval */ /* Endpoint, HID Interrupt Out */ USB_ENDPOINT_DESC_SIZE,/* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE,/* bDescriptorType */ HID_EP_OUT,/* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT,/* bmAttributes */ WBVAL(0x0004),/* wMaxPacketSize */ 0x20,/* bInterval: 16ms */ /* Terminator */ 0/* bLength */ }; /** * USB String Descriptor (optional) */ const uint8_t USB_StringDescriptor[] = { /* Index 0x00: LANGID Codes */ 0x04,/* bLength */ USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */ WBVAL(0x0409),/* wLANGID : US English*/ /* Index 0x01: Manufacturer */ (18 * 2 + 2),/* bLength (13 Char + Type + lenght) */ USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */ 'N', 0, 'X', 0, 'P', 0, ' ', 0, 'S', 0, 'e', 0, 'm', 0, 'i', 0, 'c', 0, 'o', 0, 'n', 0, 'd', 0, 'u', 0, 'c', 0, 't', 0, 'o', 0, 'r', 0, 's', 0, /* Index 0x02: Product */ (12 * 2 + 2),/* bLength (12 Char + Type + lenght) */ USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */ 'L', 0, 'P', 0, 'C', 0, '1', 0, '1', 0, 'U', 0, 'x', 0, ' ', 0, 'H', 0, 'I', 0, 'D', 0, ' ', 0, /* Index 0x03: Serial Number */ (13 * 2 + 2),/* bLength (13 Char + Type + lenght) */ USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */ 'A', 0, 'B', 0, 'C', 0, 'D', 0, '1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0, '9', 0, /* Index 0x04: Interface 0, Alternate Setting 0 */ (3 * 2 + 2),/* bLength (3 Char + Type + lenght) */ USB_STRING_DESCRIPTOR_TYPE,/* bDescriptorType */ 'H', 0, 'I', 0, 'D', 0, }; |
/* * @brief HID generic example's callabck routines * * @note * Copyright(C) NXP Semiconductors, 2013 * All rights reserved. * * @par * Software that is described herein is for illustrative purposes only * which provides customers with programming information regarding the * LPC products. This software is supplied "AS IS" without any warranties of * any kind, and NXP Semiconductors and its licensor disclaim any and * all warranties, express or implied, including all implied warranties of * merchantability, fitness for a particular purpose and non-infringement of * intellectual property rights. NXP Semiconductors assumes no responsibility * or liability for the use of the software, conveys no license or rights under any * patent, copyright, mask work right, or any other intellectual property rights in * or to any products. NXP Semiconductors reserves the right to make changes * in the software without notification. NXP Semiconductors also makes no * representation or warranty that such application will be suitable for the * specified use without further testing or modification. * * @par * Permission to use, copy, modify, and distribute this software and its * documentation is hereby granted, under NXP Semiconductors' and its * licensor's relevant copyrights in the software, without fee, provided that it * is used in conjunction with NXP Semiconductors microcontrollers. This * copyright, permission, and disclaimer notice must appear in all copies of * this code. */ #include "board.h" #include <stdint.h> #include <string.h> #include "usbd_rom_api.h" /***************************************************************************** * Private types/enumerations/variables ****************************************************************************/ static uint8_t *loopback_report; /***************************************************************************** * Public types/enumerations/variables ****************************************************************************/ extern const uint8_t HID_ReportDescriptor[]; extern const uint16_t HID_ReportDescSize; /***************************************************************************** * Private functions ****************************************************************************/ /* HID get report callback function. */ static ErrorCode_t HID_GetReport(USBD_HANDLE_T hHid, USB_SETUP_PACKET *pSetup, uint8_t * *pBuffer, uint16_t *plength) { /* ReportID = SetupPacket.wValue.WB.L; */ switch (pSetup->wValue.WB.H) { case HID_REPORT_INPUT: *pBuffer[0] = *loopback_report; *plength = 1; break; case HID_REPORT_OUTPUT: return ERR_USBD_STALL;/* Not Supported */ case HID_REPORT_FEATURE: return ERR_USBD_STALL;/* Not Supported */ } return LPC_OK; } /* HID set report callback function. */ static ErrorCode_t HID_SetReport(USBD_HANDLE_T hHid, USB_SETUP_PACKET *pSetup, uint8_t * *pBuffer, uint16_t length) { /* we will reuse standard EP0Buf */ if (length == 0) { return LPC_OK; } /* ReportID = SetupPacket.wValue.WB.L; */ switch (pSetup->wValue.WB.H) { case HID_REPORT_INPUT: return ERR_USBD_STALL;/* Not Supported */ case HID_REPORT_OUTPUT: *loopback_report = **pBuffer; break; case HID_REPORT_FEATURE: return ERR_USBD_STALL;/* Not Supported */ } return LPC_OK; } /* HID Interrupt endpoint event handler. */ static ErrorCode_t HID_Ep_Hdlr(USBD_HANDLE_T hUsb, void *data, uint32_t event) { USB_HID_CTRL_T *pHidCtrl = (USB_HID_CTRL_T *) data; switch (event) { case USB_EVT_IN: /* last report is successfully sent. Do something... */ break; case USB_EVT_OUT: /* Read the new report received. */ USBD_API->hw->ReadEP(hUsb, pHidCtrl->epout_adr, loopback_report); /* loopback the report received. */ USBD_API->hw->WriteEP(hUsb, pHidCtrl->epin_adr, loopback_report, 1); break; } return LPC_OK; } /***************************************************************************** * Public functions ****************************************************************************/ /* HID init routine */ ErrorCode_t usb_hid_init(USBD_HANDLE_T hUsb, USB_INTERFACE_DESCRIPTOR *pIntfDesc, uint32_t *mem_base, uint32_t *mem_size) { USBD_HID_INIT_PARAM_T hid_param; USB_HID_REPORT_T reports_data[1]; ErrorCode_t ret = LPC_OK; memset((void *) &hid_param, 0, sizeof(USBD_HID_INIT_PARAM_T)); /* HID paramas */ hid_param.max_reports = 1; /* Init reports_data */ reports_data[0].len = HID_ReportDescSize; reports_data[0].idle_time = 0; reports_data[0].desc = (uint8_t *) &HID_ReportDescriptor[0]; if ((pIntfDesc == 0) || (pIntfDesc->bInterfaceClass != USB_DEVICE_CLASS_HUMAN_INTERFACE)) { return ERR_FAILED; } hid_param.mem_base = *mem_base; hid_param.mem_size = *mem_size; hid_param.intf_desc = (uint8_t *) pIntfDesc; /* user defined functions */ hid_param.HID_GetReport = HID_GetReport; hid_param.HID_SetReport = HID_SetReport; hid_param.HID_EpIn_Hdlr = HID_Ep_Hdlr; hid_param.HID_EpOut_Hdlr = HID_Ep_Hdlr; hid_param.report_data = reports_data; ret = USBD_API->hid->init(hUsb, &hid_param); /* allocate USB accessable memory space for report data */ loopback_report = (uint8_t *) hid_param.mem_base; hid_param.mem_base += 4; hid_param.mem_size += 4; /* update memory variables */ *mem_base = hid_param.mem_base; *mem_size = hid_param.mem_size; return ret; } |
(Not included, just wanted to point out the name of the file, I think is too long, and wont help seeing its code) |
#define HID_INPUT_REPORT_BYTES 1/* size of report in Bytes */ #define HID_OUTPUT_REPORT_BYTES 1/* size of report in Bytes */ #define HID_FEATURE_REPORT_BYTES 1/* size of report in Bytes */ |