epd-waveshare icon indicating copy to clipboard operation
epd-waveshare copied to clipboard

Make drivers usable on devices with little RAM

Open mgottschlag opened this issue 4 years ago • 2 comments

I want to use the library on a microcontroller with 16KiB SRAM, with the 400x300 pixel 4.2 inch display. The library, however, requires a full frame buffer of 400x300x1bit = 15000Byte, almost as much as the available RAM.

I would suggest the following interface to stream data into the library:

/// Iterator which streams pixels.
///
/// This type removes the need for a full screen buffer and allows usage on very memory-constrained
/// devices such as small microcontrollers.
pub trait DisplayStream {
    /// Returns the next section of pixels.
    fn next<'a>(&'a mut self) -> Option<&'a [u8]>;
}

to be used with a corresponding function in the WaveshareDisplay trait:

/// Transmit a full frame to the SRAM of the EPD from a streaming iterator
fn update_frame_stream<S: DisplayStream>(
    &mut self,
    spi: &mut SPI,
    stream: S,
) -> Result<(), SPI::Error>;

Do you think such an interface would make sense? The implementation in the driver is trivial (I'd add a stream() function to the interface, to replace the data() call previously used to transmit all the data to the display). The old full-buffer interface could even internally be implemented as an iterator returning a single element. However, I'd have to test whether that negatively impacts code size.

If you think that's a good idea, I'd try to clean my code up a bit to create a first draft for further review.

mgottschlag avatar Apr 28 '20 17:04 mgottschlag

I think you could try that. There might be a problem to use this together with the embedded_graphics library.

Another solution would be to use a variable sized display (see examples/epd4in2_variable_size), which I also added for that purpose to still work together with the embedded_graphics stuff.

caemor avatar May 13 '20 09:05 caemor

Unfinished commit: https://github.com/mgottschlag/epd-waveshare/commit/fc18e6f6fa078312879ec978729390ca4a6ab70a

I just noticed that this is really unnecessary for my application, though. It is more efficient to partition the display into 2 or 4 parts and use partial updates for those parts. Only on devices with very little RAM would such an interface make sense to reduce the overhead of frequent refresh window settings.

mgottschlag avatar May 16 '20 07:05 mgottschlag