Skip to content

epd2in9: partial refresh support (tested on magtag 2025 w/ SSD1680)#259

Open
illegalprime wants to merge 1 commit into
rust-embedded-community:mainfrom
illegalprime:main
Open

epd2in9: partial refresh support (tested on magtag 2025 w/ SSD1680)#259
illegalprime wants to merge 1 commit into
rust-embedded-community:mainfrom
illegalprime:main

Conversation

@illegalprime
Copy link
Copy Markdown

@illegalprime illegalprime commented May 19, 2026

This is what I did to get partial refresh working on the Adafruit MagTag 2025.

Copied code from the good work at:

https://github.com/ZinggJM/GxEPD2/blob/de82887e77a78528ea386e68bba2cb0291d2c319/src/epd/GxEPD2_290_T94_V2.cpp

Adding the code I used to test:

#![no_std]
#![no_main]
#![deny(
    clippy::mem_forget,
    reason = "mem::forget is generally not safe to do with esp_hal types,
    especially those holding buffers for the duration of a data transfer."
)]

use embedded_graphics::draw_target::DrawTarget;
use embedded_graphics::geometry::Point;
use embedded_graphics::mono_font::MonoTextStyleBuilder;
use embedded_graphics::primitives::{Circle, Primitive, PrimitiveStyle};
use embedded_graphics::text::{Baseline, Text, TextStyleBuilder};
use embedded_graphics::{Drawable, mono_font};
use embedded_hal_bus::spi::ExclusiveDevice;
use epd_waveshare::color::Color;
use epd_waveshare::epd2in9_v2::{Display2in9, Epd2in9};
use epd_waveshare::graphics::DisplayRotation;
use epd_waveshare::prelude::WaveshareDisplay;
use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay;
use esp_hal::gpio::{Input, InputConfig, Level, Output, OutputConfig, Pull};
use esp_hal::main;
use esp_hal::spi::master::{self, Spi};
use esp_hal::time::{Duration, Instant, Rate};

#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
    loop {}
}

esp_bootloader_esp_idf::esp_app_desc!();

#[main]
fn main() -> ! {
    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
    let peripherals = esp_hal::init(config);

    let b1 = Input::new(
        peripherals.GPIO15,
        InputConfig::default().with_pull(Pull::Up),
    );

    let epd_busy = Input::new(peripherals.GPIO5, InputConfig::default());
    let epd_rst = Output::new(peripherals.GPIO6, Level::Low, OutputConfig::default());
    let epd_dc = Output::new(peripherals.GPIO7, Level::Low, OutputConfig::default());
    let epd_cs = Output::new(peripherals.GPIO8, Level::High, OutputConfig::default());
    let mut delay = Delay::new();

    let epd_spi = Spi::new(
        peripherals.SPI2,
        master::Config::default()
            .with_frequency(Rate::from_khz(100))
            .with_mode(esp_hal::spi::Mode::_0),
    )
    .expect("failed to init spi")
    .with_mosi(peripherals.GPIO35)
    .with_sck(peripherals.GPIO36)
    .with_miso(peripherals.GPIO37);

    let mut spi_dev =
        ExclusiveDevice::new_no_delay(epd_spi, epd_cs).expect("failed to init spi device");

    let mut epd = Epd2in9::new(
        &mut spi_dev,
        epd_busy,
        epd_dc,
        epd_rst,
        &mut delay,
        Some(10),
    )
    .expect("failed to init epd driver");

    let mut display = Display2in9::default();

    display.set_rotation(DisplayRotation::Rotate270);

    display
        .clear(Color::White)
        .expect("could not clear display");

    let _ = Circle::with_center(Point::new(64, 64), 80)
        .into_styled(PrimitiveStyle::with_stroke(Color::Black, 1))
        .draw(&mut display);

    let text_style = TextStyleBuilder::new().baseline(Baseline::Middle).build();
    let font = MonoTextStyleBuilder::new()
        .font(&mono_font::ascii::FONT_10X20)
        .text_color(Color::Black)
        .build();

    let _ = Text::with_text_style("It's working!", Point::new(64, 64), font, text_style)
        .draw(&mut display);

    epd.update_and_display_frame(&mut spi_dev, display.buffer(), &mut delay)
        .expect("failed to draw on epd");

    let mut counter = 0;

    loop {
        let delay_start = Instant::now();
        while delay_start.elapsed() < Duration::from_millis(100) {}
        if b1.is_low() {
            counter += 10;

            let c = Circle::with_center(Point::new(64 + counter, 64), 80);
            let _ = c
                .into_styled(PrimitiveStyle::with_stroke(Color::Black, 1))
                .draw(&mut display);

            epd.update_partial_frame(
                &mut spi_dev,
                &mut delay,
                display.buffer(),
                0,
                0,
                epd.width() - 1,
                epd.height() - 1,
            )
            .expect("update partial");
            epd.display_frame(&mut spi_dev, &mut delay)
                .expect("display frame");
        }
    }
}

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.

1 participant