? zu FT2232D/FT2232H im MPSSE-SPI-Modus

OP #7883236
Lesenswert?

Moin,

ich möchte mit einem PC-Programm einen EEPROM AT25160B mit Daten beschreiben, um ein anderes Gerät zu parametrieren. Programm (Oberfläche) in vb.net (ist neu für mich) ist fertig, nun soll der EEPROM beschrieben/gelesen werden. Im Fundus habe ich einen Adapter PLM2232 (mit FT2232D) und ein Mini Development Board mit FT2232H. Mit Hilfe von Beispielen und der FTDI-Doku habe ich mich soweit herangearbeitet, dass ich den entsprechenden Port A öffnen konfigurieren kann:

1
Dim readCmd As Byte()
2
Dim fT_STATUS
3
' eeprom lesen
4
fT_STATUS = ftdi.OpenByLocation(myFTLocId)
5

6
' Konfiguriere MPSSE und SPI: 8 Bits, MSB zuerst, Takt polarität und Phase für EEPROM
7
Dim mpsse_ret As Integer
8
Dim mpsseCommands As Byte() = {
9
    &H5,  ' Setze MPSSE in den SPI-Modus
10
    &H8,  ' Setze SPI Clock Polarity (CPOL)
11
    &H0,  ' CPOL = 0 (Idle Low)
12
    &H10, ' Setze Clock Phase (CPHA)
13
    &H0,  ' CPHA = 0 (Sample on rising edge)
14
    &H60, ' Setze Clock Divider für SPI-Geschwindigkeit (10 MHz)
15
    &H10  ' Divider für 3,75 MHz (60 MHz / 16)
16
}
17
fT_STATUS = ftdi.Write(mpsseCommands, mpsseCommands.Length, Nothing)
18

19
fT_STATUS = ftdi.SetBitMode(0, 0)   ' IO rücksetzen
20
fT_STATUS = ftdi.SetBitMode(&B1011, 2)   ' MPSSE-Modus setzen mit Bitmaske (&B1011)
21
FT_STATUS = ftdi.SetBaudRate(1000000)
22

23
fT_STATUS = ftdi.SetTimeouts(5000, 5000)    ' read-/write-timeout (ms)
24
fT_STATUS = ftdi.SetLatency(16)
25

26
Dim buffer(100) As Byte
27
' Puffer vorbelegen für debug
28
For i = 0 To 100
29
    buffer(i) = &HF0
30
Next i
31

32
' Lesekommando absetzen Adresse 0
33
readCmd = {&H3, CByte(0), CByte(0), &H0}
34
fT_STATUS = ftdi.Write(readCmd, readCmd.Length, Nothing)
35

36
' und jetzt Daten lesen
37
Dim BytesRead As UInt32
38
fT_STATUS = ftdi.Read(buffer, CUInt(20), BytesRead)
39

40
' Device wieder schließen
41
fT_STATUS = ftdi.Close()

Funktioniert soweit, allerdings gibt es ein Problem beim Lesen der Daten vom EEPROM, hier werden immer nur 14 Byte gelesen, egal wieviele angefordert werden. Werden per Parameter <= 14 Byte angefordert, funktioniert das Lesen, bei mehr als 14 Byte kommt der Timeout zum Tragen. Ich weiß hier nicht mehr weiter, auch das Herabsetzen der Baudrate auf 19600 bringt keine Änderung. FT2232D und FT2232H verhalten sich hier identisch. Ich bin mir recht sicher, dass ich irgendeinen Bock eingebaut habe und würde mich freuen, wenn ein Kundiger da unterstützen würde.

Danke für alle Hinweise,

Thomas

PS: Sollte Bedarf an Beschimpfungen bestehen, eröffne ich gerne einen zweiten Thread zum späteren Versenken.

OP #7883276
Lesenswert?

Der Code öffnet ein (vorher gesucht & gefundenes) USB-Device über den vom Betriebssystem vergebenen Locator, danach wird der FT2232D/FT2232H in den MPSSE-Modus versetzt, die SPI-Parameter eingestellt und Timeout/Laterncy-Parameter gesetzt. Dann wird ein Lesepuffer deklariert und initialisiert und der Lesebefehl in den FT2232 geschrieben. Anschließend wird gelesen und dabei in den Timeout gelaufen. FTDI meint, dass die USB-Übertragung in Stücken von irgendwas über 65.000 Bytes erfolgt, die sollten bei 14 gelesenen Bytes noch nicht erreicht sein.

Thomas

Moderator Persönliche Seite #7883297
Lesenswert?

Thomas P. schrieb:

FTDI meint, dass die USB-Übertragung in Stücken von irgendwas über 65.000 Bytes erfolgt

