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


von Hänschen Klein (Gast)


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

1
void __fastcall TForm1::Button2Click(TObject *Sender)
2
{
3
4
  char error[256];
5
  FTC_STATUS Status = FTC_SUCCESS;
6
7
  #define NUM_x_CMD_CONTOL_BITS  14  
8
  #define NUM_x_CMD_CONTOL_BYTES 2
9
10
  const SPI_EWEN_CMD = '\x9F'; // set up write enable command
11
12
  FTC_INIT_CONDITION WriteStartCondition;
13
  WriteControlByteBuffer WriteControlBuffer;
14
  WriteDataByteBuffer WriteDataBuffer;
15
  FTC_WAIT_DATA_WRITE WaitDataWriteComplete;
16
  FTC_HIGHER_OUTPUT_PINS HighPinsWriteActiveStates;
17
18
  WriteStartCondition.bClockPinState = true;        //false
19
  WriteStartCondition.bDataOutPinState = true;
20
  WriteStartCondition.bChipSelectPinState = true;
21
  WriteStartCondition.dwChipSelectPin = ADBUS3ChipSelect;
22
23
  WaitDataWriteComplete.bWaitDataWriteComplete = false;
24
25
  HighPinsWriteActiveStates.bPin1ActiveState = false;
26
  HighPinsWriteActiveStates.bPin1State = false;
27
  HighPinsWriteActiveStates.bPin2ActiveState = false;
28
  HighPinsWriteActiveStates.bPin2State = false;
29
  HighPinsWriteActiveStates.bPin3ActiveState = false;
30
  HighPinsWriteActiveStates.bPin3State = false;
31
  HighPinsWriteActiveStates.bPin4ActiveState = false;
32
  HighPinsWriteActiveStates.bPin4State = false;
33
34
  // enable writing
35
  WriteControlBuffer[0] = SPI_EWEN_CMD;     //des noch anpassen
36
  WriteControlBuffer[1] = '\xFF';
37
38
39
  Status = SPI_Write(ftHandle,
40
            &WriteStartCondition,
41
            MSB_FIRST,
42
            POS_EDGE,
43
            NUM_x_CONTOL_BITS,
44
            &WriteControlBuffer,
45
            NUM_x_CMD_CONTOL_BYTES,
46
            false, 
47
            0, 
48
            &WriteDataBuffer,  
49
            0,               
50
            &WaitDataWriteComplete,     
51
            &HighPinsWriteActiveStates);     
52
53
  SPI_GetErrorCodeString(
54
   "EN",
55
   Status,
56
   error,
57
   sizeof(error));
58
59
  Memo1->Lines->Add(AnsiString().sprintf("Write Device:  %s",
60
                   error));
61
62
63
64
}


Hänschen

von Ralf (Gast)


Lesenswert?

Hi,

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

Ralf

von Hänschen Klein (Gast)


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).

1
  WriteStartCondition.bClockPinState = true;        //ist das high?
2
  WriteStartCondition.bDataOutPinState = true;
3
  WriteStartCondition.bChipSelectPinState = true;
4
  WriteStartCondition.dwChipSelectPin = ADBUS3ChipSelect;
5
6
  WaitDataWriteComplete.bWaitDataWriteComplete = false;
7
8
  HighPinsWriteActiveStates.bPin1ActiveState = false;  //was macht er hier?
9
  HighPinsWriteActiveStates.bPin1State = false;        //und hier?
10
  HighPinsWriteActiveStates.bPin2ActiveState = false;
11
  HighPinsWriteActiveStates.bPin2State = false;
12
  HighPinsWriteActiveStates.bPin3ActiveState = false;
13
  HighPinsWriteActiveStates.bPin3State = false;
14
  HighPinsWriteActiveStates.bPin4ActiveState = false;
15
  HighPinsWriteActiveStates.bPin4State = false;

von Hänschen Klein (Gast)


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?

von Ralf (Gast)


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

von Guido Körber (Gast)


Lesenswert?

Hm, irgendwie geht das mit dem IO-Warrior deutlich einfacher...

von Hänschen Klein (Gast)


Angehängte Dateien:

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.
1
  FTC_STATUS Status = FTC_SUCCESS;
2
3
  FTC_INIT_CONDITION ReadStartCondition;
4
  WriteControlByteBuffer WriteControlBuffer;
5
  ReadDataByteBuffer ReadDataBuffer;
6
  DWORD dwNumDataBytesReturned = 0;
7
  FTC_HIGHER_OUTPUT_PINS HighPinsWriteActiveStates;
8
9
  ReadStartCondition.bClockPinState = false;  //false
10
  ReadStartCondition.bDataOutPinState = true;
11
  ReadStartCondition.bChipSelectPinState = true;
12
  ReadStartCondition.dwChipSelectPin = ADBUS3ChipSelect;
13
14
//####################################################
15
16
  WriteControlBuffer[1] = 0x00; //Don't care Bits
17
  WriteControlBuffer[0] = 0x02; 
18
19
//####################################################
20
21
 
22
  Status = SPI_Read(ftHandle,
23
    &ReadStartCondition,
24
    MSB_FIRST,
25
    false,         //Egde
26
    8,
27
    &WriteControlBuffer,
28
    1,
29
    MSB_FIRST,
30
    POS_EDGE,
31
    8,
32
    &ReadDataBuffer,
33
    &dwNumDataBytesReturned,
34
    &HighPinsWriteActiveStates);
35
36
37
  SPI_GetErrorCodeString(
38
   "EN",
39
   Status,
40
   error,
41
   sizeof(error));

von Ralf (Gast)


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

von Hänschen Klein (Gast)


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?

1
BOOLEAN FT2232cMpsseSpi::IsClockCorrectInitialOutputState(PFTC_INIT_CONDITION pWriteReadStartCondition, BOOL bClockInOutDataBitsPosEdge)
2
{
3
  BOOLEAN bClockCorrectInitialOutputState = true;
4
5
  // Check that the clock initial state of high is not equal to the data being clocked out on a negative edge or
6
  // the clock initial state of low is not equal to the data being clocked out on a positive edge
7
  //if ((*pWriteReadStartCondition).bClockPinState != bClockInOutDataBitsPosEdge)
8
  //  bClockCorrectInitialOutputState = false;
9
  
10
  return bClockCorrectInitialOutputState;
11
}

von Guido Körber (Gast)


Lesenswert?

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

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.