diff --git a/esp/cpp/07_lcd-panel/main/display.cpp b/esp/cpp/07_lcd-panel/main/display.cpp index e5d2e57..010faf1 100644 --- a/esp/cpp/07_lcd-panel/main/display.cpp +++ b/esp/cpp/07_lcd-panel/main/display.cpp @@ -19,44 +19,17 @@ uint8_t Display::oled_buffer_[LCD_H_RES * LCD_V_RES / 8]; _lock_t ScopedLock::lock_; Display::Display(const I2C &i2c) : - io_handle_(nullptr), - panel_handle_(nullptr), - buf_(nullptr) + panel_(i2c) { - ESP_LOGI(TAG, "Install panel IO"); - esp_lcd_panel_io_i2c_config_t io_config = { - .dev_addr = I2C_HW_ADDR, - .control_phase_bytes = 1, // According to SSD1306 datasheet - .dc_bit_offset = 6, // According to SSD1306 datasheet - .lcd_cmd_bits = LCD_CMD_BITS, // According to SSD1306 datasheet - .lcd_param_bits = LCD_CMD_BITS, // According to SSD1306 datasheet - .scl_speed_hz = LCD_PIXEL_CLOCK_HZ, - }; - ESP_ERROR_CHECK( - esp_lcd_new_panel_io_i2c(i2c.i2c_bus_, &io_config, &io_handle_)); + if (!lv_is_initialized()) { + ESP_LOGI(TAG, "Initialize LVGL"); + lv_init(); + } - ESP_LOGI(TAG, "Install SSD1306 panel driver"); - ssd1306_config_ = { - .height = LCD_V_RES, - }; - panel_config_ = { - .reset_gpio_num = PIN_RST, - .bits_per_pixel = 1, - .vendor_config = &ssd1306_config_ - }; - ESP_ERROR_CHECK( - esp_lcd_new_panel_ssd1306(io_handle_, &panel_config_, &panel_handle_)); - - ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle_)); - ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle_)); - ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle_, true)); - - ESP_LOGI(TAG, "Initialize LVGL"); - lv_init(); // create a lvgl display display_ = lv_display_create(LCD_H_RES, LCD_V_RES); // associate the i2c panel handle to the display - lv_display_set_user_data(display_, panel_handle_); + lv_display_set_user_data(display_, panel_.get()); // create draw buffer ESP_LOGI(TAG, "Allocate separate LVGL draw buffers"); // LVGL reserves 2 x 4 bytes in the buffer, as these are assumed to be used as a palette. @@ -81,7 +54,8 @@ Display::Display(const I2C &i2c) : }; /* Register done callback */ ESP_ERROR_CHECK( - esp_lcd_panel_io_register_event_callbacks(io_handle_, &cbs, display_)); + esp_lcd_panel_io_register_event_callbacks(panel_.io_handle_, &cbs, + display_)); ESP_LOGI(TAG, "Use esp_timer as LVGL tick timer"); const esp_timer_create_args_t lvgl_tick_timer_args = { @@ -213,3 +187,34 @@ I2C::I2C() : i2c_bus_(nullptr) }; ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &i2c_bus_)); } + +Panel::Panel(i2c_master_bus_handle_t i2c) : io_handle_(nullptr), panel_(nullptr) +{ + ESP_LOGI(TAG, "Install panel IO"); + esp_lcd_panel_io_i2c_config_t io_config = { + .dev_addr = I2C_HW_ADDR, + .control_phase_bytes = 1, // According to SSD1306 datasheet + .dc_bit_offset = 6, // According to SSD1306 datasheet + .lcd_cmd_bits = LCD_CMD_BITS, // According to SSD1306 datasheet + .lcd_param_bits = LCD_CMD_BITS, // According to SSD1306 datasheet + .scl_speed_hz = LCD_PIXEL_CLOCK_HZ, + }; + ESP_ERROR_CHECK( + esp_lcd_new_panel_io_i2c(i2c, &io_config, &io_handle_)); + + ESP_LOGI(TAG, "Install SSD1306 panel driver"); + ssd1306_config_ = { + .height = LCD_V_RES, + }; + panel_config_ = { + .reset_gpio_num = PIN_RST, + .bits_per_pixel = 1, + .vendor_config = &ssd1306_config_ + }; + ESP_ERROR_CHECK( + esp_lcd_new_panel_ssd1306(io_handle_, &panel_config_, &panel_)); + + ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_)); + ESP_ERROR_CHECK(esp_lcd_panel_init(panel_)); + ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_, true)); +} diff --git a/esp/cpp/07_lcd-panel/main/display.h b/esp/cpp/07_lcd-panel/main/display.h index ee7be22..1045ad1 100644 --- a/esp/cpp/07_lcd-panel/main/display.h +++ b/esp/cpp/07_lcd-panel/main/display.h @@ -54,6 +54,33 @@ struct ScopedLock { static _lock_t lock_; }; +class Panel { +public: + explicit Panel(i2c_master_bus_handle_t i2c); + + explicit Panel(const I2C &i2c) : Panel(i2c.i2c_bus_) { } + + ~Panel() = default; + + [[nodiscard]] inline const esp_lcd_panel_t *get() const { return panel_; } + + [[nodiscard]] inline esp_lcd_panel_t *get() { return panel_; } + + [[nodiscard]] inline const esp_lcd_panel_t * + operator*() const { return get(); } + + [[nodiscard]] inline esp_lcd_panel_t *operator*() { return get(); } + + esp_lcd_panel_io_handle_t io_handle_; + + esp_lcd_panel_handle_t panel_; + +private: + esp_lcd_panel_dev_config_t panel_config_; + + esp_lcd_panel_ssd1306_config_t ssd1306_config_; +}; + class Display { public: explicit Display(const I2C &i2c); @@ -88,25 +115,14 @@ public: // For LV_COLOR_FORMAT_I1 we need an extra buffer to hold the converted data. static uint8_t oled_buffer_[LCD_H_RES * LCD_V_RES / 8]; -protected: - esp_lcd_panel_io_handle_t io_handle_; - - esp_lcd_panel_handle_t panel_handle_; - - esp_lcd_panel_dev_config_t panel_config_; - - esp_lcd_panel_ssd1306_config_t ssd1306_config_; - private: -// virtual void *vendor_config() = 0; - - std::unordered_map objects_; + Panel panel_; lv_display_t *display_; - void *vendor_config_; - void *buf_; + + std::unordered_map objects_; }; //class SSD1306 : public Display {