lichuang_dev_board.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include "wifi_board.h"
  2. #include "audio_codecs/box_audio_codec.h"
  3. #include "display/lcd_display.h"
  4. #include "application.h"
  5. #include "button.h"
  6. #include "config.h"
  7. #include "i2c_device.h"
  8. #include "iot/thing_manager.h"
  9. #include <esp_log.h>
  10. #include <esp_lcd_panel_vendor.h>
  11. #include <driver/i2c_master.h>
  12. #include <driver/spi_common.h>
  13. #include <wifi_station.h>
  14. #define TAG "LichuangDevBoard"
  15. LV_FONT_DECLARE(font_puhui_20_4);
  16. LV_FONT_DECLARE(font_awesome_20_4);
  17. class Pca9557 : public I2cDevice {
  18. public:
  19. Pca9557(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) {
  20. WriteReg(0x01, 0x03);
  21. WriteReg(0x03, 0xf8);
  22. }
  23. void SetOutputState(uint8_t bit, uint8_t level) {
  24. uint8_t data = ReadReg(0x01);
  25. data = (data & ~(1 << bit)) | (level << bit);
  26. WriteReg(0x01, data);
  27. }
  28. };
  29. class LichuangDevBoard : public WifiBoard {
  30. private:
  31. i2c_master_bus_handle_t i2c_bus_;
  32. i2c_master_dev_handle_t pca9557_handle_;
  33. Button boot_button_;
  34. LcdDisplay* display_;
  35. Pca9557* pca9557_;
  36. void InitializeI2c() {
  37. // Initialize I2C peripheral
  38. i2c_master_bus_config_t i2c_bus_cfg = {
  39. .i2c_port = (i2c_port_t)1,
  40. .sda_io_num = AUDIO_CODEC_I2C_SDA_PIN,
  41. .scl_io_num = AUDIO_CODEC_I2C_SCL_PIN,
  42. .clk_source = I2C_CLK_SRC_DEFAULT,
  43. .glitch_ignore_cnt = 7,
  44. .intr_priority = 0,
  45. .trans_queue_depth = 0,
  46. .flags = {
  47. .enable_internal_pullup = 1,
  48. },
  49. };
  50. ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &i2c_bus_));
  51. // Initialize PCA9557
  52. pca9557_ = new Pca9557(i2c_bus_, 0x19);
  53. }
  54. void InitializeSpi() {
  55. spi_bus_config_t buscfg = {};
  56. buscfg.mosi_io_num = GPIO_NUM_40;
  57. buscfg.miso_io_num = GPIO_NUM_NC;
  58. buscfg.sclk_io_num = GPIO_NUM_41;
  59. buscfg.quadwp_io_num = GPIO_NUM_NC;
  60. buscfg.quadhd_io_num = GPIO_NUM_NC;
  61. buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);
  62. ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO));
  63. }
  64. void InitializeButtons() {
  65. boot_button_.OnClick([this]() {
  66. auto& app = Application::GetInstance();
  67. if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
  68. ResetWifiConfiguration();
  69. }
  70. });
  71. boot_button_.OnPressDown([this]() {
  72. Application::GetInstance().StartListening();
  73. });
  74. boot_button_.OnPressUp([this]() {
  75. Application::GetInstance().StopListening();
  76. });
  77. }
  78. void InitializeSt7789Display() {
  79. esp_lcd_panel_io_handle_t panel_io = nullptr;
  80. esp_lcd_panel_handle_t panel = nullptr;
  81. // 液晶屏控制IO初始化
  82. ESP_LOGD(TAG, "Install panel IO");
  83. esp_lcd_panel_io_spi_config_t io_config = {};
  84. io_config.cs_gpio_num = GPIO_NUM_NC;
  85. io_config.dc_gpio_num = GPIO_NUM_39;
  86. io_config.spi_mode = 2;
  87. io_config.pclk_hz = 80 * 1000 * 1000;
  88. io_config.trans_queue_depth = 10;
  89. io_config.lcd_cmd_bits = 8;
  90. io_config.lcd_param_bits = 8;
  91. ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io));
  92. // 初始化液晶屏驱动芯片ST7789
  93. ESP_LOGD(TAG, "Install LCD driver");
  94. esp_lcd_panel_dev_config_t panel_config = {};
  95. panel_config.reset_gpio_num = GPIO_NUM_NC;
  96. panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB;
  97. panel_config.bits_per_pixel = 16;
  98. ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel));
  99. esp_lcd_panel_reset(panel);
  100. pca9557_->SetOutputState(0, 0);
  101. esp_lcd_panel_init(panel);
  102. esp_lcd_panel_invert_color(panel, true);
  103. esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
  104. esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
  105. display_ = new SpiLcdDisplay(panel_io, panel,
  106. DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY,
  107. {
  108. .text_font = &font_puhui_20_4,
  109. .icon_font = &font_awesome_20_4,
  110. .emoji_font = font_emoji_64_init(),
  111. });
  112. }
  113. // 物联网初始化,添加对 AI 可见设备
  114. void InitializeIot() {
  115. auto& thing_manager = iot::ThingManager::GetInstance();
  116. thing_manager.AddThing(iot::CreateThing("Speaker"));
  117. thing_manager.AddThing(iot::CreateThing("Backlight"));
  118. }
  119. public:
  120. LichuangDevBoard() : boot_button_(BOOT_BUTTON_GPIO) {
  121. InitializeI2c();
  122. InitializeSpi();
  123. InitializeSt7789Display();
  124. InitializeButtons();
  125. InitializeIot();
  126. GetBacklight()->RestoreBrightness();
  127. }
  128. virtual AudioCodec* GetAudioCodec() override {
  129. static BoxAudioCodec audio_codec(
  130. i2c_bus_,
  131. AUDIO_INPUT_SAMPLE_RATE,
  132. AUDIO_OUTPUT_SAMPLE_RATE,
  133. AUDIO_I2S_GPIO_MCLK,
  134. AUDIO_I2S_GPIO_BCLK,
  135. AUDIO_I2S_GPIO_WS,
  136. AUDIO_I2S_GPIO_DOUT,
  137. AUDIO_I2S_GPIO_DIN,
  138. GPIO_NUM_NC,
  139. AUDIO_CODEC_ES8311_ADDR,
  140. AUDIO_CODEC_ES7210_ADDR,
  141. AUDIO_INPUT_REFERENCE);
  142. return &audio_codec;
  143. }
  144. virtual Display* GetDisplay() override {
  145. return display_;
  146. }
  147. virtual Backlight* GetBacklight() override {
  148. static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
  149. return &backlight;
  150. }
  151. };
  152. DECLARE_BOARD(LichuangDevBoard);