пояснительная записка (1231539), страница 12
Текст из файла (страница 12)
Код, реализующий алгоритм инициализации USB устройства с использование библиотеки Lib USB на языке Object Pascal
const
RQ_IO_READ:integer=$11; RQ_IO_WRITE:integer=$12;
USB2PC = USB_ENDPOINT_IN; PC2USB = USB_ENDPOINT_OUT;
aPIND = $10; aDDRD = $11; aPORTD = $12; aPINC = $13;
aDDRC = $14; aPORTC = $15; aPINB = $16; aDDRB = $17;
aPORTB = $18; aPINA = $19; aDDRA = $1A; aPORTA = $1B;
bit0=1; bit1=2; bit2=4; bit3=8; bit4=16; bit5=32; bit6=64; bit7=128;
{$R *.dfm}
type
TPString = array [0..255] of Char;
function usbGetStringAscii(handle: pusb_dev_handle; index: Integer;langid: Integer;var buf: TPString;buflen: Integer ): integer;
var
buffer: array [0..255] of char;
rval, i: Integer;
begin
rval := usb_control_msg(handle, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING shl 8) + index, langid, buffer, sizeof(buffer), 1000);
result:=rval;
if rval < 0 then exit;
result:=0;
if buffer[1] <> char(USB_DT_STRING) then Exit;
if BYTE(buffer[0]) < rval then
rval := BYTE(buffer[0]);
rval:= rval div 2;
(* преобразование к ISO Latin1 *)
for i := 1 to rval-1 do
begin
if i > buflen then (* назначить переполнение буфера *)
break;
buf[i-1] := buffer[2 * i];
if buffer[2 * i + 1] <> #0 then (*не в диапазоне ISO Latin1 *)
buf[i-1] := char('?');
end;
buf[i-1] := #0;
Result := i-1;
end;
const
USB_ERROR_NOTFOUND = 1;
USB_ERROR_ACCESS = 2;
USB_ERROR_IO = 3;
function usbOpenDevice(var device: Pusb_dev_handle; vendor: Integer; vendorName: pchar ;product: Integer; productName: pchar): Integer;
const
{$J+}
didUsbInit: integer = 0; //не константа, а статическая переменная
{$J-}
var
bus: Pusb_bus;
dev: Pusb_device;
handle: Pusb_dev_handle;
errorCode: integer;
S: TPstring;
len: Integer;
begin
handle:=nil;
errorCode := USB_ERROR_NOTFOUND;
if didUsbInit=0 then
begin
didUsbInit := 1;
usb_init;
end;
usb_find_busses;
usb_find_devices;
bus := usb_get_busses;
While assigned(bus) do
begin
dev := bus^.devices;
while assigned(dev) do
begin
if(dev.descriptor.idVendor = vendor) and (dev.descriptor.idProduct = product) then
begin
handle := usb_open(dev); (* открыть устройство для проведения необходимых запросов *)
if not assigned(handle) then
begin
errorCode := USB_ERROR_ACCESS;
raise Exception.Create('Warning: cannot open USB device '+usb_strerror());
continue;
end;
if (vendorName = nil) and (productName = nil) then break; (* имя устройства не имеет значения *)
(* проверить соответствие имён *)
len := usbGetStringAscii(handle, dev.descriptor.iManufacturer, $0409,S, sizeof(S));
if (len < 0) then
begin
errorCode := USB_ERROR_IO;
raise Exception.Create('Warning: cannot query manufacturer for device: '+usb_strerror());
end
else
begin
errorCode := USB_ERROR_NOTFOUND;
(*определить VID устройства *)
if StrPas(S)=vendorName then
begin
len := usbGetStringAscii(handle, dev.descriptor.iProduct, $0409,S, sizeof(S));
if (len < 0) then
begin
errorCode := USB_ERROR_IO;
raise Exception.Create('Warning: cannot query product for device: '+usb_strerror());
end
else
begin
errorCode := USB_ERROR_NOTFOUND;
(*определить PID устройства *)
if StrPas(S)=productName then
break;
end; //if len
end; //if string_
end; //if len<0
usb_close(handle);
handle := nil;
end; //if dev descriptor
dev := dev.next;
end; //пока назначается (dev)
if handle<>nil then break;
bus := bus.next;
end; //пока назначается (bus)
if (handle <> nil) then
begin
errorCode := 0;
device := handle;
end;
Result := errorCode;
end;
procedure SendUSBControlMessage(direction: BYTE; request, value, index, buflen: integer;var buffer: array of char);
var
handle: Pusb_dev_handle;
i: integer;
USBDEV_SHARED_VENDOR:integer;
USBDEV_SHARED_PRODUCT:integer;
Product:PANSIChar;
Vendor:PANSIChar;
begin
USBDEV_SHARED_VENDOR:=strtoint('$16C0');
USBDEV_SHARED_PRODUCT:=strtoint('$05DC');
Product:=pansichar('LEDControl');
Vendor:=pansichar('obdev.at');
usb_init();
if (usbOpenDevice(handle, USBDEV_SHARED_VENDOR, Vendor, USBDEV_SHARED_PRODUCT, Product) <> 0) then
begin
raise Exception.Create(Format(
'Could not find USB device "'+Product+'" with vid=$%x and pid=$%x !',
[USBDEV_SHARED_VENDOR, USBDEV_SHARED_PRODUCT]));
exit;
end;
usb_control_msg(handle, USB_TYPE_VENDOR or USB_RECIP_DEVICE or direction, request, value, index, buffer, sizeof(buffer), 5000);
usb_close(handle);
end;
104