Skip to content

Add LcmEn2r13 driver for Heltec Vision Master E213 and improve rotated Graphics rendering#1504

Open
garydyksman wants to merge 9 commits into
nanoframework:mainfrom
garydyksman:add-LcmEn2r13
Open

Add LcmEn2r13 driver for Heltec Vision Master E213 and improve rotated Graphics rendering#1504
garydyksman wants to merge 9 commits into
nanoframework:mainfrom
garydyksman:add-LcmEn2r13

Conversation

@garydyksman
Copy link
Copy Markdown

@garydyksman garydyksman commented Mar 31, 2026

Description

  • Adds a new LcmEn2r13 driver for the LCMEN2R13EFC1 2.13" black-and-white e-paper display used on the Heltec Vision Master E213.
  • Exposes the display using native controller RAM geometry (128x250) so the framebuffer contract remains consistent.
    Implements SPI command/data handling, panel initialization, framebuffer upload, clear, full refresh, and power-down support.
  • Adds an LcmEn2r13Sample project showing display initialization, drawing, and refresh.
    Improves Graphics by fixing line drawing, using rotation-aware logical width and height, routing pixel drawing through IEPaperDisplay.DrawPixel(), improving text wrapping, and adding optional per-glyph horizontal flipping for mirrored text cases.

Motivation and Context

  • This adds support for a new e-paper display module and board combination that is not currently available in the repository.
  • It also improves Graphics so rotated rendering works more reliably with native-orientation display drivers.

How Has This Been Tested?

  • Tested on Heltec Vision Master E213 hardware.
  • Verified panel initialization, clear, full refresh, and deep sleep behavior.
  • Verified direct pixel drawing using rectangles, lines, circles, and triangle test patterns.
  • Verified text rendering through Graphics with rotated output.
  • Verified that mirrored glyph rendering is corrected by enabling per-glyph horizontal flipping.

Screenshots

  • Added photos from hardware testing showing successful primitive rendering and corrected text rendering.
    IMG_8187
    IMG_8191

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)
  • Dependencies (update dependencies and changes associated, has no impact on code or features)
  • Unit Tests (add new Unit Test(s) or improved existing one(s), 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).
  • I have added new tests to cover my changes.

Introduce driver for LCMEN2R13EFC1 2.13" e-paper display (Heltec Vision Master E213), including SPI/GPIO handling and full drawing/refresh support. Add LcmEn2r13Sample project demonstrating usage. Enhance Graphics class with rotation-aware Width/Height, glyph mirroring, improved drawing methods, and better bounds checking. No breaking changes; new driver and sample are additive.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added LCMEN2R13EFC1 e-paper display driver with accompanying sample application
    • Enhanced Graphics class with rotation-aware dimensions and horizontal glyph flipping
    • Improved DrawBitmap rotation handling and text wrapping behavior
  • Bug Fixes

    • Fixed DrawLine coordinate calculation
    • Strengthened DrawPixel bounds validation
    • Improved resource disposal control in Graphics initialization
  • Documentation

    • Clarified display readiness documentation for controller variations

Walkthrough

A new e-paper display driver for the LCMEN2R13EFC1 panel is introduced along with an accompanying sample. The Graphics class is refactored to support disposal control, logical rotation-aware dimensions, and improved pixel drawing. Existing drivers are updated with formatting changes and buffer optimizations. Project and solution files are updated to include the new driver and sample.

Changes

