Skip to content

Add support for 18 bit SPI graphics (ILI9488)#3288

Open
mikmog wants to merge 5 commits intonanoframework:mainfrom
mikmog:add-18-bit-spi-graphics
Open

Add support for 18 bit SPI graphics (ILI9488)#3288
mikmog wants to merge 5 commits intonanoframework:mainfrom
mikmog:add-18-bit-spi-graphics

Conversation

@mikmog
Copy link
Copy Markdown
Contributor

@mikmog mikmog commented Apr 6, 2026

Description

Add support for the Ili9488 display.

Motivation and Context

Inspired by PR #2976

Second attempt at adding 18-bit support for the Ili9488 display.
Managed driver in separate PR if applicable.

How Has This Been Tested?

On an ESP32_S3 Feather and a Ili9488 RGB display.
Performance wise it's ok and colors renders as expected.

Screenshots

Types of changes

  • Improvement (non-breaking change that improves a feature, code or algorithm)
  • Bug fix (non-breaking change which fixes an issue with code or algorithm)
  • New feature (non-breaking change which adds functionality to code)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Config and build (change in the configuration and build system, has no impact on code or features)
  • Dev Containers (changes related with Dev Containers, has no impact on code or features)
  • Dependencies/declarations (update dependencies or assembly declarations and changes associated, has no impact on code or features)
  • Documentation (changes or updates in the documentation, has no impact on code or features)

Checklist

  • My code follows the code style of this project (only if there are changes in source code).
  • My changes require an update to the documentation (there are changes that require the docs website to be updated).
  • I have updated the documentation accordingly (the changes require an update on the docs in this repo).
  • I have read the CONTRIBUTING document.
  • I have tested everything locally and all new and existing tests passed (only if there are changes in source code).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 6, 2026

Warning

Rate limit exceeded

@mikmog has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 58 minutes and 27 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 58 minutes and 27 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5c1285ec-29f9-4e12-92f9-5a4573ec016b

📥 Commits

Reviewing files that changed from the base of the PR and between 3f31723 and fa5f43f.

📒 Files selected for processing (2)
  • src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp
  • src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp
📝 Walkthrough

Walkthrough

Added support for windowed 18-bit transfers by introducing SendData18Windowed and routing display transfers based on Attributes.BitsPerPixel; 18-bit path performs RGB565→24-bit (RGB888/RGB666) expansion and buffered SPI transfers with flush/swapping logic.

Changes

Cohort / File(s) Summary
Header Declaration
src/nanoFramework.Graphics/Graphics/Displays/DisplayInterface.h
Added declaration void SendData18Windowed(CLR_UINT16 *data, CLR_UINT32 startX, CLR_UINT32 startY, CLR_UINT32 width, CLR_UINT32 height, CLR_UINT32 stride);.
Driver Routing Logic
src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp
Clear() now computes fill size based on Attributes.BitsPerPixel (uses *3/2 for >16 bpp). BitBlt() now selects SendData16Windowed or SendData18Windowed depending on Attributes.BitsPerPixel.
18-bit Implementation
src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp
Implemented SendData18Windowed: iterates window rows/cols, extracts RGB565 components, widens to 8-bit channel bytes, writes 3 bytes per pixel into SPI buffer, and flushes/swap-buffers when nearing SPI_MAX_TRANSFER_SIZE, then final flush/swap.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Driver as DisplayDriver
    participant Interface as DisplayInterface
    participant SPI as SPI Buffer/Hardware

    App->>Driver: BitBlt(data, startX, startY, width, height)
    Driver->>Driver: if Attributes.BitsPerPixel > 16
    alt >16 bpp
        Driver->>Interface: SendData18Windowed(data, startX, startY, width, height, stride)
        Interface->>Interface: for each row:
        Interface->>Interface:  calculate startOfLine = data + row*stride + startX
        loop per-pixel
            Interface->>Interface: extract R/G/B from RGB565 and expand to 8-bit bytes
            Interface->>SPI: append 3 bytes (B,G,R) to currentBuffer
            alt buffer would exceed SPI_MAX_TRANSFER_SIZE
                Interface->>SPI: InternalSendBytes(currentBuffer, async=true)
                Interface->>SPI: SwapBuffers()
            end
        end
        Interface->>SPI: flush remaining bytes
        Interface->>SPI: SwapBuffers()
    else <=16 bpp
        Driver->>Interface: SendData16Windowed(..., doByteSwap)
    end
    Interface-->>Driver: Transfer complete
    Driver-->>App: BitBlt finished
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add support for 18 bit SPI graphics (ILI9488)' is concise, descriptive, clearly summarizes the main change, follows the under-50-character guideline at 45 characters, and contains no full stop or external references.
Description check ✅ Passed The pull request description is directly related to the changeset, describing the addition of 18-bit SPI graphics support for the ILI9488 display with testing details and context about prior work.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mikmog mikmog force-pushed the add-18-bit-spi-graphics branch from 6e8800a to 0335505 Compare April 6, 2026 13:41
@mikmog
Copy link
Copy Markdown
Contributor Author

mikmog commented Apr 6, 2026

