i2c_oled_example_main.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: CC0-1.0
  5. */
  6. #include <stdio.h>
  7. #include "freertos/FreeRTOS.h"
  8. #include "freertos/task.h"
  9. #include "esp_timer.h"
  10. #include "esp_lcd_panel_io.h"
  11. #include "esp_lcd_panel_ops.h"
  12. #include "driver/i2c.h"
  13. #include "esp_err.h"
  14. #include "esp_log.h"
  15. #include "lvgl.h"
  16. #include "esp_lvgl_port.h"
  17. #if CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
  18. #include "esp_lcd_sh1107.h"
  19. #else
  20. #include "esp_lcd_panel_vendor.h"
  21. #endif
  22. static const char *TAG = "example";
  23. #define I2C_HOST 0
  24. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  25. //////////////////// Please update the following configuration according to your LCD spec //////////////////////////////
  26. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  27. #define EXAMPLE_LCD_PIXEL_CLOCK_HZ (400 * 1000)
  28. #define EXAMPLE_PIN_NUM_SDA 3
  29. #define EXAMPLE_PIN_NUM_SCL 4
  30. #define EXAMPLE_PIN_NUM_RST -1
  31. #define EXAMPLE_I2C_HW_ADDR 0x3C
  32. // The pixel number in horizontal and vertical
  33. #if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306
  34. #define EXAMPLE_LCD_H_RES 128
  35. #define EXAMPLE_LCD_V_RES 64
  36. #elif CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
  37. #define EXAMPLE_LCD_H_RES 64
  38. #define EXAMPLE_LCD_V_RES 128
  39. #endif
  40. // Bit number used to represent command and parameter
  41. #define EXAMPLE_LCD_CMD_BITS 8
  42. #define EXAMPLE_LCD_PARAM_BITS 8
  43. extern void example_lvgl_demo_ui(lv_disp_t *disp);
  44. /* The LVGL port component calls esp_lcd_panel_draw_bitmap API for send data to the screen. There must be called
  45. lvgl_port_flush_ready(disp) after each transaction to display. The best way is to use on_color_trans_done
  46. callback from esp_lcd IO config structure. In IDF 5.1 and higher, it is solved inside LVGL port component. */
  47. static bool notify_lvgl_flush_ready(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_io_event_data_t *edata, void *user_ctx)
  48. {
  49. lv_disp_t * disp = (lv_disp_t *)user_ctx;
  50. lvgl_port_flush_ready(disp);
  51. return false;
  52. }
  53. void app_main(void)
  54. {
  55. ESP_LOGI(TAG, "Initialize I2C bus");
  56. i2c_config_t i2c_conf = {
  57. .mode = I2C_MODE_MASTER,
  58. .sda_io_num = EXAMPLE_PIN_NUM_SDA,
  59. .scl_io_num = EXAMPLE_PIN_NUM_SCL,
  60. .sda_pullup_en = GPIO_PULLUP_ENABLE,
  61. .scl_pullup_en = GPIO_PULLUP_ENABLE,
  62. .master.clk_speed = EXAMPLE_LCD_PIXEL_CLOCK_HZ,
  63. };
  64. ESP_ERROR_CHECK(i2c_param_config(I2C_HOST, &i2c_conf));
  65. ESP_ERROR_CHECK(i2c_driver_install(I2C_HOST, I2C_MODE_MASTER, 0, 0, 0));
  66. ESP_LOGI(TAG, "Install panel IO");
  67. esp_lcd_panel_io_handle_t io_handle = NULL;
  68. esp_lcd_panel_io_i2c_config_t io_config = {
  69. .dev_addr = EXAMPLE_I2C_HW_ADDR,
  70. .control_phase_bytes = 1, // According to SSD1306 datasheet
  71. .lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS, // According to SSD1306 datasheet
  72. .lcd_param_bits = EXAMPLE_LCD_CMD_BITS, // According to SSD1306 datasheet
  73. #if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306
  74. .dc_bit_offset = 6, // According to SSD1306 datasheet
  75. #elif CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
  76. .dc_bit_offset = 0, // According to SH1107 datasheet
  77. .flags =
  78. {
  79. .disable_control_phase = 1,
  80. }
  81. #endif
  82. };
  83. ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)I2C_HOST, &io_config, &io_handle));
  84. ESP_LOGI(TAG, "Install SSD1306 panel driver");
  85. esp_lcd_panel_handle_t panel_handle = NULL;
  86. esp_lcd_panel_dev_config_t panel_config = {
  87. .bits_per_pixel = 1,
  88. .reset_gpio_num = EXAMPLE_PIN_NUM_RST,
  89. };
  90. #if CONFIG_EXAMPLE_LCD_CONTROLLER_SSD1306
  91. ESP_ERROR_CHECK(esp_lcd_new_panel_ssd1306(io_handle, &panel_config, &panel_handle));
  92. #elif CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
  93. ESP_ERROR_CHECK(esp_lcd_new_panel_sh1107(io_handle, &panel_config, &panel_handle));
  94. #endif
  95. ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle));
  96. ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle));
  97. ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true));
  98. #if CONFIG_EXAMPLE_LCD_CONTROLLER_SH1107
  99. ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, true));
  100. #endif
  101. ESP_LOGI(TAG, "Initialize LVGL");
  102. const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG();
  103. lvgl_port_init(&lvgl_cfg);
  104. const lvgl_port_display_cfg_t disp_cfg = {
  105. .io_handle = io_handle,
  106. .panel_handle = panel_handle,
  107. .buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES,
  108. .double_buffer = true,
  109. .hres = EXAMPLE_LCD_H_RES,
  110. .vres = EXAMPLE_LCD_V_RES,
  111. .monochrome = true,
  112. .rotation = {
  113. .swap_xy = false,
  114. .mirror_x = false,
  115. .mirror_y = false,
  116. }
  117. };
  118. lv_disp_t * disp = lvgl_port_add_disp(&disp_cfg);
  119. /* Register done callback for IO */
  120. const esp_lcd_panel_io_callbacks_t cbs = {
  121. .on_color_trans_done = notify_lvgl_flush_ready,
  122. };
  123. esp_lcd_panel_io_register_event_callbacks(io_handle, &cbs, disp);
  124. /* Rotation of the screen */
  125. lv_disp_set_rotation(disp, LV_DISP_ROT_NONE);
  126. ESP_LOGI(TAG, "Display LVGL Scroll Text");
  127. example_lvgl_demo_ui(disp);
  128. }