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

 

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

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

Агуров П.В. Интерфейсы USB. Практика использования и программирования — СПб.: БХВ-Петербург, 2004. — 576 c.
ISBN 5-94157-202-6
Скачать (прямая ссылка): interface2004.djvu
Предыдущая << 1 .. 86 87 88 89 90 91 < 92 > 93 94 95 96 97 98 .. 166 >> Следующая

Формирование запроса производится с помощью типа TUSBRequest. В листинге 11.8 показано формирование запроса setaddress.
^Іистинг 11.8. формирование запроса set_address
Var
SetAddressDesc : TUSBRequest;
With SetAddressDesc do begin bmRequestType;= 0;
Гпава 11. Функции BIOS
279
bRequest := 5
wValue := 1
wlndex := O
wLength := O End;
Для передачи запроса устройству нам придется выполнить следующие действия:
? получить линейный адрес запроса;
? сформировать заголовок очереди и получить его линейный адрес;
? сформировать список кадров и получить его линейный адрес;
? добавить в список кадров записи, соответствующие транзакциям нужного запроса (см. разд. 3.10.3);
? разрешить работу контроллера и порта.
Как мы уже говорили, основной проблемой является получение линейного адреса. В простейшем случае линейный адрес вычисляется, как показано в листинге 11.9, однако при использовании драйверов Himem или Emm386 такой код работать не будет.
!A4c™Hr!1-&^A^^teMaflPeca_______________________________.......______________..... .... \
Function GetPtrBase(P : Pointer) : Longint; Begin
GetPtrBase:= Longint(Seg(РЛ)) shl 4 + Longint(Ofs(рл)); End;
Общая схема передачи запроса показана в листинге 11.10.
Іистинг 11.UL
{ Вычислить линейный адрес блока команды }
Addr SetAddress:= GetLinearAddr(OSetAddressDesc);
{ Отводим память под заголовок очереди } { Используем GetMem или другой способ }
GetMem(QueueHead, 1024*10); { Заполняем заголовок очереди }
With QueueHead^ do begin QH Descriptor[1]:= 3;
280
Часть III. Практика программирования
QH_Descriptor[2] QH_Descriptor[3] QH_Descriptor[4] QH_Descriptor[5] QH_Descriptor[6] QH_Descriptor[7] QH_Descriptor[8]
= O
= O
= O
= O
= O
= O
= O
{TD_Array : TTD_Array;} End;
{ Вычисляем линейный адрес заголовков } Addr_QH:= GetLinearAddr(@QueueHeadA.QH_Descriptor); Addr_TD_Array:= GetLinearAddr(@QueueHeadA.TD_Array);
{ Базовый адрес памяти (храним для освобождения) } GetMem(FrameListHandle, 8192); FillChar(FrameListHandle", 8192, #0); { Линейный адрес }
FrameListAddr:= GetLinearAddr(FrameListHandle); { Выравненный адрес } FrameListBaseAddr:= Longint(FrameListAddr + 4096) and $fffff000; { Указатель на выровненный адрес } FrameList:= GetBasePtr(FrameListAddr); { Заполняем }
For і:= 1 to 1024 do begin
FrameListA[i]:= Addr_QH or $2; End;
( Класс контроллеров для поиска устройства } USBControllerList:= New(PUSBControllerList, Init); USBControllerList'4. MakeList;
WriteLn('Найдено контроллеров:', USBControllerList'4.GetCount);
{ Ищем первое устройство } GetFirstDevice;
{ Если не нашли - выход } If USB_BaseAddr = 0 then begin WriteLn('Устройства не найдены');
Гпава 11. Функции BIOS
281
Dispose(USBControllerList, Done); Exit; End;
WriteLn('Найдено устройство:');
WriteLn(' номер контр-pa:', USB_HostIndex);
WriteLn(' базовый адрес :', USB_BaseAddr ) ;
WriteLn(' порт :', USB_PortNum );
WriteLn(' адрес порта :', USB_PortReg );
{ DD[Base+8], - базовый адрес списка кадров }
( Заносим адрес списка кадров }
PortW[USB_BaseAddr+ 8]:= FrameListBaseAddr and $0000FFFF;
PortW[USB_BaseAddr+10]:= FrameListBaseAddr shr 16;
( сброс номера кадра USB } PortW[USB_BaseAddr+6]:= 0;
{ Включить хост-контроллер } , PortW[USB_BaseAddr]:=1;
{ Разблокировать порт } PortW[USB_PortReg]:= $Е;
{ Определить и запомнить тип устройства}
If USBControllerList .GetAt(USB_HostIndex)А.IsLowSpeedDevice(USB_PortNum)
Then ShDevType:= $4000000
Else ShDevType:= $0000000;
{ После сброса устройство имеет нулевой номер} ShFuncNum:= 0;
{ Выполнение транзакции для запроса SET_ADDRESS}
While not(KeyPressed) do begin { Подать команду "Set Address"}
і:= 0;
With QueueHeadA do begin TD_Array[i+l]:= Addr_TD_Array + 32; TD_Array[i+2]:= ShDevType or $00800000;
282
Часть III. Практика программирования
TD_Array[i+3]:= ShFuncNum or $00E0002D; TD_Array[i+4]:= Addr_SetAddress; TD_Array[i+5]:=0; TD_Array[i+6]:= 0; TD_Array[i+7]:= 0; TD_Array[i+8]:=0; End;
With QueueHead^ do begin
TD_Array[i+1] TD_Array[i+2] TD_Array[i+3] TD_Array[i+4] TD_Array[i+5] TD_Array[i+6] TD_Arrayfi+7) TD_Array[i+8] End;
= 1;
= ShDevType or $00800000; = ShFuncNum or $FFE80069;' = 0; = 0 = 0 = 0 = 0
(Записать кадр в заголовок очереди } QueueHeadA.QH_Descriptor[2]:= Addr_TD_Array;
(Ждать выполнения транзакции }
Delay(10000); End;
{ Выключить хост-контроллер} PortW[USB_BaseAddr]:= 0;
{ Освободить список контроллеров } Dispose(USBControllerList, Done);
ЧАСТЬ IV
Создание USB-устройств
Глава 12
USB-периферия
Гадание на микросхемах, откусывая ножки, —
Любит9 Не любит?
В этой главе мы дадим краткий обзор основных микросхем, используемых для организации USB-интерфейса. Микросхемы можно разделить на следующие группы:
? преобразователи интерфейса:
• СОМ в USB;
• LPTbUSB;
• конвертеры других интерфейсов;
? микроконтроллеры с USB-интерфейсом:
• микроконтроллеры на основе ядра 8051;
• другие микроконтроллеры;
? микросхемы хабов;
? микросхемы OTG.
Такое деление довольно условно, например, микроконтроллер AT43USB320A включает в себя хаб, а микросхема FT2232BM является программируемым преобразователем интерфейса.
Предыдущая << 1 .. 86 87 88 89 90 91 < 92 > 93 94 95 96 97 98 .. 166 >> Следующая
Реклама
Авторские права © 2009 AdsNet. Все права защищены.
Rambler's Top100