@Ellerbach Can you take a look when time suits?

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp`:
- Around line 268-271: The code uses DisplayInterface::FillData16(0,
Attributes.Width * Attributes.Height * 3 / 2) which truncates for odd pixel
counts and loses the final RGB666 byte; switch this branch to a byte-oriented
clear path (call the byte-based method such as FillData8 or the DisplayInterface
byte-fill routine) and send Attributes.Width * Attributes.Height * 3 bytes so
the full 3 bytes per pixel are transmitted for RGB666 panels; update the branch
in Generic_SPI.cpp (the 3-bytes-per-pixel branch) to use the byte-fill API
instead of FillData16.

In `@src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp`:
- Around line 341-352: The code currently appends three bytes (b,g,r) into
byteBuffer then checks capacity, which can overflow when bytesWritten is near
SPI_MAX_TRANSFER_SIZE; update the logic in the method using
byteBuffer/bytesWritten (the pixel write loop) to check if bytesWritten + 3 >
SPI_MAX_TRANSFER_SIZE and call InternalSendBytes((CLR_UINT8*)currentBuffer,
bytesWritten, true) followed by SwapBuffers() and resetting byteBuffer and
bytesWritten before writing the next pixel bytes, so the staging buffer is
flushed preemptively rather than after the three-byte write.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: f550caf5-1d32-4448-bd9e-ad994aa1a70d

📥 Commits

Reviewing files that changed from the base of the PR and between be1bb6f and 6e8800a.

📒 Files selected for processing (3)
  • src/nanoFramework.Graphics/Graphics/Displays/DisplayInterface.h
  • src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp
  • src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp

Comment thread src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp Outdated
Comment thread src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp Outdated
@josesimoes josesimoes added the Area: Common libs Everything related with common libraries label Apr 6, 2026
@alberk8
Copy link
Copy Markdown
Contributor

alberk8 commented Apr 7, 2026

@mikmog, you still need the managed nuget library for this Generic SPI for ILI9488 to work.

@mikmog
Copy link
Copy Markdown
Contributor Author

mikmog commented Apr 7, 2026

Yeah. The plan was if there is any hope for this PR moving forward I'll also add the PR for managed side.

@alberk8
Copy link
Copy Markdown
Contributor

alberk8 commented Apr 8, 2026

Yeah. The plan was if there is any hope for this PR moving forward I'll also add the PR for managed side.

If you have the PR for the nuget then I can test it.

@mikmog
Copy link
Copy Markdown
Contributor Author

mikmog commented Apr 8, 2026

On an ESP32_S3 Feather and a Ili9488 RGB display.

Added PR for Ili9488 nanoframework/nanoFramework.Graphics#180
Not sure about the nuget stuff. Will probably need an oversight from core team. The driver (Ili9488.cs) can be copied to local project. I'll do some additional testing myself

@Ellerbach
Copy link
Copy Markdown
Member

@mikmog thanks for both PR. See the comment from Coderabbit about the bits alignment.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds 18-bit (RGB666 over SPI) transfer support so ILI9488-class displays can be driven correctly from the graphics stack.

Changes:

  • Introduces a new DisplayInterface::SendData18Windowed() path that expands RGB565 pixels to 3-byte transfers.
  • Updates the Generic SPI display driver to choose 16-bit vs 18-bit transfer/clear behavior based on Attributes.BitsPerPixel.
  • Extends DisplayInterface API surface with the new 18-bit windowed send method.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp Adds 18-bit windowed pixel send routine built on the existing SPI transfer buffers.
src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp Switches Clear/BitBlt to use 16-bit or 18-bit transfer logic depending on BitsPerPixel.
src/nanoFramework.Graphics/Graphics/Displays/DisplayInterface.h Declares the new SendData18Windowed API.

Comment thread src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp Outdated
Comment thread src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp`:
- Around line 341-353: The code currently writes r/g/b into byteBuffer using
byteBuffer[bytesWritten++] before checking capacity, causing a one-byte overrun
when bytesWritten is near SPI_MAX_TRANSFER_SIZE; move the capacity check so it
runs before writing the three bytes: ensure you test if (bytesWritten + 3 >
SPI_MAX_TRANSFER_SIZE) and call InternalSendBytes((CLR_UINT8*)currentBuffer,
bytesWritten, true); SwapBuffers(); byteBuffer = (CLR_UINT8*)currentBuffer;
bytesWritten = 0; before performing the three writes to byteBuffer, preserving
use of bytesWritten, SPI_MAX_TRANSFER_SIZE, InternalSendBytes and SwapBuffers
unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 48e008da-86f5-4d63-ac48-3f7f3771041c

📥 Commits

Reviewing files that changed from the base of the PR and between 6e8800a and 3f31723.

📒 Files selected for processing (3)
  • src/nanoFramework.Graphics/Graphics/Displays/DisplayInterface.h
  • src/nanoFramework.Graphics/Graphics/Displays/Generic_SPI.cpp
  • src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp

Comment thread src/nanoFramework.Graphics/Graphics/Displays/Spi_To_Display.cpp Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: Common libs Everything related with common libraries Type: enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants