Forum: Mikrocontroller und Digitale Elektronik STemWin am STM32F429-Disco Problem mit Landscape


von Uwe B. (derexponent)


Lesenswert?

Hallo,

ich habe wieder das gleiche Problem wie schon vor ein paar Monaten
wo ich das Display am STM32F429 versucht habe in Landscape-Mode zu 
bringen

und zwar hab ich die STemWin (von Segger) auf dem STM32F429-Disco Board 
am laufen

funktioniert soweit alles wunderbar bis auf das "drehen" vom Screen
also der Bildschirm steht immer im Portrait-Mode
und ich will ihn in Landscape-Mode drehen.

egal ob ich in der "GUIDRV.c" den Define auf "#define LCD_SWAP_XY  1"
einstelle oder später während der Laufzeit
den Befehl "GUI_SetOrientation(GUI_SWAP_XY);" benutze

funktioniert beides nicht

hat da jemand eine Lösung parat...
oder einen Ansatz wonach ich suchen könnte ?


Gruss Uwe

von Stephan K. (nightowl)


Lesenswert?

Wenn du die Änderung direkt über den Display-Controller machen möchtest:

http://www.newhavendisplay.com/app_notes/ILI9341.pdf

Kapitel 9.3 Seite 208

Gruß Stephan

von Lutz H. (luhe)


Lesenswert?

Geht es ein normales Bild zu bauen, und dann den Bildinhalt zu drehen 
(rotate)
 (GUI_MEMDEV_Rotate())

von Stephan K. (nightowl)


Lesenswert?

Nur so ne Idee,

könnte es sein das es für die Betribsarten unterschieldliche Sourcen 
gibt?

Es gibt discovery_lcd.c und daneben noch discovery_lcd_land.c was auf 
Landscape deuten könnte.

Gruß Stephan

von Stephan K. (nightowl)


Lesenswert?

Scheint wohl so zu sein.

In lcd_land.c ist eine TotalWidth mit 359 un High mit 247 angegeben,
in der lcd.c wird eine TotalWidth mit 279 un High mit 327 angegeben.

Also geht wohl nur entweder oder.

Gruß Stephan

von Uwe B. (derexponent)


Lesenswert?

Danke erst mal für die Antworten

>Wenn du die Änderung direkt über den Display-Controller machen möchtest:

das geht nicht, weil er im RGB-Mode nicht das interne Display-RAM 
benutzt sondern die Daten per TFT-Controller refreshed werden
und diese werden im Portrait-Mode gesendet

>Geht es ein normales Bild zu bauen, und dann den Bildinhalt zu drehen

da muss ich mich mal einlesen, scheinbar ist die "Memory-Device" 
Unterstützung nicht im standard Umfang vorhanden und muss erst 
zusätzlich runtergeladen werden...probier ich aber aus

>Es gibt discovery_lcd.c und daneben noch discovery_lcd_land.c was auf
>Landscape deuten könnte.

von welchem Beispiel hast du das ? ich bräuchte eine Lösung für ein 
Display mit externem Frame-Buffer ...alle Displays die "normal" das 
interne LCD-RAM benutzen, könnnen wahrscheinlich während der 
Initialisierung auf Landscape gedreht werden (durch die Register vom 
LCD).

...ich werd mal weiter suchen, im Demo von ST funktioniert das ganze ja, 
da werden Bilder und die Filme auch im Querformat angezeigt
(ich benutze genau die gleichen Config-Files)
aber ich kenne mich mit emWIN einfach zu wenig aus um rauszufinden wie 
die das machen.

Gruss Uwe

von Stephan K. (nightowl)


Lesenswert?

Das waren Dateien aus dem Graphic workshop.

Stm32F4_GraphicWorkshop/FW_Projects/Utilities/STM32F429I-Discovery/stm32 
f429I_discovery_lcd_land.c  bzw .h

Ich hab nochmal bei St nachgesehen, und konnte die Dateien dort nicht 
finden.

