mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 17:05:21 +01:00
I found some issue in the ili9341 driver (#3756)
This commit is contained in:
parent
e3dad7c632
commit
4788a6182e
2 changed files with 71 additions and 33 deletions
|
@ -10,7 +10,6 @@ namespace ili9341 {
|
||||||
static const char *const TAG = "ili9341";
|
static const char *const TAG = "ili9341";
|
||||||
|
|
||||||
void ILI9341Display::setup_pins_() {
|
void ILI9341Display::setup_pins_() {
|
||||||
this->init_internal_(this->get_buffer_length_());
|
|
||||||
this->dc_pin_->setup(); // OUTPUT
|
this->dc_pin_->setup(); // OUTPUT
|
||||||
this->dc_pin_->digital_write(false);
|
this->dc_pin_->digital_write(false);
|
||||||
if (this->reset_pin_ != nullptr) {
|
if (this->reset_pin_ != nullptr) {
|
||||||
|
@ -28,15 +27,14 @@ void ILI9341Display::setup_pins_() {
|
||||||
|
|
||||||
void ILI9341Display::dump_config() {
|
void ILI9341Display::dump_config() {
|
||||||
LOG_DISPLAY("", "ili9341", this);
|
LOG_DISPLAY("", "ili9341", this);
|
||||||
ESP_LOGCONFIG(TAG, " Width: %d, Height: %d, Rotation: %d", this->width_, this->height_, this->rotation_);
|
|
||||||
LOG_PIN(" Reset Pin: ", this->reset_pin_);
|
LOG_PIN(" Reset Pin: ", this->reset_pin_);
|
||||||
LOG_PIN(" DC Pin: ", this->dc_pin_);
|
LOG_PIN(" DC Pin: ", this->dc_pin_);
|
||||||
LOG_PIN(" Busy Pin: ", this->busy_pin_);
|
LOG_PIN(" Busy Pin: ", this->busy_pin_);
|
||||||
LOG_PIN(" Backlight Pin: ", this->led_pin_);
|
|
||||||
LOG_UPDATE_INTERVAL(this);
|
LOG_UPDATE_INTERVAL(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
float ILI9341Display::get_setup_priority() const { return setup_priority::PROCESSOR; }
|
float ILI9341Display::get_setup_priority() const { return setup_priority::HARDWARE; }
|
||||||
|
|
||||||
void ILI9341Display::command(uint8_t value) {
|
void ILI9341Display::command(uint8_t value) {
|
||||||
this->start_command_();
|
this->start_command_();
|
||||||
this->write_byte(value);
|
this->write_byte(value);
|
||||||
|
@ -88,10 +86,19 @@ void ILI9341Display::display_() {
|
||||||
// we will only update the changed window to the display
|
// we will only update the changed window to the display
|
||||||
uint16_t w = this->x_high_ - this->x_low_ + 1;
|
uint16_t w = this->x_high_ - this->x_low_ + 1;
|
||||||
uint16_t h = this->y_high_ - this->y_low_ + 1;
|
uint16_t h = this->y_high_ - this->y_low_ + 1;
|
||||||
|
uint32_t start_pos = ((this->y_low_ * this->width_) + x_low_);
|
||||||
|
|
||||||
|
// check if something was displayed
|
||||||
|
if ((this->x_high_ < this->x_low_) || (this->y_high_ < this->y_low_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
set_addr_window_(this->x_low_, this->y_low_, w, h);
|
set_addr_window_(this->x_low_, this->y_low_, w, h);
|
||||||
|
|
||||||
|
ESP_LOGVV("ILI9341", "Start ILI9341Display::display_(xl:%d, xh:%d, yl:%d, yh:%d, w:%d, h:%d, start_pos:%d)",
|
||||||
|
this->x_low_, this->x_high_, this->y_low_, this->y_high_, w, h, start_pos);
|
||||||
|
|
||||||
this->start_data_();
|
this->start_data_();
|
||||||
uint32_t start_pos = ((this->y_low_ * this->width_) + x_low_);
|
|
||||||
for (uint16_t row = 0; row < h; row++) {
|
for (uint16_t row = 0; row < h; row++) {
|
||||||
uint32_t pos = start_pos + (row * width_);
|
uint32_t pos = start_pos + (row * width_);
|
||||||
uint32_t rem = w;
|
uint32_t rem = w;
|
||||||
|
@ -101,7 +108,9 @@ void ILI9341Display::display_() {
|
||||||
this->write_array(transfer_buffer_, 2 * sz);
|
this->write_array(transfer_buffer_, 2 * sz);
|
||||||
pos += sz;
|
pos += sz;
|
||||||
rem -= sz;
|
rem -= sz;
|
||||||
|
App.feed_wdt();
|
||||||
}
|
}
|
||||||
|
App.feed_wdt();
|
||||||
}
|
}
|
||||||
this->end_data_();
|
this->end_data_();
|
||||||
|
|
||||||
|
@ -121,20 +130,10 @@ void ILI9341Display::fill(Color color) {
|
||||||
this->y_high_ = this->get_height_internal() - 1;
|
this->y_high_ = this->get_height_internal() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ILI9341Display::fill_internal_(Color color) {
|
void ILI9341Display::fill_internal_(uint8_t color) {
|
||||||
if (color.raw_32 == Color::BLACK.raw_32) {
|
memset(transfer_buffer_, color, sizeof(transfer_buffer_));
|
||||||
memset(transfer_buffer_, 0, sizeof(transfer_buffer_));
|
|
||||||
} else {
|
|
||||||
uint8_t *dst = transfer_buffer_;
|
|
||||||
auto color565 = display::ColorUtil::color_to_565(color);
|
|
||||||
|
|
||||||
while (dst < transfer_buffer_ + sizeof(transfer_buffer_)) {
|
uint32_t rem = (this->get_buffer_length_() * 2);
|
||||||
*dst++ = (uint8_t)(color565 >> 8);
|
|
||||||
*dst++ = (uint8_t) color565;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t rem = this->get_width_internal() * this->get_height_internal();
|
|
||||||
|
|
||||||
this->set_addr_window_(0, 0, this->get_width_internal(), this->get_height_internal());
|
this->set_addr_window_(0, 0, this->get_width_internal(), this->get_height_internal());
|
||||||
this->start_data_();
|
this->start_data_();
|
||||||
|
@ -147,26 +146,58 @@ void ILI9341Display::fill_internal_(Color color) {
|
||||||
|
|
||||||
this->end_data_();
|
this->end_data_();
|
||||||
|
|
||||||
memset(buffer_, 0, (this->get_width_internal()) * (this->get_height_internal()));
|
memset(buffer_, color, this->get_buffer_length_());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ILI9341Display::rotate_my_(uint8_t m) {
|
||||||
|
uint8_t rotation = m & 3; // can't be higher than 3
|
||||||
|
switch (rotation) {
|
||||||
|
case 0:
|
||||||
|
m = (MADCTL_MX | MADCTL_BGR);
|
||||||
|
// _width = ILI9341_TFTWIDTH;
|
||||||
|
// _height = ILI9341_TFTHEIGHT;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
m = (MADCTL_MV | MADCTL_BGR);
|
||||||
|
// _width = ILI9341_TFTHEIGHT;
|
||||||
|
// _height = ILI9341_TFTWIDTH;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
m = (MADCTL_MY | MADCTL_BGR);
|
||||||
|
// _width = ILI9341_TFTWIDTH;
|
||||||
|
// _height = ILI9341_TFTHEIGHT;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
m = (MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
|
||||||
|
// _width = ILI9341_TFTHEIGHT;
|
||||||
|
// _height = ILI9341_TFTWIDTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->command(ILI9341_MADCTL);
|
||||||
|
this->data(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HOT ILI9341Display::draw_absolute_pixel_internal(int x, int y, Color color) {
|
void HOT ILI9341Display::draw_absolute_pixel_internal(int x, int y, Color color) {
|
||||||
if (x >= this->get_width_internal() || x < 0 || y >= this->get_height_internal() || y < 0)
|
if (x >= this->get_width_internal() || x < 0 || y >= this->get_height_internal() || y < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
uint32_t pos = (y * width_) + x;
|
||||||
|
uint8_t new_color;
|
||||||
|
|
||||||
|
if (this->buffer_color_mode_ == BITS_8) {
|
||||||
|
new_color = display::ColorUtil::color_to_332(color, display::ColorOrder::COLOR_ORDER_RGB);
|
||||||
|
} else { // if (this->buffer_color_mode_ == BITS_8_INDEXED) {
|
||||||
|
new_color = display::ColorUtil::color_to_index8_palette888(color, this->palette_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer_[pos] != new_color) {
|
||||||
|
buffer_[pos] = new_color;
|
||||||
// low and high watermark may speed up drawing from buffer
|
// low and high watermark may speed up drawing from buffer
|
||||||
this->x_low_ = (x < this->x_low_) ? x : this->x_low_;
|
this->x_low_ = (x < this->x_low_) ? x : this->x_low_;
|
||||||
this->y_low_ = (y < this->y_low_) ? y : this->y_low_;
|
this->y_low_ = (y < this->y_low_) ? y : this->y_low_;
|
||||||
this->x_high_ = (x > this->x_high_) ? x : this->x_high_;
|
this->x_high_ = (x > this->x_high_) ? x : this->x_high_;
|
||||||
this->y_high_ = (y > this->y_high_) ? y : this->y_high_;
|
this->y_high_ = (y > this->y_high_) ? y : this->y_high_;
|
||||||
|
|
||||||
uint32_t pos = (y * width_) + x;
|
|
||||||
if (this->buffer_color_mode_ == BITS_8) {
|
|
||||||
uint8_t color332 = display::ColorUtil::color_to_332(color, display::ColorOrder::COLOR_ORDER_RGB);
|
|
||||||
buffer_[pos] = color332;
|
|
||||||
} else { // if (this->buffer_color_mode_ == BITS_8_INDEXED) {
|
|
||||||
uint8_t index = display::ColorUtil::color_to_index8_palette888(color, this->palette_);
|
|
||||||
buffer_[pos] = index;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +283,6 @@ void ILI9341M5Stack::initialize() {
|
||||||
this->width_ = 320;
|
this->width_ = 320;
|
||||||
this->height_ = 240;
|
this->height_ = 240;
|
||||||
this->invert_display_(true);
|
this->invert_display_(true);
|
||||||
this->fill_internal_(Color::BLACK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24_TFT display
|
// 24_TFT display
|
||||||
|
@ -260,7 +290,6 @@ void ILI9341TFT24::initialize() {
|
||||||
this->init_lcd_(INITCMD_TFT);
|
this->init_lcd_(INITCMD_TFT);
|
||||||
this->width_ = 240;
|
this->width_ = 240;
|
||||||
this->height_ = 320;
|
this->height_ = 320;
|
||||||
this->fill_internal_(Color::BLACK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 24_TFT rotated display
|
// 24_TFT rotated display
|
||||||
|
@ -268,7 +297,6 @@ void ILI9341TFT24R::initialize() {
|
||||||
this->init_lcd_(INITCMD_TFT);
|
this->init_lcd_(INITCMD_TFT);
|
||||||
this->width_ = 320;
|
this->width_ = 320;
|
||||||
this->height_ = 240;
|
this->height_ = 240;
|
||||||
this->fill_internal_(Color::BLACK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ili9341
|
} // namespace ili9341
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "esphome/components/display/display_buffer.h"
|
#include "esphome/components/display/display_buffer.h"
|
||||||
#include "ili9341_defines.h"
|
#include "ili9341_defines.h"
|
||||||
#include "ili9341_init.h"
|
#include "ili9341_init.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ili9341 {
|
namespace ili9341 {
|
||||||
|
@ -47,6 +48,14 @@ class ILI9341Display : public PollingComponent,
|
||||||
void setup() override {
|
void setup() override {
|
||||||
this->setup_pins_();
|
this->setup_pins_();
|
||||||
this->initialize();
|
this->initialize();
|
||||||
|
|
||||||
|
this->x_low_ = this->width_;
|
||||||
|
this->y_low_ = this->height_;
|
||||||
|
this->x_high_ = 0;
|
||||||
|
this->y_high_ = 0;
|
||||||
|
|
||||||
|
this->init_internal_(this->get_buffer_length_());
|
||||||
|
this->fill_internal_(0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }
|
display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }
|
||||||
|
@ -59,8 +68,9 @@ class ILI9341Display : public PollingComponent,
|
||||||
void set_addr_window_(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
void set_addr_window_(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||||||
void invert_display_(bool invert);
|
void invert_display_(bool invert);
|
||||||
void reset_();
|
void reset_();
|
||||||
void fill_internal_(Color color);
|
void fill_internal_(uint8_t color);
|
||||||
void display_();
|
void display_();
|
||||||
|
void rotate_my_(uint8_t m);
|
||||||
|
|
||||||
ILI9341Model model_;
|
ILI9341Model model_;
|
||||||
int16_t width_{320}; ///< Display width as modified by current rotation
|
int16_t width_{320}; ///< Display width as modified by current rotation
|
||||||
|
|
Loading…
Reference in a new issue