Zephyr i2c_write_dt Fehlermeldung trotz erfolgreichem Transfer

#7987804
Lesenswert?

Hallo,

ich arbeite mich gerade in das NRF Connect SDK von Nordic ein, welches ja Zephyr benutzt. Ich habe jetzt an einen nrf52810 einen SHT40 (Sensor von Sensirion) angeschlossen. Beim schrittweisen Debuggen meldet die Funktion i2c_write_dt nun aber schon bei der ersten Nutzung (Befehl 0xFD an Adresse 0x44; bitte miß mal...) den Fehler -5 zurück. Also mal den LA drangehangen und nachgeschaut, ob oder was überhaupt auf dem Bus los ist. Siehe Anhang. Sofern mir nicht noch die Beilagen vom Silversterschmaus durchs Hirn wabern, kann ich da nichts verwerfliches drauf erkennen. Auch ein Softreset (0x94) liefert das gleiche Ergebnis. Spaßeshalber bin ich dann trotzdem irgendwann weiter durchs Programm und siehe da: Der Sensor liefert die korrekten Werte! Mache ich da irgendwas banales falsch?

Debuggen ist mit vscode etwas "na ja"; letzendlich wird in i2c_write_dt() wohl i2c_write() aufgerufen, was wiederum i2c_transfer() aufruft und letztendlich die -5 liefert.

Angehängte Dateien:
: Bearbeitet durch User
#7987984
Lesenswert?

-5 bedeutet "-EIO (general input / output error". Laut Doku soll das kommen, wenn vom Slave ein NACK kommt. Tut es aber nicht. Häufigste Ursache sind wohl vergessene Pull up. Aber der Transfer funktioniert ja nachweislich. Der einzig andere Rückgabewert ist 0 für alles in Ordnung.

(Firma: 1984now) #7988027
Lesenswert?

Schwierig schrieb:

-5 bedeutet "-EIO (general input / output error". Laut Doku soll das kommen, wenn vom Slave ein NACK kommt. Tut es aber nicht. Häufigste Ursache sind wohl vergessene Pull up.

Oder ein Bug in der Treiberroutine, hier also in i2c_transfer(). Muss so sein, hast du ja selbst durch Messung/Funktionsprüfung festgestellt.

Also: Man muss sich anschauen, was i2c_transfer() wohl falsch macht. Wobei dabei natürlich durchaus herauskommen kann, dass garnicht die Routine selber schuld ist, sondern ein Bug in der I2C-Hardware, die sie verwendet.

#7988482
Lesenswert?

Lösung gefunden: Im Device Tree möchte der µC anscheinend gerne "sein" I2C-Attribut im Overlay haben:

1
&i2c0 {
2
    compatible = "nordic,nrf-twim";
3
    status = "okay";
4
    clock-frequency = <I2C_BITRATE_STANDARD>;
5
    my_sht40: my_sht40@44{
6
        compatible = "i2c-device";
7
        reg = < 0x44 >;
8
        label = "MY_SHT40";
9
        status = "okay";
10
    };
11
    clock-frequency = <I2C_BITRATE_STANDARD>;
12

13
    pinctrl-0 = <&i2c0_default>;
14
   pinctrl-1 = <&i2c0_sleep>;
15
    pinctrl-names = "default", "sleep";
16
};
17

18
&pinctrl {
19
  /omit-if-no-ref/ i2c0_default: i2c0_default {
20
    group1  {
21
      psels = <NRF_PSEL(TWIM_SCL, 0, 27)>,
22
             <NRF_PSEL(TWIM_SDA, 0, 26)>;
23
          bias-pull-up;
24
    };
25
  };

Also: compatible = "nordic,nrf-twim"; statt compatible = "i2c-device"; obwohl es im Nordic-Beispiel explizit als "allgemeines" I2C-Beispiel mit "i2c-device" beschrieben ist: https://academy.nordicsemi.com/courses/nrf-connect-sdk-fundamentals/lessons/lesson-6-serial-com-i2c/topic/exercise-1-6-2/

: Bearbeitet durch User
(Firma: 1984now) #7988915
Lesenswert?

Schwierig schrieb:

Lösung gefunden: Im Device Tree möchte der µC anscheinend gerne "sein" I2C-Attribut im Overlay haben: [c] &i2c0 { compatible = "nordic,nrf-twim";

Also passte also wohl tatsächlich der Treiber nicht ganz zur Hardware und muss entsprechend "hingedengelt" werden.

Interessant wäre hier noch, zu testen, was passiert, wenn dann tatsächlich mal kein ACK vom Target kommt. Nur wenn dann wieder -5 vom Treiber kommt, hast du wirklich eine valide Lösung gefunden.

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