12static const uint16_t SPI_SETUP_US = 100;
13static const uint16_t SPI_MAX_BLOCK_SIZE = 4092;
16static inline void put16_be(uint8_t *buf, uint16_t value) {
32 esph_log_d(TAG,
"Wrote MADCTL 0x%02X", mad);
73 this->
mark_failed(LOG_STR(
"Failed to allocate the display buffer"));
91 LOG_DISPLAY(
"",
"ili9xxx",
this);
98 ESP_LOGCONFIG(TAG,
" Color mode: 8bit Indexed");
101 ESP_LOGCONFIG(TAG,
" Color mode: 16bit");
104 ESP_LOGCONFIG(TAG,
" Color mode: 8bit 332 mode");
108 ESP_LOGCONFIG(TAG,
" 18-Bit Mode: YES");
110 ESP_LOGCONFIG(TAG,
" Data rate: %dMHz", (
unsigned) (this->
data_rate_ / 1000000));
113 LOG_PIN(
" CS Pin: ", this->
cs_);
114 LOG_PIN(
" DC Pin: ", this->
dc_pin_);
121 " Invert colors: %s",
125 LOG_UPDATE_INTERVAL(
this);
136 Display::fill(color);
140 uint16_t new_color = 0;
147 new_color = display::ColorUtil::color_to_index8_palette888(color, this->
palette_);
150 new_color = display::ColorUtil::color_to_565(color);
153 if (((uint8_t) (new_color >> 8)) == ((uint8_t) new_color)) {
155 memset(this->
buffer_, (uint8_t) new_color, buffer_length_16_bits);
157 for (
uint32_t i = 0; i < buffer_length_16_bits; i = i + 2) {
158 this->
buffer_[i] = (uint8_t) (new_color >> 8);
159 this->
buffer_[i + 1] = (uint8_t) new_color;
165 new_color = display::ColorUtil::color_to_332(color);
179 bool updated =
false;
182 new_color = display::ColorUtil::color_to_index8_palette888(color, this->
palette_);
186 new_color = display::ColorUtil::color_to_565(color);
187 if (this->
buffer_[pos] != (uint8_t) (new_color >> 8)) {
188 this->
buffer_[
pos] = (uint8_t) (new_color >> 8);
192 new_color = new_color & 0xFF;
195 new_color = display::ColorUtil::color_to_332(color);
199 if (this->
buffer_[pos] != new_color) {
232 if (this->
buffer_ ==
nullptr) {
241 size_t const w = this->
x_high_ - this->x_low_ + 1;
242 size_t const h = this->
y_high_ - this->y_low_ + 1;
246 size_t sw_time = this->
width_ * h * 16 / mhz + this->
width_ * h * 2 / SPI_MAX_BLOCK_SIZE * SPI_SETUP_US * 2;
250 "Start display(xlow:%d, ylow:%d, xhigh:%d, yhigh:%d, width:%d, "
251 "height:%zu, mode=%d, 18bit=%d, sw_time=%zuus, mw_time=%zuus)",
257 ESP_LOGV(TAG,
"Doing single write of %zu bytes", this->
width_ * h * 2);
261 ESP_LOGV(TAG,
"Doing multiple write");
272 color_val = display::ColorUtil::color_to_565(display::ColorUtil::rgb332_to_color(this->
buffer_[pos++]));
275 color_val = display::ColorUtil::color_to_565(
276 display::ColorUtil::index8_to_color_palette888(this->
buffer_[pos++], this->
palette_));
279 color_val = (this->
buffer_[pos * 2] << 8) + this->
buffer_[pos * 2 + 1];
284 transfer_buffer[idx++] = (uint8_t) ((color_val & 0xF800) >> 8);
285 transfer_buffer[idx++] = (uint8_t) ((color_val & 0x7E0) >> 3);
286 transfer_buffer[idx++] = (uint8_t) (color_val << 3);
288 put16_be(transfer_buffer + idx, color_val);
291 if (idx ==
sizeof(transfer_buffer)) {
308 ESP_LOGV(TAG,
"Data write took %dms", (
unsigned) (
millis() - now));
310 this->x_low_ = this->
width_;
321 if (
w <= 0 ||
h <= 0)
337 const int first_col = std::max(0, -x_start), end_col = std::min(
w, this->
get_width_internal() - x_start);
339 if (first_col >= end_col || first_row >= end_row)
341 for (
int y = first_row;
y != end_row;
y++) {
342 memcpy(this->
buffer_ + ((y_start +
y) * this->
width_ + x_start + first_col) * 2,
345 this->
x_low_ = std::min<int>(this->
x_low_, x_start + first_col);
346 this->
y_low_ = std::min<int>(this->
y_low_, y_start + first_row);
347 this->
x_high_ = std::max<int>(this->
x_high_, x_start + end_col - 1);
348 this->
y_high_ = std::max<int>(this->
y_high_, y_start + end_row - 1);
357 for (
size_t y = 0;
y !=
static_cast<size_t>(
h);
y++) {
364 ESP_LOGV(TAG,
"Doing multiple write");
370 uint8_t hi_byte = *
ptr++;
371 uint8_t lo_byte = *
ptr++;
372 transfer_buffer[idx++] = hi_byte & 0xF8;
373 transfer_buffer[idx++] = ((hi_byte << 5) | (lo_byte) >> 5);
374 transfer_buffer[idx++] = lo_byte << 3;
375 if (idx ==
sizeof(transfer_buffer)) {
381 if (++pixel ==
static_cast<size_t>(
w)) {
441 uint8_t cmd,
x, num_args;
442 while ((cmd = *addr++) != 0) {
444 if (
x == ILI9XXX_DELAY_FLAG) {
446 ESP_LOGV(TAG,
"Delay %dms", cmd);
450 ESP_LOGV(TAG,
"Command %02X, length %d, bits %02X", cmd, num_args, *addr);
454 ESP_LOGV(TAG,
"Delay 150ms");
469 this->
data(x1 & 0xFF);
471 this->
data(x2 & 0xFF);
474 this->
data(y1 & 0xFF);
476 this->
data(y2 & 0xFF);
484 this->
command(invert ? ILI9XXX_INVON : ILI9XXX_INVOFF);
void feed_wdt()
Feed the task watchdog.
void mark_failed()
Mark this component as failed.
virtual void digital_write(bool value)=0
void init_internal_(uint32_t buffer_length)
int int int const uint8_t ColorOrder ColorBitness bitness
int int int const uint8_t ColorOrder ColorBitness bool int int y_offset
int int int const uint8_t ColorOrder ColorBitness bool int int int x_pad
int int int const uint8_t * ptr
int int int const uint8_t ColorOrder ColorBitness bool big_endian
Rect get_clipping() const
Get the current the clipping rectangle.
int int int const uint8_t ColorOrder ColorBitness bool int x_offset
DisplayRotation rotation_
virtual void draw_pixels_internal(int x_start, int y_start, int w, int h, const uint8_t *ptr, ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad)
Draws a block for draw_pixels_at(); the parameters are the same.
virtual void data(uint8_t value)
int16_t width_
Display width as modified by current rotation.
void draw_pixels_internal(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override
std::vector< uint8_t > extra_init_sequence_
float get_setup_priority() const override
void set_addr_window_(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2)
uint8_t const * init_sequence_
void init_lcd_(const uint8_t *addr)
uint32_t get_buffer_length_()
int get_width_internal() override
virtual void set_madctl()
virtual void command(uint8_t value)
void draw_absolute_pixel_internal(int x, int y, Color color) override
void fill(Color color) override
display::ColorOrder color_order_
void dump_config() override
int get_height_internal() override
void send_command(uint8_t command_byte, const uint8_t *data_bytes, uint8_t num_data_bytes)
ILI9XXXColorMode buffer_color_mode_
int16_t height_
Display height as modified by current rotation.
void invert_colors(bool invert)
void spi_setup() override
void write_byte(uint8_t data)
void write_array(const uint8_t *data, size_t length)
@ DISPLAY_ROTATION_0_DEGREES
const size_t ILI9XXX_TRANSFER_BUFFER_SIZE
constexpr float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
value[LAYOUT.day_index()]
void HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.