//! Create and initialize ST7789 display driver // use display_interface_spi::SPIInterface; use embedded_hal_bus::spi::ExclusiveDevice; use mipidsi::{ Builder, Display as MipiDisplay, interface::SpiInterface, models::ST7789, options::{ColorInversion, Orientation}, }; use thiserror::Error; pub struct Display {} type Drawable<'a> = MipiDisplay< SpiInterface< 'a, ExclusiveDevice< esp_hal::spi::master::Spi<'a, esp_hal::Blocking>, esp_hal::gpio::Output<'a>, esp_hal::delay::Delay, >, esp_hal::gpio::Output<'a>, >, ST7789, esp_hal::gpio::Output<'a>, >; /// Display width pub const DISPLAY_SIZE_WIDTH: u16 = 240; /// Display height pub const DISPLAY_SIZE_HEIGHT: u16 = 135; pub const DISPLAY_BUFFER_SIZE: usize = DISPLAY_SIZE_WIDTH as usize * DISPLAY_SIZE_HEIGHT as usize * 2; #[derive(Debug, Error)] pub enum BuildError { #[error("SPI config error: {0}")] SpiConfigError(#[from] esp_hal::spi::master::ConfigError), #[error("Some error occurred when initialising the MIPI DSI display")] MipidsiInitError, #[error("SPI error: {0:?}")] SpiError(esp_hal::spi::Error), } pub fn build<'a>( spi: esp_hal::peripherals::SPI2<'a>, sck: esp_hal::peripherals::GPIO36<'a>, dc: esp_hal::peripherals::GPIO35<'a>, cs: esp_hal::peripherals::GPIO37<'a>, rs: esp_hal::peripherals::GPIO34<'a>, rst: esp_hal::peripherals::GPIO33<'a>, ) -> Result, BuildError> { static mut DISPLAY_BUFFER: [u8; 1000] = [0; 1000]; // let spi_config = SpiConfig::new().baudrate(80.MHz().into()); // let device_config = DriverConfig::new(); // let spi = SpiDeviceDriver::new_single( // spi, // sck, // dc, // Option::::None, // Some(cs), // &device_config, // &spi_config, // )?; let spi = esp_hal::spi::master::Spi::new( spi, esp_hal::spi::master::Config::default().with_frequency(esp_hal::time::Rate::from_mhz(80)), )? .with_sck(sck) .with_mosi(dc); let Ok(spi) = ExclusiveDevice::new( spi, esp_hal::gpio::Output::new( cs, esp_hal::gpio::Level::Low, esp_hal::gpio::OutputConfig::default(), ), esp_hal::delay::Delay::new(), ); let rs = esp_hal::gpio::Output::new( rs, esp_hal::gpio::Level::Low, esp_hal::gpio::OutputConfig::default(), ); let rst = esp_hal::gpio::Output::new( rst, esp_hal::gpio::Level::Low, esp_hal::gpio::OutputConfig::default(), ); #[allow(static_mut_refs)] let mut drawable = Builder::new( ST7789, SpiInterface::new(spi, rs, unsafe { DISPLAY_BUFFER.as_mut_slice() }), ) //st7789(SpiInterface::new(spi, rs)) .invert_colors(ColorInversion::Inverted) .display_size(DISPLAY_SIZE_HEIGHT, DISPLAY_SIZE_WIDTH) // deliberately reversed order .display_offset(40, 53) .reset_pin(rst) .init(&mut esp_hal::delay::Delay::new()) .map_err(|_| BuildError::MipidsiInitError)?; // Can't capture the error since it's a public type // in a private module and not re-exported. The master // branch of the mipidsi repo does have a fix but it's // not had a crates.io release yet. drawable .set_orientation(Orientation::new().rotate(mipidsi::options::Rotation::Deg90)) .map_err(|e| match e { mipidsi::interface::SpiError::Spi(e) => match e { embedded_hal_bus::spi::DeviceError::Spi(e) => BuildError::SpiError(e), embedded_hal_bus::spi::DeviceError::Cs(e) => match e {}, }, mipidsi::interface::SpiError::Dc(e) => match e {}, })?; drawable .set_vertical_scroll_offset(0) .map_err(|e| match e { mipidsi::interface::SpiError::Spi(e) => match e { embedded_hal_bus::spi::DeviceError::Spi(e) => BuildError::SpiError(e), embedded_hal_bus::spi::DeviceError::Cs(e) => match e {}, }, mipidsi::interface::SpiError::Dc(e) => match e {}, })?; Ok(drawable) }