Diese Initialisierungen sind für den Diplay-Controller ILI9341 des TFTs.

Im Moment versteh ich allerdings nicht wie die beiden Display-Controller 
in Abgrenzung zueinender genutzt werden.

Ich muß mir das bei Gelegenheit mal durchlesen.

Ursprünglich hatte ich es so verstanden, daß bei einem existierenden 
TFT-Controller nur Ram als Framebuffer zur Verfügung gestellt wird und 
noch ein paar 2D Befehle von Crom-Art die Bearbeitung beschleunigen.
Wobei der auch nicht viel mehr kann als ILIxxx von selber.

Also der gesamte Bildzusammenbau auf dem STM32 erfolgt.

Der Zugriff auf das Display dann aber wider über die Register des 
TFT-Controllers bzw dessen Treiber ausgeführt wird.

Dort lässt sich auch im Betrieb, und nicht nur zur Initialisierung die 
Schreibrichtung ändern.

Gruß Stephan

von Uwe B. (derexponent)


Lesenswert?

Hi Stephan,

könntest du aus den Files von diesem "STM32F429I-Discovery" Unterordner
eine ZIP machen und hier reinhängen

oder per PN an mich oder EMail an "MC-4U(AT)T-Online.de" senden ?

wenn das File "stm32f429I_discovery_lcd_land.c" von ST ist
dann steht da vermutlich drinn wie man den Display-Inhalt dreht
(event. bei der Konfig vom RGB-Mode vom Display)

das würde mir schon reichen

Gruss und Danke Uwe

von Lutz H. (luhe)


Lesenswert?

http://www.st.com/web/en/catalog/tools/PF259429#

Dort sind Unterlagen vom Lehrgang
die Files stm32f429i_discovery_lcd_land.* im zip File suchen

von manni (Gast)


Lesenswert?

lutz h. schrieb:
> die Files stm32f429i_discovery_lcd_land.* im zip File suchen

Leider existiert eine solche Datei nicht im zip, nur wie gehabt die 
"stm32f429i_discovery_lcd.c".

von manni (Gast)


Lesenswert?

Uwe B. schrieb:
> könntest du aus den Files von diesem "STM32F429I-Discovery" Unterordner
> eine ZIP machen und hier reinhängen

Ja, bitte ...

von Lutz H. (luhe)


Lesenswert?

Es wird einen Grund haben, die Datei land.c nicht anzuhängen,
Als Änderung sind nur die Werte 320 für xsize und 240 für  ysize  zu 
finden, immer wenn so eine Variable vorkommt.

von Karl K. (leluno)


Lesenswert?

1
//old    lcd_write_reg(0x03,0x1038); /* Set the scan mode */
2
    //Portrait//landscape
3
4
#if ( DISP_ORIENTATION == 0 )//0° grad
5
    lcd_write_reg(0x0003,(1<<12) );   /* importance */
6
#endif
7
#if ( DISP_ORIENTATION == 1 )//90°
8
    lcd_write_reg(0x0003,(1<<12)|(1<<5)|(1<<3) );   /* importance */
9
#endif
10
#if ( DISP_ORIENTATION == 2 )//180°
11
    lcd_write_reg(0x0003,(1<<12)|(1<<4)|(1<<5) );   /* importance */
12
#endif
13
#if ( DISP_ORIENTATION == 3 )//270°
14
    lcd_write_reg(0x0003,(1<<12)|(1<<4)|(1<<3) );   /* importance */
15
#endif

von Uwe B. (derexponent)


Lesenswert?

So...nach über 4 Stunden fehlersuche hier ein "Abschlussbericht"


zuerst das Wichtigste :

1. ich bin scheinbar zu blöd dafür und geb es auf :-)


jetzt die Sachen die ich ausprobiert habe :

[STM32F429i-Disocvery-Board mit externem RAM und ILI9341-Chip]
=================================================================

