epd-waveshare
epd-waveshare copied to clipboard
Fail to interact with epd3in7 display
Hello,
I want to use an epd3in7 with a stm32f446 that is mounted on a nucleo dev board. I wrote the following code, that is heavily inspired from https://github.com/stm32-rs/stm32f4xx-hal/blob/master/examples/ist7920-bidi-normal-spi.rs It uses the SPI3 pins of the board instead of SPI1 as advised by waveshare wiki because there is a pin conflict on PA5 between SPI1 and the onboard led.
My code is meant to initialize the EPD on SPI3 and blink, but it does not blink. If I do comment the line initializing the EPD, the board blinks. So I guess that initializing the EPD results in a panic for some reason.
I suspected that my SPI is not working, so my code only blinks if MISO is connected to the GND, and it works: if MISO is connected to 3.3V for example, it does not blink. I tested expecting 0xff, and then it blinks when on 3.3v but not on GND, so I'd say that my SPI is OK.
Since I'm a noob at this kind of game, I'd really appreciate if someone could give me a clue about what's going wrong. I'm sorry if it's a stupid error from me, I fail to spot it.
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use stm32f4xx_hal::{
pac,
spi,
gpio::GpioExt,
prelude::*,
timer::Timer,
};
#[allow(unused_imports)]
use panic_halt; // When a panic occurs, stop the microcontroller
use embedded_graphics::{
mono_font::MonoTextStyleBuilder,
prelude::*,
text::{Baseline, Text, TextStyleBuilder},
};
use epd_waveshare::{
color::*,
epd3in7::{EPD3in7,Display3in7},
prelude::*,
};
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let cp = cortex_m::peripheral::Peripherals::take().unwrap();
let gpioa = dp.GPIOA.split();
let gpiob = dp.GPIOB.split();
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.freeze();
let mut led = gpioa.pa5.into_push_pull_output();
led.set_low();
// Configure SPI
// Inspiration: stm32f4xx-hal/examples/ist7920-bidi-normal-spi.rs
let sck = gpiob.pb3.into_alternate();
let miso = gpiob.pb4.into_push_pull_output();
let mosi = gpiob.pb5.into_alternate();
let dc = gpiob.pb14.into_push_pull_output();
let rst = gpiob.pb10.into_push_pull_output();
let cs = gpiob.pb13.into_push_pull_output();
let mut delay = Timer::syst(cp.SYST, &clocks).delay();
let mut spi = dp.SPI1.spi(
(sck, miso, mosi),
spi::Mode {
polarity: spi::Polarity::IdleLow,
phase: spi::Phase::CaptureOnFirstTransition,
},
8.MHz(),
&clocks,
);
// Configure the other pins
let busy = gpioa.pa3.into_input();
//let mut epd = EPD3in7::new(&mut spi, cs, busy, dc, rst, &mut delay, None).expect("EPD init error"); // UNCOMMENT TO LET THE CODE PANIC
/*
let mut display = Display3in7::default();
let style = MonoTextStyleBuilder::new()
.font(&embedded_graphics::mono_font::ascii::FONT_6X10)
.text_color(Color::White)
.background_color(Color::Black)
.build();
let text_style = TextStyleBuilder::new().baseline(Baseline::Top).build();
let _ = Text::with_text_style("Hello Rust!", Point::new(5, 50), style, text_style).draw(&mut display);
// Transfer the frame data to the epd and display it
epd.update_and_display_frame( & mut spi, & display.buffer(), &mut delay).expect("Error while drawing");
*/
loop {
let mut read = [0x55];
spi.transfer(&mut read).unwrap();
if read[0] == 0xff {
led.set_high();
delay.delay_ms(200_u16);
led.set_low();
delay.delay_ms(50_u16);
}
}
}
tl;dr you should basically double check your configuration (you say use SPI3 but code uses SPI1) and then probably not perform the spi transfer manually in your main loop
Your EPD is created with the spi you defined above using SPI1 and your issue description says you want to use this for SPI3. You also shouldn't have to use spi.transfer(&mut read).unwrap(); in your loop. You should also double check if your EPD is a transfer only or recieve and transfer. Mine is a transfer only, so it only has the mosi pin and I initialize that through my HAL as follows.
let mut spi_d = Spi::new_blocking_txonly(p.SPI1, p.PIN_10, p.PIN_11, spi_d_cfg);
I've gotten something to display on a different device just using the below code after the configuration. Though the clear_frame might not be needed before every call to update_and_display_frame.
epd.clear_frame(&mut spi_d, &mut delay).unwrap();
epd.update_and_display_frame(&mut spi_d, &display.buffer(), &mut delay)
.unwrap();
note: I am fairly new to this and I am going off what works on my Raspberry Pi Pico WH