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!
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?
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
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
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!
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.
Jetzt habe ich auf einem neuen FPGA Board den FT601 verlötet. Der meldet sich als Flags: 0x4 [USB 3]| Type: 601 | ID: 0x0403601E Und im USB Device Tree Viewer bekomme ich korrekt
1 | --------------- Connection Information V2 ------------- |
2 | Connection Index : 0x04 (4) |
3 | Length : 0x10 (16 bytes) |
4 | SupportedUsbProtocols : 0x04 |
5 | Usb110 : 0 (no) |
6 | Usb200 : 0 (no) |
7 | Usb300 : 1 (yes) |
8 | ReservedMBZ : 0x00 |
9 | Flags : 0x03 |
10 | DevIsOpAtSsOrHigher : 1 (Is operating at SuperSpeed or higher) |
11 | DevIsSsCapOrHigher : 1 (Is SuperSpeed capable or higher) |
12 | DevIsOpAtSsPlusOrHigher : 0 (Is not operating at SuperSpeedPlus or higher) |
13 | DevIsSsPlusCapOrHigher : 0 (Is not SuperSpeedPlus capable or higher) |
14 | ReservedMBZ : 0x00 |
15 | Data (HexDump) : 04 00 00 00 10 00 00 00 04 00 00 00 03 00 00 00 ................ |
Also sollte das auch SuperSpeed sein. Was ich aber mit meinem Programm bekomme ist nur irgendwas zwischen 10 und 30 MByte/s. Dann habe ich mit dem Oszi auf TXE_N geguckt und siehe da, das ist immer nur für kurze Zeit low. Also es ist nur für kurze Zeiten jeweils schreiben vom Master (FPGA) ins FIFO erlaubt. Das würde zu der geringen Datenrate passen. Aber die Frage ist jetzt: Wieso zieht der FT601 das TXE_N so schnell wieder hoch (signalisiert, dass der FIFO voll ist)? Für mich sieht das so aus, als würde der nur USB2 verwenden, aber wie kann ich das weiter debuggen und überprüfen? Vielen Dank für jegliche Hinweise.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.