#![no_std]
use embedded_hal::digital::v2::OutputPin;
pub use display_interface::{DataFormat, DisplayError, WriteOnlyDataCommand};
pub struct PGPIO8BitInterface<P0, P1, P2, P3, P4, P5, P6, P7, DC, WR> {
p0: P0,
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
dc: DC,
wr: WR,
last: u8,
}
impl<P0, P1, P2, P3, P4, P5, P6, P7, DC, WR>
PGPIO8BitInterface<P0, P1, P2, P3, P4, P5, P6, P7, DC, WR>
where
P0: OutputPin,
P1: OutputPin,
P2: OutputPin,
P3: OutputPin,
P4: OutputPin,
P5: OutputPin,
P6: OutputPin,
P7: OutputPin,
DC: OutputPin,
WR: OutputPin,
{
#[allow(clippy::too_many_arguments)]
pub fn new(
p0: P0,
p1: P1,
p2: P2,
p3: P3,
p4: P4,
p5: P5,
p6: P6,
p7: P7,
dc: DC,
wr: WR,
) -> Self {
Self {
p0,
p1,
p2,
p3,
p4,
p5,
p6,
p7,
dc,
wr,
last: 0,
}
}
pub fn release(self) -> (P0, P1, P2, P3, P4, P5, P6, P7, DC, WR) {
(
self.p0, self.p1, self.p2, self.p3, self.p4, self.p5, self.p6, self.p7, self.dc,
self.wr,
)
}
fn set_value(self: &mut Self, value: u8) -> Result<(), DisplayError> {
let changed = value ^ self.last;
if changed == 0 {
return Ok(());
}
self.last = value;
if changed & 1 != 0 {
if value & 1 != 0 {
self.p0.set_high()
} else {
self.p0.set_low()
}
.map_err(|_| DisplayError::BusWriteError)?
};
if changed & 2 != 0 {
if value & 2 != 0 {
self.p1.set_high()
} else {
self.p1.set_low()
}
.map_err(|_| DisplayError::BusWriteError)?
};
if changed & 4 != 0 {
if value & 4 != 0 {
self.p2.set_high()
} else {
self.p2.set_low()
}
.map_err(|_| DisplayError::BusWriteError)?
};
if changed & 8 != 0 {
if value & 8 != 0 {
self.p3.set_high()
} else {
self.p3.set_low()
}
.map_err(|_| DisplayError::BusWriteError)?
};
if changed & 16 != 0 {
if value & 16 != 0 {
self.p4.set_high()
} else {
self.p4.set_low()
}
.map_err(|_| DisplayError::BusWriteError)?
};
if changed & 32 != 0 {
if value & 32 != 0 {
self.p5.set_high()
} else {
self.p5.set_low()
}
.map_err(|_| DisplayError::BusWriteError)?
};
if changed & 64 != 0 {
if value & 64 != 0 {
self.p6.set_high()
} else {
self.p6.set_low()
}
.map_err(|_| DisplayError::BusWriteError)?
};
if changed & 128 != 0 {
if value & 128 != 0 {
self.p7.set_high()
} else {
self.p7.set_low()
}
.map_err(|_| DisplayError::BusWriteError)?
};
Ok(())
}
}
impl<P0, P1, P2, P3, P4, P5, P6, P7, DC, WR> WriteOnlyDataCommand
for PGPIO8BitInterface<P0, P1, P2, P3, P4, P5, P6, P7, DC, WR>
where
P0: OutputPin,
P1: OutputPin,
P2: OutputPin,
P3: OutputPin,
P4: OutputPin,
P5: OutputPin,
P6: OutputPin,
P7: OutputPin,
DC: OutputPin,
WR: OutputPin,
{
fn send_commands(&mut self, cmds: DataFormat<'_>) -> Result<(), DisplayError> {
use byte_slice_cast::*;
self.dc.set_low().map_err(|_| DisplayError::BusWriteError)?;
match cmds {
DataFormat::U8(slice) => slice.iter().try_for_each(|cmd| {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*cmd)?;
self.wr.set_high().map_err(|_| DisplayError::BusWriteError)
}),
DataFormat::U16(slice) => slice.as_byte_slice().iter().try_for_each(|cmd| {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*cmd)?;
self.wr.set_high().map_err(|_| DisplayError::BusWriteError)
}),
DataFormat::U16LE(slice) => slice.iter().try_for_each(|cmd| {
for cmd in &cmd.to_le_bytes() {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*cmd)?;
self.wr
.set_high()
.map_err(|_| DisplayError::BusWriteError)?;
}
Ok(())
}),
DataFormat::U16BE(slice) => slice.iter().try_for_each(|cmd| {
for cmd in &cmd.to_be_bytes() {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*cmd)?;
self.wr
.set_high()
.map_err(|_| DisplayError::BusWriteError)?;
}
Ok(())
}),
_ => Err(DisplayError::DataFormatNotImplemented),
}
}
fn send_data(&mut self, buf: DataFormat<'_>) -> Result<(), DisplayError> {
use byte_slice_cast::*;
self.dc
.set_high()
.map_err(|_| DisplayError::BusWriteError)?;
match buf {
DataFormat::U8(slice) => slice.iter().try_for_each(|d| {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*d)?;
self.wr.set_high().map_err(|_| DisplayError::BusWriteError)
}),
DataFormat::U16(slice) => slice.as_byte_slice().iter().try_for_each(|d| {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*d)?;
self.wr.set_high().map_err(|_| DisplayError::BusWriteError)
}),
DataFormat::U16LE(slice) => slice.iter().try_for_each(|cmd| {
for cmd in &cmd.to_le_bytes() {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*cmd)?;
self.wr
.set_high()
.map_err(|_| DisplayError::BusWriteError)?;
}
Ok(())
}),
DataFormat::U16BE(slice) => slice.iter().try_for_each(|cmd| {
for cmd in &cmd.to_be_bytes() {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*cmd)?;
self.wr
.set_high()
.map_err(|_| DisplayError::BusWriteError)?;
}
Ok(())
}),
DataFormat::U8Iter(iter) => {
for d in iter.into_iter() {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(d)?;
self.wr
.set_high()
.map_err(|_| DisplayError::BusWriteError)?;
}
Ok(())
}
DataFormat::U16LEIter(iter) => {
for cmd in iter.into_iter() {
for cmd in &cmd.to_le_bytes() {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*cmd)?;
self.wr
.set_high()
.map_err(|_| DisplayError::BusWriteError)?;
}
}
Ok(())
}
DataFormat::U16BEIter(iter) => {
for cmd in iter.into_iter() {
for cmd in &cmd.to_be_bytes() {
self.wr.set_low().map_err(|_| DisplayError::BusWriteError)?;
self.set_value(*cmd)?;
self.wr
.set_high()
.map_err(|_| DisplayError::BusWriteError)?;
}
}
Ok(())
}
_ => Err(DisplayError::DataFormatNotImplemented),
}
}
}