Информационный сайт

 

Реклама
bulletinsite.net -> Книги на сайте -> Программисту -> Агуров П.В. -> "Интерфейсы USB. Практика использования и программирования" -> 122

Интерфейсы USB. Практика использования и программирования - Агуров П.В.

Агуров П.В. Интерфейсы USB. Практика использования и программирования — СПб.: БХВ-Петербург, 2004. — 576 c.
ISBN 5-94157-202-6
Скачать (прямая ссылка): interface2004.djvu
Предыдущая << 1 .. 116 117 118 119 120 121 < 122 > 123 124 125 126 127 128 .. 166 >> Следующая

End;
Il Освободить дескрипторы CioseHandle(ReadOL.hEvent); CioseHandle(HidHandle);
Программу чтения данных мы будем разбирать в разд. 13.6.
Использование FEATURE-репортов
Второй способ передачи данных, который мы рассмотрим, заключается в использовании репортов типа feature. Репорты этого типа удобно использовать, когда важно время доставки данных.
Для описания репорта типа feature достаточно изменить описание дескриптора REPORT (листинг 13.39).
386
Часть IV. Создание USB-устройств
code struct{
byte rep[SIZE_OF_REPORT];
}
HIDReport =
/* HID Report */ <
0x06, 0x00, Oxff, /* USAGE-PAGE (Generic Desktop) */
0x09, 0x01, /* USAGE (Vendor Usage 1) */
Oxal, 0x01, /* COLLECTIGN (Application) */
0x19, 0x01, /* USAGE_MINIMUM (Vendor Usage 1) */
0x29, 0x01, /* USAGE_MAXIMUM (Vendor Usage 1) */
0x15, 0x00, /* LOGICALJMINIMUM (0) */
0x26, Oxff, 0x00, /* LOGICAL_MAXIMUM (255) V
0x75, 0x08, /* REPORt-SIZE (8) */
0x95, 0x07, /* REPORTjCOUNT(7) */
OxBl, 0x02, /* FEATURE (Data,Var,Abs) */
OxcO /* ENDjCOLLECTION */
};
Как видно, FEATURE-репорт отличается от INPUT одним байтом, однако, способ его обработки отличается существенно.
Обработка FEATURE-запросов производится при получении запроса GETREPORT (код запроса OxAlOl). Код обработчика показан в листинге 13.40.
void usb_read_request () {
data uintl6 wReguest;
/* чтение bmRequestType */
((byte*)fiwRequest)[0] = Usb_read_byte();
/* чтение bRequest */
((byte*)fiWReguest)[1] = usb_read_byte();
switch (wReguest) {
Глава 13. HID-устройство на основе Atmel АТ89С5131
387
case GET-REPORT: hid_get_report(); break;
default: STALLO ; break;
}
}
void hid_get_report() {
Il если конфигурация еще не установлена, не отвечаем if (usb_configuration_nb = 0){
STALLO ;
return;
}
Il индикатор получения запроса (светодиод) P3.3-p_test; p_test=!p_test;
Il переключение на передачу Osb_clear_rx_setup 0; usb_set_DIR();
// передача пакета Usb_write_byte(0x11); Usb_write_byte(0x12); Usb_write_byte(pointl_state); Usb_write_byte(0x14); Usb_write_byte(0x15); usb_write_byte(0x16); Usb_write_byte(0x17); pointl_state++; // подтверждение передачи и переключение на прием END_OK();
388
Часть IV. Создание USB-устройств
Программу чтения FEATURE-репортов мы будем рассматривать в следующем разделе, объединив ее с программой чтения других репортов. В заключение отметим, что чтение данных производится не постоянно, а по запросу со стороны хоста, поэтому индикатор РЗ.З будет изменять свое состояние после каждого чтения. Однако, как и в случае с INPUT-репортами, если устройство не ответит на запрос, программа зависнет до получения данных или ответа STALL.
В этом разделе мы создадим небольшую программу для чтения данных с HID-устройства, воспользовавшись информацией главы 8. Мы специально не приводили код этой программы в предыдущих разделах, хотя и подразумевали наличие такой программы. Мы объединим программу чтения разных типов репортов, сделав одну универсальную программу.
Для чтения данных с устройства нужно получить его дескриптор с помощью функции CreateFiie. В отличие от, например, последовательных портов HID-устройства не имеют простых и понятных имен (СОМІ, COM2 и т. д.). Для получения имени устройства нужно воспользоваться функциями модуля SetupApi и выполнить следующие действия:
1. Получить GUID класса HID с помощью вызова HidDGetHidGuid.
2. Получить дескриптор PnP для HID-класса с помощью вызова
SetupDiGetClassDevs.
3. Произвести цикл по всем устройствам HID-класса, вызывая
SetupDiGetDevicelnterfaceDetail, И НЭЙТИ Нужное УСТРОЙСТВО (ДЛЯ Про-
стоты мы будем производить чтение данных с каждого найденного устройства).
Соответствующий код показан в листинге 13.41.
// Отображение списка HID-ycтройств и их свойств procedure TForml.ButtonlClick(Sender: TObject); var HldGuid : TGuid; FnPHandle : HDevInfo; DevData: TSPDevInfoData;
DevicelnterfaceData: TSPDevicelnterfaceData; FunctionClassDeviceData: PSPDevicelnterfaceDetailData; Success: LongBool; Devlndex: DWORD;
13.6. Чтение репортов в Windows
/Листинг 13.41. Поиск НІЦгустроиств
Глава 13. HID-устройство на основе Atmel АТ89С5131
389
BytesReturned: DWORD; HidName : String; begin Il Очистить лог lbLog.Iterns. Clear; Il Получить GUID для класса HID HidD_GetHidGuid(HidGuid); Il Получаем дескриптор FnP для HID-класса PnPHandle:= SetupDiGetClassDevs(0HidGuid, nil, 0,
DIGCF_PRESENT or DIGCF_DEVICEINTERFACE); Il Если ошибка, то выходим
If PnPHandle = Pointer (INVALID_HANDLE_VALUE) then Exit; Try
Il Индекс текущего устройства Devlndex := 0;
Il Цикл по всем устройствам в HID-классе Repeat
DevicelnterfaceData.cbSize := SizeOf(TSPDevicelnterfaceData); Il Получить информацию об интерфейсах устройства номер Devlndex Success := SetupDiEnumDevicelnterfaces(PnPHandle, nil,
HidGuid, Devlndex, DevicelnterfaceData);
If Success then begin DevData.cbSize : = SizeOf(DevData); BytesReturned : = 0; Il Получаем подробности об устройстве с // интерфейсам DevicelnterfaceData // Сначала вызываем с нулевым размером буфера, // получаем размер необходимого буфера, потам // вызываем повторно, сформировав правильный буфер SetupDiGetDevicelnterfaceDetail(PnPHandle, 0DeviceInterfaceData,
Предыдущая << 1 .. 116 117 118 119 120 121 < 122 > 123 124 125 126 127 128 .. 166 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100