1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-24 22:22:22 +01:00

Support for ST7567 display 128x64 (I2C, SPI) (#5952)

This commit is contained in:
Anton Viktorov
2023-12-27 02:01:15 +01:00
committed by GitHub
parent 93ac765425
commit 3be97868fc
13 changed files with 572 additions and 0 deletions

View File

@@ -0,0 +1 @@
CODEOWNERS = ["@latonita"]

View File

@@ -0,0 +1,29 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import st7567_base, i2c
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_PAGES
CODEOWNERS = ["@latonita"]
AUTO_LOAD = ["st7567_base"]
DEPENDENCIES = ["i2c"]
st7567_i2c = cg.esphome_ns.namespace("st7567_i2c")
I2CST7567 = st7567_i2c.class_("I2CST7567", st7567_base.ST7567, i2c.I2CDevice)
CONFIG_SCHEMA = cv.All(
st7567_base.ST7567_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(I2CST7567),
}
)
.extend(cv.COMPONENT_SCHEMA)
.extend(i2c.i2c_device_schema(0x3F)),
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
)
async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await st7567_base.setup_st7567(var, config)
await i2c.register_i2c_device(var, config)

View File

@@ -0,0 +1,60 @@
#include "st7567_i2c.h"
#include "esphome/core/log.h"
namespace esphome {
namespace st7567_i2c {
static const char *const TAG = "st7567_i2c";
void I2CST7567::setup() {
ESP_LOGCONFIG(TAG, "Setting up I2C ST7567 display...");
this->init_reset_();
auto err = this->write(nullptr, 0);
if (err != i2c::ERROR_OK) {
this->error_code_ = COMMUNICATION_FAILED;
this->mark_failed();
return;
}
ST7567::setup();
}
void I2CST7567::dump_config() {
LOG_DISPLAY("", "I2CST7567", this);
LOG_I2C_DEVICE(this);
ESP_LOGCONFIG(TAG, " Model: %s", this->model_str_());
LOG_PIN(" Reset Pin: ", this->reset_pin_);
ESP_LOGCONFIG(TAG, " Mirror X: %s", YESNO(this->mirror_x_));
ESP_LOGCONFIG(TAG, " Mirror Y: %s", YESNO(this->mirror_y_));
ESP_LOGCONFIG(TAG, " Invert Colors: %s", YESNO(this->invert_colors_));
LOG_UPDATE_INTERVAL(this);
if (this->error_code_ == COMMUNICATION_FAILED) {
ESP_LOGE(TAG, "Communication with I2C ST7567 failed!");
}
}
void I2CST7567::command(uint8_t value) { this->write_byte(0x00, value); }
void HOT I2CST7567::write_display_data() {
// ST7567A has built-in RAM with 132x65 bit capacity which stores the display data.
// but only first 128 pixels from each line are shown on screen
// if screen got flipped horizontally then it shows last 128 pixels,
// so we need to write x coordinate starting from column 4, not column 0
this->command(esphome::st7567_base::ST7567_SET_START_LINE + this->start_line_);
for (uint8_t y = 0; y < (uint8_t) this->get_height_internal() / 8; y++) {
this->command(esphome::st7567_base::ST7567_PAGE_ADDR + y); // Set Page
this->command(esphome::st7567_base::ST7567_COL_ADDR_H); // Set MSB Column address
this->command(esphome::st7567_base::ST7567_COL_ADDR_L + this->get_offset_x_()); // Set LSB Column address
static const size_t BLOCK_SIZE = 64;
for (uint8_t x = 0; x < (uint8_t) this->get_width_internal(); x += BLOCK_SIZE) {
this->write_register(esphome::st7567_base::ST7567_SET_START_LINE, &buffer_[y * this->get_width_internal() + x],
this->get_width_internal() - x > BLOCK_SIZE ? BLOCK_SIZE : this->get_width_internal() - x,
true);
}
}
}
} // namespace st7567_i2c
} // namespace esphome

View File

@@ -0,0 +1,23 @@
#pragma once
#include "esphome/core/component.h"
#include "esphome/components/st7567_base/st7567_base.h"
#include "esphome/components/i2c/i2c.h"
namespace esphome {
namespace st7567_i2c {
class I2CST7567 : public st7567_base::ST7567, public i2c::I2CDevice {
public:
void setup() override;
void dump_config() override;
protected:
void command(uint8_t value) override;
void write_display_data() override;
enum ErrorCode { NONE = 0, COMMUNICATION_FAILED } error_code_{NONE};
};
} // namespace st7567_i2c
} // namespace esphome