1. Das drehen vom Screen per "GUI_SWAP_XY" im Config-File
hat keine Auswirkung

2. Das drehen vom Screen während der Laufzeit per 
"GUI_SetOrientation(GUI_SWAP_XY)" liefert eine "1" als Fehler-Nr zurück 
und funktioniert nicht

3. in der GUIConfig.h wird ein Adressbreich "HeapMemSection" im externen 
RAM definiert (1MByte groß) komischerweise wird die zugehörige Funktion 
die die Adresse übergibt "Get_ExtMemHeap" scheinbar nie von der GUI 
aufgerufen.
ein anpassen vom LinkerScript bringt auch keine Verbesserung

4. Stephan hat mit das File von ST zugesendet mit dem Namen 
"stm32f429i_discovery_lcd_land.c und .h" .Dieses File erzeugt bei mir 
genau den gleichen Fehler den ich schon vor 2 Monaten hatte. Das Display 
wird zwar gedreht aber es werden nur 240 Pixel in X-Richtung gezeichnet. 
Es bleibt also ein "Rand" von 80-Pixel breite stehen...auch nicht zu 
gebrauchen.

[STM32F407-Disocvery-Board mit ST7783-Chip]
=================================================================

1. Das drehen vom Screen per "GUI_SWAP_XY" im Config-File
dreht den Screen auf Landscape-Mode !!
ABER -> die Schriften sind spiegelverkehrt

2. Wenn man zusätzlich "GUI_MIRROR_X" benutzt, wird die Darstellung 
komplett unleserlich

3. Das drehen vom Screen während der Laufzeit per 
"GUI_SetOrientation(GUI_SWAP_XY)" liefert eine "1" als Fehler-Nr zurück 
und funktioniert nicht

4. Das drehen vom Screen durch das beschreiben vom LCD-Adress-Register 
0x03 beim Initialisieren bringt auch keine Verbesserung


also...ich bin mit dem Thema durch, wer den Fehler findet kann ja kurz 
bescheid geben.

von manni (Gast)


Lesenswert?

Ich habe es auch aufgegeben (gleiches Ergebnis: Rand mit einer Breite 
von 80+ Pixeln). Man kann wohl davon ausgehen, dass es nicht möglich 
ist. Was ich ziemlich blöd finde, da man das Display meist horizontal 
verwenden möchte (ich zumindest) und der ILI9341 prinzipiell ja die 
Möglichkeit dazu bietet, ohne dass man groß herummurksen muss.

Uwe B. schrieb:
> Stephan hat mit das File von ST zugesendet mit dem Namen
> "stm32f429i_discovery_lcd_land.c und .h" .Dieses File erzeugt bei mir
> genau den gleichen Fehler den ich schon vor 2 Monaten hatte.

Das hatte ich schon befürchtet (aber dennoch gehofft, dass sich das 
große Geheimnis doch noch darin findet).

von Lutz H. (luhe)


Lesenswert?

Uwe B. schrieb:
> 1. ich bin scheinbar zu blöd dafür und geb es auf :-)

 Jetzt kämpfe schon seit 8 Stunden
    GUI_Init() auszuführen,ich komme mir erst blöd vor.

von Uwe B. (derexponent)


Lesenswert?

>Jetzt kämpfe schon seit 8 Stunden
>    GUI_Init() auszuführen,ich komme mir erst blöd vor.

schalte mal (vor dem init) den CRC-Clock ein :
1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);

und für die Pausenfunktionen "GUI_Delay" muss per Sysclock
die Variable "OS_TimeMS" jede ms incrementiert werden


beim STM32F429 brauchst du zusätzlich noch ISR-Handler
für "LTDC_IRQHandler" und "DMA2D_IRQHandler"


Gruss Uwe

von Karl K. (leluno)


Lesenswert?

mit dem oben vorgestellten code funktioniert das bei meinen ilis (9225 
und 9320) problemlos.


