Implement 7.5 inch V2 driver#5
Conversation
MorganR
left a comment
There was a problem hiding this comment.
Thank you for this contribution!
It looks really good and I'll be happy to accept it. I think there is a slight misunderstanding currently on how I intended the DisplaySimple::write_framebuffer vs. DisplayPartial::write_base_framebuffer to work.
Would you be amenable to tweaking this?
| x_end / 256, | ||
| x_end % 256 - 1, |
There was a problem hiding this comment.
This looks potentially buggy, as the second parameter will overflow if x_end is a multiple of 256. Could you please try a partial display where that's true to confirm?
There was a problem hiding this comment.
Not sure, the result is casted to u8, x_end is a signed i32, if x_end is a multiple of 256, it becomes 256 % 256 - 1 = 255.
These calculations were taken from the official code
| let buf2_value; | ||
| match self.state.mode { | ||
| RefreshMode::Fast | RefreshMode::Full | RefreshMode::Partial => { | ||
| buf1_value = BinaryColor::On as u8; |
There was a problem hiding this comment.
Should this be 0xFF? I think the u8 for BinaryColor::On is 0x01, which seems odd to use here
| self.send(spi, Command::PartialIn, &[]).await?; | ||
|
|
||
| let window: [u8; _] = [ | ||
| x_start / 256, | ||
| x_start % 256, | ||
| x_end / 256, | ||
| x_end % 256 - 1, | ||
| y_start / 256, | ||
| y_start % 256, | ||
| y_end / 256, | ||
| y_end % 256 - 1, | ||
| 0x01, | ||
| ] | ||
| .map(|p| p as u8); | ||
|
|
||
| self.send(spi, Command::PartialWindow, &window).await?; |
There was a problem hiding this comment.
This looks more like the set_window operation (see epd2in9_v2). The idea for both write_framebuffer and write_base_framebuffer is that they're both supposed to support writing to an arbitrary window within the display's internal framebuffers. So they should both support this logic.
The difference between write_framebuffer and write_base_framebuffer is that write_framebuffer should only write the main framebuffer that's going to be displayed next. In black and white mode, that's Command::DisplayStartTrans2 for this 7.5" display.
write_base_framebuffer should only write to the "base" or "old" buffer that's used as the diff base for a partial update operation (in this case, DisplayStartTrans1). You don't actually have to use this, but it's exposed for more advanced control.
When you're in partial refresh mode, the display only tries to update the pixels that differ between these two buffers. In the default operating modes, the display automatically copies the data from the active display buffer to the old display buffer on each refresh. Even if you're writing the full buffer to the screen on each update, you can still benefit from a faster refresh time if only a few pixels have changed.
So write_base_framebuffer only exists in DisplayPartial because it would be meaningless for a display that had no partial refresh like this. But I still would expect most users of a partially updating display to only need write_framebuffer. That works fine, since DisplayPartial requires DisplaySimple.
Does that make this more clear? I'd love to hear if the docs can be improved to make this more obvious.
|
Sure, thanks for the detailed review, I will try to correct them in the upcoming days. |
|
Maybe the Although the video appears correct, I discovered that I am using the partial refresh function totally wrong. This will require more investigation. Unfortunately I broke my EPD so it can take a few weeks. |
This PR
Cleartraitdebug_assert!()withassert()to make themconstcompatibleu32everywheresend_iter()function which takes an iterator instead of a&[u8]bufferThe demo sequence has been changed a bit because I could not fully decode what the existing demos should look like
Video
epd_demo.mp4