mirror of
https://github.com/esphome/esphome.git
synced 2024-11-24 16:08:10 +01:00
[ili9xxx] Add 18bit mode selection and custom init sequence (#6745)
This commit is contained in:
parent
59b1e9c1b0
commit
bad400e1cd
4 changed files with 132 additions and 40 deletions
|
@ -47,6 +47,12 @@ ILI9XXXDisplay = ili9xxx_ns.class_(
|
||||||
display.DisplayBuffer,
|
display.DisplayBuffer,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
PixelMode = ili9xxx_ns.enum("PixelMode")
|
||||||
|
PIXEL_MODES = {
|
||||||
|
"16bit": PixelMode.PIXEL_MODE_16,
|
||||||
|
"18bit": PixelMode.PIXEL_MODE_18,
|
||||||
|
}
|
||||||
|
|
||||||
ILI9XXXColorMode = ili9xxx_ns.enum("ILI9XXXColorMode")
|
ILI9XXXColorMode = ili9xxx_ns.enum("ILI9XXXColorMode")
|
||||||
ColorOrder = display.display_ns.enum("ColorMode")
|
ColorOrder = display.display_ns.enum("ColorMode")
|
||||||
|
|
||||||
|
@ -68,6 +74,7 @@ MODELS = {
|
||||||
"S3BOX": ili9xxx_ns.class_("ILI9XXXS3Box", ILI9XXXDisplay),
|
"S3BOX": ili9xxx_ns.class_("ILI9XXXS3Box", ILI9XXXDisplay),
|
||||||
"S3BOX_LITE": ili9xxx_ns.class_("ILI9XXXS3BoxLite", ILI9XXXDisplay),
|
"S3BOX_LITE": ili9xxx_ns.class_("ILI9XXXS3BoxLite", ILI9XXXDisplay),
|
||||||
"WAVESHARE_RES_3_5": ili9xxx_ns.class_("WAVESHARERES35", ILI9XXXDisplay),
|
"WAVESHARE_RES_3_5": ili9xxx_ns.class_("WAVESHARERES35", ILI9XXXDisplay),
|
||||||
|
"CUSTOM": ILI9XXXDisplay,
|
||||||
}
|
}
|
||||||
|
|
||||||
COLOR_ORDERS = {
|
COLOR_ORDERS = {
|
||||||
|
@ -80,14 +87,37 @@ COLOR_PALETTE = cv.one_of("NONE", "GRAYSCALE", "IMAGE_ADAPTIVE")
|
||||||
CONF_LED_PIN = "led_pin"
|
CONF_LED_PIN = "led_pin"
|
||||||
CONF_COLOR_PALETTE_IMAGES = "color_palette_images"
|
CONF_COLOR_PALETTE_IMAGES = "color_palette_images"
|
||||||
CONF_INVERT_DISPLAY = "invert_display"
|
CONF_INVERT_DISPLAY = "invert_display"
|
||||||
|
CONF_PIXEL_MODE = "pixel_mode"
|
||||||
|
CONF_INIT_SEQUENCE = "init_sequence"
|
||||||
|
|
||||||
|
|
||||||
|
def cmd(c, *args):
|
||||||
|
"""
|
||||||
|
Create a command sequence
|
||||||
|
:param c: The command (8 bit)
|
||||||
|
:param args: zero or more arguments (8 bit values)
|
||||||
|
:return: a list with the command, the argument count and the arguments
|
||||||
|
"""
|
||||||
|
return [c, len(args)] + list(args)
|
||||||
|
|
||||||
|
|
||||||
|
def map_sequence(value):
|
||||||
|
"""
|
||||||
|
An initialisation sequence is a literal array of data bytes.
|
||||||
|
The format is a repeated sequence of [CMD, <data>]
|
||||||
|
"""
|
||||||
|
if len(value) == 0:
|
||||||
|
raise cv.Invalid("Empty sequence")
|
||||||
|
return cmd(*value)
|
||||||
|
|
||||||
|
|
||||||
def _validate(config):
|
def _validate(config):
|
||||||
if config.get(CONF_COLOR_PALETTE) == "IMAGE_ADAPTIVE" and not config.get(
|
if (
|
||||||
CONF_COLOR_PALETTE_IMAGES
|
config.get(CONF_COLOR_PALETTE) == "IMAGE_ADAPTIVE"
|
||||||
|
and CONF_COLOR_PALETTE_IMAGES not in config
|
||||||
):
|
):
|
||||||
raise cv.Invalid(
|
raise cv.Invalid(
|
||||||
"Color palette in IMAGE_ADAPTIVE mode requires at least one 'color_palette_images' entry to generate palette"
|
"IMAGE_ADAPTIVE palette requires at least one 'color_palette_images' entry"
|
||||||
)
|
)
|
||||||
if (
|
if (
|
||||||
config.get(CONF_COLOR_PALETTE_IMAGES)
|
config.get(CONF_COLOR_PALETTE_IMAGES)
|
||||||
|
@ -96,7 +126,8 @@ def _validate(config):
|
||||||
raise cv.Invalid(
|
raise cv.Invalid(
|
||||||
"Providing color palette images requires palette mode to be 'IMAGE_ADAPTIVE'"
|
"Providing color palette images requires palette mode to be 'IMAGE_ADAPTIVE'"
|
||||||
)
|
)
|
||||||
if CORE.is_esp8266 and config.get(CONF_MODEL) not in [
|
model = config[CONF_MODEL]
|
||||||
|
if CORE.is_esp8266 and model not in [
|
||||||
"M5STACK",
|
"M5STACK",
|
||||||
"TFT_2.4",
|
"TFT_2.4",
|
||||||
"TFT_2.4R",
|
"TFT_2.4R",
|
||||||
|
@ -104,9 +135,12 @@ def _validate(config):
|
||||||
"ILI9342",
|
"ILI9342",
|
||||||
"ST7789V",
|
"ST7789V",
|
||||||
]:
|
]:
|
||||||
raise cv.Invalid(
|
raise cv.Invalid("Selected model can't run on ESP8266.")
|
||||||
"Provided model can't run on ESP8266. Use an ESP32 with PSRAM onboard"
|
|
||||||
)
|
if model == "CUSTOM":
|
||||||
|
if CONF_INIT_SEQUENCE not in config or CONF_DIMENSIONS not in config:
|
||||||
|
raise cv.Invalid("CUSTOM model requires init_sequence and dimensions")
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,6 +150,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(ILI9XXXDisplay),
|
cv.GenerateID(): cv.declare_id(ILI9XXXDisplay),
|
||||||
cv.Required(CONF_MODEL): cv.enum(MODELS, upper=True, space="_"),
|
cv.Required(CONF_MODEL): cv.enum(MODELS, upper=True, space="_"),
|
||||||
|
cv.Optional(CONF_PIXEL_MODE): cv.enum(PIXEL_MODES),
|
||||||
cv.Optional(CONF_DIMENSIONS): cv.Any(
|
cv.Optional(CONF_DIMENSIONS): cv.Any(
|
||||||
cv.dimensions,
|
cv.dimensions,
|
||||||
cv.Schema(
|
cv.Schema(
|
||||||
|
@ -150,6 +185,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Optional(CONF_MIRROR_Y, default=False): cv.boolean,
|
cv.Optional(CONF_MIRROR_Y, default=False): cv.boolean,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_INIT_SEQUENCE): cv.ensure_list(map_sequence),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("1s"))
|
.extend(cv.polling_component_schema("1s"))
|
||||||
|
@ -167,6 +203,14 @@ async def to_code(config):
|
||||||
await spi.register_spi_device(var, config)
|
await spi.register_spi_device(var, config)
|
||||||
dc = await cg.gpio_pin_expression(config[CONF_DC_PIN])
|
dc = await cg.gpio_pin_expression(config[CONF_DC_PIN])
|
||||||
cg.add(var.set_dc_pin(dc))
|
cg.add(var.set_dc_pin(dc))
|
||||||
|
if init_sequences := config.get(CONF_INIT_SEQUENCE):
|
||||||
|
sequence = []
|
||||||
|
for seq in init_sequences:
|
||||||
|
sequence.extend(seq)
|
||||||
|
cg.add(var.add_init_sequence(sequence))
|
||||||
|
|
||||||
|
if pixel_mode := config.get(CONF_PIXEL_MODE):
|
||||||
|
cg.add(var.set_pixel_mode(pixel_mode))
|
||||||
if CONF_COLOR_ORDER in config:
|
if CONF_COLOR_ORDER in config:
|
||||||
cg.add(var.set_color_order(COLOR_ORDERS[config[CONF_COLOR_ORDER]]))
|
cg.add(var.set_color_order(COLOR_ORDERS[config[CONF_COLOR_ORDER]]))
|
||||||
if CONF_TRANSFORM in config:
|
if CONF_TRANSFORM in config:
|
||||||
|
|
|
@ -34,7 +34,26 @@ void ILI9XXXDisplay::setup() {
|
||||||
ESP_LOGD(TAG, "Setting up ILI9xxx");
|
ESP_LOGD(TAG, "Setting up ILI9xxx");
|
||||||
|
|
||||||
this->setup_pins_();
|
this->setup_pins_();
|
||||||
this->init_lcd_();
|
this->init_lcd_(this->init_sequence_);
|
||||||
|
this->init_lcd_(this->extra_init_sequence_.data());
|
||||||
|
switch (this->pixel_mode_) {
|
||||||
|
case PIXEL_MODE_16:
|
||||||
|
if (this->is_18bitdisplay_) {
|
||||||
|
this->command(ILI9XXX_PIXFMT);
|
||||||
|
this->data(0x55);
|
||||||
|
this->is_18bitdisplay_ = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIXEL_MODE_18:
|
||||||
|
if (!this->is_18bitdisplay_) {
|
||||||
|
this->command(ILI9XXX_PIXFMT);
|
||||||
|
this->data(0x66);
|
||||||
|
this->is_18bitdisplay_ = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
this->set_madctl();
|
this->set_madctl();
|
||||||
this->command(this->pre_invertcolors_ ? ILI9XXX_INVON : ILI9XXX_INVOFF);
|
this->command(this->pre_invertcolors_ ? ILI9XXX_INVON : ILI9XXX_INVOFF);
|
||||||
|
@ -203,7 +222,6 @@ void ILI9XXXDisplay::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ILI9XXXDisplay::display_() {
|
void ILI9XXXDisplay::display_() {
|
||||||
uint8_t transfer_buffer[ILI9XXX_TRANSFER_BUFFER_SIZE];
|
|
||||||
// check if something was displayed
|
// check if something was displayed
|
||||||
if ((this->x_high_ < this->x_low_) || (this->y_high_ < this->y_low_)) {
|
if ((this->x_high_ < this->x_low_) || (this->y_high_ < this->y_low_)) {
|
||||||
return;
|
return;
|
||||||
|
@ -231,6 +249,7 @@ void ILI9XXXDisplay::display_() {
|
||||||
this->write_array(this->buffer_ + this->y_low_ * this->width_ * 2, h * this->width_ * 2);
|
this->write_array(this->buffer_ + this->y_low_ * this->width_ * 2, h * this->width_ * 2);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGV(TAG, "Doing multiple write");
|
ESP_LOGV(TAG, "Doing multiple write");
|
||||||
|
uint8_t transfer_buffer[ILI9XXX_TRANSFER_BUFFER_SIZE];
|
||||||
size_t rem = h * w; // remaining number of pixels to write
|
size_t rem = h * w; // remaining number of pixels to write
|
||||||
set_addr_window_(this->x_low_, this->y_low_, this->x_high_, this->y_high_);
|
set_addr_window_(this->x_low_, this->y_low_, this->x_high_, this->y_high_);
|
||||||
size_t idx = 0; // index into transfer_buffer
|
size_t idx = 0; // index into transfer_buffer
|
||||||
|
@ -247,7 +266,7 @@ void ILI9XXXDisplay::display_() {
|
||||||
display::ColorUtil::index8_to_color_palette888(this->buffer_[pos++], this->palette_));
|
display::ColorUtil::index8_to_color_palette888(this->buffer_[pos++], this->palette_));
|
||||||
break;
|
break;
|
||||||
default: // case BITS_16:
|
default: // case BITS_16:
|
||||||
color_val = (buffer_[pos * 2] << 8) + buffer_[pos * 2 + 1];
|
color_val = (this->buffer_[pos * 2] << 8) + this->buffer_[pos * 2 + 1];
|
||||||
pos++;
|
pos++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -259,7 +278,7 @@ void ILI9XXXDisplay::display_() {
|
||||||
put16_be(transfer_buffer + idx, color_val);
|
put16_be(transfer_buffer + idx, color_val);
|
||||||
idx += 2;
|
idx += 2;
|
||||||
}
|
}
|
||||||
if (idx == ILI9XXX_TRANSFER_BUFFER_SIZE) {
|
if (idx == sizeof(transfer_buffer)) {
|
||||||
this->write_array(transfer_buffer, idx);
|
this->write_array(transfer_buffer, idx);
|
||||||
idx = 0;
|
idx = 0;
|
||||||
App.feed_wdt();
|
App.feed_wdt();
|
||||||
|
@ -293,20 +312,50 @@ void ILI9XXXDisplay::draw_pixels_at(int x_start, int y_start, int w, int h, cons
|
||||||
// if color mapping or software rotation is required, hand this off to the parent implementation. This will
|
// if color mapping or software rotation is required, hand this off to the parent implementation. This will
|
||||||
// do color conversion pixel-by-pixel into the buffer and draw it later. If this is happening the user has not
|
// do color conversion pixel-by-pixel into the buffer and draw it later. If this is happening the user has not
|
||||||
// configured the renderer well.
|
// configured the renderer well.
|
||||||
if (this->rotation_ != display::DISPLAY_ROTATION_0_DEGREES || bitness != display::COLOR_BITNESS_565 || !big_endian ||
|
if (this->rotation_ != display::DISPLAY_ROTATION_0_DEGREES || bitness != display::COLOR_BITNESS_565 || !big_endian) {
|
||||||
this->is_18bitdisplay_) {
|
|
||||||
return display::Display::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset,
|
return display::Display::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset,
|
||||||
x_pad);
|
x_pad);
|
||||||
}
|
}
|
||||||
this->set_addr_window_(x_start, y_start, x_start + w - 1, y_start + h - 1);
|
this->set_addr_window_(x_start, y_start, x_start + w - 1, y_start + h - 1);
|
||||||
// x_ and y_offset are offsets into the source buffer, unrelated to our own offsets into the display.
|
// x_ and y_offset are offsets into the source buffer, unrelated to our own offsets into the display.
|
||||||
if (x_offset == 0 && x_pad == 0 && y_offset == 0) {
|
auto stride = x_offset + w + x_pad;
|
||||||
// we could deal here with a non-zero y_offset, but if x_offset is zero, y_offset probably will be so don't bother
|
if (!this->is_18bitdisplay_) {
|
||||||
this->write_array(ptr, w * h * 2);
|
if (x_offset == 0 && x_pad == 0 && y_offset == 0) {
|
||||||
|
// we could deal here with a non-zero y_offset, but if x_offset is zero, y_offset probably will be so don't bother
|
||||||
|
this->write_array(ptr, w * h * 2);
|
||||||
|
} else {
|
||||||
|
for (size_t y = 0; y != h; y++) {
|
||||||
|
this->write_array(ptr + (y + y_offset) * stride + x_offset, w * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
auto stride = x_offset + w + x_pad;
|
// 18 bit mode
|
||||||
for (size_t y = 0; y != h; y++) {
|
uint8_t transfer_buffer[ILI9XXX_TRANSFER_BUFFER_SIZE * 4];
|
||||||
this->write_array(ptr + (y + y_offset) * stride + x_offset, w * 2);
|
ESP_LOGV(TAG, "Doing multiple write");
|
||||||
|
size_t rem = h * w; // remaining number of pixels to write
|
||||||
|
size_t idx = 0; // index into transfer_buffer
|
||||||
|
size_t pixel = 0; // pixel number offset
|
||||||
|
ptr += (y_offset * stride + x_offset) * 2;
|
||||||
|
while (rem-- != 0) {
|
||||||
|
uint8_t hi_byte = *ptr++;
|
||||||
|
uint8_t lo_byte = *ptr++;
|
||||||
|
transfer_buffer[idx++] = hi_byte & 0xF8; // Blue
|
||||||
|
transfer_buffer[idx++] = ((hi_byte << 5) | (lo_byte) >> 5); // Green
|
||||||
|
transfer_buffer[idx++] = lo_byte << 3; // Red
|
||||||
|
if (idx == sizeof(transfer_buffer)) {
|
||||||
|
this->write_array(transfer_buffer, idx);
|
||||||
|
idx = 0;
|
||||||
|
App.feed_wdt();
|
||||||
|
}
|
||||||
|
// end of line? Skip to the next.
|
||||||
|
if (++pixel == w) {
|
||||||
|
pixel = 0;
|
||||||
|
ptr += (x_pad + x_offset) * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// flush any balance.
|
||||||
|
if (idx != 0) {
|
||||||
|
this->write_array(transfer_buffer, idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this->end_data_();
|
this->end_data_();
|
||||||
|
@ -356,10 +405,11 @@ void ILI9XXXDisplay::reset_() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ILI9XXXDisplay::init_lcd_() {
|
void ILI9XXXDisplay::init_lcd_(const uint8_t *addr) {
|
||||||
|
if (addr == nullptr)
|
||||||
|
return;
|
||||||
uint8_t cmd, x, num_args;
|
uint8_t cmd, x, num_args;
|
||||||
const uint8_t *addr = this->init_sequence_;
|
while ((cmd = *addr++) != 0) {
|
||||||
while ((cmd = *addr++) > 0) {
|
|
||||||
x = *addr++;
|
x = *addr++;
|
||||||
num_args = x & 0x7F;
|
num_args = x & 0x7F;
|
||||||
this->send_command(cmd, addr, num_args);
|
this->send_command(cmd, addr, num_args);
|
||||||
|
|
|
@ -17,6 +17,12 @@ enum ILI9XXXColorMode {
|
||||||
BITS_16 = 0x10,
|
BITS_16 = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PixelMode {
|
||||||
|
PIXEL_MODE_UNSPECIFIED,
|
||||||
|
PIXEL_MODE_16,
|
||||||
|
PIXEL_MODE_18,
|
||||||
|
};
|
||||||
|
|
||||||
class ILI9XXXDisplay : public display::DisplayBuffer,
|
class ILI9XXXDisplay : public display::DisplayBuffer,
|
||||||
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
|
public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
|
||||||
spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_40MHZ> {
|
spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_40MHZ> {
|
||||||
|
@ -52,6 +58,7 @@ class ILI9XXXDisplay : public display::DisplayBuffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_init_sequence(const std::vector<uint8_t> &sequence) { this->extra_init_sequence_ = sequence; }
|
||||||
void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
|
void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
void set_reset_pin(GPIOPin *reset) { this->reset_pin_ = reset; }
|
void set_reset_pin(GPIOPin *reset) { this->reset_pin_ = reset; }
|
||||||
|
@ -73,6 +80,7 @@ class ILI9XXXDisplay : public display::DisplayBuffer,
|
||||||
void set_swap_xy(bool swap_xy) { this->swap_xy_ = swap_xy; }
|
void set_swap_xy(bool swap_xy) { this->swap_xy_ = swap_xy; }
|
||||||
void set_mirror_x(bool mirror_x) { this->mirror_x_ = mirror_x; }
|
void set_mirror_x(bool mirror_x) { this->mirror_x_ = mirror_x; }
|
||||||
void set_mirror_y(bool mirror_y) { this->mirror_y_ = mirror_y; }
|
void set_mirror_y(bool mirror_y) { this->mirror_y_ = mirror_y; }
|
||||||
|
void set_pixel_mode(PixelMode mode) { this->pixel_mode_ = mode; }
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
|
@ -99,11 +107,12 @@ class ILI9XXXDisplay : public display::DisplayBuffer,
|
||||||
|
|
||||||
virtual void set_madctl();
|
virtual void set_madctl();
|
||||||
void display_();
|
void display_();
|
||||||
void init_lcd_();
|
void init_lcd_(const uint8_t *addr);
|
||||||
void set_addr_window_(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2);
|
void set_addr_window_(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2);
|
||||||
void reset_();
|
void reset_();
|
||||||
|
|
||||||
uint8_t const *init_sequence_{};
|
uint8_t const *init_sequence_{};
|
||||||
|
std::vector<uint8_t> extra_init_sequence_;
|
||||||
int16_t width_{0}; ///< Display width as modified by current rotation
|
int16_t width_{0}; ///< Display width as modified by current rotation
|
||||||
int16_t height_{0}; ///< Display height as modified by current rotation
|
int16_t height_{0}; ///< Display height as modified by current rotation
|
||||||
int16_t offset_x_{0};
|
int16_t offset_x_{0};
|
||||||
|
@ -112,7 +121,7 @@ class ILI9XXXDisplay : public display::DisplayBuffer,
|
||||||
uint16_t y_low_{0};
|
uint16_t y_low_{0};
|
||||||
uint16_t x_high_{0};
|
uint16_t x_high_{0};
|
||||||
uint16_t y_high_{0};
|
uint16_t y_high_{0};
|
||||||
const uint8_t *palette_;
|
const uint8_t *palette_{};
|
||||||
|
|
||||||
ILI9XXXColorMode buffer_color_mode_{BITS_16};
|
ILI9XXXColorMode buffer_color_mode_{BITS_16};
|
||||||
|
|
||||||
|
@ -133,6 +142,7 @@ class ILI9XXXDisplay : public display::DisplayBuffer,
|
||||||
bool prossing_update_ = false;
|
bool prossing_update_ = false;
|
||||||
bool need_update_ = false;
|
bool need_update_ = false;
|
||||||
bool is_18bitdisplay_ = false;
|
bool is_18bitdisplay_ = false;
|
||||||
|
PixelMode pixel_mode_{};
|
||||||
bool pre_invertcolors_ = false;
|
bool pre_invertcolors_ = false;
|
||||||
display::ColorOrder color_order_{display::COLOR_ORDER_BGR};
|
display::ColorOrder color_order_{display::COLOR_ORDER_BGR};
|
||||||
bool swap_xy_{};
|
bool swap_xy_{};
|
||||||
|
|
|
@ -12,24 +12,12 @@ display:
|
||||||
swap_xy: true
|
swap_xy: true
|
||||||
mirror_x: true
|
mirror_x: true
|
||||||
mirror_y: false
|
mirror_y: false
|
||||||
model: TFT 2.4
|
model: custom
|
||||||
color_palette: GRAYSCALE
|
|
||||||
cs_pin: 12
|
cs_pin: 12
|
||||||
dc_pin: 13
|
dc_pin: 13
|
||||||
reset_pin: 14
|
reset_pin: 14
|
||||||
|
init_sequence:
|
||||||
|
- [0xFF, 0x77, 0x01, 0x00, 0x00, 0x10]
|
||||||
|
|
||||||
lambda: |-
|
lambda: |-
|
||||||
it.rectangle(0, 0, it.get_width(), it.get_height());
|
it.rectangle(0, 0, it.get_width(), it.get_height());
|
||||||
- platform: ili9xxx
|
|
||||||
dimensions:
|
|
||||||
width: 320
|
|
||||||
height: 240
|
|
||||||
offset_width: 20
|
|
||||||
offset_height: 10
|
|
||||||
model: TFT 2.4
|
|
||||||
cs_pin: 25
|
|
||||||
dc_pin: 26
|
|
||||||
reset_pin: 27
|
|
||||||
auto_clear_enabled: false
|
|
||||||
rotation: 90
|
|
||||||
lambda: |-
|
|
||||||
it.fill(Color::WHITE);
|
|
||||||
|
|
Loading…
Reference in a new issue