Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using on esp32 with embassy hangs on Epd2in9bc::new #220

Closed
JohnTheCoolingFan opened this issue Nov 30, 2024 · 5 comments
Closed

Using on esp32 with embassy hangs on Epd2in9bc::new #220

JohnTheCoolingFan opened this issue Nov 30, 2024 · 5 comments

Comments

@JohnTheCoolingFan
Copy link

JohnTheCoolingFan commented Nov 30, 2024

Hello, I am trying to drive an epaper display (2.9inch b/w/r from weact, analogous to waveshare module, working with GxEPD2) using this library, running on esp32 using embassy. The lack of examples really makes it difficult, but I'm trying to figure it out.
One problem is that the library doesn't allow to just use the esp_hal::spi::master::Spi and instead one has to "wrap" it through embassy_embedded_hal::blocking::spi::SpiDevice, which itself requires a lot of setup.

So, here's my code so far, based on a template from esp-generate:

#![no_std]
#![no_main]

use core::cell::RefCell;

use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice;
use embassy_executor::Spawner;
use embassy_sync::blocking_mutex::NoopMutex;
use embassy_time::{Duration, Timer};
use embedded_graphics::{
    prelude::{Point, Primitive},
    primitives::{Line, PrimitiveStyle},
    Drawable,
};
use esp_backtrace as _;
use esp_hal::{
    gpio::{Input, Level, NoPin, Output, Pull},
    prelude::*,
    spi::{
        master::{Config, Spi},
        SpiMode,
    },
    Blocking,
};
use log::info;

extern crate alloc;

use epd_waveshare::{epd2in9bc::*, prelude::*};
use static_cell::StaticCell;
#[main]
async fn main(spawner: Spawner) {
    let peripherals = esp_hal::init({
        let mut config = esp_hal::Config::default();
        config.cpu_clock = CpuClock::max();
        config
    });

    esp_alloc::heap_allocator!(72 * 1024);

    esp_println::logger::init_logger_from_env();

    let timer0 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG1);
    esp_hal_embassy::init(timer0.timer0);

    info!("Embassy initialized!");

    /*
    let timer1 = esp_hal::timer::timg::TimerGroup::new(peripherals.TIMG0);
    let _init = esp_wifi::init(
        timer1.timer0,
        esp_hal::rng::Rng::new(peripherals.RNG),
        peripherals.RADIO_CLK,
    )
    .unwrap();
    */

    info!("Initializing spi bus");

    static SPI_BUS: StaticCell<NoopMutex<RefCell<Spi<'static, Blocking>>>> = StaticCell::new();
    let spi_bus = Spi::new(peripherals.SPI2)
        //.with_cs(peripherals.GPIO5)
        .with_cs(NoPin)
        .with_sck(peripherals.GPIO18)
        .with_mosi(peripherals.GPIO23)
        .with_miso(NoPin);
    let spi_bus = NoopMutex::new(RefCell::new(spi_bus));
    let spi_bus = SPI_BUS.init(spi_bus);

    info!("Initializing spi device");

    let mut spi = SpiDevice::new(spi_bus, Output::new(peripherals.GPIO5, Level::Low));

    info!("Initializing pins");

    let busy_in = Input::new(peripherals.GPIO4, Pull::Down);
    let dc = Output::new(peripherals.GPIO17, Level::Low);
    let rst = Output::new(peripherals.GPIO16, Level::High);

    let mut delay = embassy_time::Delay;

    info!("Initializing epd");

    let mut epd =
        Epd2in9bc::new(&mut spi, busy_in, dc, rst, &mut delay, None).expect("EPD creation error");

    info!("Drawing");

    let mut mono_display = Display2in9bc::default();

    let _ = Line::new(Point::new(0, 120), Point::new(0, 200))
        .into_styled(PrimitiveStyle::with_stroke(Color::Black, 1))
        .draw(&mut mono_display);

    let mut chromatic_display = Display2in9bc::default();

    let _ = Line::new(Point::new(15, 120), Point::new(15, 200))
        .into_styled(PrimitiveStyle::with_stroke(Color::Black, 1))
        .draw(&mut chromatic_display);

    info!("Updating color frame");

    epd.update_color_frame(
        &mut spi,
        &mut delay,
        mono_display.buffer(),
        chromatic_display.buffer(),
    )
    .unwrap();

    epd.display_frame(&mut spi, &mut delay).unwrap();

    info!("Pre sleep");

    epd.sleep(&mut spi, &mut delay).unwrap();

    info!("Post sleep");

    // TODO: Spawn some tasks
    let _ = spawner;

    loop {
        info!("Hello world!");
        Timer::after(Duration::from_secs(1)).await;
    }

    // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/v0.22.0/examples/src/bin
}

