use display_interface::{DataFormat, WriteOnlyDataCommand};
use embedded_graphics_core::{
pixelcolor::{Rgb565, Rgb666},
prelude::{IntoStorage, RgbColor},
};
use embedded_hal::{delay::DelayNs, digital::OutputPin};
use crate::{
dcs::{
BitsPerPixel, Dcs, EnterNormalMode, ExitSleepMode, PixelFormat, SetAddressMode,
SetDisplayOn, SetInvertMode, SetPixelFormat, SoftReset, WriteMemoryStart,
},
error::{Error, InitError},
options::ModelOptions,
};
use super::Model;
pub struct ILI9486Rgb565;
pub struct ILI9486Rgb666;
impl Model for ILI9486Rgb565 {
type ColorFormat = Rgb565;
const FRAMEBUFFER_SIZE: (u16, u16) = (320, 480);
fn init<RST, DELAY, DI>(
&mut self,
dcs: &mut Dcs<DI>,
delay: &mut DELAY,
options: &ModelOptions,
rst: &mut Option<RST>,
) -> Result<SetAddressMode, InitError<RST::Error>>
where
RST: OutputPin,
DELAY: DelayNs,
DI: WriteOnlyDataCommand,
{
match rst {
Some(ref mut rst) => self.hard_reset(rst, delay)?,
None => dcs.write_command(SoftReset)?,
}
delay.delay_us(120_000);
let pf = PixelFormat::with_all(BitsPerPixel::from_rgb_color::<Self::ColorFormat>());
Ok(init_common(dcs, delay, options, pf)?)
}
fn write_pixels<DI, I>(&mut self, dcs: &mut Dcs<DI>, colors: I) -> Result<(), Error>
where
DI: WriteOnlyDataCommand,
I: IntoIterator<Item = Self::ColorFormat>,
{
dcs.write_command(WriteMemoryStart)?;
let mut iter = colors.into_iter().map(|c| c.into_storage());
let buf = DataFormat::U16BEIter(&mut iter);
dcs.di.send_data(buf)
}
}
impl Model for ILI9486Rgb666 {
type ColorFormat = Rgb666;
const FRAMEBUFFER_SIZE: (u16, u16) = (320, 480);
fn init<RST, DELAY, DI>(
&mut self,
dcs: &mut Dcs<DI>,
delay: &mut DELAY,
options: &ModelOptions,
rst: &mut Option<RST>,
) -> Result<SetAddressMode, InitError<RST::Error>>
where
RST: OutputPin,
DELAY: DelayNs,
DI: WriteOnlyDataCommand,
{
match rst {
Some(ref mut rst) => self.hard_reset(rst, delay)?,
None => dcs.write_command(SoftReset)?,
};
delay.delay_us(120_000);
let pf = PixelFormat::with_all(BitsPerPixel::from_rgb_color::<Self::ColorFormat>());
Ok(init_common(dcs, delay, options, pf)?)
}
fn write_pixels<DI, I>(&mut self, dcs: &mut Dcs<DI>, colors: I) -> Result<(), Error>
where
DI: WriteOnlyDataCommand,
I: IntoIterator<Item = Self::ColorFormat>,
{
dcs.write_command(WriteMemoryStart)?;
let mut iter = colors.into_iter().flat_map(|c| {
let red = c.r() << 2;
let green = c.g() << 2;
let blue = c.b() << 2;
[red, green, blue]
});
let buf = DataFormat::U8Iter(&mut iter);
dcs.di.send_data(buf)
}
}
fn init_common<DELAY, DI>(
dcs: &mut Dcs<DI>,
delay: &mut DELAY,
options: &ModelOptions,
pixel_format: PixelFormat,
) -> Result<SetAddressMode, Error>
where
DELAY: DelayNs,
DI: WriteOnlyDataCommand,
{
let madctl = SetAddressMode::from(options);
dcs.write_command(ExitSleepMode)?; dcs.write_command(SetPixelFormat::new(pixel_format))?; dcs.write_command(madctl)?; dcs.write_command(SetInvertMode::new(options.invert_colors))?;
dcs.write_raw(0xB6, &[0b0000_0010, 0x02, 0x3B])?; dcs.write_command(EnterNormalMode)?; dcs.write_command(SetDisplayOn)?; delay.delay_us(120_000);
Ok(madctl)
}