ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
epaper_spi_ssd1681.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4#include <cstring>
5
6#include "esphome/core/log.h"
7
8namespace esphome::epaper_spi {
9ESPHOME_LOG_TAG(TAG, "epaper_spi.ssd1681");
10
12 if (!this->sent_valid_ || this->sent_.size() != this->buffer_.size())
13 return;
14 bool changed = false;
15 uint16_t row_low = this->height_, row_high = 0, col_low = this->row_width_, col_high = 0;
16 for (uint16_t row = 0; row != this->height_; row++) {
17 const size_t base = row * this->row_width_;
18 const size_t end = base + this->row_width_;
19 size_t index = base;
20 while (index != end) {
21 size_t new_length, old_length;
22 const uint8_t *new_bytes = this->buffer_.get_span(index, new_length);
23 const uint8_t *old_bytes = this->sent_.get_span(index, old_length);
24 const size_t length = std::min({new_length, old_length, end - index});
25 if (std::memcmp(new_bytes, old_bytes, length) != 0) {
26 for (size_t i = 0; i != length; i++) {
27 if (new_bytes[i] == old_bytes[i])
28 continue;
29 const auto col = static_cast<uint16_t>(index + i - base);
30 changed = true;
31 row_low = std::min(row_low, row);
32 row_high = std::max<uint16_t>(row_high, row + 1);
33 col_low = std::min(col_low, col);
34 col_high = std::max<uint16_t>(col_high, col + 1);
35 }
36 }
37 index += length;
38 }
39 }
40 if (!changed)
41 return;
42 this->x_low_ = col_low * 8;
43 this->x_high_ = std::min<uint16_t>(col_high * 8, this->width_);
44 this->y_low_ = row_low;
45 this->y_high_ = row_high;
46}
47
49 if (this->current_data_index_ == 0 && this->send_red_) {
50 if (!this->partial_) {
51 // A refresh drives the whole panel from RAM, so a full one makes both RAM banks whole again
52 this->x_low_ = 0;
53 this->x_high_ = this->width_;
54 this->y_low_ = 0;
55 this->y_high_ = this->height_;
56 } else {
57 // 0x26 already holds the image on the panel: the controller copies 0x24 into it after each refresh
59 this->set_window();
60 this->send_red_ = false;
61 }
62 }
64}
65
67 ESP_LOGV(TAG, "Refresh screen");
68 this->cmd_data(0x3C, {partial ? (uint8_t) 0x80 : (uint8_t) 0x01});
69 // 0x26 is compared as it is on a partial refresh and ignored on a full one
70 this->cmd_data(0x21, {partial ? (uint8_t) 0x00 : (uint8_t) 0x40, (uint8_t) 0x00});
71 // Both end with analog and OSC off before the panel goes to sleep
72 this->cmd_data(0x22, {partial ? (uint8_t) 0xFF : (uint8_t) 0xF7});
73 this->command(0x20);
74}
75
76} // namespace esphome::epaper_spi
void command(uint8_t value)
split_buffer::SplitBuffer buffer_
Definition epaper_spi.h:218
void cmd_data(uint8_t command, const uint8_t *ptr, size_t length)
split_buffer::SplitBuffer sent_
Definition epaper_spi.h:219
void refresh_screen(bool partial) override
const uint8_t * get_span(size_t index, size_t &length) const
ESPHOME_LOG_TAG(TAG, "display")
uint8_t end[39]
Definition sun_gtil2.cpp:17
uint16_t length
Definition tt21100.cpp:0