spidev: auslesen via python schlägt fehl

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Hallo,

    ich hab folgendes Problem. Ich habe einen ADXL345 welchen ich per C++ auslesen kann und auch auf der CLI. Aber Python weigert sich.
    Der Hintergrund ist das ich hier ein Mainsailos habe und das mit Klipper zum laufen bringen will. Also hab ich das ganze reversed runter zu simplen aufrufen:

    Was hab ich:
    Model : Raspberry Pi 4 Model B Rev 1.4
    OS: Raspbian GNU/Linux 10 (buster)

    Was möchte ich erreichen:

    Ich sende dem ADXL345 ein 0x80 (ein "READ" | "Register 0" ) und erwarte ein E5 als Antwort (Q:"Hallo wer bist du." A: "Ich bin ein ADXL345").

    CLI:

    Code
    pi@mainsailos:~/ $ sudo systemctl start pigpiod 
    pi@mainsailos:~/ $ pigs spio 0 2000000 3
    0
    pi@mainsailos:~/ $ pigs spix 0 0x80
    1 229
    
    #229 = E5 = OK!

    C++:

    Python:

    Klipper geht natürlich auch nicht. Der meldet mir auch die Id 0 und verweigert den Dienst.

    Irgendwas stimmt doch mit den Python Libraries nicht. Ideen?

    Was ich bisher zum Thema gefunden habe ist das man zwingend den max_speed_hz setzen muss. Ansonsten kommt genau das verhalten. Aber das mache ich schon.

    Ich könnte Hilfe gebrauchen...

    Danke fürs lesen.

  • In C übermittelst du 2 bytes:

    Code
        data[0] = 0x80;
        data[1] = 0;
        bytes = spiXfer(h, data, data, 1);

    Wird wohl nur ein Byte übermittelt, weil das letzte Argument die Anzahl der Bytes angibt.

    Bei Python ist es aber nur ein Byte:

    Code
    r=spi.xfer2([0x80])

    Probier mal einfach 2 Byte zu senden.

    Code
    reply = spi.xfer2([0x80, 0x00])
  • Hi, nein ich übermittle nicht 2 Byte. Ich sage ja spixfer explizit das es count "1" ist. Mach ich ja auch auf der CLI nicht.

    Ist aber hin wie her, geht auch so nicht:

    Wenn man mehr als 1 Byte übertragen will müsste man das multibyte Bit noch setzen. Aber auch mit dem klappt es nicht.

  • Code
        int h = spiOpen(0, 2000000, 3);

    vs

    Code
    spi.max_speed_hz = 5000

    Das bei C ist 2 MHz und bei Python sind es 5 kHz. Das kann nicht richtig sein.

    Das mit den 2 Bytes hat was wahrscheinlich mit TX und RX zu tun. Sendebuffer/Empfangbuffer.

  • Hi. Der C Code steigt bei 5kHz mit Fehlermeldung aus. 50kHz ist das langsamste was tut. Also hab ich das python mit 50kHz getestet. Keine Änderung im Verhalten.

    Ich hab inzwischen das python modul spidev auseinandergenommen und die Initialisierung und Xfer2 in einem eigenen Binary übertragen.
    Wie es ausschaut arbeitet spidev per ioctl direkt mit dem Kerneldevice.

    Wenn ich auch so arbeite verhält sich das PI (oder der Kernel wie man es sieht) seltsam.

    Was mir auffällt ist, dass wenn ich den SPI Mode abfrage ich 7 bekomme. Da ist ein Bit zu viel drin. Auch wenn ich vorher 3 setze. (Das kann richtig sein, müsste ich mich in die SPI Kernel Doku einlesen). SPIDEV greppt das Bit per default einfach mal weg.
    Und ich bekomme bisher per ioctl auch nur 0 als Antwort auf die Anfrage 0x80.

    Linux Kernel auseinander nehmen hab ich eigentlich keine Lust zu. Alternativ könnte man die pigpio Library auseinander nehmen was die anders macht das es da tut.

    EDIT:
    OK habs gefunden warum der 7 sagt. Das ist das Thema mit dem CS_HIGH. 0x04 ist das Bit für CS_HIGH. Zu dem Thema gibts ja auch Seitenweise Diskussionen im Internet. Da wurde das Verhalten in irgendeinem Kernelrelease verändert. Das ist nicht mehr setzbar.

    EDIT2:
    Pigpio popelt direkt per nmap im "Speicher" der Physik rum. Da ist gar kein Kernel(-aufruf) dazwischen. Wow...

    Ja Sackgasse.

    2 Mal editiert, zuletzt von steipi (2. Februar 2022 um 12:34)

  • Also... ich hab was, was für mich funktioniert.

    Ich hab den CS Pin vom IC auf GND gezogen. Sprich der SPI Master auf dem PI kontrolliert nicht mehr CS. Das funktioniert zumindest für den Testcase hier. Ich hab aber auch nur einen IC am SPI BUS.

    Und schon läuft die Kommunikation mit ioctl und auch spidev.
    Klipper tut auch.

    Ich frag mich allerdings warum ich zu dem Problem hier keine Treffer bei Google bekomme. So wie ich das lese ist das ein Fehler im Kernel(Kernelmodul) der seid 5.4 irgendwas drin ist. Die HW vom PI kann es, die OS-Software erlaubt es einfach nicht.
    ...Oder ich bin auf dem komplett falschen Dampfer unterwegs.

  • OK geht so doch nicht. Denn der adxl345 unterstützt mehrere Register. Um die zu wechseln (bzw zu resetten) muss man den IC per CS abwählen. Sprich wenn ich den CS auf GND zwinge, hänge ich auf einem Register fest.

    Ich hab inzwischen den ganzen Aufbau auf einem ESP8266 nachgebaut. Der adxl345 funktioniert. (Funktioniert ja auch am PI, nur halt ohne spidev).

    Das hat was mit der Kombination von Linux-Kernel + bcm-Kernel-Modul zu tun.

  • Ok... die Auflösung der Geschichte ist folgende:

    Wenn man das pigpio SPI Modul einmal verwendet hat, wird jeder folgende spidev Aufruf nicht mehr aktiv CS steuern.
    Nach einem Reboot tut spidev wieder.

    Nachdem ich immer mit pigpio rumgetestet habe, ist spidev immer ausgestiegen. Erst ein "Oszilloskop" hat mich auf die Lösung gebracht. Hier kann ich piscope empfehlen, weil man kein extra Gerät braucht (kann man auf dem PI laufen lassen wo auch der SPI Master läuft, also nur 1 PI).

    Sprich mit 1m Kabel, spidev und dem System wie beschrieben angeschlossen auf SPI0 auf CE0, frisch gebooted, tut es.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!