use display_interface::{DataFormat, WriteOnlyDataCommand}; use embedded_graphics_core::{pixelcolor::Rgb565, prelude::IntoStorage}; use embedded_hal::{delay::DelayNs, digital::OutputPin}; use mipidsi::{ dcs::{ BitsPerPixel, Dcs, EnterNormalMode, ExitSleepMode, PixelFormat, SetAddressMode, SetDisplayOn, SetInvertMode, SetPixelFormat, SoftReset, WriteMemoryStart, }, error::{Error, InitError}, models::Model, options::ModelOptions, }; /// Copy of the ST7789 driver to check if it can also be implemented in another /// crate. pub struct ExternalST7789; impl Model for ExternalST7789 { type ColorFormat = Rgb565; const FRAMEBUFFER_SIZE: (u16, u16) = (240, 320); fn init( &mut self, dcs: &mut Dcs, delay: &mut DELAY, options: &ModelOptions, rst: &mut Option, ) -> Result> where RST: OutputPin, DELAY: DelayNs, DI: WriteOnlyDataCommand, { let madctl = SetAddressMode::from(options); match rst { Some(ref mut rst) => self.hard_reset(rst, delay)?, None => dcs.write_command(SoftReset)?, } delay.delay_us(150_000); dcs.write_command(ExitSleepMode)?; delay.delay_us(10_000); // set hw scroll area based on framebuffer size dcs.write_command(madctl)?; dcs.write_command(SetInvertMode::new(options.invert_colors))?; let pf = PixelFormat::with_all(BitsPerPixel::from_rgb_color::()); dcs.write_command(SetPixelFormat::new(pf))?; delay.delay_us(10_000); dcs.write_command(EnterNormalMode)?; delay.delay_us(10_000); dcs.write_command(SetDisplayOn)?; // DISPON requires some time otherwise we risk SPI data issues delay.delay_us(120_000); Ok(madctl) } fn write_pixels(&mut self, dcs: &mut Dcs, colors: I) -> Result<(), Error> where DI: WriteOnlyDataCommand, I: IntoIterator, { dcs.write_command(WriteMemoryStart)?; let mut iter = colors.into_iter().map(Rgb565::into_storage); let buf = DataFormat::U16BEIter(&mut iter); dcs.di.send_data(buf)?; Ok(()) } }