mirror of
https://github.com/esphome/esphome.git
synced 2025-10-10 13:53:49 +01:00
[inkplate] Rename component and fix grayscale (#10200)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -234,7 +234,7 @@ esphome/components/ina2xx_base/* @latonita
|
||||
esphome/components/ina2xx_i2c/* @latonita
|
||||
esphome/components/ina2xx_spi/* @latonita
|
||||
esphome/components/inkbird_ibsth1_mini/* @fkirill
|
||||
esphome/components/inkplate6/* @jesserockz
|
||||
esphome/components/inkplate/* @jesserockz @JosipKuci
|
||||
esphome/components/integration/* @OttoWinter
|
||||
esphome/components/internal_temperature/* @Mat931
|
||||
esphome/components/interval/* @esphome/core
|
||||
|
1
esphome/components/inkplate/__init__.py
Normal file
1
esphome/components/inkplate/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
CODEOWNERS = ["@jesserockz", "@JosipKuci"]
|
105
esphome/components/inkplate/const.py
Normal file
105
esphome/components/inkplate/const.py
Normal file
@@ -0,0 +1,105 @@
|
||||
WAVEFORMS = {
|
||||
"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),
|
||||
),
|
||||
"inkplate_5": (
|
||||
(0, 0, 1, 1, 0, 1, 1, 1, 0),
|
||||
(0, 1, 1, 1, 1, 2, 0, 1, 0),
|
||||
(1, 2, 2, 0, 2, 1, 1, 1, 0),
|
||||
(1, 1, 1, 2, 0, 1, 1, 2, 0),
|
||||
(0, 1, 1, 1, 2, 0, 1, 2, 0),
|
||||
(0, 0, 0, 1, 1, 2, 1, 2, 0),
|
||||
(1, 1, 1, 2, 0, 2, 1, 2, 0),
|
||||
(0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
),
|
||||
"inkplate_5_v2": (
|
||||
(0, 0, 1, 1, 2, 1, 1, 1, 0),
|
||||
(1, 1, 2, 2, 1, 2, 1, 1, 0),
|
||||
(0, 1, 2, 2, 1, 1, 2, 1, 0),
|
||||
(0, 0, 1, 1, 1, 1, 1, 2, 0),
|
||||
(1, 2, 1, 2, 1, 1, 1, 2, 0),
|
||||
(0, 1, 1, 1, 2, 0, 1, 2, 0),
|
||||
(1, 1, 1, 2, 2, 2, 1, 2, 0),
|
||||
(0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
),
|
||||
}
|
||||
|
||||
INKPLATE_10_CUSTOM_WAVEFORMS = (
|
||||
(
|
||||
(0, 0, 0, 0, 0, 0, 0, 0, 0),
|
||||
(0, 0, 0, 2, 1, 2, 1, 1, 0),
|
||||
(0, 0, 0, 2, 2, 1, 2, 1, 0),
|
||||
(0, 0, 2, 2, 1, 2, 2, 1, 0),
|
||||
(0, 0, 0, 2, 1, 1, 1, 2, 0),
|
||||
(0, 0, 2, 2, 2, 1, 1, 2, 0),
|
||||
(0, 0, 0, 0, 0, 1, 2, 2, 0),
|
||||
(0, 0, 0, 0, 2, 2, 2, 2, 0),
|
||||
),
|
||||
(
|
||||
(0, 3, 3, 3, 3, 3, 3, 3, 0),
|
||||
(0, 1, 2, 1, 1, 2, 2, 1, 0),
|
||||
(0, 2, 2, 2, 1, 2, 2, 1, 0),
|
||||
(0, 0, 2, 2, 2, 2, 2, 1, 0),
|
||||
(0, 3, 3, 2, 1, 1, 1, 2, 0),
|
||||
(0, 3, 3, 2, 2, 1, 1, 2, 0),
|
||||
(0, 2, 1, 2, 1, 2, 1, 2, 0),
|
||||
(0, 3, 3, 3, 2, 2, 2, 2, 0),
|
||||
),
|
||||
(
|
||||
(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),
|
||||
(1, 1, 2, 2, 1, 2, 2, 1, 0),
|
||||
(0, 0, 2, 1, 2, 2, 2, 1, 0),
|
||||
(0, 1, 2, 2, 2, 2, 2, 1, 0),
|
||||
(0, 0, 0, 2, 2, 2, 1, 2, 0),
|
||||
(0, 0, 0, 2, 2, 2, 2, 2, 0),
|
||||
),
|
||||
(
|
||||
(0, 0, 0, 0, 0, 0, 0, 1, 0),
|
||||
(0, 0, 0, 2, 2, 2, 1, 1, 0),
|
||||
(2, 2, 2, 1, 0, 2, 1, 0, 0),
|
||||
(2, 1, 1, 2, 1, 1, 1, 2, 0),
|
||||
(2, 2, 2, 1, 1, 1, 0, 2, 0),
|
||||
(2, 2, 2, 1, 1, 2, 1, 2, 0),
|
||||
(0, 0, 0, 0, 2, 1, 2, 2, 0),
|
||||
(0, 0, 0, 0, 2, 2, 2, 2, 0),
|
||||
),
|
||||
)
|
238
esphome/components/inkplate/display.py
Normal file
238
esphome/components/inkplate/display.py
Normal file
@@ -0,0 +1,238 @@
|
||||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import display, i2c
|
||||
from esphome.components.esp32 import CONF_CPU_FREQUENCY
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_FULL_UPDATE_EVERY,
|
||||
CONF_ID,
|
||||
CONF_LAMBDA,
|
||||
CONF_MIRROR_X,
|
||||
CONF_MIRROR_Y,
|
||||
CONF_MODEL,
|
||||
CONF_OE_PIN,
|
||||
CONF_PAGES,
|
||||
CONF_TRANSFORM,
|
||||
CONF_WAKEUP_PIN,
|
||||
PLATFORM_ESP32,
|
||||
)
|
||||
import esphome.final_validate as fv
|
||||
|
||||
from .const import INKPLATE_10_CUSTOM_WAVEFORMS, WAVEFORMS
|
||||
|
||||
DEPENDENCIES = ["i2c", "esp32"]
|
||||
AUTO_LOAD = ["psram"]
|
||||
|
||||
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_PARTIAL_UPDATING = "partial_updating"
|
||||
CONF_POWERUP_PIN = "powerup_pin"
|
||||
CONF_SPH_PIN = "sph_pin"
|
||||
CONF_SPV_PIN = "spv_pin"
|
||||
CONF_VCOM_PIN = "vcom_pin"
|
||||
|
||||
inkplate_ns = cg.esphome_ns.namespace("inkplate")
|
||||
Inkplate = inkplate_ns.class_(
|
||||
"Inkplate",
|
||||
cg.PollingComponent,
|
||||
i2c.I2CDevice,
|
||||
display.Display,
|
||||
display.DisplayBuffer,
|
||||
)
|
||||
|
||||
InkplateModel = inkplate_ns.enum("InkplateModel")
|
||||
|
||||
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,
|
||||
"inkplate_5": InkplateModel.INKPLATE_5,
|
||||
"inkplate_5_v2": InkplateModel.INKPLATE_5_V2,
|
||||
}
|
||||
|
||||
CONF_CUSTOM_WAVEFORM = "custom_waveform"
|
||||
|
||||
|
||||
def _validate_custom_waveform(config):
|
||||
if CONF_CUSTOM_WAVEFORM in config and config[CONF_MODEL] != "inkplate_10":
|
||||
raise cv.Invalid("Custom waveforms are only supported on the Inkplate 10")
|
||||
return config
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
display.FULL_DISPLAY_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Inkplate),
|
||||
cv.Optional(CONF_GREYSCALE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_CUSTOM_WAVEFORM): cv.All(
|
||||
cv.uint8_t, cv.Range(min=1, max=len(INKPLATE_10_CUSTOM_WAVEFORMS))
|
||||
),
|
||||
cv.Optional(CONF_TRANSFORM): cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_MIRROR_X, default=False): cv.boolean,
|
||||
cv.Optional(CONF_MIRROR_Y, default=False): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_PARTIAL_UPDATING, default=True): cv.boolean,
|
||||
cv.Optional(CONF_FULL_UPDATE_EVERY, default=10): cv.uint32_t,
|
||||
cv.Optional(CONF_MODEL, default="inkplate_6"): cv.enum(
|
||||
MODELS, lower=True, space="_"
|
||||
),
|
||||
# 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),
|
||||
_validate_custom_waveform,
|
||||
)
|
||||
|
||||
|
||||
def _validate_cpu_frequency(config):
|
||||
esp32_config = fv.full_config.get()[PLATFORM_ESP32]
|
||||
if esp32_config[CONF_CPU_FREQUENCY] != "240MHZ":
|
||||
raise cv.Invalid(
|
||||
"Inkplate requires 240MHz CPU frequency (set in esp32 component)"
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = _validate_cpu_frequency
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
|
||||
await display.register_display(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = await cg.process_lambda(
|
||||
config[CONF_LAMBDA], [(display.DisplayRef, "it")], return_type=cg.void
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
|
||||
cg.add(var.set_greyscale(config[CONF_GREYSCALE]))
|
||||
if transform := config.get(CONF_TRANSFORM):
|
||||
cg.add(var.set_mirror_x(transform[CONF_MIRROR_X]))
|
||||
cg.add(var.set_mirror_y(transform[CONF_MIRROR_Y]))
|
||||
cg.add(var.set_partial_updating(config[CONF_PARTIAL_UPDATING]))
|
||||
cg.add(var.set_full_update_every(config[CONF_FULL_UPDATE_EVERY]))
|
||||
|
||||
cg.add(var.set_model(config[CONF_MODEL]))
|
||||
|
||||
if custom_waveform := config.get(CONF_CUSTOM_WAVEFORM):
|
||||
waveform = INKPLATE_10_CUSTOM_WAVEFORMS[custom_waveform - 1]
|
||||
waveform = [element for tupl in waveform for element in tupl]
|
||||
cg.add(var.set_waveform(waveform, True))
|
||||
else:
|
||||
waveform = WAVEFORMS[config[CONF_MODEL]]
|
||||
waveform = [element for tupl in waveform for element in tupl]
|
||||
cg.add(var.set_waveform(waveform, False))
|
||||
|
||||
ckv = await cg.gpio_pin_expression(config[CONF_CKV_PIN])
|
||||
cg.add(var.set_ckv_pin(ckv))
|
||||
|
||||
gmod = await cg.gpio_pin_expression(config[CONF_GMOD_PIN])
|
||||
cg.add(var.set_gmod_pin(gmod))
|
||||
|
||||
gpio0_enable = await cg.gpio_pin_expression(config[CONF_GPIO0_ENABLE_PIN])
|
||||
cg.add(var.set_gpio0_enable_pin(gpio0_enable))
|
||||
|
||||
oe = await cg.gpio_pin_expression(config[CONF_OE_PIN])
|
||||
cg.add(var.set_oe_pin(oe))
|
||||
|
||||
powerup = await cg.gpio_pin_expression(config[CONF_POWERUP_PIN])
|
||||
cg.add(var.set_powerup_pin(powerup))
|
||||
|
||||
sph = await cg.gpio_pin_expression(config[CONF_SPH_PIN])
|
||||
cg.add(var.set_sph_pin(sph))
|
||||
|
||||
spv = await cg.gpio_pin_expression(config[CONF_SPV_PIN])
|
||||
cg.add(var.set_spv_pin(spv))
|
||||
|
||||
vcom = await cg.gpio_pin_expression(config[CONF_VCOM_PIN])
|
||||
cg.add(var.set_vcom_pin(vcom))
|
||||
|
||||
wakeup = await cg.gpio_pin_expression(config[CONF_WAKEUP_PIN])
|
||||
cg.add(var.set_wakeup_pin(wakeup))
|
||||
|
||||
cl = await cg.gpio_pin_expression(config[CONF_CL_PIN])
|
||||
cg.add(var.set_cl_pin(cl))
|
||||
|
||||
le = await cg.gpio_pin_expression(config[CONF_LE_PIN])
|
||||
cg.add(var.set_le_pin(le))
|
||||
|
||||
display_data_0 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_0_PIN])
|
||||
cg.add(var.set_display_data_0_pin(display_data_0))
|
||||
|
||||
display_data_1 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_1_PIN])
|
||||
cg.add(var.set_display_data_1_pin(display_data_1))
|
||||
|
||||
display_data_2 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_2_PIN])
|
||||
cg.add(var.set_display_data_2_pin(display_data_2))
|
||||
|
||||
display_data_3 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_3_PIN])
|
||||
cg.add(var.set_display_data_3_pin(display_data_3))
|
||||
|
||||
display_data_4 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_4_PIN])
|
||||
cg.add(var.set_display_data_4_pin(display_data_4))
|
||||
|
||||
display_data_5 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_5_PIN])
|
||||
cg.add(var.set_display_data_5_pin(display_data_5))
|
||||
|
||||
display_data_6 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_6_PIN])
|
||||
cg.add(var.set_display_data_6_pin(display_data_6))
|
||||
|
||||
display_data_7 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_7_PIN])
|
||||
cg.add(var.set_display_data_7_pin(display_data_7))
|
@@ -6,11 +6,11 @@
|
||||
#include <hal/gpio_hal.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace inkplate6 {
|
||||
namespace inkplate {
|
||||
|
||||
static const char *const TAG = "inkplate";
|
||||
|
||||
void Inkplate6::setup() {
|
||||
void Inkplate::setup() {
|
||||
for (uint32_t i = 0; i < 256; i++) {
|
||||
this->pin_lut_[i] = ((i & 0b00000011) << 4) | (((i & 0b00001100) >> 2) << 18) | (((i & 0b00010000) >> 4) << 23) |
|
||||
(((i & 0b11100000) >> 5) << 25);
|
||||
@@ -56,7 +56,7 @@ void Inkplate6::setup() {
|
||||
/**
|
||||
* Allocate buffers. May be called after setup to re-initialise if e.g. greyscale is changed.
|
||||
*/
|
||||
void Inkplate6::initialize_() {
|
||||
void Inkplate::initialize_() {
|
||||
RAMAllocator<uint8_t> allocator;
|
||||
RAMAllocator<uint32_t> allocator32;
|
||||
uint32_t buffer_size = this->get_buffer_length_();
|
||||
@@ -81,29 +81,25 @@ void Inkplate6::initialize_() {
|
||||
return;
|
||||
}
|
||||
if (this->greyscale_) {
|
||||
uint8_t glut_size = 9;
|
||||
|
||||
this->glut_ = allocator32.allocate(256 * glut_size);
|
||||
this->glut_ = allocator32.allocate(256 * GLUT_SIZE);
|
||||
if (this->glut_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Could not allocate glut!");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
this->glut2_ = allocator32.allocate(256 * glut_size);
|
||||
this->glut2_ = allocator32.allocate(256 * GLUT_SIZE);
|
||||
if (this->glut2_ == nullptr) {
|
||||
ESP_LOGE(TAG, "Could not allocate glut2!");
|
||||
this->mark_failed();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto *const waveform3_bit = waveform3BitAll[this->model_];
|
||||
|
||||
for (int i = 0; i < glut_size; i++) {
|
||||
for (uint8_t i = 0; i < GLUT_SIZE; i++) {
|
||||
for (uint32_t j = 0; j < 256; j++) {
|
||||
uint8_t z = (waveform3_bit[j & 0x07][i] << 2) | (waveform3_bit[(j >> 4) & 0x07][i]);
|
||||
uint8_t z = (this->waveform_[j & 0x07][i] << 2) | (this->waveform_[(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 = ((waveform3_bit[j & 0x07][i] << 2) | (waveform3_bit[(j >> 4) & 0x07][i])) << 4;
|
||||
z = ((this->waveform_[j & 0x07][i] << 2) | (this->waveform_[(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);
|
||||
}
|
||||
@@ -130,9 +126,9 @@ void Inkplate6::initialize_() {
|
||||
memset(this->buffer_, 0, buffer_size);
|
||||
}
|
||||
|
||||
float Inkplate6::get_setup_priority() const { return setup_priority::PROCESSOR; }
|
||||
float Inkplate::get_setup_priority() const { return setup_priority::PROCESSOR; }
|
||||
|
||||
size_t Inkplate6::get_buffer_length_() {
|
||||
size_t Inkplate::get_buffer_length_() {
|
||||
if (this->greyscale_) {
|
||||
return size_t(this->get_width_internal()) * size_t(this->get_height_internal()) / 2u;
|
||||
} else {
|
||||
@@ -140,7 +136,7 @@ size_t Inkplate6::get_buffer_length_() {
|
||||
}
|
||||
}
|
||||
|
||||
void Inkplate6::update() {
|
||||
void Inkplate::update() {
|
||||
this->do_update_();
|
||||
|
||||
if (this->full_update_every_ > 0 && this->partial_updates_ >= this->full_update_every_) {
|
||||
@@ -150,7 +146,7 @@ void Inkplate6::update() {
|
||||
this->display();
|
||||
}
|
||||
|
||||
void HOT Inkplate6::draw_absolute_pixel_internal(int x, int y, Color color) {
|
||||
void HOT Inkplate::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;
|
||||
|
||||
@@ -171,18 +167,18 @@ void HOT Inkplate6::draw_absolute_pixel_internal(int x, int y, Color color) {
|
||||
// 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);
|
||||
this->buffer_[pos] = (PIXEL_MASK_GLUT[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]);
|
||||
this->partial_buffer_[pos] = (~PIXEL_MASK_LUT[x_sub] & current) | (color.is_on() ? 0 : PIXEL_MASK_LUT[x_sub]);
|
||||
}
|
||||
}
|
||||
|
||||
void Inkplate6::dump_config() {
|
||||
void Inkplate::dump_config() {
|
||||
LOG_DISPLAY("", "Inkplate", this);
|
||||
ESP_LOGCONFIG(TAG,
|
||||
" Greyscale: %s\n"
|
||||
@@ -214,7 +210,7 @@ void Inkplate6::dump_config() {
|
||||
LOG_UPDATE_INTERVAL(this);
|
||||
}
|
||||
|
||||
void Inkplate6::eink_off_() {
|
||||
void Inkplate::eink_off_() {
|
||||
ESP_LOGV(TAG, "Eink off called");
|
||||
if (!panel_on_)
|
||||
return;
|
||||
@@ -242,7 +238,7 @@ void Inkplate6::eink_off_() {
|
||||
pins_z_state_();
|
||||
}
|
||||
|
||||
void Inkplate6::eink_on_() {
|
||||
void Inkplate::eink_on_() {
|
||||
ESP_LOGV(TAG, "Eink on called");
|
||||
if (panel_on_)
|
||||
return;
|
||||
@@ -284,7 +280,7 @@ void Inkplate6::eink_on_() {
|
||||
this->oe_pin_->digital_write(true);
|
||||
}
|
||||
|
||||
bool Inkplate6::read_power_status_() {
|
||||
bool Inkplate::read_power_status_() {
|
||||
uint8_t data;
|
||||
auto err = this->read_register(0x0F, &data, 1);
|
||||
if (err == i2c::ERROR_OK) {
|
||||
@@ -293,7 +289,7 @@ bool Inkplate6::read_power_status_() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Inkplate6::fill(Color color) {
|
||||
void Inkplate::fill(Color color) {
|
||||
ESP_LOGV(TAG, "Fill called");
|
||||
uint32_t start_time = millis();
|
||||
|
||||
@@ -308,7 +304,7 @@ void Inkplate6::fill(Color color) {
|
||||
ESP_LOGV(TAG, "Fill finished (%ums)", millis() - start_time);
|
||||
}
|
||||
|
||||
void Inkplate6::display() {
|
||||
void Inkplate::display() {
|
||||
ESP_LOGV(TAG, "Display called");
|
||||
uint32_t start_time = millis();
|
||||
|
||||
@@ -324,7 +320,7 @@ void Inkplate6::display() {
|
||||
ESP_LOGV(TAG, "Display finished (full) (%ums)", millis() - start_time);
|
||||
}
|
||||
|
||||
void Inkplate6::display1b_() {
|
||||
void Inkplate::display1b_() {
|
||||
ESP_LOGV(TAG, "Display1b called");
|
||||
uint32_t start_time = millis();
|
||||
|
||||
@@ -334,32 +330,71 @@ void Inkplate6::display1b_() {
|
||||
uint8_t buffer_value;
|
||||
const uint8_t *buffer_ptr;
|
||||
eink_on_();
|
||||
if (this->model_ == INKPLATE_6_PLUS) {
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 15);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 5);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 15);
|
||||
} else {
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 21);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 12);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 21);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 12);
|
||||
clean_fast_(2, 1);
|
||||
uint8_t rep = 4;
|
||||
switch (this->model_) {
|
||||
case INKPLATE_10:
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 10);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 10);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 10);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 10);
|
||||
rep = 5;
|
||||
break;
|
||||
case INKPLATE_6_PLUS:
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 15);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 5);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 15);
|
||||
break;
|
||||
case INKPLATE_6:
|
||||
case INKPLATE_6_V2:
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 18);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 18);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 18);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 18);
|
||||
clean_fast_(2, 1);
|
||||
if (this->model_ == INKPLATE_6_V2)
|
||||
rep = 5;
|
||||
break;
|
||||
case INKPLATE_5:
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 14);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 14);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 14);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 14);
|
||||
clean_fast_(2, 1);
|
||||
rep = 5;
|
||||
break;
|
||||
case INKPLATE_5_V2:
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 11);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 11);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 11);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 11);
|
||||
rep = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
int rep = (this->model_ == INKPLATE_6_V2) ? 5 : 4;
|
||||
|
||||
for (int k = 0; k < rep; k++) {
|
||||
for (uint8_t 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++) {
|
||||
@@ -452,28 +487,75 @@ void Inkplate6::display1b_() {
|
||||
ESP_LOGV(TAG, "Display1b finished (%ums)", millis() - start_time);
|
||||
}
|
||||
|
||||
void Inkplate6::display3b_() {
|
||||
void Inkplate::display3b_() {
|
||||
ESP_LOGV(TAG, "Display3b called");
|
||||
uint32_t start_time = millis();
|
||||
|
||||
eink_on_();
|
||||
if (this->model_ == INKPLATE_6_PLUS) {
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 15);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 5);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 15);
|
||||
} else {
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 21);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 12);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 21);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 12);
|
||||
clean_fast_(2, 1);
|
||||
|
||||
switch (this->model_) {
|
||||
case INKPLATE_10:
|
||||
if (this->custom_waveform_) {
|
||||
clean_fast_(1, 1);
|
||||
clean_fast_(0, 7);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 12);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 7);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 12);
|
||||
} else {
|
||||
clean_fast_(1, 1);
|
||||
clean_fast_(0, 10);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 10);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 10);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 10);
|
||||
}
|
||||
break;
|
||||
case INKPLATE_6_PLUS:
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 15);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 5);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 15);
|
||||
break;
|
||||
case INKPLATE_6:
|
||||
case INKPLATE_6_V2:
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 18);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 18);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 18);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 18);
|
||||
clean_fast_(2, 1);
|
||||
break;
|
||||
case INKPLATE_5:
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 14);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 14);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 14);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 14);
|
||||
clean_fast_(2, 1);
|
||||
break;
|
||||
case INKPLATE_5_V2:
|
||||
clean_fast_(0, 1);
|
||||
clean_fast_(1, 11);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 11);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(1, 11);
|
||||
clean_fast_(2, 1);
|
||||
clean_fast_(0, 11);
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t clock = (1 << this->cl_pin_->get_pin());
|
||||
@@ -518,7 +600,7 @@ void Inkplate6::display3b_() {
|
||||
ESP_LOGV(TAG, "Display3b finished (%ums)", millis() - start_time);
|
||||
}
|
||||
|
||||
bool Inkplate6::partial_update_() {
|
||||
bool Inkplate::partial_update_() {
|
||||
ESP_LOGV(TAG, "Partial update called");
|
||||
uint32_t start_time = millis();
|
||||
if (this->greyscale_)
|
||||
@@ -560,7 +642,7 @@ bool Inkplate6::partial_update_() {
|
||||
GPIO.out_w1ts = this->pin_lut_[data] | clock;
|
||||
GPIO.out_w1tc = data_mask | clock;
|
||||
}
|
||||
// New Inkplate6 panel doesn't need last clock
|
||||
// New Inkplate panel doesn't need last clock
|
||||
if (this->model_ != INKPLATE_6_V2) {
|
||||
GPIO.out_w1ts = clock;
|
||||
GPIO.out_w1tc = data_mask | clock;
|
||||
@@ -580,7 +662,7 @@ bool Inkplate6::partial_update_() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Inkplate6::vscan_start_() {
|
||||
void Inkplate::vscan_start_() {
|
||||
this->ckv_pin_->digital_write(true);
|
||||
delayMicroseconds(7);
|
||||
this->spv_pin_->digital_write(false);
|
||||
@@ -604,7 +686,7 @@ void Inkplate6::vscan_start_() {
|
||||
this->ckv_pin_->digital_write(true);
|
||||
}
|
||||
|
||||
void Inkplate6::hscan_start_(uint32_t d) {
|
||||
void Inkplate::hscan_start_(uint32_t d) {
|
||||
uint8_t clock = (1 << this->cl_pin_->get_pin());
|
||||
this->sph_pin_->digital_write(false);
|
||||
GPIO.out_w1ts = d | clock;
|
||||
@@ -613,14 +695,14 @@ void Inkplate6::hscan_start_(uint32_t d) {
|
||||
this->ckv_pin_->digital_write(true);
|
||||
}
|
||||
|
||||
void Inkplate6::vscan_end_() {
|
||||
void Inkplate::vscan_end_() {
|
||||
this->ckv_pin_->digital_write(false);
|
||||
this->le_pin_->digital_write(true);
|
||||
this->le_pin_->digital_write(false);
|
||||
delayMicroseconds(0);
|
||||
}
|
||||
|
||||
void Inkplate6::clean() {
|
||||
void Inkplate::clean() {
|
||||
ESP_LOGV(TAG, "Clean called");
|
||||
uint32_t start_time = millis();
|
||||
|
||||
@@ -634,7 +716,7 @@ void Inkplate6::clean() {
|
||||
ESP_LOGV(TAG, "Clean finished (%ums)", millis() - start_time);
|
||||
}
|
||||
|
||||
void Inkplate6::clean_fast_(uint8_t c, uint8_t rep) {
|
||||
void Inkplate::clean_fast_(uint8_t c, uint8_t rep) {
|
||||
ESP_LOGV(TAG, "Clean fast called with: (%d, %d)", c, rep);
|
||||
uint32_t start_time = millis();
|
||||
|
||||
@@ -666,7 +748,7 @@ void Inkplate6::clean_fast_(uint8_t c, uint8_t rep) {
|
||||
GPIO.out_w1ts = clock;
|
||||
GPIO.out_w1tc = clock;
|
||||
}
|
||||
// New Inkplate6 panel doesn't need last clock
|
||||
// New Inkplate panel doesn't need last clock
|
||||
if (this->model_ != INKPLATE_6_V2) {
|
||||
GPIO.out_w1ts = send | clock;
|
||||
GPIO.out_w1tc = clock;
|
||||
@@ -679,7 +761,7 @@ void Inkplate6::clean_fast_(uint8_t c, uint8_t rep) {
|
||||
ESP_LOGV(TAG, "Clean fast finished (%ums)", millis() - start_time);
|
||||
}
|
||||
|
||||
void Inkplate6::pins_z_state_() {
|
||||
void Inkplate::pins_z_state_() {
|
||||
this->cl_pin_->pin_mode(gpio::FLAG_INPUT);
|
||||
this->le_pin_->pin_mode(gpio::FLAG_INPUT);
|
||||
this->ckv_pin_->pin_mode(gpio::FLAG_INPUT);
|
||||
@@ -699,7 +781,7 @@ void Inkplate6::pins_z_state_() {
|
||||
this->display_data_7_pin_->pin_mode(gpio::FLAG_INPUT);
|
||||
}
|
||||
|
||||
void Inkplate6::pins_as_outputs_() {
|
||||
void Inkplate::pins_as_outputs_() {
|
||||
this->cl_pin_->pin_mode(gpio::FLAG_OUTPUT);
|
||||
this->le_pin_->pin_mode(gpio::FLAG_OUTPUT);
|
||||
this->ckv_pin_->pin_mode(gpio::FLAG_OUTPUT);
|
||||
@@ -719,5 +801,5 @@ void Inkplate6::pins_as_outputs_() {
|
||||
this->display_data_7_pin_->pin_mode(gpio::FLAG_OUTPUT);
|
||||
}
|
||||
|
||||
} // namespace inkplate6
|
||||
} // namespace inkplate
|
||||
} // namespace esphome
|
@@ -5,8 +5,10 @@
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace esphome {
|
||||
namespace inkplate6 {
|
||||
namespace inkplate {
|
||||
|
||||
enum InkplateModel : uint8_t {
|
||||
INKPLATE_6 = 0,
|
||||
@@ -17,79 +19,35 @@ enum InkplateModel : uint8_t {
|
||||
INKPLATE_5_V2 = 5,
|
||||
};
|
||||
|
||||
class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice {
|
||||
static constexpr uint8_t GLUT_SIZE = 9;
|
||||
static constexpr uint8_t GLUT_COUNT = 8;
|
||||
|
||||
static constexpr uint8_t LUT2[16] = {0xAA, 0xA9, 0xA6, 0xA5, 0x9A, 0x99, 0x96, 0x95,
|
||||
0x6A, 0x69, 0x66, 0x65, 0x5A, 0x59, 0x56, 0x55};
|
||||
static constexpr uint8_t LUTW[16] = {0xFF, 0xFE, 0xFB, 0xFA, 0xEF, 0xEE, 0xEB, 0xEA,
|
||||
0xBF, 0xBE, 0xBB, 0xBA, 0xAF, 0xAE, 0xAB, 0xAA};
|
||||
static constexpr uint8_t LUTB[16] = {0xFF, 0xFD, 0xF7, 0xF5, 0xDF, 0xDD, 0xD7, 0xD5,
|
||||
0x7F, 0x7D, 0x77, 0x75, 0x5F, 0x5D, 0x57, 0x55};
|
||||
|
||||
static constexpr uint8_t PIXEL_MASK_LUT[8] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
|
||||
static constexpr uint8_t PIXEL_MASK_GLUT[2] = {0x0F, 0xF0};
|
||||
|
||||
class Inkplate : public display::DisplayBuffer, public i2c::I2CDevice {
|
||||
public:
|
||||
const uint8_t LUT2[16] = {0xAA, 0xA9, 0xA6, 0xA5, 0x9A, 0x99, 0x96, 0x95,
|
||||
0x6A, 0x69, 0x66, 0x65, 0x5A, 0x59, 0x56, 0x55};
|
||||
const uint8_t LUTW[16] = {0xFF, 0xFE, 0xFB, 0xFA, 0xEF, 0xEE, 0xEB, 0xEA,
|
||||
0xBF, 0xBE, 0xBB, 0xBA, 0xAF, 0xAE, 0xAB, 0xAA};
|
||||
const uint8_t LUTB[16] = {0xFF, 0xFD, 0xF7, 0xF5, 0xDF, 0xDD, 0xD7, 0xD5,
|
||||
0x7F, 0x7D, 0x77, 0x75, 0x5F, 0x5D, 0x57, 0x55};
|
||||
|
||||
const uint8_t pixelMaskLUT[8] = {0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80};
|
||||
const uint8_t pixelMaskGLUT[2] = {0x0F, 0xF0};
|
||||
|
||||
const uint8_t waveform3BitAll[6][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}},
|
||||
// INKPLATE_5
|
||||
{{0, 0, 1, 1, 0, 1, 1, 1, 0},
|
||||
{0, 1, 1, 1, 1, 2, 0, 1, 0},
|
||||
{1, 2, 2, 0, 2, 1, 1, 1, 0},
|
||||
{1, 1, 1, 2, 0, 1, 1, 2, 0},
|
||||
{0, 1, 1, 1, 2, 0, 1, 2, 0},
|
||||
{0, 0, 0, 1, 1, 2, 1, 2, 0},
|
||||
{1, 1, 1, 2, 0, 2, 1, 2, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0}},
|
||||
// INKPLATE_5_V2
|
||||
{{0, 0, 1, 1, 2, 1, 1, 1, 0},
|
||||
{1, 1, 2, 2, 1, 2, 1, 1, 0},
|
||||
{0, 1, 2, 2, 1, 1, 2, 1, 0},
|
||||
{0, 0, 1, 1, 1, 1, 1, 2, 0},
|
||||
{1, 2, 1, 2, 1, 1, 1, 2, 0},
|
||||
{0, 1, 1, 1, 2, 0, 1, 2, 0},
|
||||
{1, 1, 1, 2, 2, 2, 1, 2, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0}}};
|
||||
|
||||
void set_greyscale(bool greyscale) {
|
||||
this->greyscale_ = greyscale;
|
||||
this->block_partial_ = true;
|
||||
if (this->is_ready())
|
||||
this->initialize_();
|
||||
}
|
||||
|
||||
void set_waveform(const std::array<uint8_t, GLUT_COUNT * GLUT_SIZE> &waveform, bool is_custom) {
|
||||
static_assert(sizeof(this->waveform_) == sizeof(uint8_t) * GLUT_COUNT * GLUT_SIZE,
|
||||
"waveform_ buffer size must match input waveform array size");
|
||||
memmove(this->waveform_, waveform.data(), sizeof(this->waveform_));
|
||||
this->custom_waveform_ = is_custom;
|
||||
}
|
||||
|
||||
void set_mirror_y(bool mirror_y) { this->mirror_y_ = mirror_y; }
|
||||
void set_mirror_x(bool mirror_x) { this->mirror_x_ = mirror_x; }
|
||||
|
||||
@@ -225,6 +183,8 @@ class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice {
|
||||
bool mirror_y_{false};
|
||||
bool mirror_x_{false};
|
||||
bool partial_updating_;
|
||||
bool custom_waveform_{false};
|
||||
uint8_t waveform_[GLUT_COUNT][GLUT_SIZE];
|
||||
|
||||
InkplateModel model_;
|
||||
|
||||
@@ -250,5 +210,5 @@ class Inkplate6 : public display::DisplayBuffer, public i2c::I2CDevice {
|
||||
GPIOPin *wakeup_pin_;
|
||||
};
|
||||
|
||||
} // namespace inkplate6
|
||||
} // namespace inkplate
|
||||
} // namespace esphome
|
@@ -1 +0,0 @@
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
|
@@ -1,214 +1,5 @@
|
||||
from esphome import pins
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import display, i2c
|
||||
from esphome.components.esp32 import CONF_CPU_FREQUENCY
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_FULL_UPDATE_EVERY,
|
||||
CONF_ID,
|
||||
CONF_LAMBDA,
|
||||
CONF_MIRROR_X,
|
||||
CONF_MIRROR_Y,
|
||||
CONF_MODEL,
|
||||
CONF_OE_PIN,
|
||||
CONF_PAGES,
|
||||
CONF_TRANSFORM,
|
||||
CONF_WAKEUP_PIN,
|
||||
PLATFORM_ESP32,
|
||||
|
||||
CONFIG_SCHEMA = cv.invalid(
|
||||
"The inkplate6 display component has been renamed to inkplate."
|
||||
)
|
||||
import esphome.final_validate as fv
|
||||
|
||||
DEPENDENCIES = ["i2c", "esp32"]
|
||||
AUTO_LOAD = ["psram"]
|
||||
|
||||
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_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.Display,
|
||||
display.DisplayBuffer,
|
||||
)
|
||||
|
||||
InkplateModel = inkplate6_ns.enum("InkplateModel")
|
||||
|
||||
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,
|
||||
"inkplate_5": InkplateModel.INKPLATE_5,
|
||||
"inkplate_5_v2": InkplateModel.INKPLATE_5_V2,
|
||||
}
|
||||
|
||||
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_TRANSFORM): cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_MIRROR_X, default=False): cv.boolean,
|
||||
cv.Optional(CONF_MIRROR_Y, default=False): cv.boolean,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_PARTIAL_UPDATING, default=True): cv.boolean,
|
||||
cv.Optional(CONF_FULL_UPDATE_EVERY, default=10): cv.uint32_t,
|
||||
cv.Optional(CONF_MODEL, default="inkplate_6"): cv.enum(
|
||||
MODELS, lower=True, space="_"
|
||||
),
|
||||
# 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 _validate_cpu_frequency(config):
|
||||
esp32_config = fv.full_config.get()[PLATFORM_ESP32]
|
||||
if esp32_config[CONF_CPU_FREQUENCY] != "240MHZ":
|
||||
raise cv.Invalid(
|
||||
"Inkplate requires 240MHz CPU frequency (set in esp32 component)"
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
FINAL_VALIDATE_SCHEMA = _validate_cpu_frequency
|
||||
|
||||
|
||||
async def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
|
||||
await display.register_display(var, config)
|
||||
await i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = await cg.process_lambda(
|
||||
config[CONF_LAMBDA], [(display.DisplayRef, "it")], return_type=cg.void
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
|
||||
cg.add(var.set_greyscale(config[CONF_GREYSCALE]))
|
||||
if transform := config.get(CONF_TRANSFORM):
|
||||
cg.add(var.set_mirror_x(transform[CONF_MIRROR_X]))
|
||||
cg.add(var.set_mirror_y(transform[CONF_MIRROR_Y]))
|
||||
cg.add(var.set_partial_updating(config[CONF_PARTIAL_UPDATING]))
|
||||
cg.add(var.set_full_update_every(config[CONF_FULL_UPDATE_EVERY]))
|
||||
|
||||
cg.add(var.set_model(config[CONF_MODEL]))
|
||||
|
||||
ckv = await cg.gpio_pin_expression(config[CONF_CKV_PIN])
|
||||
cg.add(var.set_ckv_pin(ckv))
|
||||
|
||||
gmod = await cg.gpio_pin_expression(config[CONF_GMOD_PIN])
|
||||
cg.add(var.set_gmod_pin(gmod))
|
||||
|
||||
gpio0_enable = await cg.gpio_pin_expression(config[CONF_GPIO0_ENABLE_PIN])
|
||||
cg.add(var.set_gpio0_enable_pin(gpio0_enable))
|
||||
|
||||
oe = await cg.gpio_pin_expression(config[CONF_OE_PIN])
|
||||
cg.add(var.set_oe_pin(oe))
|
||||
|
||||
powerup = await cg.gpio_pin_expression(config[CONF_POWERUP_PIN])
|
||||
cg.add(var.set_powerup_pin(powerup))
|
||||
|
||||
sph = await cg.gpio_pin_expression(config[CONF_SPH_PIN])
|
||||
cg.add(var.set_sph_pin(sph))
|
||||
|
||||
spv = await cg.gpio_pin_expression(config[CONF_SPV_PIN])
|
||||
cg.add(var.set_spv_pin(spv))
|
||||
|
||||
vcom = await cg.gpio_pin_expression(config[CONF_VCOM_PIN])
|
||||
cg.add(var.set_vcom_pin(vcom))
|
||||
|
||||
wakeup = await cg.gpio_pin_expression(config[CONF_WAKEUP_PIN])
|
||||
cg.add(var.set_wakeup_pin(wakeup))
|
||||
|
||||
cl = await cg.gpio_pin_expression(config[CONF_CL_PIN])
|
||||
cg.add(var.set_cl_pin(cl))
|
||||
|
||||
le = await cg.gpio_pin_expression(config[CONF_LE_PIN])
|
||||
cg.add(var.set_le_pin(le))
|
||||
|
||||
display_data_0 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_0_PIN])
|
||||
cg.add(var.set_display_data_0_pin(display_data_0))
|
||||
|
||||
display_data_1 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_1_PIN])
|
||||
cg.add(var.set_display_data_1_pin(display_data_1))
|
||||
|
||||
display_data_2 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_2_PIN])
|
||||
cg.add(var.set_display_data_2_pin(display_data_2))
|
||||
|
||||
display_data_3 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_3_PIN])
|
||||
cg.add(var.set_display_data_3_pin(display_data_3))
|
||||
|
||||
display_data_4 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_4_PIN])
|
||||
cg.add(var.set_display_data_4_pin(display_data_4))
|
||||
|
||||
display_data_5 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_5_PIN])
|
||||
cg.add(var.set_display_data_5_pin(display_data_5))
|
||||
|
||||
display_data_6 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_6_PIN])
|
||||
cg.add(var.set_display_data_6_pin(display_data_6))
|
||||
|
||||
display_data_7 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_7_PIN])
|
||||
cg.add(var.set_display_data_7_pin(display_data_7))
|
||||
|
@@ -1,5 +1,5 @@
|
||||
i2c:
|
||||
- id: i2c_inkplate6
|
||||
- id: i2c_inkplate
|
||||
scl: 16
|
||||
sda: 17
|
||||
|
||||
@@ -7,7 +7,7 @@ esp32:
|
||||
cpu_frequency: 240MHz
|
||||
|
||||
display:
|
||||
- platform: inkplate6
|
||||
- platform: inkplate
|
||||
id: inkplate_display
|
||||
greyscale: false
|
||||
partial_updating: false
|
Reference in New Issue
Block a user