Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/epd3in7/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pub(crate) enum Command {
WriteRam = 0x24,
/// This command writes VCOM register from MCU interface
WriteVcomRegister = 0x2C,
/// This command will transfer its data to R RAM, until another command is written
WriteRamRed = 0x26,
/// This command writes LUT register from MCU interface (105 bytes),
/// which contains the content of VS [nx-LUT], TP #[nX], RP #[n]
WriteLutRegister = 0x32,
Expand Down
34 changes: 32 additions & 2 deletions src/epd3in7/constants.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This LUT clears the whole display during updates.
#[allow(unused)]
pub(crate) const LUT_1GRAY_GC: [u8; 105] = [
0x2A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //1
0x05, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //2
Expand All @@ -13,7 +13,7 @@ pub(crate) const LUT_1GRAY_GC: [u8; 105] = [
0x22, 0x22, 0x22, 0x22, 0x22,
];

// This LUT updates only the pixels that have changed.
#[allow(unused)]
pub(crate) const LUT_1GRAY_DU: [u8; 105] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //1
0x01, 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //2
Expand All @@ -27,3 +27,33 @@ pub(crate) const LUT_1GRAY_DU: [u8; 105] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //10
0x22, 0x22, 0x22, 0x22, 0x22,
];

#[allow(unused)]
pub(crate) const LUT_4GRAY_GC: [u8; 105] = [
0x2A, 0x06, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //1
0x28, 0x06, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //2
0x20, 0x06, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //3
0x14, 0x06, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //4
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //5
0x00, 0x02, 0x02, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x08, 0x02, //6
0x00, 0x02, 0x02, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //7
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //8
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //9
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //10
0x22, 0x22, 0x22, 0x22, 0x22,
];

#[allow(unused)]
pub(crate) const LUT_1GRAY_A2: [u8; 105] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //1
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //2
0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //3
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //4
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //5
0x00, 0x00, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //6
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //7
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //8
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //9
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //10
0x22, 0x22, 0x22, 0x22, 0x22,
];
94 changes: 78 additions & 16 deletions src/epd3in7/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,29 @@ pub struct EPD3in7<SPI, BUSY, DC, RST, DELAY> {
background_color: Color,
}

impl<SPI, BUSY, DC, RST, DELAY> EPD3in7<SPI, BUSY, DC, RST, DELAY>
where
SPI: SpiDevice,
BUSY: InputPin,
DC: OutputPin,
RST: OutputPin,
DELAY: DelayNs,
{
fn reset_ram_start_end_positions(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
self.interface.cmd_with_data(
spi,
Command::SetRamXAddressStartEndPosition,
&[0x00, 0x00, 0x17, 0x01],
)?;
self.interface.cmd_with_data(
spi,
Command::SetRamYAddressStartEndPosition,
&[0x00, 0x00, 0xDF, 0x01],
)?;
Ok(())
}
}

impl<SPI, BUSY, DC, RST, DELAY> InternalWiAdditions<SPI, BUSY, DC, RST, DELAY>
for EPD3in7<SPI, BUSY, DC, RST, DELAY>
where
Expand All @@ -64,7 +87,7 @@ where
self.interface.reset(delay, 30, 10);

self.interface.cmd(spi, Command::SwReset)?;
delay.delay_us(300000u32);
delay.delay_us(10000u32);

self.interface
.cmd_with_data(spi, Command::AutoWriteRedRamRegularPattern, &[0xF7])?;
Expand Down Expand Up @@ -101,19 +124,10 @@ where
self.interface.cmd_with_data(
spi,
Command::DisplayOption,
&[0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF],
&[0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF],
)?;

self.interface.cmd_with_data(
spi,
Command::SetRamXAddressStartEndPosition,
&[0x00, 0x00, 0x17, 0x01],
)?;
self.interface.cmd_with_data(
spi,
Command::SetRamYAddressStartEndPosition,
&[0x00, 0x00, 0xDF, 0x01],
)?;
self.reset_ram_start_end_positions(spi)?;

self.interface
.cmd_with_data(spi, Command::DisplayUpdateSequenceSetting, &[0xCF])?;
Expand Down Expand Up @@ -197,7 +211,6 @@ where
Ok(())
}

#[allow(unused)]
fn update_partial_frame(
&mut self,
spi: &mut SPI,
Expand All @@ -208,12 +221,61 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
todo!()
let x_start = x;
let x_end = x + width - 1;
let y_start = y;
let y_end = y + height - 1;

self.interface.cmd_with_data(
spi,
Command::SetRamXAddressStartEndPosition,
&[
(x_start & 0xFF) as u8,
((x_start >> 8) & 0x03) as u8,
(x_end & 0xFF) as u8,
((x_end >> 8) & 0x03) as u8,
],
)?;
self.interface.cmd_with_data(
spi,
Command::SetRamYAddressStartEndPosition,
&[
(y_start & 0xFF) as u8,
((y_start >> 8) & 0x03) as u8,
(y_end & 0xFF) as u8,
((y_end >> 8) & 0x03) as u8,
],
)?;

self.interface.cmd_with_data(
spi,
Command::SetRamXAddressCounter,
&[(x_start & 0xFF) as u8, ((x_start >> 8) & 0x03) as u8],
)?;
self.interface.cmd_with_data(
spi,
Command::SetRamYAddressCounter,
&[(y_start & 0xFF) as u8, ((y_start >> 8) & 0x03) as u8],
)?;

self.interface
.cmd_with_data(spi, Command::WriteRam, buffer)?;

self.set_lut(spi, delay, Some(RefreshLut::Quick))?;
self.interface
.cmd_with_data(spi, Command::DisplayUpdateSequenceSetting, &[0xCF])?;
self.interface.cmd(spi, Command::DisplayUpdateSequence)?;
self.interface.wait_until_idle(delay, IS_BUSY_LOW);

self.reset_ram_start_end_positions(spi)?;

Ok(())
}

fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
//self.interface
// .cmd_with_data(spi, Command::WRITE_LUT_REGISTER, &LUT_1GRAY_GC)?;
self.set_lut(spi, delay, Some(RefreshLut::Full))?;
self.interface
.cmd_with_data(spi, Command::DisplayUpdateSequenceSetting, &[0xC7])?;
self.interface.cmd(spi, Command::DisplayUpdateSequence)?;
self.interface.wait_until_idle(delay, IS_BUSY_LOW);
Ok(())
Expand Down
Loading