ESPHome  2024.4.0
ili9xxx_display.h
Go to the documentation of this file.
1 #pragma once
5 #include "ili9xxx_defines.h"
6 #include "ili9xxx_init.h"
7 
8 namespace esphome {
9 namespace ili9xxx {
10 
11 static const char *const TAG = "ili9xxx";
12 const size_t ILI9XXX_TRANSFER_BUFFER_SIZE = 126; // ensure this is divisible by 6
13 
15  BITS_8 = 0x08,
17  BITS_16 = 0x10,
18 };
19 
21  public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
22  spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_40MHZ> {
23  public:
24  ILI9XXXDisplay() = default;
25  ILI9XXXDisplay(uint8_t const *init_sequence, int16_t width, int16_t height, bool invert_colors)
26  : init_sequence_{init_sequence}, width_{width}, height_{height}, pre_invertcolors_{invert_colors} {
27  uint8_t cmd, num_args, bits;
28  const uint8_t *addr = init_sequence;
29  while ((cmd = *addr++) != 0) {
30  num_args = *addr++ & 0x7F;
31  bits = *addr;
32  esph_log_d(TAG, "Command %02X, length %d, bits %02X", cmd, num_args, bits);
33  switch (cmd) {
34  case ILI9XXX_MADCTL: {
35  this->swap_xy_ = (bits & MADCTL_MV) != 0;
36  this->mirror_x_ = (bits & MADCTL_MX) != 0;
37  this->mirror_y_ = (bits & MADCTL_MY) != 0;
38  this->color_order_ = (bits & MADCTL_BGR) ? display::COLOR_ORDER_BGR : display::COLOR_ORDER_RGB;
39  break;
40  }
41 
42  case ILI9XXX_PIXFMT: {
43  if ((bits & 0xF) == 6)
44  this->is_18bitdisplay_ = true;
45  break;
46  }
47 
48  default:
49  break;
50  }
51  addr += num_args;
52  }
53  }
54 
55  void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
56  float get_setup_priority() const override;
58  void set_palette(const uint8_t *palette) { this->palette_ = palette; }
59  void set_buffer_color_mode(ILI9XXXColorMode color_mode) { this->buffer_color_mode_ = color_mode; }
60  void set_dimensions(int16_t width, int16_t height) {
61  this->height_ = height;
62  this->width_ = width;
63  }
64  void set_offsets(int16_t offset_x, int16_t offset_y) {
65  this->offset_x_ = offset_x;
66  this->offset_y_ = offset_y;
67  }
68  void invert_colors(bool invert);
69  virtual void command(uint8_t value);
70  virtual void data(uint8_t value);
71  void send_command(uint8_t command_byte, const uint8_t *data_bytes, uint8_t num_data_bytes);
72  void set_color_order(display::ColorOrder color_order) { this->color_order_ = color_order; }
73  void set_swap_xy(bool swap_xy) { this->swap_xy_ = swap_xy; }
74  void set_mirror_x(bool mirror_x) { this->mirror_x_ = mirror_x; }
75  void set_mirror_y(bool mirror_y) { this->mirror_y_ = mirror_y; }
76 
77  void update() override;
78 
79  void fill(Color color) override;
80 
81  void dump_config() override;
82  void setup() override;
83 
85  void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order,
86  display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override;
87 
88  protected:
89  inline bool check_buffer_() {
90  if (this->buffer_ == nullptr) {
91  this->alloc_buffer_();
92  return !this->is_failed();
93  }
94  return true;
95  }
96 
97  void draw_absolute_pixel_internal(int x, int y, Color color) override;
98  void setup_pins_();
99 
100  virtual void set_madctl();
101  void display_();
102  void init_lcd_();
103  void set_addr_window_(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2);
104  void reset_();
105 
106  uint8_t const *init_sequence_{};
107  int16_t width_{0};
108  int16_t height_{0};
109  int16_t offset_x_{0};
110  int16_t offset_y_{0};
111  uint16_t x_low_{0};
112  uint16_t y_low_{0};
113  uint16_t x_high_{0};
114  uint16_t y_high_{0};
115  const uint8_t *palette_;
116 
118 
119  uint32_t get_buffer_length_();
120  int get_width_internal() override;
121  int get_height_internal() override;
122 
123  void start_command_();
124  void end_command_();
125  void start_data_();
126  void end_data_();
127  void alloc_buffer_();
128 
129  GPIOPin *reset_pin_{nullptr};
130  GPIOPin *dc_pin_{nullptr};
131  GPIOPin *busy_pin_{nullptr};
132 
133  bool prossing_update_ = false;
134  bool need_update_ = false;
135  bool is_18bitdisplay_ = false;
136  bool pre_invertcolors_ = false;
138  bool swap_xy_{};
139  bool mirror_x_{};
140  bool mirror_y_{};
141 };
142 
143 //----------- M5Stack display --------------
145  public:
146  ILI9XXXM5Stack() : ILI9XXXDisplay(INITCMD_M5STACK, 320, 240, true) {}
147 };
148 
149 //----------- M5Stack display --------------
151  public:
152  ILI9XXXM5CORE() : ILI9XXXDisplay(INITCMD_M5CORE, 320, 240, true) {}
153 };
154 
155 //----------- ST7789V display --------------
157  public:
158  ILI9XXXST7789V() : ILI9XXXDisplay(INITCMD_ST7789V, 240, 320, false) {}
159 };
160 
161 //----------- ILI9XXX_24_TFT display --------------
163  public:
164  ILI9XXXILI9341() : ILI9XXXDisplay(INITCMD_ILI9341, 240, 320, false) {}
165 };
166 
167 //----------- ILI9XXX_24_TFT rotated display --------------
169  public:
170  ILI9XXXILI9342() : ILI9XXXDisplay(INITCMD_ILI9341, 320, 240, false) {}
171 };
172 
173 //----------- ILI9XXX_??_TFT rotated display --------------
175  public:
176  ILI9XXXILI9481() : ILI9XXXDisplay(INITCMD_ILI9481, 480, 320, false) {}
177 };
178 
179 //----------- ILI9481 in 18 bit mode --------------
181  public:
182  ILI9XXXILI948118() : ILI9XXXDisplay(INITCMD_ILI9481_18, 320, 480, true) {}
183 };
184 
185 //----------- ILI9XXX_35_TFT rotated display --------------
187  public:
188  ILI9XXXILI9486() : ILI9XXXDisplay(INITCMD_ILI9486, 480, 320, false) {}
189 };
190 
192  public:
193  ILI9XXXILI9488(const uint8_t *seq = INITCMD_ILI9488) : ILI9XXXDisplay(seq, 480, 320, true) {}
194 
195  protected:
196  void set_madctl() override {
197  uint8_t mad = this->color_order_ == display::COLOR_ORDER_BGR ? MADCTL_BGR : MADCTL_RGB;
198  uint8_t dfun = 0x22;
199  this->width_ = 320;
200  this->height_ = 480;
201  if (!(this->swap_xy_ || this->mirror_x_ || this->mirror_y_)) {
202  // no transforms
203  } else if (this->mirror_y_ && this->mirror_x_) {
204  // rotate 180
205  dfun = 0x42;
206  } else if (this->swap_xy_) {
207  this->width_ = 480;
208  this->height_ = 320;
209  mad |= 0x20;
210  if (this->mirror_x_) {
211  dfun = 0x02;
212  } else {
213  dfun = 0x62;
214  }
215  }
216  this->command(ILI9XXX_DFUNCTR);
217  this->data(0);
218  this->data(dfun);
219  this->command(ILI9XXX_MADCTL);
220  this->data(mad);
221  }
222 };
223 //----------- Waveshare 3.5 Res Touch - ILI9488 interfaced via 16 bit shift register to parallel */
225  public:
226  WAVESHARERES35() : ILI9XXXILI9488(INITCMD_WAVESHARE_RES_3_5) {}
227  void data(uint8_t value) override {
228  this->start_data_();
229  this->write_byte(0);
230  this->write_byte(value);
231  this->end_data_();
232  }
233 };
234 
235 //----------- ILI9XXX_35_TFT origin colors rotated display --------------
237  public:
238  ILI9XXXILI9488A() : ILI9XXXDisplay(INITCMD_ILI9488_A, 480, 320, true) {}
239 };
240 
241 //----------- ILI9XXX_35_TFT rotated display --------------
243  public:
244  ILI9XXXST7796() : ILI9XXXDisplay(INITCMD_ST7796, 320, 480, false) {}
245 };
246 
247 class ILI9XXXS3Box : public ILI9XXXDisplay {
248  public:
249  ILI9XXXS3Box() : ILI9XXXDisplay(INITCMD_S3BOX, 320, 240, false) {}
250 };
251 
253  public:
254  ILI9XXXS3BoxLite() : ILI9XXXDisplay(INITCMD_S3BOXLITE, 320, 240, true) {}
255 };
256 
258  public:
259  ILI9XXXGC9A01A() : ILI9XXXDisplay(INITCMD_GC9A01A, 240, 240, true) {}
260 };
261 
262 } // namespace ili9xxx
263 } // namespace esphome
ILI9XXXDisplay(uint8_t const *init_sequence, int16_t width, int16_t height, bool invert_colors)
void send_command(uint8_t command_byte, const uint8_t *data_bytes, uint8_t num_data_bytes)
ILI9XXXILI9488(const uint8_t *seq=INITCMD_ILI9488)
void set_palette(const uint8_t *palette)
void set_addr_window_(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2)
uint16_t x
Definition: tt21100.cpp:17
void set_mirror_x(bool mirror_x)
void set_mirror_y(bool mirror_y)
void data(uint8_t value) override
uint16_t y
Definition: tt21100.cpp:18
void set_buffer_color_mode(ILI9XXXColorMode color_mode)
int16_t width_
Display width as modified by current rotation.
The SPIDevice is what components using the SPI will create.
Definition: spi.h:408
void draw_absolute_pixel_internal(int x, int y, Color color) override
int16_t height_
Display height as modified by current rotation.
float get_setup_priority() const override
const size_t ILI9XXX_TRANSFER_BUFFER_SIZE
uint16_t reset
Definition: ina226.h:39
virtual void data(uint8_t value)
void set_dimensions(int16_t width, int16_t height)
display::DisplayType get_display_type() override
void set_offsets(int16_t offset_x, int16_t offset_y)
uint8_t h
Definition: bl0939.h:21
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order, display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override
void fill(Color color) override
void set_dc_pin(GPIOPin *dc_pin)
void set_reset_pin(GPIOPin *reset)
void set_color_order(display::ColorOrder color_order)
stm32_cmd_t * cmd
Definition: stm32flash.h:96
virtual void command(uint8_t value)