|
|
|
@ -51,24 +51,15 @@ pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; |
|
|
|
const IS_BUSY_LOW: bool = false; |
|
|
|
const IS_BUSY_LOW: bool = false; |
|
|
|
|
|
|
|
|
|
|
|
const LUT_PARTIAL_2IN9: [u8; 153] = [ |
|
|
|
const LUT_PARTIAL_2IN9: [u8; 153] = [ |
|
|
|
0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x0, 0x0, 0x0, 0x0, |
|
|
|
0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
|
|
|
0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
|
|
|
0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
|
|
|
0x0A,0x0,0x0,0x0,0x0,0x0,0x2,
|
|
|
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
|
|
|
0x1,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, |
|
|
|
0x1,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x22, 0x22, 0x22, 0x22, |
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
0x22, 0x0, 0x0, 0x0, |
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
|
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
|
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
|
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
|
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
|
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
|
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
|
|
|
|
0x0,0x0,0x0,0x0,0x0,0x0,0x0, |
|
|
|
|
|
|
|
0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0, |
|
|
|
|
|
|
|
]; |
|
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
use embedded_hal::{ |
|
|
|
use embedded_hal::{ |
|
|
|
@ -76,9 +67,7 @@ use embedded_hal::{ |
|
|
|
digital::v2::*, |
|
|
|
digital::v2::*, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
use crate::type_a::{ |
|
|
|
use crate::type_a::command::Command; |
|
|
|
command::Command, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use crate::color::Color; |
|
|
|
use crate::color::Color; |
|
|
|
|
|
|
|
|
|
|
|
@ -127,15 +116,18 @@ where |
|
|
|
// 0.. A[8]
|
|
|
|
// 0.. A[8]
|
|
|
|
// 0.. B[2:0]
|
|
|
|
// 0.. B[2:0]
|
|
|
|
// Default Values: A = Height of Screen (0x127), B = 0x00 (GD, SM and TB=0?)
|
|
|
|
// Default Values: A = Height of Screen (0x127), B = 0x00 (GD, SM and TB=0?)
|
|
|
|
self.interface.cmd_with_data(spi, Command::DriverOutputControl, &[0x27, 0x01, 0x00])?; |
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::DriverOutputControl, &[0x27, 0x01, 0x00])?; |
|
|
|
|
|
|
|
|
|
|
|
// One Databyte with default value 0x03
|
|
|
|
// One Databyte with default value 0x03
|
|
|
|
// -> address: x increment, y increment, address counter is updated in x direction
|
|
|
|
// -> address: x increment, y increment, address counter is updated in x direction
|
|
|
|
self.interface.cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])?; |
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])?; |
|
|
|
|
|
|
|
|
|
|
|
self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?; |
|
|
|
self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?; |
|
|
|
|
|
|
|
|
|
|
|
self.interface.cmd_with_data(spi, Command::DisplayUpdateControl1, &[0x00, 0x80])?; |
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::DisplayUpdateControl1, &[0x00, 0x80])?; |
|
|
|
|
|
|
|
|
|
|
|
self.set_ram_counter(spi, 0, 0)?; |
|
|
|
self.set_ram_counter(spi, 0, 0)?; |
|
|
|
|
|
|
|
|
|
|
|
@ -186,7 +178,8 @@ where |
|
|
|
fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { |
|
|
|
fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { |
|
|
|
self.wait_until_idle(); |
|
|
|
self.wait_until_idle(); |
|
|
|
// 0x00 for Normal mode (Power on Reset), 0x01 for Deep Sleep Mode
|
|
|
|
// 0x00 for Normal mode (Power on Reset), 0x01 for Deep Sleep Mode
|
|
|
|
self.interface.cmd_with_data(spi, Command::DeepSleepMode, &[0x01])?; |
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::DeepSleepMode, &[0x01])?; |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -225,7 +218,8 @@ where |
|
|
|
fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { |
|
|
|
fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { |
|
|
|
self.wait_until_idle(); |
|
|
|
self.wait_until_idle(); |
|
|
|
// Enable clock signal, Enable Analog, Load temperature value, DISPLAY with DISPLAY Mode 1, Disable Analog, Disable OSC
|
|
|
|
// Enable clock signal, Enable Analog, Load temperature value, DISPLAY with DISPLAY Mode 1, Disable Analog, Disable OSC
|
|
|
|
self.interface.cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xF7])?; |
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xF7])?; |
|
|
|
self.interface.cmd(spi, Command::MasterActivation)?; |
|
|
|
self.interface.cmd(spi, Command::MasterActivation)?; |
|
|
|
self.wait_until_idle(); |
|
|
|
self.wait_until_idle(); |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
@ -342,7 +336,8 @@ where |
|
|
|
/// Set your own LUT, this function is also used internally for set_lut
|
|
|
|
/// Set your own LUT, this function is also used internally for set_lut
|
|
|
|
fn set_lut_helper(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { |
|
|
|
fn set_lut_helper(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { |
|
|
|
self.wait_until_idle(); |
|
|
|
self.wait_until_idle(); |
|
|
|
self.interface.cmd_with_data(spi, Command::WriteLutRegister, buffer)?; |
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::WriteLutRegister, buffer)?; |
|
|
|
self.wait_until_idle(); |
|
|
|
self.wait_until_idle(); |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
@ -360,8 +355,10 @@ where |
|
|
|
/// To be followed immediately by `update_new_frame`.
|
|
|
|
/// To be followed immediately by `update_new_frame`.
|
|
|
|
fn update_old_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { |
|
|
|
fn update_old_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { |
|
|
|
self.wait_until_idle(); |
|
|
|
self.wait_until_idle(); |
|
|
|
self.interface.cmd_with_data(spi, Command::WriteRam, buffer)?; |
|
|
|
self.interface |
|
|
|
self.interface.cmd_with_data(spi, Command::WriteRam2, buffer) |
|
|
|
.cmd_with_data(spi, Command::WriteRam, buffer)?; |
|
|
|
|
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::WriteRam2, buffer) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// To be used immediately after `update_old_frame`.
|
|
|
|
/// To be used immediately after `update_old_frame`.
|
|
|
|
@ -370,19 +367,27 @@ where |
|
|
|
//TODO original waveshare library has a hardware reset for 2 ms. But it works without reset apparently.
|
|
|
|
//TODO original waveshare library has a hardware reset for 2 ms. But it works without reset apparently.
|
|
|
|
|
|
|
|
|
|
|
|
self.set_lut_helper(spi, &LUT_PARTIAL_2IN9)?; |
|
|
|
self.set_lut_helper(spi, &LUT_PARTIAL_2IN9)?; |
|
|
|
self.interface.cmd_with_data(spi, Command::WriteOtpSelection, &[0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00])?; |
|
|
|
self.interface.cmd_with_data( |
|
|
|
self.interface.cmd_with_data(spi, Command::BorderWaveformControl, &[0x80])?; |
|
|
|
spi, |
|
|
|
self.interface.cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC0])?; |
|
|
|
Command::WriteOtpSelection, |
|
|
|
|
|
|
|
&[0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00], |
|
|
|
|
|
|
|
)?; |
|
|
|
|
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::BorderWaveformControl, &[0x80])?; |
|
|
|
|
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC0])?; |
|
|
|
self.interface.cmd(spi, Command::MasterActivation)?; |
|
|
|
self.interface.cmd(spi, Command::MasterActivation)?; |
|
|
|
|
|
|
|
|
|
|
|
self.wait_until_idle(); |
|
|
|
self.wait_until_idle(); |
|
|
|
|
|
|
|
|
|
|
|
self.use_full_frame(spi)?; |
|
|
|
self.use_full_frame(spi)?; |
|
|
|
|
|
|
|
|
|
|
|
self.interface.cmd_with_data(spi, Command::WriteRam, buffer)?; |
|
|
|
self.interface |
|
|
|
|
|
|
|
.cmd_with_data(spi, Command::WriteRam, buffer)?; |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Partial quick refresh not supported yet
|
|
|
|
#[allow(unused)] |
|
|
|
#[allow(unused)] |
|
|
|
fn update_partial_old_frame( |
|
|
|
fn update_partial_old_frame( |
|
|
|
&mut self, |
|
|
|
&mut self, |
|
|
|
@ -397,6 +402,7 @@ where |
|
|
|
unimplemented!() |
|
|
|
unimplemented!() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Partial quick refresh not supported yet
|
|
|
|
#[allow(unused)] |
|
|
|
#[allow(unused)] |
|
|
|
fn update_partial_new_frame( |
|
|
|
fn update_partial_new_frame( |
|
|
|
&mut self, |
|
|
|
&mut self, |
|
|
|
@ -411,6 +417,7 @@ where |
|
|
|
unimplemented!() |
|
|
|
unimplemented!() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Partial quick refresh not supported yet
|
|
|
|
#[allow(unused)] |
|
|
|
#[allow(unused)] |
|
|
|
fn clear_partial_frame( |
|
|
|
fn clear_partial_frame( |
|
|
|
&mut self, |
|
|
|
&mut self, |
|
|
|
|