10 static const uint16_t SPI_SETUP_US = 100;
11 static const uint16_t SPI_MAX_BLOCK_SIZE = 4092;
14 static inline void put16_be(uint8_t *buf, uint16_t value) {
30 esph_log_d(TAG,
"Wrote MADCTL 0x%02X", mad);
34 ESP_LOGD(TAG,
"Setting up ILI9xxx");
94 LOG_DISPLAY(
"",
"ili9xxx",
this);
95 ESP_LOGCONFIG(TAG,
" Width Offset: %u", this->
offset_x_);
96 ESP_LOGCONFIG(TAG,
" Height Offset: %u", this->
offset_y_);
99 ESP_LOGCONFIG(TAG,
" Color mode: 8bit Indexed");
102 ESP_LOGCONFIG(TAG,
" Color mode: 16bit");
105 ESP_LOGCONFIG(TAG,
" Color mode: 8bit 332 mode");
109 ESP_LOGCONFIG(TAG,
" 18-Bit Mode: YES");
111 ESP_LOGCONFIG(TAG,
" Data rate: %dMHz", (
unsigned) (this->
data_rate_ / 1000000));
114 LOG_PIN(
" CS Pin: ", this->
cs_);
115 LOG_PIN(
" DC Pin: ", this->
dc_pin_);
118 ESP_LOGCONFIG(TAG,
" Swap_xy: %s", YESNO(this->
swap_xy_));
119 ESP_LOGCONFIG(TAG,
" Mirror_x: %s", YESNO(this->
mirror_x_));
120 ESP_LOGCONFIG(TAG,
" Mirror_y: %s", YESNO(this->
mirror_y_));
124 ESP_LOGCONFIG(TAG,
" => Failed to init Memory: YES!");
126 LOG_UPDATE_INTERVAL(
this);
134 uint16_t new_color = 0;
147 if (((uint8_t) (new_color >> 8)) == ((uint8_t) new_color)) {
149 memset(this->
buffer_, (uint8_t) new_color, buffer_length_16_bits);
151 for (uint32_t i = 0; i < buffer_length_16_bits; i = i + 2) {
152 this->
buffer_[i] = (uint8_t) (new_color >> 8);
153 this->
buffer_[i + 1] = (uint8_t) new_color;
171 uint32_t pos = (y *
width_) + x;
173 bool updated =
false;
181 if (this->
buffer_[pos] != (uint8_t) (new_color >> 8)) {
182 this->
buffer_[pos] = (uint8_t) (new_color >> 8);
186 new_color = new_color & 0xFF;
193 if (this->
buffer_[pos] != new_color) {
194 this->
buffer_[pos] = new_color;
226 if ((this->x_high_ < this->
x_low_) || (this->y_high_ < this->
y_low_)) {
231 size_t const w = this->
x_high_ - this->x_low_ + 1;
232 size_t const h = this->
y_high_ - this->y_low_ + 1;
236 size_t sw_time = this->
width_ * h * 16 / mhz + this->
width_ * h * 2 / SPI_MAX_BLOCK_SIZE * SPI_SETUP_US * 2;
240 "Start display(xlow:%d, ylow:%d, xhigh:%d, yhigh:%d, width:%d, " 241 "height:%zu, mode=%d, 18bit=%d, sw_time=%zuus, mw_time=%zuus)",
247 ESP_LOGV(TAG,
"Doing single write of %zu bytes", this->
width_ * h * 2);
251 ESP_LOGV(TAG,
"Doing multiple write");
257 size_t pos = this->y_low_ * this->
width_ + this->
x_low_;
269 color_val = (this->
buffer_[pos * 2] << 8) + this->
buffer_[pos * 2 + 1];
274 transfer_buffer[idx++] = (uint8_t) ((color_val & 0xF800) >> 8);
275 transfer_buffer[idx++] = (uint8_t) ((color_val & 0x7E0) >> 3);
276 transfer_buffer[idx++] = (uint8_t) (color_val << 3);
278 put16_be(transfer_buffer + idx, color_val);
281 if (idx ==
sizeof(transfer_buffer)) {
298 ESP_LOGV(TAG,
"Data write took %dms", (
unsigned) (
millis() - now));
300 this->x_low_ = this->
width_;
309 int x_offset,
int y_offset,
int x_pad) {
310 if (w <= 0 || h <= 0)
316 display::Display::draw_pixels_at(x_start, y_start, w, h, ptr, order, bitness, big_endian, x_offset, y_offset,
322 auto stride = x_offset + w + x_pad;
324 if (x_offset == 0 && x_pad == 0 && y_offset == 0) {
328 for (
size_t y = 0;
y !=
h;
y++) {
329 this->
write_array(ptr + (
y + y_offset) * stride + x_offset, w * 2);
335 ESP_LOGV(TAG,
"Doing multiple write");
339 ptr += (y_offset * stride + x_offset) * 2;
341 uint8_t hi_byte = *ptr++;
342 uint8_t lo_byte = *ptr++;
343 transfer_buffer[idx++] = hi_byte & 0xF8;
344 transfer_buffer[idx++] = ((hi_byte << 5) | (lo_byte) >> 5);
345 transfer_buffer[idx++] = lo_byte << 3;
346 if (idx ==
sizeof(transfer_buffer)) {
354 ptr += (x_pad + x_offset) * 2;
412 uint8_t
cmd,
x, num_args;
413 while ((cmd = *addr++) != 0) {
415 if (x == ILI9XXX_DELAY_FLAG) {
417 ESP_LOGV(TAG,
"Delay %dms", cmd);
421 ESP_LOGV(TAG,
"Command %02X, length %d, bits %02X", cmd, num_args, *addr);
425 ESP_LOGV(TAG,
"Delay 150ms");
440 this->
data(x1 & 0xFF);
442 this->
data(x2 & 0xFF);
445 this->
data(y1 & 0xFF);
447 this->
data(y2 & 0xFF);
455 this->
command(invert ? ILI9XXX_INVON : ILI9XXX_INVOFF);
void send_command(uint8_t command_byte, const uint8_t *data_bytes, uint8_t num_data_bytes)
virtual void digital_write(bool value)=0
uint32_t get_buffer_length_()
uint8_t const * init_sequence_
static uint16_t color_to_565(Color color, ColorOrder color_order=ColorOrder::COLOR_ORDER_RGB)
void spi_setup() override
void set_addr_window_(uint16_t x, uint16_t y, uint16_t x2, uint16_t y2)
void write_byte(uint8_t data)
uint32_t IRAM_ATTR HOT millis()
int16_t width_
Display width as modified by current rotation.
void init_internal_(uint32_t buffer_length)
void draw_absolute_pixel_internal(int x, int y, Color color) override
int16_t height_
Display height as modified by current rotation.
int get_width_internal() override
ILI9XXXColorMode buffer_color_mode_
display::ColorOrder color_order_
void init_lcd_(const uint8_t *addr)
static uint8_t color_to_332(Color color, ColorOrder color_order=ColorOrder::COLOR_ORDER_RGB)
int get_height_internal() override
float get_setup_priority() const override
void dump_config() override
static Color index8_to_color_palette888(uint8_t index, const uint8_t *palette)
const size_t ILI9XXX_TRANSFER_BUFFER_SIZE
Application App
Global storage of Application pointer - only one Application can exist.
virtual void data(uint8_t value)
DisplayRotation rotation_
const float HARDWARE
For components that deal with hardware and are very important like GPIO switch.
virtual void set_madctl()
static uint8_t color_to_index8_palette888(Color color, const uint8_t *palette)
virtual void mark_failed()
Mark this component as failed.
void write_array(const uint8_t *data, size_t length)
Implementation of SPI Controller mode.
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
static Color rgb332_to_color(uint8_t rgb332_color)
virtual void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, ColorOrder order, ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad)
Given an array of pixels encoded in the nominated format, draw these into the display's buffer...
virtual void command(uint8_t value)
void IRAM_ATTR HOT delay(uint32_t ms)
void invert_colors(bool invert)