Forum: Mikrocontroller und Digitale Elektronik STM32F100: DMA oder nicht DMA ?


von Christian J. (Gast)


Lesenswert?

Hallo,

ich flansche derzeit ein ILI9341 (SPI) an einen kleinen uC an und 
schreibe die dazu nötigen Routinen selbst, allerdings nach Vorlage aus 
einer Lib, zb die Inits des Displays und die Kommandos zur Darstellung. 
Damit will ich mich nicht befassen, das Rad gibt es ja schon.

Nun zum mir bisher noch geheimnisvollen DMA Zugriff: Was würde mir der 
bringen, bezogen auf das Display und wie müsste ich ihn realisieren? Die 
Display Befehle sind unterschiedlich lang, es wird nur geschrieben, nie 
gelesen.

Derzeit muss die CPU so lange warten, bis die SPI eben fertig ist. 
Müsste eigentlich nicht sein.

Wie schreibe ich das nun um? Eine typische Display Sequenz für den 
Aufbau eines Graphen sind hunderte Display Kommndos und Bytes, die ich 
genausogut in einen Puffer schreiben könnte. Also die jetzige SPI 
Routine schreibt nicht in die SPi sondern in einen Puffer. Und wenn das 
Bild fertig ist müsste nur ein "Trigger" dafür sorgen, dass der DMA los 
rattert und alle Bytes ins Display schiebt. Natürlich mit den richtigen 
CE Takten.

Soweit theoretisch, da gibt es aber noch den Chip Select und einen 
weiteren Steuerpin. Und den kennt DMA ja nicht.

Wie würde es denn richtig gemacht?

von hp-freund (Gast)


Lesenswert?

Hallo,
ist zwar für den F4, aber das Prinzip ist das Gleiche.
Die Initialisierung wie bisher und zum übertragen der Pixeldaten 
schaltest Du in den window/page Modus. Dann gibt es keine störenden 
Steuersignale mehr und dem DMA steht nichts im Wege.

http://www.requiem-projects.com/en/ili9341-lcd-driver-stm32f4-dma/

von Christian J. (Gast)


Lesenswert?

hp-freund schrieb:
> ist zwar für den F4, aber das Prinzip ist das Gleiche.

Für den f4 habe ich das alles schon aber der 100 ist schon etwas anders, 
ich musste viel umstricken da die Lib andere Namen hat, die Peripherie 
an anderen Bussen hängt usw.

Allerdings werde ich mir diesen Code wohl schnappen und Stück für Stück 
umarbeiten, daran wird wohl kein Weg dran vorbei führen.

von hp-freund (Gast)


Lesenswert?

Eigentlich meinte ich mit dem Prinzip nur den window/page Modus mit DMA.
Den einschalten und Datenblock marsch :)

von Vincent H. (vinci)


Lesenswert?

Für exakt solche Fälle schreib ich immer eine Queue, in der die Befehle 
nach FIFO abgearbeitet werden. Eine "addTask" Funktion, in der neue 
Befehle reingeladen werden und an deren Ende geprüft wird ob der DMA 
bereits läuft.

Läuft er nicht -> aufdrehen.
Läuft er bereits -> nix tun, den neuen Task haben wir eh schon 
hinzugefügt.

Innerhalb des DMA Interrupts wird dann geprüft, ob noch Befehle in der 
Queue liegen und der DMA gegebenenfalls neu initialisiert.


Die Befehle selbst liegen in einer simplen Struktur, etwa so
1
struct
2
{
3
  struct
4
  { uint8_t buf[SIZE_DISPLAY_BUF];
5
    uint8_t nbyte;
6
    //uint8_t* src;
7
  } buf_t[NUMBER_OF_TASKS];
8
  uint8_t qwrite;
9
  uint8_t qread;
10
} disp_t;

qwrite und qread sind die aktuellen Indizes für "Task hinzufügen" und 
"Task bearbeitet". Mit einer modulo Funktion kann man die schön 
überrollen lassen, ohne sich irgendwelche Gedanken über deren Größe 
machen zu müssen. Wenn man garantieren kann dass die Wunschdaten auch 
nach hinzufügen eines Tasks noch erhalten bleiben, kann man theoretisch 
auch einen Pointer in die Queue schmeißen, statt dem Buffer... aber 
keine Ahnung wie viel RAM du hast?
Wer sauber programmiert darf den nötigen Platz wohl auch allokieren.

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.