Forum: Mikrocontroller und Digitale Elektronik FT600 ucPipeID 0x82 - Bedeutung der Bits?


von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

Hallo,
ich bin dabei einen FT600 in Betrieb zu nehmen und orientiere mich dabei 
am 
https://www.ftdichip.com/Support/Documents/ProgramGuides/AN_379%20D3xx%20Programmers%20Guide.pdf 
.

Daraus möchte ich die Funktion FT_ReadPipe (Seite 17) verwenden. Mache 
ich auch, aber ich bekomme keine Daten zurück. Diese Funktion verwendet

ucPipeID
Corresponds to the bEndpointAddress field in the endpoint descriptor. In 
the bEndpointAddress field, Bit 7 indicates the direction of the 
endpoint:
0 for OUT; 1 for IN.

OK, aber was machen die anderen Bits von ucPipeID? Im Codebeispiel von 
FTDI wird einfach Pipe 0x82 verwendet. Ist das eine Defaultpipe? Wie 
bekomme ich die ID meiner Pipe heraus?

Synchronous read from pipe 0x82
UCHAR acBuf[BUFFER_SIZE] = {0xFF};
ULONG ulBytesTransferred= 0;
ftStatus = FT_ReadPipe(ftHandle, 0x82, acBuf, BUFFER_SIZE 
&ulBytesTransferred, NULL);

Meinen FT600 habe ich in den 1 channel, 245 Synchronous FIFO mode 
konfiguriert (siehe Bildchen). Da ich im Programmers Guide keine 
Erwähnung von 245 finde gehe ich mal davon aus, dass das für die 
PC-Software egfal ist ob der FT600 im 245 mode oder im FT600 mode 
betrieben wird.

Vielen Dank!

von Uwe Bonnes (Gast)


Lesenswert?

Irgendwo muessen die verwendetet Endpoint definiert sein. Schau dort 
nach.  Gibt es keine Beispielprojekt dass Du zuerst unveraendert und 
dann mit leichten Veraenderungen kompiliert und getestet hast?

von Gustl B. (-gb-)


Lesenswert?

Uwe Bonnes schrieb:
> Irgendwo muessen die verwendetet Endpoint definiert sein. Schau dort
> nach.

Ja aber wo?

Uwe Bonnes schrieb:
> Gibt es keine Beispielprojekt dass Du zuerst unveraendert und
> dann mit leichten Veraenderungen kompiliert und getestet hast?

In denen steht überall 0x82. Ich wüsste gerne was das bedeutet.

Mein Problem ist, das TXE_N dauerhaft auf '1' bleibt. Scheinbar wird in 
meinem C Programm das FT_ReadPipe aber ausgeführt, denn wenn ich das 
Programm laufen lasse, dann gibt der FT600 seinen Takt aus, und den kann 
ich messen, der passt wunderbar. Nur zieht der FT600 eben das TXE_N 
nicht runter und erlaubt somit meinem FPGA nicht Daten auszugeben. OE_N 
und RD_N sind beide auf '1'.

Ja, die Beispiele die ich im Internet finde wie hier 
https://www2.hdl.co.jp/en/demonstration/439-enspc20170216.html verwenden 
alle 0x82 wenn gelesen werden soll un 0x02 wenn geschreiben werden soll. 
Das finde ich aus zwei Gründen seltsam:

Im Programmers Guide steht:

ucPipeID
Corresponds to the bEndpointAddress field in the endpoint descriptor. In
the bEndpointAddress field, Bit 7 indicates the direction of the
endpoint:
0 for OUT; 1 for IN.

Aber 0x82 ist ja 10000010. Damit ist die 1 ganz links das 8. Bit ausser 
man fängt bei Null an zu zählen.

Und dann steht da rechts noch eine 1 an Stelle 2. Die steht da wenn 
gelesen und geschrieben wird in den Beispielen. Aber für mich ist unklar 
was die dort bewirkt. Ich habe nur einen Channel.

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

So, es war ein Fehler in meinem C Programm. 0x82 ist korrekt, und zwar 
bei FT245 egal was man da für Pipes einstellt. Was auch immer diese 2 
bedeutet bleibt wohl unklare Magie. Ja, auch wenn ich nur 1 IN Pipe 
einstelle muss ich 0x82 verwenden.

Jedenfalls bekomme ich jetzt Daten, aber deutlich langsamer wie ich 
eigentlich möchte. Im Schnitt erreiche ich 57 MB/s. Und das eben, weil 
TXE_N die meiste Zeit oben ist, das FPGA also keine Daten ausgeben darf. 
Hm ... vielleicht sollte ich asynchron lesen ...

