ESPHome 2026.5.0b1
Loading...
Searching...
No Matches
epaper_spi_ssd1683.cpp
Go to the documentation of this file.
2
3#include <algorithm>
4
5#include "esphome/core/log.h"
6
7namespace esphome::epaper_spi {
8static constexpr const char *const TAG = "epaper_spi.mono";
9
11 ESP_LOGV(TAG, "Refresh screen");
12 this->cmd_data(0x3C, {partial ? (uint8_t) 0x80 : (uint8_t) 0x01});
13 // On partial update, set red RAM to inverse to remove BW ghosting
14 this->cmd_data(0x21, {partial ? (uint8_t) 0x80 : (uint8_t) 0x40, (uint8_t) 0x00});
15 // Set full update to 0xD7 for fast update, 0xF7 for normal
16 // Fast update flashes less and draws sooner but is in busy state for the same amount of time
17 // Manufacturer recommends not using fast update all the time, TODO expose this to the user
18 this->cmd_data(0x22, {partial ? (uint8_t) 0xFC : (uint8_t) 0xF7});
19 this->command(0x20);
20}
21
22// Puts the display into deep sleep mode 1, only way to get out is to reset the display
23// Mode 1 retains RAM while sleeping, necessary for future partial and window updates
25 if (this->is_using_partial_update_()) {
26 ESP_LOGV(TAG, "Deep sleep mode 1");
27 this->cmd_data(0x10, {0x01}); // deep sleep, retain RAM
28 } else {
29 ESP_LOGV(TAG, "Deep sleep mode 2");
30 this->cmd_data(0x10, {0x03}); // deep sleep, lose RAM
31 }
32}
33
35 // if not using partial update, the display will go into deep sleep mode 2, so must rewrite entire
36 // buffer since the display RAM will not retain contents
37 if (!this->is_using_partial_update_()) {
38 this->x_low_ = 0;
39 this->x_high_ = this->width_;
40 this->y_low_ = 0;
41 this->y_high_ = this->height_;
42 }
43
44 // round x-coordinates to byte boundaries
45 this->x_low_ /= 8;
46 this->x_high_ += 7;
47 this->x_high_ /= 8;
48
49 this->cmd_data(0x44, {(uint8_t) this->x_low_, (uint8_t) (this->x_high_ - 1)});
50 this->cmd_data(0x45, {(uint8_t) this->y_low_, (uint8_t) (this->y_low_ / 256), (uint8_t) (this->y_high_ - 1),
51 (uint8_t) ((this->y_high_ - 1) / 256)});
52 this->cmd_data(0x4E, {(uint8_t) this->x_low_});
53 this->cmd_data(0x4F, {(uint8_t) this->y_low_, (uint8_t) (this->y_low_ / 256)});
54}
55
57 auto start_time = millis();
58 if (this->current_data_index_ == 0) {
59 if (this->send_red_) {
60 // round to byte boundaries
61 this->set_window();
62 }
63 // for monochrome, we need to send red on every refresh to prevent dirty pixels
64 // when doing a partial refresh
65 this->command(this->send_red_ ? 0x26 : 0x24);
66 this->current_data_index_ = this->y_low_; // actually current line
67 }
68 size_t row_length = this->x_high_ - this->x_low_;
69 FixedVector<uint8_t> bytes_to_send{};
70 bytes_to_send.init(row_length);
71 ESP_LOGV(TAG, "Writing %u bytes at line %zu at %ums", row_length, this->current_data_index_, (unsigned) millis());
72 this->start_data_();
73 while (this->current_data_index_ != this->y_high_) {
74 size_t data_idx = this->current_data_index_ * this->row_width_ + this->x_low_;
75 for (size_t i = 0; i != row_length; i++) {
76 bytes_to_send[i] = this->buffer_[data_idx++];
77 }
78 ++this->current_data_index_;
79 this->write_array(&bytes_to_send.front(), row_length); // NOLINT
80 if (millis() - start_time > MAX_TRANSFER_TIME) {
81 // Let the main loop run and come back next loop
82 this->disable();
83 return false;
84 }
85 }
86
87 this->disable();
88 this->current_data_index_ = 0;
89 if (this->send_red_) {
90 this->send_red_ = false;
91 return false;
92 }
93 this->send_red_ = true;
94 return true;
95}
96
97} // namespace esphome::epaper_spi
Fixed-capacity vector - allocates once at runtime, never reallocates This avoids std::vector template...
Definition helpers.h:529
void init(size_t n)
Definition helpers.h:619
void command(uint8_t value)
split_buffer::SplitBuffer buffer_
Definition epaper_spi.h:176
void cmd_data(uint8_t command, const uint8_t *ptr, size_t length)
void refresh_screen(bool partial) override
uint32_t IRAM_ATTR HOT millis()
Definition hal.cpp:28