Skip to content

Commit 180ca89

Browse files
WDF-king78
andauthored
初次提交亘具科技s3 1.54小智代码 (#576)
* 初次提交亘具科技s3 1.54小智代码 * 第一次修改命名 * 修改名字,移除GennJu文件夹 * 提交修改了名字的genju文件夹 --------- Co-authored-by: Xiaoxia <terrence@tenclass.com>
1 parent b49ad17 commit 180ca89

File tree

6 files changed

+531
-0
lines changed

6 files changed

+531
-0
lines changed

main/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ elseif(CONFIG_BOARD_TYPE_DOIT_S3_AIBOX)
157157
set(BOARD_TYPE "doit-s3-aibox")
158158
elseif(CONFIG_BOARD_TYPE_MIXGO_NOVA)
159159
set(BOARD_TYPE "mixgo-nova")
160+
elseif(CONFIG_BOARD_TYPE_GENJUTECH_S3_1_54TFT)
161+
set(BOARD_TYPE "genjutech-s3-1.54tft")
160162
elseif(CONFIG_BOARD_TYPE_ESP32_CGC)
161163
set(BOARD_TYPE "esp32-cgc")
162164
elseif(CONFIG_BOARD_TYPE_ESP_S3_LCD_EV_Board)

main/Kconfig.projbuild

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ choice BOARD_TYPE
152152
bool "四博智联AI陪伴盒子"
153153
config BOARD_TYPE_MIXGO_NOVA
154154
bool "元控·青春"
155+
config BOARD_TYPE_GENJUTECH_S3_1_54TFT
156+
bool "亘具科技1.54(s3)"
155157
config BOARD_TYPE_ESP_S3_LCD_EV_Board
156158
bool "乐鑫ESP S3 LCD EV Board开发板"
157159
config BOARD_TYPE_ZHENGCHEN_1_54TFT_WIFI
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#ifndef _BOARD_CONFIG_H_
2+
#define _BOARD_CONFIG_H_
3+
4+
#include <driver/gpio.h>
5+
6+
#define AUDIO_INPUT_SAMPLE_RATE 16000
7+
#define AUDIO_OUTPUT_SAMPLE_RATE 16000
8+
9+
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_14
10+
#define AUDIO_I2S_GPIO_WS GPIO_NUM_11
11+
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_13
12+
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_12
13+
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_10
14+
15+
#define AUDIO_CODEC_PA_PIN GPIO_NUM_21
16+
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_9
17+
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_8
18+
#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR
19+
20+
#define BUILTIN_LED_GPIO GPIO_NUM_1
21+
#define BOOT_BUTTON_GPIO GPIO_NUM_0
22+
#define VOLUME_UP_BUTTON_GPIO GPIO_NUM_42
23+
#define VOLUME_DOWN_BUTTON_GPIO GPIO_NUM_41
24+
25+
#define DISPLAY_SDA GPIO_NUM_3
26+
#define DISPLAY_SCL GPIO_NUM_4
27+
#define DISPLAY_DC GPIO_NUM_5
28+
#define DISPLAY_CS GPIO_NUM_6
29+
#define DISPLAY_RES GPIO_NUM_7
30+
31+
#define DISPLAY_WIDTH 240
32+
#define DISPLAY_HEIGHT 240
33+
#define DISPLAY_SWAP_XY false
34+
#define DISPLAY_MIRROR_X false
35+
#define DISPLAY_MIRROR_Y false
36+
#define BACKLIGHT_INVERT false
37+
38+
#define DISPLAY_OFFSET_X 0
39+
#define DISPLAY_OFFSET_Y 0
40+
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_2
41+
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT false
42+
43+
#endif // _BOARD_CONFIG_H_
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"target": "esp32s3",
3+
"builds": [
4+
{
5+
"name": "GenJuTech-s3-1.54tft",
6+
"sdkconfig_append": []
7+
}
8+
]
9+
}
Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
#include "wifi_board.h"
2+
#include "audio_codecs/es8311_audio_codec.h"
3+
#include "display/lcd_display.h"
4+
#include "system_reset.h"
5+
#include "application.h"
6+
#include "button.h"
7+
#include "config.h"
8+
#include "iot/thing_manager.h"
9+
#include "led/single_led.h"
10+
11+
#include <esp_log.h>
12+
#include <esp_lcd_panel_vendor.h>
13+
#include <driver/i2c_master.h>
14+
#include <wifi_station.h>
15+
#include <esp_efuse_table.h>
16+
#include <freertos/FreeRTOS.h>
17+
#include <freertos/task.h>
18+
#include "power_save_timer.h"
19+
20+
#include "assets/lang_config.h"
21+
#include "power_manager.h"
22+
23+
#define TAG "GenJuTech_s3_1_54TFT"
24+
25+
LV_FONT_DECLARE(font_puhui_20_4);
26+
LV_FONT_DECLARE(font_awesome_20_4);
27+
28+
class SparkBotEs8311AudioCodec : public Es8311AudioCodec {
29+
private:
30+
31+
public:
32+
SparkBotEs8311AudioCodec(void* i2c_master_handle, i2c_port_t i2c_port, int input_sample_rate, int output_sample_rate,
33+
gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din,
34+
gpio_num_t pa_pin, uint8_t es8311_addr, bool use_mclk = true)
35+
: Es8311AudioCodec(i2c_master_handle, i2c_port, input_sample_rate, output_sample_rate,
36+
mclk, bclk, ws, dout, din,pa_pin, es8311_addr, use_mclk = true) {}
37+
38+
void EnableOutput(bool enable) override {
39+
if (enable == output_enabled_) {
40+
return;
41+
}
42+
if (enable) {
43+
Es8311AudioCodec::EnableOutput(enable);
44+
} else {
45+
// Nothing todo because the display io and PA io conflict
46+
}
47+
}
48+
};
49+
50+
class GenJuTech_s3_1_54TFT : public WifiBoard {
51+
private:
52+
// i2c_master_bus_handle_t display_i2c_bus_;
53+
Button boot_button_;
54+
Button volume_up_button_;
55+
Button volume_down_button_;
56+
LcdDisplay* display_;
57+
i2c_master_bus_handle_t codec_i2c_bus_;
58+
PowerSaveTimer* power_save_timer_;
59+
PowerManager* power_manager_;
60+
61+
void InitializePowerManager() {
62+
power_manager_ = new PowerManager(GPIO_NUM_16);
63+
power_manager_->OnChargingStatusChanged([this](bool is_charging) {
64+
if (is_charging) {
65+
power_save_timer_->SetEnabled(false);
66+
} else {
67+
power_save_timer_->SetEnabled(true);
68+
}
69+
});
70+
}
71+
72+
void InitializePowerSaveTimer() {
73+
power_save_timer_ = new PowerSaveTimer(160, 60);
74+
power_save_timer_->OnEnterSleepMode([this]() {
75+
ESP_LOGI(TAG, "Enabling sleep mode");
76+
auto display = GetDisplay();
77+
display->SetChatMessage("system", "");
78+
display->SetEmotion("sleepy");
79+
80+
auto codec = GetAudioCodec();
81+
codec->EnableInput(false);
82+
});
83+
power_save_timer_->OnExitSleepMode([this]() {
84+
auto codec = GetAudioCodec();
85+
codec->EnableInput(true);
86+
87+
auto display = GetDisplay();
88+
display->SetChatMessage("system", "");
89+
display->SetEmotion("neutral");
90+
});
91+
power_save_timer_->SetEnabled(true);
92+
}
93+
94+
void InitializeCodecI2c() {
95+
// Initialize I2C peripheral
96+
i2c_master_bus_config_t i2c_bus_cfg = {
97+
.i2c_port = I2C_NUM_0,
98+
.sda_io_num = AUDIO_CODEC_I2C_SDA_PIN,
99+
.scl_io_num = AUDIO_CODEC_I2C_SCL_PIN,
100+
.clk_source = I2C_CLK_SRC_DEFAULT,
101+
.glitch_ignore_cnt = 7,
102+
.intr_priority = 0,
103+
.trans_queue_depth = 0,
104+
.flags = {
105+
.enable_internal_pullup = 1,
106+
},
107+
};
108+
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &codec_i2c_bus_));
109+
}
110+
111+
void InitializeSpi() {
112+
spi_bus_config_t buscfg = {};
113+
buscfg.mosi_io_num = DISPLAY_SDA;
114+
buscfg.miso_io_num = GPIO_NUM_NC;
115+
buscfg.sclk_io_num = DISPLAY_SCL;
116+
buscfg.quadwp_io_num = GPIO_NUM_NC;
117+
buscfg.quadhd_io_num = GPIO_NUM_NC;
118+
buscfg.max_transfer_sz = DISPLAY_WIDTH * DISPLAY_HEIGHT * sizeof(uint16_t);
119+
ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO));
120+
}
121+
122+
void InitializeButtons() {
123+
boot_button_.OnClick([this]() {
124+
power_save_timer_->WakeUp();
125+
auto& app = Application::GetInstance();
126+
if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) {
127+
ResetWifiConfiguration();
128+
}
129+
app.ToggleChatState();
130+
});
131+
// boot_button_.OnPressDown([this]() {
132+
// Application::GetInstance().StartListening();
133+
// });
134+
// boot_button_.OnPressUp([this]() {
135+
// Application::GetInstance().StopListening();
136+
// });
137+
138+
volume_up_button_.OnClick([this]() {
139+
power_save_timer_->WakeUp();
140+
auto codec = GetAudioCodec();
141+
auto volume = codec->output_volume() + 10;
142+
if (volume > 100) {
143+
volume = 100;
144+
}
145+
codec->SetOutputVolume(volume);
146+
GetDisplay()->ShowNotification(Lang::Strings::VOLUME + std::to_string(volume));
147+
});
148+
149+
volume_up_button_.OnLongPress([this]() {
150+
power_save_timer_->WakeUp();
151+
GetAudioCodec()->SetOutputVolume(100);
152+
GetDisplay()->ShowNotification(Lang::Strings::MAX_VOLUME);
153+
});
154+
155+
volume_down_button_.OnClick([this]() {
156+
power_save_timer_->WakeUp();
157+
auto codec = GetAudioCodec();
158+
auto volume = codec->output_volume() - 10;
159+
if (volume < 0) {
160+
volume = 0;
161+
}
162+
codec->SetOutputVolume(volume);
163+
GetDisplay()->ShowNotification(Lang::Strings::VOLUME + std::to_string(volume));
164+
});
165+
166+
volume_down_button_.OnLongPress([this]() {
167+
power_save_timer_->WakeUp();
168+
GetAudioCodec()->SetOutputVolume(0);
169+
GetDisplay()->ShowNotification(Lang::Strings::MUTED);
170+
});
171+
}
172+
173+
void InitializeSt7789Display() {
174+
gpio_config_t config = {
175+
.pin_bit_mask = (1ULL << DISPLAY_RES),
176+
.mode = GPIO_MODE_OUTPUT,
177+
.pull_up_en = GPIO_PULLUP_DISABLE,
178+
.pull_down_en = GPIO_PULLDOWN_DISABLE,
179+
.intr_type = GPIO_INTR_DISABLE,
180+
};
181+
ESP_ERROR_CHECK(gpio_config(&config));
182+
gpio_set_level(DISPLAY_RES, 0);
183+
vTaskDelay(20);
184+
gpio_set_level(DISPLAY_RES, 1);
185+
186+
esp_lcd_panel_io_handle_t panel_io = nullptr;
187+
esp_lcd_panel_handle_t panel = nullptr;
188+
// 液晶屏控制IO初始化
189+
ESP_LOGD(TAG, "Install panel IO");
190+
esp_lcd_panel_io_spi_config_t io_config = {};
191+
io_config.cs_gpio_num = DISPLAY_CS;
192+
io_config.dc_gpio_num = DISPLAY_DC;
193+
io_config.spi_mode = 3;
194+
io_config.pclk_hz = 80 * 1000 * 1000;
195+
io_config.trans_queue_depth = 10;
196+
io_config.lcd_cmd_bits = 8;
197+
io_config.lcd_param_bits = 8;
198+
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io));
199+
200+
// 初始化液晶屏驱动芯片ST7789
201+
ESP_LOGD(TAG, "Install LCD driver");
202+
esp_lcd_panel_dev_config_t panel_config = {};
203+
panel_config.reset_gpio_num = DISPLAY_RES;
204+
panel_config.rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB;
205+
panel_config.bits_per_pixel = 16;
206+
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel));
207+
ESP_ERROR_CHECK(esp_lcd_panel_reset(panel));
208+
ESP_ERROR_CHECK(esp_lcd_panel_init(panel));
209+
ESP_ERROR_CHECK(esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY));
210+
ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y));
211+
ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel, true));
212+
213+
display_ = new SpiLcdDisplay(panel_io, panel,
214+
DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_OFFSET_X, DISPLAY_OFFSET_Y, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y, DISPLAY_SWAP_XY,
215+
{
216+
.text_font = &font_puhui_20_4,
217+
.icon_font = &font_awesome_20_4,
218+
.emoji_font = font_emoji_64_init(),
219+
});
220+
}
221+
222+
// 物联网初始化,添加对 AI 可见设备
223+
void InitializeIot() {
224+
auto& thing_manager = iot::ThingManager::GetInstance();
225+
thing_manager.AddThing(iot::CreateThing("Speaker"));
226+
thing_manager.AddThing(iot::CreateThing("Screen"));
227+
// thing_manager.AddThing(iot::CreateThing("Lamp"));
228+
thing_manager.AddThing(iot::CreateThing("Battery"));
229+
}
230+
231+
public:
232+
GenJuTech_s3_1_54TFT() :
233+
boot_button_(BOOT_BUTTON_GPIO),
234+
volume_up_button_(VOLUME_UP_BUTTON_GPIO),
235+
volume_down_button_(VOLUME_DOWN_BUTTON_GPIO) {
236+
ESP_LOGI(TAG, "Initializing GenJuTech S3 1.54 Board");
237+
InitializePowerManager();
238+
InitializePowerSaveTimer();
239+
InitializeCodecI2c();
240+
InitializeSpi();
241+
InitializeButtons();
242+
InitializeSt7789Display();
243+
InitializeIot();
244+
GetBacklight()->RestoreBrightness();
245+
}
246+
247+
248+
virtual Led* GetLed() override {
249+
static SingleLed led(BUILTIN_LED_GPIO);
250+
return &led;
251+
}
252+
253+
virtual AudioCodec* GetAudioCodec() override {
254+
static SparkBotEs8311AudioCodec audio_codec(codec_i2c_bus_, I2C_NUM_0, AUDIO_INPUT_SAMPLE_RATE, AUDIO_OUTPUT_SAMPLE_RATE,
255+
AUDIO_I2S_GPIO_MCLK, AUDIO_I2S_GPIO_BCLK, AUDIO_I2S_GPIO_WS, AUDIO_I2S_GPIO_DOUT, AUDIO_I2S_GPIO_DIN,
256+
AUDIO_CODEC_PA_PIN, AUDIO_CODEC_ES8311_ADDR);
257+
return &audio_codec;
258+
}
259+
260+
virtual Display *GetDisplay() override {
261+
return display_;
262+
}
263+
264+
virtual Backlight* GetBacklight() override {
265+
static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
266+
return &backlight;
267+
}
268+
269+
virtual bool GetBatteryLevel(int& level, bool& charging, bool& discharging) override {
270+
static bool last_discharging = false;
271+
charging = power_manager_->IsCharging();
272+
discharging = power_manager_->IsDischarging();
273+
if (discharging != last_discharging) {
274+
power_save_timer_->SetEnabled(discharging);
275+
last_discharging = discharging;
276+
}
277+
level = power_manager_->GetBatteryLevel();
278+
return true;
279+
}
280+
281+
virtual void SetPowerSaveMode(bool enabled) override {
282+
if (!enabled) {
283+
power_save_timer_->WakeUp();
284+
}
285+
WifiBoard::SetPowerSaveMode(enabled);
286+
}
287+
};
288+
289+
DECLARE_BOARD(GenJuTech_s3_1_54TFT);

0 commit comments

Comments
 (0)