ESPHome  2024.8.3
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 
20 enum PixelMode {
24 };
25 
27  public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW,
28  spi::CLOCK_PHASE_LEADING, spi::DATA_RATE_40MHZ> {
29  public:
30  ILI9XXXDisplay() = default;
31  ILI9XXXDisplay(uint8_t const *init_sequence, int16_t width, int16_t height, bool invert_colors)
32  : init_sequence_{init_sequence}, width_{width}, height_{height}, pre_invertcolors_{invert_colors} {
33  uint8_t cmd, num_args, bits;
34  const uint8_t *addr = init_sequence;
35  while ((cmd = *addr++) != 0) {
36  num_args = *addr++;
37  if (num_args == ILI9XXX_DELAY_FLAG)
38  continue;
39  bits = *addr;
40  switch (cmd) {
41  case ILI9XXX_MADCTL: {
42  this->swap_xy_ = (bits & MADCTL_MV) != 0;
43  this->mirror_x_ = (bits & MADCTL_MX) != 0;
44  this->mirror_y_ = (bits & MADCTL_MY) != 0;
45  this->color_order_ = (bits & MADCTL_BGR) ? display::COLOR_ORDER_BGR : display::COLOR_ORDER_RGB;
46  break;
47  }
48 
49  case ILI9XXX_PIXFMT: {
50  if ((bits & 0xF) == 6)
51  this->is_18bitdisplay_ = true;
52  break;
53  }
54 
55  default:
56  break;
57  }
58  addr += (num_args & 0x7F);
59  }
60  }
61 
62  void add_init_sequence(const std::vector<uint8_t> &sequence) { this->extra_init_sequence_ = sequence; }
63  void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
64  float get_setup_priority() const override;
66  void set_palette(const uint8_t *palette) { this->palette_ = palette; }
67  void set_buffer_color_mode(ILI9XXXColorMode color_mode) { this->buffer_color_mode_ = color_mode; }
68  void set_dimensions(int16_t width, int16_t height) {
69  this->height_ = height;
70  this->width_ = width;
71  }
72  void set_offsets(int16_t offset_x, int16_t offset_y) {
73  this->offset_x_ = offset_x;
74  this->offset_y_ = offset_y;
75  }
76  void invert_colors(bool invert);
77  virtual void command(uint8_t value);
78  virtual void data(uint8_t value);
79  void send_command(uint8_t command_byte, const uint8_t *data_bytes, uint8_t num_data_bytes);
80  void set_color_order(display::ColorOrder color_order) { this->color_order_ = color_order; }
81  void set_swap_xy(bool swap_xy) { this->swap_xy_ = swap_xy; }
82  void set_mirror_x(bool mirror_x) { this->mirror_x_ = mirror_x; }
83  void set_mirror_y(bool mirror_y) { this->mirror_y_ = mirror_y; }
85 
86  void update() override;
87 
88  void fill(Color color) override;
89 
90  void dump_config() override;
91  void setup() override;
92 
94  void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order,
95  display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override;
96 
97  protected:
98  inline bool check_buffer_() {
99  if (this->buffer_ == nullptr) {
100  this->alloc_buffer_();
101  return !this->is_failed();
102  }
103  return true;
104  }
105 
106  void draw_absolute_pixel_internal(int x, int y, Color color) override;
107  void setup_pins_();
108 
109  virtual void set_madctl();
110  void display_();
111  void init_lcd_(const uint8_t *addr);
112  void set_addr_window_(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2);
113  void reset_();
114 
115  uint8_t const *init_sequence_{};
116  std::vector<uint8_t> extra_init_sequence_;
117  int16_t width_{0};
118  int16_t height_{0};
119  int16_t offset_x_{0};
120  int16_t offset_y_{0};
121  uint16_t x_low_{0};
122  uint16_t y_low_{0};
123  uint16_t x_high_{0};
124  uint16_t y_high_{0};
125  const uint8_t *palette_{};
126 
128 
129  uint32_t get_buffer_length_();
130  int get_width_internal() override;
131  int get_height_internal() override;
132 
133  void start_command_();
134  void end_command_();
135  void start_data_();
136  void end_data_();
137  void alloc_buffer_();
138 
139  GPIOPin *reset_pin_{nullptr};
140  GPIOPin *dc_pin_{nullptr};
141  GPIOPin *busy_pin_{nullptr};
142 
143  bool prossing_update_ = false;
144  bool need_update_ = false;
145  bool is_18bitdisplay_ = false;
147  bool pre_invertcolors_ = false;
149  bool swap_xy_{};
150  bool mirror_x_{};
151  bool mirror_y_{};
152 };
153 
154 //----------- M5Stack display --------------
156  public:
157  ILI9XXXM5Stack() : ILI9XXXDisplay(INITCMD_M5STACK, 320, 240, true) {}
158 };
159 
160 //----------- M5Stack display --------------
162  public:
163  ILI9XXXM5CORE() : ILI9XXXDisplay(INITCMD_M5CORE, 320, 240, true) {}
164 };
165 
166 //----------- ST7789V display --------------
168  public:
169  ILI9XXXST7789V() : ILI9XXXDisplay(INITCMD_ST7789V, 240, 320, false) {}
170 };
171 
172 //----------- ILI9XXX_24_TFT display --------------
174  public:
175  ILI9XXXILI9341() : ILI9XXXDisplay(INITCMD_ILI9341, 240, 320, false) {}
176 };
177 
178 //----------- ILI9XXX_24_TFT rotated display --------------
180  public:
181  ILI9XXXILI9342() : ILI9XXXDisplay(INITCMD_ILI9341, 320, 240, false) {}
182 };
183 
184 //----------- ILI9XXX_??_TFT rotated display --------------
186  public:
187  ILI9XXXILI9481() : ILI9XXXDisplay(INITCMD_ILI9481, 480, 320, false) {}
188 };
189 
190 //----------- ILI9481 in 18 bit mode --------------
192  public:
193  ILI9XXXILI948118() : ILI9XXXDisplay(INITCMD_ILI9481_18, 320, 480, true) {}
194 };
195 
196 //----------- ILI9XXX_35_TFT rotated display --------------
198  public:
199  ILI9XXXILI9486() : ILI9XXXDisplay(INITCMD_ILI9486, 480, 320, false) {}
200 };
201 
203  public:
204  ILI9XXXILI9488(const uint8_t *seq = INITCMD_ILI9488) : ILI9XXXDisplay(seq, 480, 320, true) {}
205 
206  protected:
207  void set_madctl() override {
208  uint8_t mad = this->color_order_ == display::COLOR_ORDER_BGR ? MADCTL_BGR : MADCTL_RGB;
209  uint8_t dfun = 0x22;
210  this->width_ = 320;
211  this->height_ = 480;
212  if (!(this->swap_xy_ || this->mirror_x_ || this->mirror_y_)) {
213  // no transforms
214  } else if (this->mirror_y_ && this->mirror_x_) {
215  // rotate 180
216  dfun = 0x42;
217  } else if (this->swap_xy_) {
218  this->width_ = 480;
219  this->height_ = 320;
220  mad |= 0x20;
221  if (this->mirror_x_) {
222  dfun = 0x02;
223  } else {
224  dfun = 0x62;
225  }
226  }
227  this->command(ILI9XXX_DFUNCTR);
228  this->data(0);
229  this->data(dfun);
230  this->command(ILI9XXX_MADCTL);
231  this->data(mad);
232  }
233 };
234 //----------- Waveshare 3.5 Res Touch - ILI9488 interfaced via 16 bit shift register to parallel */
236  public:
237  WAVESHARERES35() : ILI9XXXILI9488(INITCMD_WAVESHARE_RES_3_5) {}
238  void data(uint8_t value) override {
239  this->start_data_();
240  this->write_byte(0);
241  this->write_byte(value);
242  this->end_data_();
243  }
244 };
245 
246 //----------- ILI9XXX_35_TFT origin colors rotated display --------------
248  public:
249  ILI9XXXILI9488A() : ILI9XXXDisplay(INITCMD_ILI9488_A, 480, 320, true) {}
250 };
251 
252 //----------- ILI9XXX_35_TFT rotated display --------------
254  public:
255  ILI9XXXST7796() : ILI9XXXDisplay(INITCMD_ST7796, 320, 480, false) {}
256 };
257 
258 class ILI9XXXS3Box : public ILI9XXXDisplay {
259  public:
260  ILI9XXXS3Box() : ILI9XXXDisplay(INITCMD_S3BOX, 320, 240, false) {}
261 };
262 
264  public:
265  ILI9XXXS3BoxLite() : ILI9XXXDisplay(INITCMD_S3BOXLITE, 320, 240, true) {}
266 };
267 
269  public:
270  ILI9XXXGC9A01A() : ILI9XXXDisplay(INITCMD_GC9A01A, 240, 240, true) {}
271 };
272 
273 //----------- ILI9XXX_24_TFT display --------------
275  public:
276  ILI9XXXST7735() : ILI9XXXDisplay(INITCMD_ST7735, 128, 160, false) {}
277 };
278 
279 } // namespace ili9xxx
280 } // 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)
void set_pixel_mode(PixelMode mode)
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)
bool is_failed() const
Definition: component.cpp:143
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:391
void draw_absolute_pixel_internal(int x, int y, Color color) override
int16_t height_
Display height as modified by current rotation.
void init_lcd_(const uint8_t *addr)
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:181
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 add_init_sequence(const std::vector< uint8_t > &sequence)
void set_offsets(int16_t offset_x, int16_t offset_y)
uint8_t h
Definition: bl0939.h:21
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
std::vector< uint8_t > extra_init_sequence_
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)