132 lines
4.1 KiB
Rust
132 lines
4.1 KiB
Rust
//! 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<Drawable<'a>, 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::<AnyIOPin>::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)
|
|
}
|