www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik USB zu SPI klappt nicht (FT2232D)


Autor: Hänschen Klein (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

auf meiner Platine soll ein FT2232D einen SPI Bautein ansprechen. Leider 
klappt des nicht so recht. Die Knowledge-Dingsbums-Webseite von FTDI 
gibt es zwar jede Menge Beispiele zur SPI-Lib, die sind jedoch sehr 
wenig bis gar nicht kommentiert und es bleiben viele offene Fragen 
übrig.

Mein Beispiel Programm soll den SPI-Baustein vom FT2232 beschreiben. Auf 
dem Logic Analyzer sieht man aber nix zappeln, nicht mal einen CS.

Das Oszi meldet einen nur knapp 3V Pegel am CS Signal, sollte es nicht 
wenigstens 5V sein, wenn der high/passiv ist?

Die ganzen Pinzustände wie z.B. "WriteStartCondition.bClockPinState" 
verstehe ich auch noch nicht so ganz. Wie initialisiert man denn nun den 
Baustein richtig?

Hier noch der Code von der Write-Funktion

void __fastcall TForm1::Button2Click(TObject *Sender)
{

  char error[256];
  FTC_STATUS Status = FTC_SUCCESS;

  #define NUM_x_CMD_CONTOL_BITS  14  
  #define NUM_x_CMD_CONTOL_BYTES 2

  const SPI_EWEN_CMD = '\x9F'; // set up write enable command

  FTC_INIT_CONDITION WriteStartCondition;
  WriteControlByteBuffer WriteControlBuffer;
  WriteDataByteBuffer WriteDataBuffer;
  FTC_WAIT_DATA_WRITE WaitDataWriteComplete;
  FTC_HIGHER_OUTPUT_PINS HighPinsWriteActiveStates;

  WriteStartCondition.bClockPinState = true;        //false
  WriteStartCondition.bDataOutPinState = true;
  WriteStartCondition.bChipSelectPinState = true;
  WriteStartCondition.dwChipSelectPin = ADBUS3ChipSelect;

  WaitDataWriteComplete.bWaitDataWriteComplete = false;

  HighPinsWriteActiveStates.bPin1ActiveState = false;
  HighPinsWriteActiveStates.bPin1State = false;
  HighPinsWriteActiveStates.bPin2ActiveState = false;
  HighPinsWriteActiveStates.bPin2State = false;
  HighPinsWriteActiveStates.bPin3ActiveState = false;
  HighPinsWriteActiveStates.bPin3State = false;
  HighPinsWriteActiveStates.bPin4ActiveState = false;
  HighPinsWriteActiveStates.bPin4State = false;

  // enable writing
  WriteControlBuffer[0] = SPI_EWEN_CMD;     //des noch anpassen
  WriteControlBuffer[1] = '\xFF';


  Status = SPI_Write(ftHandle,
            &WriteStartCondition,
            MSB_FIRST,
            POS_EDGE,
            NUM_x_CONTOL_BITS,
            &WriteControlBuffer,
            NUM_x_CMD_CONTOL_BYTES,
            false, 
            0, 
            &WriteDataBuffer,  
            0,               
            &WaitDataWriteComplete,     
            &HighPinsWriteActiveStates);     

  SPI_GetErrorCodeString(
   "EN",
   Status,
   error,
   sizeof(error));

  Memo1->Lines->Add(AnsiString().sprintf("Write Device:  %s",
                   error));



}


Hänschen

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

wo führst du denn SPI_OPEN, SPI_INITDEVICE etc. aus? Mit denen musst du 
ja auch erstmal das Device anwerfen...

Ralf

Autor: Hänschen Klein (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit der SPI_INITDEVICE-Funktion im Konstruktor (neben SPI_OPEN) sieht 
die Sache schon viel besser aus.

Nun ist mir die Initialisierung der CS-Leitungen und der Clk-Leitungen 
noch nicht so ganz klar (siehe Kommentare im Code).


  WriteStartCondition.bClockPinState = true;        //ist das high?
  WriteStartCondition.bDataOutPinState = true;
  WriteStartCondition.bChipSelectPinState = true;
  WriteStartCondition.dwChipSelectPin = ADBUS3ChipSelect;

  WaitDataWriteComplete.bWaitDataWriteComplete = false;

  HighPinsWriteActiveStates.bPin1ActiveState = false;  //was macht er hier?
  HighPinsWriteActiveStates.bPin1State = false;        //und hier?
  HighPinsWriteActiveStates.bPin2ActiveState = false;
  HighPinsWriteActiveStates.bPin2State = false;
  HighPinsWriteActiveStates.bPin3ActiveState = false;
  HighPinsWriteActiveStates.bPin3State = false;
  HighPinsWriteActiveStates.bPin4ActiveState = false;
  HighPinsWriteActiveStates.bPin4State = false;


Autor: Hänschen Klein (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nun hab ich noch eine Frage: es scheint, dass die Daten immer mit der 
negativen Clockflanke rausgetaktet werden.

In der SPI_Write-Fkt. kann man beim Parameter "bClockOutDataBitsPosEdge" 
eintragen, ob's mit der positiven oder mit der negativen Flanke 
rausgehen soll. Mit meinem Eintrag "true" sollte es eigentlich so sein. 
Aber er taktet mit der negativen Flanke raus, ändert man was an dem 
Parameter so ändert sich aber nichts am Clock.
Da fehlt doch noch irgendwas?

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

wie prüfst du denn, mit welcher Flanke die Daten rausgepustet werden? 
Oszi? Kannst du ein Bild machen, jeweils mit bClockOutDataBitsPosEdge = 
false/true?

Die FTDI Libs sind ein Schrott, und die Doku auch, ich muss mir bei 
Gelegenheit eigene basteln, bei denen von FTDI ist gleichzeitig 
lesen/schreiben nicht möglich, die sind echt nur "demo".

Ralf

Autor: Guido Körber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, irgendwie geht das mit dem IO-Warrior deutlich einfacher...

Autor: Hänschen Klein (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Mein Problem stellt sich nun wie folgt da, ich konnte den Clk 
invertieren (auf positiveEgded). (Siehe Screenshot)
Doch nun will der olle Baustein keinen high Initialclockvalue 
akzeptieren (also das Clk-Signal darf aus irgendwelchen Gründen nur low 
sein). Die Funktion "SPI_GetErrorCodeString" spuckt dann einfach: "Read 
Device:  Invalid initial clock state ie for clocking data in/out on 
positive edge, clock initial state must be low." aus, wenn man schreibt: 
denReadStartCondition.bClockPinState = true; und damit eigentlich nur 
den Anfangszustand auf high setzen möchte.
  FTC_STATUS Status = FTC_SUCCESS;

  FTC_INIT_CONDITION ReadStartCondition;
  WriteControlByteBuffer WriteControlBuffer;
  ReadDataByteBuffer ReadDataBuffer;
  DWORD dwNumDataBytesReturned = 0;
  FTC_HIGHER_OUTPUT_PINS HighPinsWriteActiveStates;

  ReadStartCondition.bClockPinState = false;  //false
  ReadStartCondition.bDataOutPinState = true;
  ReadStartCondition.bChipSelectPinState = true;
  ReadStartCondition.dwChipSelectPin = ADBUS3ChipSelect;

//####################################################

  WriteControlBuffer[1] = 0x00; //Don't care Bits
  WriteControlBuffer[0] = 0x02; 

//####################################################

 
  Status = SPI_Read(ftHandle,
    &ReadStartCondition,
    MSB_FIRST,
    false,         //Egde
    8,
    &WriteControlBuffer,
    1,
    MSB_FIRST,
    POS_EDGE,
    8,
    &ReadDataBuffer,
    &dwNumDataBytesReturned,
    &HighPinsWriteActiveStates);


  SPI_GetErrorCodeString(
   "EN",
   Status,
   error,
   sizeof(error));


Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, eigentlich sollte es gehen, prüfen kann ich's aber nicht. Steht in 
der Anleitung zu den Libs nix drin, welche Beschränkungen es gibt?

Die Libs haben für mich sowieso eher "Demo"-Feeling, die taugen nur zum 
Demonstrieren (sonst könnte man gleichzeitig Lesen/Schreiben auf SPI). 
Warum schreibst du dir nicht ne eigene Ansteuerung? Der MPSSE-Prozessor 
ist ebenfalls dokumentiert, und du kannst dir dann das ganze Geraffel 
mit den tausenden Parametern sparen, die sowieso nur spärlich(wenn 
überhaupt) dokumentiert sind, dreiviertel der Parameter braucht man m.E. 
nicht.

Ich denke nicht, dass eine direkte MPSSE-Ansteuerung komplizierter ist, 
als der Versuch die FTDI-Libs zu verstehen.

Ralf

Autor: Hänschen Klein (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Irgendwie ist das auch nicht der Wahrheit letzter Schluss. Wir haben in 
der IsClockCorrectInitialOutputState-Funktion die Sperre für den 
Initial-Clock-State auskommentiert. Der Clock schaut nun sauber aus. 
Allerdings kommt nun nichts mehr auf dem Data-Out raus.
Wie soll man sich denn nur in diesem Chaoscode zurechtfinden?

BOOLEAN FT2232cMpsseSpi::IsClockCorrectInitialOutputState(PFTC_INIT_CONDITION pWriteReadStartCondition, BOOL bClockInOutDataBitsPosEdge)
{
  BOOLEAN bClockCorrectInitialOutputState = true;

  // Check that the clock initial state of high is not equal to the data being clocked out on a negative edge or
  // the clock initial state of low is not equal to the data being clocked out on a positive edge
  //if ((*pWriteReadStartCondition).bClockPinState != bClockInOutDataBitsPosEdge)
  //  bClockCorrectInitialOutputState = false;
  
  return bClockCorrectInitialOutputState;
}

Autor: Guido Körber (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was soll denn eigentlich gebaut werden und warum ist ein FTDI Chip 
gewählt worden?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.