Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//
Expand Down Expand Up @@ -88,6 +88,13 @@ struct DisplayInterface
CLR_UINT32 height,
CLR_UINT32 stride,
bool doByteSwap);
void SendData18Windowed(
CLR_UINT16 *data,
CLR_UINT32 startX,
CLR_UINT32 startY,
CLR_UINT32 width,
CLR_UINT32 height,
CLR_UINT32 stride);
void FillData16(CLR_UINT16 fillValue, CLR_UINT32 fillLength);
void SetCommandMode(int mode);
};
Expand Down
26 changes: 21 additions & 5 deletions src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Copyright (c) .NET Foundation and Contributors
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
// See LICENSE file in the project root for full license information.
Expand Down Expand Up @@ -260,7 +260,16 @@ void DisplayDriver::Clear()

g_DisplayInterface.SendCommand(1, g_DisplayInterfaceConfig.GenericDriverCommands.MemoryWrite);

g_DisplayInterface.FillData16(0, Attributes.Width * Attributes.Height);
if (Attributes.BitsPerPixel <= 16)
{
// 2 bytes per pixel
g_DisplayInterface.FillData16(0, Attributes.Width * Attributes.Height);
}
else
{
// 3 bytes per pixel
g_DisplayInterface.FillData16(0, (Attributes.Width * Attributes.Height * 3 + 1) / 2);
}
}
else
{
Expand Down Expand Up @@ -289,16 +298,23 @@ void DisplayDriver::BitBlt(
int screenY,
CLR_UINT32 data[])
{
// 16 bit colour RRRRRGGGGGGBBBBB mode 565

ASSERT((screenX >= 0) && ((screenX + width) <= Attributes.Width));
ASSERT((screenY >= 0) && ((screenY + height) <= Attributes.Height));

SetWindow(screenX, screenY, (screenX + width - 1), (screenY + height - 1));

g_DisplayInterface.SendCommand(1, g_DisplayInterfaceConfig.GenericDriverCommands.MemoryWrite);

g_DisplayInterface.SendData16Windowed((CLR_UINT16 *)&data[0], srcX, srcY, width, height, stride, true);
if (Attributes.BitsPerPixel <= 16)
{
// 16-bit / two byte pixel formats. RGB mode 565
g_DisplayInterface.SendData16Windowed((CLR_UINT16 *)&data[0], srcX, srcY, width, height, stride, true);
}
else
{
// 18-bit / three byte pixel formats. RGB mode 666
g_DisplayInterface.SendData18Windowed((CLR_UINT16 *)&data[0], srcX, srcY, width, height, stride);
}

return;
}
Expand Down
61 changes: 60 additions & 1 deletion src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// Copyright (c) .NET Foundation and Contributors
// See LICENSE file in the project root for full license information.
//
Expand Down Expand Up @@ -307,6 +307,65 @@ void DisplayInterface::SendData16Windowed(
return;
}

void DisplayInterface::SendData18Windowed(
CLR_UINT16 *data,
CLR_UINT32 startX,
CLR_UINT32 startY,
CLR_UINT32 width,
CLR_UINT32 height,
CLR_UINT32 stride)
{
// Offset for window start
CLR_UINT16 *startOfLine = data + (startY * stride) + startX;

CLR_UINT8 *byteBuffer = (CLR_UINT8 *)currentBuffer;
CLR_UINT32 bytesWritten = 0;

while (height--)
{
CLR_UINT16 *pixel = startOfLine;

for (CLR_UINT32 x = 0; x < width; x++)
{
CLR_UINT16 color = *pixel++;

// Extract RGB565 components and bit-widen to 8-bit
CLR_UINT8 b = color & 0x1F;
CLR_UINT8 g = (color >> 5) & 0x3F;
CLR_UINT8 r = (color >> 11) & 0x1F;

b = (b << 3) | (b >> 2);
g = (g << 2) | (g >> 4);
r = (r << 3) | (r >> 2);

// Ensure there is room for a full pixel
if (bytesWritten + 3 > SPI_MAX_TRANSFER_SIZE)
{
InternalSendBytes((CLR_UINT8 *)currentBuffer, bytesWritten, true);
SwapBuffers();
byteBuffer = (CLR_UINT8 *)currentBuffer;
bytesWritten = 0;
}

byteBuffer[bytesWritten++] = b;
byteBuffer[bytesWritten++] = g;
byteBuffer[bytesWritten++] = r;
}

startOfLine += stride;
}

// Flush remaining bytes
if (bytesWritten > 0)
{
InternalSendBytes((CLR_UINT8 *)currentBuffer, bytesWritten, true);

SwapBuffers();
}

return;
}

void DisplayInterface::FillData16(CLR_UINT16 fillValue, CLR_UINT32 fillLength)
{
// Fill the current buffer full of fillValue, or as much as we need
Expand Down