Forum: Mikrocontroller und Digitale Elektronik SPI mit FT2232H


von Marius S. (lupin) Benutzerseite


Lesenswert?

Hat schonmal jemand den FT2232H als USB->SPI Wandler erfolgreich 
eingesetzt?

Ich habe das Problem, dass ich die Beispiele und die Doku zur SPI DLL 
ziemlich unverständlich finde.

z.B. verstehe ich nicht warum es bei der Funktion 
SPI_WriteHiSpeedDevice() einen Control- und einen Daten-Buffer gibt - 
worin besteht da der Unterschied? Was wird wie gesendet? Oder warum muss 
ich bei dieser Funktion den Status der GPIOH1-8 pins übergeben? Ich will 
doch nur Daten auf den SPI Bus schreiben (die GPIOs sind für mich 
uninteressant).

Außerdem wirkt sich die Clock-Rate Einstellung gar nicht aus...

Ich möchte einfach nur 28 Bits per SPI raus schieben, andere Funktionen 
wie GPIOs usw interessieren micht nicht.

Vielleicht hat jemand einen erprobten Source-Code?

von Willivonbienemaya .. (willivonbienemaya)


Lesenswert?

Das halbe Dokument besteht aus Beispielcode:
http://www.ftdichip.com/Projects/MPSSE/AN_114_FTDI_Hi_Speed_USB_To_SPI_Example.pdf

Schau dir mal dieses Dokument noch an:
http://www.ftdichip.com/Documents/ProgramGuides/AN_111_Programmers_Guide_for_High_Speed_FTCSPI_DLL.pdf

Darin sind zu deiner genannten Funktion "SPI_WriteHiSpeedDevice()" 4 
Seiten Erklärung. Ich habs mir nicht durchgelesen, aber da sollte was 
dabei sein.

von Marius S. (lupin) Benutzerseite


Lesenswert?

Ich merke gerade, dass es mit den Funktionen der SPI DLL nicht möglich 
ist gleichzeitig zu schreiben und zu lesen.

Also ich rufe die ReadHiSpeedDevice Funktion auf um 28 Bits zu schreiben 
und 28 Bits zu lesen - es werden dann insgesammt 56 Bits übertragen 
anstatt, wie erwartet, 28 Bits zu schreiben und gleichzeitig zu lesen...

Deshalb habe ich jetzt versucht auf direkte MPSSE Programmierung um zu 
steigen. Jetzt möchte ich erstmal 4 Bytes (also 32 Bit) per MPSSE Befehl 
0x34 übertragen. Das erste Byte wird richtig raus getaktet (Daten werden 
mit Low-Flanke gesetzt und stehen bei High-Flanke zum senden an) - das 
zweite Byte wird genau anders rum gesendet...

Liegt wahrscheinlich daran, dass beim achten Clock-Cycle was falsch 
läuft (der Cycle ist doppelt so lang wie die anderen).

Macht echt riesig Spass diese Programmierung... :)

von Marius S. (lupin) Benutzerseite


Lesenswert?

hatte den falschen mode erwischt denke ich... ich werd meinen code hier 
mal rein stellen wenn ich das fertig habe.

von Ralf (Gast)


Lesenswert?

> Macht echt riesig Spass diese Programmierung... :)
Ja, ich bin auch grad dran, die Steuerung in C++/C# zu realisieren... 
Rauskommen soll ne DLL, damit das ganze mal ordentlich ist, keine 
Ahnung, um wieviel Ecken die FTDI-Programmier denken, aber den Stuß, den 
sie für SPI/I2C/etc. zur Verfügung stellen kannste inne Tonne kloppen...

> hatte den falschen mode erwischt denke ich... ich werd meinen code hier
> mal rein stellen wenn ich das fertig habe.
Hört sich gut, werde ich denke ich mit meinem Code auch machen...

Ralf

von Stephan L (Gast)


Lesenswert?

Wollte mal fragen ob ihr schon weiter gekommen seit mit euren Code!?

