Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi USBDescriptoren einer Cypress-USB-Geräts auslesen (https://www.delphipraxis.net/97170-usbdescriptoren-einer-cypress-usb-geraets-auslesen.html)

dj9nmh 6. Aug 2007 10:25


USBDescriptoren einer Cypress-USB-Geräts auslesen
 
Hallo zusammen,

Ich beschäftige mich im Moment (Praxissemester) damit den Device- und String-Descriptor aus einer Cypress-USBKomponente auszulesen.
Für mein Projekt habe ich schon ein fertiges Programm, dass diese beiden Descriptoren für ein eigenes USBDevice mittels einen eigenen Drivers über DeviceIOControl ausliest. Nun soll dieses Programm erweitert werden und eben diese zwei Descriptoren aus einem CypressUSBDevice ausgelesen werden.
Mir wurde eine Cyress SuiteUSB.NET 2.0 mit einer 'CyUSB.dll' zur Verfügung gestellt. Damit wäre es möglich die gewünschten Descriptoren auszulesen. Doch wie es der Name schon sagt, ist die Verwendung nur mit .NET möglich. Meine Anwendung ist aber WIN32...

Nun meine Frage: Kennt jemand eine WIN32 Lösung, mit der ich für diese Komponente den Descriptor auslesen kann?

thx schonmal für Antworten,

Stefan

Robert Marquardt 6. Aug 2007 12:30

Re: USBDescriptoren einer Cypress-USB-Geräts auslesen
 
Na da duerfte auch nichts anderes dahinter stecken als DeviceIoControls an den Cypress Treiber. Probier doch erst mal die bisherigen DeviceIoControls aus. Treiberentwickler sind faul und aendern so leicht ein API nicht. Das ist ja auch eine Geldfrage, denn man muss den Treiber bei MS signieren lassen.
Ansonsten gibt es noch den generischen Weg ueber den Hub-Treiber. Das ist nur im Beispiel USBView des DDKs dokumentiert und daher in C programmiert.

dj9nmh 10. Aug 2007 10:58

Re: USBDescriptoren einer Cypress-USB-Geräts auslesen
 
So also an den DeviceDescriptor komme ich mittlerweile ran. Dies funktioniert über ein DeviceIOControl mit Control_Transfer. Beim StringDescriptor bin ich noch am testen.
Könnte es sein, dass dies der Standard-Weg ist an den Descriptor ranzukommen?
Ich kopiere mal die interessanten Zeilen aus meinem Testquellcode raus, evtl hat ja irgendjemand mal Nutzen davon:

Habe den Quellcode mit dem CyPress-Driver (CyUSB.sys Version 1.07.0000.0 Release) aus dem USBDevStudio benutzt, welches es auf cypress.com zum download gibt.

Delphi-Quellcode:
type
  SETUP_PACKET = packed record
    bmRequest : UChar;
    bRequest : UChar;
    wValue   : WORD;
    wIndex   : WORD;
    wLength  : WORD;
    ulTimeOut : ULong;
  end;

  SINGLE_TRANSFER = packed record
    SetupPacket      : SETUP_PACKET;
    WaitForever      : UChar;
    ucEndpointAddress : UChar;
    NtStatus         : ULong;
    UsbdStatus       : ULong;
    IsoPacketOffset  : ULong;
    IsoPacketLength  : ULong;
    BufferOffset     : ULong;
    BufferLength     : ULong;
  end;
Delphi-Quellcode:
  const
    METHOD_BUFFERED  =  0;
    METHOD_IN_DIRECT =  1;
    METHOD_OUT_DIRECT =  2;
    METHOD_NEITHER   =  3;


    FILE_ANY_ACCESS  =      0;
    FILE_READ_ACCESS =  $0001;
    FILW_WRITE_ACCESS =  $0002;
    FILE_DEVICE_UNKNOWN: DEVICE_TYPE = $0C0000022;
Delphi-Quellcode:
  var
    DeviceHandle : THandle;
    Success : Boolean;
    nBytes: LongWord;
    IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER : DWord;
    Buffer : Array[0..1023] of Byte; // hier kleineren Buffer wählen
    SingleTransfer : SINGLE_TRANSFER;
    BufferLen : Integer;
Delphi-Quellcode:
  BufferLen := SizeOf(USB_DEVICE_DESCRIPTOR);
  SingleTransfer.SetupPacket.bmRequest := $00;
  SingleTransfer.SetupPacket.bRequest := 6;
  SingleTransfer.SetupPacket.wValue := $0100;

  SingleTransfer.SetupPacket.wIndex := $0000;

  SingleTransfer.SetupPacket.wLength := BufferLen;
  SingleTransfer.SetupPacket.ulTimeOut := 1000;

  SingleTransfer.WaitForever := 0;

  SingleTransfer.ucEndpointAddress := $00;
  SingleTransfer.IsoPacketLength := 0;
  SingleTransfer.BufferOffset := SizeOf(SINGLE_TRANSFER);
  SingleTransfer.BufferLength := BufferLen;
Delphi-Quellcode:
  IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER := CTL_CODE(FILE_DEVICE_UNKNOWN,
                                                    8,
                                                    METHOD_BUFFERED,
                                                    FILE_ANY_ACCESS);

  //DeviceHandle bekommt man über ein CreateFile des Devices
  success := DeviceIoControl(DeviceHandle,
                             IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER,
                             @SingleTransfer,
                             SizeOf(SINGLE_TRANSFER) + BufferLen,
                             @Buffer,
                             SizeOf(Buffer),
                             nBytes,
                             NIL);

  // in die DescriptorStruktur kopieren
  Move(Buffer[38], DC, SizeOf(DC));
Delphi-Quellcode:
  function TForm1.CTL_CODE (Devicetype: DWord; Func, Method, Access: Word) : DWord;
    begin
      CTL_CODE := (Devicetype shl 16) OR (Access shl 14) Or (Func shl 2) Or Method;
  end;

Robert Marquardt 10. Aug 2007 15:31

Re: USBDescriptoren einer Cypress-USB-Geräts auslesen
 
Es gibt keinen Standardweg an den Deskriptor zu kommen. Der Weg ueber den Hub-Treiber ist nicht wirklich offiziell. Eigentlich eine Frechheit von Microsoft, aber so ist es nun mal.
CTL_CODE braucht man nicht als Funktion zu uebersetzen. Das Makro CTL_CODE wird immer nur zur Deklaration von Konstanten verwendet. Man konvertiert also das File mit den Konstanten und verwendet diese.

dj9nmh 13. Aug 2007 13:39

Re: USBDescriptoren einer Cypress-USB-Geräts auslesen
 
So und nu noch die Lösung zum StringDescriptor:

Funktionieren tuts so wie beim DeviceDescriptor nur mit dem Unterschied, dass paar Werte anders gesetzt sind.

Bei der ganzen Sache sollte BufferLen nicht zu klein gewählt werden.

über ein ControlTransfer mit wIndex := $0000 und wValue := $0300 bekommt man die LanguageIDs für den StringDescriptor.
wIndex dann auf die gewünschte LanguageID setzen (hier: wIndex := $0409 für Englisch )
für wValue bekommt man folgende Strings:

wValue := $0301 // Manufacture
wValue := $0302 // Product
wValue := $0303 // SerialNo

Nach dem ControlTransfer den Buffer dann noch ab dem Byte 40 auf einen String casten und schon hat man den gewünschten StringDescriptor.


Den Cypress-Support habe ich zu dieser Problematik auch bemüht, bekam da aber nur unter anderem so eine Antwort:

"We have the Get Dev button that helps in getting the device descriptors in the Ez-SUB interface. We do not provide the source code for the Ez USB interface in the CyConsole."

Ich gehe wohl davon aus, dass dies wohl der Weg ist, den sie nicht verraten.

Robert Marquardt 13. Aug 2007 14:18

Re: USBDescriptoren einer Cypress-USB-Geräts auslesen
 
Da sollte man die Werte dann noch richtig aus dem Deskriptor beziehen. Es besteht keine Notwendigkeit das die Manufacturer-, Product und SerialNumber-Strings an den Positionen 1, und 3 sind.
Der Treiber macht hier offensichtlich einfach USB-Control-Transfers moeglich. Damit kommt man natuerlich an alles was man will.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:50 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz