mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	Add Lilygo T-Embed to st7789v display config. (#5337)
* Add Lilygo T-Embed to st7789v display config. * Move all configuration into the Python code. Add presets for TTGO. All preset configuration can be overridden. * Add Adafruit S2 pin presets * Add test * Add funhouse pins. Co-authored-by: Keith Burzinski <kbx81x@gmail.com> * Keep ordering of options consistent * Remove unused declarations --------- Co-authored-by: Keith Burzinski <kbx81x@gmail.com>
This commit is contained in:
		| @@ -12,6 +12,8 @@ from esphome.const import ( | |||||||
|     CONF_RESET_PIN, |     CONF_RESET_PIN, | ||||||
|     CONF_WIDTH, |     CONF_WIDTH, | ||||||
|     CONF_POWER_SUPPLY, |     CONF_POWER_SUPPLY, | ||||||
|  |     CONF_ROTATION, | ||||||
|  |     CONF_CS_PIN, | ||||||
| ) | ) | ||||||
| from . import st7789v_ns | from . import st7789v_ns | ||||||
|  |  | ||||||
| @@ -26,48 +28,106 @@ DEPENDENCIES = ["spi"] | |||||||
| ST7789V = st7789v_ns.class_( | ST7789V = st7789v_ns.class_( | ||||||
|     "ST7789V", cg.PollingComponent, spi.SPIDevice, display.DisplayBuffer |     "ST7789V", cg.PollingComponent, spi.SPIDevice, display.DisplayBuffer | ||||||
| ) | ) | ||||||
| ST7789VRef = ST7789V.operator("ref") |  | ||||||
| ST7789VModel = st7789v_ns.enum("ST7789VModel") | MODEL_PRESETS = "model_presets" | ||||||
|  | REQUIRE_PS = "require_ps" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def model_spec(require_ps=False, presets=None): | ||||||
|  |     if presets is None: | ||||||
|  |         presets = {} | ||||||
|  |     return {MODEL_PRESETS: presets, REQUIRE_PS: require_ps} | ||||||
|  |  | ||||||
|  |  | ||||||
| MODELS = { | MODELS = { | ||||||
|     "TTGO_TDISPLAY_135X240": ST7789VModel.ST7789V_MODEL_TTGO_TDISPLAY_135_240, |     "TTGO_TDISPLAY_135X240": model_spec( | ||||||
|     "ADAFRUIT_FUNHOUSE_240X240": ST7789VModel.ST7789V_MODEL_ADAFRUIT_FUNHOUSE_240_240, |         presets={ | ||||||
|     "ADAFRUIT_RR_280X240": ST7789VModel.ST7789V_MODEL_ADAFRUIT_RR_280_240, |             CONF_HEIGHT: 240, | ||||||
|     "ADAFRUIT_S2_TFT_FEATHER_240X135": ST7789VModel.ST7789V_MODEL_ADAFRUIT_S2_TFT_FEATHER_240_135, |             CONF_WIDTH: 135, | ||||||
|     "CUSTOM": ST7789VModel.ST7789V_MODEL_CUSTOM, |             CONF_OFFSET_HEIGHT: 52, | ||||||
|  |             CONF_OFFSET_WIDTH: 40, | ||||||
|  |             CONF_CS_PIN: "GPIO5", | ||||||
|  |             CONF_DC_PIN: "GPIO16", | ||||||
|  |             CONF_RESET_PIN: "GPIO23", | ||||||
|  |             CONF_BACKLIGHT_PIN: "GPIO4", | ||||||
|  |         } | ||||||
|  |     ), | ||||||
|  |     "ADAFRUIT_FUNHOUSE_240X240": model_spec( | ||||||
|  |         presets={ | ||||||
|  |             CONF_HEIGHT: 240, | ||||||
|  |             CONF_WIDTH: 240, | ||||||
|  |             CONF_OFFSET_HEIGHT: 0, | ||||||
|  |             CONF_OFFSET_WIDTH: 0, | ||||||
|  |             CONF_CS_PIN: "GPIO40", | ||||||
|  |             CONF_DC_PIN: "GPIO39", | ||||||
|  |             CONF_RESET_PIN: "GPIO41", | ||||||
|  |         } | ||||||
|  |     ), | ||||||
|  |     "ADAFRUIT_RR_280X240": model_spec( | ||||||
|  |         presets={ | ||||||
|  |             CONF_HEIGHT: 280, | ||||||
|  |             CONF_WIDTH: 240, | ||||||
|  |             CONF_OFFSET_HEIGHT: 0, | ||||||
|  |             CONF_OFFSET_WIDTH: 20, | ||||||
|  |         } | ||||||
|  |     ), | ||||||
|  |     "ADAFRUIT_S2_TFT_FEATHER_240X135": model_spec( | ||||||
|  |         require_ps=True, | ||||||
|  |         presets={ | ||||||
|  |             CONF_HEIGHT: 240, | ||||||
|  |             CONF_WIDTH: 135, | ||||||
|  |             CONF_OFFSET_HEIGHT: 52, | ||||||
|  |             CONF_OFFSET_WIDTH: 40, | ||||||
|  |             CONF_CS_PIN: "GPIO7", | ||||||
|  |             CONF_DC_PIN: "GPIO39", | ||||||
|  |             CONF_RESET_PIN: "GPIO40", | ||||||
|  |             CONF_BACKLIGHT_PIN: "GPIO45", | ||||||
|  |         }, | ||||||
|  |     ), | ||||||
|  |     "LILYGO_T-EMBED_170X320": model_spec( | ||||||
|  |         presets={ | ||||||
|  |             CONF_HEIGHT: 320, | ||||||
|  |             CONF_WIDTH: 170, | ||||||
|  |             CONF_OFFSET_HEIGHT: 35, | ||||||
|  |             CONF_OFFSET_WIDTH: 0, | ||||||
|  |             CONF_ROTATION: 270, | ||||||
|  |             CONF_CS_PIN: "GPIO10", | ||||||
|  |             CONF_DC_PIN: "GPIO13", | ||||||
|  |             CONF_RESET_PIN: "GPIO9", | ||||||
|  |             CONF_BACKLIGHT_PIN: "GPIO15", | ||||||
|  |         } | ||||||
|  |     ), | ||||||
|  |     "CUSTOM": model_spec(), | ||||||
| } | } | ||||||
|  |  | ||||||
| ST7789V_MODEL = cv.enum(MODELS, upper=True, space="_") |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def validate_st7789v(config): | def validate_st7789v(config): | ||||||
|     if config[CONF_MODEL].upper() == "CUSTOM" and ( |     model_data = MODELS[config[CONF_MODEL]] | ||||||
|         CONF_HEIGHT not in config |     presets = model_data[MODEL_PRESETS] | ||||||
|         or CONF_WIDTH not in config |     for key, value in presets.items(): | ||||||
|         or CONF_OFFSET_HEIGHT not in config |         if key not in config: | ||||||
|         or CONF_OFFSET_WIDTH not in config |             if key.endswith("pin"): | ||||||
|     ): |                 # All pins are output. | ||||||
|         raise cv.Invalid( |                 value = pins.gpio_output_pin_schema(value) | ||||||
|             f'{CONF_HEIGHT}, {CONF_WIDTH}, {CONF_OFFSET_HEIGHT} and {CONF_OFFSET_WIDTH} must be specified when {CONF_MODEL} is "CUSTOM"' |             config[key] = value | ||||||
|         ) |  | ||||||
|  |  | ||||||
|     if config[CONF_MODEL].upper() != "CUSTOM" and ( |     if model_data[REQUIRE_PS] and CONF_POWER_SUPPLY not in config: | ||||||
|         CONF_HEIGHT in config |  | ||||||
|         or CONF_WIDTH in config |  | ||||||
|         or CONF_OFFSET_HEIGHT in config |  | ||||||
|         or CONF_OFFSET_WIDTH in config |  | ||||||
|     ): |  | ||||||
|         raise cv.Invalid( |         raise cv.Invalid( | ||||||
|             f'Do not specify {CONF_HEIGHT}, {CONF_WIDTH}, {CONF_OFFSET_HEIGHT} or {CONF_OFFSET_WIDTH} when using {CONF_MODEL} that is not "CUSTOM"' |             f'{CONF_POWER_SUPPLY} must be specified when {CONF_MODEL} is {config[CONF_MODEL]}"' | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|     if ( |     if ( | ||||||
|         config[CONF_MODEL].upper() == "ADAFRUIT_S2_TFT_FEATHER_240X135" |         CONF_OFFSET_WIDTH not in config | ||||||
|         and CONF_POWER_SUPPLY not in config |         or CONF_OFFSET_HEIGHT not in config | ||||||
|  |         or CONF_HEIGHT not in config | ||||||
|  |         or CONF_WIDTH not in config | ||||||
|     ): |     ): | ||||||
|         raise cv.Invalid( |         raise cv.Invalid( | ||||||
|             f'{CONF_POWER_SUPPLY} must be specified when {CONF_MODEL} is "ADAFRUIT_S2_TFT_FEATHER_240X135"' |             f"{CONF_HEIGHT}, {CONF_WIDTH}, {CONF_OFFSET_HEIGHT} and {CONF_OFFSET_WIDTH} must all be specified" | ||||||
|         ) |         ) | ||||||
|  |     if CONF_DC_PIN not in config or CONF_RESET_PIN not in config: | ||||||
|  |         raise cv.Invalid(f"both {CONF_DC_PIN} and {CONF_RESET_PIN} must be specified") | ||||||
|  |  | ||||||
|     return config |     return config | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -75,9 +135,9 @@ CONFIG_SCHEMA = cv.All( | |||||||
|     display.FULL_DISPLAY_SCHEMA.extend( |     display.FULL_DISPLAY_SCHEMA.extend( | ||||||
|         { |         { | ||||||
|             cv.GenerateID(): cv.declare_id(ST7789V), |             cv.GenerateID(): cv.declare_id(ST7789V), | ||||||
|             cv.Required(CONF_MODEL): ST7789V_MODEL, |             cv.Required(CONF_MODEL): cv.one_of(*MODELS.keys(), upper=True, space="_"), | ||||||
|             cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema, |             cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema, | ||||||
|             cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema, |             cv.Optional(CONF_DC_PIN): pins.gpio_output_pin_schema, | ||||||
|             cv.Optional(CONF_BACKLIGHT_PIN): pins.gpio_output_pin_schema, |             cv.Optional(CONF_BACKLIGHT_PIN): pins.gpio_output_pin_schema, | ||||||
|             cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply), |             cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply), | ||||||
|             cv.Optional(CONF_EIGHTBITCOLOR, default=False): cv.boolean, |             cv.Optional(CONF_EIGHTBITCOLOR, default=False): cv.boolean, | ||||||
| @@ -99,13 +159,12 @@ async def to_code(config): | |||||||
|     await display.register_display(var, config) |     await display.register_display(var, config) | ||||||
|     await spi.register_spi_device(var, config) |     await spi.register_spi_device(var, config) | ||||||
|  |  | ||||||
|     cg.add(var.set_model(config[CONF_MODEL])) |     cg.add(var.set_model_str(config[CONF_MODEL])) | ||||||
|  |  | ||||||
|     if config[CONF_MODEL].upper() == "CUSTOM": |     cg.add(var.set_height(config[CONF_HEIGHT])) | ||||||
|         cg.add(var.set_height(config[CONF_HEIGHT])) |     cg.add(var.set_width(config[CONF_WIDTH])) | ||||||
|         cg.add(var.set_width(config[CONF_WIDTH])) |     cg.add(var.set_offset_height(config[CONF_OFFSET_HEIGHT])) | ||||||
|         cg.add(var.set_offset_height(config[CONF_OFFSET_HEIGHT])) |     cg.add(var.set_offset_width(config[CONF_OFFSET_WIDTH])) | ||||||
|         cg.add(var.set_offset_width(config[CONF_OFFSET_WIDTH])) |  | ||||||
|  |  | ||||||
|     cg.add(var.set_eightbitcolor(config[CONF_EIGHTBITCOLOR])) |     cg.add(var.set_eightbitcolor(config[CONF_EIGHTBITCOLOR])) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -122,11 +122,11 @@ void ST7789V::setup() { | |||||||
|  |  | ||||||
| void ST7789V::dump_config() { | void ST7789V::dump_config() { | ||||||
|   LOG_DISPLAY("", "SPI ST7789V", this); |   LOG_DISPLAY("", "SPI ST7789V", this); | ||||||
|   ESP_LOGCONFIG(TAG, "  Model: %s", this->model_str_()); |   ESP_LOGCONFIG(TAG, "  Model: %s", this->model_str_); | ||||||
|   if (this->model_ == ST7789V_MODEL_CUSTOM) { |   ESP_LOGCONFIG(TAG, "  Height: %u", this->height_); | ||||||
|     ESP_LOGCONFIG(TAG, "  Height Offset: %u", this->offset_height_); |   ESP_LOGCONFIG(TAG, "  Width: %u", this->width_); | ||||||
|     ESP_LOGCONFIG(TAG, "  Width Offset: %u", this->offset_width_); |   ESP_LOGCONFIG(TAG, "  Height Offset: %u", this->offset_height_); | ||||||
|   } |   ESP_LOGCONFIG(TAG, "  Width Offset: %u", this->offset_width_); | ||||||
|   ESP_LOGCONFIG(TAG, "  8-bit color mode: %s", YESNO(this->eightbitcolor_)); |   ESP_LOGCONFIG(TAG, "  8-bit color mode: %s", YESNO(this->eightbitcolor_)); | ||||||
|   LOG_PIN("  CS Pin: ", this->cs_); |   LOG_PIN("  CS Pin: ", this->cs_); | ||||||
|   LOG_PIN("  DC Pin: ", this->dc_pin_); |   LOG_PIN("  DC Pin: ", this->dc_pin_); | ||||||
| @@ -145,42 +145,7 @@ void ST7789V::update() { | |||||||
|   this->write_display_data(); |   this->write_display_data(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void ST7789V::set_model(ST7789VModel model) { | void ST7789V::set_model_str(const char *model_str) { this->model_str_ = model_str; } | ||||||
|   this->model_ = model; |  | ||||||
|  |  | ||||||
|   switch (this->model_) { |  | ||||||
|     case ST7789V_MODEL_TTGO_TDISPLAY_135_240: |  | ||||||
|       this->height_ = 240; |  | ||||||
|       this->width_ = 135; |  | ||||||
|       this->offset_height_ = 52; |  | ||||||
|       this->offset_width_ = 40; |  | ||||||
|       break; |  | ||||||
|  |  | ||||||
|     case ST7789V_MODEL_ADAFRUIT_FUNHOUSE_240_240: |  | ||||||
|       this->height_ = 240; |  | ||||||
|       this->width_ = 240; |  | ||||||
|       this->offset_height_ = 0; |  | ||||||
|       this->offset_width_ = 0; |  | ||||||
|       break; |  | ||||||
|  |  | ||||||
|     case ST7789V_MODEL_ADAFRUIT_RR_280_240: |  | ||||||
|       this->height_ = 280; |  | ||||||
|       this->width_ = 240; |  | ||||||
|       this->offset_height_ = 0; |  | ||||||
|       this->offset_width_ = 20; |  | ||||||
|       break; |  | ||||||
|  |  | ||||||
|     case ST7789V_MODEL_ADAFRUIT_S2_TFT_FEATHER_240_135: |  | ||||||
|       this->height_ = 240; |  | ||||||
|       this->width_ = 135; |  | ||||||
|       this->offset_height_ = 52; |  | ||||||
|       this->offset_width_ = 40; |  | ||||||
|       break; |  | ||||||
|  |  | ||||||
|     default: |  | ||||||
|       break; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void ST7789V::write_display_data() { | void ST7789V::write_display_data() { | ||||||
|   uint16_t x1 = this->offset_height_; |   uint16_t x1 = this->offset_height_; | ||||||
| @@ -339,20 +304,5 @@ void HOT ST7789V::draw_absolute_pixel_internal(int x, int y, Color color) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| const char *ST7789V::model_str_() { |  | ||||||
|   switch (this->model_) { |  | ||||||
|     case ST7789V_MODEL_TTGO_TDISPLAY_135_240: |  | ||||||
|       return "TTGO T-Display 135x240"; |  | ||||||
|     case ST7789V_MODEL_ADAFRUIT_FUNHOUSE_240_240: |  | ||||||
|       return "Adafruit Funhouse 240x240"; |  | ||||||
|     case ST7789V_MODEL_ADAFRUIT_RR_280_240: |  | ||||||
|       return "Adafruit Round-Rectangular 280x240"; |  | ||||||
|     case ST7789V_MODEL_ADAFRUIT_S2_TFT_FEATHER_240_135: |  | ||||||
|       return "Adafruit ESP32-S2 TFT Feather"; |  | ||||||
|     default: |  | ||||||
|       return "Custom"; |  | ||||||
|   } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| }  // namespace st7789v | }  // namespace st7789v | ||||||
| }  // namespace esphome | }  // namespace esphome | ||||||
|   | |||||||
| @@ -10,14 +10,6 @@ | |||||||
| namespace esphome { | namespace esphome { | ||||||
| namespace st7789v { | namespace st7789v { | ||||||
|  |  | ||||||
| enum ST7789VModel { |  | ||||||
|   ST7789V_MODEL_TTGO_TDISPLAY_135_240, |  | ||||||
|   ST7789V_MODEL_ADAFRUIT_FUNHOUSE_240_240, |  | ||||||
|   ST7789V_MODEL_ADAFRUIT_RR_280_240, |  | ||||||
|   ST7789V_MODEL_ADAFRUIT_S2_TFT_FEATHER_240_135, |  | ||||||
|   ST7789V_MODEL_CUSTOM |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| static const uint8_t ST7789_NOP = 0x00;        // No Operation | static const uint8_t ST7789_NOP = 0x00;        // No Operation | ||||||
| static const uint8_t ST7789_SWRESET = 0x01;    // Software Reset | static const uint8_t ST7789_SWRESET = 0x01;    // Software Reset | ||||||
| static const uint8_t ST7789_RDDID = 0x04;      // Read Display ID | static const uint8_t ST7789_RDDID = 0x04;      // Read Display ID | ||||||
| @@ -120,7 +112,7 @@ class ST7789V : public PollingComponent, | |||||||
|                 public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING, |                 public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING, | ||||||
|                                       spi::DATA_RATE_20MHZ> { |                                       spi::DATA_RATE_20MHZ> { | ||||||
|  public: |  public: | ||||||
|   void set_model(ST7789VModel model); |   void set_model_str(const char *model_str); | ||||||
|   void set_dc_pin(GPIOPin *dc_pin) { this->dc_pin_ = dc_pin; } |   void set_dc_pin(GPIOPin *dc_pin) { this->dc_pin_ = dc_pin; } | ||||||
|   void set_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; } |   void set_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; } | ||||||
|   void set_backlight_pin(GPIOPin *backlight_pin) { this->backlight_pin_ = backlight_pin; } |   void set_backlight_pin(GPIOPin *backlight_pin) { this->backlight_pin_ = backlight_pin; } | ||||||
| @@ -146,7 +138,6 @@ class ST7789V : public PollingComponent, | |||||||
|   display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; } |   display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; } | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   ST7789VModel model_{ST7789V_MODEL_TTGO_TDISPLAY_135_240}; |  | ||||||
|   GPIOPin *dc_pin_{nullptr}; |   GPIOPin *dc_pin_{nullptr}; | ||||||
|   GPIOPin *reset_pin_{nullptr}; |   GPIOPin *reset_pin_{nullptr}; | ||||||
|   GPIOPin *backlight_pin_{nullptr}; |   GPIOPin *backlight_pin_{nullptr}; | ||||||
| @@ -175,7 +166,7 @@ class ST7789V : public PollingComponent, | |||||||
|  |  | ||||||
|   void draw_absolute_pixel_internal(int x, int y, Color color) override; |   void draw_absolute_pixel_internal(int x, int y, Color color) override; | ||||||
|  |  | ||||||
|   const char *model_str_(); |   const char *model_str_; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace st7789v | }  // namespace st7789v | ||||||
|   | |||||||
| @@ -710,6 +710,14 @@ interval: | |||||||
|     - logger.log: Interval Run |     - logger.log: Interval Run | ||||||
|  |  | ||||||
| display: | display: | ||||||
|  |   - platform: st7789v | ||||||
|  |     model: LILYGO_T-EMBED_170X320 | ||||||
|  |     height: 320 | ||||||
|  |     width: 170 | ||||||
|  |     offset_height: 35 | ||||||
|  |     offset_width: 0 | ||||||
|  |     dc_pin: GPIO13 | ||||||
|  |     reset_pin: GPIO9 | ||||||
|  |  | ||||||
| image: | image: | ||||||
|   - id: binary_image |   - id: binary_image | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user