From 52719e4be280b5dfb301da72fafe43c475376052 Mon Sep 17 00:00:00 2001 From: Richard Barnes Date: Fri, 10 Oct 2025 15:57:32 -1000 Subject: [PATCH 1/3] Move to mipidsi --- ui-stm32/Cargo.toml | 4 +- ui-stm32/src/board/ev13.rs | 130 ++++++++++--------------------------- 2 files changed, 36 insertions(+), 98 deletions(-) diff --git a/ui-stm32/Cargo.toml b/ui-stm32/Cargo.toml index 84a5b2f..8393227 100644 --- a/ui-stm32/Cargo.toml +++ b/ui-stm32/Cargo.toml @@ -30,11 +30,13 @@ heapless = { version = "0.9.1", features = ["defmt"] } embedded-io-async = "0.6.1" embedded-io = { version = "0.6.1", default-features = false } ili9341 = "0.6.0" -display-interface = "0.5.0" embedded-graphics-core = { version = "0.4.0", default-features = false } bitmap-font = "0.3.0" embedded-graphics = "0.8.1" embedded-hal = { version = "1.0.0", default-features = false } +mipidsi = "0.9.0" +embassy-embedded-hal = "0.5.0" +static_cell = "2.1.1" [profile.release] debug = 2 diff --git a/ui-stm32/src/board/ev13.rs b/ui-stm32/src/board/ev13.rs index 1bb6d28..bd26389 100644 --- a/ui-stm32/src/board/ev13.rs +++ b/ui-stm32/src/board/ev13.rs @@ -1,5 +1,6 @@ use super::{Button, Eeprom, Keyboard, NetTx, StatusLed}; -use display_interface::{DataFormat, DisplayError, WriteOnlyDataCommand}; +use core::cell::RefCell; +use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice; use embassy_stm32::{ bind_interrupts, exti::ExtiInput, @@ -7,108 +8,37 @@ use embassy_stm32::{ i2c::{mode::Master, I2c}, mode::{Async, Blocking}, peripherals, - spi::{Spi, Word}, + spi::Spi, usart::{self, UartRx, UartTx}, }; +use embassy_sync::blocking_mutex::{raw::NoopRawMutex, NoopMutex}; use embassy_time::Delay; use embedded_graphics::{pixelcolor::Rgb565, prelude::*}; -use ili9341::{Ili9341, Orientation}; +use mipidsi::{ + interface::SpiInterface, + models::ILI9341Rgb565, + options::{ColorOrder, Orientation}, + Builder, Display, +}; +use static_cell::StaticCell; use ui_app::{Led, Outputs}; -struct DisplayData { - // These fields are not used, but we need to keep them alive so that the chip select output is - // held low and the backlight output is held high. - _chip_select: Output<'static>, - _backlight: Output<'static>, - - data_command: Output<'static>, - spi: Spi<'static, Blocking>, -} - -impl DisplayData { - fn new( - mut backlight: Output<'static>, - mut chip_select: Output<'static>, - data_command: Output<'static>, - spi: Spi<'static, Blocking>, - ) -> Self { - backlight.set_high(); - chip_select.set_low(); - - Self { - _backlight: backlight, - _chip_select: chip_select, - data_command, - spi, - } - } - - fn write(&mut self, data: DataFormat<'_>) -> Result<(), DisplayError> { - use DataFormat::*; - match data { - U8(slice) => self.write_slice(slice), - U16(slice) => self.write_slice(slice), - U16BE(slice) => self.write_slice(slice), - U16LE(slice) => self.write_slice(slice), - U8Iter(iter) => self.write_iter(iter), - U16BEIter(iter) => self.write_iter(iter), - U16LEIter(iter) => self.write_iter(iter), - _ => unreachable!(), - } - } - - fn write_slice(&mut self, data: &[W]) -> Result<(), DisplayError> { - self.spi.blocking_write(data).unwrap(); - Ok(()) - } - - fn write_iter( - &mut self, - iter: &mut dyn Iterator, - ) -> Result<(), DisplayError> { - // 1kb of render buffer - const CHUNK_SIZE: usize = 512; - - // XXX(RLB) Very C-style iteration, could probably write this in a way that would optimize - // better. - let mut data = [W::default(); CHUNK_SIZE]; - let mut n = 0; - for (i, x) in iter.enumerate() { - data[i % CHUNK_SIZE] = x; - n += 1; - - if n > 0 && n % CHUNK_SIZE == 0 { - self.spi.blocking_write(&data).unwrap(); - n = 0; - } - } - - self.spi.blocking_write(&data[..n]).unwrap(); - Ok(()) - } -} - -impl WriteOnlyDataCommand for DisplayData { - fn send_commands(&mut self, cmd: DataFormat<'_>) -> Result<(), DisplayError> { - self.data_command.set_low(); - self.write(cmd) - } - - fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> { - self.data_command.set_high(); - self.write(buf) - } -} +type DisplaySpiDevice = SpiDevice<'static, NoopRawMutex, Spi<'static, Blocking>, Output<'static>>; +type DisplaySpiInterface = SpiInterface<'static, DisplaySpiDevice, Output<'static>>; pub struct Board { status_led: StatusLed, - screen: Ili9341>, + screen: Display>, net_tx: NetTx>, i2c: I2c<'static, Blocking, Master>, pub button_a: Option