реклама на сайте
подробности

 
 
> USB HID LPC1768, Как поднять скорость опроса и размер буфера?
Vitaliy_ARM
сообщение Jul 28 2011, 12:57
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



В одно время сделал устройство в виде небольшой клавиатуры с кнопками и светодиодами на микропроцессоре 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 мс?


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
shista
сообщение Jul 28 2011, 17:58
Сообщение #2





Группа: Участник
Сообщений: 12
Регистрация: 15-07-09
Пользователь №: 51 296



Недавно "допиливал" данный код. У меня это выглядит так:

hiduser.c
CODE
#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
CODE
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".

Сообщение отредактировал IgorKossak - Jul 28 2011, 19:46
Причина редактирования: [codebox]
Go to the top of the page
 
+Quote Post
Vitaliy_ARM
сообщение Jul 29 2011, 09:57
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 509
Регистрация: 19-07-07
Из: г. Таганрог
Пользователь №: 29 246



Цитата(shista @ Jul 28 2011, 21:58) *
Недавно "допиливал" данный код. У меня это выглядит так:

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. Немного переделал функции репортов примерно таким образом (используется непосредственно буфер конечной точки для экономии памяти)
CODE

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 для удобства.
CODE

/* 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
CODE

#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. Прикрепляю сей проект к этому топику sm.gif
Прикрепленные файлы
Прикрепленный файл  USBHID.zip ( 486.66 килобайт ) Кол-во скачиваний: 55
 


--------------------
Умные речи подобны строкам, напечатанным курсивом. К. Прутков
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 22:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01385 секунд с 7
ELECTRONIX ©2004-2016