Expand description
§ESP-HUB75
A no-std Rust driver for HUB75-style LED matrix panels on ESP32-series
microcontrollers. HUB75 is a standard interface for driving large, bright,
and colorful RGB LED displays, commonly used in digital signage and art
installations.
This library provides a high-performance implementation that uses Direct Memory Access (DMA) to drive the display with minimal CPU overhead. It is designed to work with a variety of ESP32 models, using the most efficient peripheral available on each chip:
- ESP32-S3: Uses the LCD_CAM peripheral
- ESP32-C6: Uses the PARL_IO peripheral
- ESP32: Uses the I2S peripheral in parallel mode
§Usage
Here is an example of how to initialize the driver for an ESP32-S3:
//! Example for using the LCD/CAM driver with a HUB75 LED matrix display
//!
//! This example demonstrates how to use the LCD/CAM driver to drive a HUB75 LED
//! matrix display. It uses the ESP32's LCD/CAM peripheral in I8080 mode to send
//! data to the display.
#![no_std]
#![no_main]
#![allow(clippy::uninlined_format_args)]
#[cfg(feature = "defmt")]
use defmt_rtt as _;
use embedded_graphics::geometry::Point;
use embedded_graphics::mono_font::ascii::FONT_5X7;
use embedded_graphics::mono_font::MonoTextStyleBuilder;
use embedded_graphics::prelude::RgbColor;
use embedded_graphics::text::Alignment;
use embedded_graphics::text::Text;
use embedded_graphics::Drawable;
use esp_backtrace as _;
use esp_hal::clock::CpuClock;
use esp_hal::gpio::Pin;
use esp_hal::main;
use esp_hal::time::Rate;
use esp_hub75::framebuffer::compute_frame_count;
use esp_hub75::framebuffer::compute_rows;
use esp_hub75::framebuffer::plain::DmaFrameBuffer;
use esp_hub75::Color;
use esp_hub75::Hub75;
use esp_hub75::Hub75Pins16;
esp_bootloader_esp_idf::esp_app_desc!();
const ROWS: usize = 32;
const COLS: usize = 64;
const BITS: u8 = 4;
const NROWS: usize = compute_rows(ROWS);
const FRAME_COUNT: usize = compute_frame_count(BITS);
type FBType = DmaFrameBuffer<ROWS, COLS, NROWS, BITS, FRAME_COUNT>;
#[main]
fn main() -> ! {
let peripherals = esp_hal::init(esp_hal::Config::default().with_cpu_clock(CpuClock::max()));
let (_, tx_descriptors) = esp_hal::dma_descriptors!(0, FBType::dma_buffer_size_bytes());
let pins = Hub75Pins16 {
red1: peripherals.GPIO38.degrade(),
grn1: peripherals.GPIO42.degrade(),
blu1: peripherals.GPIO48.degrade(),
red2: peripherals.GPIO47.degrade(),
grn2: peripherals.GPIO2.degrade(),
blu2: peripherals.GPIO21.degrade(),
addr0: peripherals.GPIO14.degrade(),
addr1: peripherals.GPIO46.degrade(),
addr2: peripherals.GPIO13.degrade(),
addr3: peripherals.GPIO9.degrade(),
addr4: peripherals.GPIO3.degrade(),
blank: peripherals.GPIO11.degrade(),
clock: peripherals.GPIO12.degrade(),
latch: peripherals.GPIO10.degrade(),
};
let mut hub75 = Hub75::new_async(
peripherals.LCD_CAM,
pins,
peripherals.DMA_CH0,
tx_descriptors,
Rate::from_mhz(20),
)
.expect("failed to create Hub75!");
let mut fb = FBType::new();
let text_style = MonoTextStyleBuilder::new()
.font(&FONT_5X7)
.text_color(Color::YELLOW)
.background_color(Color::BLACK)
.build();
let point = Point::new(32, 31);
Text::with_alignment("Hello, World!", point, text_style, Alignment::Center)
.draw(&mut fb)
.expect("failed to draw text");
loop {
let xfer = hub75
.render(&fb)
.map_err(|(e, _hub75)| e)
.expect("failed to start render!");
let (result, new_hub75) = xfer.wait();
hub75 = new_hub75;
result.expect("transfer failed");
}
}§Crate Features
esp32: Enable support for the ESP32esp32s3: Enable support for the ESP32-S3esp32c6: Enable support for the ESP32-C6defmt: Enable logging withdefmtlog: Enable logging with thelogcrateinvert-blank: Invert the blank signal, required for some controller boards.invert-clock: Invert the clock signal. By default the driver outputs data that changes on the falling edge of CLK so that it is stable when the panel latches on the rising edge. Enable this feature if your panel requires the opposite polarity.skip-black-pixels: Forwards to thehub75-framebuffercrate, enabling an optimization that skips writing black pixels to the framebuffer.iram: Place the driver’s hot-path (render / DMA wait functions) in Instruction RAM (IRAM) to avoid flash-cache stalls (for example during Wi-Fi, PSRAM, or SPI-flash activity) that can cause visible flicker. Enabling this feature consumes roughly 5–10 KiB of IRAM.
§Safety
This crate uses unsafe code to interface with hardware peripherals, but it
exposes a safe, high-level API.
Re-exports§
pub use hub75_framebuffer as framebuffer;
Structs§
- Hub75
- HUB75 LED matrix display driver
- Hub75
Pins8 - Pin configuration for a HUB75 panel with an external address latch.
- Hub75
Pins16 - Pin configuration for a HUB75 panel without an external address latch.
- Hub75
Transfer - Represents an in-progress transfer to the HUB75 display
Enums§
- Hub75
Error - Represents errors that can occur during HUB75 driver operations.
Traits§
- Hub75
Pins - A trait for converting a set of HUB75 pins into the required format for a specific ESP32 peripheral.
Type Aliases§
- Color
- The color type used by the HUB75 driver. Color type used in the framebuffer