use display_interface::{AsyncWriteOnlyDataCommand, DataFormat, DisplayError};
use crate::{command::Command, display::DisplayVariant, displayrotation::DisplayRotation};
pub struct DisplayProperties<DV, DI> {
_variant: DV,
iface: DI,
display_rotation: DisplayRotation,
draw_area_start: (u8, u8),
draw_area_end: (u8, u8),
draw_column: u8,
draw_row: u8,
}
impl<DV, DI> DisplayProperties<DV, DI>
where
DI: AsyncWriteOnlyDataCommand,
DV: DisplayVariant,
{
pub fn new(
variant: DV,
iface: DI,
display_rotation: DisplayRotation,
) -> DisplayProperties<DV, DI> {
DisplayProperties {
_variant: variant,
iface,
display_rotation,
draw_area_start: (0, 0),
draw_area_end: (0, 0),
draw_column: 0,
draw_row: 0,
}
}
pub async fn init_column_mode(&mut self) -> Result<(), DisplayError> {
let display_rotation = self.display_rotation;
DV::init_column_mode(&mut self.iface).await?;
self.set_rotation(display_rotation).await?;
Ok(())
}
pub async fn set_draw_area(
&mut self,
start: (u8, u8),
end: (u8, u8),
) -> Result<(), DisplayError> {
self.draw_area_start = start;
self.draw_area_end = end;
self.draw_column = start.0;
self.draw_row = start.1;
self.send_draw_address().await
}
pub async fn draw(&mut self, mut buffer: &[u8]) -> Result<(), DisplayError> {
while !buffer.is_empty() {
let count = self.draw_area_end.0 - self.draw_column;
self.iface
.send_data(DataFormat::U8(&buffer[..count as usize]))
.await?;
self.draw_column += count;
if self.draw_column >= self.draw_area_end.0 {
self.draw_column = self.draw_area_start.0;
self.draw_row += 1;
if self.draw_row >= self.draw_area_end.1 {
self.draw_row = self.draw_area_start.1;
}
self.send_draw_address().await?;
}
buffer = &buffer[count as usize..];
}
Ok(())
}
async fn send_draw_address(&mut self) -> Result<(), DisplayError> {
if DV::LARGE_PAGE_ADDRESS {
Command::LargePageAddress(self.draw_row.into())
.send(&mut self.iface)
.await?;
} else {
Command::PageAddress(self.draw_row.into())
.send(&mut self.iface)
.await?;
}
Command::ColumnAddressLow(0xF & self.draw_column)
.send(&mut self.iface)
.await?;
Command::ColumnAddressHigh(0xF & (self.draw_column >> 4))
.send(&mut self.iface)
.await
}
pub fn get_dimensions(&self) -> (u8, u8) {
let (w, h) = DV::dimensions();
match self.display_rotation {
DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => (w, h),
DisplayRotation::Rotate90 | DisplayRotation::Rotate270 => (h, w),
}
}
pub fn get_rotation(&self) -> DisplayRotation {
self.display_rotation
}
pub async fn set_rotation(
&mut self,
display_rotation: DisplayRotation,
) -> Result<(), DisplayError> {
self.display_rotation = display_rotation;
match display_rotation {
DisplayRotation::Rotate0 => {
Command::SegmentRemap(true).send(&mut self.iface).await?;
Command::ReverseComDir(true).send(&mut self.iface).await
}
DisplayRotation::Rotate90 => {
Command::SegmentRemap(false).send(&mut self.iface).await?;
Command::ReverseComDir(true).send(&mut self.iface).await
}
DisplayRotation::Rotate180 => {
Command::SegmentRemap(false).send(&mut self.iface).await?;
Command::ReverseComDir(false).send(&mut self.iface).await
}
DisplayRotation::Rotate270 => {
Command::SegmentRemap(true).send(&mut self.iface).await?;
Command::ReverseComDir(false).send(&mut self.iface).await
}
}
}
pub async fn display_on(&mut self, on: bool) -> Result<(), DisplayError> {
Command::DisplayOn(on).send(&mut self.iface).await
}
pub async fn set_contrast(&mut self, contrast: u8) -> Result<(), DisplayError> {
Command::Contrast(contrast).send(&mut self.iface).await
}
}