Forum: Projekte & Code Banana PI (Allwinner A20): SPI


von Andreas K (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe ein Codebeispiel geschrieben, mit dem man unter Linux den 
SPI-Bus durch das Setzen von Registern steuert.
Den Weg über den Linux-Treiber:
1
system ("modprobe spi-sun7i");
2
spiDevice = open ("/dev/spidev0.0" , O_RDWR));
3
...
wollte ich nicht nehmen, weil ich bestimmte Timings nicht einhalten 
konnte.
Im konkreten Fall habe ich einen MCP3208 an SPI0 gehängt (an SS0).


Ich finde, aus dem Datenblatt des Allwinner A20 lässt sich die 
Funktionweise, wann welches Bit geschrieben wird, nicht erkennen.
Ein Beispiel habe ich im Internet auch nicht gefunden. Deshalb 
veröffentliche ich hier meinen Code.
Da werden sicherlich noch irgendwo Fehler sein.
(Datenblatt: https://linux-sunxi.org/A20 -> User Manual)

Derzeit läuft der SPI auf 2.5MHz (wenn ich richtig gemessen habe).
Mit der Methode ist die Framelänge maximal 64 Byte, danach ist der 
TX-Fifo voll.

LG Andreas

von Rohrdommel (Gast)


Lesenswert?

Hi,

ich habe vor einiger einmal versucht, ein TFT-Display über SPI mit dem 
BananaPro zu verbinden. Das hat auch funktioniert, war aber viel zu 
langsam, weil der SPI-Controller zwischen den einzelnen Bytes eine sehr 
lange Pause eingebaut hat, die sich nicht verkürzen ließ. Die Länge der 
Pause blieb immer gleich unabhängig vom SPI-Clock. Ich habe da viel Zeit 
reingesteckt aber das Problem nicht gelöst.

Hast Du eine ähnliche Erfahrung? Beim Raspberry tritt das Problem nicht 
auf.

von Andreas K (Gast)


Angehängte Dateien:

Lesenswert?

Was meinst du mit Pause, dass das Clock-Signal stehen geblieben ist 
zwischen den Bytes?

Bei mir sind die Bytes alle direkt nacheinander übertragen wurden.
Das Problem bei Benutzung des Linux-Treibers war, dass nachdem das CS0 
gesetzt wurde ca. 10µs vergangen sind, bis er angefangen hat zu senden. 
Nach dem Senden sind nochmal ca. 15µs vergangen (siehe Bild).

Wie lang ist bei dir die Pause zwischen 2 Bytes und wie viele Bytes 
verschickst du mit einem Burst?


Beim Oszi-Bild, wie es bei mir vorher (mit Linux-Treiber) aussah:
Die obere Kurve ist Channel-Select (0-Aktiv). Die untere ist das 
Clock-Signal, leider durch Aliasing nicht so gut erkennbar. Aber man 
sieht, wann die Clock aktiv ist und wann nicht.
Den Cursor kannst du ignorieren.

von Vancouver (Gast)


Lesenswert?

Hi,

> Das Problem bei Benutzung des Linux-Treibers war, dass nachdem das CS0
> gesetzt wurde ca. 10µs vergangen sind, bis er angefangen hat zu senden.
> Nach dem Senden sind nochmal ca. 15µs vergangen (siehe Bild).

Genau das war das Problem, ist schon eine Weile her, deswegen hatte ich 
es nicht mehr genau in Erinnerung. Ich habe das Problem hier bschrieben: 
Beitrag "SPI Chipselect-Delay auf Banana PI" (unter einem anderen 
Nickname).


Das ganze hat dazu geführt, dass ich das Display am BananaPro nicht 
nutzen konnte, weil viel zu langsam. Die Übertragung eines kompletten 
Framebuffers war eine Angelegenheit von einigen Sekunden.

Verstehe ich das richtig, dass diese Verzögerung bei Deiner eignen 
Implementierung nicht auftritt?

von Andreas K (Gast)


Lesenswert?

Ich habe das Betriebsystem Bananian.

Bei meinem Code tritt das Problem nicht auf.
Die Verzögerung zwischen zwei Übertragungen ist bei mir ca. 4µs. Ich 
nehme an, die entsteht durch meinen Code (Schreiben in TX-FIFO, lesen 
vom RX-FIFO, usw).

Wenn du diesen Code einsetzt, vergleich mal mit dem Datenblatt, ob die 
Bits im Config-Register sinvoll gesetzt sind. :p

Zum DMA:
In dieser Implementierung des Treibers wird der DMA-Modus eingesetzt, 
wenn mehr als 64-Bytes übertragen werden:
http://dl.cubieboard.org/parteners/waveshare/Source_Code/a20-cubieboard-dvk/driver%20source/spi-sun7i.c
Funktion: sun7i_spi_xfer
Ich weiß nicht, ob das der tatsächlich eingesetzte Treiber ist. Ich bin 
auch kein Treiberexperte.

Da das Programm beim Aufruf von ioctl(...) unterbrochen wird, bis die 
Übertragung fertig ist, finde ich, dass man sich den DMA dann auch 
sparen kann. Schließlich dauert das Übertragen viel länger, als Bytes 
durch den Prozessor zu schleifen.
Wenn man mehr als 64 Bytes übertragen möchte, könnte man während der 
Übertragung noch Bytes in den TX-FIFO schreiben und aus dem RX-FIFO 
lesen (damit er nicht überläuft).

Im verlinkten Treiber wird erst das Start-Burst-Bit gesetzt und danach 
die Bytes in den TX-FIFO geschoben.

Ist meine Meinung dazu.

von Vancouver (Gast)


Lesenswert?

Ok, danke für Deine Hinweise. Ich werde Deinen Sourcecode mal anpassen 
und testen. Wäre ja cool, wenn das doch noch funktionieren würde.

Ich bin mittlerweile zu der Einsicht gekommen, dass DMA in meinem Fall 
ohnehin nicht sinnvoll ist. Das TFT-Display hat ein Parallel-interface, 
das über ein Schieberegister mit dem SPI-Bus verbunden ist. Man schreibt 
dann erst das Schieberegister über SPI (16bit) und dann wird über einen 
Impuls auf einem GPIO der Wert in den Displaycontroller übertragen. 
Danach muss man ohnehin einen neuen SPI-Transfer aufsetzen für die 
nächsten beiden Bytes.

Mit dem gleichen SPI-Takt läft das auf einem Raspberry so schnell, dass 
man sogar Videos abspielen kann (mit geringer Framerate), aber auf dem 
BananaPro war das wie gesagt schnarchlangsam, und das nur, weil die 
Verzögerung nach dem CS0 um ein Vielfaches länger war als die 
eigentliche Übertragung.

Anfangs dachte ich, das geht so langsam, weil kein DMA verwendet wird, 
aber der eigentliche Grund ist das CS0-Delay.

Also danke nochmal.

von Vancouver (Gast)


Lesenswert?

Ok, ich habe Deinen Code mal getestet. Saubere Sache, ich messe zwischen 
CS->low und dem ersten Clock jetzt ca. 700ns, die ganze Übertragung 
eines 16Bit-Wertes dauert jetzt 7us gegenüber 45us vorher. Wobei diese 
Zeit jetzt hauptsächlich vom SPI-Clock bestimmt wird und nicht mehr von 
dieser unsinning großen Delay am Anfang. Mit einem höheren SPI-Clock 
sollte das also noch schneller werden. Das sieht alles sehr gut aus.

Ich frage mich nur, wieso sich der Linux-Treiber so unsinnig verhält. 
Vielleicht liegt irgendwo im spi_sun7i-Modul ein Hund begraben, denn 
dort werden anscheinend die Register-Settings im A20 gemacht. Das müsste 
ich jetzt mal mit Deinen Settings vergleichen. Also jetzt erstmal 
Datenblatt inhalieren.

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.