Skip to content

decaday/display-driver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

88 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

display-driver

Crates.io Crates.io docs.rs

An Async display driver framework designed to provide a unified interface for various LCD panels.

Features

  • Async-Native: Built from the ground up with first-class async/await support.

  • Bus / Interface Layer: Unlike simple byte-stream interfaces, display-driver is designed for complex communication requirements. Features include atomic commands, stream payload classification, ROI-aware transfers, duplex operations, and hardware-accelerated fill. While this architecture is crucial for supporting advanced interfaces like MIPI DSI, QSPI, or hardware with 2D graphics acceleration, it also ensures high performance for simple buses like SPI.

  • Panel Logic Layer:

    • MIPI DCS Standard: Simplifies driver implementation for common controllers (e.g., ST77xx, ILI9xxx).
    • Zero-Cost Polymorphism: Leverages the Spec trait for static configuration (e.g., Gamma curves) without runtime overhead. This system includes built-in presets (e.g., ST7735 Generic_128x128_Type1) while fully supporting custom Spec implementations, and automatically handles coordinate offsets across different rotations.
    • Static Init Sequences: Uses statically computed initialization sequences to minimize Flash/RAM usage—vital for async state machines.

Peek

use display_driver::{ColorFormat, DisplayDriver, Orientation, LCDResetOption};
// The `Spec` (Generic128x160Type1) defines the hardware-specific constants (Gamma, Voltage).
use display_driver_st7735::{St7735, spec::generic::Generic128x160Type1};

// 1. Configure Reset
let reset_opt = LCDResetOption::new_pin(reset_pin);

// 2. Create the Panel instance using a Generic Spec (e.g., Generic128x160Type1)
let panel = St7735::<Generic128x160Type1, _, _>::new(reset_opt);

// 3. Bind Bus and Panel, Configure, and Initialize
// The driver orchestrates the logic, delegating transport to 'bus' and commands to 'panel'.
let mut display = DisplayDriver::builder(bus, panel)
    .with_color_format(ColorFormat::RGB565)
    // This framework automatically handles offsets.
    .with_orientation(Orientation::Deg90)
    .init(&mut delay).await.unwrap();

// Now you can use `display` to draw:
display.write_frame(fb).await.unwrap();

Display Bus Implementations

  • spi: SPI bus implementation.

  • SF32 LCDC: Bus Implementation for SF32LB52x LCDC Hardware.

Display Panel Implementations

  • mipidcs: Common impl for standard MIPI DCS.

  • st7735: ST7735, commonly used in TFT LCD.

  • st7789: ST7789, commonly used in TFT LCD.

  • gc9a01: GC9A01, commonly used in round screens.

  • co5300: CO5300, commonly used in AMOLED.

Examples

check Examples for more.

Display framework

  • embedded-graphics

    DisplayDriver is optimized for asynchronous, batched transfers and does not implement embedded-graphics's DrawTarget directly. For framebuffer-based drawing, wrap it in FrameBufferedDisplayDriver. The wrapper implements DrawTarget, so embedded-graphics primitives can draw into the framebuffer and then be transferred to the panel asynchronously.

    // Import...
    let mut framebuffer: Framebuffer<
        Rgb565,
        RawU16,
        BigEndian,
        WIDTH,
        HEIGHT,
        { embedded_graphics::framebuffer::buffer_size::<Rgb565>(WIDTH, HEIGHT) },
    > = Framebuffer::new();
    
    let mut display = FrameBufferedDisplayDriver::new(driver, &mut framebuffer);
    display.clear(Rgb565::BLACK)?;
    // Draw embedded-graphics primitives with `&mut display`.
    display.flush().await?;

    For a framebuffer that represents a screen sub-region, use new_partial(driver, area, &mut framebuffer); its Area dimensions must exactly match the framebuffer dimensions. set_area can move that region later under the same constraint.

    Use flush_lines to transfer an inclusive range of framebuffer rows, or the *_with_frame_control variants when coordinating multi-part writes, double buffering, or TE synchronization. See the Examples for complete targets.

  • Slint

    A Slint example for SF32 is also available.

TODOs

  • Other Driver ICs and Panels

  • Use Macros to replace InitStep::maybe_cmd_with

  • Tearing Effect Control

License

This project is under Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0).

About

Rust Async Display Driver

Resources

License

Stars

11 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages