Skip to content

Conversation

@dexterdy
Copy link

Good evening,

I could not get the demo to work for the epd7in5_v2 on my rpi. After a lot of fiddling, I gave up and set about to manually transpile the C demo to rust code, since that one did work. Took me some time, got it working, then started making it idiomatic rust. Then came onto the same issues as I had with the demo here. I managed to solve it. Turns out: you don't need to manually set the CS pin (that is done for you), but you DO need to set the power pin. Without that it won't work. Took the liberty to update the newer CdevPin api as well.

Anyway, I now had a bunch of rust code dealing with raw hexadecimal to drive the display and I noticed that the init functions were all incredibly different. Specifically, the C library has a different init function for full, fast, partial and grasyscale refreshing. Some had power and booster settings, others touched more esoteric stuff. None were setting anything related to refresh modes or LUT.

After a some experimenting, I figured out which commands specifically were responsible for making the refresh modes work and which commands were superfluous.

Apparently, the manufacturers are using a hack: using the temperature override command to select a custom LUT in the OTP memory (better explanation in the code).

I took the liberty of using this knowledge to implement the set_lut function and update_partial_frame functions.

There is also an incredibly cursed hack in the waveshare C libraries that uses the OLD/NEW buffers in the display combined with the temperature override LUT selector hack to fool the display into displaying grayscale (4 shades), which is a feature the website claims. I have not implemented this, as I think it could be harmful for the device itself.

Here a small changelog:

  • fixed and updated demo for epd7in5_v2
  • implemented set_lut for epd7in5_v2
  • added PartialRefresh as a mode for RefreshLut
  • implemented update_partial frame for epd7in5_v2

I hope you will consider my contribution.

@auto-assign auto-assign bot requested a review from caemor December 17, 2025 23:07
@dexterdy dexterdy changed the title feat: fix epd7in5_v2 demo and add support for partial refresh and setting LUT feat: add support for partial refresh and setting LUT epd7in5_v2 Dec 17, 2025
@dexterdy dexterdy marked this pull request as draft December 17, 2025 23:14
@dexterdy dexterdy marked this pull request as ready for review December 22, 2025 13:26
@dexterdy
Copy link
Author

Some notes about this PR:

  • I added a new struct (PartialFrame), with the purpose to make it easier to work with partial updates on devices that require the partial window to be byte-aligned in the full display. This PartialFrame translates operations on the arbitrarily places virtual partial frame, onto a byte-aligned buffer. It also takes care to keep the full display buffer in sync, and to fill the padding bits with data from the full display, so that they won't be replaced with a random empty column.
  • The partial frame does depend on the Vec from the alloc crate, to make a byte-aligned buffer
  • I changed the code in the epd_7in5_v2 driver to wait until idle after each call that requires waiting, instead of before every single call. This seems cleaner and more self-contained

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants