Vitaliy_ARM 0 28 июля, 2011 Опубликовано 28 июля, 2011 · Жалоба В одно время сделал устройство в виде небольшой клавиатуры с кнопками и светодиодами на микропроцессоре LPC1343. За основу было взято описание использования встроенного аппаратного стека HID устройства в этот микропроцессор: http://www.nxp.com/documents/application_note/AN10904.pdf и презентация http://ics.nxp.com/literature/presentation...lpc13xx.usb.pdf Структура с настройками этого устройства приведена ниже: HidDevInfo.idVendor = USB_VENDOR_ID; HidDevInfo.idProduct = USB_PROD_ID; HidDevInfo.bcdDevice = USB_DEVICE; HidDevInfo.StrDescPtr = (uint32_t)&USB_StringDescriptor[0]; HidDevInfo.InReportCount = 17; HidDevInfo.OutReportCount = 1; HidDevInfo.SampleInterval = 0x02; HidDevInfo.InReport = GetInReport; HidDevInfo.OutReport = SetOutReport; Для LPC1768 существует аналогичный пример от Keil, который лежит в папке с установленной программой по адресу: "C:\Keil\ARM\Boards\Keil\MCB1700\USBHID\" Вопрос к тем, кто разбирался с этим HID. В этом примере функции SetOutReport и GetInReport могут передавать и принимать только один байт. Каким образом размер буфера можно увеличить до 64 (в описанном мной примере это делается путем установки переменных InReportCount и OutReportCount )? Второй вопрос: как поднять скорость вызова функции GetInReport() до 2 мс? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kovigor 6 28 июля, 2011 Опубликовано 28 июля, 2011 (изменено) · Жалоба В этом примере функции SetOutReport и GetInReport могут передавать и принимать только один байт. Каким образом размер буфера можно увеличить до 64 (в описанном мной примере это делается путем установки переменных InReportCount и OutReportCount )? Второй вопрос: как поднять скорость вызова функции GetInReport() до 2 мс? 1. Как минимум придестся корректировать дескрипторы REPORT'ов и еще очень полезно было бы скорректировать размеры пакетов в дескрипторах крнечных точек Interrupt In и Interrupt Out. Возможно, придется дорабатывать и сами функции. 2. Задайте соотв. интервал опроса в дескрипторе конечной точки прерывания. По умолнанию клавиатуры используют интервал в 10 мС ... Изменено 28 июля, 2011 пользователем kovigor Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
shista 0 28 июля, 2011 Опубликовано 28 июля, 2011 (изменено) · Жалоба Недавно "допиливал" данный код. У меня это выглядит так: hiduser.c #define HID_INPUT_REPORT_BYTES 33 /* size of report in Bytes */ #define HID_OUTPUT_REPORT_BYTES 33 /* size of report in Bytes */ #define HID_FEATURE_REPORT_BYTES 2 /* size of report in Bytes */ /* HID Demo Variables */ extern U8 InReport[HID_INPUT_REPORT_BYTES]; extern U8 OutReport[HID_OUTPUT_REPORT_BYTES]; extern U8 SetupReport[HID_FEATURE_REPORT_BYTES]; /* HID Demo Functions */ extern void GetInReport (void); extern void SetOutReport (void); extern void SetupFuture (void); BOOL HID_GetReport (void) { /* ReportID = SetupPacket.wValue.WB.L; */ switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: GetInReport(); memcpy(EP0Buf, InReport, HID_INPUT_REPORT_BYTES); //m_DEBUG("Packet(Get)= 0x%02x bytes\n", InReport[0]); memset(InReport, 0, HID_INPUT_REPORT_BYTES); break; case HID_REPORT_OUTPUT: return (__FALSE); /* Not Supported */ case HID_REPORT_FEATURE: /* EP0Buf[] = ...; */ /* break; */ return (__FALSE); /* Not Supported */ } return (__TRUE); } BOOL HID_SetReport (void) { /* ReportID = SetupPacket.wValue.WB.L; */ m_DEBUG("Packet= 0x%02x\n", SetupPacket.wValue.WB.H); switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: return (__FALSE); /* Not Supported */ case HID_REPORT_OUTPUT: memcpy(OutReport, EP0Buf, HID_OUTPUT_REPORT_BYTES); SetOutReport(); break; case HID_REPORT_FEATURE: memcpy(SetupReport, EP0Buf, HID_FEATURE_REPORT_BYTES); SetupFuture(); break; } return (__TRUE); } usbdesc.c const U8 HID_ReportDescriptor[] = { HID_UsagePageVendor( 0x00 ), HID_Usage ( 0x01 ), HID_Collection ( HID_Application ), HID_LogicalMin ( 0 ), HID_LogicalMaxS ( 0xFF ), HID_ReportSize ( 8 ), 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, }; Для понимания того, как заполняется дескриптор, рекомендую почитать документ "HID Usage Tables". Изменено 28 июля, 2011 пользователем IgorKossak [codebox] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 29 июля, 2011 Опубликовано 29 июля, 2011 · Жалоба Недавно "допиливал" данный код. У меня это выглядит так: hiduser.c #define HID_INPUT_REPORT_BYTES 33 /* size of report in Bytes */ #define HID_OUTPUT_REPORT_BYTES 33 /* size of report in Bytes */ #define HID_FEATURE_REPORT_BYTES 2 /* size of report in Bytes */ }; Для понимания того, как заполняется дескриптор, рекомендую почитать документ "HID Usage Tables". Спасибо за подсказку. Не нашел сразу эти константы. Допилил следующие моменты: 1. Файл usbcfg.h #define USB_MAX_PACKET0 64 //8 // максимальный размер конечной точки 2. Файл 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 1 /* size of report in Bytes */ 3. Немного переделал функции репортов примерно таким образом (используется непосредственно буфер конечной точки для экономии памяти) BOOL HID_GetReport (void) { /* ReportID = SetupPacket.wValue.WB.L; */ switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: memset(EP0Buf, 0, HID_INPUT_REPORT_BYTES); GetInReport(EP0Buf); break; case HID_REPORT_OUTPUT: return (__FALSE); /* Not Supported */ case HID_REPORT_FEATURE: /* EP0Buf[] = ...; */ /* break; */ return (__FALSE); /* Not Supported */ } return (__TRUE); } /* * HID Set Report Request Callback * Called automatically on HID Set Report Request * Parameters: None (global SetupPacket and EP0Buf) * Return Value: TRUE - Success, FALSE - Error */ BOOL HID_SetReport (void) { /* ReportID = SetupPacket.wValue.WB.L; */ switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: return (__FALSE); /* Not Supported */ case HID_REPORT_OUTPUT: SetOutReport(EP0Buf); break; case HID_REPORT_FEATURE: return (__FALSE); /* Not Supported */ } return (__TRUE); } 4. Интервал опроса описывается в файле usbdesc.c в следующей структуре. Вместо константы 0ч20 по умолчанию (32 мс), я вставил директиву HID_INPUT_REPORT_INTERVAL для удобства. /* USB Configuration Descriptor */ /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor) */ const U8 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: 0x01 is used to select this configuration */ 0x00, /* iConfiguration: no string to describe this configuration */ USB_CONFIG_BUS_POWERED /*|*/ /* bmAttributes */ /*USB_CONFIG_REMOTE_WAKEUP*/, USB_CONFIG_POWER_MA(100), /* bMaxPower, device power consumption is 100 mA */ /* 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(0x0004), /* wMaxPacketSize */ HID_INPUT_REPORT_INTERVAL, /* 32ms */ /* bInterval */ /* Terminator */ 0 /* bLength */ }; 5. Последним этапом перенес все нужные константы в одно место, в hiduser.h #ifndef __HIDUSER_H__ #define __HIDUSER_H__ #define HID_INPUT_REPORT_BYTES 64 /* size of report in Bytes */ #define HID_OUTPUT_REPORT_BYTES 64 /* size of report in Bytes */ #define HID_INPUT_REPORT_INTERVAL 0x20 /* report interval in ms (32 ms) */ #define HID_FEATURE_REPORT_BYTES 1 /* size of report in Bytes */ /* HID Number of Reports */ #define HID_REPORT_NUM 1 /* HID In/Out Endpoint Address */ #define HID_EP_IN 0x81 /* HID Global Variables */ extern U8 HID_Protocol; extern U8 HID_IdleTime[HID_REPORT_NUM]; /* HID Requests Callback Functions */ extern BOOL HID_GetReport (void); extern BOOL HID_SetReport (void); extern BOOL HID_GetIdle (void); extern BOOL HID_SetIdle (void); extern BOOL HID_GetProtocol (void); extern BOOL HID_SetProtocol (void); #endif /* __HIDUSER_H__ */ 6. Прикрепляю сей проект к этому топику :) USBHID.zip Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Эмма 0 18 сентября, 2020 Опубликовано 18 сентября, 2020 · Жалоба РЕАЛИЗАЦИЯ ИНТЕРФЕЙСА USB-HID В МИКРОПРОЦЕССОРНОЙ СИСТЕМЕ https://studzachet.ru/primeryi-uchebnyix-rabot/realizacziya-interfejsa-usb/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться