USB zu SPI klappt nicht (FT2232D)

Gast #1129613
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
Gast #1131943
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;
Gast #1132489
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?
Gast #1132666
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
Gast #1136054
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));
Angehängte Dateien:
Gast #1136124
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
Gast #1136673
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
}

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