mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 16:38:16 +01:00
Inkplate 6 support for ESPHome (#1283)
* Add Inkplate 6 support Inkplate 6 is e-paper display based on ESP32. This commit adds support for integrating Inkplate 6 into the ESPHome. Find more info here: inkplate.io * Greyscale working * Update inkplate.h * Fix formatting * Formatting * Update esphome/components/inkplate6/display.py Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> * Update esphome/components/inkplate6/display.py Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> * Fix some lint errors Ignore some lint errors Only allow on ESP32 * Update the codeowners file Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
52e13164b4
commit
6a99789c92
5 changed files with 930 additions and 0 deletions
|
@ -37,6 +37,7 @@ esphome/components/globals/* @esphome/core
|
||||||
esphome/components/gpio/* @esphome/core
|
esphome/components/gpio/* @esphome/core
|
||||||
esphome/components/homeassistant/* @OttoWinter
|
esphome/components/homeassistant/* @OttoWinter
|
||||||
esphome/components/i2c/* @esphome/core
|
esphome/components/i2c/* @esphome/core
|
||||||
|
esphome/components/inkplate6/* @jesserockz
|
||||||
esphome/components/integration/* @OttoWinter
|
esphome/components/integration/* @OttoWinter
|
||||||
esphome/components/interval/* @esphome/core
|
esphome/components/interval/* @esphome/core
|
||||||
esphome/components/json/* @OttoWinter
|
esphome/components/json/* @OttoWinter
|
||||||
|
|
1
esphome/components/inkplate6/__init__.py
Normal file
1
esphome/components/inkplate6/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
CODEOWNERS = ['@jesserockz']
|
141
esphome/components/inkplate6/display.py
Normal file
141
esphome/components/inkplate6/display.py
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
import esphome.codegen as cg
|
||||||
|
import esphome.config_validation as cv
|
||||||
|
from esphome import pins
|
||||||
|
from esphome.components import display, i2c
|
||||||
|
from esphome.const import CONF_FULL_UPDATE_EVERY, CONF_ID, CONF_LAMBDA, CONF_PAGES, \
|
||||||
|
CONF_WAKEUP_PIN, ESP_PLATFORM_ESP32
|
||||||
|
|
||||||
|
DEPENDENCIES = ['i2c']
|
||||||
|
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||||
|
|
||||||
|
CONF_DISPLAY_DATA_0_PIN = 'display_data_0_pin'
|
||||||
|
CONF_DISPLAY_DATA_1_PIN = 'display_data_1_pin'
|
||||||
|
CONF_DISPLAY_DATA_2_PIN = 'display_data_2_pin'
|
||||||
|
CONF_DISPLAY_DATA_3_PIN = 'display_data_3_pin'
|
||||||
|
CONF_DISPLAY_DATA_4_PIN = 'display_data_4_pin'
|
||||||
|
CONF_DISPLAY_DATA_5_PIN = 'display_data_5_pin'
|
||||||
|
CONF_DISPLAY_DATA_6_PIN = 'display_data_6_pin'
|
||||||
|
CONF_DISPLAY_DATA_7_PIN = 'display_data_7_pin'
|
||||||
|
|
||||||
|
CONF_CL_PIN = 'cl_pin'
|
||||||
|
CONF_CKV_PIN = 'ckv_pin'
|
||||||
|
CONF_GREYSCALE = 'greyscale'
|
||||||
|
CONF_GMOD_PIN = 'gmod_pin'
|
||||||
|
CONF_GPIO0_ENABLE_PIN = 'gpio0_enable_pin'
|
||||||
|
CONF_LE_PIN = 'le_pin'
|
||||||
|
CONF_OE_PIN = 'oe_pin'
|
||||||
|
CONF_PARTIAL_UPDATING = 'partial_updating'
|
||||||
|
CONF_POWERUP_PIN = 'powerup_pin'
|
||||||
|
CONF_SPH_PIN = 'sph_pin'
|
||||||
|
CONF_SPV_PIN = 'spv_pin'
|
||||||
|
CONF_VCOM_PIN = 'vcom_pin'
|
||||||
|
|
||||||
|
|
||||||
|
inkplate6_ns = cg.esphome_ns.namespace('inkplate6')
|
||||||
|
Inkplate6 = inkplate6_ns.class_('Inkplate6', cg.PollingComponent, i2c.I2CDevice,
|
||||||
|
display.DisplayBuffer)
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = cv.All(display.FULL_DISPLAY_SCHEMA.extend({
|
||||||
|
cv.GenerateID(): cv.declare_id(Inkplate6),
|
||||||
|
cv.Optional(CONF_GREYSCALE, default=False): cv.boolean,
|
||||||
|
cv.Optional(CONF_PARTIAL_UPDATING, default=True): cv.boolean,
|
||||||
|
cv.Optional(CONF_FULL_UPDATE_EVERY, default=10): cv.uint32_t,
|
||||||
|
# Control pins
|
||||||
|
cv.Required(CONF_CKV_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_GMOD_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_GPIO0_ENABLE_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_OE_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_POWERUP_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_SPH_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_SPV_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_VCOM_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Required(CONF_WAKEUP_PIN): pins.gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_CL_PIN, default=0): pins.internal_gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_LE_PIN, default=2): pins.internal_gpio_output_pin_schema,
|
||||||
|
# Data pins
|
||||||
|
cv.Optional(CONF_DISPLAY_DATA_0_PIN, default=4): pins.internal_gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_DISPLAY_DATA_1_PIN, default=5): pins.internal_gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_DISPLAY_DATA_2_PIN, default=18): pins.internal_gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_DISPLAY_DATA_3_PIN, default=19): pins.internal_gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_DISPLAY_DATA_4_PIN, default=23): pins.internal_gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_DISPLAY_DATA_5_PIN, default=25): pins.internal_gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_DISPLAY_DATA_6_PIN, default=26): pins.internal_gpio_output_pin_schema,
|
||||||
|
cv.Optional(CONF_DISPLAY_DATA_7_PIN, default=27): pins.internal_gpio_output_pin_schema,
|
||||||
|
}).extend(cv.polling_component_schema('5s').extend(i2c.i2c_device_schema(0x48))),
|
||||||
|
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA))
|
||||||
|
|
||||||
|
|
||||||
|
def to_code(config):
|
||||||
|
var = cg.new_Pvariable(config[CONF_ID])
|
||||||
|
|
||||||
|
yield cg.register_component(var, config)
|
||||||
|
yield display.register_display(var, config)
|
||||||
|
yield i2c.register_i2c_device(var, config)
|
||||||
|
|
||||||
|
if CONF_LAMBDA in config:
|
||||||
|
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(display.DisplayBufferRef, 'it')],
|
||||||
|
return_type=cg.void)
|
||||||
|
cg.add(var.set_writer(lambda_))
|
||||||
|
|
||||||
|
cg.add(var.set_greyscale(config[CONF_GREYSCALE]))
|
||||||
|
cg.add(var.set_partial_updating(config[CONF_PARTIAL_UPDATING]))
|
||||||
|
cg.add(var.set_full_update_every(config[CONF_FULL_UPDATE_EVERY]))
|
||||||
|
|
||||||
|
ckv = yield cg.gpio_pin_expression(config[CONF_CKV_PIN])
|
||||||
|
cg.add(var.set_ckv_pin(ckv))
|
||||||
|
|
||||||
|
gmod = yield cg.gpio_pin_expression(config[CONF_GMOD_PIN])
|
||||||
|
cg.add(var.set_gmod_pin(gmod))
|
||||||
|
|
||||||
|
gpio0_enable = yield cg.gpio_pin_expression(config[CONF_GPIO0_ENABLE_PIN])
|
||||||
|
cg.add(var.set_gpio0_enable_pin(gpio0_enable))
|
||||||
|
|
||||||
|
oe = yield cg.gpio_pin_expression(config[CONF_OE_PIN])
|
||||||
|
cg.add(var.set_oe_pin(oe))
|
||||||
|
|
||||||
|
powerup = yield cg.gpio_pin_expression(config[CONF_POWERUP_PIN])
|
||||||
|
cg.add(var.set_powerup_pin(powerup))
|
||||||
|
|
||||||
|
sph = yield cg.gpio_pin_expression(config[CONF_SPH_PIN])
|
||||||
|
cg.add(var.set_sph_pin(sph))
|
||||||
|
|
||||||
|
spv = yield cg.gpio_pin_expression(config[CONF_SPV_PIN])
|
||||||
|
cg.add(var.set_spv_pin(spv))
|
||||||
|
|
||||||
|
vcom = yield cg.gpio_pin_expression(config[CONF_VCOM_PIN])
|
||||||
|
cg.add(var.set_vcom_pin(vcom))
|
||||||
|
|
||||||
|
wakeup = yield cg.gpio_pin_expression(config[CONF_WAKEUP_PIN])
|
||||||
|
cg.add(var.set_wakeup_pin(wakeup))
|
||||||
|
|
||||||
|
cl = yield cg.gpio_pin_expression(config[CONF_CL_PIN])
|
||||||
|
cg.add(var.set_cl_pin(cl))
|
||||||
|
|
||||||
|
le = yield cg.gpio_pin_expression(config[CONF_LE_PIN])
|
||||||
|
cg.add(var.set_le_pin(le))
|
||||||
|
|
||||||
|
display_data_0 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_0_PIN])
|
||||||
|
cg.add(var.set_display_data_0_pin(display_data_0))
|
||||||
|
|
||||||
|
display_data_1 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_1_PIN])
|
||||||
|
cg.add(var.set_display_data_1_pin(display_data_1))
|
||||||
|
|
||||||
|
display_data_2 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_2_PIN])
|
||||||
|
cg.add(var.set_display_data_2_pin(display_data_2))
|
||||||
|
|
||||||
|
display_data_3 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_3_PIN])
|
||||||
|
cg.add(var.set_display_data_3_pin(display_data_3))
|
||||||
|
|
||||||
|
display_data_4 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_4_PIN])
|
||||||
|
cg.add(var.set_display_data_4_pin(display_data_4))
|
||||||
|
|
||||||
|
display_data_5 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_5_PIN])
|
||||||
|
cg.add(var.set_display_data_5_pin(display_data_5))
|
||||||
|
|
||||||
|
display_data_6 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_6_PIN])
|
||||||
|
cg.add(var.set_display_data_6_pin(display_data_6))
|
||||||
|
|
||||||
|
display_data_7 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_7_PIN])
|
||||||
|
cg.add(var.set_display_data_7_pin(display_data_7))
|
||||||
|
|
||||||
|
cg.add_build_flag('-DBOARD_HAS_PSRAM')
|
630
esphome/components/inkplate6/inkplate.cpp
Normal file
630
esphome/components/inkplate6/inkplate.cpp
Normal file
|
@ -0,0 +1,630 @@
|
||||||
|
#include "inkplate.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/application.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace inkplate6 {
|
||||||
|
|
||||||
|
static const char *TAG = "inkplate";
|
||||||
|
|
||||||
|
void Inkplate6::setup() {
|
||||||
|
this->initialize_();
|
||||||
|
|
||||||
|
this->vcom_pin_->setup();
|
||||||
|
this->powerup_pin_->setup();
|
||||||
|
this->wakeup_pin_->setup();
|
||||||
|
this->gpio0_enable_pin_->setup();
|
||||||
|
this->gpio0_enable_pin_->digital_write(true);
|
||||||
|
|
||||||
|
this->cl_pin_->setup();
|
||||||
|
this->le_pin_->setup();
|
||||||
|
this->ckv_pin_->setup();
|
||||||
|
this->gmod_pin_->setup();
|
||||||
|
this->oe_pin_->setup();
|
||||||
|
this->sph_pin_->setup();
|
||||||
|
this->spv_pin_->setup();
|
||||||
|
|
||||||
|
this->display_data_0_pin_->setup();
|
||||||
|
this->display_data_1_pin_->setup();
|
||||||
|
this->display_data_2_pin_->setup();
|
||||||
|
this->display_data_3_pin_->setup();
|
||||||
|
this->display_data_4_pin_->setup();
|
||||||
|
this->display_data_5_pin_->setup();
|
||||||
|
this->display_data_6_pin_->setup();
|
||||||
|
this->display_data_7_pin_->setup();
|
||||||
|
|
||||||
|
this->clean();
|
||||||
|
this->display();
|
||||||
|
}
|
||||||
|
void Inkplate6::initialize_() {
|
||||||
|
uint32_t buffer_size = this->get_buffer_length_();
|
||||||
|
|
||||||
|
if (this->partial_buffer_ != nullptr) {
|
||||||
|
free(this->partial_buffer_); // NOLINT
|
||||||
|
}
|
||||||
|
if (this->partial_buffer_2_ != nullptr) {
|
||||||
|
free(this->partial_buffer_2_); // NOLINT
|
||||||
|
}
|
||||||
|
if (this->buffer_ != nullptr) {
|
||||||
|
free(this->buffer_); // NOLINT
|
||||||
|
}
|
||||||
|
|
||||||
|
this->buffer_ = (uint8_t *) ps_malloc(buffer_size);
|
||||||
|
if (this->buffer_ == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate buffer for display!");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!this->greyscale_) {
|
||||||
|
this->partial_buffer_ = (uint8_t *) ps_malloc(buffer_size);
|
||||||
|
if (this->partial_buffer_ == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate partial buffer for display!");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->partial_buffer_2_ = (uint8_t *) ps_malloc(buffer_size * 2);
|
||||||
|
if (this->partial_buffer_2_ == nullptr) {
|
||||||
|
ESP_LOGE(TAG, "Could not allocate partial buffer 2 for display!");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memset(this->partial_buffer_, 0, buffer_size);
|
||||||
|
memset(this->partial_buffer_2_, 0, buffer_size * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(this->buffer_, 0, buffer_size);
|
||||||
|
}
|
||||||
|
float Inkplate6::get_setup_priority() const { return setup_priority::PROCESSOR; }
|
||||||
|
size_t Inkplate6::get_buffer_length_() {
|
||||||
|
if (this->greyscale_) {
|
||||||
|
return size_t(this->get_width_internal()) * size_t(this->get_height_internal()) / 2u;
|
||||||
|
} else {
|
||||||
|
return size_t(this->get_width_internal()) * size_t(this->get_height_internal()) / 8u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Inkplate6::update() {
|
||||||
|
this->do_update_();
|
||||||
|
|
||||||
|
if (this->full_update_every_ > 0 && this->partial_updates_ >= this->full_update_every_) {
|
||||||
|
this->block_partial_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->display();
|
||||||
|
}
|
||||||
|
void HOT Inkplate6::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;
|
||||||
|
|
||||||
|
if (this->greyscale_) {
|
||||||
|
int x1 = x / 2;
|
||||||
|
int x_sub = x % 2;
|
||||||
|
uint32_t pos = (x1 + y * (this->get_width_internal() / 2));
|
||||||
|
uint8_t current = this->buffer_[pos];
|
||||||
|
|
||||||
|
// float px = (0.2126 * (color.red / 255.0)) + (0.7152 * (color.green / 255.0)) + (0.0722 * (color.blue / 255.0));
|
||||||
|
// px = pow(px, 1.5);
|
||||||
|
// uint8_t gs = (uint8_t)(px*7);
|
||||||
|
|
||||||
|
uint8_t gs = ((color.red * 2126 / 10000) + (color.green * 7152 / 10000) + (color.blue * 722 / 10000)) >> 5;
|
||||||
|
this->buffer_[pos] = (pixelMaskGLUT[x_sub] & current) | (x_sub ? gs : gs << 4);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
int x1 = x / 8;
|
||||||
|
int x_sub = x % 8;
|
||||||
|
uint32_t pos = (x1 + y * (this->get_width_internal() / 8));
|
||||||
|
uint8_t current = this->partial_buffer_[pos];
|
||||||
|
this->partial_buffer_[pos] = (~pixelMaskLUT[x_sub] & current) | (color.is_on() ? 0 : pixelMaskLUT[x_sub]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Inkplate6::dump_config() {
|
||||||
|
LOG_DISPLAY("", "Inkplate", this);
|
||||||
|
ESP_LOGCONFIG(TAG, " Greyscale: %s", YESNO(this->greyscale_));
|
||||||
|
ESP_LOGCONFIG(TAG, " Partial Updating: %s", YESNO(this->partial_updating_));
|
||||||
|
ESP_LOGCONFIG(TAG, " Full Update Every: %d", this->full_update_every_);
|
||||||
|
// Log pins
|
||||||
|
LOG_PIN(" CKV Pin: ", this->ckv_pin_);
|
||||||
|
LOG_PIN(" CL Pin: ", this->cl_pin_);
|
||||||
|
LOG_PIN(" GPIO0 Enable Pin: ", this->gpio0_enable_pin_);
|
||||||
|
LOG_PIN(" GMOD Pin: ", this->gmod_pin_);
|
||||||
|
LOG_PIN(" LE Pin: ", this->le_pin_);
|
||||||
|
LOG_PIN(" OE Pin: ", this->oe_pin_);
|
||||||
|
LOG_PIN(" POWERUP Pin: ", this->powerup_pin_);
|
||||||
|
LOG_PIN(" SPH Pin: ", this->sph_pin_);
|
||||||
|
LOG_PIN(" SPV Pin: ", this->spv_pin_);
|
||||||
|
LOG_PIN(" VCOM Pin: ", this->vcom_pin_);
|
||||||
|
LOG_PIN(" WAKEUP Pin: ", this->wakeup_pin_);
|
||||||
|
|
||||||
|
LOG_PIN(" Data 0 Pin: ", this->display_data_0_pin_);
|
||||||
|
LOG_PIN(" Data 1 Pin: ", this->display_data_1_pin_);
|
||||||
|
LOG_PIN(" Data 2 Pin: ", this->display_data_2_pin_);
|
||||||
|
LOG_PIN(" Data 3 Pin: ", this->display_data_3_pin_);
|
||||||
|
LOG_PIN(" Data 4 Pin: ", this->display_data_4_pin_);
|
||||||
|
LOG_PIN(" Data 5 Pin: ", this->display_data_5_pin_);
|
||||||
|
LOG_PIN(" Data 6 Pin: ", this->display_data_6_pin_);
|
||||||
|
LOG_PIN(" Data 7 Pin: ", this->display_data_7_pin_);
|
||||||
|
|
||||||
|
LOG_UPDATE_INTERVAL(this);
|
||||||
|
}
|
||||||
|
void Inkplate6::eink_off_() {
|
||||||
|
ESP_LOGV(TAG, "Eink off called");
|
||||||
|
unsigned long start_time = millis();
|
||||||
|
if (panel_on_ == 0)
|
||||||
|
return;
|
||||||
|
panel_on_ = 0;
|
||||||
|
this->gmod_pin_->digital_write(false);
|
||||||
|
this->oe_pin_->digital_write(false);
|
||||||
|
|
||||||
|
GPIO.out &= ~(get_data_pin_mask_() | (1 << this->cl_pin_->get_pin()) | (1 << this->le_pin_->get_pin()));
|
||||||
|
|
||||||
|
this->sph_pin_->digital_write(false);
|
||||||
|
this->spv_pin_->digital_write(false);
|
||||||
|
|
||||||
|
this->powerup_pin_->digital_write(false);
|
||||||
|
this->wakeup_pin_->digital_write(false);
|
||||||
|
this->vcom_pin_->digital_write(false);
|
||||||
|
|
||||||
|
pins_z_state_();
|
||||||
|
}
|
||||||
|
void Inkplate6::eink_on_() {
|
||||||
|
ESP_LOGV(TAG, "Eink on called");
|
||||||
|
unsigned long start_time = millis();
|
||||||
|
if (panel_on_ == 1)
|
||||||
|
return;
|
||||||
|
panel_on_ = 1;
|
||||||
|
pins_as_outputs_();
|
||||||
|
this->wakeup_pin_->digital_write(true);
|
||||||
|
this->powerup_pin_->digital_write(true);
|
||||||
|
this->vcom_pin_->digital_write(true);
|
||||||
|
|
||||||
|
this->write_byte(0x01, 0x3F);
|
||||||
|
|
||||||
|
delay(40);
|
||||||
|
|
||||||
|
this->write_byte(0x0D, 0x80);
|
||||||
|
|
||||||
|
delay(2);
|
||||||
|
|
||||||
|
this->read_byte(0x00, &temperature_, 0);
|
||||||
|
|
||||||
|
this->le_pin_->digital_write(false);
|
||||||
|
this->oe_pin_->digital_write(false);
|
||||||
|
this->cl_pin_->digital_write(false);
|
||||||
|
this->sph_pin_->digital_write(true);
|
||||||
|
this->gmod_pin_->digital_write(true);
|
||||||
|
this->spv_pin_->digital_write(true);
|
||||||
|
this->ckv_pin_->digital_write(false);
|
||||||
|
this->oe_pin_->digital_write(true);
|
||||||
|
}
|
||||||
|
void Inkplate6::fill(Color color) {
|
||||||
|
ESP_LOGV(TAG, "Fill called");
|
||||||
|
unsigned long start_time = millis();
|
||||||
|
|
||||||
|
if (this->greyscale_) {
|
||||||
|
uint8_t fill = ((color.red * 2126 / 10000) + (color.green * 7152 / 10000) + (color.blue * 722 / 10000)) >> 5;
|
||||||
|
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
|
||||||
|
this->buffer_[i] = (fill << 4) | fill;
|
||||||
|
} else {
|
||||||
|
uint8_t fill = color.is_on() ? 0x00 : 0xFF;
|
||||||
|
for (uint32_t i = 0; i < this->get_buffer_length_(); i++)
|
||||||
|
this->partial_buffer_[i] = fill;
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGV(TAG, "Fill finished (%lums)", millis() - start_time);
|
||||||
|
}
|
||||||
|
void Inkplate6::display() {
|
||||||
|
ESP_LOGV(TAG, "Display called");
|
||||||
|
unsigned long start_time = millis();
|
||||||
|
|
||||||
|
if (this->greyscale_) {
|
||||||
|
this->display3b_();
|
||||||
|
} else {
|
||||||
|
if (this->partial_updating_ && this->partial_update_()) {
|
||||||
|
ESP_LOGV(TAG, "Display finished (partial) (%lums)", millis() - start_time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->display1b_();
|
||||||
|
}
|
||||||
|
ESP_LOGV(TAG, "Display finished (full) (%lums)", millis() - start_time);
|
||||||
|
}
|
||||||
|
void Inkplate6::display1b_() {
|
||||||
|
ESP_LOGV(TAG, "Display1b called");
|
||||||
|
unsigned long start_time = millis();
|
||||||
|
|
||||||
|
for (int i = 0; i < this->get_buffer_length_(); i++) {
|
||||||
|
this->buffer_[i] &= this->partial_buffer_[i];
|
||||||
|
this->buffer_[i] |= this->partial_buffer_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t pos;
|
||||||
|
uint32_t send;
|
||||||
|
uint8_t data;
|
||||||
|
uint8_t buffer_value;
|
||||||
|
eink_on_();
|
||||||
|
clean_fast_(0, 1);
|
||||||
|
clean_fast_(1, 5);
|
||||||
|
clean_fast_(2, 1);
|
||||||
|
clean_fast_(0, 5);
|
||||||
|
clean_fast_(2, 1);
|
||||||
|
clean_fast_(1, 12);
|
||||||
|
clean_fast_(2, 1);
|
||||||
|
clean_fast_(0, 11);
|
||||||
|
|
||||||
|
ESP_LOGV(TAG, "Display1b start loops (%lums)", millis() - start_time);
|
||||||
|
for (int k = 0; k < 3; k++) {
|
||||||
|
pos = this->get_buffer_length_() - 1;
|
||||||
|
vscan_start_();
|
||||||
|
for (int i = 0; i < this->get_height_internal(); i++) {
|
||||||
|
buffer_value = this->buffer_[pos];
|
||||||
|
data = LUTB[(buffer_value >> 4) & 0x0F];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
hscan_start_(send);
|
||||||
|
data = LUTB[buffer_value & 0x0F];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
pos--;
|
||||||
|
|
||||||
|
for (int j = 0; j < (this->get_width_internal() / 8) - 1; j++) {
|
||||||
|
buffer_value = this->buffer_[pos];
|
||||||
|
data = LUTB[(buffer_value >> 4) & 0x0F];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
data = LUTB[buffer_value & 0x0F];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
pos--;
|
||||||
|
}
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
vscan_end_();
|
||||||
|
}
|
||||||
|
delayMicroseconds(230);
|
||||||
|
}
|
||||||
|
ESP_LOGV(TAG, "Display1b first loop x %d (%lums)", 3, millis() - start_time);
|
||||||
|
|
||||||
|
pos = this->get_buffer_length_() - 1;
|
||||||
|
vscan_start_();
|
||||||
|
for (int i = 0; i < this->get_height_internal(); i++) {
|
||||||
|
buffer_value = this->buffer_[pos];
|
||||||
|
data = LUT2[(buffer_value >> 4) & 0x0F];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
hscan_start_(send);
|
||||||
|
data = LUT2[buffer_value & 0x0F];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
pos--;
|
||||||
|
for (int j = 0; j < (this->get_width_internal() / 8) - 1; j++) {
|
||||||
|
buffer_value = this->buffer_[pos];
|
||||||
|
data = LUT2[(buffer_value >> 4) & 0x0F];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
data = LUT2[buffer_value & 0x0F];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
pos--;
|
||||||
|
}
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
vscan_end_();
|
||||||
|
}
|
||||||
|
delayMicroseconds(230);
|
||||||
|
ESP_LOGV(TAG, "Display1b second loop (%lums)", millis() - start_time);
|
||||||
|
|
||||||
|
vscan_start_();
|
||||||
|
for (int i = 0; i < this->get_height_internal(); i++) {
|
||||||
|
buffer_value = this->buffer_[pos];
|
||||||
|
data = 0b00000000;
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
hscan_start_(send);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
for (int j = 0; j < (this->get_width_internal() / 8) - 1; j++) {
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
}
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
vscan_end_();
|
||||||
|
}
|
||||||
|
delayMicroseconds(230);
|
||||||
|
ESP_LOGV(TAG, "Display1b third loop (%lums)", millis() - start_time);
|
||||||
|
|
||||||
|
vscan_start_();
|
||||||
|
eink_off_();
|
||||||
|
this->block_partial_ = false;
|
||||||
|
this->partial_updates_ = 0;
|
||||||
|
ESP_LOGV(TAG, "Display1b finished (%lums)", millis() - start_time);
|
||||||
|
}
|
||||||
|
void Inkplate6::display3b_() {
|
||||||
|
ESP_LOGV(TAG, "Display3b called");
|
||||||
|
unsigned long start_time = millis();
|
||||||
|
|
||||||
|
eink_on_();
|
||||||
|
clean_fast_(0, 1);
|
||||||
|
clean_fast_(1, 12);
|
||||||
|
clean_fast_(2, 1);
|
||||||
|
clean_fast_(0, 11);
|
||||||
|
clean_fast_(2, 1);
|
||||||
|
clean_fast_(1, 12);
|
||||||
|
clean_fast_(2, 1);
|
||||||
|
clean_fast_(0, 11);
|
||||||
|
|
||||||
|
for (int k = 0; k < 8; k++) {
|
||||||
|
uint32_t pos = this->get_buffer_length_() - 1;
|
||||||
|
uint32_t send;
|
||||||
|
uint8_t pix1;
|
||||||
|
uint8_t pix2;
|
||||||
|
uint8_t pix3;
|
||||||
|
uint8_t pix4;
|
||||||
|
uint8_t pixel;
|
||||||
|
uint8_t pixel2;
|
||||||
|
|
||||||
|
vscan_start_();
|
||||||
|
for (int i = 0; i < this->get_height_internal(); i++) {
|
||||||
|
pix1 = this->buffer_[pos--];
|
||||||
|
pix2 = this->buffer_[pos--];
|
||||||
|
pix3 = this->buffer_[pos--];
|
||||||
|
pix4 = this->buffer_[pos--];
|
||||||
|
pixel = (waveform3Bit[pix1 & 0x07][k] << 6) | (waveform3Bit[(pix1 >> 4) & 0x07][k] << 4) |
|
||||||
|
(waveform3Bit[pix2 & 0x07][k] << 2) | (waveform3Bit[(pix2 >> 4) & 0x07][k] << 0);
|
||||||
|
pixel2 = (waveform3Bit[pix3 & 0x07][k] << 6) | (waveform3Bit[(pix3 >> 4) & 0x07][k] << 4) |
|
||||||
|
(waveform3Bit[pix4 & 0x07][k] << 2) | (waveform3Bit[(pix4 >> 4) & 0x07][k] << 0);
|
||||||
|
|
||||||
|
send = ((pixel & B00000011) << 4) | (((pixel & B00001100) >> 2) << 18) | (((pixel & B00010000) >> 4) << 23) |
|
||||||
|
(((pixel & B11100000) >> 5) << 25);
|
||||||
|
hscan_start_(send);
|
||||||
|
send = ((pixel2 & B00000011) << 4) | (((pixel2 & B00001100) >> 2) << 18) | (((pixel2 & B00010000) >> 4) << 23) |
|
||||||
|
(((pixel2 & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
|
||||||
|
for (int j = 0; j < (this->get_width_internal() / 8) - 1; j++) {
|
||||||
|
pix1 = this->buffer_[pos--];
|
||||||
|
pix2 = this->buffer_[pos--];
|
||||||
|
pix3 = this->buffer_[pos--];
|
||||||
|
pix4 = this->buffer_[pos--];
|
||||||
|
pixel = (waveform3Bit[pix1 & 0x07][k] << 6) | (waveform3Bit[(pix1 >> 4) & 0x07][k] << 4) |
|
||||||
|
(waveform3Bit[pix2 & 0x07][k] << 2) | (waveform3Bit[(pix2 >> 4) & 0x07][k] << 0);
|
||||||
|
pixel2 = (waveform3Bit[pix3 & 0x07][k] << 6) | (waveform3Bit[(pix3 >> 4) & 0x07][k] << 4) |
|
||||||
|
(waveform3Bit[pix4 & 0x07][k] << 2) | (waveform3Bit[(pix4 >> 4) & 0x07][k] << 0);
|
||||||
|
|
||||||
|
send = ((pixel & B00000011) << 4) | (((pixel & B00001100) >> 2) << 18) | (((pixel & B00010000) >> 4) << 23) |
|
||||||
|
(((pixel & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
|
||||||
|
send = ((pixel2 & B00000011) << 4) | (((pixel2 & B00001100) >> 2) << 18) | (((pixel2 & B00010000) >> 4) << 23) |
|
||||||
|
(((pixel2 & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
}
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
vscan_end_();
|
||||||
|
}
|
||||||
|
delayMicroseconds(230);
|
||||||
|
}
|
||||||
|
clean_fast_(2, 1);
|
||||||
|
clean_fast_(3, 1);
|
||||||
|
vscan_start_();
|
||||||
|
eink_off_();
|
||||||
|
ESP_LOGV(TAG, "Display3b finished (%lums)", millis() - start_time);
|
||||||
|
}
|
||||||
|
bool Inkplate6::partial_update_() {
|
||||||
|
ESP_LOGV(TAG, "Partial update called");
|
||||||
|
unsigned long start_time = millis();
|
||||||
|
if (this->greyscale_)
|
||||||
|
return false;
|
||||||
|
if (this->block_partial_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this->partial_updates_++;
|
||||||
|
|
||||||
|
uint16_t pos = this->get_buffer_length_() - 1;
|
||||||
|
uint32_t send;
|
||||||
|
uint8_t data;
|
||||||
|
uint8_t diffw, diffb;
|
||||||
|
uint32_t n = (this->get_buffer_length_() * 2) - 1;
|
||||||
|
|
||||||
|
for (int i = 0; i < this->get_height_internal(); i++) {
|
||||||
|
for (int j = 0; j < (this->get_width_internal() / 8); j++) {
|
||||||
|
diffw = (this->buffer_[pos] ^ this->partial_buffer_[pos]) & ~(this->partial_buffer_[pos]);
|
||||||
|
diffb = (this->buffer_[pos] ^ this->partial_buffer_[pos]) & this->partial_buffer_[pos];
|
||||||
|
pos--;
|
||||||
|
this->partial_buffer_2_[n--] = LUTW[diffw >> 4] & LUTB[diffb >> 4];
|
||||||
|
this->partial_buffer_2_[n--] = LUTW[diffw & 0x0F] & LUTB[diffb & 0x0F];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ESP_LOGV(TAG, "Partial update buffer built after (%lums)", millis() - start_time);
|
||||||
|
|
||||||
|
eink_on_();
|
||||||
|
for (int k = 0; k < 5; k++) {
|
||||||
|
vscan_start_();
|
||||||
|
n = (this->get_buffer_length_() * 2) - 1;
|
||||||
|
for (int i = 0; i < this->get_height_internal(); i++) {
|
||||||
|
data = this->partial_buffer_2_[n--];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
hscan_start_(send);
|
||||||
|
for (int j = 0; j < (this->get_width_internal() / 4) - 1; j++) {
|
||||||
|
data = this->partial_buffer_2_[n--];
|
||||||
|
send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
}
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
vscan_end_();
|
||||||
|
}
|
||||||
|
delayMicroseconds(230);
|
||||||
|
ESP_LOGV(TAG, "Partial update loop k=%d (%lums)", k, millis() - start_time);
|
||||||
|
}
|
||||||
|
clean_fast_(2, 2);
|
||||||
|
clean_fast_(3, 1);
|
||||||
|
vscan_start_();
|
||||||
|
eink_off_();
|
||||||
|
|
||||||
|
for (int i = 0; i < this->get_buffer_length_(); i++) {
|
||||||
|
this->buffer_[i] = this->partial_buffer_[i];
|
||||||
|
}
|
||||||
|
ESP_LOGV(TAG, "Partial update finished (%lums)", millis() - start_time);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void Inkplate6::vscan_start_() {
|
||||||
|
this->ckv_pin_->digital_write(true);
|
||||||
|
delayMicroseconds(7);
|
||||||
|
this->spv_pin_->digital_write(false);
|
||||||
|
delayMicroseconds(10);
|
||||||
|
this->ckv_pin_->digital_write(false);
|
||||||
|
delayMicroseconds(0);
|
||||||
|
this->ckv_pin_->digital_write(true);
|
||||||
|
delayMicroseconds(8);
|
||||||
|
this->spv_pin_->digital_write(true);
|
||||||
|
delayMicroseconds(10);
|
||||||
|
this->ckv_pin_->digital_write(false);
|
||||||
|
delayMicroseconds(0);
|
||||||
|
this->ckv_pin_->digital_write(true);
|
||||||
|
delayMicroseconds(18);
|
||||||
|
this->ckv_pin_->digital_write(false);
|
||||||
|
delayMicroseconds(0);
|
||||||
|
this->ckv_pin_->digital_write(true);
|
||||||
|
delayMicroseconds(18);
|
||||||
|
this->ckv_pin_->digital_write(false);
|
||||||
|
delayMicroseconds(0);
|
||||||
|
this->ckv_pin_->digital_write(true);
|
||||||
|
}
|
||||||
|
void Inkplate6::vscan_write_() {
|
||||||
|
this->ckv_pin_->digital_write(false);
|
||||||
|
this->le_pin_->digital_write(true);
|
||||||
|
this->le_pin_->digital_write(false);
|
||||||
|
delayMicroseconds(0);
|
||||||
|
this->sph_pin_->digital_write(false);
|
||||||
|
this->cl_pin_->digital_write(true);
|
||||||
|
this->cl_pin_->digital_write(false);
|
||||||
|
this->sph_pin_->digital_write(true);
|
||||||
|
this->ckv_pin_->digital_write(true);
|
||||||
|
}
|
||||||
|
void Inkplate6::hscan_start_(uint32_t d) {
|
||||||
|
this->sph_pin_->digital_write(false);
|
||||||
|
GPIO.out_w1ts = (d) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
this->sph_pin_->digital_write(true);
|
||||||
|
}
|
||||||
|
void Inkplate6::vscan_end_() {
|
||||||
|
this->ckv_pin_->digital_write(false);
|
||||||
|
this->le_pin_->digital_write(true);
|
||||||
|
this->le_pin_->digital_write(false);
|
||||||
|
delayMicroseconds(1);
|
||||||
|
this->ckv_pin_->digital_write(true);
|
||||||
|
}
|
||||||
|
void Inkplate6::clean() {
|
||||||
|
ESP_LOGV(TAG, "Clean called");
|
||||||
|
unsigned long start_time = millis();
|
||||||
|
|
||||||
|
eink_on_();
|
||||||
|
clean_fast_(0, 1); // White
|
||||||
|
clean_fast_(0, 8); // White to White
|
||||||
|
clean_fast_(0, 1); // White to Black
|
||||||
|
clean_fast_(0, 8); // Black to Black
|
||||||
|
clean_fast_(2, 1); // Black to White
|
||||||
|
clean_fast_(1, 10); // White to White
|
||||||
|
ESP_LOGV(TAG, "Clean finished (%lums)", millis() - start_time);
|
||||||
|
}
|
||||||
|
void Inkplate6::clean_fast_(uint8_t c, uint8_t rep) {
|
||||||
|
ESP_LOGV(TAG, "Clean fast called with: (%d, %d)", c, rep);
|
||||||
|
unsigned long start_time = millis();
|
||||||
|
|
||||||
|
eink_on_();
|
||||||
|
uint8_t data = 0;
|
||||||
|
if (c == 0) // White
|
||||||
|
data = B10101010;
|
||||||
|
else if (c == 1) // Black
|
||||||
|
data = B01010101;
|
||||||
|
else if (c == 2) // Discharge
|
||||||
|
data = B00000000;
|
||||||
|
else if (c == 3) // Skip
|
||||||
|
data = B11111111;
|
||||||
|
|
||||||
|
uint32_t send = ((data & B00000011) << 4) | (((data & B00001100) >> 2) << 18) | (((data & B00010000) >> 4) << 23) |
|
||||||
|
(((data & B11100000) >> 5) << 25);
|
||||||
|
|
||||||
|
for (int k = 0; k < rep; k++) {
|
||||||
|
vscan_start_();
|
||||||
|
for (int i = 0; i < this->get_height_internal(); i++) {
|
||||||
|
hscan_start_(send);
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
for (int j = 0; j < this->get_width_internal() / 8; j++) {
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
}
|
||||||
|
GPIO.out_w1ts = (send) | (1 << this->cl_pin_->get_pin());
|
||||||
|
GPIO.out_w1tc = get_data_pin_mask_() | (1 << this->cl_pin_->get_pin());
|
||||||
|
vscan_end_();
|
||||||
|
}
|
||||||
|
delayMicroseconds(230);
|
||||||
|
ESP_LOGV(TAG, "Clean fast rep loop %d finished (%lums)", k, millis() - start_time);
|
||||||
|
}
|
||||||
|
ESP_LOGV(TAG, "Clean fast finished (%lums)", millis() - start_time);
|
||||||
|
}
|
||||||
|
void Inkplate6::pins_z_state_() {
|
||||||
|
this->ckv_pin_->pin_mode(INPUT);
|
||||||
|
this->sph_pin_->pin_mode(INPUT);
|
||||||
|
|
||||||
|
this->oe_pin_->pin_mode(INPUT);
|
||||||
|
this->gmod_pin_->pin_mode(INPUT);
|
||||||
|
this->spv_pin_->pin_mode(INPUT);
|
||||||
|
|
||||||
|
this->display_data_0_pin_->pin_mode(INPUT);
|
||||||
|
this->display_data_1_pin_->pin_mode(INPUT);
|
||||||
|
this->display_data_2_pin_->pin_mode(INPUT);
|
||||||
|
this->display_data_3_pin_->pin_mode(INPUT);
|
||||||
|
this->display_data_4_pin_->pin_mode(INPUT);
|
||||||
|
this->display_data_5_pin_->pin_mode(INPUT);
|
||||||
|
this->display_data_6_pin_->pin_mode(INPUT);
|
||||||
|
this->display_data_7_pin_->pin_mode(INPUT);
|
||||||
|
}
|
||||||
|
void Inkplate6::pins_as_outputs_() {
|
||||||
|
this->ckv_pin_->pin_mode(OUTPUT);
|
||||||
|
this->sph_pin_->pin_mode(OUTPUT);
|
||||||
|
|
||||||
|
this->oe_pin_->pin_mode(OUTPUT);
|
||||||
|
this->gmod_pin_->pin_mode(OUTPUT);
|
||||||
|
this->spv_pin_->pin_mode(OUTPUT);
|
||||||
|
|
||||||
|
this->display_data_0_pin_->pin_mode(OUTPUT);
|
||||||
|
this->display_data_1_pin_->pin_mode(OUTPUT);
|
||||||
|
this->display_data_2_pin_->pin_mode(OUTPUT);
|
||||||
|
this->display_data_3_pin_->pin_mode(OUTPUT);
|
||||||
|
this->display_data_4_pin_->pin_mode(OUTPUT);
|
||||||
|
this->display_data_5_pin_->pin_mode(OUTPUT);
|
||||||
|
this->display_data_6_pin_->pin_mode(OUTPUT);
|
||||||
|
this->display_data_7_pin_->pin_mode(OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace inkplate6
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif
|
157
esphome/components/inkplate6/inkplate.h
Normal file
157
esphome/components/inkplate6/inkplate.h
Normal file
|
@ -0,0 +1,157 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/component.h"
|
||||||
|
#include "esphome/components/i2c/i2c.h"
|
||||||
|
#include "esphome/components/display/display_buffer.h"
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace inkplate6 {
|
||||||
|
|
||||||
|
class Inkplate6 : public PollingComponent, public display::DisplayBuffer, public i2c::I2CDevice {
|
||||||
|
public:
|
||||||
|
const uint8_t LUT2[16] = {B10101010, B10101001, B10100110, B10100101, B10011010, B10011001, B10010110, B10010101,
|
||||||
|
B01101010, B01101001, B01100110, B01100101, B01011010, B01011001, B01010110, B01010101};
|
||||||
|
const uint8_t LUTW[16] = {B11111111, B11111110, B11111011, B11111010, B11101111, B11101110, B11101011, B11101010,
|
||||||
|
B10111111, B10111110, B10111011, B10111010, B10101111, B10101110, B10101011, B10101010};
|
||||||
|
const uint8_t LUTB[16] = {B11111111, B11111101, B11110111, B11110101, B11011111, B11011101, B11010111, B11010101,
|
||||||
|
B01111111, B01111101, B01110111, B01110101, B01011111, B01011101, B01010111, B01010101};
|
||||||
|
const uint8_t pixelMaskLUT[8] = {B00000001, B00000010, B00000100, B00001000,
|
||||||
|
B00010000, B00100000, B01000000, B10000000};
|
||||||
|
const uint8_t pixelMaskGLUT[2] = {B00001111, B11110000};
|
||||||
|
const uint8_t waveform3Bit[8][8] = {{0, 0, 0, 0, 1, 1, 1, 0}, {1, 2, 2, 2, 1, 1, 1, 0}, {0, 1, 2, 1, 1, 2, 1, 0},
|
||||||
|
{0, 2, 1, 2, 1, 2, 1, 0}, {0, 0, 0, 1, 1, 1, 2, 0}, {2, 1, 1, 1, 2, 1, 2, 0},
|
||||||
|
{1, 1, 1, 2, 1, 2, 2, 0}, {0, 0, 0, 0, 0, 0, 2, 0}};
|
||||||
|
const uint32_t waveform[50] = {
|
||||||
|
0x00000008, 0x00000008, 0x00200408, 0x80281888, 0x60a81898, 0x60a8a8a8, 0x60a8a8a8, 0x6068a868, 0x6868a868,
|
||||||
|
0x6868a868, 0x68686868, 0x6a686868, 0x5a686868, 0x5a686868, 0x5a586a68, 0x5a5a6a68, 0x5a5a6a68, 0x55566a68,
|
||||||
|
0x55565a64, 0x55555654, 0x55555556, 0x55555556, 0x55555556, 0x55555516, 0x55555596, 0x15555595, 0x95955595,
|
||||||
|
0x95959595, 0x95949495, 0x94949495, 0x94949495, 0xa4949494, 0x9494a4a4, 0x84a49494, 0x84948484, 0x84848484,
|
||||||
|
0x84848484, 0x84848484, 0xa5a48484, 0xa9a4a4a8, 0xa9a8a8a8, 0xa5a9a9a4, 0xa5a5a5a4, 0xa1a5a5a1, 0xa9a9a9a9,
|
||||||
|
0xa9a9a9a9, 0xa9a9a9a9, 0xa9a9a9a9, 0x15151515, 0x11111111};
|
||||||
|
|
||||||
|
void set_greyscale(bool greyscale) {
|
||||||
|
this->greyscale_ = greyscale;
|
||||||
|
this->initialize_();
|
||||||
|
this->block_partial_ = true;
|
||||||
|
}
|
||||||
|
void set_partial_updating(bool partial_updating) { this->partial_updating_ = partial_updating; }
|
||||||
|
void set_full_update_every(uint32_t full_update_every) { this->full_update_every_ = full_update_every; }
|
||||||
|
|
||||||
|
void set_display_data_0_pin(GPIOPin *data) { this->display_data_0_pin_ = data; }
|
||||||
|
void set_display_data_1_pin(GPIOPin *data) { this->display_data_1_pin_ = data; }
|
||||||
|
void set_display_data_2_pin(GPIOPin *data) { this->display_data_2_pin_ = data; }
|
||||||
|
void set_display_data_3_pin(GPIOPin *data) { this->display_data_3_pin_ = data; }
|
||||||
|
void set_display_data_4_pin(GPIOPin *data) { this->display_data_4_pin_ = data; }
|
||||||
|
void set_display_data_5_pin(GPIOPin *data) { this->display_data_5_pin_ = data; }
|
||||||
|
void set_display_data_6_pin(GPIOPin *data) { this->display_data_6_pin_ = data; }
|
||||||
|
void set_display_data_7_pin(GPIOPin *data) { this->display_data_7_pin_ = data; }
|
||||||
|
|
||||||
|
void set_ckv_pin(GPIOPin *ckv) { this->ckv_pin_ = ckv; }
|
||||||
|
void set_cl_pin(GPIOPin *cl) { this->cl_pin_ = cl; }
|
||||||
|
void set_gpio0_enable_pin(GPIOPin *gpio0_enable) { this->gpio0_enable_pin_ = gpio0_enable; }
|
||||||
|
void set_gmod_pin(GPIOPin *gmod) { this->gmod_pin_ = gmod; }
|
||||||
|
void set_le_pin(GPIOPin *le) { this->le_pin_ = le; }
|
||||||
|
void set_oe_pin(GPIOPin *oe) { this->oe_pin_ = oe; }
|
||||||
|
void set_powerup_pin(GPIOPin *powerup) { this->powerup_pin_ = powerup; }
|
||||||
|
void set_sph_pin(GPIOPin *sph) { this->sph_pin_ = sph; }
|
||||||
|
void set_spv_pin(GPIOPin *spv) { this->spv_pin_ = spv; }
|
||||||
|
void set_vcom_pin(GPIOPin *vcom) { this->vcom_pin_ = vcom; }
|
||||||
|
void set_wakeup_pin(GPIOPin *wakeup) { this->wakeup_pin_ = wakeup; }
|
||||||
|
|
||||||
|
float get_setup_priority() const override;
|
||||||
|
|
||||||
|
void dump_config() override;
|
||||||
|
|
||||||
|
void display();
|
||||||
|
void clean();
|
||||||
|
void fill(Color color) override;
|
||||||
|
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
void setup() override;
|
||||||
|
|
||||||
|
uint8_t get_panel_state() { return this->panel_on_; }
|
||||||
|
bool get_greyscale() { return this->greyscale_; }
|
||||||
|
bool get_partial_updating() { return this->partial_updating_; }
|
||||||
|
uint8_t get_temperature() { return this->temperature_; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void draw_absolute_pixel_internal(int x, int y, Color color) override;
|
||||||
|
void display1b_();
|
||||||
|
void display3b_();
|
||||||
|
void initialize_();
|
||||||
|
bool partial_update_();
|
||||||
|
void clean_fast_(uint8_t c, uint8_t rep);
|
||||||
|
|
||||||
|
void hscan_start_(uint32_t d);
|
||||||
|
void vscan_end_();
|
||||||
|
void vscan_start_();
|
||||||
|
void vscan_write_();
|
||||||
|
|
||||||
|
void eink_off_();
|
||||||
|
void eink_on_();
|
||||||
|
|
||||||
|
void setup_pins_();
|
||||||
|
void pins_z_state_();
|
||||||
|
void pins_as_outputs_();
|
||||||
|
|
||||||
|
int get_width_internal() override { return 800; }
|
||||||
|
|
||||||
|
int get_height_internal() override { return 600; }
|
||||||
|
|
||||||
|
size_t get_buffer_length_();
|
||||||
|
|
||||||
|
int get_data_pin_mask_() {
|
||||||
|
int data = 0;
|
||||||
|
data |= (1 << this->display_data_0_pin_->get_pin());
|
||||||
|
data |= (1 << this->display_data_1_pin_->get_pin());
|
||||||
|
data |= (1 << this->display_data_2_pin_->get_pin());
|
||||||
|
data |= (1 << this->display_data_3_pin_->get_pin());
|
||||||
|
data |= (1 << this->display_data_4_pin_->get_pin());
|
||||||
|
data |= (1 << this->display_data_5_pin_->get_pin());
|
||||||
|
data |= (1 << this->display_data_6_pin_->get_pin());
|
||||||
|
data |= (1 << this->display_data_7_pin_->get_pin());
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t panel_on_ = 0;
|
||||||
|
uint8_t temperature_;
|
||||||
|
|
||||||
|
uint8_t *partial_buffer_{nullptr};
|
||||||
|
uint8_t *partial_buffer_2_{nullptr};
|
||||||
|
|
||||||
|
uint32_t full_update_every_;
|
||||||
|
uint32_t partial_updates_{0};
|
||||||
|
|
||||||
|
bool block_partial_;
|
||||||
|
bool greyscale_;
|
||||||
|
bool partial_updating_;
|
||||||
|
|
||||||
|
GPIOPin *display_data_0_pin_;
|
||||||
|
GPIOPin *display_data_1_pin_;
|
||||||
|
GPIOPin *display_data_2_pin_;
|
||||||
|
GPIOPin *display_data_3_pin_;
|
||||||
|
GPIOPin *display_data_4_pin_;
|
||||||
|
GPIOPin *display_data_5_pin_;
|
||||||
|
GPIOPin *display_data_6_pin_;
|
||||||
|
GPIOPin *display_data_7_pin_;
|
||||||
|
|
||||||
|
GPIOPin *ckv_pin_;
|
||||||
|
GPIOPin *cl_pin_;
|
||||||
|
GPIOPin *gpio0_enable_pin_;
|
||||||
|
GPIOPin *gmod_pin_;
|
||||||
|
GPIOPin *le_pin_;
|
||||||
|
GPIOPin *oe_pin_;
|
||||||
|
GPIOPin *powerup_pin_;
|
||||||
|
GPIOPin *sph_pin_;
|
||||||
|
GPIOPin *spv_pin_;
|
||||||
|
GPIOPin *vcom_pin_;
|
||||||
|
GPIOPin *wakeup_pin_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace inkplate6
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue