Initial display_partial() implementation
This commit is contained in:
@@ -1887,17 +1887,26 @@ static const uint8_t GRAY4_LUT_2IN9[159] = {
|
||||
};
|
||||
|
||||
void WaveshareEPaper2P9InV2R22Bpp::initialize() {
|
||||
RAMAllocator<uint8_t> allocator;
|
||||
if (this->buffer2_ == nullptr) {
|
||||
RAMAllocator<uint8_t> allocator;
|
||||
this->buffer2_ = allocator.allocate(this->get_buffer_length_());
|
||||
if (this->buffer2_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Could not allocate buffer2 for 2bpp display!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// With Gray4 LUT, bit=0 = white. Init both buffers to white.
|
||||
if (this->old_buffer_bw_ == nullptr) {
|
||||
this->old_buffer_bw_ = allocator.allocate(this->get_buffer_length_());
|
||||
if (this->old_buffer_bw_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Could not allocate old_buffer_bw for 2bpp display!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Gray4 LUT: bit=0=white. Init framebuffers to white.
|
||||
// old_buffer_bw_ uses standard convention (bit=1=white) so init to 0xFF.
|
||||
memset(this->buffer_, 0x00, this->get_buffer_length_());
|
||||
memset(this->buffer2_, 0x00, this->get_buffer_length_());
|
||||
memset(this->old_buffer_bw_, 0xFF, this->get_buffer_length_());
|
||||
|
||||
this->reset_();
|
||||
this->wait_until_idle_();
|
||||
@@ -1978,6 +1987,84 @@ void WaveshareEPaper2P9InV2R22Bpp::display() {
|
||||
this->command(0x22);
|
||||
this->data(0xC7);
|
||||
this->command(0x20);
|
||||
|
||||
// Update the old-frame reference for subsequent partial updates.
|
||||
// buffer_ uses bit=0=white (Gray4 convention); old_buffer_bw_ needs
|
||||
// bit=1=white (standard partial-LUT convention), so store the inverse.
|
||||
if (this->old_buffer_bw_ != nullptr) {
|
||||
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
|
||||
this->old_buffer_bw_[i] = ~this->buffer_[i];
|
||||
}
|
||||
}
|
||||
|
||||
void WaveshareEPaper2P9InV2R22Bpp::display_partial() {
|
||||
// Skip if the display is still busy — natural throttle for rapid drag events.
|
||||
// The next on_value call will trigger another update once the display is ready.
|
||||
if (this->busy_pin_ != nullptr && this->busy_pin_->digital_read())
|
||||
return;
|
||||
|
||||
this->write_lut_(PARTIAL_UPD_2IN9_LUT, PARTIAL_UPD_2IN9_LUT_SIZE);
|
||||
|
||||
this->command(0x37);
|
||||
this->data(0x00); this->data(0x00); this->data(0x00); this->data(0x00); this->data(0x00);
|
||||
this->data(0x40); this->data(0x00); this->data(0x00); this->data(0x00); this->data(0x00);
|
||||
|
||||
this->command(0x3C);
|
||||
this->data(0x80);
|
||||
|
||||
this->command(0x22);
|
||||
this->data(0xC0);
|
||||
this->command(0x20);
|
||||
|
||||
// Wait for the LUT load sequence to complete before writing pixel data.
|
||||
// This is typically ~50ms and must complete before we can clock in new data.
|
||||
if (!this->wait_until_idle_())
|
||||
return;
|
||||
|
||||
// Full window
|
||||
this->command(0x44);
|
||||
this->data(0x00);
|
||||
this->data(((this->get_width_controller() - 1) >> 3) & 0xFF);
|
||||
this->command(0x45);
|
||||
this->data(0x00); this->data(0x00);
|
||||
this->data((this->get_height_internal() - 1) & 0xFF);
|
||||
this->data(((this->get_height_internal() - 1) >> 8) & 0xFF);
|
||||
this->command(0x4E); this->data(0x00);
|
||||
this->command(0x4F); this->data(0x00); this->data(0x00);
|
||||
|
||||
// 0x26 = old frame reference in standard convention (bit=1=white).
|
||||
// This tells the partial LUT the previous pixel states so it can apply
|
||||
// correct transition waveforms (BW, WB, WW, BB) per pixel.
|
||||
this->command(0x26);
|
||||
this->start_data_();
|
||||
if (this->old_buffer_bw_ != nullptr) {
|
||||
this->write_array(this->old_buffer_bw_, this->get_buffer_length_());
|
||||
} else {
|
||||
// Fallback: assume all-white previous state
|
||||
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
|
||||
this->write_byte(0xFF);
|
||||
}
|
||||
this->end_data_();
|
||||
|
||||
// 0x24 = new frame in standard convention (bit=1=white).
|
||||
// buffer_ uses bit=0=white (Gray4 convention), so invert it.
|
||||
this->command(0x24);
|
||||
this->start_data_();
|
||||
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
|
||||
this->write_byte(~this->buffer_[i]);
|
||||
this->end_data_();
|
||||
|
||||
// Update old-frame reference before activating so it's ready for the next call.
|
||||
if (this->old_buffer_bw_ != nullptr) {
|
||||
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
|
||||
this->old_buffer_bw_[i] = ~this->buffer_[i];
|
||||
}
|
||||
|
||||
// Activate partial update — fire and return without waiting.
|
||||
// Display is now busy; subsequent calls will skip until it completes.
|
||||
this->command(0x22);
|
||||
this->data(0x0F);
|
||||
this->command(0x20);
|
||||
}
|
||||
|
||||
void WaveshareEPaper2P9InV2R22Bpp::write_lut_(const uint8_t *lut, const uint8_t size) {
|
||||
|
||||
Reference in New Issue
Block a user