tja, wenn sie meinen …

Was spräche denn dagegen, dass du deinen EEPROM in kleineren Stücken liest und schreibst, statt weiter gegen Windmühlenflügel zu kämpfen?

Ich kann nochmal versuchen, MPSSE mit Python anzuwerfen und gucken, ob ich da längere Blöcke auf einmal gelesen bekomme. Habe ich bisher nie benötigt.

OP #7883314
Lesenswert?

Jörg W. schrieb:

Was spräche denn dagegen, dass du deinen EEPROM in kleineren Stücken liest und schreibst, statt weiter gegen Windmühlenflügel zu kämpfen?

Hmm, eigentlich nix, aber da FTDI die Anzahl der zu lesenden Bytes mit dem Typ Int angibt, kann ich mir nicht vorstellen, dass das wirklich nur mit 14 Bytes (und dazu noch einer so dv-technisch krummen Zahl) funktionieren soll. Irgendwas habe ich da übersehen... Jeder doofe Controller kann so einen SPI-EEPROM in ganzer Länge in einem Rutsch auslesen, da muss doch ein FT2232 wenigstens 64 Bytes am Stück lesen können. Beim Schreiben wird das dann noch verrückter, da hat der EEPROM ja page-Grenzen und wenn da noch so ein Limit dazukommen sollte, wird es noch übler.

Thomas

Moderator Persönliche Seite #7883325
Lesenswert?

Thomas P. schrieb:

Jeder doofe Controller kann so einen SPI-EEPROM in ganzer Länge in einem Rutsch auslesen, da muss doch ein FT2232 wenigstens 64 Bytes am Stück lesen können.

Das Problem ist ja nicht der FTDI, sondern der USB. Der hat halt limitierte Paketgrößen. Die Library drunter muss also deine gewünschte Datenmenge aufteilen.

Beim Schreiben wird das dann noch verrückter, da hat der EEPROM ja page-Grenzen und wenn da noch so ein Limit dazukommen sollte, wird es noch übler.

Das ist natürlich wahr.

Ich habe es gerade mit Python probiert (pyftdi.spi), da kann ich problemlos mehr als 14 Bytes am Stück lesen.

Ist nun halt die Frage, an welcher Stelle bei dir das Problem entsteht bzw. was unter deinem vb.net drunter liegt.

Moderator Persönliche Seite #7883509
Lesenswert?

Thomas P. schrieb:

Da liegt die FTD2XX_Net drunter, wie von FTDI angegeben.

Dann ist es möglicherweise ein Problem im Zusammenspiel dessen mit dem vb.net?

Unter pyftdi liegt einfach nur PyUSB und eine der möglichen libusb-Implementierungen, kein proprietärer Code von FTDI. Das haben wir bei einem früheren Projekt bereits ausgiebig auch unter Windows benutzt, um mit einem UWB-Transceiver von NXP zu reden.

OP #7883517
Lesenswert?

Jörg W. schrieb:

Thomas P. schrieb:

Da liegt die FTD2XX_Net drunter, wie von FTDI angegeben.

Dann ist es möglicherweise ein Problem im Zusammenspiel dessen mit dem vb.net?

Das weiß ich nicht, ich wollte nie tiefer in die FTD2XX_NET einsteigen und das Zeug nur benutzen, um Anwendern eine einfache Möglichkeit zur Parametrierung zu geben. Ich werde da in den nächsten Tagen mal mit dem LA drangehen und versuchen herauszufinden, ob schon der Lesevorgang des EEPROMs scheitert, oder die Datenweitergabe über den FT2332 und USB das Ganze verstümmelt.

OP #7883554
Lesenswert?

Wäre eventuell auch denkbar, wenn sich hier absolut keine Lösung oder Jemand mit einschlägiger Erfahrung finden sollte.

Mit vb kann ich einigermaßen umgehen und bin froh, die Funktionen und die Logik der Elemente der Oberfläche erfolgreich umgesetzt zu haben, bei Python würde ich wieder bei Null anfangen müssen - ich habe damit noch nie eine Oberfläche programmiert.

Moderator Persönliche Seite #7883586
Lesenswert?

Thomas P. schrieb:

bei Python würde ich wieder bei Null anfangen müssen - ich habe damit noch nie eine Oberfläche programmiert.

Wenn es nicht gerade mit kommerziellen Interessen (und Lizenzkosten) in Konflikt gerät, kann ich da PySide (Qt-Anbindung in Python, die von Qt selbst bereitgestellt wird) empfehlen. Damit bekommt man relativ schnell GUIs hin, die auch noch plattformunabhängig (Win, Mac, Unix) sein können.

