From a3cacc0c8b5b567c37c0f6a57870f3608fd5be42 Mon Sep 17 00:00:00 2001 From: Dave Johnston <1548274+johnsto@users.noreply.github.com> Date: Wed, 12 Apr 2023 05:02:29 +0100 Subject: [PATCH] Add support for SSD1306 72x40 displays (#4659) * add SSD1306 72x40 * fix indents * fix clang style --- esphome/components/ssd1306_base/__init__.py | 1 + esphome/components/ssd1306_base/ssd1306_base.cpp | 15 +++++++++++++++ esphome/components/ssd1306_base/ssd1306_base.h | 1 + esphome/components/ssd1306_i2c/ssd1306_i2c.cpp | 8 +++++++- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/esphome/components/ssd1306_base/__init__.py b/esphome/components/ssd1306_base/__init__.py index f2e4ef5811..48143b9e1a 100644 --- a/esphome/components/ssd1306_base/__init__.py +++ b/esphome/components/ssd1306_base/__init__.py @@ -27,6 +27,7 @@ MODELS = { "SSD1306_96X16": SSD1306Model.SSD1306_MODEL_96_16, "SSD1306_64X48": SSD1306Model.SSD1306_MODEL_64_48, "SSD1306_64X32": SSD1306Model.SSD1306_MODEL_64_32, + "SSD1306_72X40": SSD1306Model.SSD1306_MODEL_72_40, "SH1106_128X32": SSD1306Model.SH1106_MODEL_128_32, "SH1106_128X64": SSD1306Model.SH1106_MODEL_128_64, "SH1106_96X16": SSD1306Model.SH1106_MODEL_96_16, diff --git a/esphome/components/ssd1306_base/ssd1306_base.cpp b/esphome/components/ssd1306_base/ssd1306_base.cpp index 2ba990637e..730e1c8f35 100644 --- a/esphome/components/ssd1306_base/ssd1306_base.cpp +++ b/esphome/components/ssd1306_base/ssd1306_base.cpp @@ -59,6 +59,7 @@ void SSD1306::setup() { // Set Y offset (0xD3) this->command(SSD1306_COMMAND_SET_DISPLAY_OFFSET_Y); this->command(0x00 + this->offset_y_); + // Set start line at line 0 (0x40) this->command(SSD1306_COMMAND_SET_START_LINE | 0x00); @@ -100,6 +101,7 @@ void SSD1306::setup() { case SH1107_MODEL_128_64: case SSD1305_MODEL_128_32: case SSD1305_MODEL_128_64: + case SSD1306_MODEL_72_40: this->command(0x12); break; } @@ -118,6 +120,9 @@ void SSD1306::setup() { case SH1107_MODEL_128_64: this->command(0x35); break; + case SSD1306_MODEL_72_40: + this->command(0x20); + break; default: this->command(0x00); break; @@ -156,6 +161,10 @@ void SSD1306::display() { this->command(0x20 + this->offset_x_); this->command(0x20 + this->offset_x_ + this->get_width_internal() - 1); break; + case SSD1306_MODEL_72_40: + this->command(0x1C + this->offset_x_); + this->command(0x1C + this->offset_x_ + this->get_width_internal() - 1); + break; default: this->command(0 + this->offset_x_); // Page start address, 0 this->command(this->get_width_internal() + this->offset_x_ - 1); @@ -225,6 +234,8 @@ int SSD1306::get_height_internal() { case SSD1306_MODEL_64_48: case SH1106_MODEL_64_48: return 48; + case SSD1306_MODEL_72_40: + return 40; default: return 0; } @@ -246,6 +257,8 @@ int SSD1306::get_width_internal() { case SH1106_MODEL_64_48: case SH1107_MODEL_128_64: return 64; + case SSD1306_MODEL_72_40: + return 72; default: return 0; } @@ -294,6 +307,8 @@ const char *SSD1306::model_str_() { return "SSD1306 96x16"; case SSD1306_MODEL_64_48: return "SSD1306 64x48"; + case SSD1306_MODEL_72_40: + return "SSD1306 72x40"; case SH1106_MODEL_128_32: return "SH1106 128x32"; case SH1106_MODEL_128_64: diff --git a/esphome/components/ssd1306_base/ssd1306_base.h b/esphome/components/ssd1306_base/ssd1306_base.h index 2f5baffb69..7402ae3af2 100644 --- a/esphome/components/ssd1306_base/ssd1306_base.h +++ b/esphome/components/ssd1306_base/ssd1306_base.h @@ -13,6 +13,7 @@ enum SSD1306Model { SSD1306_MODEL_96_16, SSD1306_MODEL_64_48, SSD1306_MODEL_64_32, + SSD1306_MODEL_72_40, SH1106_MODEL_128_32, SH1106_MODEL_128_64, SH1106_MODEL_96_16, diff --git a/esphome/components/ssd1306_i2c/ssd1306_i2c.cpp b/esphome/components/ssd1306_i2c/ssd1306_i2c.cpp index 64b09c0672..96734eb618 100644 --- a/esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +++ b/esphome/components/ssd1306_i2c/ssd1306_i2c.cpp @@ -53,8 +53,14 @@ void HOT I2CSSD1306::write_display_data() { } } } else { + size_t block_size = 16; + if ((this->get_buffer_length_() & 8) == 8) { + // use smaller block size for e.g. 72x40 displays where buffer size is multiple of 8, not 16 + block_size = 8; + } + for (uint32_t i = 0; i < this->get_buffer_length_();) { - uint8_t data[16]; + uint8_t data[block_size]; for (uint8_t &j : data) j = this->buffer_[i++]; this->write_bytes(0x40, data, sizeof(data));