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
16 changes: 14 additions & 2 deletions src/epd7in5_v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,16 @@ where
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
self.wait_until_idle(spi, delay)?;
self.cmd_with_data(spi, Command::DataStartTransmission2, buffer)?;
// Waveshare's reference C demo (EPD_7in5_V2.c::EPD_7IN5_V2_Display)
// sends the framebuffer to DTM1 (0x10) raw and to DTM2 (0x13) bitwise-
// inverted. The user-facing convention is bit 1 = white; the panel's
// DTM2 register expects bit 0 = white (datasheet §22, KW mode with
// NEW/OLD, DDX=00). Writing both DTM1 and DTM2 with opposite polarity
// forces a full LUTKW/LUTWK transition for every pixel, producing
// strong contrast. Without this, every framebuffer renders inverted.
self.cmd_with_data(spi, Command::DataStartTransmission1, buffer)?;
self.command(spi, Command::DataStartTransmission2)?;
self.interface.data_inverted(spi, buffer)?;
Ok(())
}

Expand Down Expand Up @@ -169,8 +178,11 @@ where
self.wait_until_idle(spi, delay)?;
self.send_resolution(spi)?;

// Match Waveshare's `EPD_7IN5_V2_Clear` (DTM1=0xFF, DTM2=0x00) so
// every pixel transitions black->white via LUTKW. See `update_frame`
// for the polarity rationale.
self.command(spi, Command::DataStartTransmission1)?;
self.interface.data_x_times(spi, 0x00, WIDTH / 8 * HEIGHT)?;
self.interface.data_x_times(spi, 0xFF, WIDTH / 8 * HEIGHT)?;

self.command(spi, Command::DataStartTransmission2)?;
self.interface.data_x_times(spi, 0x00, WIDTH / 8 * HEIGHT)?;
Expand Down
17 changes: 17 additions & 0 deletions src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,23 @@ where
self.data(spi, data)
}

/// Sends data with bytewise bitwise-NOT applied. Streams via a stack chunk
/// to avoid heap allocation. Required for displays whose DTM2 register
/// expects bit polarity inverted from the user-facing framebuffer (e.g.
/// 7.5" V2, where Waveshare's reference C demo
/// `EPD_7in5_V2.c::EPD_7IN5_V2_Display` applies the same `~` before 0x13).
pub(crate) fn data_inverted(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
let _ = self.dc.set_high();
let mut chunk = [0u8; 256];
for source in data.chunks(chunk.len()) {
for (index, &byte) in source.iter().enumerate() {
chunk[index] = !byte;
}
self.write(spi, &chunk[..source.len()])?;
}
Ok(())
}

/// Basic function for sending the same byte of data (one u8) multiple times over spi
///
/// Enables direct interaction with the device with the help of [command()](ConnectionInterface::command())
Expand Down
Loading