Hallo, ich habe an einem nucleo-746zg ein TFT mit einem ILI9488 Controller hängen. Das Display betreibe ich über SPI. Das funktioniert soweit auch ganz gut, allerdings ist es sehr langsam. Ich kann beim Löschen des Displays wirklich zugucken. Vileicht hat ja jemand eine Idee, oder einen Kniff, mit dem STM32 bin ich relativ neu und die Einstellungen habe ich wahrscheinlich noch nicht alle verstanden. Ich habe mal die Treiberdateien angehangen. Vielen Dank schon mal Markus
Beitrag "Re: Stm32f103 Problem mit Spi2" beim f103 0,11 sec für 240x320 - Bildaufbau mit 16bit-Farben. Das kannst du zum Vergleichen nehmen.
Das ist schon mal interressant, ich brauche zur zeit ca. 2 sec. für ein 480x320 TFT bei maximalem Prozessortakt von 209MHz. Gruß Markus
Markus F. schrieb: > Vileicht hat ja jemand eine Idee, oder einen Kniff, mit dem STM32 bin > ich relativ neu und die Einstellungen habe ich wahrscheinlich noch nicht > alle verstanden. Tja wenn man so ein fertiges hardware-fernes (HAL-) Programmierteil verwendet dann kommt sowas dabei raus. Der Kniff besteht darin das SPI optimal auszunutzen und die Anzahl der aufzurufenden Schichten zu verringern. Entweder HAL oder schnell. Markus F. schrieb: > Ich habe mal die Treiberdateien angehangen. "Angehängt". Oder "als Anhang beigefügt".
Arduinoquäler schrieb: > Entweder HAL oder schnell. Bitte quäl weiter dein Ardudingsda. Programmierer benutzen DMA. HAL DMA.
>Entweder HAL oder schnell. SPI mit CubeMX kann auch schnell sein. Man muss nur DMA nutzen. >maximalem Prozessortakt von 209MHz Der CPU Takt sagt nichts über die SPI Taktung aus. Und die ist entscheidend. Gruß, dasrotemopped.
Hi, danke für die Antworten, an HAL DMA habe ich schon gedacht, erste Versuche sind aber leider bei mir gescheitert. Wie gehe ich denn dabei richtig vor ? Den gesamten Displayinhalt bekomme ich schlecht in den Speicher, also muss ich den Speicher aufteilen. Wie macht denn dabei eine Aufteilung Sinn ? Wird das Ganze über DMA schneller, wenn ich nur Punkte setze ? Wie konfiguriere ich den DMA für SPI richtig. Hat jemand ein Beispiel zur Konfiguration oder einen Ansatz für mich ? Viele Fragen, trotzdem schon mal vielen Dank Gruß Markus
da liegt der Hase im Pfeffer: void ili9488_send_byte(int data) { HAL_StatusTypeDef status = HAL_OK; //int timeout = 100; //status = HAL_SPI_Transmit(&ili9488_Spi, (uint8_t*) &data, 1, timeout); status = HAL_SPI_Transmit_IT(&ili9488_Spi, (uint8_t*) &data, 1); if(status != HAL_OK) { /* Execute user timeout callback */ //LCD_TESTLED_SET; } } überträgt genau ein Byte. bei 480*320*16bit =307200 Aufrufe dieser Funktion für ein Bild. Versuchs mal mit HAL_SPI_Transmit_DMA(&ili9488_Spi, zeiger, res_x*2); Aber Obacht, der DMA Transfer kann nicht ein Bild in einem Rutsch übertragen. Ich mache es zeilenweise, hat immer noch Overhead aber deutlich besser als mit der IRQ Variante pro Byte. Gruß, dasrotemopped.
So geht DMA mit SPI. Den Rest macht CubeMX. Danach geht dieser DMA Aufruf problemlos: HAL_SPI_Transmit_DMA(&ili9488_Spi, zeiger, res_x*2); Gruß, dasrotemopped.
@dasrotemopped Vielen Dank, dann werde ich in der Richtung mal weitermachen, sieht ja eigentlich nicht aus wie Hexenwerk. Gruß Markus
Hallo, ich habe mal die Init angepasst, aber so ganz klappt es nocht nicht.
1 | /* DMA controller clock enable */
|
2 | __HAL_RCC_DMA2_CLK_ENABLE(); |
3 | /* Peripheral DMA init*/
|
4 | ili9488_dma.Instance = DMA2_Stream3; |
5 | ili9488_dma.Init.Channel = DMA_CHANNEL_3; |
6 | ili9488_dma.Init.Direction = DMA_MEMORY_TO_PERIPH; |
7 | ili9488_dma.Init.PeriphInc = DMA_PINC_DISABLE; |
8 | ili9488_dma.Init.MemInc = DMA_MINC_DISABLE; |
9 | ili9488_dma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; |
10 | ili9488_dma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; |
11 | ili9488_dma.Init.Mode = DMA_NORMAL; |
12 | ili9488_dma.Init.Priority = DMA_PRIORITY_LOW; |
13 | ili9488_dma.Init.FIFOMode = DMA_FIFOMODE_DISABLE; |
14 | |
15 | HAL_DMA_Init(&ili9488_dma); |
16 | HAL_SPI_Init(&ili9488_Spi); |
17 | |
18 | /* DMA interrupt init */
|
19 | /* DMA2_Stream3_IRQn interrupt configuration */
|
20 | HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 0, 0); |
21 | HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn); |
22 | |
23 | /* Peripheral interrupt init */
|
24 | HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0); |
25 | HAL_NVIC_EnableIRQ(SPI1_IRQn); |
passt das so, oder hab ich da irgendwas vergessen ? Zum Probieren hab ich draw_full_rectangle geändert:
1 | void gfx_ili9488_draw_full_rectangle(ili9488_coord_t start_x, ili9488_coord_t start_y, ili9488_coord_t end_x, ili9488_coord_t end_y, ili9488_color_t color) |
2 | {
|
3 | if(start_x>=end_x) |
4 | return; |
5 | |
6 | color = COLOR_CONVERT(color); |
7 | |
8 | |
9 | uint8_t groesse; |
10 | groesse = abs((end_x-start_x)*(end_y-start_y)); |
11 | uint8_t Daten[groesse]; |
12 | |
13 | /* Set up draw area */
|
14 | ili9488_set_limits(start_x, start_y, end_x-1, end_y-1); |
15 | /* Write into GRAM */
|
16 | ili9488_send_command(ILI9488_CMD_MEMORY_WRITE); |
17 | /* Fill GRAM with Pixelcolor to clear the Display */
|
18 | |
19 | for(int n=0;n<abs((end_x-start_x)*(end_y-start_y));n=n+3) |
20 | {
|
21 | Daten[n]=(color); |
22 | Daten[n+1]=(color >> 8); |
23 | Daten[n+2]=(color >> 16); |
24 | }
|
25 | HAL_SPI_Transmit_DMA(&ili9488_Spi, Daten, groesse); |
26 | |
27 | ili9488_wait_for_send_done(); |
28 | ili9488_deselect_chip(); |
29 | }
|
Nochmal jemand einen Tipp ? Ich stehe gerade auf dem Schlauch. Gruß Markus
> aber so ganz klappt es noch nicht.
Sehr detaillierte Fehlerbeschreibung, aber das geht noch was genauer,
oder ?
Die mit CubeMX generierte Initialisierung sieht etwas anders aus, mal
verglichen ?
Das nucleo-746zg kann man per Mausklick mit aller Onboard Peripherie
auswählen.
Gruß,
dasrotemopped.
>ili9488_deselect_chip(); du brauchst Hardware CS für SPI DMA Pinmapping für ILI und SPI am STM32 ? Gruß, dasrotemopped.
du hast doch offensichtlich ein Problem mit deinem spi-code. Bevor du jetzt auf dma umstellst, wäre Fehlersuche und Fehlerbehebung angebracht. Schau dir mal im Debugger an, wieviel - überflüssige - Takte dein code bei ili9488_send_byte(); macht.
Markus F. schrieb: > Wird das Ganze über DMA schneller, wenn ich nur Punkte setze ? Die DMA Jünger werden dich anlügen. Oder sie werden nichtssagend ganz leise sein. Nein, sie sind es schon.
Schau dir mal im Debugger an, wie viele - überflüssige - Takte dein Code bei ili9488_send_byte(); macht. Jeder Takt ist zu viel, weil ein DMA Transfer keine CPU Zyklen benötigt. Darum beten die DMA Jünger ihn ja auch so an. Die DMA Jünger werden dich anlügen. Schon mal mit DMA selbst gearbeitet ? Hat deine CPU so was ? Gruß, dasrotemopped.
dasrotemopped schrieb: > Darum beten die DMA Jünger ihn ja auch so an. Und DMA Jünger sind solche Freaks dass sie es schaffen bei einzelnen DMA Byte-Transfers den Overhead einfach abzuschaffen. Die schaffen das!
Den DMA mit HAL_SPI_Transmit_DMA(&ili9488_Spi, Daten, groesse); zu starten benötigt natürlich CPU Zyklen, der DMA an sich aber nicht. Effizient und effektiv wird es erst bei großen Datenmengen. Ein Farb-TFT ist da ein gerne genommener Anwendungsfall. Man muss kein Freak sein, um mit der Maus in CubeMX die richtigen Häkchen zu setzen, RTFM reicht. Darf ich vom Nickname auf deine CPU schliessen ? Wie oft fällt im Datenblatt der Begriff DMA ? Aber lieber zurück zum STM32 und ili9488. Gruß, dasrotemopped.
dasrotemopped schrieb: > du brauchst Hardware CS für SPI DMA Wieso denn das? dasrotemopped schrieb: > Den DMA mit > HAL_SPI_Transmit_DMA(&ili9488_Spi, Daten, groesse); > zu starten benötigt natürlich CPU Zyklen, der DMA an sich aber nicht. > Effizient und effektiv wird es erst bei großen Datenmengen. Das ist nicht richtig. Der DMA kann sehr wohl CPU Zyklen benötigen, denn sowohl CPU als auch DMA greifen über die Busse auf den Speicher bzw. die Peripherie zu und dabei kann es passieren, dass der DMA die CPU blockiert.
>kann es passieren, dass der DMA die CPU blockiert. Das ist alles eine Frage der Speicherbandbreite und der Anforderungen der Anwendung. Zur Verfügung stehen internes, segmentiertes SRAM zur Erhöhung der parallel verfügbaren Speicherbandbreite. Die Hardwareausstattung des STM32F746ZG laut Datenblatt : L1-cache: 4KB data cache and 4KB instruction cache SRAM: 320KB (including 64KB of data TCM RAM for critical real-time data) + 16KB of instruction TCM RAM (for critical real-time routines) + 4KB of backup SRAM (available in the lowest power modes) Multiple masters: Cortex-Mx core AHB buses DMA1 memory bus DMA2 memory bus DMA2 peripheral bus Ethernet DMA bus USB high-speed DMA bus Chrom-ART Accelerator bus LCD-TFT bus siehe auch AN4031 / en.DM00046011.pdf Die Speicherbandbreite reicht aus, um all diese Sachen mit Daten zu versorgen. Da sollte ein SPI Bus mit 25MHz@8bit= 3MByte/s doch reibungslos zu bedienen sein. Ein FIFO Buffer (siehe Screenshot weiter oben) vermeidet konkurrierende Zugriffe aufs RAM noch weiter. >> du brauchst Hardware CS für SPI DMA >Wieso denn das? Einen GPIO Pin von der CPU umschalten zu lassen ist viel zu langsam für den DMA Controller. Und kostet natürlich auch wieder CPU Zyklen, das würde die Benutzung von DMA ad absurdum führen. Gruß, dasrotemopped.
@arduinoquäler http://www.stm32duino.com/ komm auf die dunkle Seite, sie ist nicht stärker, aber schneller, verführerischer, mit DMA
Hallo und danke erst einmal an alle, die geantwortet haben. Leider muss ich die nächsten Tage erst einmal etwas anderes bearbeiten, ich lese aber hier mit und freue mich über alle Tipps und Vorschläge. Gruß Markus
Ich hab schon seit einigen Monaten ein TFT mit ILI9488 hier herumliegen, es hat 4 inch Diagonale und es hat den RaspBerry Connector mit SPI. Anlässlich dieses Threads hab ich das TFT endlich mal in Betrieb genommen. Grundlage für meine Tests ist ein ATxMega128A1 der mit 32 Mhz läuft, die SPI im 2x Speed Mode mit 16 Mhz. Damit erreiche ich das Löschen des gesamten 480x320 Feldes in weniger als 280msec. Und da ist kein DMA dabei. Siehe Film .... Markus F. schrieb: > ich brauche zur zeit ca. 2 sec. für ein > 480x320 TFT bei maximalem Prozessortakt von 209MHz.
Zu Erklärung vielleicht noch: Gegen Ende des Demo-Video wird das TFT achtmal mit verschiedenen Farben gelöscht und zwischen jedem Löschen noch 20 msec gewartet. Also braucht das Löschen eigentlich nur etwa knapp 260 msec.
Arduinoquäler schrieb: > Grundlage für meine Tests ist ein > ATxMega128A1 der mit 32 Mhz läuft, die SPI im 2x > Speed Mode mit 16 Mhz. Damit erreiche ich das Löschen > des gesamten 480x320 Feldes in weniger als 280msec. Ich habe hier ein ILI9341 mit einer Auflösung von 320x240, betrieben im 16 Bit-Farbmodus. Dort komme ich auf eine effektive Datenrate von 2,8 MByte/s auf der SPI. Genutzt wird ein STM32F4 180 MHz, SPI läuft mit 22,5 MHz und natürlich mit DMA. Wenn DMA läuft kann die CPU sich wieder um andere Dinge kümmern. dasrotemopped schrieb: >>> du brauchst Hardware CS für SPI DMA >>Wieso denn das? > Einen GPIO Pin von der CPU umschalten zu lassen ist viel zu langsam für > den DMA Controller. Und kostet natürlich auch wieder CPU Zyklen, das > würde die Benutzung von DMA ad absurdum führen. /CS braucht man, wenn man noch andere Dinge am SPI hat. An meinem Display brauchte ich /CS um aus dem read mode wieder rauszukommen. Wichtig ist einen GPIO-Pin um zwischen Kommando und Datenmodus umzuschalten. Da kommt man nicht drumrum. Oder hat jemand eine Idee, wie man das dem STM-SPI-Modul mit überlassen kann? DMA lohnt sich nur für die Daten (nicht für die Kommandos) und auch nur, wenn man viele davon hat, also beim Bildschirm löschen, Rechteck füllen, orthogonale Linien zeichnen oder Fonts ausgeben. Bei einem einzelnen PutPixel bringt DMA nix. Rolf
Rolf schrieb: > Dort komme ich auf eine effektive Datenrate von 2,8 MByte/s auf der SPI. Dann dazu noch kurz die Datenrate meiner Anordnung ohne DMA und 16 MBit/sec SPI: 260msec, 16 Bit, 480x320 Pixel .... ergibt eine Datenrate von grob 1.18 MBytes/sec auf dem vergleichsweise "schwachbrüstigen" ATxMega128.
Rolf schrieb: > SPI läuft mit 22,5 MHz Theoretisches SPI Maximum: 22,5 MHz / 8 Bit = 2,8125 MByte /s realer Wert: 2,778 MByte /s (wenn die Displayausgabe stimmt) real/max = 98,8 % Arduinoquäler schrieb: > 16 MBit/sec SPI Theoretisches SPI Maximum: 16 MBit/s = 2 MByte/s realer Wert: 1,18 MByte/s real/max = 59 % Laufen da auf dem ATxMega128 noch irgendwelche Tasks?
>Damit erreiche ich das Löschen des gesamten 480x320 Feldes >in weniger als 280msec. Und da ist kein DMA dabei. Siehe Film .... Gutes Ergebnis. Das heisst aber, das der DMA Controller im Xmega128 ungenutzt rumliegt ? Mit DMA würde SPI nicht viel schneller, aber die CPU Last ist deutlich geringer und der uC könnte sich um das Ranschaffen der nächsten Datenpakete kümmern. Hier mal ein Beispiel mit STM32F4 und ili9341 im SPI Modus: https://www.youtube.com/watch?v=qSf7YtFZIsA Abwechselnd wird mit und ohne DMA ein neues Bild geschrieben. Der Unterschied im Bildaufbau ist gering, aber die CPU Last ohne DMA ist 100%, mit DMA muss die CPU sich nur um den Start des DMA Prozesses kümmern. In den Kommentaren ist auch ein Link zum Sourcecode, falls es jemand interessiert. SPI und ili9341 ist aber nur ein Nebenschauplatz bei dem Projekt. Beim Xmega128 mit 32 MHz/8bit kann die CPU intern bist zu 32MB/s schieben, das heisst, SPI ist mit 2 MB/s im Verhältnis ein Flaschenhals für die CPU. Beim STM32F4 mit 180MHz/32bit wird das Verhältnis noch schlechter, so das DMA schon fast zur Pflicht wird. >GPIO-Pin um zwischen Kommando und Datenmodus >umzuschalten... hat jemand eine Idee, wie man das dem >STM-SPI-Modul mit überlassen kann? Nicht mit SPI. Die Lösung ist ein SSD1963 am i80/SRAM Speicherinterface. Ist mit STM32F4 und Xmega128 möglich. Da bestimmt nur die beschriebene Speicheradresse im externen RAM ob das Daten oder Command Flag gesetzt ist. Gruß, dasrotemopped.
dasrotemopped schrieb: > Gutes Ergebnis. Das heisst aber, das der DMA Controller im Xmega128 > ungenutzt rumliegt ? So ist es. Ich wollte das Display in Betrieb nehmen und dabei zeigen was gegenüber der erschreckenden Datenrate beim STM32 (siehe Eingangs-Post) herauszuholen ist. Ohne DMA. Stefan schrieb: > Laufen da auf dem ATxMega128 noch irgendwelche Tasks? Nein, nur der 1 msec Timer Interrupt. Man bedenke dass die SPI nicht nur die Daten rausschaufeln muss sondern der Prozessor muss auch jedes Byte einzeln in das SPI Datenregister schreiben, und das "ge-handshaked". Eine teilweise Entrollung der Schleife (4 Transfers) macht das Ganze noch etwas flotter, aber viel mehr ist nicht zu holen. Auch ein 16-Bit Schleifen- Inkement braucht seine Zeit.
Ich würde ja die DMA-Jünger befriedigen wollen die so sehr darauf schwören, auch weil es mich (rein theoretisch) interessiert, aber ich fürchte es geht in diesem Fall nicht. Die DMA Maschine beim ATxMega braucht entweder eine feste Quelladresse oder einen kontinuierlichen Speicherbereich zum Lesen. Im Falle eines TFTs mit SPI müssen jedoch für das einzelne Pixel 16-Bit Worte geschrieben werden, also alternierend Low Byte / High Byte. Das kann die DMA Maschine aber nicht leisten. So wäre ein DMA-Transfer fürs TFT nur möglich wenn die Farbe schwarz ist, dann kann man einfach die erforderliche Zahl Nullen schicken, oder die gewählte Farbe hat im Low und High-Anteil den gleichen Wert. Nicht sehr warscheinlich und auch nicht sehr praktisch ..... Einziger Ausweg wäre einen Buffer in der Grösse des Displays bereitzustellen wo die Lösch-Daten schon drinstehen, aber die müssten auch erst mal (für jede Farbe) da drinstehen und der Buffer müsste immer da sein. Wäre die SPI-Maschine auf 16 Bit ausgelegt dann bestünde Hoffnung. Vielleicht fällt jemand noch etwas ein was ich beim ATxMega übersehen habe.
Um mal wieder auf die Frage des TO zurückzukommen. Hier mal das Nucleo-F746ZG einmal ohne DMA, aber dafür alle 3 Bilder von SDcard gelesen und das zweite Beispiel transferiert die selben 3 Bilder aus dem Flash per SPI DMA ans Display. Der RAM Verbrauch bleibt bei beiden Varianten gering, da immer nur maximal eine Bildzeile im RAM zwischengespeichert wird. Das sollte auch ein Xmega packen (Kapitel 2.2): http://www.atmel.com/Images/Atmel-8046-Using-the-XMEGA-DMA-Controller_Application-Note_AVR1304.pdf Die Daten müssen natürlich in der Bytereihenfolge vorliegen, so wie es der Framebuffer des Displays sie erwartet. Umschichten beim SPI Transfer ist nicht möglich. Beim Xmega und beim STM32 ist der SPI Modus durch das Display festgelegt. Ich habe 16 bit Farbtiefe, aber 8 bit SPI und es geht offensichtlich, und das schnell. Gruß, dasrotemopped. PS: Ein Microprozessor bearbeitet Datenströme, ein Microcontroller steuert Datenströme. Das muss man bei der Konzeptionierung seiner Programme und Hardware immer bedenken. Das Lesen des Eingabedatenstroms vom externen Speicher und die Weiterleitung an ein externes Display per DMA lässt den Microcontroller als Dirigent auftreten, der DMA Controller ist der, der die Arbeit erledigt, hoch spezialisiert und effizient. Die Leistungsfähigkeit des Microcontrollers ist dann unwichtig.
Arduinoquäler schrieb: > Ich wollte das Display in Betrieb nehmen und dabei > zeigen was gegenüber der erschreckenden Datenrate beim STM32 > (siehe Eingangs-Post) herauszuholen ist. Ohne DMA. Der STM kommt auch ohne DMA auf eine ordentliche Datenrate. Aber definitv nicht mit der HAL. Man sollte die HAL einfach als eine Beispielimplementierung betrachten, die von ängstlichen Javaprogrammieren entworfen wurde. Man betrachte nur mal die ganzen Sicherheitsabfragen, bevor da was passiert. Beim ILI-TFT muß ja auch ständig zwischen 8- und 16-Bit, data und command, single- und DMA-Transfer umgeschalten werden, da kommt man mit der HAL auf keinen grünen Zweig. Ich habe die HAL-Funktionen als Startpunkt genommen. Dann habe ich Schritt für Schritt die überflüssigen Codeteile entfernt. > Nein, nur der 1 msec Timer Interrupt. Der läuft bei mir auch, für die Zeitzählung. Und die Bytezählung habe ich in die SPI-Transferfunktionen mit reingenommen. Arduinoquäler schrieb: > Im Falle eines TFTs mit SPI müssen jedoch für das > einzelne Pixel 16-Bit Worte geschrieben werden, also > alternierend Low Byte / High Byte. Das kann die DMA Maschine > aber nicht leisten. Da war ich ganz froh, das der STM32 das kann (16 Bit SPI und 16 Bit DMA). Sonst wären da auch ein paar Krücken nötig gewesen. Rolf
>Beim ILI-TFT muß ja auch ständig zwischen 8- und 16-Bit, data und >command, single- und DMA-Transfer umgeschalten werden, da kommt man mit >der HAL auf keinen grünen Zweig. Kann ich nicht nachvollziehen. Ich nutze ausschliesslich CubeMX/HAL und irgendwas umschalten 8/16 bit beim ili-TFT mache ich auch nie. Und langsam kommt mir das jetzt auch nicht vor. Aber ich lasse mich durch Gegenbeispiele gerne überzeugen. Gruß, dasrotemopped.
Arduinoquäler schrieb: > Ich hab schon seit einigen Monaten ein TFT mit ILI9488 > hier herumliegen, es hat 4 inch Diagonale und es hat > den RaspBerry Connector mit SPI. So .... jetzt zum feierlichen Sonntag Nachmittag ein bisschen Übung auf dem STM32F407 (Discovery). Display Löschen dauert hier 117 msec bei 21.xxx Mhz SPI Clock. Ergibt etwa 2.62 MByte/sec wenn ich richtig gerechnet habe. Ach ja: ohne DMA. Ach ja: ohne HAL, aber mit "Arduinoquäler-Optimierung" Wenn ich wieder Zeit habe werde ich das Ganze noch mit DMA machen.
Der auf dem Foto sichtbare blaue Connector ist übrigens für die 16-Bit Displays (SSD1963, ILI9325, ILI9341...). Da macht so ein Display noch etwas mehr Freude / Speed. Sogar ohne DMA.
@Arduinoquäler, finde ich klasse, wie schnell das bei Dir geht. Würdest Du mich teilhaben lassen und einen Source hochladen ? Ich würde mich freuen. Ich bin leider nicht zu besonders viel gekommen, ich habe einen Bandscheibenvorfall und kann mich kaum bewegen. Gruß Markus
>ein bisschen Übung auf dem STM32F407 der zieht gleichauf mit meinem STM32F429 >Ach ja: ohne DMA die etwa 3 MB/s sollten weder Xmega noch STM32 in Verlegenheit bringen auch hier wird klar, das das SPI Display im wesendlichen davon abhängt, das der SPI Kanal immer gut mit Daten versorget wird und möglichst hoch getaktet ist. Allerdings ist keine CPU damit überfordert. Eigendlich ist die Warheit, das die CPUs sich bei dem ili9341/9388 Display langweilen und könnten noch viel mehr zusätzlich machen. Im Video habe ich da mal ein Beispiel: das ili9341 am SPI2 benutze ich nur als Debug/Status Anzeige, der eigendliches Spass ist auf dem externen LTDC VGA Ausgang. 800x480@16bit mit 30fps. Das ili9341 wird auch mit 30 fps aktualisiert, aber nicht Vollbild. Auf dem Monitor rechts oben ist übrigens der framecounter eingeblendet, DMA wird natürlich ;) benutzt, aber das Optimum ist noch lange nicht erreicht. Aber da das ganze nur Hobby ist geht es langsam vorran. Gruß, dasrotemopped.
dasrotemopped schrieb: > die etwa 3 MB/s sollten weder Xmega noch STM32 in Verlegenheit bringen Diese Aussage verstehe ich allerdings nicht .... Dann noch dieses: Stefan schrieb: > Theoretisches SPI Maximum: 22,5 MHz / 8 Bit = 2,8125 MByte /s Dann bin ich ja mit meiner Nicht-DMA-Implementierung nicht weit vom möglichen Maximum entfernt, solange man mit der SPI-Datenrate bei 21..22 Mhz bleibt: Beitrag "Re: STM32 F746zg nucleo und ILI9488 TFT per SPI langsam ?" Liebe DMA-Jünger: Bleibt also anzunehmen/vorauszusagen dass durch das "langsame" SPI hier sich die Datenrate mit DMA nicht wesentlich steigern lässt. Insbesondere auch deshalb weil DMA-Transfers sich für kleine Datenmengen nicht lohnen wird weil der Overhead zuviel Zeit verschlingt.
Arduinoquäler schrieb: > Liebe DMA-Jünger: > Bleibt also anzunehmen/vorauszusagen dass durch das "langsame" > SPI hier sich die Datenrate mit DMA nicht wesentlich steigern > lässt. Insbesondere auch deshalb weil DMA-Transfers sich für > kleine Datenmengen nicht lohnen wird weil der Overhead zuviel > Zeit verschlingt. Die Datenrate steigt sicherlich nicht, aber sehr wohl lohnt sich DMA schon oft bei kleinen Datenmengen. Bei 20MHz SPI kann eine 180MHz-MPU während eines 16-Bit-Transfers (ein Pixel) schon etliche Befehle ausführen. Erst recht gilt das für die 216MHz F7 oder gar die 400MHz H7 MCUs. Der Overhead bei DMA beschränkt sich ja meistens auf das Setzen vom CS, der Anfangsadresse sowie der Menge der Daten. Zum Schluss dann noch ein, zwei Befehle im IRQ. Rechnen lohnt sich also, insbesondere wo etliche SPI-ICs auch nur 10MHz oder weniger verkraften.
john doe schrieb: > Bei 20MHz SPI kann eine 180MHz-MPU während eines 16-Bit-Transfers (ein > Pixel) schon etliche Befehle ausführen. Ja das könnte der Fall sein wenn ich (als Prozessor-Kern) nicht schon drauf warte das nächste Graphik-Paket an das SPI zu senden. Im Nachhinein: Wen man sich die Sourcen des im Eingangsbeitrag geposteten Treibers anschaut dann kann einem schon das blanke Entsetzen packen. Für jedes Bitchen setzen eine eigene Funktion ..... geschrieben von einem (vermutlich) Java-Programmierer der von 8-Core xxxGHz Pentiums verdorben ist. Schlimmster "Fehler" (das kann man natürlich auch anders sehen): Die Pixel werden im 24-Bit-Modus geschrieben. Würde man sich auf 16 Bit Farbauflösung beschränken (was die Displays ja klaglos hergeben) könnte man alleine dadurch ca 30% Verarbeitungszeit sparen. Korinthenkacker können jetzt philosophieren wie sinnvoll 24 Bit Farbe auf einen Mikrocontroller-Display ist ....
>sich die Datenrate mit DMA nicht wesentlich steigern lässt richtig, SPI mit 25MHz bleibt auch mit DMA SPI mit 25MHz >kann eine 180MHz-MPU während eines ... Transfers ... schon >etliche Befehle ausführen genau das ist der Punkt. Die CPU von einfachen Datenschiebeaufgaben zu befreien und anderweitig nutzen. Ich denke, mein Beispiel mit dem VGA Ausgang zeigt deutlich, das DMA die Aufgabenteilung im System optimiert. DMA was DMA am besten kann und CPU was CPU am Besten kann. Und allgemein muss man feststellen, das selbst bei "kleinen" Systemen die beste Lösung nicht automatisch eine schnellere CPU ist, sondern zu prüfen, ob man schon alles aus der Plattform herausgeholt hat. Auch ein Singlecore uC kann Multitasking mit guter Performance. Bleibt nur zu hoffen, das ein Blick in den Quellcode dem TO genug Hilfe ist um seine Performanceprobleme zu beheben. Aber mein Code zum ili9341 und sein Code zum ili9488 sind ja fast gleich strukturiert, es fehlt nur eine etwas mehr Hardware optimierte Implementierung der SPI Nutzung (Hardware CS und DMA). Grundsätzlich funktioniert die Ansteuerung des ili9488 ja. Gruß, dasrotemopped.
Arduinoquäler schrieb: > Dann bin ich ja mit meiner Nicht-DMA-Implementierung nicht weit > vom möglichen Maximum entfernt, solange man mit der SPI-Datenrate > bei 21..22 Mhz bleibt Der Sinn von DMA ist nicht nur, die Hardware-Übertragung zu beschleunigen, sondern die CPU während der Übertragung für andere Aufgaben benutzen zu können. Gruß, Stefan
Stefan K. schrieb: > sondern die CPU während der Übertragung für andere > Aufgaben benutzen zu können. Arduinoquäler schrieb (schon) im Beitrag #4883559: > Ja das könnte der Fall sein wenn ich (als Prozessor-Kern) nicht > schon drauf warte das nächste Graphik-Paket an das SPI zu senden.
Hallo zusammen, ein wenig habe ich heute mit einem Kollegen daran weiterarbeiten können. Die größte Optimierung, die wir erreicht haben, kam durch das schreiben der 3 Farb-Bytes direkt hintereinander und des Löschen des Displays mit einem Zeilenweisen Buffer. Vielen , vielen Dank für die Hinweise von Euch, manchmal steht man einfach ein bisschen auf der Leitung. Jetzt geht es nach und nach an die Optimierung z.B. der Textausgabe. Viele Grüße Markus
Die Funktion die am häufigsten aufgerufen wird ist send_byte() und arbeitet mit dem aufwändigen ST HAL. Den muss man aber nicht gleich komplett wegwerfen, es reicht soetwas wie ein fastWrite() dazuzubauen. Hier ist ein Beispiel wie das bei der mbed lib gemacht wurde: https://developer.mbed.org/users/Sissors/code/BurstSPI/file/bc069279eb37/BurstSPI_STM32F4.cpp Probiert mal aus einfach den Teil aus dem fastWrite in das send_byte zu packen, der spi Pointer muss dabei durch eure globale ili9488_Spi Struktur ersetzt werden. Und weil vom Display nichts zurückgelesen wird ist der ClearRX Teil nicht nötig.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.