Browse Source

add color swap BGR/RGB and generalize invert option

philippe44 3 years ago
parent
commit
dd519b9229

+ 15 - 9
components/display/ILI9341.c

@@ -191,49 +191,54 @@ static void Update24( struct GDS_Device* Device ) {
 #endif	
 }
 
-static void SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) { 
+static void SetLayout( struct GDS_Device* Device, struct GDS_Layout *Layout ) { 
 	struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
-	ESP_LOGI(TAG, "SetLayout 197 HFlip=%d VFlip=%d Rotate=%d (1=true)", HFlip, VFlip, Rotate);
+	ESP_LOGI(TAG, "SetLayout 197 HFlip=%d VFlip=%d Rotate=%d (1=true)", Layout->HFlip, Layout->VFlip, Layout->Rotate);
 	//        D/CX RDX WRX D17-8 D7 D6 D5 D4 D3  D2 D1 D0 HEX
 	//Command   0   1   ↑    XX  0  0  1  1  0   1  1  0  36h
 	//Parameter 1   1   ↑    XX  MY MX MV ML BGR MH 0  0  00
 	//Orientation 0: MADCtl = 0x80  =   1000 0000 (MY=1)
 	if ((Device->Height)>(Device->Width)){		//Resolution = 320x240
 		Private->MADCtl = (1 << 7);				// 0x80 = default (no Rotation an no Flip)
-		if (HFlip) {							//Flip Horizontal
+		if (Layout->HFlip) {							//Flip Horizontal
 			int a = Private->MADCtl;
 			Private->MADCtl = (a ^ (1 << 7));
 		}
-		if (Rotate) {							//Rotate 180 degr.
+		if (Layout->Rotate) {							//Rotate 180 degr.
 			int a = Private->MADCtl;
 			a = (a ^ (1 << 7));
 			Private->MADCtl = (a ^ (1 << 6));
 		}
-		if (VFlip) {							//Flip Vertical
+		if (Layout->VFlip) {							//Flip Vertical
 			int a = Private->MADCtl;
 			Private->MADCtl = (a ^ (1 << 6));
 		}
 	} else {									//Resolution = 240x320
 		Private->MADCtl = (1 << 5);				// 0x20 = default (no Rotation an no Flip)
-		if (HFlip) {							//Flip Horizontal
+		if (Layout->HFlip) {							//Flip Horizontal
 			int a = Private->MADCtl;
 			Private->MADCtl = (a ^ (1 << 6));
 		}
-		if (Rotate) {							//Rotate 180 degr.
+		if (Layout->Rotate) {							//Rotate 180 degr.
 			int a = Private->MADCtl;
 			a = (a ^ (1 << 7));
 			Private->MADCtl = (a ^ (1 << 6));
 		}
-		if (VFlip) {							//Flip Vertical
+		if (Layout->VFlip) {							//Flip Vertical
 			int a = Private->MADCtl;
 			Private->MADCtl = (a ^ (1 << 7));
 		}
 	}
+	
+	Private->MADCtl = Layout->ColorSwap ? (Private->MADCtl | (1 << 3)) : (Private->MADCtl & ~(1 << 3));
 
 	ESP_LOGI(TAG, "SetLayout 255 Private->MADCtl=%hhu", Private->MADCtl);
 
 	Device->WriteCommand( Device, 0x36 );
 	WriteByte( Device, Private->MADCtl );
+	
+	Device->WriteCommand( Device, Layout->Invert ? 0x21 : 0x20 );
+	
 
 #ifdef SHADOW_BUFFER
 	// force a full refresh (almost ...)
@@ -274,7 +279,8 @@ static bool Init( struct GDS_Device* Device ) {
 			
 	// set flip modes & contrast
 	GDS_SetContrast( Device, 0x7f );
-	Device->SetLayout( Device, false, false, false );
+	struct GDS_Layout Layout = { };
+	Device->SetLayout( Device, &Layout );
 	
 	// set screen depth (16/18) *** INTERFACE PIXEL FORMAT: 0x66=18 bit; 0x55=16 bit
 	Device->WriteCommand( Device, 0x3A );

+ 6 - 4
components/display/SH1106.c

@@ -73,9 +73,10 @@ static void Update( struct GDS_Device* Device ) {
 #endif	
 }
 
-static void SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) {
-	Device->WriteCommand( Device, HFlip ? 0xA1 : 0xA0 );
-	Device->WriteCommand( Device, VFlip ? 0xC8 : 0xC0 );
+static void SetLayout( struct GDS_Device* Device, struct GDS_Layout *Layout ) { 
+	Device->WriteCommand( Device, Layout->HFlip ? 0xA1 : 0xA0 );
+	Device->WriteCommand( Device, Layout->VFlip ? 0xC8 : 0xC0 );
+    Device->WriteCommand( Device, Layout->Invert ? 0xA7 : 0xA6 );
 }	
 
 static void DisplayOn( struct GDS_Device* Device ) { Device->WriteCommand( Device, 0xAF ); }
@@ -124,7 +125,8 @@ static bool Init( struct GDS_Device* Device ) {
     Device->WriteCommand( Device, 0x40 + 0x00 );
 	Device->SetContrast( Device, 0x7F );
 	// set flip modes
-	Device->SetLayout( Device, false, false, false );
+	struct GDS_Layout Layout = { };
+	Device->SetLayout( Device, &Layout );
 	// no Display Inversion
     Device->WriteCommand( Device, 0xA6 );
 	// set Clocks

+ 6 - 4
components/display/SSD1306.c

@@ -85,9 +85,10 @@ static void Update( struct GDS_Device* Device ) {
 #endif	
 }
 
-static void SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) { 
-	Device->WriteCommand( Device, HFlip ? 0xA1 : 0xA0 );
-	Device->WriteCommand( Device, VFlip ? 0xC8 : 0xC0 );
+static void SetLayout( struct GDS_Device* Device, struct GDS_Layout *Layout ) { 
+	Device->WriteCommand( Device, Layout->HFlip ? 0xA1 : 0xA0 );
+	Device->WriteCommand( Device, Layout->VFlip ? 0xC8 : 0xC0 );
+	Device->WriteCommand( Device, Layout->Invert ? 0xA7 : 0xA6 );
 }
 	
 static void DisplayOn( struct GDS_Device* Device ) { Device->WriteCommand( Device, 0xAF ); }
@@ -132,7 +133,8 @@ static bool Init( struct GDS_Device* Device ) {
     Device->WriteCommand( Device, 0x40 + 0x00 );
 	Device->SetContrast( Device, 0x7F );
 	// set flip modes
-	Device->SetLayout( Device, false, false, false);
+	struct GDS_Layout Layout = { };
+	Device->SetLayout( Device, &Layout );
 	// no Display Inversion
     Device->WriteCommand( Device, 0xA6 );
 	// set Clocks

+ 6 - 4
components/display/SSD1322.c

@@ -96,13 +96,14 @@ static void Update( struct GDS_Device* Device ) {
 #endif	
 }
 
-static void SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) { 
+static void SetLayout( struct GDS_Device* Device, struct GDS_Layout *Layout ) { 
 	struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
-	Private->ReMap = HFlip ? (Private->ReMap & ~(1 << 1)) : (Private->ReMap | (1 << 1));
-	Private->ReMap = VFlip ? (Private->ReMap | (1 << 4)) : (Private->ReMap & ~(1 << 4));
+	Private->ReMap = Layout->HFlip ? (Private->ReMap & ~(1 << 1)) : (Private->ReMap | (1 << 1));
+	Private->ReMap = Layout->VFlip ? (Private->ReMap | (1 << 4)) : (Private->ReMap & ~(1 << 4));
 	Device->WriteCommand( Device, 0xA0 );
 	Device->WriteData( Device, &Private->ReMap, 1 );
 	WriteDataByte( Device, 0x11 );		
+	Device->WriteCommand( Device, Layout->Invert ? 0xA7 : 0xA6 );
 }	
 
 static void DisplayOn( struct GDS_Device* Device ) { Device->WriteCommand( Device, 0xAF ); }
@@ -145,7 +146,8 @@ static bool Init( struct GDS_Device* Device ) {
 	
 	// set flip modes
 	Private->ReMap = 0;
-	Device->SetLayout( Device, false, false, false);
+	struct GDS_Layout Layout = { };
+	Device->SetLayout( Device, &Layout );
 	
 	// set Display Enhancement
     Device->WriteCommand( Device, 0xB4 );

+ 8 - 6
components/display/SSD132x.c

@@ -222,17 +222,18 @@ static void DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, i
 	}
 }
 
-static void SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) { 
+static void SetLayout( struct GDS_Device* Device, struct GDS_Layout *Layout ) { 
 	struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
 	if (Private->Model == SSD1326) {
-		Private->ReMap = HFlip ? (Private->ReMap | ((1 << 0) | (1 << 2))) : (Private->ReMap & ~((1 << 0) | (1 << 2)));
-		Private->ReMap = HFlip ? (Private->ReMap | (1 << 1)) : (Private->ReMap & ~(1 << 1));		
+		Private->ReMap = Layout->HFlip ? (Private->ReMap | ((1 << 0) | (1 << 2))) : (Private->ReMap & ~((1 << 0) | (1 << 2)));
+		Private->ReMap = Layout->HFlip ? (Private->ReMap | (1 << 1)) : (Private->ReMap & ~(1 << 1));		
 	} else {
-		Private->ReMap = VFlip ? (Private->ReMap | ((1 << 0) | (1 << 1))) : (Private->ReMap & ~((1 << 0) | (1 << 1)));
-		Private->ReMap = VFlip ? (Private->ReMap | (1 << 4)) : (Private->ReMap & ~(1 << 4));
+		Private->ReMap = Layout->VFlip ? (Private->ReMap | ((1 << 0) | (1 << 1))) : (Private->ReMap & ~((1 << 0) | (1 << 1)));
+		Private->ReMap = Layout->VFlip ? (Private->ReMap | (1 << 4)) : (Private->ReMap & ~(1 << 4));
 	}	
 	Device->WriteCommand( Device, 0xA0 );
 	Device->WriteCommand( Device, Private->ReMap );
+    Device->WriteCommand( Device, Layout->Invert ? 0xA7 : 0xA6 );	
 }	
 
 static void DisplayOn( struct GDS_Device* Device ) { Device->WriteCommand( Device, 0xAF ); }
@@ -288,7 +289,8 @@ static bool Init( struct GDS_Device* Device ) {
 	Device->WriteCommand( Device, 0x00 );
 	Device->SetContrast( Device, 0x7F );
 	// set flip modes
-	Device->SetLayout( Device, false, false, false );
+	struct GDS_Layout Layout = { };
+	Device->SetLayout( Device, &Layout );
 	// no Display Inversion
     Device->WriteCommand( Device, 0xA6 );
 	// set Clocks

+ 6 - 4
components/display/SSD1351.c

@@ -181,12 +181,13 @@ static void Update24( struct GDS_Device* Device ) {
 #endif	
 }
 
-static void SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) { 
+static void SetLayout( struct GDS_Device* Device, struct GDS_Layout *Layout ) { 
 	struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
-	Private->ReMap = HFlip ? (Private->ReMap & ~(1 << 1)) : (Private->ReMap | (1 << 1));
-	Private->ReMap = VFlip ? (Private->ReMap | (1 << 4)) : (Private->ReMap & ~(1 << 4));
+	Private->ReMap = Layout->HFlip ? (Private->ReMap & ~(1 << 1)) : (Private->ReMap | (1 << 1));
+	Private->ReMap = Layout->VFlip ? (Private->ReMap | (1 << 4)) : (Private->ReMap & ~(1 << 4));
 	Device->WriteCommand( Device, 0xA0 );
 	WriteByte( Device, Private->ReMap );
+    Device->WriteCommand( Device, Layout->Invert ? 0xA7 : 0xA6 );	
 }	
 
 static void DisplayOn( struct GDS_Device* Device ) { Device->WriteCommand( Device, 0xAF ); }
@@ -239,7 +240,8 @@ static bool Init( struct GDS_Device* Device ) {
 	
 	// set flip modes & contrast
 	Device->SetContrast( Device, 0x7F );
-	Device->SetLayout( Device, false, false, false );
+	struct GDS_Layout Layout = { };
+	Device->SetLayout( Device, &Layout );
 	
 	// set Adressing Mode Horizontal
 	Private->ReMap |= (0 << 2);

+ 19 - 18
components/display/ST77xx.c

@@ -34,7 +34,6 @@ struct PrivateSpace {
 	} Offset;
 	uint8_t MADCtl, PageSize;
 	uint8_t Model;
-	bool Invert;
 };
 
 // Functions are not declared to minimize # of lines
@@ -189,20 +188,25 @@ static void Update24( struct GDS_Device* Device ) {
 #endif	
 }
 
-static void SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) { 
+static void SetLayout( struct GDS_Device* Device, struct GDS_Layout *Layout ) { 
 	struct PrivateSpace *Private = (struct PrivateSpace*) Device->Private;
 	
-	Private->MADCtl = HFlip ? (Private->MADCtl | (1 << 7)) : (Private->MADCtl & ~(1 << 7));
-	Private->MADCtl = VFlip ? (Private->MADCtl | (1 << 6)) : (Private->MADCtl & ~(1 << 6));
-	Private->MADCtl = Rotate ? (Private->MADCtl | (1 << 5)) : (Private->MADCtl & ~(1 << 5));
-	
+	if (Private->Model == ST7789) {
+		if (Layout->Rotate) Private->Offset.Width += Layout->HFlip ? 320 - Device->Width : 0;
+		else Private->Offset.Height += Layout->HFlip ? 320 - Device->Height : 0;
+		Device->WriteCommand( Device, Layout->Invert ? 0x20 : 0x21 );			
+		Private->MADCtl = Layout->ColorSwap ? (Private->MADCtl & ~(1 << 3)) : (Private->MADCtl | (1 << 3));
+	} else {
+		Device->WriteCommand( Device, Layout->Invert ? 0x21 : 0x20 );	
+		Private->MADCtl = Layout->ColorSwap ? (Private->MADCtl | (1 << 3)) : (Private->MADCtl & ~(1 << 3));		
+	}		
+
+	Private->MADCtl = Layout->HFlip ? (Private->MADCtl | (1 << 7)) : (Private->MADCtl & ~(1 << 7));
+	Private->MADCtl = Layout->VFlip ? (Private->MADCtl | (1 << 6)) : (Private->MADCtl & ~(1 << 6));
+	Private->MADCtl = Layout->Rotate ? (Private->MADCtl | (1 << 5)) : (Private->MADCtl & ~(1 << 5));
+
 	Device->WriteCommand( Device, 0x36 );
 	WriteByte( Device, Private->MADCtl );
-	
-	if (Private->Model == ST7789) {
-		if (Rotate) Private->Offset.Width += HFlip ? 320 - Device->Width : 0;
-		else Private->Offset.Height += HFlip ? 320 - Device->Height : 0;
-	}
 
 #ifdef SHADOW_BUFFER
 	// force a full refresh (almost ...)
@@ -240,24 +244,22 @@ static bool Init( struct GDS_Device* Device ) {
 	
 	// Sleepout + Booster
 	Device->WriteCommand( Device, 0x11 );
-		
+	
 	// need BGR & Address Mode
 	Private->MADCtl = 1 << 3;
 	Device->WriteCommand( Device, 0x36 );
 	WriteByte( Device, Private->MADCtl );		
-		
+	
 	// set flip modes & contrast
 	GDS_SetContrast( Device, 0x7f );
-	Device->SetLayout( Device, false, false, false );
+	struct GDS_Layout Layout = { };
+	Device->SetLayout( Device, &Layout );
 	
 	// set screen depth (16/18)
 	Device->WriteCommand( Device, 0x3A );
 	if (Private->Model == ST7789) WriteByte( Device, Device->Depth == 24 ? 0x066 : 0x55 );
 	else WriteByte( Device, Device->Depth == 24 ? 0x06 : 0x05 );
 	
-	// no Display Inversion
-	Device->WriteCommand( Device, Private->Invert ? 0x21 : 0x20 );	
-		
 	// gone with the wind
 	Device->DisplayOn( Device );
 	Device->Update( Device );
@@ -299,7 +301,6 @@ struct GDS_Device* ST77xx_Detect(char *Driver, struct GDS_Device* Device) {
 		Device->Update = Update24;
 	} 	
 	
-	if (Model == ST7789 || strcasestr(Driver, "invert")) Private->Invert = true;
 	if (Model == ST7789) Device->SetContrast = SetContrast;
 
 	return Device;

+ 1 - 1
components/display/core/gds.c

@@ -236,7 +236,7 @@ void GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast ) {
 	}
 }
 
-void GDS_SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate ) { if (Device->SetLayout) Device->SetLayout( Device, HFlip, VFlip, Rotate ); }
+void GDS_SetLayout( struct GDS_Device* Device, struct GDS_Layout *Layout ) { if (Device->SetLayout) Device->SetLayout( Device, Layout ); }
 void GDS_SetDirty( struct GDS_Device* Device ) { Device->Dirty = true; }
 int	 GDS_GetWidth( struct GDS_Device* Device ) { return Device ? Device->Width : 0; }
 void GDS_SetTextWidth( struct GDS_Device* Device, int TextWidth ) { Device->TextWidth = Device && TextWidth && TextWidth < Device->Width ? TextWidth : Device->Width; }

+ 7 - 1
components/display/core/gds.h

@@ -26,6 +26,12 @@ struct GDS_BacklightPWM {
 	int Channel, Timer, Max;
 	bool Init;
 };
+struct GDS_Layout {
+	bool HFlip, VFlip;
+	bool Rotate;
+	bool Invert; 
+	bool ColorSwap;
+};
 
 typedef struct GDS_Device* GDS_DetectFunc(char *Driver, struct GDS_Device *Device);
 
@@ -35,7 +41,7 @@ void 	GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast );
 void 	GDS_DisplayOn( struct GDS_Device* Device );
 void 	GDS_DisplayOff( struct GDS_Device* Device ); 
 void 	GDS_Update( struct GDS_Device* Device );
-void 	GDS_SetLayout( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate );
+void 	GDS_SetLayout( struct GDS_Device* Device, struct GDS_Layout* Layout);
 void 	GDS_SetDirty( struct GDS_Device* Device );
 int 	GDS_GetWidth( struct GDS_Device* Device );
 void 	GDS_SetTextWidth( struct GDS_Device* Device, int TextWidth );

+ 1 - 1
components/display/core/gds_private.h

@@ -117,7 +117,7 @@ struct GDS_Device {
 	void (*SetContrast)( struct GDS_Device* Device, uint8_t Contrast );
 	void (*DisplayOn)( struct GDS_Device* Device );
 	void (*DisplayOff)( struct GDS_Device* Device );
-	void (*SetLayout)( struct GDS_Device* Device, bool HFlip, bool VFlip, bool Rotate );
+	void (*SetLayout)( struct GDS_Device* Device, struct GDS_Layout *Layout );
 	// must provide for depth other than 1 (vertical) and 4 (may provide for optimization)
 	void (*DrawPixelFast)( struct GDS_Device* Device, int X, int Y, int Color );
 	void (*DrawBitmapCBR)(struct GDS_Device* Device, uint8_t *Data, int Width, int Height, int Color );

+ 9 - 2
components/display/display.c

@@ -141,8 +141,15 @@ void display_init(char *welcome) {
 	if (init) {
 		static DRAM_ATTR StaticTask_t xTaskBuffer __attribute__ ((aligned (4)));
 		static EXT_RAM_ATTR StackType_t xStack[DISPLAYER_STACK_SIZE] __attribute__ ((aligned (4)));
-		
-		GDS_SetLayout(display, strcasestr(config, "HFlip"), strcasestr(config, "VFlip"), strcasestr(config, "rotate"));
+		struct GDS_Layout Layout = {
+			.HFlip = strcasestr(config, "HFlip"), 
+			.VFlip = strcasestr(config, "VFlip"), 
+			.Rotate = strcasestr(config, "rotate"), 
+			.Invert = strcasestr(config, "invert"),
+			.ColorSwap = strcasestr(config, "cswap"),
+		};	
+					
+		GDS_SetLayout(display, &Layout);
 		GDS_SetFont(display, &Font_line_2);
 		GDS_TextPos(display, GDS_FONT_DEFAULT, GDS_TEXT_CENTERED, GDS_TEXT_CLEAR | GDS_TEXT_UPDATE, welcome);
 

+ 2 - 0
components/services/accessors.c

@@ -464,6 +464,7 @@ const display_config_t * config_display_get(){
 		.speed = 0,
 		.rotate = false,
 		.invert = false,
+		.colorswap = 0,
 	};
 	char *config = config_alloc_get(NVS_TYPE_STR, "display_config");
 	if (!config) {
@@ -491,6 +492,7 @@ const display_config_t * config_display_get(){
 	dstruct.vflip= strcasestr(config, "VFlip") ? true : false;
 	dstruct.rotate= strcasestr(config, "rotate") ? true : false;
 	dstruct.invert= strcasestr(config, "invert") ? true : false;
+	dstruct.colorswap= strcasestr(config, "cswap") ? 1 : 0;
 	return &dstruct;
 }
 

+ 1 - 0
components/services/accessors.h

@@ -32,6 +32,7 @@ typedef struct {
 	const char *type;
 	bool rotate;
 	bool invert;
+	int colorswap;
 } display_config_t;
 
 typedef struct eth_config_struct {