Forum: Mikrocontroller und Digitale Elektronik ? zu FT2232D/FT2232H im MPSSE-SPI-Modus


von Thomas P. (topla)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Schuss ins Blaue (ohne irgendwie zu verstehen, was der Code macht): mehr 
passt  nicht in ein USB-Paket rein als Antwort. Wenn du mehr lesen 
willst, musst du das aufteilen.

von Thomas P. (topla)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Thomas P. (topla)


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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Thomas P. (topla)


Lesenswert?

Da liegt die FTD2XX_Net drunter, wie von FTDI angegeben.

Thomas

von Jim M. (turboj)


Lesenswert?

Vor >10 Jahren hatte ich sowas schon mal mit flashrom 
(https://www.flashrom.org/) gemacht.

Das hat Unterstützung für FT2232 Chips als Schnittstelle und etliche 
Flash ROM Targets.

Dürfte erheblich einfacher sein als sich das MPSSE Zeuchs selbst zu 
erarbeiten.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Thomas P. (topla)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Thomas P. schrieb:
> das Zeug nur benutzen, um Anwendern eine einfache Möglichkeit zur
> Parametrierung zu geben

Die Python-Variante käme dafür nicht in Frage?

von Thomas P. (topla)


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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Thomas E. (Firma: privat) (iseldur)


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.

von Thomas P. (topla)


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

von Thomas Z. (usbman)


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.

von Thomas P. (topla)


Angehängte Dateien:

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

von Thomas Z. (usbman)


Lesenswert?

ByRef dürfte die Lösung sein (Call by Reference wie ich schon angemerkt 
hatte) Ich kenn mich aber mit VB bzw NET nicht im Detail aus.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.