use crate::error::Error;
use embedded_hal::digital::v2::OutputPin;
#[derive(Debug)]
#[allow(dead_code)]
pub enum Command {
Contrast(u8, u8, u8),
AllOn(bool),
Invert(bool),
DisplayOn(bool),
ColumnAddress(u8, u8),
RowAddress(u8, u8),
StartLine(u8),
RemapAndColorDepth(bool, bool, ColorMode, AddressIncrementMode),
Multiplex(u8),
ReverseComDir(bool),
DisplayOffset(u8),
ComPinConfig(bool, bool),
DisplayClockDiv(u8, u8),
PreChargePeriod(u8, u8),
VcomhDeselect(VcomhLevel),
Noop,
}
impl Command {
pub fn send<SPI, DC, CommE, PinE>(
self,
spi: &mut SPI,
dc: &mut DC,
) -> Result<(), Error<CommE, PinE>>
where
SPI: hal::blocking::spi::Write<u8, Error = CommE>,
DC: OutputPin<Error = PinE>,
{
let (data, len) = match self {
Command::Contrast(a, b, c) => ([0x81, a, 0x82, b, 0x83, c, 0], 6),
Command::AllOn(on) => ([if on { 0xA5 } else { 0xA6 }, 0, 0, 0, 0, 0, 0], 1),
Command::Invert(inv) => ([if inv { 0xA7 } else { 0xA4 }, 0, 0, 0, 0, 0, 0], 1),
Command::DisplayOn(on) => ([0xAE | (on as u8), 0, 0, 0, 0, 0, 0], 1),
Command::ColumnAddress(start, end) => ([0x15, start, end, 0, 0, 0, 0], 3),
Command::RowAddress(start, end) => ([0x75, start, end, 0, 0, 0, 0], 3),
Command::StartLine(line) => ([0xA1, (0x3F & line), 0, 0, 0, 0, 0], 2),
Command::RemapAndColorDepth(hremap, vremap, cmode, addr_inc_mode) => (
[
0xA0,
0x20 | ((vremap as u8) << 4
| (hremap as u8) << 1
| (cmode as u8) << 6
| (addr_inc_mode as u8)),
0,
0,
0,
0,
0,
],
2,
),
Command::Multiplex(ratio) => ([0xA8, ratio, 0, 0, 0, 0, 0], 2),
Command::ReverseComDir(rev) => ([0xC0 | ((rev as u8) << 3), 0, 0, 0, 0, 0, 0], 1),
Command::DisplayOffset(offset) => ([0xA2, offset, 0, 0, 0, 0, 0], 2),
Command::ComPinConfig(alt, lr) => (
[
0xDA,
0x2 | ((alt as u8) << 4) | ((lr as u8) << 5),
0,
0,
0,
0,
0,
],
2,
),
Command::DisplayClockDiv(fosc, div) => {
([0xB3, ((0xF & fosc) << 4) | (0xF & div), 0, 0, 0, 0, 0], 2)
}
Command::PreChargePeriod(phase1, phase2) => (
[0x3e, ((0xF & phase2) << 4) | (0xF & phase1), 0, 0, 0, 0, 0],
2,
),
Command::VcomhDeselect(level) => ([0xBE, (level as u8) << 1, 0, 0, 0, 0, 0], 2),
Command::Noop => ([0xE3, 0, 0, 0, 0, 0, 0], 1),
};
dc.set_low().map_err(Error::Pin)?;
spi.write(&data[0..len]).map_err(Error::Comm)
}
}
#[derive(Debug, Clone, Copy)]
#[allow(dead_code)]
pub enum HScrollDir {
LeftToRight = 0,
RightToLeft = 1,
}
#[derive(Debug, Clone, Copy)]
#[allow(dead_code)]
pub enum VHScrollDir {
VerticalRight = 0b01,
VerticalLeft = 0b10,
}
#[derive(Debug, Clone, Copy)]
#[allow(dead_code)]
pub enum NFrames {
F2 = 0b111,
F3 = 0b100,
F4 = 0b101,
F5 = 0b000,
F25 = 0b110,
F64 = 0b001,
F128 = 0b010,
F256 = 0b011,
}
#[derive(Debug, Clone, Copy)]
#[allow(dead_code)]
pub enum VcomhLevel {
V044 = 0b00000,
V052 = 0b01000,
V061 = 0b10000,
V071 = 0b11000,
V083 = 0b11111,
}
#[derive(Debug, Clone, Copy)]
#[allow(dead_code)]
pub enum ColorMode {
CM256 = 0x00,
CM65k = 0x01,
}
#[derive(Debug, Clone, Copy)]
#[allow(dead_code)]
pub enum AddressIncrementMode {
Horizontal = 0x00,
Vertical = 0x01,
}