diff --git a/esphome/components/inkplate6/display.py b/esphome/components/inkplate6/display.py index 7534731175..f05169ea2e 100644 --- a/esphome/components/inkplate6/display.py +++ b/esphome/components/inkplate6/display.py @@ -48,6 +48,7 @@ MODELS = { "inkplate_6": InkplateModel.INKPLATE_6, "inkplate_10": InkplateModel.INKPLATE_10, "inkplate_6_plus": InkplateModel.INKPLATE_6_PLUS, + "inkplate_6_v2": InkplateModel.INKPLATE_6_V2, } CONFIG_SCHEMA = cv.All( diff --git a/esphome/components/inkplate6/inkplate.cpp b/esphome/components/inkplate6/inkplate.cpp index e6fb9b773c..92a226de87 100644 --- a/esphome/components/inkplate6/inkplate.cpp +++ b/esphome/components/inkplate6/inkplate.cpp @@ -69,9 +69,9 @@ void Inkplate6::initialize_() { if (this->buffer_ != nullptr) allocator.deallocate(this->buffer_, buffer_size); if (this->glut_ != nullptr) - allocator32.deallocate(this->glut_, 256 * (this->model_ == INKPLATE_6_PLUS ? 9 : 8)); + allocator32.deallocate(this->glut_, 256 * 9); if (this->glut2_ != nullptr) - allocator32.deallocate(this->glut2_, 256 * (this->model_ == INKPLATE_6_PLUS ? 9 : 8)); + allocator32.deallocate(this->glut2_, 256 * 9); this->buffer_ = allocator.allocate(buffer_size); if (this->buffer_ == nullptr) { @@ -80,7 +80,7 @@ void Inkplate6::initialize_() { return; } if (this->greyscale_) { - uint8_t glut_size = (this->model_ == INKPLATE_6_PLUS ? 9 : 8); + uint8_t glut_size = 9; this->glut_ = allocator32.allocate(256 * glut_size); if (this->glut_ == nullptr) { @@ -95,12 +95,14 @@ void Inkplate6::initialize_() { return; } + const auto *const waveform3_bit = waveform3BitAll[this->model_]; + for (int i = 0; i < glut_size; i++) { for (uint32_t j = 0; j < 256; j++) { - uint8_t z = (waveform3Bit[j & 0x07][i] << 2) | (waveform3Bit[(j >> 4) & 0x07][i]); + uint8_t z = (waveform3_bit[j & 0x07][i] << 2) | (waveform3_bit[(j >> 4) & 0x07][i]); this->glut_[i * 256 + j] = ((z & 0b00000011) << 4) | (((z & 0b00001100) >> 2) << 18) | (((z & 0b00010000) >> 4) << 23) | (((z & 0b11100000) >> 5) << 25); - z = ((waveform3Bit[j & 0x07][i] << 2) | (waveform3Bit[(j >> 4) & 0x07][i])) << 4; + z = ((waveform3_bit[j & 0x07][i] << 2) | (waveform3_bit[(j >> 4) & 0x07][i])) << 4; this->glut2_[i * 256 + j] = ((z & 0b00000011) << 4) | (((z & 0b00001100) >> 2) << 18) | (((z & 0b00010000) >> 4) << 23) | (((z & 0b11100000) >> 5) << 25); } @@ -339,13 +341,16 @@ void Inkplate6::display1b_() { clean_fast_(1, 21); clean_fast_(2, 1); clean_fast_(0, 12); + clean_fast_(2, 1); } uint32_t clock = (1 << this->cl_pin_->get_pin()); uint32_t data_mask = this->get_data_pin_mask_(); ESP_LOGV(TAG, "Display1b start loops (%ums)", millis() - start_time); - for (int k = 0; k < 4; k++) { + int rep = (this->model_ == INKPLATE_6_V2) ? 5 : 4; + + for (int k = 0; k < rep; k++) { buffer_ptr = &this->buffer_[this->get_buffer_length_() - 1]; vscan_start_(); for (int i = 0, im = this->get_height_internal(); i < im; i++) { @@ -365,8 +370,11 @@ void Inkplate6::display1b_() { GPIO.out_w1ts = this->pin_lut_[data] | clock; GPIO.out_w1tc = data_mask | clock; } - GPIO.out_w1ts = clock; - GPIO.out_w1tc = data_mask | clock; + // New Inkplate6 panel doesn't need last clock + if (this->model_ != INKPLATE_6_V2) { + GPIO.out_w1ts = clock; + GPIO.out_w1tc = data_mask | clock; + } vscan_end_(); } delayMicroseconds(230); @@ -392,8 +400,11 @@ void Inkplate6::display1b_() { GPIO.out_w1ts = this->pin_lut_[data] | clock; GPIO.out_w1tc = data_mask | clock; } - GPIO.out_w1ts = clock; - GPIO.out_w1tc = data_mask | clock; + // New Inkplate6 panel doesn't need last clock + if (this->model_ != INKPLATE_6_V2) { + GPIO.out_w1ts = clock; + GPIO.out_w1tc = data_mask | clock; + } vscan_end_(); } delayMicroseconds(230); @@ -415,8 +426,11 @@ void Inkplate6::display1b_() { GPIO.out_w1ts = send | clock; GPIO.out_w1tc = data_mask | clock; } - GPIO.out_w1ts = send | clock; - GPIO.out_w1tc = data_mask | clock; + // New Inkplate6 panel doesn't need last clock + if (this->model_ != INKPLATE_6_V2) { + GPIO.out_w1ts = clock; + GPIO.out_w1tc = data_mask | clock; + } vscan_end_(); } delayMicroseconds(230); @@ -450,13 +464,14 @@ void Inkplate6::display3b_() { clean_fast_(1, 21); clean_fast_(2, 1); clean_fast_(0, 12); + clean_fast_(2, 1); } uint32_t clock = (1 << this->cl_pin_->get_pin()); uint32_t data_mask = this->get_data_pin_mask_(); uint32_t pos; uint32_t data; - uint8_t glut_size = this->model_ == INKPLATE_6_PLUS ? 9 : 8; + uint8_t glut_size = 9; for (int k = 0; k < glut_size; k++) { pos = this->get_buffer_length_(); vscan_start_(); @@ -479,8 +494,11 @@ void Inkplate6::display3b_() { GPIO.out_w1ts = data | clock; GPIO.out_w1tc = data_mask | clock; } - GPIO.out_w1ts = clock; - GPIO.out_w1tc = data_mask | clock; + // New Inkplate6 panel doesn't need last clock + if (this->model_ != INKPLATE_6_V2) { + GPIO.out_w1ts = clock; + GPIO.out_w1tc = data_mask | clock; + } vscan_end_(); } delayMicroseconds(230); @@ -517,10 +535,12 @@ bool Inkplate6::partial_update_() { } ESP_LOGV(TAG, "Partial update buffer built after (%ums)", millis() - start_time); + int rep = (this->model_ == INKPLATE_6_V2) ? 6 : 5; + eink_on_(); uint32_t clock = (1 << this->cl_pin_->get_pin()); uint32_t data_mask = this->get_data_pin_mask_(); - for (int k = 0; k < 5; k++) { + for (int k = 0; k < rep; k++) { vscan_start_(); const uint8_t *data_ptr = &this->partial_buffer_2_[(this->get_buffer_length_() * 2) - 1]; for (int i = 0; i < this->get_height_internal(); i++) { @@ -531,8 +551,11 @@ bool Inkplate6::partial_update_() { GPIO.out_w1ts = this->pin_lut_[data] | clock; GPIO.out_w1tc = data_mask | clock; } - GPIO.out_w1ts = clock; - GPIO.out_w1tc = data_mask | clock; + // New Inkplate6 panel doesn't need last clock + if (this->model_ != INKPLATE_6_V2) { + GPIO.out_w1ts = clock; + GPIO.out_w1tc = data_mask | clock; + } vscan_end_(); } delayMicroseconds(230); @@ -634,8 +657,11 @@ void Inkplate6::clean_fast_(uint8_t c, uint8_t rep) { GPIO.out_w1ts = clock; GPIO.out_w1tc = clock; } - GPIO.out_w1ts = send | clock; - GPIO.out_w1tc = clock; + // New Inkplate6 panel doesn't need last clock + if (this->model_ != INKPLATE_6_V2) { + GPIO.out_w1ts = send | clock; + GPIO.out_w1tc = clock; + } vscan_end_(); } delayMicroseconds(230); diff --git a/esphome/components/inkplate6/inkplate.h b/esphome/components/inkplate6/inkplate.h index e650b57631..565bd74710 100644 --- a/esphome/components/inkplate6/inkplate.h +++ b/esphome/components/inkplate6/inkplate.h @@ -14,6 +14,7 @@ enum InkplateModel : uint8_t { INKPLATE_6 = 0, INKPLATE_10 = 1, INKPLATE_6_PLUS = 2, + INKPLATE_6_V2 = 3, }; class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public i2c::I2CDevice { @@ -28,13 +29,42 @@ class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public const uint8_t pixelMaskLUT[8] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80}; const uint8_t pixelMaskGLUT[2] = {0x0F, 0xF0}; - const uint8_t waveform3Bit[8][8] = {{0, 1, 1, 0, 0, 1, 1, 0}, {0, 1, 2, 1, 1, 2, 1, 0}, {1, 1, 1, 2, 2, 1, 0, 0}, - {0, 0, 0, 1, 1, 1, 2, 0}, {2, 1, 1, 1, 2, 1, 2, 0}, {2, 2, 1, 1, 2, 1, 2, 0}, - {1, 1, 1, 2, 1, 2, 2, 0}, {0, 0, 0, 0, 0, 0, 2, 0}}; - const uint8_t waveform3Bit6Plus[8][9] = {{0, 0, 0, 0, 0, 2, 1, 1, 0}, {0, 0, 2, 1, 1, 1, 2, 1, 0}, - {0, 2, 2, 2, 1, 1, 2, 1, 0}, {0, 0, 2, 2, 2, 1, 2, 1, 0}, - {0, 0, 0, 0, 2, 2, 2, 1, 0}, {0, 0, 2, 1, 2, 1, 1, 2, 0}, - {0, 0, 2, 2, 2, 1, 1, 2, 0}, {0, 0, 0, 0, 2, 2, 2, 2, 0}}; + const uint8_t waveform3BitAll[4][8][9] = {// INKPLATE_6 + {{0, 1, 1, 0, 0, 1, 1, 0, 0}, + {0, 1, 2, 1, 1, 2, 1, 0, 0}, + {1, 1, 1, 2, 2, 1, 0, 0, 0}, + {0, 0, 0, 1, 1, 1, 2, 0, 0}, + {2, 1, 1, 1, 2, 1, 2, 0, 0}, + {2, 2, 1, 1, 2, 1, 2, 0, 0}, + {1, 1, 1, 2, 1, 2, 2, 0, 0}, + {0, 0, 0, 0, 0, 0, 2, 0, 0}}, + // INKPLATE_10 + {{0, 0, 0, 0, 0, 0, 0, 1, 0}, + {0, 0, 0, 2, 2, 2, 1, 1, 0}, + {0, 0, 2, 1, 1, 2, 2, 1, 0}, + {0, 1, 2, 2, 1, 2, 2, 1, 0}, + {0, 0, 2, 1, 2, 2, 2, 1, 0}, + {0, 2, 2, 2, 2, 2, 2, 1, 0}, + {0, 0, 0, 0, 0, 2, 1, 2, 0}, + {0, 0, 0, 2, 2, 2, 2, 2, 0}}, + // INKPLATE_6_PLUS + {{0, 0, 0, 0, 0, 2, 1, 1, 0}, + {0, 0, 2, 1, 1, 1, 2, 1, 0}, + {0, 2, 2, 2, 1, 1, 2, 1, 0}, + {0, 0, 2, 2, 2, 1, 2, 1, 0}, + {0, 0, 0, 0, 2, 2, 2, 1, 0}, + {0, 0, 2, 1, 2, 1, 1, 2, 0}, + {0, 0, 2, 2, 2, 1, 1, 2, 0}, + {0, 0, 0, 0, 2, 2, 2, 2, 0}}, + // INKPLATE_6_V2 + {{1, 0, 1, 0, 1, 1, 1, 0, 0}, + {0, 0, 0, 1, 1, 1, 1, 0, 0}, + {1, 1, 1, 1, 0, 2, 1, 0, 0}, + {1, 1, 1, 2, 2, 1, 1, 0, 0}, + {1, 1, 1, 1, 2, 2, 1, 0, 0}, + {0, 1, 1, 1, 2, 2, 1, 0, 0}, + {0, 0, 0, 0, 1, 1, 2, 0, 0}, + {0, 0, 0, 0, 0, 1, 2, 0, 0}}}; void set_greyscale(bool greyscale) { this->greyscale_ = greyscale; @@ -111,7 +141,7 @@ class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public void pins_as_outputs_(); int get_width_internal() override { - if (this->model_ == INKPLATE_6) { + if (this->model_ == INKPLATE_6 || this->model_ == INKPLATE_6_V2) { return 800; } else if (this->model_ == INKPLATE_10) { return 1200; @@ -122,7 +152,7 @@ class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public } int get_height_internal() override { - if (this->model_ == INKPLATE_6) { + if (this->model_ == INKPLATE_6 || this->model_ == INKPLATE_6_V2) { return 600; } else if (this->model_ == INKPLATE_10) { return 825;