Versuche gerade die SPI - Testapplikation(C++) von der FTDI Seite um 
zuschreiben, so das ich mit der SPI_Write/ReadHiSpeedDevice Funktion 
einfach 2 Byte raus schicke bzw lese. Muss aber sagen das es mir ähnlich 
geht wie Marius, da mich manche Funktionen wei z.B schon erwähnt die 
GPIO´s überhaupt nicht interessieren. Auch die Doku der netten Leute von 
FTDI finde ich nicht gerade hilfreich dabei. Deswegen stagniert mein 
Vorhaben zur Zeit auch ein wenig. Wäre für neue Ideen offen!

von Thanne (Gast)


Lesenswert?

Hi Forum,

Marius, Ralf, seid ihr scho weitergekommen? Ich bin ganz neu, was sowohl 
das Programmieren als auch SPI FTDI & Co betrifft.
Ich würde gern mit c# programmieren und habe vor an den FTDI 4232h einen 
D/A wandler anzuschliessen. die erste Frage, die ich habe ist, was muss 
ich alles in dem MS Visual Basic Project verlinken? Ich hatte zunächst 
diese wrapper dll von der FTDI homnepage eingebunden und konnte damit 
auch ein bisschen programmieren, aber wenn ich es richtig verstanden 
habe, dann kann ich damit nicht das SPI ansprechen ?!
Wie also muss ich mein Projekt aufbauen, damit ich diese SPI Funktionen 
benutzen kann?
Werd mir jetzt mal das Doc von Willivonbienemaya reinziehen, aber wenn 
ihr Teile oder den Anfang von Euren Fortschritten offenbart wäre das 
toll.

Hilfe Tips und Anregung nehme ich gern an.

Servus

von Ralf (Gast)


Lesenswert?

Hi Thanne,

ich hab dummerweise mehrere Projekte parallel am Laufen, am FTDI-Treiber 
bastle ich zwar auch, aber das geht aufgrund der nötigen Projektwechsel 
nicht so schnell wie ich's gerne hätte.

Die SPI/I²C/JTAG-DLLs von FTDI verwenden die D2xx.DLL um mit den Devices 
zu kommunizieren und die Teile entsprechend zu konfigurieren, d.h. die 
DLLs sind auch nur Wrapper für die D2xx.DLL. Ich weiss nicht wer bei 
FTDI damals die DLLs für die Schnittstellen geschrieben hatte, 
jedenfalls waren die Dinger grausig, von der Bedienung her umständlich 
und es mussten Parameter übergeben werden, deren Sinn sich mir bis heute 
entzieht. Und zumindest mit der damaligen SPI-DLL war es nicht 
möglich, gleichzeitig zu senden und zu empfangen, obwohl es die Devices 
eigentlich unterstützen. Ich weiss nicht ob's mittlerweile besser 
geworden ist, mein Eindruck war, dass die DLL von jemandem kam, der 
keine Ahnung von Controllern bzw. Elektronik hatte.

Ich habe dann ebenfalls die D2xx.DLL als Basis genommen, und eigene I²C 
und SPI-DLLs geschrieben, was sehr gut funktioniert hat, denn das 
Programmierhandbuch für die D2xx.DLL ist wesentlich verständlicher als 
die Handbücher für die Schnittstellen-DLLs.
Du kannst jetzt also die SPI-DLL von FTDI verwenden, wenn diese für dich 
ausreicht:
http://www.ftdichip.com/Documents/AppNotes.htm -> AN111
http://www.ftdichip.com/Projects/MPSSE/FTCSPI.htm

Andernfalls kannst du mit diesen zusätzlichen Dokumenten eigene 
Interface-Treiber schreiben, indem du dein Device im MPSSE-Modus 
ansprichst:
AN108, AN114 und AN135 aus den o.g.AppNotes und:
http://www.ftdichip.com/Projects/MPSSE
http://www.ftdichip.com/Documents/AppNotes.htm

