Initial display_partial() implementation
This commit is contained in:
@@ -1887,17 +1887,26 @@ static const uint8_t GRAY4_LUT_2IN9[159] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void WaveshareEPaper2P9InV2R22Bpp::initialize() {
|
void WaveshareEPaper2P9InV2R22Bpp::initialize() {
|
||||||
if (this->buffer2_ == nullptr) {
|
|
||||||
RAMAllocator<uint8_t> allocator;
|
RAMAllocator<uint8_t> allocator;
|
||||||
|
if (this->buffer2_ == nullptr) {
|
||||||
this->buffer2_ = allocator.allocate(this->get_buffer_length_());
|
this->buffer2_ = allocator.allocate(this->get_buffer_length_());
|
||||||
if (this->buffer2_ == nullptr) {
|
if (this->buffer2_ == nullptr) {
|
||||||
ESP_LOGE(TAG, "Could not allocate buffer2 for 2bpp display!");
|
ESP_LOGE(TAG, "Could not allocate buffer2 for 2bpp display!");
|
||||||
return;
|
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->buffer_, 0x00, this->get_buffer_length_());
|
||||||
memset(this->buffer2_, 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->reset_();
|
||||||
this->wait_until_idle_();
|
this->wait_until_idle_();
|
||||||
@@ -1978,6 +1987,84 @@ void WaveshareEPaper2P9InV2R22Bpp::display() {
|
|||||||
this->command(0x22);
|
this->command(0x22);
|
||||||
this->data(0xC7);
|
this->data(0xC7);
|
||||||
this->command(0x20);
|
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) {
|
void WaveshareEPaper2P9InV2R22Bpp::write_lut_(const uint8_t *lut, const uint8_t size) {
|
||||||
|
|||||||
@@ -448,6 +448,10 @@ class WaveshareEPaper2P9InV2R22Bpp : public WaveshareEPaper {
|
|||||||
|
|
||||||
void display() override;
|
void display() override;
|
||||||
|
|
||||||
|
// Fast 1-bit partial refresh. Non-blocking: skips if display is busy.
|
||||||
|
// Suitable for animation feedback; grayscale is restored on next display().
|
||||||
|
void display_partial();
|
||||||
|
|
||||||
void fill(Color color) override;
|
void fill(Color color) override;
|
||||||
|
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
@@ -471,6 +475,9 @@ class WaveshareEPaper2P9InV2R22Bpp : public WaveshareEPaper {
|
|||||||
uint32_t full_update_every_{30};
|
uint32_t full_update_every_{30};
|
||||||
uint32_t at_update_{0};
|
uint32_t at_update_{0};
|
||||||
uint8_t *buffer2_{nullptr};
|
uint8_t *buffer2_{nullptr};
|
||||||
|
// Tracks last-sent 1-bit state in standard convention (bit=1=white) for use
|
||||||
|
// as the 0x26 old-frame reference in partial updates.
|
||||||
|
uint8_t *old_buffer_bw_{nullptr};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reset_();
|
void reset_();
|
||||||
|
|||||||
Reference in New Issue
Block a user