Autor Beitrag
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Sa 02.04.11 19:11 
Hi,
ich arbeite mit libUsb und möchte mit einem usb-Microcontroller kommunizieren.
Momentan scheitere ich jedoch schon am erkennen der USB-Geräte:
Ich benutze die LibUSB.pas und device-seitig eine USB-Firmware von Stefan Salewski.
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
(* LIBUSB-WIN32, Generic Windows USB Library
 * Copyright (c) 2002-2004 Stephan Meyer <ste_meyer@web.de>
 * Copyright (c) 2000-2004 Johannes Erdfelt <johannes@erdfelt.com>
 *
 * Pascal translation
 * Copyright (c) 2004 Yvo Nelemans <ynlmns@xs4all.nl>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *)



unit LibUSB;

interface

const
  LIBUSB_PATH_MAX = 512;
  LIBUSB_DLL_NAME =  'libusb0.dll';

  USB_OK = 0// 0 = success from functions < 0 is failed


  { Device and/or Interface Class codes }
  USB_CLASS_PER_INTERFACE   =   0{ for DeviceClass }
  USB_CLASS_AUDIO           =   1;
  USB_CLASS_COMM            =   2;
  USB_CLASS_HID             =   3;
  USB_CLASS_PRINTER         =   7;
  USB_CLASS_MASS_STORAGE    =   8;
  USB_CLASS_HUB             =   9;
  USB_CLASS_DATA            =  10;
  USB_CLASS_VENDOR_SPEC     = $ff;

  // Descriptor types
  USB_DT_DEVICE     = $01;
  USB_DT_CONFIG     = $02;
  USB_DT_STRING     = $03;
  USB_DT_INTERFACE  = $04;
  USB_DT_ENDPOINT   = $05;

  USB_DT_HID        = $21;
  USB_DT_REPORT     = $22;
  USB_DT_PHYSICAL   = $23;
  USB_DT_HUB        = $29;

  // Descriptor sizes per descriptor type
  USB_DT_DEVICE_SIZE          = 18;
  USB_DT_CONFIG_SIZE          =  9;
  USB_DT_INTERFACE_SIZE       =  9;
  USB_DT_ENDPOINT_SIZE        =  7;
  USB_DT_ENDPOINT_AUDIO_SIZE  =  9// Audio extension
  USB_DT_HUB_NONVAR_SIZE      =  7;


