1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-12 00:02:21 +01:00

Add support for ST7789V display module (as on TTGO T-Display) (#1050)

* TFT-LCD ST7789V of ESP32 TTGO.

This patch allows you to use TFT-LCD ST7789V of ESP32 TTGO

* Lots of polish and a few tweaks

* Add test

* Add color to core, take 1

* Where did those tabs come from?

* Fix lines too long

* Added color component

* Linted

* Rebase, SPI fix, test

* Shuffle bits

* One more thing...oops

* Image type fix...oops

* Make display_buffer use Color

* Fix BGR/RGB, remove predefined colors

* Fix all the things

* renamed colors to color

* migrate max7219

Co-authored-by: musk95 <musk95@naver.com>
Co-authored-by: Guillermo Ruffino <glm.net@gmail.com>
This commit is contained in:
Keith Burzinski
2020-06-28 16:37:36 -05:00
committed by GitHub
parent bfb9cb6732
commit 491f7e96f0
21 changed files with 843 additions and 85 deletions

View File

@@ -4,13 +4,15 @@ from esphome import core
from esphome.components import display, font
import esphome.config_validation as cv
import esphome.codegen as cg
from esphome.const import CONF_FILE, CONF_ID, CONF_RESIZE
from esphome.const import CONF_FILE, CONF_ID, CONF_RESIZE, CONF_TYPE
from esphome.core import CORE, HexInt
_LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['display']
MULTI_CONF = True
ImageType = {'binary': 0, 'grayscale4': 1, 'rgb565': 2}
Image_ = display.display_ns.class_('Image')
CONF_RAW_DATA_ID = 'raw_data_id'
@@ -19,6 +21,7 @@ IMAGE_SCHEMA = cv.Schema({
cv.Required(CONF_ID): cv.declare_id(Image_),
cv.Required(CONF_FILE): cv.file_,
cv.Optional(CONF_RESIZE): cv.dimensions,
cv.Optional(CONF_TYPE): cv.string,
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8),
})
@@ -37,20 +40,54 @@ def to_code(config):
if CONF_RESIZE in config:
image.thumbnail(config[CONF_RESIZE])
image = image.convert('1', dither=Image.NONE)
width, height = image.size
if width > 500 or height > 500:
_LOGGER.warning("The image you requested is very big. Please consider using the resize "
"parameter")
width8 = ((width + 7) // 8) * 8
data = [0 for _ in range(height * width8 // 8)]
for y in range(height):
for x in range(width):
if image.getpixel((x, y)):
continue
pos = x + y * width8
data[pos // 8] |= 0x80 >> (pos % 8)
if CONF_TYPE in config:
if config[CONF_TYPE].startswith('GRAYSCALE4'):
width, height = image.size
image = image.convert('L', dither=Image.NONE)
pixels = list(image.getdata())
data = [0 for _ in range(height * width // 2)]
pos = 0
for pixnum, pix in enumerate(pixels):
pixshift = (pixnum % 2) * 4
data[pos] |= (pix >> 4) << pixshift
if pixshift != 0:
pos += 1
rhs = [HexInt(x) for x in data]
prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs)
cg.new_Pvariable(config[CONF_ID], prog_arr, width, height, ImageType['grayscale4'])
elif config[CONF_TYPE].startswith('RGB565'):
width, height = image.size
image = image.convert('RGB')
pixels = list(image.getdata())
data = [0 for _ in range(height * width * 2)]
pos = 0
for pix in pixels:
r = (pix[0] >> 3) & 0x1F
g = (pix[1] >> 2) & 0x3F
b = (pix[2] >> 3) & 0x1F
p = (r << 11) + (g << 5) + b
data[pos] = (p >> 8) & 0xFF
pos += 1
data[pos] = p & 0xFF
pos += 1
rhs = [HexInt(x) for x in data]
prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs)
cg.new_Pvariable(config[CONF_ID], prog_arr, width, height, ImageType['rgb565'])
else:
image = image.convert('1', dither=Image.NONE)
width, height = image.size
if width > 500 or height > 500:
_LOGGER.warning("The image you requested is very big. Please consider using"
" the resize parameter.")
width8 = ((width + 7) // 8) * 8
data = [0 for _ in range(height * width8 // 8)]
for y in range(height):
for x in range(width):
if image.getpixel((x, y)):
continue
pos = x + y * width8
data[pos // 8] |= 0x80 >> (pos % 8)
rhs = [HexInt(x) for x in data]
prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs)
cg.new_Pvariable(config[CONF_ID], prog_arr, width, height)
rhs = [HexInt(x) for x in data]
prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs)
cg.new_Pvariable(config[CONF_ID], prog_arr, width, height)