mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 00:48:19 +01:00
Support tri-color waveshare eink displays 2.7inch B and B V2 (#4238)
Co-authored-by: Richard Nauber <richard@nauber.dev>
This commit is contained in:
parent
23a9a704f3
commit
92798751c2
4 changed files with 423 additions and 46 deletions
|
@ -17,8 +17,12 @@ from esphome.const import (
|
||||||
DEPENDENCIES = ["spi"]
|
DEPENDENCIES = ["spi"]
|
||||||
|
|
||||||
waveshare_epaper_ns = cg.esphome_ns.namespace("waveshare_epaper")
|
waveshare_epaper_ns = cg.esphome_ns.namespace("waveshare_epaper")
|
||||||
WaveshareEPaper = waveshare_epaper_ns.class_(
|
WaveshareEPaperBase = waveshare_epaper_ns.class_(
|
||||||
"WaveshareEPaper", cg.PollingComponent, spi.SPIDevice, display.DisplayBuffer
|
"WaveshareEPaperBase", cg.PollingComponent, spi.SPIDevice, display.DisplayBuffer
|
||||||
|
)
|
||||||
|
WaveshareEPaper = waveshare_epaper_ns.class_("WaveshareEPaper", WaveshareEPaperBase)
|
||||||
|
WaveshareEPaperBWR = waveshare_epaper_ns.class_(
|
||||||
|
"WaveshareEPaperBWR", WaveshareEPaperBase
|
||||||
)
|
)
|
||||||
WaveshareEPaperTypeA = waveshare_epaper_ns.class_(
|
WaveshareEPaperTypeA = waveshare_epaper_ns.class_(
|
||||||
"WaveshareEPaperTypeA", WaveshareEPaper
|
"WaveshareEPaperTypeA", WaveshareEPaper
|
||||||
|
@ -26,6 +30,12 @@ WaveshareEPaperTypeA = waveshare_epaper_ns.class_(
|
||||||
WaveshareEPaper2P7In = waveshare_epaper_ns.class_(
|
WaveshareEPaper2P7In = waveshare_epaper_ns.class_(
|
||||||
"WaveshareEPaper2P7In", WaveshareEPaper
|
"WaveshareEPaper2P7In", WaveshareEPaper
|
||||||
)
|
)
|
||||||
|
WaveshareEPaper2P7InB = waveshare_epaper_ns.class_(
|
||||||
|
"WaveshareEPaper2P7InB", WaveshareEPaperBWR
|
||||||
|
)
|
||||||
|
WaveshareEPaper2P7InBV2 = waveshare_epaper_ns.class_(
|
||||||
|
"WaveshareEPaper2P7InBV2", WaveshareEPaperBWR
|
||||||
|
)
|
||||||
WaveshareEPaper2P7InV2 = waveshare_epaper_ns.class_(
|
WaveshareEPaper2P7InV2 = waveshare_epaper_ns.class_(
|
||||||
"WaveshareEPaper2P7InV2", WaveshareEPaper
|
"WaveshareEPaper2P7InV2", WaveshareEPaper
|
||||||
)
|
)
|
||||||
|
@ -92,6 +102,8 @@ MODELS = {
|
||||||
"2.90inv2": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN_V2),
|
"2.90inv2": ("a", WaveshareEPaperTypeAModel.WAVESHARE_EPAPER_2_9_IN_V2),
|
||||||
"gdey029t94": ("c", GDEY029T94),
|
"gdey029t94": ("c", GDEY029T94),
|
||||||
"2.70in": ("b", WaveshareEPaper2P7In),
|
"2.70in": ("b", WaveshareEPaper2P7In),
|
||||||
|
"2.70in-b": ("b", WaveshareEPaper2P7InB),
|
||||||
|
"2.70in-bv2": ("b", WaveshareEPaper2P7InBV2),
|
||||||
"2.70inv2": ("b", WaveshareEPaper2P7InV2),
|
"2.70inv2": ("b", WaveshareEPaper2P7InV2),
|
||||||
"2.90in-b": ("b", WaveshareEPaper2P9InB),
|
"2.90in-b": ("b", WaveshareEPaper2P9InB),
|
||||||
"2.90in-bv3": ("b", WaveshareEPaper2P9InBV3),
|
"2.90in-bv3": ("b", WaveshareEPaper2P9InBV3),
|
||||||
|
@ -130,7 +142,7 @@ def validate_full_update_every_only_types_ac(value):
|
||||||
CONFIG_SCHEMA = cv.All(
|
CONFIG_SCHEMA = cv.All(
|
||||||
display.FULL_DISPLAY_SCHEMA.extend(
|
display.FULL_DISPLAY_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(WaveshareEPaper),
|
cv.GenerateID(): cv.declare_id(WaveshareEPaperBase),
|
||||||
cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
|
cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
|
||||||
cv.Required(CONF_MODEL): cv.one_of(*MODELS, lower=True),
|
cv.Required(CONF_MODEL): cv.one_of(*MODELS, lower=True),
|
||||||
cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
||||||
|
|
|
@ -83,7 +83,7 @@ static const uint8_t PARTIAL_UPDATE_LUT_TTGO_B1[LUT_SIZE_TTGO_B1] = {
|
||||||
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
0x00, 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||||
|
|
||||||
void WaveshareEPaper::setup_pins_() {
|
void WaveshareEPaperBase::setup_pins_() {
|
||||||
this->init_internal_(this->get_buffer_length_());
|
this->init_internal_(this->get_buffer_length_());
|
||||||
this->dc_pin_->setup(); // OUTPUT
|
this->dc_pin_->setup(); // OUTPUT
|
||||||
this->dc_pin_->digital_write(false);
|
this->dc_pin_->digital_write(false);
|
||||||
|
@ -98,13 +98,13 @@ void WaveshareEPaper::setup_pins_() {
|
||||||
|
|
||||||
this->reset_();
|
this->reset_();
|
||||||
}
|
}
|
||||||
float WaveshareEPaper::get_setup_priority() const { return setup_priority::PROCESSOR; }
|
float WaveshareEPaperBase::get_setup_priority() const { return setup_priority::PROCESSOR; }
|
||||||
void WaveshareEPaper::command(uint8_t value) {
|
void WaveshareEPaperBase::command(uint8_t value) {
|
||||||
this->start_command_();
|
this->start_command_();
|
||||||
this->write_byte(value);
|
this->write_byte(value);
|
||||||
this->end_command_();
|
this->end_command_();
|
||||||
}
|
}
|
||||||
void WaveshareEPaper::data(uint8_t value) {
|
void WaveshareEPaperBase::data(uint8_t value) {
|
||||||
this->start_data_();
|
this->start_data_();
|
||||||
this->write_byte(value);
|
this->write_byte(value);
|
||||||
this->end_data_();
|
this->end_data_();
|
||||||
|
@ -112,7 +112,7 @@ void WaveshareEPaper::data(uint8_t value) {
|
||||||
|
|
||||||
// write a command followed by one or more bytes of data.
|
// write a command followed by one or more bytes of data.
|
||||||
// The command is the first byte, length is the total including cmd.
|
// The command is the first byte, length is the total including cmd.
|
||||||
void WaveshareEPaper::cmd_data(const uint8_t *c_data, size_t length) {
|
void WaveshareEPaperBase::cmd_data(const uint8_t *c_data, size_t length) {
|
||||||
this->dc_pin_->digital_write(false);
|
this->dc_pin_->digital_write(false);
|
||||||
this->enable();
|
this->enable();
|
||||||
this->write_byte(c_data[0]);
|
this->write_byte(c_data[0]);
|
||||||
|
@ -121,7 +121,7 @@ void WaveshareEPaper::cmd_data(const uint8_t *c_data, size_t length) {
|
||||||
this->disable();
|
this->disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaveshareEPaper::wait_until_idle_() {
|
bool WaveshareEPaperBase::wait_until_idle_() {
|
||||||
if (this->busy_pin_ == nullptr || !this->busy_pin_->digital_read()) {
|
if (this->busy_pin_ == nullptr || !this->busy_pin_->digital_read()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,7 @@ bool WaveshareEPaper::wait_until_idle_() {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void WaveshareEPaper::update() {
|
void WaveshareEPaperBase::update() {
|
||||||
this->do_update_();
|
this->do_update_();
|
||||||
this->display();
|
this->display();
|
||||||
}
|
}
|
||||||
|
@ -159,20 +159,51 @@ void HOT WaveshareEPaper::draw_absolute_pixel_internal(int x, int y, Color color
|
||||||
this->buffer_[pos] &= ~(0x80 >> subpos);
|
this->buffer_[pos] &= ~(0x80 >> subpos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t WaveshareEPaper::get_buffer_length_() {
|
uint32_t WaveshareEPaper::get_buffer_length_() {
|
||||||
return this->get_width_controller() * this->get_height_internal() / 8u;
|
return this->get_width_controller() * this->get_height_internal() / 8u;
|
||||||
|
} // just a black buffer
|
||||||
|
uint32_t WaveshareEPaperBWR::get_buffer_length_() {
|
||||||
|
return this->get_width_controller() * this->get_height_internal() / 4u;
|
||||||
|
} // black and red buffer
|
||||||
|
|
||||||
|
void WaveshareEPaperBWR::fill(Color color) {
|
||||||
|
this->filled_rectangle(0, 0, this->get_width(), this->get_height(), color);
|
||||||
}
|
}
|
||||||
void WaveshareEPaper::start_command_() {
|
void HOT WaveshareEPaperBWR::draw_absolute_pixel_internal(int x, int y, Color color) {
|
||||||
|
if (x >= this->get_width_internal() || y >= this->get_height_internal() || x < 0 || y < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const uint32_t buf_half_len = this->get_buffer_length_() / 2u;
|
||||||
|
|
||||||
|
const uint32_t pos = (x + y * this->get_width_internal()) / 8u;
|
||||||
|
const uint8_t subpos = x & 0x07;
|
||||||
|
// flip logic
|
||||||
|
if (color.is_on()) {
|
||||||
|
this->buffer_[pos] |= 0x80 >> subpos;
|
||||||
|
} else {
|
||||||
|
this->buffer_[pos] &= ~(0x80 >> subpos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw red pixels only, if the color contains red only
|
||||||
|
if (((color.red > 0) && (color.green == 0) && (color.blue == 0))) {
|
||||||
|
this->buffer_[pos + buf_half_len] |= 0x80 >> subpos;
|
||||||
|
} else {
|
||||||
|
this->buffer_[pos + buf_half_len] &= ~(0x80 >> subpos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveshareEPaperBase::start_command_() {
|
||||||
this->dc_pin_->digital_write(false);
|
this->dc_pin_->digital_write(false);
|
||||||
this->enable();
|
this->enable();
|
||||||
}
|
}
|
||||||
void WaveshareEPaper::end_command_() { this->disable(); }
|
void WaveshareEPaperBase::end_command_() { this->disable(); }
|
||||||
void WaveshareEPaper::start_data_() {
|
void WaveshareEPaperBase::start_data_() {
|
||||||
this->dc_pin_->digital_write(true);
|
this->dc_pin_->digital_write(true);
|
||||||
this->enable();
|
this->enable();
|
||||||
}
|
}
|
||||||
void WaveshareEPaper::end_data_() { this->disable(); }
|
void WaveshareEPaperBase::end_data_() { this->disable(); }
|
||||||
void WaveshareEPaper::on_safe_shutdown() { this->deep_sleep(); }
|
void WaveshareEPaperBase::on_safe_shutdown() { this->deep_sleep(); }
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// Type A
|
// Type A
|
||||||
|
@ -493,7 +524,7 @@ uint32_t WaveshareEPaperTypeA::idle_timeout_() {
|
||||||
case TTGO_EPAPER_2_13_IN_B1:
|
case TTGO_EPAPER_2_13_IN_B1:
|
||||||
return 2500;
|
return 2500;
|
||||||
default:
|
default:
|
||||||
return WaveshareEPaper::idle_timeout_();
|
return WaveshareEPaperBase::idle_timeout_();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,6 +730,246 @@ void WaveshareEPaper2P7InV2::dump_config() {
|
||||||
LOG_UPDATE_INTERVAL(this);
|
LOG_UPDATE_INTERVAL(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// 2.7inch_e-paper_b
|
||||||
|
// ========================================================
|
||||||
|
// Datasheet:
|
||||||
|
// - https://www.waveshare.com/w/upload/d/d8/2.7inch-e-paper-b-specification.pdf
|
||||||
|
// - https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_2in7b.c
|
||||||
|
|
||||||
|
static const uint8_t LUT_VCOM_DC_2_7B[44] = {0x00, 0x00, 0x00, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x0A,
|
||||||
|
0x00, 0x00, 0x08, 0x00, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x00, 0x0A,
|
||||||
|
0x0A, 0x00, 0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00,
|
||||||
|
0x03, 0x0E, 0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
|
||||||
|
|
||||||
|
static const uint8_t LUT_WHITE_TO_WHITE_2_7B[42] = {0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x0A, 0x00, 0x00,
|
||||||
|
0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x80, 0x0A, 0x0A, 0x00,
|
||||||
|
0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 0x03, 0x0E,
|
||||||
|
0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
|
||||||
|
|
||||||
|
static const uint8_t LUT_BLACK_TO_WHITE_2_7B[42] = {0xA0, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x0A, 0x0A, 0x00, 0x00,
|
||||||
|
0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x90, 0x0A, 0x0A, 0x00,
|
||||||
|
0x00, 0x08, 0xB0, 0x04, 0x10, 0x00, 0x00, 0x05, 0xB0, 0x03, 0x0E,
|
||||||
|
0x00, 0x00, 0x0A, 0xC0, 0x23, 0x00, 0x00, 0x00, 0x01};
|
||||||
|
|
||||||
|
static const uint8_t LUT_WHITE_TO_BLACK_2_7B[] = {0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x20, 0x0A, 0x0A, 0x00, 0x00,
|
||||||
|
0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x10, 0x0A, 0x0A, 0x00,
|
||||||
|
0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 0x03, 0x0E,
|
||||||
|
0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
|
||||||
|
|
||||||
|
static const uint8_t LUT_BLACK_TO_BLACK_2_7B[42] = {0x90, 0x1A, 0x1A, 0x00, 0x00, 0x01, 0x40, 0x0A, 0x0A, 0x00, 0x00,
|
||||||
|
0x08, 0x84, 0x0E, 0x01, 0x0E, 0x01, 0x10, 0x80, 0x0A, 0x0A, 0x00,
|
||||||
|
0x00, 0x08, 0x00, 0x04, 0x10, 0x00, 0x00, 0x05, 0x00, 0x03, 0x0E,
|
||||||
|
0x00, 0x00, 0x0A, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01};
|
||||||
|
|
||||||
|
void WaveshareEPaper2P7InB::initialize() {
|
||||||
|
this->reset_();
|
||||||
|
|
||||||
|
// command power on
|
||||||
|
this->command(0x04);
|
||||||
|
this->wait_until_idle_();
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
// Command panel setting
|
||||||
|
this->command(0x00);
|
||||||
|
this->data(0xAF); // KW-BF KWR-AF BWROTP 0f
|
||||||
|
// command pll control
|
||||||
|
this->command(0x30);
|
||||||
|
this->data(0x3A); // 3A 100HZ 29 150Hz 39 200HZ 31 171HZ
|
||||||
|
|
||||||
|
// command power setting
|
||||||
|
this->command(0x01);
|
||||||
|
this->data(0x03); // VDS_EN, VDG_EN
|
||||||
|
this->data(0x00); // VCOM_HV, VGHL_LV[1], VGHL_LV[0]
|
||||||
|
this->data(0x2B); // VDH
|
||||||
|
this->data(0x2B); // VDL
|
||||||
|
this->data(0x09); // VDHR
|
||||||
|
|
||||||
|
// command booster soft start
|
||||||
|
this->command(0x06);
|
||||||
|
this->data(0x07);
|
||||||
|
this->data(0x07);
|
||||||
|
this->data(0x17);
|
||||||
|
|
||||||
|
// Power optimization - ???
|
||||||
|
this->command(0xF8);
|
||||||
|
this->data(0x60);
|
||||||
|
this->data(0xA5);
|
||||||
|
this->command(0xF8);
|
||||||
|
this->data(0x89);
|
||||||
|
this->data(0xA5);
|
||||||
|
this->command(0xF8);
|
||||||
|
this->data(0x90);
|
||||||
|
this->data(0x00);
|
||||||
|
this->command(0xF8);
|
||||||
|
this->data(0x93);
|
||||||
|
this->data(0x2A);
|
||||||
|
this->command(0xF8);
|
||||||
|
this->data(0x73);
|
||||||
|
this->data(0x41);
|
||||||
|
|
||||||
|
// COMMAND VCM DC SETTING
|
||||||
|
this->command(0x82);
|
||||||
|
this->data(0x12);
|
||||||
|
|
||||||
|
// VCOM_AND_DATA_INTERVAL_SETTING
|
||||||
|
this->command(0x50);
|
||||||
|
this->data(0x87); // define by OTP
|
||||||
|
|
||||||
|
delay(2);
|
||||||
|
// COMMAND LUT FOR VCOM
|
||||||
|
this->command(0x20);
|
||||||
|
for (uint8_t i : LUT_VCOM_DC_2_7B)
|
||||||
|
this->data(i);
|
||||||
|
// COMMAND LUT WHITE TO WHITE
|
||||||
|
this->command(0x21);
|
||||||
|
for (uint8_t i : LUT_WHITE_TO_WHITE_2_7B)
|
||||||
|
this->data(i);
|
||||||
|
// COMMAND LUT BLACK TO WHITE
|
||||||
|
this->command(0x22);
|
||||||
|
for (uint8_t i : LUT_BLACK_TO_WHITE_2_7B)
|
||||||
|
this->data(i);
|
||||||
|
// COMMAND LUT WHITE TO BLACK
|
||||||
|
this->command(0x23);
|
||||||
|
for (uint8_t i : LUT_WHITE_TO_BLACK_2_7B) {
|
||||||
|
this->data(i);
|
||||||
|
}
|
||||||
|
// COMMAND LUT BLACK TO BLACK
|
||||||
|
this->command(0x24);
|
||||||
|
|
||||||
|
for (uint8_t i : LUT_BLACK_TO_BLACK_2_7B) {
|
||||||
|
this->data(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HOT WaveshareEPaper2P7InB::display() {
|
||||||
|
uint32_t buf_len_half = this->get_buffer_length_() >> 1;
|
||||||
|
this->initialize();
|
||||||
|
|
||||||
|
// TCON_RESOLUTION
|
||||||
|
this->command(0x61);
|
||||||
|
this->data(this->get_width_internal() >> 8);
|
||||||
|
this->data(this->get_width_internal() & 0xff); // 176
|
||||||
|
this->data(this->get_height_internal() >> 8);
|
||||||
|
this->data(this->get_height_internal() & 0xff); // 264
|
||||||
|
|
||||||
|
// COMMAND DATA START TRANSMISSION 1 (BLACK)
|
||||||
|
this->command(0x10);
|
||||||
|
delay(2);
|
||||||
|
for (uint32_t i = 0; i < buf_len_half; i++) {
|
||||||
|
this->data(this->buffer_[i]);
|
||||||
|
}
|
||||||
|
this->command(0x11);
|
||||||
|
delay(2);
|
||||||
|
|
||||||
|
// COMMAND DATA START TRANSMISSION 2 (RED)
|
||||||
|
this->command(0x13);
|
||||||
|
delay(2);
|
||||||
|
for (uint32_t i = buf_len_half; i < buf_len_half * 2u; i++) {
|
||||||
|
this->data(this->buffer_[i]);
|
||||||
|
}
|
||||||
|
this->command(0x11);
|
||||||
|
|
||||||
|
delay(2);
|
||||||
|
|
||||||
|
// COMMAND DISPLAY REFRESH
|
||||||
|
this->command(0x12);
|
||||||
|
this->wait_until_idle_();
|
||||||
|
|
||||||
|
this->deep_sleep();
|
||||||
|
}
|
||||||
|
int WaveshareEPaper2P7InB::get_width_internal() { return 176; }
|
||||||
|
int WaveshareEPaper2P7InB::get_height_internal() { return 264; }
|
||||||
|
void WaveshareEPaper2P7InB::dump_config() {
|
||||||
|
LOG_DISPLAY("", "Waveshare E-Paper", this);
|
||||||
|
ESP_LOGCONFIG(TAG, " Model: 2.7in B");
|
||||||
|
LOG_PIN(" Reset Pin: ", this->reset_pin_);
|
||||||
|
LOG_PIN(" DC Pin: ", this->dc_pin_);
|
||||||
|
LOG_PIN(" Busy Pin: ", this->busy_pin_);
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================================================
|
||||||
|
// 2.7inch_e-paper_b_v2
|
||||||
|
// ========================================================
|
||||||
|
// Datasheet:
|
||||||
|
// - https://www.waveshare.com/w/upload/7/7b/2.7inch-e-paper-b-v2-specification.pdf
|
||||||
|
// - https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_2in7b_V2.c
|
||||||
|
|
||||||
|
void WaveshareEPaper2P7InBV2::initialize() {
|
||||||
|
this->reset_();
|
||||||
|
|
||||||
|
this->wait_until_idle_();
|
||||||
|
this->command(0x12);
|
||||||
|
this->wait_until_idle_();
|
||||||
|
|
||||||
|
this->command(0x00);
|
||||||
|
this->data(0x27);
|
||||||
|
this->data(0x01);
|
||||||
|
this->data(0x00);
|
||||||
|
|
||||||
|
this->command(0x11);
|
||||||
|
this->data(0x03);
|
||||||
|
|
||||||
|
// self.SetWindows(0, 0, self.width-1, self.height-1)
|
||||||
|
// SetWindows(self, Xstart, Ystart, Xend, Yend):
|
||||||
|
|
||||||
|
uint32_t xend = this->get_width_internal() - 1;
|
||||||
|
uint32_t yend = this->get_height_internal() - 1;
|
||||||
|
this->command(0x44);
|
||||||
|
this->data(0x00);
|
||||||
|
this->data((xend >> 3) & 0xff);
|
||||||
|
|
||||||
|
this->command(0x45);
|
||||||
|
this->data(0x00);
|
||||||
|
this->data(0x00);
|
||||||
|
this->data(yend & 0xff);
|
||||||
|
this->data((yend >> 8) & 0xff);
|
||||||
|
|
||||||
|
// SetCursor(self, Xstart, Ystart):
|
||||||
|
this->command(0x4E);
|
||||||
|
this->data(0x00);
|
||||||
|
this->command(0x4F);
|
||||||
|
this->data(0x00);
|
||||||
|
this->data(0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HOT WaveshareEPaper2P7InBV2::display() {
|
||||||
|
uint32_t buf_len = this->get_buffer_length_();
|
||||||
|
// COMMAND DATA START TRANSMISSION 1 (BLACK)
|
||||||
|
this->command(0x24);
|
||||||
|
delay(2);
|
||||||
|
for (uint32_t i = 0; i < buf_len; i++) {
|
||||||
|
this->data(this->buffer_[i]);
|
||||||
|
}
|
||||||
|
delay(2);
|
||||||
|
|
||||||
|
// COMMAND DATA START TRANSMISSION 2 (RED)
|
||||||
|
this->command(0x26);
|
||||||
|
delay(2);
|
||||||
|
for (uint32_t i = 0; i < buf_len; i++) {
|
||||||
|
this->data(this->buffer_[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
delay(2);
|
||||||
|
|
||||||
|
this->command(0x20);
|
||||||
|
|
||||||
|
this->wait_until_idle_();
|
||||||
|
}
|
||||||
|
int WaveshareEPaper2P7InBV2::get_width_internal() { return 176; }
|
||||||
|
int WaveshareEPaper2P7InBV2::get_height_internal() { return 264; }
|
||||||
|
void WaveshareEPaper2P7InBV2::dump_config() {
|
||||||
|
LOG_DISPLAY("", "Waveshare E-Paper", this);
|
||||||
|
ESP_LOGCONFIG(TAG, " Model: 2.7in B V2");
|
||||||
|
LOG_PIN(" Reset Pin: ", this->reset_pin_);
|
||||||
|
LOG_PIN(" DC Pin: ", this->dc_pin_);
|
||||||
|
LOG_PIN(" Busy Pin: ", this->busy_pin_);
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
}
|
||||||
|
|
||||||
// ========================================================
|
// ========================================================
|
||||||
// 2.90in Type B (LUT from OTP)
|
// 2.90in Type B (LUT from OTP)
|
||||||
// Datasheet:
|
// Datasheet:
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace waveshare_epaper {
|
namespace waveshare_epaper {
|
||||||
|
|
||||||
class WaveshareEPaper : public display::DisplayBuffer,
|
class WaveshareEPaperBase : public display::DisplayBuffer,
|
||||||
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
|
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
|
||||||
spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_2MHZ> {
|
spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_2MHZ> {
|
||||||
public:
|
public:
|
||||||
void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
|
void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
@ -27,8 +27,6 @@ class WaveshareEPaper : public display::DisplayBuffer,
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
void fill(Color color) override;
|
|
||||||
|
|
||||||
void setup() override {
|
void setup() override {
|
||||||
this->setup_pins_();
|
this->setup_pins_();
|
||||||
this->initialize();
|
this->initialize();
|
||||||
|
@ -36,11 +34,7 @@ class WaveshareEPaper : public display::DisplayBuffer,
|
||||||
|
|
||||||
void on_safe_shutdown() override;
|
void on_safe_shutdown() override;
|
||||||
|
|
||||||
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_BINARY; }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void draw_absolute_pixel_internal(int x, int y, Color color) override;
|
|
||||||
|
|
||||||
bool wait_until_idle_();
|
bool wait_until_idle_();
|
||||||
|
|
||||||
void setup_pins_();
|
void setup_pins_();
|
||||||
|
@ -56,7 +50,7 @@ class WaveshareEPaper : public display::DisplayBuffer,
|
||||||
|
|
||||||
virtual int get_width_controller() { return this->get_width_internal(); };
|
virtual int get_width_controller() { return this->get_width_internal(); };
|
||||||
|
|
||||||
uint32_t get_buffer_length_();
|
virtual uint32_t get_buffer_length_() = 0; // NOLINT(readability-identifier-naming)
|
||||||
uint32_t reset_duration_{200};
|
uint32_t reset_duration_{200};
|
||||||
|
|
||||||
void start_command_();
|
void start_command_();
|
||||||
|
@ -70,6 +64,28 @@ class WaveshareEPaper : public display::DisplayBuffer,
|
||||||
virtual uint32_t idle_timeout_() { return 1000u; } // NOLINT(readability-identifier-naming)
|
virtual uint32_t idle_timeout_() { return 1000u; } // NOLINT(readability-identifier-naming)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WaveshareEPaper : public WaveshareEPaperBase {
|
||||||
|
public:
|
||||||
|
void fill(Color color) override;
|
||||||
|
|
||||||
|
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_BINARY; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void draw_absolute_pixel_internal(int x, int y, Color color) override;
|
||||||
|
uint32_t get_buffer_length_() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WaveshareEPaperBWR : public WaveshareEPaperBase {
|
||||||
|
public:
|
||||||
|
void fill(Color color) override;
|
||||||
|
|
||||||
|
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void draw_absolute_pixel_internal(int x, int y, Color color) override;
|
||||||
|
uint32_t get_buffer_length_() override;
|
||||||
|
};
|
||||||
|
|
||||||
enum WaveshareEPaperTypeAModel {
|
enum WaveshareEPaperTypeAModel {
|
||||||
WAVESHARE_EPAPER_1_54_IN = 0,
|
WAVESHARE_EPAPER_1_54_IN = 0,
|
||||||
WAVESHARE_EPAPER_1_54_IN_V2,
|
WAVESHARE_EPAPER_1_54_IN_V2,
|
||||||
|
@ -134,6 +150,8 @@ class WaveshareEPaperTypeA : public WaveshareEPaper {
|
||||||
|
|
||||||
enum WaveshareEPaperTypeBModel {
|
enum WaveshareEPaperTypeBModel {
|
||||||
WAVESHARE_EPAPER_2_7_IN = 0,
|
WAVESHARE_EPAPER_2_7_IN = 0,
|
||||||
|
WAVESHARE_EPAPER_2_7_IN_B,
|
||||||
|
WAVESHARE_EPAPER_2_7_IN_B_V2,
|
||||||
WAVESHARE_EPAPER_4_2_IN,
|
WAVESHARE_EPAPER_4_2_IN,
|
||||||
WAVESHARE_EPAPER_4_2_IN_B_V2,
|
WAVESHARE_EPAPER_4_2_IN_B_V2,
|
||||||
WAVESHARE_EPAPER_7_5_IN,
|
WAVESHARE_EPAPER_7_5_IN,
|
||||||
|
@ -155,6 +173,68 @@ class WaveshareEPaper2P7In : public WaveshareEPaper {
|
||||||
this->data(0xA5); // check byte
|
this->data(0xA5); // check byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int get_width_internal() override;
|
||||||
|
int get_height_internal() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WaveshareEPaper2P7InB : public WaveshareEPaperBWR {
|
||||||
|
public:
|
||||||
|
void initialize() override;
|
||||||
|
|
||||||
|
void display() override;
|
||||||
|
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
void deep_sleep() override {
|
||||||
|
// COMMAND VCOM_AND_DATA_INTERVAL_SETTING
|
||||||
|
this->command(0x50);
|
||||||
|
// COMMAND POWER OFF
|
||||||
|
this->command(0x02);
|
||||||
|
this->wait_until_idle_();
|
||||||
|
// COMMAND DEEP SLEEP
|
||||||
|
this->command(0x07); // deep sleep
|
||||||
|
this->data(0xA5); // check byte
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int get_width_internal() override;
|
||||||
|
int get_height_internal() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WaveshareEPaper2P7InBV2 : public WaveshareEPaperBWR {
|
||||||
|
public:
|
||||||
|
void initialize() override;
|
||||||
|
|
||||||
|
void display() override;
|
||||||
|
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
void deep_sleep() override {
|
||||||
|
// COMMAND DEEP SLEEP
|
||||||
|
this->command(0x10);
|
||||||
|
this->data(0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int get_width_internal() override;
|
||||||
|
int get_height_internal() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GDEY029T94 : public WaveshareEPaper {
|
||||||
|
public:
|
||||||
|
void initialize() override;
|
||||||
|
|
||||||
|
void display() override;
|
||||||
|
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
void deep_sleep() override {
|
||||||
|
// COMMAND DEEP SLEEP
|
||||||
|
this->command(0x07);
|
||||||
|
this->data(0xA5); // check byte
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int get_width_internal() override;
|
int get_width_internal() override;
|
||||||
|
|
||||||
|
@ -177,26 +257,6 @@ class WaveshareEPaper2P7InV2 : public WaveshareEPaper {
|
||||||
int get_height_internal() override;
|
int get_height_internal() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GDEY029T94 : public WaveshareEPaper {
|
|
||||||
public:
|
|
||||||
void initialize() override;
|
|
||||||
|
|
||||||
void display() override;
|
|
||||||
|
|
||||||
void dump_config() override;
|
|
||||||
|
|
||||||
void deep_sleep() override {
|
|
||||||
// COMMAND DEEP SLEEP
|
|
||||||
this->command(0x07);
|
|
||||||
this->data(0xA5); // check byte
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int get_width_internal() override;
|
|
||||||
|
|
||||||
int get_height_internal() override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GDEW0154M09 : public WaveshareEPaper {
|
class GDEW0154M09 : public WaveshareEPaper {
|
||||||
public:
|
public:
|
||||||
void initialize() override;
|
void initialize() override;
|
||||||
|
|
|
@ -671,6 +671,40 @@ display:
|
||||||
full_update_every: 30
|
full_update_every: 30
|
||||||
lambda: |-
|
lambda: |-
|
||||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
- platform: waveshare_epaper
|
||||||
|
spi_id: spi_id_1
|
||||||
|
cs_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO23
|
||||||
|
dc_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO23
|
||||||
|
busy_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO23
|
||||||
|
reset_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO23
|
||||||
|
model: 2.70in-b
|
||||||
|
lambda: |-
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
|
- platform: waveshare_epaper
|
||||||
|
spi_id: spi_id_1
|
||||||
|
cs_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO23
|
||||||
|
dc_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO23
|
||||||
|
busy_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO23
|
||||||
|
reset_pin:
|
||||||
|
allow_other_uses: true
|
||||||
|
number: GPIO23
|
||||||
|
model: 2.70in-bv2
|
||||||
|
lambda: |-
|
||||||
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
- platform: waveshare_epaper
|
- platform: waveshare_epaper
|
||||||
spi_id: spi_id_1
|
spi_id: spi_id_1
|
||||||
cs_pin:
|
cs_pin:
|
||||||
|
|
Loading…
Reference in a new issue