esp32-p4-nano.cc 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "wifi_board.h"
  2. #include "codecs/es8311_audio_codec.h"
  3. #include "application.h"
  4. #include "display/lcd_display.h"
  5. // #include "display/no_display.h"
  6. #include "button.h"
  7. #include "config.h"
  8. #include "esp_lcd_panel_ops.h"
  9. #include "esp_lcd_mipi_dsi.h"
  10. #include "esp_ldo_regulator.h"
  11. #include "esp_lcd_mipi_dsi.h"
  12. #include "esp_lcd_jd9365_10_1.h"
  13. #include <wifi_station.h>
  14. #include <esp_log.h>
  15. #include <driver/i2c_master.h>
  16. #include <esp_lvgl_port.h>
  17. #include "esp_lcd_touch_gt911.h"
  18. #define TAG "WaveshareEsp32p4nano"
  19. LV_FONT_DECLARE(font_puhui_20_4);
  20. LV_FONT_DECLARE(font_awesome_20_4);
  21. class CustomBacklight : public Backlight {
  22. public:
  23. CustomBacklight(i2c_master_bus_handle_t i2c_handle)
  24. : Backlight(), i2c_handle_(i2c_handle) {}
  25. protected:
  26. i2c_master_bus_handle_t i2c_handle_;
  27. virtual void SetBrightnessImpl(uint8_t brightness) override {
  28. uint8_t i2c_address = 0x45; // 7-bit address
  29. #if CONFIG_LCD_TYPE_800_1280_10_1_INCH
  30. uint8_t reg = 0x86;
  31. #elif CONFIG_LCD_TYPE_800_1280_10_1_INCH_A
  32. uint8_t reg = 0x96;
  33. #endif
  34. uint8_t data[2] = {reg, brightness};
  35. i2c_master_dev_handle_t dev_handle;
  36. i2c_device_config_t dev_cfg = {
  37. .dev_addr_length = I2C_ADDR_BIT_LEN_7,
  38. .device_address = i2c_address,
  39. .scl_speed_hz = 100000,
  40. };
  41. esp_err_t err = i2c_master_bus_add_device(i2c_handle_, &dev_cfg, &dev_handle);
  42. if (err != ESP_OK) {
  43. ESP_LOGE(TAG, "Failed to add I2C device: %s", esp_err_to_name(err));
  44. return;
  45. }
  46. err = i2c_master_transmit(dev_handle, data, sizeof(data), -1);
  47. if (err != ESP_OK) {
  48. ESP_LOGE(TAG, "Failed to transmit brightness: %s", esp_err_to_name(err));
  49. } else {
  50. ESP_LOGI(TAG, "Backlight brightness set to %u", brightness);
  51. }
  52. // i2c_master_bus_rm_device(dev_handle);
  53. }
  54. };
  55. class WaveshareEsp32p4nano : public WifiBoard {
  56. private:
  57. i2c_master_bus_handle_t codec_i2c_bus_;
  58. Button boot_button_;
  59. LcdDisplay *display__;
  60. CustomBacklight *backlight_;
  61. void InitializeCodecI2c() {
  62. // Initialize I2C peripheral
  63. i2c_master_bus_config_t i2c_bus_cfg = {
  64. .i2c_port = I2C_NUM_1,
  65. .sda_io_num = AUDIO_CODEC_I2C_SDA_PIN,
  66. .scl_io_num = AUDIO_CODEC_I2C_SCL_PIN,
  67. .clk_source = I2C_CLK_SRC_DEFAULT,
  68. .glitch_ignore_cnt = 7,
  69. .intr_priority = 0,
  70. .trans_queue_depth = 0,
  71. .flags = {
  72. .enable_internal_pullup = 1,
  73. },
  74. };
  75. ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &codec_i2c_bus_));
  76. }
  77. static esp_err_t bsp_enable_dsi_phy_power(void) {
  78. #if MIPI_DSI_PHY_PWR_LDO_CHAN > 0
  79. // Turn on the power for MIPI DSI PHY, so it can go from "No Power" state to "Shutdown" state
  80. static esp_ldo_channel_handle_t phy_pwr_chan = NULL;
  81. esp_ldo_channel_config_t ldo_cfg = {
  82. .chan_id = MIPI_DSI_PHY_PWR_LDO_CHAN,
  83. .voltage_mv = MIPI_DSI_PHY_PWR_LDO_VOLTAGE_MV,
  84. };
  85. esp_ldo_acquire_channel(&ldo_cfg, &phy_pwr_chan);
  86. ESP_LOGI(TAG, "MIPI DSI PHY Powered on");
  87. #endif // BSP_MIPI_DSI_PHY_PWR_LDO_CHAN > 0
  88. return ESP_OK;
  89. }
  90. void InitializeLCD() {
  91. bsp_enable_dsi_phy_power();
  92. esp_lcd_panel_io_handle_t io = NULL;
  93. esp_lcd_panel_handle_t disp_panel = NULL;
  94. esp_lcd_dsi_bus_handle_t mipi_dsi_bus = NULL;
  95. esp_lcd_dsi_bus_config_t bus_config = JD9365_PANEL_BUS_DSI_2CH_CONFIG();
  96. esp_lcd_new_dsi_bus(&bus_config, &mipi_dsi_bus);
  97. ESP_LOGI(TAG, "Install MIPI DSI LCD control panel");
  98. // we use DBI interface to send LCD commands and parameters
  99. esp_lcd_dbi_io_config_t dbi_config = JD9365_PANEL_IO_DBI_CONFIG();
  100. esp_lcd_new_panel_io_dbi(mipi_dsi_bus, &dbi_config, &io);
  101. esp_lcd_dpi_panel_config_t dpi_config = {
  102. .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT,
  103. .dpi_clock_freq_mhz = 80,
  104. .pixel_format = LCD_COLOR_PIXEL_FORMAT_RGB565,
  105. .num_fbs = 1,
  106. .video_timing = {
  107. .h_size = 800,
  108. .v_size = 1280,
  109. .hsync_pulse_width = 20,
  110. .hsync_back_porch = 20,
  111. .hsync_front_porch = 40,
  112. .vsync_pulse_width = 10,
  113. .vsync_back_porch = 4,
  114. .vsync_front_porch = 30,
  115. },
  116. .flags = {
  117. .use_dma2d = true,
  118. },
  119. };
  120. jd9365_vendor_config_t vendor_config = {
  121. .mipi_config = {
  122. .dsi_bus = mipi_dsi_bus,
  123. .dpi_config = &dpi_config,
  124. .lane_num = 2,
  125. },
  126. .flags = {
  127. .use_mipi_interface = 1,
  128. },
  129. };
  130. const esp_lcd_panel_dev_config_t lcd_dev_config = {
  131. .reset_gpio_num = PIN_NUM_LCD_RST,
  132. .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB,
  133. .bits_per_pixel = 16,
  134. .vendor_config = &vendor_config,
  135. };
  136. esp_lcd_new_panel_jd9365(io, &lcd_dev_config, &disp_panel);
  137. esp_lcd_panel_reset(disp_panel);
  138. esp_lcd_panel_init(disp_panel);
  139. display__ = new MipiLcdDisplay(io, disp_panel, DISPLAY_WIDTH, DISPLAY_HEIGHT,
  140. DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY,
  141. {
  142. .text_font = &font_puhui_20_4,
  143. .icon_font = &font_awesome_20_4,
  144. .emoji_font = font_emoji_64_init(),
  145. });
  146. backlight_ = new CustomBacklight(codec_i2c_bus_);
  147. backlight_->RestoreBrightness();
  148. }
  149. void InitializeTouch()
  150. {
  151. esp_lcd_touch_handle_t tp;
  152. esp_lcd_touch_config_t tp_cfg = {
  153. .x_max = DISPLAY_WIDTH,
  154. .y_max = DISPLAY_HEIGHT,
  155. .rst_gpio_num = GPIO_NUM_NC,
  156. .int_gpio_num = GPIO_NUM_NC,
  157. .levels = {
  158. .reset = 0,
  159. .interrupt = 0,
  160. },
  161. .flags = {
  162. .swap_xy = 0,
  163. .mirror_x = 0,
  164. .mirror_y = 0,
  165. },
  166. };
  167. esp_lcd_panel_io_handle_t tp_io_handle = NULL;
  168. esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_GT911_CONFIG();
  169. tp_io_config.scl_speed_hz = 100 * 1000;
  170. ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(codec_i2c_bus_, &tp_io_config, &tp_io_handle));
  171. ESP_LOGI(TAG, "Initialize touch controller");
  172. ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_gt911(tp_io_handle, &tp_cfg, &tp));
  173. const lvgl_port_touch_cfg_t touch_cfg = {
  174. .disp = lv_display_get_default(),
  175. .handle = tp,
  176. };
  177. lvgl_port_add_touch(&touch_cfg);
  178. ESP_LOGI(TAG, "Touch panel initialized successfully");
  179. }
  180. void InitializeButtons() {
  181. boot_button_.OnClick([this]() {
  182. auto& app = Application::GetInstance();
  183. if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
  184. ResetWifiConfiguration();
  185. }
  186. app.ToggleChatState(); });
  187. }
  188. public:
  189. WaveshareEsp32p4nano() :
  190. boot_button_(BOOT_BUTTON_GPIO) {
  191. InitializeCodecI2c();
  192. InitializeLCD();
  193. InitializeTouch();
  194. InitializeButtons();
  195. }
  196. virtual AudioCodec *GetAudioCodec() override {
  197. static Es8311AudioCodec audio_codec(codec_i2c_bus_, I2C_NUM_1, AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
  198. AUDIO_I2S_GPIO_MCLK, AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN,
  199. AUDIO_CODEC_PA_PIN, AUDIO_CODEC_ES8311_ADDR);
  200. return &audio_codec;
  201. }
  202. virtual Display *GetDisplay() override {
  203. return display__;
  204. }
  205. virtual Backlight *GetBacklight() override {
  206. return backlight_;
  207. }
  208. };
  209. DECLARE_BOARD(WaveshareEsp32p4nano);