#screen #oled #async #spi #frame-buffer

ssd1322_rs

SSD1322 OLED屏幕的异步Rust驱动程序

2个不稳定版本

新增 0.2.0 2024年8月23日
0.1.0 2024年8月2日

374嵌入式开发

Download history 77/week @ 2024-07-28 18/week @ 2024-08-04 1/week @ 2024-08-11 79/week @ 2024-08-18

175 每月下载量

MIT/Apache

51KB
553

ssd1322_rs

目录

关于

ssd1322_rs 是一个针对SSD1322 OLED屏幕的异步Rust驱动程序,专门为嵌入式系统设计。它提供了一个易于使用的、非阻塞的接口来与显示屏交互,非常适合与DMA一起使用。

ssd1322_rs 驱动程序的创建是为了填补SSD1322 OLED屏幕异步驱动程序的生态空白。该项目借鉴了现有的 ssd1322 crate,但将设计从同步改为异步。它还改变了设计理念,从使用迭代器模式(最小化内存使用)改为使用固定静态缓冲区(当启用 frame 功能时),这允许DMA执行繁重的工作并最小化传输数据时CPU的时间。

为了参考,我为创建这个crate的屏幕是256x64像素的屏幕。由于SSD1322使用4bpp,这意味着要传输的总字节数是

$$ 总字节数 = 128×64=8192 \ 总比特数 = 8192b × (8bits/byte)=65536 $$

以10MHz的速度运行SPI总线,这将产生

$$ 时间_s = \frac{总比特数}{SPI时钟速度} = \frac{65535 \ 比特}{10,000,000 \ 比特/秒} = 0.0065536 \ 秒 $$

因此 $$ 时间_{ms} =0.0065536秒×1000毫秒/秒 = 6.5536 \ 毫秒 $$

在没有DMA的情况下执行此操作的性能影响对我们应用程序来说太大,因此创建了此crate,该crate专注于性能吞吐量,以牺牲内存效率(尽管如此,仍然没有分配或堆内存!)。

功能

  • 异步API:使用Rust的async/await语法进行非阻塞操作。
  • 仅支持SPI通信协议(如果想要添加其他通信方法,请随时提交拉取请求!)。
  • 简单和复杂API:默认设置处理了通常的配置,提供了命令选项来手动配置屏幕。
  • 无标准库:适用于 #![no_std] 环境。
  • 无alloc
  • 最小依赖项:仅依赖于嵌入式hal crates(可选支持 embedded_graphics,可以通过 default-features=false 禁用)
  • 可选的 frame 缓冲区(支持 embedded_graphics 以简化将屏幕处理为固定大小的缓冲区)

用法

以下代码是设置屏幕的示例。此代码以 STM32H745 上的 embassy 为例,但此 crate 与执行器无关,因此可以使用任何异步运行时。任何支持 SPI 的芯片也兼容。

    use ssd1322_rs::{Orientation, SSD1322};

    let mut spi_config = spi::Config::default();
    spi_config.frequency = mhz(10);

    // Create an SPI instance, we only need TX for this library
    let spi_p = spi::Spi::new_txonly(
        screen.spi,
        screen.sck,
        screen.mosi,
        screen.dma_tx,
        spi_config,
    );

    // Reset pin required to hard reset and initilaise the screen
    let reset = Output::new(screen.reset, Level::Low, Speed::Low);
    //Power on the screen
    let scr_power = Output::new(screen.pwr, Level::Low, Speed::Low);
    // Control command/data mode
    let data_command_pin = Output::new(screen.dc, Level::Low, Speed::Medium);

    // Chip select
    let cs_pin = Output::new(screen.cs, Level::Low, Speed::Medium);

    // Create an Exclusive device from the from the embedded_hal, for SPI busses with only one other device on.
    let spi_dev = ExclusiveDevice::new_no_delay(spi_p, cs_pin).unwrap();

    // Create a display handle
    let mut display = SSD1322::new(
        spi_dev,
        data_command_pin,
        reset,
        scr_power,
        Default::default(),
    );

    // Initialise the display. This calls the reset procedue and then sends the neccesary commands to set up the display
    display.init_default(&mut Delay).await.unwrap();

要使用显示屏,您可以选择使用或不用帧支持。在此示例中,我们将使用内置的默认帧支持将帧刷新到显示屏

use ssd1322_rs::{calculate_buffer_size, Frame, Orientation, SSD1322};
use static_cell::StaticCell;

const SCREEN_WIDTH: usize = 256;
const SCREEN_HEIGHT: usize = 64;
const BUF_SIZE: usize = calculate_buffer_size(SCREEN_WIDTH, SCREEN_HEIGHT);

static FRAME_A: StaticCell<Frame<BUF_SIZE>> = StaticCell::new();

let frame = FRAME_A.init(Default::default());
//Draw some stuff into the buffer
//embedded_graphics::Text::with_alignment("hello world", Point::new(128, 12), MonoTextStyle::new(&FONT_10X20, Gray4::WHITE), Alignment::Center).draw(frame).unwrap();
display.flush_frame(&frame).await.ok();

示例

请查看 示例 文件夹,了解如何在项目中使用 async-ssd1322 驱动程序的实际演示。

致谢

向受此启发的各种 crates 致敬,并向整个嵌入式 Rust 社区致敬

原始 ssd1322 crate - 这对如何使用 SSD1322 上的命令是一个很好的参考。

st7735-embassy - 主要结构(和帧缓冲区)深受此 crate 的设计架构启发

embassy - Embassy 项目是对嵌入式 Rust 生态系统的一项了不起的贡献,并且是运行嵌入式设备上异步代码的事实标准。

拉取请求

欢迎为添加功能、功能或错误修复提交拉取请求!

依赖关系

~170KB