With the debug logs in place, the point in the program where it stops is after info!("Initializing epd");.
Did I do something obviously wrong in my code? What can I do to diagnose the issue further to find out why it's hung?

@JohnTheCoolingFan
Copy link
Author

Potentially related issues, none of which have an answer:

@JohnTheCoolingFan
Copy link
Author

JohnTheCoolingFan commented Dec 2, 2024

Also, a pin mapping:

EPD ESP32
GND GND
VCC 3V3
SDA P23 (VSPI MOSI)
SCL P18 (VSPI SCLK)
CS P5
D/C P17
RES P16
BUSY P4

Same as what I've used to run GxEPD2 example

@JohnTheCoolingFan
Copy link
Author

For info, here are the crate versions I'm using:

esp-backtrace = { version = "0.14.2", features = [
    "esp32",
    "exception-handler",
    "panic-handler",
    "println",
]}

esp-hal = { version = "0.22.0", features = [
    "esp32",
] }
esp-println = { version = "0.12.0", features = ["esp32", "log"] }
log = { version = "0.4.21" }
esp-alloc = { version = "0.5.0" }
embedded-io = "0.6.1"

embedded-io-async = "0.6.1"
embassy-net = { version = "0.4.0", features = [ "tcp", "udp", "dhcpv4", "medium-ethernet"] }

esp-wifi = { version = "0.11.0", default-features=false, features = [
    "esp32",
    "utils",
    "wifi",
    "esp-alloc",
    "log",
] }
heapless = { version = "0.8.0", default-features = false }
smoltcp = { version = "0.11.0", default-features = false, features = [
    "medium-ethernet",
    "proto-dhcpv4",
    "proto-igmp",
    "proto-ipv4",
    "socket-dhcpv4",
    "socket-icmp",
    "socket-raw",
    "socket-tcp",
    "socket-udp",
] }
embassy-executor = { version = "0.6.0",  features = [
    "task-arena-size-12288",
] }
embassy-time     = { version = "0.3.1",  features = ["generic-queue-8"] }
esp-hal-embassy  = { version = "0.5.0",  features = ["esp32"] }
static_cell      = { version = "2.1.0",  features = ["nightly"] }
critical-section = "1.2.0"
epd-waveshare = "0.6.0"
embedded-graphics = "0.8.1"
embassy-embedded-hal = "0.2.0"
embassy-sync = "0.6.1"
embedded-hal-bus = "0.2.0"

@JohnTheCoolingFan
Copy link
Author

I've checked some things and I think this library has a problem with Epd2in9bc::new or Epd2in9bc::init specifically.

I've used https://github.com/GnomedDev/epaper-simplyplural-badge/tree/0440c798289a3b36dcfb42f4938d9fc3a9111da9 as a base project to verify whether the project that was linked to me would work if I tweak it to my hardware. I've done some incremental changes: first changing gpio pins, then adding logging, and at the end changing from epd2in13_v2 to epd2in9bc. The last one caused the program to break. Source code here: https://github.com/JohnTheCoolingFan/epaper-simplyplural-badge/tree/f58ac26fcb97d9d7a89a55d27dc0b1b0afd37201

@JohnTheCoolingFan
Copy link
Author

Also, switching to Epd2in9 goes past new so now I am quite confident there's a bug in the implementation of epd2in9bc. I'll check whether it depends on the platform (esp32) later

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

No branches or pull requests

1 participant