type
  // All standard descriptors have these 2 fields in common
  usb_descriptor_header = packed record
    bLength,
    bDescriptorType: byte;
  end;

  // String descriptor
  usb_string_descriptor = packed record
    bLength,
    bDescriptorType: byte;
    wData: packed array [0..0of word;
  end;

  usb_hid_descriptor = packed record
    bLength,
    bDescriptorType: byte;
    bcdHID: word;
    bCountryCode,
    bNumDescriptors: byte;
  end;

const
  // Endpoint descriptor
  USB_MAXENDPOINTS = 32;

type
  // Endpoint descriptor
  pusb_endpoint_descriptor = ^usb_endpoint_descriptor;
  usb_endpoint_descriptor = packed record
    bLength,
    bDescriptorType,
    bEndpointAddress,
    bmAttributes: byte;

    wMaxPacketSize: word;

    bInterval,
    bRefresh,
    bSynchAddress: byte;

    extra: PByte; // Extra descriptors
    extralen: longword;
  end;
  // pascal translation of C++ struc
  TArray_usb_endpoint_descriptor =
   packed array [0..65535of usb_endpoint_descriptor;
  PArray_usb_endpoint_descriptor = ^TArray_usb_endpoint_descriptor;


const
  USB_ENDPOINT_ADDRESS_MASK      = $0f// in bEndpointAddress
  USB_ENDPOINT_DIR_MASK          = $80;

  USB_ENDPOINT_TYPE_MASK         = $03// in bmAttributes
  USB_ENDPOINT_TYPE_CONTROL      = 0;
  USB_ENDPOINT_TYPE_ISOCHRONOUS  = 1;
  USB_ENDPOINT_TYPE_BULK         = 2;
  USB_ENDPOINT_TYPE_INTERRUPT    = 3;

  // Interface descriptor
  USB_MAXINTERFACES = 32;

type
  // Interface descriptor
  pusb_interface_descriptor = ^usb_interface_descriptor;
  usb_interface_descriptor = packed record
    bLength,
    bDescriptorType,
    bInterfaceNumber,
    bAlternateSetting,
    bNumEndpoints,
    bInterfaceClass,
    bInterfaceSubClass,
    bInterfaceProtocol,
    iInterface: byte;

    endpoint: PArray_usb_endpoint_descriptor;

    extra: PByte; // Extra descriptors
    extralen: longword;
  end;
  // pascal translation of C++ struc
  TArray_usb_interface_descriptor =
   packed array [0..65535of usb_interface_descriptor;
  PArray_usb_interface_descriptor = ^TArray_usb_interface_descriptor;


const
  USB_MAXALTSETTING = 128// Hard limit

type
  pusb_interface = ^usb_interface;
  usb_interface = packed record
    altsetting: PArray_usb_interface_descriptor;
    num_altsetting: longword;
  end;
  // pascal translation of C++ struc
  TArray_usb_interface = packed array [0..65535of usb_interface;
  PArray_usb_interface = ^TArray_usb_interface;


const
  // Configuration descriptor information..
  USB_MAXCONFIG = 8;

type
  // Configuration descriptor information..
  pusb_config_descriptor = ^usb_config_descriptor;
  usb_config_descriptor = packed record
    bLength,
    bDescriptorType: byte;

    wTotalLength: word;

    bNumInterfaces,
    bConfigurationValue,
    iConfiguration,
    bmAttributes,
    MaxPower: byte;

    iinterface: PArray_usb_interface;

    extra: PByte; // Extra descriptors
    extralen: longword;
  end;
  // pascal translation of C++ struc
  TArray_usb_config_descriptor =
   packed array [0..65535of usb_config_descriptor;
  PArray_usb_config_descriptor = ^TArray_usb_config_descriptor;


  // Device descriptor
  usb_device_descriptor = packed record
    bLength,
    bDescriptorType: byte;
    bcdUSB: word;

    bDeviceClass,
    bDeviceSubClass,
    bDeviceProtocol,
    bMaxPacketSize0: byte;

    idVendor,
    idProduct,
    bcdDevice: word;

    iManufacturer,
    iProduct,
    iSerialNumber,
    bNumConfigurations: byte;
  end;

  usb_ctrl_setup = packed record
    bRequestType,
    bRequest: byte;
    wValue,
    wIndex,
    wLength: word;
  end;

const
  // Standard requests
  USB_REQ_GET_STATUS         = $00;
  USB_REQ_CLEAR_FEATURE      = $01;
  // $02 is reserved
  USB_REQ_SET_FEATURE        = $03;
  // $04 is reserved
  USB_REQ_SET_ADDRESS        = $05;
  USB_REQ_GET_DESCRIPTOR     = $06;
  USB_REQ_SET_DESCRIPTOR     = $07;
  USB_REQ_GET_CONFIGURATION  = $08;
  USB_REQ_SET_CONFIGURATION  = $09;
  USB_REQ_GET_INTERFACE      = $0A;
  USB_REQ_SET_INTERFACE      = $0B;
  USB_REQ_SYNCH_FRAME        = $0C;

  USB_TYPE_STANDARD   = ($00 shl 5);
  USB_TYPE_CLASS      = ($01 shl 5);
  USB_TYPE_VENDOR     = ($02 shl 5);
  USB_TYPE_RESERVED   = ($03 shl 5);

  USB_RECIP_DEVICE     = $00;
  USB_RECIP_INTERFACE  = $01;
  USB_RECIP_ENDPOINT   = $02;
  USB_RECIP_OTHER      = $03;

  // Various libusb API related stuff
  USB_ENDPOINT_IN   = $80;
  USB_ENDPOINT_OUT  = $00;

  // Error codes
  USB_ERROR_BEGIN  = 500000;

type
  pusb_device = ^usb_device;
  pusb_bus = ^usb_bus;

  usb_device = packed record
    next,
    prev: pusb_device;
    filename: packed array [0..LIBUSB_PATH_MAX-1of char;
    bus: pusb_bus;
    descriptor: usb_device_descriptor;
    config: PArray_usb_config_descriptor;
    dev: pointer; // Darwin support
    devnum,
     num_children: byte;
     children : ^pusb_device;
  end;

  usb_bus = packed record
    next,
    prev: pusb_bus;
    dirname: packed array [0..LIBUSB_PATH_MAX-1of char;
    devices: pusb_device;
    location: longint;
     root_dev: pusb_device;
   end;

  // Version information, Windows specific
  pusb_version = ^usb_version;
  usb_version = packed record
    dllmajor,
    dllminor,
    dllmicro,
    dllnano: longint;
    drivermajor,
    driverminor,
    drivermicro,
    drivernano: longint;
  end;

  pusb_dev_handle = pointer; // struct usb_dev_handle;


{ Function prototypes }

// usb.c
function  usb_open(dev: pusb_device): pusb_dev_handle; cdecl;
function  usb_close(dev: pusb_dev_handle): longword; cdecl;
function  usb_get_string(dev: pusb_dev_handle;index, langid: longword; var buf;buflen: longword): longword; cdecl;
function  usb_get_string_simple(dev: pusb_dev_handle;index: longword; var buf;buflen: longword): longword; cdecl;


// descriptors.c
function  usb_get_descriptor_by_endpoint(udev: pusb_dev_handle;ep: longword;ttype: byte;index: byte;var buf;size: longword): longword; cdecl;
function  usb_get_descriptor(udev: pusb_dev_handle;ttype: byte;index: byte;var buf;size: longword): longword; cdecl;

// <arch>.c
function  usb_bulk_write(dev: pusb_dev_handle;ep : longword; var bytes;size,timeout:longword): longword; cdecl;
function  usb_bulk_read(dev: pusb_dev_handle;ep: longword; var bytes; size,timeout:longword): longword; cdecl;

function  usb_interrupt_write(dev: pusb_dev_handle;ep : longword; var bytes; size, timeout: longword): longword; cdecl;
function  usb_interrupt_read(dev: pusb_dev_handle;ep : longword; var bytes; size, timeout: longword): longword; cdecl;
function  usb_control_msg(dev: pusb_dev_handle;requesttype, request, value, index: longword;var bytes;size, timeout: longword): longword; cdecl;
function  usb_set_configuration(dev: pusb_dev_handle;configuration: longword): longword; cdecl;
function  usb_claim_interface(dev: pusb_dev_handle;iinterface: longword): longword;  cdecl// was interface, a pascal reserved word
function  usb_release_interface(dev: pusb_dev_handle;iinterface: longword): longword; cdecl;
function  usb_set_altinterface(dev: pusb_dev_handle;alternate: longword): longword; cdecl;
function  usb_resetep(dev: pusb_dev_handle;ep: longword): longword; cdecl;
function  usb_clear_halt(dev: pusb_dev_handle;ep: longword): longword; cdecl;
function  usb_reset(dev: pusb_dev_handle): longword; cdecl;

function usb_strerror: pchar; cdecl;

procedure usb_init; cdecl;
procedure usb_set_debug(level: longword); cdecl;
function  usb_find_busses: longword; cdecl;
function  usb_find_devices: longword; cdecl;
function  usb_get_device(dev: pusb_dev_handle): pusb_device;  cdecl// renamed from usb_device because of same named record
function  usb_get_busses: pusb_bus; cdecl;

function  usb_install_service_np: integer; cdecl;
function  usb_uninstall_service_np: integer; cdecl;
function  usb_install_driver_np(inf_file: PChar): integer; cdecl;
function  usb_get_version: pusb_version; cdecl;
function  usb_isochronous_setup_async(dev: pusb_dev_handle; var context: pointer; ep: char; pktsize: integer): integer; cdecl;
function  usb_bulk_setup_async(dev: pusb_dev_handle; var context: pointer; ep: char): integer; cdecl;
function  usb_interrupt_setup_async(dev: pusb_dev_handle; var context: pointer; ep: char): integer; cdecl;
function  usb_submit_async(context: pointer; bytes: PByte; size: integer): integer; cdecl;
function  usb_reap_async(context: pointer; timeout: integer): integer; cdecl;
function  usb_free_async(var context: pointer): integer; cdecl;


implementation


function  usb_open(dev: pusb_device): pusb_dev_handle; cdeclexternal LIBUSB_DLL_NAME name 'usb_open';
function  usb_close(dev: pusb_dev_handle): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_close';
function  usb_get_string(dev: pusb_dev_handle;index, langid: longword;var buf;buflen: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_get_string';
function  usb_get_string_simple(dev: pusb_dev_handle;index: longword;var buf;buflen: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_get_string_simple';


// descriptors.c
function  usb_get_descriptor_by_endpoint(udev: pusb_dev_handle;ep: longword;ttype: byte;index: byte;var buf;size: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_get_descriptor_by_endpoint';
function  usb_get_descriptor(udev: pusb_dev_handle;ttype: byte;index: byte;var buf;size: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_get_descriptor';

// <arch>.c
function  usb_bulk_write(dev: pusb_dev_handle;ep : longword; var bytes;size,timeout:longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_bulk_write';
function  usb_bulk_read(dev: pusb_dev_handle;ep: longword; var bytes; size,timeout:longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_bulk_read';

function  usb_interrupt_write(dev: pusb_dev_handle;ep : longword; var bytes; size, timeout: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_interrupt_write';
function  usb_interrupt_read(dev: pusb_dev_handle;ep : longword; var bytes; size, timeout: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_interrupt_read';
function  usb_control_msg(dev: pusb_dev_handle;requesttype, request, value, index: longword;var bytes;size, timeout: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_control_msg';
function  usb_set_configuration(dev: pusb_dev_handle;configuration: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_set_configuration';
function  usb_claim_interface(dev: pusb_dev_handle;iinterface: longword): longword;  cdeclexternal LIBUSB_DLL_NAME name 'usb_claim_interface';// was interface, a pascal reserved word
function  usb_release_interface(dev: pusb_dev_handle;iinterface: longword): longword;  cdeclexternal LIBUSB_DLL_NAME name 'usb_release_interface';
function  usb_set_altinterface(dev: pusb_dev_handle;alternate: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_set_altinterface';
function  usb_resetep(dev: pusb_dev_handle;ep: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_resetep';
function  usb_clear_halt(dev: pusb_dev_handle;ep: longword): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_clear_halt';
function  usb_reset(dev: pusb_dev_handle): longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_reset';

function  usb_strerror: pchar; cdeclexternal LIBUSB_DLL_NAME name 'usb_strerror';

procedure usb_init; cdeclexternal LIBUSB_DLL_NAME name 'usb_init';
procedure usb_set_debug(level: longword); cdeclexternal LIBUSB_DLL_NAME name 'usb_set_debug';
function  usb_find_busses: longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_find_busses';
function  usb_find_devices: longword; cdeclexternal LIBUSB_DLL_NAME name 'usb_find_devices';
function  usb_get_device(dev: pusb_dev_handle): pusb_device;  cdeclexternal LIBUSB_DLL_NAME name 'usb_device'// renamed from usb_device because of same named record
function  usb_get_busses: pusb_bus; cdeclexternal LIBUSB_DLL_NAME name 'usb_get_busses';

function  usb_install_service_np; cdeclexternal LIBUSB_DLL_NAME name 'usb_install_service_np';
function  usb_uninstall_service_np; cdeclexternal LIBUSB_DLL_NAME name 'usb_uninstall_service_np';
function  usb_install_driver_np; cdeclexternal LIBUSB_DLL_NAME name 'usb_install_driver_np';
function  usb_get_version; cdeclexternal LIBUSB_DLL_NAME name 'usb_get_version';
function  usb_isochronous_setup_async; cdeclexternal LIBUSB_DLL_NAME name 'usb_isochronous_setup_async';
function  usb_bulk_setup_async; cdeclexternal LIBUSB_DLL_NAME name 'usb_bulk_setup_async';
function  usb_interrupt_setup_async; cdeclexternal LIBUSB_DLL_NAME name 'usb_interrupt_setup_async';
function  usb_submit_async; cdeclexternal LIBUSB_DLL_NAME name 'usb_submit_async';
function  usb_reap_async; cdeclexternal LIBUSB_DLL_NAME name 'usb_reap_async';
function  usb_free_async; cdeclexternal LIBUSB_DLL_NAME name 'usb_free_async';


end.

Dort liegt eine Demo (für Linux und in C) bei, welche ich für Delphi und Win32 umbauen wollte.
Ich habe im original folgende Funktion:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
static struct usb_device
*UsbFindDevice(void)
{
  struct usb_bus *bus;
  struct usb_device *dev;
  usb_init();
  usb_find_busses();
  usb_find_devices();
  for (bus = usb_busses; bus; bus = bus->next)
  {
    for (dev = bus->devices; dev; dev = dev->next)
    {
      if ((dev->descriptor.idVendor == MyUSB_VendorID) && (dev->descriptor.idProduct == MyUSB_ProductID))
        return dev;
    }
  }
  return NULL;
}


und daraus folgendes gemacht:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
function USBFinddevice: pUSB_Device;
var bus: PUSB_BUS;
    dev: PUSB_device;
begin
  result := nil;
  usb_init();
  form1.ListBox1.Items.Add('Busses: '+inttostr(usb_find_busses()));
  form1.ListBox1.Items.Add('Devices: '+inttostr(usb_find_devices));
  bus:=USB_get_Busses;
  form1.ListBox1.Items.Add('Entering While');
  while (bus<>nildo
  begin
    dev:=bus.devices;
    form1.ListBox1.Items.Add('Bus Found: '+bus.dirname);
    while (dev<>nildo
    begin
      form1.ListBox1.Items.Add('VID Found: '+ inttostr(dev.descriptor.idVendor)+'; PID: '+inttostr(dev.descriptor.idProduct));
      if (dev.descriptor.idVendor=MyUSB_VendorID) and (dev.descriptor.idProduct= MyUSB_ProductID) then
      begin
        result:=dev;
      end;
      dev:=dev.next;
    end;
    bus:=bus.next;
  end;
  showmessage (usb_strerror);
end;

Auf meinem PC mit Windows 7 werden tadellos alle USB-Geräte erkannt.
Auf dem Test-PC mit XP leider nicht.
Obwohl ich extra einige USB-Testgeräte angehängt habe, findet er 0 Devices und usb_strerror sagt immer andere Sachen: Manchmal "No Error", manchmal "couldn't read device descriptor",.
Allerdings gibt usb_find_devices scheinbar immer 0 zurück, obwohl mehrere USB-Geräte angeschlossen sind.
Vielleicht findet ja irgendjemand einen dummen Fehler oder so...
mfg Boldar