Edit:
Die Datenrate passt auch schön zu dem, was ich mit dem Oszi beobachten 
kann. TXE_N sieht aus wie ein Rechtecksignal wobei es für ca. 114 us 
High und für ca. 50 us Low ist.

: Bearbeitet durch User
von Gustl B. (-gb-)


Lesenswert?

Hat denn Jemand eine schön schnelle c Implementierung?

Ich verwende gerade:
1
    ftStatus = FT_InitializeOverlapped(ftHandle, &vOverlapped);
2
  while(micros < time){
3
        end = clock();
4
        micros = end - start;
5
        //ftStatus = FT_ReadPipe(ftHandle, 0x82, acReadBuf, BUFFER_SIZE, &ulBytesRead, NULL); //1. Versuch
6
        //ftStatus = FT_ReadPipeEx(ftHandle, 0x82, acReadBuf, BUFFER_SIZE, &ulBytesRead, NULL); //2. Versuch
7
        ftStatus = FT_ReadPipeEx(ftHandle, 0x82, acReadBuf, BUFFER_SIZE, &ulBytesRead, &vOverlapped);
8
        if (ftStatus ==FT_IO_PENDING){
9
            ftStatus = FT_GetOverlappedResult(ftHandle, &vOverlapped, &ulBytesRead, TRUE);
10
        }
11
        //printf("%i\r\n", ulBytesRead);
12
        if (ftStatus != FT_OK){
13
            printf("FT_ReadPipe FAILED!\r\n");
14
            FT_Close(ftHandle);
15
            fclose(out);
16
            return 0;
17
        }
18
        bytecounter = bytecounter+ulBytesRead;
19
        //fwrite(acReadBuf,1,ulBytesRead,out);
20
  }
21
  printf("%i MBytes/s\r\n",bytecounter/(micros*1000));
22
  FT_ReleaseOverlapped(ftHandle, &vOverlapped);
23
  FT_Close(ftHandle);

Da kann ich über time einstellen wie lange das lesen soll. Für mich ist 
aber unklar was in die while Schleife rein soll.

Soll das so aussehen:
while ... {
   FT_InitializeOverlapped
   FT_ReadPipeEx
   FT_GetOverlappedResult
   ReleaseOverlapped}

Oder so wie in meinem Code:

FT_InitializeOverlapped
while ... {
   FT_ReadPipeEx
   FT_GetOverlappedResult}
ReleaseOverlapped

Oder ganz anders?

Ich will eigentlich auch keine feste Datenmenge lesen, sondern zum Test 
so schnell wie möglich bis die Zeit um ist. Wenn ich aber größere Blöcke 
lese, also BUFFER_SIZE z. B. auf 256 kByte stelle, oder kleine Blöcke 
lese und BUFFER_SIZE auf 4 kByte stelle, dann wird die Übertragung noch 
langsamer. Mein Optimum liegt aktuell bei 64 kBytes. Aber da erreiche 
ich nur knapp 60 MByte/s. An mehreren Rechnern getestet. Die 
auskommentierten Versuche lesen nicht asynchron sondern synchron. Die 
sind aber in meinem Test gleich schnell.

Das FPGA füttert den FT600 in (fast) jedem Takt in dem TXE_N Low ist. 
Ich habe da nur einen 16 Bit Zähler und gebe den Zählerstand immer dann 
aus wenn TXE_N Low ist. Aber TXE_N bleibt leider die meiste Zeit oben, 
für mich sieht das so aus, also bräuchte die PC-Software oder der 
Treiber/die USB-Übertragung zu viel Zeit.

Vielen Dank für alle Hinweise!

von Gustl B. (-gb-)


Angehängte Dateien:

Lesenswert?

So, es geht weiter.

Tatsächlich funktioniert das ziemlich gut wenn man es so baut wie hier 
https://www.ftdichip.com/Support/Documents/ProgramGuides/AN_379%20D3xx%20Programmers%20Guide.pdf 
auf Seite 22. Allerdings ist die Datenrate stark abhängig von 
NUM_BUFFERS und BUFFER_SIZE. Ich habe dazu mal Daten aufgenommen. Das 
ist hier aber ein FT600, der hat nur ein 16 Bit FIFO Interface bei 100 
MHz, kommt also nur auf 200 MByte/s.

Im Anhang auch die VHDL Beschreibung. Die hat ein FIFO Interface zu 
einem (Dual-Clock) FIFO den man noch dazubauen muss (mit FT600_CLK als 
Lesetakt) wenn man mag und es ist nur die Richtung FPGA -> FT600 
beschrieben. Den FT600 muss man in den FT245 Modus konfigurieren.

Darf gerne verwendet werden, bei Fragen fragen.

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.