(Firma: privat) #7883595
Lesenswert?

Schau dir mal die Application Note AN_135 FTDI MPSSE Basics auf der FTDI Seite an. Ist zwar nicht in vb geschrieben, aber der Ablauf sollte ähnlich sein. Im Abschnitt 5.2 "Configure FTDI Port For MPSSE Use" steht unter anderem die Zeile

1
ftStatus |= FT_SetUSBParameters(ftHandle, 65536, 65535);

So eine Zeile finde ich in deinem vb code nicht. Da wird die Transfergröße fürs Schreiben und Lesen festgelegt.

OP #7883746
Lesenswert?

Jörg W. schrieb:

Wenn es nicht gerade mit kommerziellen Interessen (und Lizenzkosten) in Konflikt gerät, kann ich da PySide (Qt-Anbindung in Python, die von Qt selbst bereitgestellt wird) empfehlen.

Danke für die Empfehlung, ist kein kommerzielles Projekt und betrifft bestenfalls 10 User. Ich behalte das mal im Hinterkopf, wenn der eingeschlagene Weg eine Sackgasse werden sollte.

Thomas E. schrieb:

Schau dir mal die Application Note AN_135 FTDI MPSSE Basics auf der FTDI Seite an. Ist zwar nicht in vb geschrieben, aber der Ablauf sollte ähnlich sein. Im Abschnitt 5.2 "Configure FTDI Port For MPSSE Use" steht unter anderem die Zeile

1
ftStatus |= FT_SetUSBParameters(ftHandle, 65536, 65535);

So eine Zeile finde ich in deinem vb code nicht. Da wird die Transfergröße fürs Schreiben und Lesen festgelegt.

Danke für den Hinweis, ich bin gerade beim Stöbern in der FTD2XX_NET, da finde ich nichts Derartiges. Da sollte es ja einen default-Wert geben. Auf der anderen Seite schlägt da mein Unwissen über die USB-Internas zu; ich kann mir nicht vorstellen, dass die Paketgröße den Nebeneffekt hat, dass nach einem Paket die Übertragung eingestellt wird. Ein Timeout von 5000 ms sollte ja ausreichen, dass weitere Pakete übertragen werden. Je kleiner die Paketgröße, je größer der Anteil des Overheads an den übertragenen Daten, das leuchtet mir noch ein, aber ein Abbruch?

Thomas

#7883775
Lesenswert?

Thomas P. schrieb:

Auf der anderen Seite schlägt da mein Unwissen über die USB-Internas zu; ich kann mir nicht vorstellen, dass die Paketgröße den Nebeneffekt hat, dass nach einem Paket die Übertragung eingestellt wird. Ein Timeout von 5000 ms sollte ja ausreichen,

Du hast vollkommen falsche Vorstellungen von USB... Die Paketgröße ist bei Fullspeed(1.1) und Bulk fest 64 Bytes pro Transfer. Bei Highspeed(2.0) wären es übrigens 512 Bytes. Auf diese Packet Size hast du aber von der Anwendungsseite keinen Zugriff und musst das auch nicht beachten. Es ist immer Aufgabe des Treibers einen Usermode Read in entsprechende Häppchen aufzuteilen. Kann ein Device einen Bulk In nicht mit Daten beantworten oder weniger als 64 Bytes liefern, so sieht USB vor mit einem Short Packet die Übertragung zu beenden. Ein Timeout kommt nur wenn nach Ablauf der Timeoutzeit immer noch nichts geliefert wurde.

Ich kenn mich mit Basic und im speziellen mit NET nicht aus, aber für mich sieht das das Read nach einem normalen gekapselten Readfile des Win OS aus.

fT_STATUS = ftdi.Read(buffer, CUInt(20), BytesRead)

In allen mir bekannten Sprachen ist BytesRead eine Zeiger Variable. (Var in Pascal, Call by Reference in C). Wie das in Net geht keine Ahnung.

Ich empfehle mal mit einem USB Sniffer auf die Übertragung zu schauen.

OP #7884611
Lesenswert?

Mal als Abschluss:

Nachdem der Versuch mit der FTD2XX_Net leider an irgendeiner Befindlichkeit der read-Funktion gescheitert ist, habe ich das Ganze jetzt mal auf die libmpsse.dll umgestellt. Geht auch nicht ohne Weiteres, da vb.net diese DLL nur über Umwege ansprechen kann. Dank ChatGPT wurde in kürzester Zeit ein Wrapper gebaut. Das ganze Konstrukt funktioniert und ich kann jetzt die gewünschten 96 Byte an einem Stück lesen und in einem Puffer ablegen, weiter bin ich noch nicht.

Danke an alle Unterstützer.

Thomas

Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren