use crate::error::Error;
use embedded_hal::digital::OutputPin;
#[cfg(not(feature = "async"))]
use embedded_hal::spi::SpiDevice;
#[cfg(feature = "async")]
use embedded_hal_async::spi::SpiDevice;
#[cfg(not(feature = "async"))]
pub trait Command {
fn send<SPI: SpiDevice>(&self, display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error> where SPI: SpiDevice;
fn send_command<SPI>(cmd: &[u8], display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error>
where
SPI: SpiDevice,
{
dc.set_low().unwrap();
display.write(cmd).unwrap();
Ok(())
}
fn send_data<SPI>(cmd: &[u8], display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error>
where
SPI: SpiDevice,
{
dc.set_high().unwrap();
display.write(cmd).unwrap();
Ok(())
}
}
#[cfg(feature = "async")]
pub trait Command {
async fn send<SPI: SpiDevice>(&self, display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error> where SPI: SpiDevice;
async fn send_command<SPI>(cmd: &[u8], display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error>
where
SPI: SpiDevice,
{
dc.set_low().unwrap();
display.write(cmd).await.unwrap();
Ok(())
}
async fn send_data<SPI>(cmd: &[u8], display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error>
where
SPI: SpiDevice,
{
dc.set_high().unwrap();
display.write(cmd).await.unwrap();
Ok(())
}
}
macro_rules! cmd {
($t:ty, $l:literal) => {
impl Command for $t {
#[cfg(not(feature = "async"))]
fn send<SPI>(&self, display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error>
where
SPI: SpiDevice,
{
Self::send_command(&[$l], display, dc)
}
#[cfg(feature = "async")]
async fn send<SPI>(&self, display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error>
where
SPI: SpiDevice,
{
Self::send_command(&[$l], display, dc).await
}
}
};
}
macro_rules! cmd_arg {
($t:ty, $l:literal) => {
impl Command for $t {
#[cfg(not(feature = "async"))]
fn send<SPI>(&self, display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error>
where
SPI: SpiDevice,
{
Self::send_command(&[$l], display, dc)?;
Self::send_data(&self.0, display, dc)
}
#[cfg(feature = "async")]
async fn send<SPI>(&self, display: &mut SPI, dc: &mut impl OutputPin) -> Result<(), Error>
where
SPI: SpiDevice,
{
Self::send_command(&[$l], display, dc).await?;
Self::send_data(&self.0, display, dc).await
}
}
};
}
pub struct DriverOutputControl( pub [u8; 3]);
#[allow(dead_code)]
pub struct GateDrivingVoltage;
#[allow(dead_code)]
pub struct SourceDrivingVoltage;
#[allow(dead_code)]
pub struct InitialCodeSetting;
#[allow(dead_code)]
pub struct BoosterSoftStartControl( pub [u8; 4]);
pub struct DeepSleepMode( pub [u8; 1]);
pub struct DataEntryModeSetting( pub [u8; 1]);
pub struct SwReset;
#[allow(dead_code)]
pub struct TemperatureSensorSelection;
pub struct TemperatureSensorWrite( pub [u8; 2]);
pub struct MasterActivation;
#[allow(dead_code)]
pub struct DisplayUpdateControl1( pub [u8; 1]);
pub struct DisplayUpdateControl2( pub [u8; 1]);
pub struct WriteRam<'a>( pub &'a [u8]);
pub struct SetRamXAddressStartEndPosition( pub [u8; 2]);
pub struct SetRamYAddressStartEndPosition( pub [u8; 4]);
pub struct SetRamXAddressPosition( pub [u8; 1]);
pub struct SetRamYAddressPosition( pub [u8; 2]);
#[allow(dead_code)]
pub struct Nop;
cmd_arg!(DriverOutputControl, 0x01);
cmd!(GateDrivingVoltage, 0x03);
cmd!(SourceDrivingVoltage, 0x04);
cmd!(InitialCodeSetting, 0x08);
cmd_arg!(BoosterSoftStartControl, 0x0c);
cmd_arg!(DeepSleepMode, 0x10);
cmd_arg!(DataEntryModeSetting, 0x11);
cmd!(SwReset, 0x12);
cmd!(TemperatureSensorSelection, 0x18);
cmd_arg!(TemperatureSensorWrite, 0x1a);
cmd!(MasterActivation, 0x20);
cmd_arg!(DisplayUpdateControl1, 0x21);
cmd_arg!(DisplayUpdateControl2, 0x22);
cmd_arg!(WriteRam<'_>, 0x24);
cmd_arg!(SetRamXAddressStartEndPosition, 0x44);
cmd_arg!(SetRamYAddressStartEndPosition, 0x45);
cmd_arg!(SetRamXAddressPosition, 0x4e);
cmd_arg!(SetRamYAddressPosition, 0x4f);
cmd!(Nop, 0x7f);