ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
rpi_dpi_rgb.cpp
Go to the documentation of this file.
1#ifdef USE_ESP32_VARIANT_ESP32S3
2#include "rpi_dpi_rgb.h"
3#include "esphome/core/gpio.h"
4#include "esphome/core/log.h"
5#include <driver/gpio.h>
6
8
10 this->reset_display_();
11 esp_lcd_rgb_panel_config_t config{};
12 config.flags.fb_in_psram = 1;
13 config.bounce_buffer_size_px = this->width_ * 10;
14 config.num_fbs = 1;
15 config.timings.h_res = this->width_;
16 config.timings.v_res = this->height_;
17 config.timings.hsync_pulse_width = this->hsync_pulse_width_;
18 config.timings.hsync_back_porch = this->hsync_back_porch_;
19 config.timings.hsync_front_porch = this->hsync_front_porch_;
20 config.timings.vsync_pulse_width = this->vsync_pulse_width_;
21 config.timings.vsync_back_porch = this->vsync_back_porch_;
22 config.timings.vsync_front_porch = this->vsync_front_porch_;
23 config.timings.flags.pclk_active_neg = this->pclk_inverted_;
24 config.timings.pclk_hz = this->pclk_frequency_;
25 config.clk_src = LCD_CLK_SRC_PLL160M;
26 size_t data_pin_count = sizeof(this->data_pins_) / sizeof(this->data_pins_[0]);
27 for (size_t i = 0; i != data_pin_count; i++) {
28 config.data_gpio_nums[i] = static_cast<gpio_num_t>(this->data_pins_[i]->get_pin());
29 }
30 config.data_width = data_pin_count;
31 config.disp_gpio_num = GPIO_NUM_NC;
32 config.hsync_gpio_num = static_cast<gpio_num_t>(this->hsync_pin_->get_pin());
33 config.vsync_gpio_num = static_cast<gpio_num_t>(this->vsync_pin_->get_pin());
34 config.de_gpio_num = static_cast<gpio_num_t>(this->de_pin_->get_pin());
35 config.pclk_gpio_num = static_cast<gpio_num_t>(this->pclk_pin_->get_pin());
36 esp_err_t err = esp_lcd_new_rgb_panel(&config, &this->handle_);
37 if (err != ESP_OK) {
38 ESP_LOGE(TAG, "lcd_new_rgb_panel failed: %s", esp_err_to_name(err));
39 this->mark_failed();
40 return;
41 }
42 ESP_ERROR_CHECK(esp_lcd_panel_reset(this->handle_));
43 ESP_ERROR_CHECK(esp_lcd_panel_init(this->handle_));
44}
46 if (this->handle_ != nullptr)
47 esp_lcd_rgb_panel_restart(this->handle_);
48}
49
50void RpiDpiRgb::draw_pixels_internal(int x_start, int y_start, int w, int h, const uint8_t *ptr,
51 display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset,
52 int x_pad) {
53 if (w <= 0 || h <= 0)
54 return;
56 this->is_clipping()) {
58 return;
59 }
60 this->write_to_display_(x_start, y_start, w, h, ptr, x_offset, y_offset, x_pad);
61}
62
63void RpiDpiRgb::write_to_display_(int x_start, int y_start, int w, int h, const uint8_t *ptr, int x_offset,
64 int y_offset, int x_pad) {
65 x_start += this->offset_x_;
66 y_start += this->offset_y_;
67 esp_err_t err = ESP_OK;
68 // x_ and y_offset are offsets into the source buffer, unrelated to our own offsets into the display.
69 if (x_offset == 0 && x_pad == 0 && y_offset == 0) {
70 // we could deal here with a non-zero y_offset, but if x_offset is zero, y_offset probably will be so don't bother
71 err = esp_lcd_panel_draw_bitmap(this->handle_, x_start, y_start, x_start + w, y_start + h, ptr);
72 } else {
73 // draw line by line
74 auto stride = x_offset + w + x_pad;
75 for (int y = 0; y != h; y++) {
76 err = esp_lcd_panel_draw_bitmap(this->handle_, x_start, y + y_start, x_start + w, y + y_start + 1,
77 ptr + ((y + y_offset) * stride + x_offset) * 2);
78 if (err != ESP_OK)
79 break;
80 }
81 }
82 if (err != ESP_OK) {
83 ESP_LOGE(TAG, "lcd_lcd_panel_draw_bitmap failed: %s", esp_err_to_name(err));
84 }
85}
86
88 switch (this->rotation_) {
91 return this->get_height_internal();
92 default:
93 return this->get_width_internal();
94 }
95}
96
98 switch (this->rotation_) {
101 return this->get_width_internal();
102 default:
103 return this->get_height_internal();
104 }
105}
106
107void RpiDpiRgb::draw_pixel_at(int x, int y, Color color) {
108 if (this->is_point_clipped(x, y))
109 return; // NOLINT
110
111 switch (this->rotation_) {
113 break;
115 std::swap(x, y);
116 x = this->width_ - x - 1;
117 break;
119 x = this->width_ - x - 1;
120 y = this->height_ - y - 1;
121 break;
123 std::swap(x, y);
124 y = this->height_ - y - 1;
125 break;
126 }
127 auto pixel = convert_big_endian(display::ColorUtil::color_to_565(color));
128
129 this->write_to_display_(x, y, 1, 1, (const uint8_t *) &pixel, 0, 0, 0);
130 this->feed_wdt_per_pixel_();
131}
132
134 ESP_LOGCONFIG("", "RPI_DPI_RGB LCD");
135 ESP_LOGCONFIG(TAG,
136 " Height: %u\n"
137 " Width: %u",
138 this->height_, this->width_);
139 LOG_PIN(" DE Pin: ", this->de_pin_);
140 LOG_PIN(" Enable Pin: ", this->enable_pin_);
141 LOG_PIN(" Reset Pin: ", this->reset_pin_);
142 size_t data_pin_count = sizeof(this->data_pins_) / sizeof(this->data_pins_[0]);
143 char pin_summary[GPIO_SUMMARY_MAX_LEN];
144 for (size_t i = 0; i != data_pin_count; i++) {
145 this->data_pins_[i]->dump_summary(pin_summary, sizeof(pin_summary));
146 ESP_LOGCONFIG(TAG, " Data pin %d: %s", i, pin_summary);
147 }
148}
149
151 if (this->reset_pin_ != nullptr) {
152 this->reset_pin_->setup();
153 this->reset_pin_->digital_write(false);
154 if (this->enable_pin_ != nullptr) {
155 this->enable_pin_->setup();
156 this->enable_pin_->digital_write(false);
157 }
158 delay(1);
159 this->reset_pin_->digital_write(true);
160 if (this->enable_pin_ != nullptr) {
161 delay(11);
162 this->enable_pin_->digital_write(true);
163 }
164 }
165}
166
167} // namespace esphome::rpi_dpi_rgb
168
169#endif // USE_ESP32_VARIANT_ESP32S3
uint8_t h
Definition bl0906.h:2
void mark_failed()
Mark this component as failed.
virtual void setup()=0
virtual void digital_write(bool value)=0
int int int const uint8_t ColorOrder ColorBitness bitness
Definition display.h:392
void ESPHOME_ALWAYS_INLINE feed_wdt_per_pixel_()
Watchdog feed for per pixel loops.
Definition display.h:845
bool is_clipping() const
Definition display.h:805
int int int const uint8_t ColorOrder ColorBitness bool int int y_offset
Definition display.h:392
int int int const uint8_t ColorOrder ColorBitness bool int int int x_pad
Definition display.h:392
int int int const uint8_t * ptr
Definition display.h:391
bool ESPHOME_ALWAYS_INLINE is_point_clipped(int x, int y) const
Whether (x, y) falls outside the active clipping rectangle.
Definition display.h:810
int int int const uint8_t ColorOrder ColorBitness bool big_endian
Definition display.h:392
int int int const uint8_t ColorOrder ColorBitness bool int x_offset
Definition display.h:392
DisplayRotation rotation_
Definition display.h:863
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.
Definition display.cpp:119
size_t dump_summary(char *buffer, size_t len) const override
Definition gpio.cpp:139
InternalGPIOPin * data_pins_[16]
Definition rpi_dpi_rgb.h:77
void write_to_display_(int x_start, int y_start, int w, int h, const uint8_t *ptr, int x_offset, int y_offset, int x_pad)
esp_lcd_panel_handle_t handle_
Definition rpi_dpi_rgb.h:94
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
void draw_pixel_at(int x, int y, Color color) override
@ DISPLAY_ROTATION_0_DEGREES
Definition display.h:136
@ DISPLAY_ROTATION_270_DEGREES
Definition display.h:139
@ DISPLAY_ROTATION_180_DEGREES
Definition display.h:138
@ DISPLAY_ROTATION_90_DEGREES
Definition display.h:137
constexpr T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order.
Definition helpers.h:1098
constexpr size_t GPIO_SUMMARY_MAX_LEN
Maximum buffer size for dump_summary output.
Definition gpio_pin.h:14
void HOT delay(uint32_t ms)
Definition hal.cpp:85
uint16_t x
Definition tt21100.cpp:5
uint16_t y
Definition tt21100.cpp:6