STM32F100: DMA oder nicht DMA ?

Gast #4476387
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?
Gast #4476539
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.
#4477185
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren