From e0e12450c5277889acf343eea3e2ddb3419395c6 Mon Sep 17 00:00:00 2001 From: jake12355 Date: Tue, 29 Jul 2025 17:28:40 +0800 Subject: [PATCH] =?UTF-8?q?jiuchuan-s3=E4=BF=AE=E6=94=B9=E6=8C=89=E9=94=AE?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E5=8F=96=E6=B6=88=E4=B8=8D=E5=AF=B9=E8=AF=9D?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=85=B3=E6=9C=BA=E4=BF=AE=E5=A4=8D=E5=B1=8F?= =?UTF-8?q?=E5=B9=95=E6=98=BE=E7=A4=BA=E4=B8=8D=E5=85=A8=20(#997)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * jiuchuan-s3修改按键定义取消不对话自动关机修复屏幕显示不全 * jiuchuan-s3修改按键定义取消不对话自动关机修复屏幕显示不全 --- main/boards/jiuchuan-s3/jiuchuan_dev_board.cc | 225 +++++++++++++----- 1 file changed, 162 insertions(+), 63 deletions(-) diff --git a/main/boards/jiuchuan-s3/jiuchuan_dev_board.cc b/main/boards/jiuchuan-s3/jiuchuan_dev_board.cc index b3ce93b9..94e9b890 100644 --- a/main/boards/jiuchuan-s3/jiuchuan_dev_board.cc +++ b/main/boards/jiuchuan-s3/jiuchuan_dev_board.cc @@ -22,12 +22,35 @@ #include #include -#define TAG "JiuchuanDevBoard" +#define BOARD_TAG "JiuchuanDevBoard" #define __USER_GPIO_PWRDOWN__ LV_FONT_DECLARE(font_puhui_20_4); LV_FONT_DECLARE(font_awesome_20_4); +// 自定义LCD显示器类,用于圆形屏幕适配 +class CustomLcdDisplay : public SpiLcdDisplay +{ +public: + CustomLcdDisplay(esp_lcd_panel_io_handle_t io_handle, + esp_lcd_panel_handle_t panel_handle, + int width, + int height, + int offset_x, + int offset_y, + bool mirror_x, + bool mirror_y, + bool swap_xy, + DisplayFonts fonts) + : SpiLcdDisplay(io_handle, panel_handle, width, height, offset_x, offset_y, mirror_x, mirror_y, swap_xy, fonts) + { + + DisplayLockGuard lock(this); + lv_obj_set_style_pad_left(status_bar_, LV_HOR_RES * 0.167, 0); + lv_obj_set_style_pad_right(status_bar_, LV_HOR_RES * 0.167, 0); + } +}; + class JiuchuanDevBoard : public WifiBoard { private: i2c_master_bus_handle_t codec_i2c_bus_; @@ -40,6 +63,17 @@ private: PowerManager* power_manager_; esp_lcd_panel_io_handle_t panel_io = NULL; esp_lcd_panel_handle_t panel = NULL; + + // 音量映射函数:将内部音量(0-80)映射为显示音量(0-100%) + int MapVolumeForDisplay(int internal_volume) { + // 确保输入在有效范围内 + if (internal_volume < 0) internal_volume = 0; + if (internal_volume > 80) internal_volume = 80; + + // 将0-80映射到0-100 + // 公式: 显示音量 = (内部音量 / 80) * 100 + return (internal_volume * 100) / 80; + } void InitializePowerManager() { power_manager_ = new PowerManager(PWR_ADC_GPIO); @@ -81,7 +115,7 @@ private: } #endif //一分钟进入浅睡眠,5分钟进入深睡眠关机 - power_save_timer_ = new PowerSaveTimer(-1, (60*10), (60*30)); + power_save_timer_ = new PowerSaveTimer(-1, (60*5), -1); // power_save_timer_ = new PowerSaveTimer(-1, 6, 10);//test power_save_timer_->OnEnterSleepMode([this]() { GetDisplay()->SetPowerSaveMode(true); @@ -128,6 +162,11 @@ private: } void InitializeButtons() { + static bool pwrbutton_unreleased = false; + + if (gpio_get_level(GPIO_NUM_3) == 1) { + pwrbutton_unreleased = true; + } // 配置GPIO ESP_LOGI(TAG, "Configuring power button GPIO"); GpioManager::Config(GPIO_NUM_3, GpioManager::GpioMode::INPUT_PULLDOWN); @@ -139,10 +178,19 @@ private: // 检查电源按钮初始状态 ESP_LOGI(TAG, "Power button initial state: %d", GpioManager::GetLevel(PWR_BUTTON_GPIO)); - + // 高电平有效长按关机逻辑 - pwr_button_.OnLongPress([this]() { - ESP_LOGI(TAG, "Power button long press detected (high-active)"); + pwr_button_.OnPressDown([this]() { + pwrbutton_unreleased = false; + }); + pwr_button_.OnLongPress([this]() + { + ESP_LOGI(TAG, "Power button long press detected (high-active)"); + + if (pwrbutton_unreleased){ + ESP_LOGI(TAG, "开机后电源键未松开,取消关机"); + return; + } // 高电平有效防抖确认 for (int i = 0; i < 5; i++) { @@ -157,75 +205,126 @@ private: } ESP_LOGI(TAG, "Confirmed power button pressed - initiating shutdown"); - power_manager_->SetPowerState(PowerState::SHUTDOWN); - }); + power_manager_->SetPowerState(PowerState::SHUTDOWN); }); - wifi_button.OnClick([this]() { - ESP_LOGI(TAG, "Wifi button clicked"); - power_save_timer_->WakeUp(); + //单击切换状态 + pwr_button_.OnClick([this]() + { + // 获取当前应用实例和状态 + auto &app = Application::GetInstance(); + auto current_state = app.GetDeviceState(); + + ESP_LOGI(TAG, "当前设备状态: %d", current_state); + if (current_state == kDeviceStateIdle) { + // 如果当前是待命状态,切换到聆听状态 + ESP_LOGI(TAG, "从待命状态切换到聆听状态"); + app.ToggleChatState(); // 切换到聆听状态 + } else if (current_state == kDeviceStateListening) { + // 如果当前是聆听状态,切换到待命状态 + ESP_LOGI(TAG, "从聆听状态切换到待命状态"); + app.ToggleChatState(); // 切换到待命状态 + } else if (current_state == kDeviceStateSpeaking) { + // 如果当前是说话状态,终止说话并切换到待命状态 + ESP_LOGI(TAG, "从说话状态切换到待命状态"); + app.ToggleChatState(); // 终止说话 + } else { + // 其他状态下只唤醒设备 + ESP_LOGI(TAG, "唤醒设备"); + power_save_timer_->WakeUp(); + } }); - ESP_LOGI(TAG, "Resetting WiFi configuration"); - GpioManager::SetLevel(PWR_EN_GPIO, 1); - ResetWifiConfiguration(); - - }); - - cmd_button.OnClick([this]() { - ESP_LOGI(TAG, "Command button clicked"); + // 电源键三击:重置WiFi + pwr_button_.OnMultipleClick([this]() + { + ESP_LOGI(TAG, "Power button triple click: 重置WiFi"); power_save_timer_->WakeUp(); - Application::GetInstance().ToggleChatState(); - }); + ResetWifiConfiguration(); }, 3); + + wifi_button.OnPressDown([this]() + { + ESP_LOGI(TAG, "Volume up button pressed"); + power_save_timer_->WakeUp(); + + auto codec = GetAudioCodec(); + int current_vol = codec->output_volume(); // 获取实际当前音量 + current_vol = (current_vol + 8 > 80) ? 80 : current_vol + 8; + + codec->SetOutputVolume(current_vol); + + ESP_LOGI(TAG, "Current volume: %d", current_vol); + int display_volume = MapVolumeForDisplay(current_vol); + GetDisplay()->ShowNotification(Lang::Strings::VOLUME + std::to_string(display_volume) + "%");}); + + cmd_button.OnPressDown([this]() + { + ESP_LOGI(TAG, "Volume down button pressed"); + power_save_timer_->WakeUp(); + + auto codec = GetAudioCodec(); + int current_vol = codec->output_volume(); // 获取实际当前音量 + current_vol = (current_vol - 8 < 0) ? 0 : current_vol - 8; + + codec->SetOutputVolume(current_vol); + + ESP_LOGI(TAG, "Current volume: %d", current_vol); + if (current_vol == 0) { + GetDisplay()->ShowNotification(Lang::Strings::MUTED); + } else { + int display_volume = MapVolumeForDisplay(current_vol); + GetDisplay()->ShowNotification(Lang::Strings::VOLUME + std::to_string(display_volume) + "%"); + }}); } - void InitializeGC9301isplay() { - // 液晶屏控制IO初始化 - ESP_LOGI(TAG, "test Install panel IO"); - spi_bus_config_t buscfg = {}; - buscfg.mosi_io_num = DISPLAY_SPI_MOSI_PIN; - buscfg.sclk_io_num = DISPLAY_SPI_SCK_PIN; - buscfg.miso_io_num = GPIO_NUM_NC; - buscfg.quadwp_io_num = GPIO_NUM_NC; - buscfg.quadhd_io_num = GPIO_NUM_NC; - buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t); - ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO)); - - // 初始化SPI总线 - esp_lcd_panel_io_spi_config_t io_config = {}; - io_config.cs_gpio_num = DISPLAY_SPI_CS_PIN; - io_config.dc_gpio_num = DISPLAY_DC_PIN; - io_config.spi_mode = 3; - io_config.pclk_hz = 80 * 1000 * 1000; - io_config.trans_queue_depth = 10; - io_config.lcd_cmd_bits = 8; - io_config.lcd_param_bits = 8; - esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io); + void InitializeGC9301isplay() + { + // 液晶屏控制IO初始化 + ESP_LOGI(TAG, "test Install panel IO"); + spi_bus_config_t buscfg = {}; + buscfg.mosi_io_num = DISPLAY_SPI_MOSI_PIN; + buscfg.sclk_io_num = DISPLAY_SPI_SCK_PIN; + buscfg.miso_io_num = GPIO_NUM_NC; + buscfg.quadwp_io_num = GPIO_NUM_NC; + buscfg.quadhd_io_num = GPIO_NUM_NC; + buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t); + ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO)); - // 初始化液晶屏驱动芯片9309 - ESP_LOGI(TAG, "Install LCD driver"); - esp_lcd_panel_dev_config_t panel_config = {}; - panel_config.reset_gpio_num = GPIO_NUM_NC; - panel_config.rgb_ele_order = LCD_RGB_ENDIAN_BGR; - panel_config.bits_per_pixel = 16; - esp_lcd_new_panel_gc9309na(panel_io, &panel_config, &panel); + // 初始化SPI总线 + esp_lcd_panel_io_spi_config_t io_config = {}; + io_config.cs_gpio_num = DISPLAY_SPI_CS_PIN; + io_config.dc_gpio_num = DISPLAY_DC_PIN; + io_config.spi_mode = 3; + io_config.pclk_hz = 80 * 1000 * 1000; + io_config.trans_queue_depth = 10; + io_config.lcd_cmd_bits = 8; + io_config.lcd_param_bits = 8; + esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io); - esp_lcd_panel_reset(panel); + // 初始化液晶屏驱动芯片9309 + ESP_LOGI(TAG, "Install LCD driver"); + esp_lcd_panel_dev_config_t panel_config = {}; + panel_config.reset_gpio_num = GPIO_NUM_NC; + panel_config.rgb_ele_order = LCD_RGB_ENDIAN_BGR; + panel_config.bits_per_pixel = 16; + esp_lcd_new_panel_gc9309na(panel_io, &panel_config, &panel); - esp_lcd_panel_init(panel); - esp_lcd_panel_invert_color(panel, false); - esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY); - esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); - display_ = new SpiLcdDisplay(panel_io, panel, - DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, - { - .text_font = &font_puhui_20_4, - .icon_font = &font_awesome_20_4, + esp_lcd_panel_reset(panel); + + esp_lcd_panel_init(panel); + esp_lcd_panel_invert_color(panel, false); + esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY); + esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y); + display_ = new CustomLcdDisplay(panel_io, panel, + DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY, + { + .text_font = &font_puhui_20_4, + .icon_font = &font_awesome_20_4, #if CONFIG_USE_WECHAT_MESSAGE_STYLE - .emoji_font = font_emoji_32_init(), + .emoji_font = font_emoji_32_init(), #else - .emoji_font = font_emoji_64_init(), + .emoji_font = font_emoji_64_init(), #endif - }); + }); } public: @@ -295,4 +394,4 @@ public: } }; -DECLARE_BOARD(JiuchuanDevBoard); \ No newline at end of file +DECLARE_BOARD(JiuchuanDevBoard);