x-y muss natürlich auch umdefiniert werden:
1
#define lcd_max_width 320
2
#define lcd_min_width 240
3
4
5
#define DISP_ORIENTATION  0 //0x0° screen rotation
6
//#define DISP_ORIENTATION  1 //1x90° screen rotation
7
//#define DISP_ORIENTATION  2 //2x180° screen rotation
8
//#define DISP_ORIENTATION  3 //3x270° screen rotation
9
10
11
#if  ( DISP_ORIENTATION == 1 ) || ( DISP_ORIENTATION == 3 )
12
//querformat landscape
13
#define  MAX_X  lcd_max_width
14
#define  MAX_Y  lcd_min_width   
15
#elif  ( DISP_ORIENTATION == 0 ) || ( DISP_ORIENTATION == 2 )
16
//hochformat portrait
17
#define  MAX_X  lcd_min_width
18
#define  MAX_Y  lcd_max_width   
19
#endif

von Uwe B. (derexponent)


Lesenswert?

karl k. schrieb:
> mit dem oben vorgestellten code funktioniert das bei meinen ilis (9225
> und 9320) problemlos.

auch in Verbindung mit emWin (bzw. STemWin) und externem RAM als 
Grafik-Speicher ?

von Stephan K. (nightowl)


Lesenswert?

Laut o.A. ILI Datenblatt

In both RGB interface modes, the input display data is written to GRAM 
first then outputs corresponding source voltage according the gray data 
from GRAM.

Möglicherweise interpretiere ich das ja falsch, aber für mich sieht es 
so aus als ob die Daten auf jeden Fall ins GRAM geschrieben werden.

Die o.A. Register definieren dann immer den Aufbau des Bildes aus dem 
GRAM heraus.

Ich werde morgen noch einmal die rotate Funktion zerlegen. Diese macht 
meiner Ansicht nach nichts anderes als genau diese Register zu setzen.

Grundsätzlich funktioniert das ja auch bis auf die bekannten fehlenden 
80.

Gruß Stephan

von Karl K. (leluno)


Lesenswert?

Uwe B. schrieb:
> auch in Verbindung mit emWin (bzw. STemWin) und externem RAM als
> Grafik-Speicher ?

dem display ist es völlig egal, wo die Daten herkommen. Der Fehler liegt 
mit einiger Wahrscheinlichkeit nicht am display. EmWin ist ausgereifte 
Software und wahrscheinlich auch nicht die Fehlerursache. Definier dein 
Display mal als 320 x 320 und schau was dann passiert.

von Friesenmartin (Gast)


Lesenswert?

Also ich bekomme es ebenfalls nicht wirklich hin.

Arbeit noch jemand an dem Thema?

VG

von Lutz H. (luhe)


Lesenswert?

Ich habe mir das auch einfach vorgestellt
zwei Werte ändern und alles ist ok.
zum Beispiel
#define LCD_SWAP_XY  1
#define LCD_MIRROR_Y 1

Die Bildpunkte des Displays bilden oft einen Speicherbereich  der linear 
ausgelesen wird. z.B in X Richtung.
Ändert sich das Bildschirmverhältnis, fängt das Problem an, wo ist Y, wo 
ist X, wie muss der Speicherausgelesen werden?
Wenn ich etwas drehe, ist dann unten oben,links oder rechts?

Schön wäre es, wenn ich verstehen würde, wie  EmWin für das Board 
angepasst werden kann.

oder ist es besser die lib STemWin522_patch1_CM4_IAR.a
mit den zugehörigen c und h einzubinden?

von holger (Gast)


Lesenswert?

Wenn ich in der Firmwaredemo beim Videoplayer
nur diese Zeile ändere, dann ändert sich auch die Ausgabe richtig:

//GUI_SetOrientation(GUI_SWAP_XY | GUI_MIRROR_Y);
GUI_SetOrientation(GUI_SWAP_XY | GUI_MIRROR_X);

Das Video steht bei Fullscreen dann auf dem Kopf.
GUI_SetOrientation() funktioniert also.
Jetzt müsste man mal rausfinden wo euer Problem ist;)

