Forum: Mikrocontroller und Digitale Elektronik FT2232D + libMPSSE: Lange Pausen auf dem I2C-Bus :o(


von Roland (Gast)


Lesenswert?

Hallo liebes Internet!

Ich möchte einen ADC per I2C auslesen und einen DAC beschreiben.

Hierzu habe ich einen FT2232D nach dem BeispielProjekt02 verschaltet:
http://www.ftdichip.com/Support/SoftwareExamples/MPSSE/FT2232C-Proj02_v11.pdf

Und mit Hilfe der d2xx.dll und libMPSSE.dll wie in AppNote 177 
beschrieben losprogrammiert.
http://www.ftdichip.com/Support/Documents/AppNotes/AN_177_User_Guide_For_LibMPSSE-I2C.pdf

War eigentlich sehr einfach und das ganze funktioniert soweit auch, nur 
macht der FT2232 nach jedem übertragenen Byte eine Pause, so dass ein 
übertragenes Byte unabhängig der Taktrate 16ms in Anspruch nimmt, bis er 
mit dem nächsten Byte anfängt.
D.h.: 8bit + x = 16ms.

Mein Code ist z.B. folgender:
1
uint32 write_byte(uint8 slaveAddress, uint8 registerAddress, uint8 data1, uint8 data2) {
2
    uint32 bytesToTransfer = 0;
3
    uint32 bytesTransfered;
4
    bool writeComplete=0;
5
    uint32 retry=0;
6
7
    bytesToTransfer=0;
8
    bytesTransfered=0;
9
    buffer[bytesToTransfer++]=registerAddress; /*PointerRegister*/
10
    buffer[bytesToTransfer++]=data1; /*HiByte of wordToSend*/
11
    buffer[bytesToTransfer++]=data2; /*LoByte of wordToSend*/
12
    status = p_I2C_DeviceWrite(ftHandle, slaveAddress, bytesToTransfer, buffer, &bytesTransfered, I2C_TRANSFER_OPTIONS_START_BIT|I2C_TRANSFER_OPTIONS_STOP_BIT);
13
    APP_CHECK_STATUS(status);
14
15
    while((writeComplete==0) && (retry<I2C_WRITE_COMPLETION_RETRY)) {
16
        bytesToTransfer=0;
17
        bytesTransfered=0;
18
        buffer[bytesToTransfer++]=registerAddress; /*PointerRegister*/
19
        status = p_I2C_DeviceWrite(ftHandle, slaveAddress, bytesToTransfer, buffer, &bytesTransfered, I2C_TRANSFER_OPTIONS_START_BIT|I2C_TRANSFER_OPTIONS_BREAK_ON_NACK);
20
        APP_CHECK_STATUS(status);
21
        
22
        if(bytesToTransfer==bytesTransfered) {
23
                writeComplete=1;
24
                // printf("... Write done\n");
25
        }
26
        retry++;
27
    }
28
    return 0;
29
}

Was ziemlich genau dem Muster in FTDIs AppNote 177 entspricht.

Ich kann nun hingehen und per:
1
channelConf.ClockRate = 400000 //I2C Clock in kHz
2
channelConf.LatencyTimer = 1;  //USB latency

Den Bus-Takt und die USB-Latenz einstellen.
Der Bus-Takt bestimmt wie schnell ein Byte über den Bus wandert, 
allerdings ist zwischen beiden MSBs immer eine Pause von 16ms, der 
effektive Bus-Takt liegt also bei satten 500Hz, was definitiv nicht im 
Sinne des Erfinders liegen sollte.
Eine Latenz zwischen zwei kompletten I2C-Blöcken könnte ich mir 
vielleicht noch erklären, aber zwischen zwei Bytes kann definitiv nicht 
im Sinne des Erfinders liegen.

Was mache ich falsch?
Die 16ms können sicher kein Zufall sein... da muss noch irgendwo eine 
Einstellung sein, die ich nicht finde.

Hilfe?
Danke!

Gruß, Roland

von Roland (Gast)


Lesenswert?

Ich habe mittlerweile den FTDI-Support angeschrieben, und der meint es 
läge daran, dass die libMPSSE.dll jedes übertragene ACK softwareseitig 
auswertet, was bedeutet, dass für jedes übertragene I2C-Byte sowohl eine 
write und eine read Aktion fällig wird.

USB 2.0 kann aber höchstens ein mal pro Millisekunde vom Schreib- in den 
Lesemodus und zurück wechseln, also gelinde gesagt ist die libMPSSE.dll 
somit höchstens für Demonstrationszwecke zu gebrauchen.

Der Support riet mir dazu den Buffer im FT2232 händisch mit Opcodes zu 
füttern um die read/write Vorgänge auf dem USB-Bus zu minimieren.

Damit nimmt das Projekt vollkommen andere Dimensionen an und es stellt 
sich die Frage, ob man dann nicht genau so gut einen vollwertigen µC 
programmieren könnte (was mir bis dato zu Aufwändig erschien).

Naja, schaumermal.
Ich dachte ich schreib wenigstens erstmal meine Erkenntnisse hier rein, 
falls jemand auf der Suche nach ähnlichen Antworten ist.

Gruß, Roland

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.