Cohort / File(s) Summary
LcmEn2r13 Driver Implementation
devices/ePaper/Drivers/LcmEn2r13/Command.cs, devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
New internal Command enum for panel opcodes. Complete LcmEn2r13 driver class implementing IEPaperDisplay with 1bpp frame buffer, power/refresh management, SPI communication, GPIO-driven busy-pin synchronization, and partial/full refresh capabilities.
Graphics Class Refactoring
devices/ePaper/Graphics.cs
Added disposal control via disposeDisplay parameter. Introduced rotation-aware logical Width/Height properties and FlipGlyphsHorizontally flag. Fixed Bresenham line algorithm (dy comparison). Enhanced text wrapping/rendering to respect logical dimensions and optional glyph mirroring. Refactored bitmap and pixel drawing for rotation awareness. Consolidated coordinate transformation logic.
Project Configuration
devices/ePaper/ePaper.nfproj, devices/ePaper/ePaper.sln, devices/ePaper/nuget.config
Updated project file to include new LcmEn2r13 driver sources. Added LcmEn2r13Sample project to solution with build/deploy configurations. Added NuGet source configuration file.
LcmEn2r13 Sample Implementation
devices/ePaper/Samples/LcmEn2r13Sample/*
New sample project with GPIO/SPI pin configuration, display initialization, graphics rendering with rotation and glyph flipping, demo frame drawing with shapes/text, and partial/full refresh loop demonstration. Includes project file, assembly info, package configuration, and main program entry point.
Existing Driver Updates
devices/ePaper/Drivers/JD796xx/Gdew0154m09.cs, devices/ePaper/Drivers/JD796xx/JD79653A.cs
Gdew0154m09 constructor formatting only. JD79653A: constructor reformatted; _whiteBuffer reduced from Width * Height to (Width * Height) / 8 bytes for 1bpp packing; DirectDrawBuffer stripped of 5ms delay and full refresh trigger.
Interface & Sample Updates
devices/ePaper/Drivers/IePaperDisplay.cs, devices/ePaper/Samples/SSD1680Sample/Program.cs, devices/ePaper/Samples/SSD1681Sample/Program.cs
Updated WaitReady documentation for controller-dependent busy-pin polarity. Updated existing SSD samples to pass disposeDisplay: false when constructing Graphics.
Assembly Metadata
devices/ePaper/Samples/LcmEn2r13Sample/Properties/AssemblyInfo.cs
New assembly info file with standard metadata attributes and AssemblyNativeVersion for NanoFramework interop.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main changes: adding a new LcmEn2r13 driver and improving Graphics rendering with rotation support. It is concise, specific, and clearly summarizes the changeset.
Description check ✅ Passed The description comprehensively covers the driver implementation, sample project, Graphics improvements, testing on hardware, and includes screenshots. It directly relates to all major changes in the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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.

@garydyksman garydyksman changed the title Add LCMEN2R13 2.13" e-paper driver and sample Add LcmEn2r13 driver for Heltec Vision Master E213 and improve rotated Graphics rendering Mar 31, 2026
@Ellerbach Ellerbach requested a review from Copilot March 31, 2026 15:45
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 support for the Heltec Vision Master E213’s LCMEN2R13EFC1 2.13" B/W e-paper panel by introducing a new ePaper driver and a sample app, and updates the ePaper Graphics helper to improve rotation-aware rendering and primitive drawing.

Changes:

  • Added LcmEn2r13 display driver (SPI init, framebuffer upload/clear, refresh, power-down).
  • Added LcmEn2r13Sample nanoFramework project demonstrating initialization and drawing.
  • Updated Graphics to be rotation-aware (logical Width/Height, fixed line drawing, pixel routing via IEPaperDisplay.DrawPixel, text wrapping/mirroring option).

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
devices/LcmEn2r13Sample/Properties/AssemblyInfo.cs Adds sample assembly metadata (currently template-like).
devices/LcmEn2r13Sample/Program.cs Sample demonstrating SPI + drawing + refresh on the new panel.
devices/LcmEn2r13Sample/packages.config NuGet dependencies for the sample.
devices/LcmEn2r13Sample/LcmEn2r13Sample.nfproj Sample project definition and references.
devices/ePaper/Graphics.cs Rotation-aware width/height, line fix, pixel routing, text wrapping + optional glyph flip.
devices/ePaper/ePaper.sln Adds the new sample project to the solution.
devices/ePaper/ePaper.nfproj Includes the new driver file in the ePaper library project.
devices/ePaper/Drivers/JD796xx/LcmEn2r13.cs New driver implementation for LCMEN2R13EFC1 panel.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread devices/LcmEn2r13Sample/Program.cs Outdated
Comment thread devices/LcmEn2r13Sample/Program.cs Outdated
Comment thread devices/ePaper/Graphics.cs Outdated
Comment thread devices/ePaper/Drivers/JD796xx/LcmEn2r13.cs Outdated
Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs Outdated
Comment thread devices/LcmEn2r13Sample/Properties/AssemblyInfo.cs Outdated
Comment thread devices/ePaper/Samples/LcmEn2r13Sample/packages.config
@Ellerbach
Copy link
Copy Markdown
Member

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

@Ellerbach
Copy link
Copy Markdown
Member

@garydyksman please accept the policy. And also address the comments from Copilot. I'll also have a look.

Copy link
Copy Markdown
Member

@Ellerbach Ellerbach left a comment

Choose a reason for hiding this comment

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

Overall all good. Couple of comments mainly related to where to find the magic numbers. And thanks also for the improvements in the Graphics.

Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
Comment thread devices/ePaper/Drivers/JD796xx/LcmEn2r13.cs Outdated
Comment thread devices/ePaper/Drivers/JD796xx/LcmEn2r13.cs Outdated
@josesimoes
Copy link
Copy Markdown
Member

@garydyksman can you please address the review comments so we can merge and have this new device ?

- update project and sample to use the single LcmEn2r13 namespace
- restore busy-pin based refresh flow for HT-VME213
- remove extra sample refreshes and clean up SPI pin usage
- reintroduce Heltec LUT-based partial refresh sequence
- preserve correct panel orientation during partial refresh
Copy link
Copy Markdown

@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: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
devices/ePaper/Graphics.cs (1)

162-197: ⚠️ Potential issue | 🟡 Minor

DrawText silently clips when text overflows the bottom.

Horizontal overflow wraps onto a new line using rotation-aware Width, but there is no corresponding check against Height. Once y + line + font.Height exceeds the display, glyphs are quietly dropped by DrawPixel's bounds check. Consider either early-exiting the loop when the next line would fall outside the display, or documenting this behavior on the method so callers know content beyond the bottom edge is silently discarded.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@devices/ePaper/Graphics.cs` around lines 162 - 197, DrawText currently wraps
horizontally using Width but never checks vertical bounds, so glyph rows past
the bottom are silently dropped by DrawPixel; update DrawText (and the wrap
logic that updates line) to check against Height and early-exit when the next
glyph row would be entirely outside the display (e.g., if y + line + font.Height
> Height) to stop processing further characters, or alternatively add a clear
XML doc comment on DrawText stating that content past the bottom is discarded;
refer to DrawText, DrawPixel, Width, Height, FlipGlyphsHorizontally and
font.Width/font.Height when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs`:
- Around line 48-86: Add a short comment above the five LUT arrays
(PartialLutVcom, PartialLutWhiteToWhite, PartialLutBlackToWhite,
PartialLutWhiteToBlack, PartialLutBlackToBlack) that cites the original vendor
source (datasheet section, vendor document or Heltec sample) and include the
exact reference (document name and section or URL) so maintainers can
trace/regenerate the waveforms; while editing, verify the source to confirm
whether PartialLutWhiteToWhite and PartialLutBlackToWhite being identical is
intentional and, if it is not, correct the duplicated table per the vendor data
and note the correction in the comment.
- Around line 255-283: PerformPartialRefresh currently powers the panel on and
triggers DisplayRefresh but never issues PowerOff, leaving DC/DC converters
running; update PerformPartialRefresh to follow the same shutdown pattern as
PerformFullRefresh by sending the PowerOff command after DisplayRefresh and
waiting for Ready plus the same small delay (use WaitReady() and WaitMs(...)
consistent with PerformFullRefresh), then call UpdatePreviousFrame as
appropriate; alternatively, if leaving the panel powered is intentional, add a
clear comment in PerformPartialRefresh explaining why it must remain powered and
document expected caller behavior.
- Around line 246-249: SetPosition currently throws NotImplementedException
which violates the IEPaperDisplay contract; change SetPosition in class
LcmEn2r13 to be a silent no-op by removing the exception and returning
immediately (or delegate to existing logic such as calling SetRamPointerToOrigin
if you opt to implement it); reference the SetPosition method and, if choosing
implementation, reuse SetRamPointerToOrigin to update RAM X/Y address counters
instead of throwing so generic consumers and Graphics callers won't crash.
- Around line 552-577: Dispose(bool disposing) unconditionally disposes
_spiDevice which conflicts with caller ownership; change the logic so _spiDevice
is only disposed when the driver owns it. Update the Dispose implementation in
LcmEn2r13.Dispose(bool) to dispose _spiDevice only if the ownership flag is true
(either reuse the existing _shouldDispose flag or add a new _shouldDisposeSpi
flag set via the constructor), and ensure the constructor/fields (where
_shouldDispose is set) are adjusted accordingly so that when the caller supplies
the SpiDevice the flag is false and the driver does not call
_spiDevice.Dispose().
- Around line 441-450: WaitReady currently waits for PinValue.High which is
inverted; change the busy-pin check in WaitReady to wait for PinValue.Low (use
_busyPin.WaitUntilPinValueEquals(PinValue.Low, ...)) so it blocks until the
controller is idle (align with IEPaperDisplay and Ssd168x). Also increase the
non-busy fallback delay in the _useBusyPin == false path (replace WaitMs(1500)
with a longer timeout such as 3000–4000 ms or make a named constant) or document
that PerformFullRefresh/PowerOn/DisplayRefresh/PowerOff require longer
full-refresh timing when hardware busy pin is not used.

In `@devices/ePaper/Graphics.cs`:
- Around line 59-65: The constructor change silently alters disposal semantics:
restore the previous default by making the optional parameter default to true so
Graphics(IEPaperDisplay) continues to dispose the wrapped IEPaperDisplay; update
the constructor signature (Graphics(IEPaperDisplay ePaperDisplay, bool
disposeDisplay = true)), ensure the existing _disposeDisplay field and
Graphics.Dispose() logic still use _disposeDisplay, and add a brief comment on
the constructor explaining ownership semantics so callers who want to retain the
display can pass disposeDisplay: false.

In `@devices/LcmEn2r13Sample/packages.config`:
- Around line 3-8: Program.cs calls Thread.Sleep (e.g., lines referencing
Thread.Sleep), but packages.config is missing the nanoFramework.System.Threading
package; add an entry for the nanoFramework.System.Threading package to
packages.config (use a compatible version for netnano1.0 consistent with the
other nanoFramework packages) so the System.Threading assembly is declared and
the sample can deploy.

In `@devices/LcmEn2r13Sample/Program.cs`:
- Around line 31-59: The GpioController instance (gpio) is never disposed while
LcmEn2r13 is constructed with shouldDispose: false, leaking the controller; fix
by either owning its lifetime (change to using var gpio = new GpioController();
so gpio is disposed when out of scope) or let the driver own it by removing the
shouldDispose argument or passing shouldDispose: true to the LcmEn2r13
constructor; update references to GpioController/gpio and the LcmEn2r13(...)
call accordingly.
- Around line 77-105: The loop currently calls PerformPartialRefresh() every
iteration after the first, causing potential ghosting; modify the loop in
Program.Main that uses firstFrame, fillFirstShape and calls
display.PerformPartialRefresh()/display.PerformFullRefresh() to insert a
periodic full refresh (e.g., count iterations with an int counter like
partialCount and when partialCount % 10 == 0 call display.PerformFullRefresh()
and reset or continue) so that after N partial refreshes you perform a full
refresh; ensure the initial firstFrame logic remains and increment/reset the
counter and toggle fillFirstShape as before.

In `@devices/LcmEn2r13Sample/Properties/AssemblyInfo.cs`:
- Around line 8-13: Update the assembly metadata attributes to match the rest of
the nanoFramework.IoT.Device samples: replace AssemblyTitle and AssemblyProduct
values that currently read "CSharp.BlankApplication" with the correct sample
name, set AssemblyCompany to the consistent organization name used across the
repo, and update AssemblyCopyright from "Copyright © iO 2026" to the same
copyright string used by other samples; modify the
AssemblyDescription/AssemblyConfiguration if needed to reflect the device/sample
purpose so the AssemblyTitle, AssemblyProduct, AssemblyCompany, and
AssemblyCopyright attributes are consistent with the project's conventions.

---

Outside diff comments:
In `@devices/ePaper/Graphics.cs`:
- Around line 162-197: DrawText currently wraps horizontally using Width but
never checks vertical bounds, so glyph rows past the bottom are silently dropped
by DrawPixel; update DrawText (and the wrap logic that updates line) to check
against Height and early-exit when the next glyph row would be entirely outside
the display (e.g., if y + line + font.Height > Height) to stop processing
further characters, or alternatively add a clear XML doc comment on DrawText
stating that content past the bottom is discarded; refer to DrawText, DrawPixel,
Width, Height, FlipGlyphsHorizontally and font.Width/font.Height when making the
change.
🪄 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: nanoframework/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0c1abe72-f189-4f84-a124-5c2c71b52689

📥 Commits

Reviewing files that changed from the base of the PR and between 8ff9f4d and 5cb491e.

📒 Files selected for processing (12)
  • devices/LcmEn2r13Sample/LcmEn2r13Sample.nfproj
  • devices/LcmEn2r13Sample/Program.cs
  • devices/LcmEn2r13Sample/Properties/AssemblyInfo.cs
  • devices/LcmEn2r13Sample/packages.config
  • devices/ePaper/Drivers/JD796xx/Gdew0154m09.cs
  • devices/ePaper/Drivers/JD796xx/JD79653A.cs
  • devices/ePaper/Drivers/LcmEn2r13/Command.cs
  • devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
  • devices/ePaper/Graphics.cs
  • devices/ePaper/ePaper.nfproj
  • devices/ePaper/ePaper.sln
  • devices/ePaper/nuget.config

Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
Comment thread devices/ePaper/Graphics.cs Outdated
Comment thread devices/ePaper/Samples/LcmEn2r13Sample/packages.config
Comment thread devices/LcmEn2r13Sample/Program.cs Outdated
Comment thread devices/LcmEn2r13Sample/Program.cs
Comment thread devices/LcmEn2r13Sample/Properties/AssemblyInfo.cs Outdated
- align LcmEn2r13 frame flow with flush-then-refresh semantics
- preserve partial refresh support and document Heltec-based LUT/init sequences
- stop disposing caller-owned SpiDevice and fix DrawBitmap non-rotated fast path
- clean up the sample metadata, package lock, and StyleCop dependency
- update the sample to exercise full then partial refresh shape toggling
@garydyksman
Copy link
Copy Markdown
Author

@dotnet-policy-service agree

@garydyksman
Copy link
Copy Markdown
Author

@garydyksman can you please address the review comments so we can merge and have this new device ?

@josesimoes i have updated my PR. I have had an absolute blast working on the nanoFramework. I decided to use these ESP32 devices as a hackathon project for my team, I don't think they know what is possible with .Net.

If you are interested i can give you more details and give feedback after the event.

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

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

Comment thread devices/ePaper/Graphics.cs Outdated
Comment thread devices/ePaper/Drivers/JD796xx/JD79653A.cs Outdated
Comment thread devices/ePaper/ePaper.sln Outdated
@Ellerbach
Copy link
Copy Markdown
Member

@josesimoes i have updated my PR. I have had an absolute blast working on the nanoFramework. I decided to use these ESP32 devices as a hackathon project for my team, I don't think they know what is possible with .Net.

If you are interested i can give you more details and give feedback after the event.

Thanks! Yes, .NET nanoFramework is an AMAZING* platform :-) And yes, we're always interested to get some feedback and more details about such events!

And you also have couple of feedback from Copilot!

@josesimoes
Copy link
Copy Markdown
Member

@garydyksman nice!! Agreed: .NET nanoFramework can offer a great learning playground for development team. Would love to know more abou the event. Please do provide details. Here or just email me directly, or over Discord. 😉

- LcmEn2r13: no-op SetPosition, PowerOff after partial refresh, longer busy-pin fallback, init/prep doc pointers.

- Graphics: default disposeDisplay true, DrawText stops when past logical height.

- Jd79653A.EndFrameDraw: flush only (match Ssd168x); IEPaperDisplay WaitReady remark clarified.

- Move LcmEn2r13Sample under ePaper/Samples; fix nfproj paths; add System.Threading package.

- Sample: periodic full refresh; Graphics does not dispose driver when display is owned.

- SSD1680/1681 samples: disposeDisplay false with nested usings.

Made-with: Cursor
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

Copilot reviewed 16 out of 16 changed files in this pull request and generated 4 comments.

Comment thread devices/ePaper/Samples/LcmEn2r13Sample/Program.cs Outdated
Comment thread devices/ePaper/Samples/LcmEn2r13Sample/Properties/AssemblyInfo.cs
Comment thread devices/ePaper/Samples/LcmEn2r13Sample/Properties/AssemblyInfo.cs Outdated
Comment thread devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
- Add nanoFramework copyright headers to LcmEn2r13Sample Program and AssemblyInfo.

- Align AssemblyInfo with other ePaper samples (copyright string, drop Product and fixed AssemblyVersion).

- LcmEn2r13.Clear: call UpdatePreviousFrame after writing white to RAM so partial refresh diffing stays consistent.

Made-with: Cursor
@garydyksman garydyksman requested a review from Ellerbach April 22, 2026 12:48
Copy link
Copy Markdown

@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 `@devices/ePaper/Drivers/JD796xx/JD79653A.cs`:
- Line 69: The buffer allocation for _whiteBuffer in JD79653A.cs uses floor
division and can underrun when Width*Height isn't divisible by 8; change the
allocation to use ceiling division so partial final bytes are included (e.g.,
compute packedSize = (Width * Height + 7) / 8 or use an equivalent
Math.Ceiling-based expression) and replace the current new byte[(Width * Height)
/ 8] with new byte[packedSize]; ensure the same fix is applied for any similar
_blackBuffer or packed-buffer allocations in the class.

In `@devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs`:
- Around line 360-361: Add a named constant for the magic command 0x3C used in
the initialization sequence to match the existing style and improve readability:
define a descriptive constant (e.g., VendorCommandUnknown3C or CMD_0x3C) in the
LcmEn2r13 class and replace the literal used in the SendCommand call, and
optionally add a short comment explaining its purpose or that it is
vendor-specific where SendCommand(0x3C) and SendData(0x01) currently appear to
clarify intent.
🪄 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: nanoframework/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1175d99c-74b3-41e3-ae6a-c1013724e009

📥 Commits

Reviewing files that changed from the base of the PR and between 5cb491e and 6466b03.

📒 Files selected for processing (12)
  • devices/ePaper/Drivers/IePaperDisplay.cs
  • devices/ePaper/Drivers/JD796xx/JD79653A.cs
  • devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs
  • devices/ePaper/Graphics.cs
  • devices/ePaper/Samples/LcmEn2r13Sample/LcmEn2r13Sample.nfproj
  • devices/ePaper/Samples/LcmEn2r13Sample/Program.cs
  • devices/ePaper/Samples/LcmEn2r13Sample/Properties/AssemblyInfo.cs
  • devices/ePaper/Samples/LcmEn2r13Sample/packages.config
  • devices/ePaper/Samples/LcmEn2r13Sample/packages.lock.json
  • devices/ePaper/Samples/SSD1680Sample/Program.cs
  • devices/ePaper/Samples/SSD1681Sample/Program.cs
  • devices/ePaper/ePaper.sln

PagedFrameDrawEnabled = enableFramePaging;

_whiteBuffer = new byte[Width * Height];
_whiteBuffer = new byte[(Width * Height) / 8];
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Round up the packed buffer size.

Line 69 uses floor division, so geometries whose total pixel count is not divisible by 8 will allocate one byte too few and truncate the final partial byte during upload. Use ceiling division here instead.

Proposed fix
-            _whiteBuffer = new byte[(Width * Height) / 8];
+            _whiteBuffer = new byte[((Width * Height) + 7) / 8];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_whiteBuffer = new byte[(Width * Height) / 8];
_whiteBuffer = new byte[((Width * Height) + 7) / 8];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@devices/ePaper/Drivers/JD796xx/JD79653A.cs` at line 69, The buffer allocation
for _whiteBuffer in JD79653A.cs uses floor division and can underrun when
Width*Height isn't divisible by 8; change the allocation to use ceiling division
so partial final bytes are included (e.g., compute packedSize = (Width * Height
+ 7) / 8 or use an equivalent Math.Ceiling-based expression) and replace the
current new byte[(Width * Height) / 8] with new byte[packedSize]; ensure the
same fix is applied for any similar _blackBuffer or packed-buffer allocations in
the class.

Comment on lines +360 to +361
SendCommand(0x3C);
SendData(0x01);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding a named constant for command 0x3C.

Unlike other commands in the initialization sequence, 0x3C is used directly without a named constant or comment explaining its purpose. Consider adding a VendorCommandUnknown3C constant or a brief comment for consistency with the documented approach.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@devices/ePaper/Drivers/LcmEn2r13/LcmEn2r13.cs` around lines 360 - 361, Add a
named constant for the magic command 0x3C used in the initialization sequence to
match the existing style and improve readability: define a descriptive constant
(e.g., VendorCommandUnknown3C or CMD_0x3C) in the LcmEn2r13 class and replace
the literal used in the SendCommand call, and optionally add a short comment
explaining its purpose or that it is vendor-specific where SendCommand(0x3C) and
SendData(0x01) currently appear to clarify intent.

Copy link
Copy Markdown
Member

@Ellerbach Ellerbach left a comment

Choose a reason for hiding this comment

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

Really nice! few little nits and questions.

_resetPin.Write(PinValue.High);
}

_dataCommandPin = _gpioController.OpenPin(dataCommandPin, PinMode.Output);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

check that the pin is a valid one (should be >= 0) and throw if not (technically it will be done in there but still a bit better)

PagedFrameDrawEnabled = enableFramePaging;

_whiteBuffer = new byte[Width * Height];
_whiteBuffer = new byte[(Width * Height) / 8];
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why this change?

/// Positioned streaming writes are not used by this driver; callers should use <see cref="DrawPixel"/> or <see cref="Graphics"/>.
/// </remarks>
public void SetPosition(int x, int y)
{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

maybe throw a not implemented? So at least from a developer point of view it's clear?

/////////////////////////////////////////////////////////////////
// This attribute is mandatory when building Interop libraries //
// update this whenever the native assembly signature changes //
[assembly: AssemblyNativeVersion("0.0.0.0")]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this can be removed as no dependency from native

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants