|
|
  |
hid-report, Alphаnumeric Display |
|
|
|
Jan 2 2008, 15:14
|
Частый гость
 
Группа: Свой
Сообщений: 126
Регистрация: 1-09-07
Из: Винница
Пользователь №: 30 222

|
Всем привет! Разбираюсь с USB HID (по usb.org и книге "Агуров Интерфейс USB Практика использования и программирования"), уже почти все понял, проблема ток с hid-report'ом... Создаю Alphanumeric Display report (0х14), но не понимаю значение некоторых элементов репорта. В частности - объясните плз для чего нужны USAGE - и почему их так много в репорте? Т.е. я должен создать USAGE на каждую используемую функцию из спецификации HID Usage Tables? Составляю дескриптор репорта с помощью HID descriptor Tool, там и пример для Alphanumeric Display есть, но ведь там USAGE не на все возможные функции прописаны: Код char ReportDescriptor[136] = { 0x05, 0x14, // USAGE_PAGE (Alphnumeric Display) 0x09, 0x01, // USAGE (Alphanumeric Display) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0xa1, 0x02, // COLLECTION (Logical) 0x09, 0x20, // USAGE (Display Attributes Report) 0xa1, 0x02, // COLLECTION (Logical) 0x09, 0x35, // USAGE (Rows) 0x09, 0x36, // USAGE (Columns) 0x09, 0x3d, // USAGE (Character Width) 0x09, 0x3e, // USAGE (Character Height) 0x85, 0x01, // REPORT_ID (1) 0x25, 0x1f, // LOGICAL_MAXIMUM (31) 0x75, 0x05, // REPORT_SIZE (5) 0x95, 0x04, // REPORT_COUNT (4) 0xb1, 0x03, // FEATURE (Cnst,Var,Abs) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x03, // REPORT_COUNT (3) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x09, 0x21, // USAGE (ASCII Character Set) 0x09, 0x22, // USAGE (Data Read Back) 0x09, 0x29, // USAGE (Vertical Scroll) 0xb1, 0x03, // FEATURE (Cnst,Var,Abs) 0x95, 0x03, // REPORT_COUNT (3) 0xb1, 0x03, // FEATURE (Cnst,Var,Abs) 0xc0, // END_COLLECTION 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x01, // REPORT_COUNT (1) 0x25, 0x02, // LOGICAL_MAXIMUM (2) 0x09, 0x2d, // USAGE (Display Status) 0xa1, 0x02, // COLLECTION (Logical) 0x09, 0x2e, // USAGE (Stat Not Ready) 0x09, 0x2f, // USAGE (Stat Ready) 0x09, 0x30, // USAGE (Err Not a loadable character) 0x81, 0x40, // INPUT (Data,Ary,Abs,Null) 0xc0, // END_COLLECTION 0x09, 0x32, // USAGE (Cursor Position Report) 0xa1, 0x02, // COLLECTION (Logical) 0x85, 0x02, // REPORT_ID (2) 0x75, 0x04, // REPORT_SIZE (4) 0x95, 0x01, // REPORT_COUNT (1) 0x25, 0x0f, // LOGICAL_MAXIMUM (15) 0x09, 0x34, // USAGE (Column) 0xb1, 0x22, // FEATURE (Data,Var,Abs,NPrf) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x09, 0x33, // USAGE (Row) 0xb1, 0x22, // FEATURE (Data,Var,Abs,NPrf) 0xc0, // END_COLLECTION 0x09, 0x2b, // USAGE (Character Report) 0xa1, 0x02, // COLLECTION (Logical) 0x85, 0x03, // REPORT_ID (3) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x04, // REPORT_COUNT (4) 0x25, 0x7e, // LOGICAL_MAXIMUM (126) 0x09, 0x2c, // USAGE (Display Data) 0xb2, 0x02, 0x01, // FEATURE (Data,Var,Abs,Buf) 0xc0, // END_COLLECTION 0x85, 0x04, // REPORT_ID (4) 0x09, 0x3b, // USAGE (Font Report) 0xa1, 0x02, // COLLECTION (Logical) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x7e, // LOGICAL_MAXIMUM (126) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x01, // REPORT_COUNT (1) 0x09, 0x2c, // USAGE (Display Data) 0x91, 0x02, // OUTPUT (Data,Var,Abs) 0x95, 0x05, // REPORT_COUNT (5) 0x09, 0x3c, // USAGE (Font Data) 0x92, 0x02, 0x01, // OUTPUT (Data,Var,Abs,Buf) 0xc0, // END_COLLECTION 0xc0 // END_COLLECTION }; И почему я не могу просто прописать в репорте одну INPUT, и одну OUTPUT (ессно с остальными обязательными элементами)? А в проге для компа просто записывать нужные команды? Где еще можно почитать про составление hid-report, кроме как на usb.org , книге Агурова, USB masters? Поиск по форуму дает в основном эти ссылки, по ним я и разбирался с HID, сейчас опять по спецификациям из usb.org пытаюсь разобраться...
|
|
|
|
|
Jan 4 2008, 12:04
|
Частый гость
 
Группа: Свой
Сообщений: 126
Регистрация: 1-09-07
Из: Винница
Пользователь №: 30 222

|
Пока составил репорт только с одной INPUT и одной OUTPUT, чтоб попробовать получше разобраться: Код BYTE __flash ReportDescriptor_HID[] = { 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined Page 1) 0x09, 0x01, // Usage (Vendor Usage 1) 0xa1, 0x01, // Collection (Application) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x01, // Report Count (1) 0x09, 0x01, // Usage (Vendor Usage 1) 0x81, 0x02, // Input (Data, Variable, Absolute, Bit Field) 0x09, 0x02, // Usage (Vendor Usage 2) 0x91, 0x02, // Output (Data, Variable, Absolute, Bit Field) 0xc0 // End Collection }; Также сделал вот такой дескриптор конфигурации, использую конечную точку EP1: Код // Configuration descriptor USB_CONFIG_DATA __flash ConfigurationDescriptor_HID = { { // configuration descriptor sizeof(USB_CONFIGURATION_DESCRIPTOR), // bLength TYPE_CONFIGURATION_DESCRIPTOR, // bDescriptorType sizeof(USB_CONFIG_DATA), // wTotalLength 1, // bNumInterfaces 1, // bConfigurationValue 0, // iConfiguration String Index 0xA0, // bmAttributes Bus Powered, Remote Wakeup 0x32 // bMaxPower, 100mA }, { // interface descriptor sizeof(USB_INTERFACE_DESCRIPTOR), // bLength TYPE_INTERFACE_DESCRIPTOR, // bDescriptorType 0, // bInterface Number 0, // bAlternateSetting 2, // bNumEndpoints 3, // bInterfaceClass (HID class) 0, // bInterfaceSubClass(Boot subclass) 0, // bInterfaceProtocol 2 // iInterface String Index }, { // HID descriptor sizeof(USB_HID_DESCRIPTOR), // bLength TYPE_HID_DESCRIPTOR, // bDescriptorType 0x0100, // wHIDClassSpecComp 0, // bCountry 1, // bNumDescriptors 0x22, // b1stDescType (Report) sizeof(ReportDescriptor_HID) // w1stDescLength }, { // endpoint descriptor sizeof(USB_ENDPOINT_DESCRIPTOR), // bLength TYPE_ENDPOINT_DESCRIPTOR, // bDescriptorType 0x81, // bEndpoint Address EP1 IN 0x03, // bmAttributes - Interrupt 0x0008, // wMaxPacketSize 0x0A // bInterval (10 ms) }, { // endpoint descriptor sizeof(USB_ENDPOINT_DESCRIPTOR), // bLength TYPE_ENDPOINT_DESCRIPTOR, // bDescriptorType 0x01, // bEndpoint Address EP1 OUT 0x03, // bmAttributes - Interrupt 0x0008, // wMaxPacketSize 0x0A // bInterval (10 ms) } }; Вот эта часть кода находится в главном цикле: Код if (Irq & D11_INT_EP1_IN){ D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP1_IN, Buffer, 1); //debug('b'); } if (1) { // заполнить информационные данные Buffer[0] = temp; hid_bufsize = 1;
// отправить буфер D11WriteEndpoint(D11_ENDPOINT_EP1_IN, Buffer, hid_bufsize); }
if (Irq & D11_INT_EP1_OUT) { D11CmdDataRead(D11_READ_LAST_TRANSACTION + D11_ENDPOINT_EP1_OUT, Buffer, 1); if (1) { D11ReadEndpoint(D11_ENDPOINT_EP1_OUT, &Buffer[0]); temp = 2;//Buffer[0]; } debug('c'); debug('c'); } По идее, при вызове WriteFile с пользовательского приложения, должно генерироваться D11_INT_EP1_OUT, но этого не происходит (debug- отладка по UART). Сам исходник для отправки/приема данных взял с книги "Агуров Интерфейс USB Практика использования и программирования", исходник на Делфи, добавил туда WriteFile. При вызове WriteFile возвращается ошибка, при ReadFile все корректно читается с устройства. В чем может быть проблема при записи? Исходник прикрепил, посмотрите плз.
HID.rar ( 220.98 килобайт )
Кол-во скачиваний: 182
|
|
|
|
|
Jan 4 2008, 14:23
|
Частый гость
 
Группа: Свой
Сообщений: 126
Регистрация: 1-09-07
Из: Винница
Пользователь №: 30 222

|
Хех, разобрался вроде с записью. Я не правильно буфер для отправки устройству заполнял - в hid-репорте не указывал REPORT_ID, а при отсутствии его по умолчанию REPORT_ID равен 0, если я правильно понял спецификацию  Т.е. первую ячейку буфера устанавливаю в 0, остальные - данные для отправки - тогда все работает!
|
|
|
|
|
Jan 10 2008, 21:01
|
Частый гость
 
Группа: Свой
Сообщений: 126
Регистрация: 1-09-07
Из: Винница
Пользователь №: 30 222

|
Разобрался как строится hid-report, и почему там так много USAGE:)
Появилась еще одна небольшая проблема - если добавить FEATURE 0x75, 0x05, // REPORT_SIZE (5) 0x95, 0x04, // REPORT_COUNT (4) 0xb1, 0x03, // FEATURE (Cnst,Var,Abs) то устройство не работает корректно (“Запуск этого устройства невозможен” в диспетчере устройств), но если при этом REPORT_SIZE установить в 8, то все работает (все значения, которые отличаются от 8 тоже не работают). Но почему так? Ведь 8 должно быть только при установленном "Array" бите, а я использую "Variable"?
|
|
|
|
|
Jan 16 2008, 10:38
|
Участник

Группа: Участник
Сообщений: 39
Регистрация: 1-11-06
Пользователь №: 21 855

|
Цитата(_lukash_ @ Jan 11 2008, 00:01)  Разобрался как строится hid-report, и почему там так много USAGE:)
Появилась еще одна небольшая проблема - если добавить FEATURE 0x75, 0x05, // REPORT_SIZE (5) 0x95, 0x04, // REPORT_COUNT (4) 0xb1, 0x03, // FEATURE (Cnst,Var,Abs) то устройство не работает корректно (“Запуск этого устройства невозможен” в диспетчере устройств), но если при этом REPORT_SIZE установить в 8, то все работает (все значения, которые отличаются от 8 тоже не работают). Но почему так? Ведь 8 должно быть только при установленном "Array" бите, а я использую "Variable"? разбирался с джойстиком, так там если задается в дескрипторе, например, 4 кнопки, то нужно отправлять 4 бита. Так не делается, нужно отправлять по байтам, поэтому задается report_size 1 (т.к. состояние кнопки 1 бит - нажата или не нажата), но report_count должен быть 8 (т.к. передается 1 байт) см еще http://microchip.com.ru/1010/Support/USB%20apps.html"В нашем случае «газ» это одно 8-и битное значение (report_size = 8, report_count = 1), а состояние кнопок определяется как поле однобитных значений. В примере используется только 2 кнопки, но необходимо выровнять поле до байтовой величины (report_size = 1, report_count = 8). Итого микроконтроллер при запросе данных от компьютера должен передать 2 байта – уровень газа и состояние кнопок"
|
|
|
|
|
Jan 17 2008, 16:50
|
Знающий
   
Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640

|
Цитата(_lukash_ @ Jan 17 2008, 00:12)  Вот что еще интересует - в спецификации HID Usage Tables не сказано какие типы передачи (FEATURE или через прерывания) нужно применять для определенных репортов. Я сделал все на FEATURE, вроде работает корректно, но правильно ли это? Делайте как удобнее. Я использую и то и другое в одном устройстве. FEATURE пользоваться сложнее. И со стороны компьютера, и со стороны устройства. Но этот метод более продвинутый. FEATURE: 1. Обмен всегда начинается по инициативе компьютера. 2. FEATURE репортов м.б. 254 штуки (Interrupt-ов токо 2, по 1 в каждую сторону). Устойство, получив пакет SETUP, по Report ID (есть в SETUP-ном пакете) уже знает, что будет посылать (принимать). 3. Длина ограничена только размером буфера USB (у USB буфер на контрольный канал вроде-бы 4 кбайта). 8 байт у LowSpeed это размер пакета за кадр USB (1 мсек). А пакетов м.б. несколько. Токо не забывайте про DATA1/DATA0. (Как раз наоборот - у Interrupt токо 1 пакет м.б.). Interrupt: 1. Interrupt In начинается по инициативе устройства. Interrupt Out - компьютера. 2. Буфера на несколько посылок (кол-во можно изменять) встроены в HID драйвер. Из-за этого данные не теряются даже если задача не активна. Но и проблема с синхронизацией ввода и вывода возникает. Если вам это надо конечно. 3. На компьютере простой readfile (+overlap чтоб не ждать). По описанию FEATURE c 1 пакетом данных должен выполнятся за 3 мсек. SETUP=1мсек + DATA=1мсек + подтв. чтение/запись=1мсек. А если устойство пошлёт NAK, то след-й пакет от хоста д.б. через 1 мсек. Тоесть max скорость менее 64 кбайт в сек (1 пакет 64 байта в мсек на FullSpeed). Реально всё зависит от южного моста. Заметил, что интеловские чипсеты - соответствуют. А те, которые с АМД процессорами (в часности VIA) - нет. С VIA мой HID - 600 кбайт в секунду качает (Full Speed)! Почти как MassStorage (1000). Жаль только, что рассчитывать на это нельзя. Неизвестно, что у пользователя будет.
|
|
|
|
|
Jan 21 2008, 17:10
|
Знающий
   
Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640