Insgesamt würde ich dir folgende Vorgehensweise empfehlen: Verwende 
zuerst die FTDI-SPI-DLL, und schaue, ob sie für dich ausreichend ist. 
Wenn nicht, mach eine eigene Implementierung. Fragen was die 
Programmierung in VS betrifft bzw. falls es nicht klappt mit dem 
Einbinden kannst du auch hier.
Zusätzlich gibt's noch dieses Dokument:
http://www.ftdichip.com/Documents/TechnicalNotes -> TN109

Was die Hardware betrifft, poste deine Schaltung hier, bevor du sie 
herstellst, dann kann sie jemand prüfen, nicht dass du dir den Port 
zerbröselst oder der DA-Wandler stirbt.

Ralf

von Marius S. (lupin) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ich bin mittlerweile mit meiner Anwendung fertig. So schlimm wie ich 
zuerst dachte ist die Programmierung ja gar nicht. Eigentlich alles ganz 
easy und verständlich.

Habe mal meine Anwendung dran gehangen. Ich programmiere damit über ein 
CPLD ein paralleles flash (32 Bit Schieberegister).

von Uwe H. (uwehermann) Benutzerseite


Lesenswert?

Falls da noch Bedarf besteht, für Linux bzw. libftdi gibts in flashrom 
(eine Open-Source BIOS-Chip Programmer Software) Beispielcode der MPSSE 
bzw. Bitbang SPI benutzt um SPI Flash ROM Chips zu programmieren:

http://www.flashrom.org/FT2232SPI_Programmer
http://flashrom.org/trac/flashrom/browser/trunk/ft2232_spi.c

Uwe.

von Thanne (Gast)


Angehängte Dateien:

Lesenswert?

Sers Ralf und Forum,

danke für die Antworten, Rat und Hilfe.

Ich bin soweit, dass ich das Projekt zum laufen bekommen habe und auch 
ein wenig mit dem FTDI4232h kommunizieren kann.
Folgender link führt zu dem Dokument von FTDI, aus dem ich Schaltung 6.1 
benutze.

http://www.google.de/url?sa=t&source=web&ved=0CB0QFjAA&url=http%3A%2F%2Fwww.ftdichip.com%2FDocuments%2FDataSheets%2FDS_FT4232H_V207.pdf&rct=j&q=ftdi+%22quad+high+speed+usb+to+multipurpose+uart%2C+mpsse+ic%22&ei=DTL2S8bzLo6InQO5zN3HAg&usg=AFQjCNFnjc6cuAVDqBP9vyoi8k8EGm8a4g

Das angehängte Bild ist der Schaltplan, dessen Realisierung vor mir auf 
dem Schreibtisch liegt. Aus einigen von Ralf angegebenen Dokumenten 
(AN114, AN111) und aus
http://www.ftdichip.com/Projects/MPSSE/FTCSPI.htm
C# Beispiel versuche ich, mir was zusammenzubasteln. Wie gesagt ich bin 
praktisch unerfahren, was Programmieren und diese Chips angeht.

Bisher habe ich es geschafft, in meinem Projekt die .Net wrapper dll 
einzubinden, die Typdefinitionen und die SPI Funktionen zu importieren, 
damit ich die FTCSPI.dll benutzen kann. Im FTCSPI Programmers guide
http://www.ftdichip.com/Documents/ProgramGuides.htm
steht eine für mich nicht so toll verständliche Funktionenbeschreibung.
Von denen habe ich erfolgreich benutzen können:
SPI_GetNumHiSpeedDevices
SPI_GetHiSpeedDeviceNameLocIDChannel
SPI_OpenHiSpeedDevice
SPI_GetHiSpeedDeviceType
SPI_GetHiSpeedDeviceClock
GetDllVersion
Mien Programm erkennt also bisher brav den FT4232, was angestöpselt ist 
und auch einen Channel A und Channel B, was die 2 SPI Busse sein 
müssten.

