extern crate libm;
use hal;
use command::{BufCommand, Command, DeepSleepMode};
use config::Config;
use interface::DisplayInterface;
pub const MAX_GATE_OUTPUTS: u16 = 296;
pub const MAX_SOURCE_OUTPUTS: u8 = 160;
const ANALOG_BLOCK_CONTROL_MAGIC: u8 = 0x54;
const DIGITAL_BLOCK_CONTROL_MAGIC: u8 = 0x3B;
pub struct Dimensions {
pub rows: u16,
pub cols: u8,
}
#[derive(Clone, Copy)]
pub enum Rotation {
Rotate0,
Rotate90,
Rotate180,
Rotate270,
}
impl Default for Rotation {
fn default() -> Self {
Rotation::Rotate0
}
}
pub struct Display<'a, I>
where
I: DisplayInterface,
{
interface: I,
config: Config<'a>,
}
impl<'a, I> Display<'a, I>
where
I: DisplayInterface,
{
pub fn new(interface: I, config: Config<'a>) -> Self {
Self { interface, config }
}
pub fn reset<D: hal::blocking::delay::DelayMs<u8>>(
&mut self,
delay: &mut D,
) -> Result<(), I::Error> {
self.interface.reset(delay);
Command::SoftReset.execute(&mut self.interface)?;
self.interface.busy_wait();
self.init()
}
fn init(&mut self) -> Result<(), I::Error> {
Command::AnalogBlockControl(ANALOG_BLOCK_CONTROL_MAGIC).execute(&mut self.interface)?;
Command::DigitalBlockControl(DIGITAL_BLOCK_CONTROL_MAGIC).execute(&mut self.interface)?;
Command::DriverOutputControl(self.config.dimensions.rows, 0x00)
.execute(&mut self.interface)?;
self.config.dummy_line_period.execute(&mut self.interface)?;
self.config.gate_line_width.execute(&mut self.interface)?;
self.config.write_vcom.execute(&mut self.interface)?;
if let Some(ref write_lut) = self.config.write_lut {
write_lut.execute(&mut self.interface)?;
}
self.config.data_entry_mode.execute(&mut self.interface)?;
let end = self.config.dimensions.cols / 8 - 1;
Command::StartEndXPosition(0, end).execute(&mut self.interface)?;
Command::StartEndYPosition(0, self.config.dimensions.rows).execute(&mut self.interface)?;
Ok(())
}
pub fn update<D: hal::blocking::delay::DelayMs<u8>>(
&mut self,
black: &[u8],
red: &[u8],
delay: &mut D,
) -> Result<(), I::Error> {
let buf_limit = libm::ceilf((self.rows() * self.cols() as u16) as f32 / 8.) as usize;
Command::XAddress(0).execute(&mut self.interface)?;
Command::YAddress(0).execute(&mut self.interface)?;
BufCommand::WriteBlackData(&black[..buf_limit]).execute(&mut self.interface)?;
Command::XAddress(0).execute(&mut self.interface)?;
Command::YAddress(0).execute(&mut self.interface)?;
BufCommand::WriteRedData(&red[..buf_limit]).execute(&mut self.interface)?;
Command::UpdateDisplayOption2(0xC7).execute(&mut self.interface)?;
Command::UpdateDisplay.execute(&mut self.interface)?;
delay.delay_ms(50);
self.interface.busy_wait();
Ok(())
}
pub fn deep_sleep(&mut self) -> Result<(), I::Error> {
Command::DeepSleepMode(DeepSleepMode::PreserveRAM).execute(&mut self.interface)
}
pub fn rows(&self) -> u16 {
self.config.dimensions.rows
}
pub fn cols(&self) -> u8 {
self.config.dimensions.cols
}
pub fn rotation(&self) -> Rotation {
self.config.rotation
}
}