diff --git a/components/display/ILI9341.c b/components/display/ILI9341.c index 41755c49..f643d31f 100644 --- a/components/display/ILI9341.c +++ b/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 ); diff --git a/components/display/SH1106.c b/components/display/SH1106.c index 11e69707..136b53d3 100644 --- a/components/display/SH1106.c +++ b/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 diff --git a/components/display/SSD1306.c b/components/display/SSD1306.c index eb85e6f3..036f787d 100644 --- a/components/display/SSD1306.c +++ b/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 diff --git a/components/display/SSD1322.c b/components/display/SSD1322.c index ee6c0b37..73929d68 100644 --- a/components/display/SSD1322.c +++ b/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 ); diff --git a/components/display/SSD132x.c b/components/display/SSD132x.c index 12749177..57cd87fb 100644 --- a/components/display/SSD132x.c +++ b/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 diff --git a/components/display/SSD1351.c b/components/display/SSD1351.c index a7f0440d..c8e4b6ec 100644 --- a/components/display/SSD1351.c +++ b/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); diff --git a/components/display/ST77xx.c b/components/display/ST77xx.c index 1bf5d3fe..2370aae7 100644 --- a/components/display/ST77xx.c +++ b/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; diff --git a/components/display/core/gds.c b/components/display/core/gds.c index fc1d8d3d..910f874f 100644 --- a/components/display/core/gds.c +++ b/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; } diff --git a/components/display/core/gds.h b/components/display/core/gds.h index fa782329..f0abb5ab 100644 --- a/components/display/core/gds.h +++ b/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 ); diff --git a/components/display/core/gds_private.h b/components/display/core/gds_private.h index 17203083..c25dd4d9 100644 --- a/components/display/core/gds_private.h +++ b/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 ); diff --git a/components/display/display.c b/components/display/display.c index 94414dac..dc90e709 100644 --- a/components/display/display.c +++ b/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); diff --git a/components/services/accessors.c b/components/services/accessors.c index 68a324e1..8bc4b18d 100644 --- a/components/services/accessors.c +++ b/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; } diff --git a/components/services/accessors.h b/components/services/accessors.h index ac8cd745..d7c9c640 100644 --- a/components/services/accessors.h +++ b/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 {