Mir ist jetzt überhaupt nicht klar, wie ich jetzt lesen und schreiben 
kann (also was ich mit SPI_SetHiSpeedDeviceGPIOs und 
SPI_GetHiSpeedDeviceGPIOs machen muss) wozu die SPI_InitDevice Fktn ist 
(bzw. ob die auch für den 4232 ist, denn es steht da nicht explizit) und 
was es mit dem ChipSelect auf sich hat. Wahrscheinlich liegt das alles 
daran, dass ich noch nciht verstanden habe, wie der 
Übertragungsmechanismus funktioniert. Wenn mir da jemand helfen mit 
Erklärung könnte oder ein gutes Dokument empfehlen kann, wäre ich sehr 
dankbar.

Sind denn die 2 SPI unabhängig voneinander, also könnte ich den channel 
A mit einem D/A Wandler und den channel B mit was anderem benutzen?

Vielen Dank für Eure Hilfe,

Thanne

von Kim Vogelmann (Gast)


Lesenswert?

Hallo zusammen,

sorry dass ich noch einmal so einen alten Thread hervorhole.
Es geht hier aber genau um mein Problem:

Ich kann mit C# den FT2232H ansprechen und über die FTCSPI.dll von FTDI 
die SPI-Schnittstelle verwenden. Die dort vorhandene Funktion SPI_Read 
lässt aber nicht zu, dass sofort und gleichzeitig auch Daten eingelesen 
werden können.

Kennt jemand einen guten Link zu einem Beispiel, dass statt der 
FTCSPI.dll eine bessere selbst geschriebene verwendet? Oder sonst 
irgendwie die SPI-Schnittstelle besser implementiert..

Vielen Dank.

Kim

von Ralf (Gast)


Lesenswert?

Hi Kim,

ich würde vorschlagen, dass du das selbst implementierst, also die 
FT2xx.DLL verwendest und darauf aufbauend eine eigene SPI-Steuerung 
machst (nichts anderes sind die I2C/SPI/etc.-DLLs von FTDI).
Wie du die speziellen Funktionen aktivierst und verwendest steht in den 
ProgrammerGuides und ApplicationNotes beschrieben:

http://www.ftdichip.com/Support/Documents/ProgramGuides.htm
-> D2XX Programmer's Guide

http://www.ftdichip.com/Support/Documents/AppNotes.htm
-> Command Processor For MPSSE and MCU Host Bus Emulation Modes
-> Interfacing FT2232H Hi-Speed Devices To SPI Bus
-> MPSSE Basics

Wenn du Fragen oder Schwierigkeiten hast, einfach nochmal melden.

Ralf

von Kim Vogelmann (Gast)


Lesenswert?

Hallo Ralf,

vielen Dank schon mal für die Infos.
AN 108 und AN135 sind also die Dokumente, mit denen ich mich 
beschäftigen muss.

Ich hätte mal noch eine Frage zum FT_2232H_Mini_Module. Darauf befindet 
sich ein EEPROM. Wozu wird das verwendet? Ist das irgendwie relevant für 
eine SPI-Erzeugung?

Kim

von Ralf (Gast)


Lesenswert?

> Ich hätte mal noch eine Frage zum FT_2232H_Mini_Module. Darauf befindet
> sich ein EEPROM. Wozu wird das verwendet? Ist das irgendwie relevant für
> eine SPI-Erzeugung?
Ohne jetzt einen Blick in die Datenblätter zu werfen behaupte ich nein. 
Es sei denn, der MPSSE-Modus kann nur im EEPROM hinterlegt werden.

Ralf

von Kim Vogelmann (Gast)


Lesenswert?

Ich habe jetzt die SPI-Erzeugung mit Hilfe der AN 108 erzeugt. Mit dem 
opcode 0x10 (S.8) kann ich die Daten bei positiver Flanke und mit 0x11 
bei negativer Flanke clocken. Dies entspricht SPI-Mode 0 und 2. Ich 
bräuchte aber SPI-Mode 1. Wie kann ich das mit dem FT2232H realisieren?

Vielen Dank.
Kim

von Ralf (Gast)


Lesenswert?

