Expand description
§sky-ili9341
Async-ready ILI9341 TFT display driver for embedded Rust.
§Features
- Blocking and async SPI interfaces (
embedded-hal1.0 /embedded-hal-async) - Builder pattern for flexible configuration (orientation, color order, inversion, offsets)
- Correct MADCTL implementation per ILI9341 datasheet — no hardcoded BGR
- Optimized drawing with 512-byte buffered SPI writes and fast
fill_rect embedded-graphics-coreDrawTargetsupport (optionalgraphicsfeature)defmtlogging support (optionaldefmtfeature)- Board presets Made for SkyRizz E32
no_std— works on any embedded target
§Cargo Features
| Feature | Default | Description |
|---|---|---|
graphics | ✅ | Enables embedded-graphics-core DrawTarget implementation |
async | ❌ | Enables async interface, builder, and display types via embedded-hal-async |
defmt | ❌ | Enables defmt::Format derives for error and option types |
§Quick Start (Blocking)
ⓘ
use sky_ili9341::{Builder, SpiInterface, Orientation, ColorOrder};
let di = SpiInterface::new(spi, dc);
let mut display = Builder::new(di)
.orientation(Orientation::Landscape)
.color_order(ColorOrder::Bgr)
.init(&mut reset_pin, &mut delay)
.unwrap();
display.clear_screen(0x0000).unwrap(); // Black§Quick Start (Async with Embassy on ESP32)
ⓘ
use sky_ili9341::{AsyncBuilder, AsyncSpiInterface, Orientation};
let di = AsyncSpiInterface::new(spi, dc);
let mut display = AsyncBuilder::new(di)
.orientation(Orientation::Landscape)
.init(&mut reset_pin, &mut delay)
.await
.unwrap();
display.clear_screen(0xF800).await.unwrap(); // Red§ESP32 Example (esp-hal + embassy)
ⓘ
use esp_hal::spi::master::{Config as SpiConfig, Spi};
use esp_hal::spi::Mode;
use esp_hal::gpio::{Level, Output};
use esp_hal::delay::Delay;
use sky_ili9341::{Builder, SpiInterface, presets};
use embedded_graphics_core::prelude::*;
use embedded_graphics_core::pixelcolor::Rgb565;
// Configure SPI at 40 MHz (ILI9341 max for most boards)
let spi = Spi::new(peripherals.SPI2, SpiConfig::default()
.with_frequency(40.MHz())
.with_mode(Mode::_0))
.with_sck(sclk)
.with_mosi(mosi)
.with_cs(cs);
let dc = Output::new(dc_pin, Level::Low);
let mut reset = Output::new(reset_pin, Level::High);
let mut delay = Delay::new();
// Use a board preset or configure manually
let di = SpiInterface::new(spi, dc);
let mut display = Builder::with_options(di, presets::skyrizz_e32())
.init(&mut reset, &mut delay)
.unwrap();
display.clear_screen(0x001F).unwrap(); // Blue§Using with embedded-graphics
Enable the graphics feature (on by default) and use standard drawing primitives:
ⓘ
use embedded_graphics_core::prelude::*;
use embedded_graphics_core::pixelcolor::Rgb565;
use embedded_graphics_core::primitives::{Rectangle, PrimitiveStyle};
use embedded_graphics_core::geometry::{Point, Size};
// DrawTarget is automatically implemented
display.clear(Rgb565::BLACK).unwrap();
// Solid fills are optimized — no per-pixel overhead
let rect = Rectangle::new(Point::new(10, 10), Size::new(100, 50));
display.fill_solid(&rect, Rgb565::RED).unwrap();§Architecture
The driver is organized into focused modules:
interface/ [interface_async] — Bus abstraction (ownInterfacetrait, notdisplay-interface)builder/ [builder_async] — Fluent configuration and initializationdisplay/ [display_async] — Core driver with drawing and display controloptions— Orientation, color order, inversion, and MADCTL encodingcommands— ILI9341 command opcodespresets— Ready-to-use configs for popular boardserror— Typed errors preserving the underlying bus error
Re-exports§
pub use builder::Builder;pub use display::Display;pub use error::Error;pub use interface::Interface;pub use interface::SpiInterface;pub use options::ColorInversion;pub use options::ColorOrder;pub use options::DisplayOptions;pub use options::HorizontalRefreshOrder;pub use options::Orientation;pub use options::VerticalRefreshOrder;
Modules§
Constants§
- SPI_
MODE - SPI mode for ILI9341 (CPOL=0, CPHA=0). Helper for CPOL = 0, CPHA = 0.