| Crates.io | gdep073e01 |
| lib.rs | gdep073e01 |
| version | 0.4.0 |
| created_at | 2025-08-04 19:41:32.516793+00 |
| updated_at | 2025-08-14 19:33:48.511169+00 |
| description | Embedded-graphics driver for the GDEP073E01 7-color e-paper display |
| homepage | https://github.com/xandronak/gdep073e01 |
| repository | https://github.com/xandronak/gdep073e01 |
| max_upload_size | |
| id | 1781085 |
| size | 52,725 |
A robust, no_std embedded Rust driver for the Good Display GDEP073E01 7.5-inch, 7-color e-paper display. This driver provides full integration with the embedded-graphics ecosystem, enabling rich graphical applications on resource-constrained embedded systems.
DrawTarget and OriginDimensionsembedded-hal 1.0 implementationAdd to your Cargo.toml:
[dependencies]
gdep073e01 = "0.1"
embedded-graphics = "0.8"
use embedded_graphics::{
mono_font::{ascii::FONT_6X10, MonoTextStyle},
pixelcolor::BinaryColor,
prelude::*,
primitives::{Circle, PrimitiveStyle, Rectangle},
text::{Baseline, Text},
};
use gdep073e01::prelude::*;
// Initialize your platform's HAL components
let spi = /* your SPI implementation */;
let cs_pin = /* chip select pin */;
let dc_pin = /* data/command pin */;
let rst_pin = /* reset pin */;
let busy_pin = /* busy pin */;
let delay = /* delay implementation */;
// Create the display driver
let mut display = Gdep073e01::new(spi, cs_pin, dc_pin, rst_pin, busy_pin, delay);
// Initialize the display
display.init().expect("Failed to initialize display");
// Clear the display with white background
display.clear(Color::White).unwrap();
// Draw a red rectangle
Rectangle::new(Point::new(50, 50), Size::new(200, 100))
.into_styled(PrimitiveStyle::with_fill(Color::Red))
.draw(&mut display)
.unwrap();
// Draw a blue circle
Circle::new(Point::new(400, 200), 80)
.into_styled(PrimitiveStyle::with_fill(Color::Blue))
.draw(&mut display)
.unwrap();
// Add some text
let text_style = MonoTextStyle::new(&FONT_6X10, Color::Black);
Text::with_baseline("Hello, E-Paper!", Point::new(100, 300), text_style, Baseline::Top)
.draw(&mut display)
.unwrap();
// Update the display (this will take ~15-20 seconds)
display.flush().expect("Failed to update display");
// Put the display to sleep to save power
display.sleep().expect("Failed to enter sleep mode");
Connect your GDEP073E01 to your microcontroller as follows:
| Display Pin | MCU Pin | Function | Description |
|---|---|---|---|
| VCC | 3.3V | Power | 3.3V power supply (β οΈ NOT 5V tolerant) |
| GND | GND | Ground | Ground reference |
| DIN | SPI MOSI | Data In | SPI Master Out, Slave In |
| CLK | SPI SCK | Clock | SPI Serial Clock |
| CS | GPIO | Chip Select | SPI Chip Select (active low) |
| DC | GPIO | Data/Command | Data/Command selection |
| RST | GPIO | Reset | Hardware reset (active low) |
| BUSY | GPIO | Busy Status | Display busy indicator |
// Example for STM32F4xx with stm32f4xx-hal
use stm32f4xx_hal::{
gpio::{GpioExt, Speed},
pac,
prelude::*,
spi::{NoMiso, Spi},
timer::Timer,
};
let dp = pac::Peripherals::take().unwrap();
let cp = cortex_m::peripheral::Peripherals::take().unwrap();
let gpioa = dp.GPIOA.split();
let gpiob = dp.GPIOB.split();
// SPI1 pins: SCK=PA5, MOSI=PA7
let sck = gpioa.pa5.into_alternate();
let mosi = gpioa.pa7.into_alternate();
// Control pins
let cs = gpiob.pb0.into_push_pull_output().speed(Speed::High);
let dc = gpiob.pb1.into_push_pull_output().speed(Speed::High);
let rst = gpiob.pb2.into_push_pull_output().speed(Speed::High);
let busy = gpiob.pb3.into_pull_down_input();
// Initialize SPI
let spi = Spi::new(
dp.SPI1,
(sck, NoMiso, mosi),
embedded_hal::spi::MODE_0,
2.MHz(),
&clocks,
);
// Create delay
let mut delay = Timer::new(dp.TIM2, &clocks).delay();
let mut display = Gdep073e01::new(spi, cs, dc, rst, busy, delay);
The GDEP073E01 supports 7 distinct colors:
| Color | Value | Hex | Preview |
|---|---|---|---|
| Black | Color::Black |
0x00 |
β¬ |
| White | Color::White |
0x01 |
β¬ |
| Yellow | Color::Yellow |
0x02 |
π¨ |
| Red | Color::Red |
0x03 |
π₯ |
| Orange | Color::Orange |
0x04 |
π§ |
| Blue | Color::Blue |
0x05 |
π¦ |
| Green | Color::Green |
0x06 |
π’ |
use gdep073e01::Color;
// Using colors in your code
let red_style = PrimitiveStyle::with_fill(Color::Red);
let blue_stroke = PrimitiveStyle::with_stroke(Color::Blue, 3);
Enable exactly one dither feature at a time together with pal-spectra6:
Example usage with embedded-graphics Rgb888 drawing through a dither wrapper:
use embedded_graphics::{prelude::*, pixelcolor::Rgb888, primitives::*};
use gdep073e01::{Gdep073e01, WIDTH, HEIGHT};
#[cfg(feature = "dither-bayer")] use gdep073e01::dither::Bayer4x4;
use gdep073e01::adapter::DitherDrawTarget;
let mut display = Gdep073e01::new(spi, cs, dc, rst, busy, delay);
display.init()?;
#[cfg(feature = "dither-bayer")]
let strat = Bayer4x4;
#[cfg(feature = "dither-bayer")]
let mut dt = DitherDrawTarget::new(display, strat);
#[cfg(feature = "dither-bayer")]
Rectangle::new(Point::new(0,0), Size::new(WIDTH, HEIGHT))
.into_styled(PrimitiveStyle::with_fill(Rgb888::new(200,220,255)))
.draw(&mut dt)?;
Build example feature set:
cargo build --no-default-features --features pal-spectra6,dither-bayer
Limitations: choose exactly one dither feature; FS expects left-to-right scanline order for best results.
use embedded_graphics::primitives::*;
// Filled rectangle
Rectangle::new(Point::new(10, 10), Size::new(100, 50))
.into_styled(PrimitiveStyle::with_fill(Color::Red))
.draw(&mut display)?;
// Stroked circle
Circle::new(Point::new(200, 100), 60)
.into_styled(PrimitiveStyle::with_stroke(Color::Blue, 3))
.draw(&mut display)?;
// Triangle
Triangle::new(
Point::new(300, 50),
Point::new(250, 150),
Point::new(350, 150)
)
.into_styled(PrimitiveStyle::with_fill(Color::Green))
.draw(&mut display)?;
use embedded_graphics::{
mono_font::{ascii::FONT_9X18_BOLD, MonoTextStyle},
text::{Alignment, Text},
};
let large_text = MonoTextStyle::new(&FONT_9X18_BOLD, Color::Black);
Text::with_alignment(
"E-Paper Display",
Point::new(400, 100),
large_text,
Alignment::Center,
)
.draw(&mut display)?;
use embedded_graphics::image::Image;
use tinybmp::Bmp;
// Load BMP image from embedded data
let bmp = Bmp::from_slice(include_bytes!("../assets/logo.bmp")).unwrap();
let image = Image::new(&bmp, Point::new(50, 50));
image.draw(&mut display)?;
Your platform must provide:
embedded-hal::spi::SpiDevice)embedded-hal::digital::OutputPin)embedded-hal::digital::InputPin)embedded-hal::delay::DelayNs)Error: Timeout waiting for display ready
Solution: Check BUSY pin connection and ensure proper pull-down resistor.
flush() only after all drawing operationsdisplay.sleep() after updating the display| Method | Description | Duration |
|---|---|---|
new() |
Create driver instance | Instant |
init() |
Initialize display | ~2-3s |
flush() |
Update display | ~15-20s |
sleep() |
Enter deep sleep | ~100ms |
clear() |
Clear buffer | Instant |
set_pixel() |
Set individual pixel | Instant |
use gdep073e01::Error;
match display.init() {
Ok(()) => println!("Display initialized successfully"),
Err(Error::Spi(e)) => println!("SPI error: {:?}", e),
Err(Error::Pin(e)) => println!("GPIO error: {:?}", e),
Err(Error::Timeout) => println!("Display timeout - check connections"),
}
Contributions are welcome! Here's how you can help:
git clone https://github.com/yourusername/gdep073e01.git
cd gdep073e01
cargo test
cargo doc --open
# Run all tests
cargo test
# Test with specific features
cargo test --features debug
# Run tests on specific target
cargo test --target thumbv7em-none-eabihf
Licensed under either of:
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Made with β€οΈ for the embedded Rust community