Zeig mal deinen Code mit Kommentaren, dann kann man auch die Stelle 
sehen, an der geändertet werden müsste.

Ralf

von Kim Vogelmann (Gast)


Lesenswert?

Anbei mein Code. Da ich Mode 1 benötige, habe ich eine positive Flanke 
am Anfang selbst eingefügt. Das Problem ist, dass beim Befehl 0x10 am 
Schluss immer noch der CLK auf 1 geht. Also bevor CS wieder auf 1 geht, 
kommt noch eine positive Flanke. Kann man das irgendwie vermeiden?

Kim
1
myFtdiDevice.Purge(FTDI.FT_PURGE.FT_PURGE_RX);
2
myFtdiDevice.Purge(FTDI.FT_PURGE.FT_PURGE_TX);  
3
      
4
//CS auf 0 setzen
5
dwNumBytesToSend = 0; // Reset output buffer pointer
6
byOutputBuffer[dwNumBytesToSend++] = 0x80; // Set data bits low-byte of MPSSE port
7
byOutputBuffer[dwNumBytesToSend++] = 0x00;//CS auf 0
8
byOutputBuffer[dwNumBytesToSend++] = 0xFB; //Directions bleiben gleich
9
      
10
//CLK auf 1 setzen
11
byOutputBuffer[dwNumBytesToSend++] = 0x80; // Set data bits low-byte of MPSSE port
12
byOutputBuffer[dwNumBytesToSend++] = 0x01;//CLK auf 1
13
byOutputBuffer[dwNumBytesToSend++] = 0xFB; //Directions bleiben gleich
14
15
      
16
byOutputBuffer[dwNumBytesToSend++] = 0x10;// Output on rising clock
17
byOutputBuffer[dwNumBytesToSend++] = 0x01; // Length Lowbyte
18
byOutputBuffer[dwNumBytesToSend++] = 0x00; // Length Highbyte
19
byOutputBuffer[dwNumBytesToSend++] = 0xC5; // Datenbyte 1
20
byOutputBuffer[dwNumBytesToSend++] = 0x24; // Datenbyte 2
21
22
      
23
byOutputBuffer[dwNumBytesToSend++] = 0x80; // Set data bits low-byte of MPSSE port
24
byOutputBuffer[dwNumBytesToSend++] = 0x09; //CS (und CLK) auf 1
25
byOutputBuffer[dwNumBytesToSend++] = 0xFB; // Direction config is still needed for each GPIO write
26
      
27
//jetzt clock wieder auf null
28
byOutputBuffer[dwNumBytesToSend++] = 0x80; // Set data bits low-byte of MPSSE port
29
byOutputBuffer[dwNumBytesToSend++] = 0x08; //CLK auf 0 , CS bleibt 1
30
byOutputBuffer[dwNumBytesToSend++] = 0xFB; // Direction config is still needed for each GPIO write
31
      
32
//Befehle abschicken
33
ftStatus = myFtdiDevice.Write(byOutputBuffer, dwNumBytesToSend, ref dwNumBytesSent);

von Ralf (Gast)


Lesenswert?

Was spricht dagegen eines der Kommandos von 0x38 aufwärts zu verwenden? 
Dort im man wohl unabhängig vom initialen Clock-Zustand. Probier das 
mal...

Ralf

von Ralf (Gast)


Lesenswert?

@Kim:
Bist du mittlerweile weitergekommen?

Ralf

von Kim Vogelmann (Gast)


Lesenswert?

@ Ralf:
Leider helfen die Kommandos ab 0x38 auch nicht weiter. Es wird nur LSB 
statt MSB zuerst geschickt. Muss mir wohl eine andere Lösung überlegen..

Kim

von Ralf (Gast)


Lesenswert?

> Leider helfen die Kommandos ab 0x38 auch nicht weiter. Es wird nur LSB
> statt MSB zuerst geschickt.
Dann nimm halt die ab 0x30 :)
Kapitel: 3.3.9 Clock Data Bytes In and Out MSB first

Ralf

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.