Gesendet: Dienstag, 09. Mai 2017 um 11:35 Uhr Von: "Uwe Kleine-König" uwe@kleine-koenig.org Betreff: Re: [Flug] SPI 9bit/16bit
Hallo Arno,
du hast natürlich recht. Das mit den Protokoll (9bit Adresse + rw-bit + Daten) habe ich gelöst.
Für .bits_per_word werden andere Werte als 8 nicht akzeptiert, da bekomme ich eine Fehlermeldung.
Dann ist der spi-Treiber doof (oder die Hardware kann das nicht).
Mh, hab noch gesehen, es gibt unabhängig von bits/word (was ja eh nicht hilft, wenn Adresse und Daten unterschiedlich sind) noch __u8 tx_nbits; __u8 rx_nbits; Hab damit aber nicht weiter rumgespielt.
Ich pussele halt die Adresse, RW-Bit und Daten so in einen Buffer, dass es passt. Kommen halt am Ende ein paar Takte mehr. Sende 4x8bit für den Inhalt von 9+1+16. Aber das scheint kein Problem zu sein.
Sehe ich am Oszi so.
Was ich nicht hinbekommen habe ist, dass ich zum Lesen eine andere Flanke samplen muss!! (siehe Bild).
uah, ich weiß, Gewalt ist keine Lösung, aber der Hardware-Entwickler ...
Ja, das war auch mein Gedanke, wtf....
Zwar gibt es
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
aber ich sehe nur eine Reaktion auf die Änderung des Write modes ?!?
Wenn wir mal einen Hardware-Bug ausschließen: Was schreibst Du denn in mode rein? Für die erste Sequenz muss da CPOL=0 + CPHA=0 (also mode=0) und für die zweite Sequenz CPOL=0 + CPHA=1 (also mode=1) einstellt sein.
Zunächst hatte ich gar keinen Mode gesetzt, aber 0 scheint default. Den Effekt am Oszi kann ich natürlich nur für den Write-Teil sehen. Und da ist "0" richtig. Mit eins bekomme ich die korrekten Daten zurück. (Es gibt ein Register mit Adresse 0, da ist es egal ob mit Mode 0 oder 1 geschrieben wird. Daher weiß ich das) Bei allen anderen Adressen werden diese natürlich falsch übermittelt, so das ich die richtige Daten zur falschen Adresse bekomme :(
Das kriegst Du nur hin, wenn Dein Treiber die Verwendung von struct spi_ioc_transfer::cs_change unterstützt und selbst dann ist das hacky.
Ich hatte da diesen kurzen Hoffnungsschimmer und hab im spi_ioc_transfer struct auch die .cs_change = 1 gesetzt, aber leider ohne Effekt. SPI_IOC_RD_MODE wird ignoriert. Ist es das was du meinst?
Jetzt fallen mir nur noch zwei Sachen ein: Clock oder Daten per Hardware verzögern, damit ich nicht direkt an der Flanke lesen muss oder den Read in zwei Protokolle aufteilen und zwischendrin den Mode wechseln. Ich schätze dazu müsste ich ausserdem noch das CS low halten, damit das Device nicht meint, es wäre ein neues Kommando.
Gruß Arno