|
Цитата(_lukash_ @ Jan 20 2008, 14:09)  Еще вопрос - есть ли какие-то программки для тестирования Alphаnumeric Display? Или в самой Винде (ХР), или отдельно. К примеру, USB джойстик можно потестить в самой ХР. Специально для Alphаnumeric Display наверное нет. На usb.org есть тестовые вообще, и для HID в частности. Рекомендую проверить. Сам когда проверял - был удивлён скоко несоответствий. Одна из программ даже HID-дескриптор отдельно запросила. Хотя по описанию USB, вроде токо вместе с конфигурацией должна. Посмотрел, USB мышка отдельно выдаёт, ну и я начал. Цитата(_lukash_ @ Jan 20 2008, 14:09)  Или эта 14 страница приводится как "рекомендации" для создания протокола обмена?)) Это для того, чтоб кто-то, не знакомый ни с вами ни с вашим устройством, написал программу которая Alphаnumeric Display работает - и она-бы сразу с вашим устройством заработала. Ни драйверов ни настройки не потребовав. Вам это надо? Мне, например, нет. Я Vendor Defined page пользуюсь. С моим устройством токо моя программа работает. А другие пусть лучше и не пытаются.
|
|
|
|
|
Jan 23 2008, 14:38
|
Знающий
   
Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640

|
Цитата(_lukash_ @ Jan 22 2008, 01:24)  С usb.org испробовал все кроме той которая больше 100 метров. Но они у меня не работают, или я просто не до конца разобрался еще. А какую из них Вы использовали? Давно это было. Года 2 назад. С тех пор компьютер поменял. И забыл многое, в т.ч. названия. Но помню, что у меня тоже в начале не шли. Я сначала USB мышку и USB джойстик научился тестировать. А сам в это время SnoopyPro смотрел, какие запросы там шлются. Пока на них правильно отвечать не начнешь - тестироватся не будет. Ещё помню, что для одной из тестирующих программ W98 установить пришлось. С тех пор с HID никаких проблем не имел в т.ч. под Linux. Ну и не тестировал ничо. Цитата(_lukash_ @ Jan 22 2008, 01:24)  Это мое первое USB устройство, хочу разобраться как следует. Завидую. Тоже хотел, но не смог из-за недостатка времени. Если, что интересное всплывёт - пишите. Цитата(_lukash_ @ Jan 22 2008, 01:24)  А так, то я к нему пишу библиотеку, экспортирующую уже совсем "высокоуровневые" функции. А ваша библиотека токо с вашим устойством работать будет? Или с Alphаnumeric Display общего вида (чужим)? И как вы его ищете - по VID+PID, или по Usage Page, или по Usage Page + корневая коллекция Usage? Или может ещё как?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|