ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
epaper_spi_ssd1677.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4
6#include "esphome/core/log.h"
7
8namespace esphome::epaper_spi {
9ESPHOME_LOG_TAG(TAG, "epaper_spi.ssd1677");
10
13 if (!this->is_failed())
15}
16
18 if (!this->is_using_partial_update_())
19 return;
20 if (!this->sent_.init(this->plane_row_length_() * this->height_)) {
21 ESP_LOGW(TAG, "No memory for the comparison frame; partial updates will degrade unchanged areas");
22 }
23}
24
25void EPaperSSD1677::plane_row(size_t y, uint8_t *out) {
26 const size_t row_length = this->plane_row_length_();
27 const size_t data_idx = y * row_length;
28 for (size_t i = 0; i != row_length; i++)
29 out[i] = this->buffer_[data_idx + i];
30}
31
32// Nothing a partial update needs is kept in controller RAM any more, so skip the reset for those.
34 if (this->update_count_ != 0 && this->sent_.is_valid())
35 return true;
36 return EPaperMono::reset();
37}
38
39// The window always covers the whole panel, so each plane is the frame's bytes in order. Where
40// those bytes are already stored as the plane needs them (the comparison frame, and a 1-bit
41// buffer) they are written straight from the buffer, as many at a time as the time slice allows;
42// otherwise they are built a row at a time by plane_row().
44 if (!this->sent_.is_valid())
46
47 const auto start_time = millis();
48 if (this->current_data_index_ == 0) {
49 if (this->plane_ == 0) {
50 this->x_low_ = 0;
51 this->x_high_ = this->width_;
52 this->y_low_ = 0;
53 this->y_high_ = this->height_;
54 }
55 this->set_window();
56 this->command(this->plane_ == 0 ? 0x26 : 0x24);
57 }
58 // A full update ignores 0x26, and the copy may not hold a real frame yet (first update after
59 // boot): send the new frame to both planes.
60 const bool send_copy = this->plane_ == 0 && this->update_count_ != 0;
61 // A 1 bit per pixel buffer already holds the frame as a RAM plane does, so it can be sent as it is; a
62 // deeper buffer (the four-level model, 2 bits per pixel) packs the plane in plane_row() instead.
63 const bool direct = send_copy || this->buffer_is_mono_();
64 const auto &source = send_copy ? this->sent_ : this->buffer_;
65 const size_t row_length = this->plane_row_length_();
66 const size_t plane_length = row_length * this->height_;
67 // Roughly what the bus moves in one time slice, so a slice is not overrun by much
68 const size_t max_chunk = std::max<size_t>(this->data_rate_ / 8000 * MAX_TRANSFER_TIME, MAX_TRANSFER_SIZE);
69 SmallBufferWithHeapFallback<128> row_alloc(direct ? 0 : row_length);
70 this->start_data_();
71 while (this->current_data_index_ != plane_length) {
72 size_t length;
73 const uint8_t *data;
74 if (direct) {
75 data = source.get_span(this->current_data_index_, length);
76 length = std::min(length, max_chunk);
77 } else {
78 // Always at the start of a row here, since this path sends whole rows only
79 this->plane_row(this->current_data_index_ / row_length, row_alloc.get());
80 data = row_alloc.get();
81 length = row_length;
82 }
83 this->write_array(data, length);
84 if (this->plane_ == 1)
85 this->sent_.write(this->current_data_index_, data, length);
87 if (this->current_data_index_ != plane_length && millis() - start_time > MAX_TRANSFER_TIME) {
88 // Let the main loop run and come back next loop
89 this->disable();
90 return false;
91 }
92 }
93 this->disable();
94 this->current_data_index_ = 0;
95 if (this->plane_ == 0) {
96 this->plane_ = 1;
97 return false;
98 }
99 this->plane_ = 0;
100 return true;
101}
102
103} // namespace esphome::epaper_spi
bool is_failed() const
Definition component.h:274
Helper class for efficient buffer allocation - uses stack for small sizes, heap for large This is use...
Definition helpers.h:819
void command(uint8_t value)
split_buffer::SplitBuffer buffer_
Definition epaper_spi.h:190
virtual void plane_row(size_t y, uint8_t *out)
uint32_t data_rate_
Definition spi.h:430
bool init(size_t total_length, size_t max_buffer_size=SIZE_MAX)
void write(size_t index, const uint8_t *data, size_t length)
std::vector< uint8_t > & out
Definition gif.cpp:49
ESPHOME_LOG_TAG(TAG, "display")
uint32_t IRAM_ATTR HOT millis()
Definition hal.cpp:25
uint16_t y
Definition tt21100.cpp:6