Forum: Mikrocontroller und Digitale Elektronik Linux, SAM9261, SPI, Pausen bei Übertragung


von Thomas B. (thomasb)


Lesenswert?

Hallo !

Es geht um folgendes: Ich übertrage unter Linux (das auf einem 
AT91SAM9261 läuft) Daten über die SPI-Schnittstelle an ein Display 
(S65).
Das funktioniert so weit auch problemlos.

Allerdings kam mir die Zeitdauer für die Übertragung eines kompletten 
Screens (46464 Bytes bei 13MHz SPI Takt) etwas lang vor, weswegen ich 
mir das mal mit nem Logic Analyzer angeschaut habe. Dabei ist mir 
aufgefallen, dass zwischen dem eigentlichen Senden eines Words (Dauer: 
~1,3us) immer eine Pause von ungefähr 3.2us vorhanden ist.

Ich benutze dabei die Funktion
int spi_write (struct spi_device *spi,const u8 *buf,size_t len)
,wobei ich den kompletten Speicher (also die 46464 Bytes) auf einmal 
übertragen lasse.

Meine Frage: Welche Möglichkeiten hab ich um die Effizienz der 
Übetragung zu verbessern bzw. konkret die nicht notwendigen Pausen 
zwischen den Übertragungen zu verringern.
Oder komm ich vielleicht mit dieser Schnittstelle von Linux hier gar 
nicht weiter und muss weiter unten am SPI des Prozessors ansetzen 
(spi_writel usw. ) ?

Beschäftige mich noch nicht so lange mit der Linux-Treiberprogrammierung 
und weiß daher nicht so recht wo ich ansetzen kann/soll.

Besten Dank und schöne Grüße,
Thomas B.

: Verschoben durch Admin
von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Verwendest du den Treiber atmel_spi? Der unterstützt eigentlich DMA, 
schneller geht's also von Hand auch nicht. Woher die Pause kommt kann 
ich mir da nicht erklären.

von O. D. (odbs)


Lesenswert?

Wo und wie wird die SPI-Schnittstelle initialisiert?

Was wird in das "SPI Chip Select Register" geschrieben, insbesondere in 
das Feld DLYBCT (= "Delay Between Consecutive Transfers")?

Ich habe gerade nur das Datenblatt vom AT91RM9200 vor mir liegen, weil 
ich mich mit dem im Moment herumärgere. Das SPI-Modul dürfte aber 
ähnlich sein. Nur hoffentlich weniger "buggy".

von Thomas B. (thomasb)


Angehängte Dateien:

Lesenswert?

Hallo !

Also ob Linux hier den SPI-Treiber aus atmel_spi.c benutzt bin ich mir 
ehrlich gesagt nicht sicher. In der Konfiguration habe ich zwar den 
Atmel-SPI ausgewählt, kann aber in den Linux-Sourcen keinen Aufruf der 
Funktionen aus der atmel_spi.c erkennen (was aber nicht unbedingt etwas 
heißen muss, da ich mich - wie schon erwähnt - noch nicht so lange damit 
beschäftige)

In meinem Board-File hänge ich die spi_board_info-Struktur
1
static struct spi_board_info testboard_spi_devices[] = {
2
{ /* User accessible spi - cs1 (1Mhz) */
3
  .modalias = "s65spi",
4
  .bus_num = 1,
5
  .chip_select  = 1,
6
  .max_speed_hz = 20 * 1000 *  1000,
7
},
8
...

mittels folgendem Funktionsaufruf ein:
1
at91_add_device_spi(testboard_spi_devices, 1);

Diese Funktion ist im File at91sam9261_devices.c realisiert. Dort werden 
scheinbar auch die entsprechenden Pins für die Verwendung als SPI 
konfiguriert:
1
...
2
at91_set_A_periph(AT91_PIN_PB30, 0);  /* SPI1_MISO */
3
at91_set_A_periph(AT91_PIN_PB31, 0);  /* SPI1_MOSI */
4
at91_set_A_periph(AT91_PIN_PB29, 0);  /* SPI1_SPCK */
5
...


Bei der Programmierung an sich habe ich mich an die Doku "spi-summary" 
und das Buch "Essential Linux Device Drivers" gehalten. Ich habe dabei 
aber die in der spi-summary angesprochene "Wrapper-Funktion" spi_write 
benutzt, welche das Generieren der spi_messages selber macht.

Anbei auch noch eine Grafik um die Delay-Problematik zu 
veranschaulichen. (Clock=13MHz, Dauer Übertragung: ~1.3us, Pause 
zwischen Übertragungen: ~3.2us)

Schöne Grüße,
Thomas B.

von O. D. (odbs)


Lesenswert?

Du benutzt atmel_spi.c

Schau dort mal rein, in den Linux-Quellen findest du das unter 
drivers/spi/...

Ich habe nachgeschaut, in das Feld DLYBCT wird tatsächlich eine "0" 
eingetragen, daran liegt es zumindest nicht. Du wirst aber sehen, dass 
der Treiber einige Workarounds um Hardware-Bugs enthält und insgesamt 
nicht gerade schön ist. Zum Beispiel werden die Chipselect-Leitungen per 
GPIO angesteuert. Es gibt auch einige Aufrufe von udelay() in diesem 
Treiber.

Dein Problem wird vermutlich irgendwo dort erzeugt. Vielleicht kannst du 
da ein wenig forschen.

Auf jeden Fall solltest du dich an die Linux4SAM-Mailingliste wenden und 
eine evtl. Problemlösung von dort hier posten.

von Thomas B. (thomasb)


Lesenswert?

Hallo !

Danke für die Antwort, werde mir die atmel_spi.c mal etwas genauer 
anschauen und das Problem (oder "Feature" ?) bei Linux4Sam bzw. At91.com 
posten.

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.