Benutzer-Werkzeuge

Webseiten-Werkzeuge


projects:2020:i2c_foo

I2C Foo

Maintainer:
tux
Status
Solved - kind of

Problem

RaspberryPi 2B und Attiny verstehen sich nicht per I2C.

Effekt: Der RPi erhält die Antwort auf die vorherige Anfrage. Es handelt sich nicht um ein Timing-Problem, das Signal sieht gut aus und die Übertragung ist auf dem PHY sauber. Nur die Inhalte stimmen nicht.

Lösung

  • Repeated Starts im I2C Frame führen dazu, dass die Bibliothek die Schwelle zwischen Schreiben zum Slave und Lesen vom Slave nicht mehr erkennt und den Callback zu spät ausführt, sodass die Puffer-Daten aus dem jeweils letzten Request zurückgelesen werden.
  • Der aktuelle Workaround ist, nach dem Empfang des ersten Bytes mit der Verarbeitung zu beginnen.
  • Der Blick auf das Direction Bit könnte ein generischer Marker sein. Diese Bibliothek nutzt aber in ihrer Implementierung die Zeit, die der Master mit dem Senden der Adresse für ein Read auf dem Bus verbringt, für die Berechnung. Diese Zeit fehlt dann und wahrscheinlich ist der µC damit nicht mehr schnell genug. Clock-Stretching wird nicht unterstützt.
  • Optimal wäre, die Repeated Starts abzuschalten, dazu habe ich aber keinen Switch gefunden.

Logbuch des Wahnsinns

  • RaspberryPi kann kein Clock Stretching
  • Problem tritt auf RPi 2B, aber nicht auf RPi A auf
  • Abstand zwischen den Abfragen ist nicht relevant, es können mehrere Minuten dazwischen liegen
  • Start und Stop Condition werden vom Oszi nicht dekodiert (mit anderen Transfers gegenchecken)

2021-11-06

  • Offenbar sendet der RPi2 Repeated-Start-Conditions, die den AVR dazu veranlassen, sofort den Puffer zurückzugeben, ohne die Interrupt-Routine aufzurufen.
  • Workaround: i2cget und i2cset trennen
  • Besser wäre es, wenn der Kernel das schon auseinander nehmen könnte
    • Es gibt den Parameter "combined", über den festgelegt wird, ob Nachrichten über Repeated-Start zusammengefasst werden
  • Für den relevanten Bus ist bcm-2835 zuständig … oder auch nicht. Es ist bcm2708
  • Offenbar kommt das repeated-start aus dem Userspace
  • Benutzt die USITWI-Library für den AVR die Stop-Condition, um das callback aufzurufen?
    • Der Callback wird nicht in der ISR aufgerufen (was eig. sinnvoll ist)
    • Ablauf wäre dann so:
      • Master sendet Adresse und Parameter im ersten Block
      • Parameter landet im Puffer
      • Stop-Condition führt dazu, dass Callback (mit Parameter aus Puffer) ausgeführt wird
      • Während der Master das Adress-Byte für den Read-Request schickt (USI ist Hardware-basiert, unterbricht also den Programmablauf nicht), führt der Prozessor den Callback auf dem Parameter aus dem Eingangspuffer aus und schreibt das Ergebnis in den Ausgangspuffer.
      • Wenn der Master die das Adress-Byte geschrieben hat, liegt das Ergebnis zum Senden im Ausgangspuffer
    • Beim Repeated Start fehlt die Stop-Condition
      • Callback wird nicht nach Empfang des Eingangs-Parameters (erster Frame) aufgerufen
      • d.g. beim Antworten liegen noch die Daten des vorherigen Requests im Ausgangspuffer
      • Callback wird _nach_ dem gesamten Request/Response aufgerufen
      • d.h. bei der nächsten Anfrage liegen dann die Daten der letzten Anfrage im Puffer und werden zurückgegeben

Lösung könnte sein:

  • 1)
    • Einen anderen Trigger verwenden (es gibt eine interne State Machine)
  • 2)
    • I2C-Zugriff zentralisieren, wie das schon mal geplant war.
    • Bei der Gelegenheit könnte auch gleich der ganze I3C-Teil umgesetzt werden.
    • Read/Write trennen, sodass der AVR auch definitiv genug Zeit für die Verarbeitung hat

Linksammlung

projects/2020/i2c_foo.txt · Zuletzt geändert: 2021-11-07 16:23 von tux