von Stephan K. (nightowl)


Lesenswert?

@ Holger 90° ist das Problem nicht 180°.

Die Änderung über die Register im ILI zu machen geht wohl tatsächlich 
nicht.
Der Hersteller macht in diesem Forum eine Aussage dazu es ist der 14. 
Kommentar.

http://www.lpcware.com/content/forum/lcd-orientation-issue

Es gibt auch noch ein offenes Problem im Segger Forum
Dort steht auch wie es eigentlich richtig gemacht wird.

http://forum.segger.com/index.php?page=Thread&threadID=1672


Gruß Stephan

von Friesenmartin (Gast)


Lesenswert?

Hat es jemand schon hinbekommen?
Hab einiges versucht, war aber bis jetzt alles ohne Erfolg:-(

von Uwe B. (derexponent)


Lesenswert?

ich hab das Problem (teilweise) gelöst !!


1. Der Befehl "GUI_SetOrientation()" benötigt zum drehen vom Display 
sehr viel speicher (> 512 kByte)

wenn er den nicht hat gibt er eine "1" als Rückgabewert zurück und
dreht das Display nicht

2. Wenn man der GUI einen Teil vom externen SDRAM per LinkerScript 
zuteilt
funktioniert zwar das drehen (in allen 4 Ausrichtungen)

ABER !!

die GUI wird sehr viel langsamer...weil er nicht auf den schnellen 
internen RAM der CPU sondern per FMC-Bus auf den externen RAM zugreifen 
muss

Vergleich :
internes RAM = 34.752.000 Pixel/sec
SDRAM        =  1.375.000 Pixel/sec




in der Demo von ST läuft freeRTOS im Hintergrund und da
kann man zwei Speicherbereiche übergeben

1. Heap (1MByte vom SDRam)
2. Memory für die GUI (126 Kbyte vom internen RAM)


was jetzt ?!?

von Lutz H. (luhe)


Lesenswert?

Eine andere Möglichkeit ist das Querformatbei bei der 
Programmentwicklung zu erzeugen:

- Drehen des Bildes mit Gimp,
Speichern als Bitmap,
Umwandeln in ein C File mit BmpCvt.exe

Das erzeugte File enthält zum Beispiel:
  .
GUI_CONST_STORAGE GUI_BITMAP bm_acgitter_x240y320 = {
  240, // xSize
  320, // ySize
  480, // BytesPerLine
  16, // BitsPerPixel
  (unsigned char *)_ac_acgitter_x240y320,  // Pointer to picture data
  NULL,  // Pointer to palette
  GUI_DRAW_BMP565
};
 in COOCOX einbinden.

C file in das Projektverzeichnis kopieren


#include "_acgitter_x240y320.c

 GUI_DrawBitmap(&bm_acgitter_x240y320, 0,0);

von Holger (Gast)


Lesenswert?

Abhilfe für die explodierte Link-Time schafft eine kleine Änderung im 
Linkerscript, indem die HeapMemSection als NOLOAD deklariert wird:

.HeapMemSection (NOLOAD) :
{
*(.HeapMemSection)
} > sdram

Ohne diese Änderung  wird der als Pixelspeicher benutzte SDRAM-Speicher 
vom Linker zum Binary dazugelinkt, vom Flasher aber nicht geflasht, weil 
der SDRAM-Adressbereich nicht im Flash-Adressbereich liegt (Die 
Flashzeiten bleiben unverändert).

Tip: kommt es bei Rotate zu einem Hard Fault, ist der SDRAM nicht in der 
GUI alloziiert. Nach der SDRAM-Initialisierung und vor 
GUI_SetOrientation (Rotation) GUI_Init() ausführen, das ruft dann 
GUI_ALLOC_AssignMemory(extMem, GUI_NUMBYTES) (in GUIConf.c) auf, das den 
SDRAM zuweist.

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.