From e7afe9b562b8df3e0733238aff4895fa9892579a Mon Sep 17 00:00:00 2001 From: Mikael Mogren Date: Thu, 20 Mar 2025 19:05:44 +0000 Subject: [PATCH 1/2] Invert colors and partial flush for ILI9488 display --- .../Graphics/Displays/ILI9488_480x320_SPI.cpp | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp index c1a93634d0..65710cb30c 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp @@ -87,7 +87,7 @@ enum ILI9488_Orientation : CLR_UINT8 MADCTL_MX = 0x40, // sets the Column Order, 0=Left-Right and 1=Right-Left MADCTL_MY = 0x80, // sets the Row Order, 0=Top-Bottom and 1=Bottom-Top - MADCTL_BGR = 0x08, // Blue-Green-Red pixel order + MADCTL_BGR = 0x00, // Red-Green-Blue pixel order }; bool DisplayDriver::Initialize() @@ -140,7 +140,7 @@ bool DisplayDriver::Initialize() g_DisplayInterface.SendCommand(2, Interface_Signal_Control, 0x80); g_DisplayInterface.SendCommand(2, Frame_Rate_Control_Normal, 0xA0); g_DisplayInterface.SendCommand(2, Inversion_Control, 0x02); - g_DisplayInterface.SendCommand(3, Display_Function_Control, 0x02, 0x02, 0x3B); + g_DisplayInterface.SendCommand(4, Display_Function_Control, 0x02, 0x02, 0x3B); g_DisplayInterface.SendCommand(2, Set_Image_Function, 0x00); g_DisplayInterface.SendCommand(5, Pump_Ratio_Control, 0xA9, 0x51, 0x2C, 0x82); g_DisplayInterface.SendCommand(1, Sleep_Out); @@ -288,36 +288,39 @@ void DisplayDriver::BitBlt( SetWindow(screenX, screenY, (screenX + width - 1), (screenY + height - 1)); g_DisplayInterface.SendCommand(1, Memory_Write); - - uint32_t numPixels = width * height; + uint32_t count = 0; CLR_UINT8 *TransferBuffer = Attributes.TransferBuffer; CLR_UINT32 TransferBufferSize = Attributes.TransferBufferSize; // only 18/24 bit is supported on SPI - for (uint32_t i = 0; i < numPixels; i++) + for (uint32_t y = srcY; y < srcY + height; y++) { - uint32_t element = data[i / 2]; // Each uint32 stores 2 pixels - uint16_t color = (i % 2 == 0) ? (element & 0xFFFF) : (element >> 16); - - uint8_t b = color & 0x1F; - uint8_t g = (color >> 5) & 0x3F; - uint8_t r = (color >> 11) & 0x1F; - - b = (b << 3) | (b >> 2); - g = (g << 2) | (g >> 4); - r = (r << 3) | (r >> 2); - - TransferBuffer[count++] = b; - TransferBuffer[count++] = g; - TransferBuffer[count++] = r; - - // can't fit another 3 bytes - if (count + 3 > TransferBufferSize - 1) + for (uint32_t x = srcX; x < srcX + width; x++) { - g_DisplayInterface.SendBytes(TransferBuffer, count); - count = 0; + uint32_t i = y * Attributes.Width + x; + uint32_t element = data[i / 2]; // Each uint32 stores 2 pixels + uint16_t color = (i % 2 == 0) ? (element & 0xFFFF) : (element >> 16); + + uint8_t b = color & 0x1F; + uint8_t g = (color >> 5) & 0x3F; + uint8_t r = (color >> 11) & 0x1F; + + b = (b << 3) | (b >> 2); + g = (g << 2) | (g >> 4); + r = (r << 3) | (r >> 2); + + TransferBuffer[count++] = b; + TransferBuffer[count++] = g; + TransferBuffer[count++] = r; + + // can't fit another 3 bytes + if (count + 3 > TransferBufferSize - 1) + { + g_DisplayInterface.SendBytes(TransferBuffer, count); + count = 0; + } } } g_DisplayInterface.SendBytes(TransferBuffer, count); From 40118bdad97bff875331741a05ae75fe2f73792b Mon Sep 17 00:00:00 2001 From: Mikael Mogren Date: Thu, 20 Mar 2025 19:33:52 +0000 Subject: [PATCH 2/2] Invert colors and partial flush for ILI9488 display --- .../Graphics/Displays/ILI9488_480x320_SPI.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp b/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp index 65710cb30c..da058b718b 100644 --- a/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp +++ b/src/nanoFramework.Graphics/Graphics/Displays/ILI9488_480x320_SPI.cpp @@ -87,7 +87,7 @@ enum ILI9488_Orientation : CLR_UINT8 MADCTL_MX = 0x40, // sets the Column Order, 0=Left-Right and 1=Right-Left MADCTL_MY = 0x80, // sets the Row Order, 0=Top-Bottom and 1=Bottom-Top - MADCTL_BGR = 0x00, // Red-Green-Blue pixel order + MADCTL_RGB = 0x00, // Red-Green-Blue pixel order }; bool DisplayDriver::Initialize() @@ -172,19 +172,19 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) Attributes.Height = Attributes.LongerSide; Attributes.Width = Attributes.ShorterSide; g_DisplayInterface.SendCommand(2, Memory_Access_Control, - (MADCTL_MX | MADCTL_BGR)); // Portrait + BGR + (MADCTL_MX | MADCTL_RGB)); // Portrait break; case DisplayOrientation::DisplayOrientation_Portrait180: Attributes.Height = Attributes.LongerSide; Attributes.Width = Attributes.ShorterSide; g_DisplayInterface.SendCommand(2, Memory_Access_Control, - (MADCTL_MY | MADCTL_BGR)); // Portrait 180 + BGR + (MADCTL_MY | MADCTL_RGB)); // Portrait 180 break; case DisplayOrientation::DisplayOrientation_Landscape: Attributes.Height = Attributes.ShorterSide; Attributes.Width = Attributes.LongerSide; g_DisplayInterface.SendCommand(2, Memory_Access_Control, - (MADCTL_MV | MADCTL_BGR)); // Landscape + BGR + (MADCTL_MV | MADCTL_RGB)); // Landscape break; case DisplayOrientation::DisplayOrientation_Landscape180: Attributes.Height = Attributes.ShorterSide; @@ -192,7 +192,7 @@ bool DisplayDriver::ChangeOrientation(DisplayOrientation orientation) g_DisplayInterface.SendCommand( 2, Memory_Access_Control, - (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR)); // Landscape 180 + BGR + (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_RGB)); // Landscape 180 break; } return true;