mirror of
https://github.com/78/xiaozhi-esp32.git
synced 2026-02-14 16:08:07 +00:00
Compare commits
13 Commits
v1.7.2
...
license_to
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e572296d7 | ||
|
|
ee4a2ab5fc | ||
|
|
f8c9126442 | ||
|
|
a118e8f786 | ||
|
|
85f3f1ba9f | ||
|
|
e2777cc16b | ||
|
|
5bb7c6deb8 | ||
|
|
895a3cfa72 | ||
|
|
c9dec29d73 | ||
|
|
968ed1fae3 | ||
|
|
f8cd0d30cd | ||
|
|
01215d77ed | ||
|
|
3df2f3970a |
@@ -4,7 +4,7 @@
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(PROJECT_VER "1.7.2")
|
||||
set(PROJECT_VER "1.7.4")
|
||||
|
||||
# Add this line to disable the specific warning
|
||||
add_compile_options(-Wno-missing-field-initializers)
|
||||
|
||||
@@ -360,9 +360,9 @@ config USE_WECHAT_MESSAGE_STYLE
|
||||
config USE_ESP_WAKE_WORD
|
||||
bool "Enable Wake Word Detection (without AFE)"
|
||||
default n
|
||||
depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5
|
||||
depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32
|
||||
help
|
||||
支持 ESP32 C3 与 ESP32 C5
|
||||
支持 ESP32 C3 与 ESP32 C5,增加ESP32支持(需要开启PSRAM)
|
||||
|
||||
config USE_AFE_WAKE_WORD
|
||||
bool "Enable Wake Word Detection (AFE)"
|
||||
|
||||
@@ -6,13 +6,14 @@
|
||||
|
||||
Es8311AudioCodec::Es8311AudioCodec(void* i2c_master_handle, i2c_port_t i2c_port, int input_sample_rate, int output_sample_rate,
|
||||
gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din,
|
||||
gpio_num_t pa_pin, uint8_t es8311_addr, bool use_mclk) {
|
||||
gpio_num_t pa_pin, uint8_t es8311_addr, bool use_mclk, bool pa_inverted) {
|
||||
duplex_ = true; // 是否双工
|
||||
input_reference_ = false; // 是否使用参考输入,实现回声消除
|
||||
input_channels_ = 1; // 输入通道数
|
||||
input_sample_rate_ = input_sample_rate;
|
||||
output_sample_rate_ = output_sample_rate;
|
||||
pa_pin_ = pa_pin;
|
||||
pa_inverted_ = pa_inverted;
|
||||
CreateDuplexChannels(mclk, bclk, ws, dout, din);
|
||||
|
||||
// Do initialize of related interface: data_if, ctrl_if and gpio_if
|
||||
@@ -44,6 +45,7 @@ Es8311AudioCodec::Es8311AudioCodec(void* i2c_master_handle, i2c_port_t i2c_port,
|
||||
es8311_cfg.use_mclk = use_mclk;
|
||||
es8311_cfg.hw_gain.pa_voltage = 5.0;
|
||||
es8311_cfg.hw_gain.codec_dac_voltage = 3.3;
|
||||
es8311_cfg.pa_reverted = pa_inverted_;
|
||||
codec_if_ = es8311_codec_new(&es8311_cfg);
|
||||
assert(codec_if_ != NULL);
|
||||
|
||||
@@ -171,12 +173,12 @@ void Es8311AudioCodec::EnableOutput(bool enable) {
|
||||
ESP_ERROR_CHECK(esp_codec_dev_open(output_dev_, &fs));
|
||||
ESP_ERROR_CHECK(esp_codec_dev_set_out_vol(output_dev_, output_volume_));
|
||||
if (pa_pin_ != GPIO_NUM_NC) {
|
||||
gpio_set_level(pa_pin_, 1);
|
||||
gpio_set_level(pa_pin_, !pa_inverted_ ? 1 : 0);
|
||||
}
|
||||
} else {
|
||||
ESP_ERROR_CHECK(esp_codec_dev_close(output_dev_));
|
||||
if (pa_pin_ != GPIO_NUM_NC) {
|
||||
gpio_set_level(pa_pin_, 0);
|
||||
gpio_set_level(pa_pin_, !pa_inverted_ ? 0 : 1);
|
||||
}
|
||||
}
|
||||
AudioCodec::EnableOutput(enable);
|
||||
|
||||
@@ -18,6 +18,7 @@ private:
|
||||
esp_codec_dev_handle_t output_dev_ = nullptr;
|
||||
esp_codec_dev_handle_t input_dev_ = nullptr;
|
||||
gpio_num_t pa_pin_ = GPIO_NUM_NC;
|
||||
bool pa_inverted_ = false;
|
||||
|
||||
void CreateDuplexChannels(gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din);
|
||||
|
||||
@@ -27,7 +28,7 @@ private:
|
||||
public:
|
||||
Es8311AudioCodec(void* i2c_master_handle, i2c_port_t i2c_port, int input_sample_rate, int output_sample_rate,
|
||||
gpio_num_t mclk, gpio_num_t bclk, gpio_num_t ws, gpio_num_t dout, gpio_num_t din,
|
||||
gpio_num_t pa_pin, uint8_t es8311_addr, bool use_mclk = true);
|
||||
gpio_num_t pa_pin, uint8_t es8311_addr, bool use_mclk = true, bool pa_inverted = false);
|
||||
virtual ~Es8311AudioCodec();
|
||||
|
||||
virtual void SetOutputVolume(int volume) override;
|
||||
|
||||
@@ -24,11 +24,15 @@ void AfeAudioProcessor::Initialize(AudioCodec* codec) {
|
||||
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
char* ns_model_name = esp_srmodel_filter(models, ESP_NSNET_PREFIX, NULL);
|
||||
|
||||
char* vad_model_name = esp_srmodel_filter(models, ESP_VADN_PREFIX, NULL);
|
||||
|
||||
afe_config_t* afe_config = afe_config_init(input_format.c_str(), NULL, AFE_TYPE_VC, AFE_MODE_HIGH_PERF);
|
||||
afe_config->aec_mode = AEC_MODE_VOIP_HIGH_PERF;
|
||||
afe_config->vad_mode = VAD_MODE_0;
|
||||
afe_config->vad_min_noise_ms = 100;
|
||||
if (vad_model_name != nullptr) {
|
||||
afe_config->vad_model_name = vad_model_name;
|
||||
}
|
||||
|
||||
if (ns_model_name != nullptr) {
|
||||
afe_config->ns_init = true;
|
||||
|
||||
@@ -35,6 +35,10 @@ void AfeWakeWord::Initialize(AudioCodec* codec) {
|
||||
int ref_num = codec_->input_reference() ? 1 : 0;
|
||||
|
||||
srmodel_list_t *models = esp_srmodel_init("model");
|
||||
if (models == nullptr || models->num == -1) {
|
||||
ESP_LOGE(TAG, "Failed to initialize wakenet model");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < models->num; i++) {
|
||||
ESP_LOGI(TAG, "Model %d: %s", i, models->model_name[i]);
|
||||
if (strstr(models->model_name[i], ESP_WN_PREFIX) != NULL) {
|
||||
|
||||
@@ -27,7 +27,10 @@ void EspWakeWord::Initialize(AudioCodec* codec) {
|
||||
codec_ = codec;
|
||||
|
||||
wakenet_model_ = esp_srmodel_init("model");
|
||||
|
||||
if (wakenet_model_ == nullptr || wakenet_model_->num == -1) {
|
||||
ESP_LOGE(TAG, "Failed to initialize wakenet model");
|
||||
return;
|
||||
}
|
||||
if(wakenet_model_->num > 1) {
|
||||
ESP_LOGW(TAG, "More than one model found, using the first one");
|
||||
} else if (wakenet_model_->num == 0) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=0",
|
||||
"CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=n",
|
||||
"CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y",
|
||||
"CONFIG_ESP_MAIN_TASK_STACK_SIZE=6144",
|
||||
"CONFIG_ESP_MAIN_TASK_STACK_SIZE=7168",
|
||||
"CONFIG_FREERTOS_HZ=1000",
|
||||
"CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=768",
|
||||
"CONFIG_LWIP_MAX_SOCKETS=10",
|
||||
@@ -28,7 +28,8 @@
|
||||
"CONFIG_MMAP_FILE_NAME_LENGTH=25",
|
||||
"CONFIG_ESP_CONSOLE_NONE=y",
|
||||
"CONFIG_USE_ESP_WAKE_WORD=y",
|
||||
"CONFIG_IOT_PROTOCOL_MCP=y"
|
||||
"CONFIG_IOT_PROTOCOL_MCP=y",
|
||||
"CONFIG_COMPILER_OPTIMIZATION_SIZE=y"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -85,17 +85,28 @@ private:
|
||||
int32_t event_id, void* event_data)
|
||||
{
|
||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
|
||||
EspHi* instance = static_cast<EspHi*>(arg);
|
||||
if (!instance->web_server_initialized_) {
|
||||
ESP_LOGI(TAG, "WiFi connected, init web control server");
|
||||
esp_err_t err = esp_hi_web_control_server_init();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to initialize web control server: %d", err);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Web control server initialized");
|
||||
instance->web_server_initialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
xTaskCreate(
|
||||
[](void* arg) {
|
||||
EspHi* instance = static_cast<EspHi*>(arg);
|
||||
|
||||
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
||||
|
||||
if (!instance->web_server_initialized_) {
|
||||
ESP_LOGI(TAG, "WiFi connected, init web control server");
|
||||
esp_err_t err = esp_hi_web_control_server_init();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to initialize web control server: %d", err);
|
||||
} else {
|
||||
ESP_LOGI(TAG, "Web control server initialized");
|
||||
instance->web_server_initialized_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
},
|
||||
"web_server_init",
|
||||
1024 * 10, arg, 5, nullptr);
|
||||
}
|
||||
}
|
||||
#endif //CONFIG_ESP_HI_WEB_CONTROL_ENABLED
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
"sdkconfig_append": [
|
||||
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
|
||||
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v1/8m.csv\"",
|
||||
"CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=n",
|
||||
"CONFIG_LWIP_IPV6=n",
|
||||
"CONFIG_USE_ESP_WAKE_WORD=y"
|
||||
"CONFIG_USE_ESP_WAKE_WORD=y",
|
||||
"CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,8 @@
|
||||
"sdkconfig_append": [
|
||||
"CONFIG_PM_ENABLE=y",
|
||||
"CONFIG_FREERTOS_USE_TICKLESS_IDLE=y",
|
||||
"CONFIG_USE_ESP_WAKE_WORD=y"
|
||||
"CONFIG_USE_ESP_WAKE_WORD=y",
|
||||
"CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -5,7 +5,7 @@ dependencies:
|
||||
espressif/esp_lcd_gc9a01: ==2.0.1
|
||||
espressif/esp_lcd_st77916: ^1.0.1
|
||||
espressif/esp_lcd_st7796:
|
||||
version: '1.3.2'
|
||||
version: 1.3.2
|
||||
rules:
|
||||
- if: target not in [esp32c3]
|
||||
espressif/esp_lcd_spd2010: ==1.0.2
|
||||
@@ -30,9 +30,19 @@ dependencies:
|
||||
espressif/esp_io_expander_tca95xx_16bit: ^2.0.0
|
||||
espressif2022/image_player: ^1.1.0
|
||||
espressif/adc_mic: ^0.2.0
|
||||
espressif/esp_mmap_assets: ">=1.2"
|
||||
espressif/esp_mmap_assets: '>=1.2'
|
||||
txp666/otto-emoji-gif-component: ~1.0.2
|
||||
|
||||
# SenseCAP Watcher Board
|
||||
wvirgil123/esp_jpeg_simd:
|
||||
version: 1.0.0
|
||||
rules:
|
||||
- if: target in [esp32s3]
|
||||
wvirgil123/sscma_client:
|
||||
version: 1.0.2
|
||||
rules:
|
||||
- if: target in [esp32s3]
|
||||
|
||||
tny-robotics/sh1106-esp-idf:
|
||||
version: ^1.0.0
|
||||
rules:
|
||||
@@ -45,7 +55,7 @@ dependencies:
|
||||
waveshare/esp_lcd_st7703:
|
||||
version: '*'
|
||||
rules:
|
||||
- if: target in [esp32p4]
|
||||
- if: target in [esp32p4]
|
||||
espressif/esp_lcd_ili9881c:
|
||||
version: ^1.0.1
|
||||
rules:
|
||||
@@ -55,19 +65,9 @@ dependencies:
|
||||
rules:
|
||||
- if: target in [esp32p4]
|
||||
lijunru-hub/servo_dog_ctrl:
|
||||
version: '^0.1.6'
|
||||
version: ^0.1.6
|
||||
rules:
|
||||
- if: target in [esp32c3]
|
||||
|
||||
sscma_client:
|
||||
git: https://github.com/Seeed-Studio/SenseCAP-Watcher-Firmware.git
|
||||
path: components/sscma_client
|
||||
|
||||
esp_jpeg_simd:
|
||||
git: https://github.com/Seeed-Studio/SenseCAP-Watcher-Firmware.git
|
||||
path: components/esp_jpeg_simd
|
||||
rules:
|
||||
- if: target not in [esp32p4]
|
||||
|
||||
## Required IDF version
|
||||
idf:
|
||||
|
||||
3
scripts/license_tools/.gitignore
vendored
Normal file
3
scripts/license_tools/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
config.json
|
||||
__pycache__/
|
||||
firmware_cache/
|
||||
193
scripts/license_tools/README.md
Normal file
193
scripts/license_tools/README.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# ESP32生产固件烧录工具
|
||||
|
||||
这是一个基于tkinter的ESP32生产用途的固件烧录工具,支持自动检测USB设备、读取MAC地址、获取授权信息、下载并烧录固件。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- **自动设备检测**: 自动监控USB设备插入(支持 `/dev/ttyACMx` 和 `/dev/ttyUSBx`)
|
||||
- **设备信息读取**: 使用esptool读取ESP32设备的MAC地址
|
||||
- **授权管理**: 通过API获取设备授权信息和固件下载链接
|
||||
- **固件烧录**: 自动下载并烧录固件到ESP32设备
|
||||
- **序列号烧录**: 将序列号烧录到BLOCK_USR_DATA
|
||||
- **授权密钥烧录**: 将授权密钥烧录到BLOCK_KEY0
|
||||
- **GUI界面**: 友好的图形用户界面,实时显示操作日志
|
||||
- **可配置网格布局**: 支持自定义端口显示布局(默认4x4)
|
||||
- **批量烧录**: 支持同时烧录多个设备
|
||||
- **固件缓存**: 自动缓存下载的固件,避免重复下载
|
||||
|
||||
## 配置文件
|
||||
|
||||
工具使用 `config.json` 文件保存配置,支持以下配置项:
|
||||
|
||||
```json
|
||||
{
|
||||
"license_url": "https://xiaozhi.me/api/developers/generate-license?token=YOUR_TOKEN&seed=00:00:00:00:00:00",
|
||||
"grid_rows": 4,
|
||||
"grid_cols": 4,
|
||||
"fullscreen_on_startup": true
|
||||
}
|
||||
```
|
||||
|
||||
### 网格布局配置
|
||||
|
||||
通过修改 `grid_rows` 和 `grid_cols` 可以调整端口显示布局:
|
||||
|
||||
- **4x4布局** (默认): `{"grid_rows": 4, "grid_cols": 4}` - 16个端口,4行4列
|
||||
- **8x1布局**: `{"grid_rows": 8, "grid_cols": 1}` - 8个端口,8行1列
|
||||
- **2x8布局**: `{"grid_rows": 2, "grid_cols": 8}` - 16个端口,2行8列
|
||||
- **1x16布局**: `{"grid_rows": 1, "grid_cols": 16}` - 16个端口,1行16列
|
||||
|
||||
配置文件会在程序首次运行时自动创建,也可以手动创建。修改配置后重启程序生效。
|
||||
|
||||
### 配置项说明
|
||||
|
||||
- **license_url**: 授权API链接,`seed`参数会被自动替换为设备MAC地址
|
||||
- **grid_rows**: 网格行数,控制端口显示的行数
|
||||
- **grid_cols**: 网格列数,控制端口显示的列数
|
||||
- **fullscreen_on_startup**: 启动时是否全屏,`true`为全屏,`false`为窗口模式
|
||||
|
||||
## 安装依赖
|
||||
|
||||
```bash
|
||||
pip3 install -r requirements.txt
|
||||
```
|
||||
|
||||
或者使用启动脚本自动安装:
|
||||
|
||||
```bash
|
||||
./run_tool.sh
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 启动工具
|
||||
|
||||
```bash
|
||||
# 方式1: 直接运行Python脚本
|
||||
python3 esp32_production_tool.py
|
||||
|
||||
# 方式2: 使用启动脚本(推荐)
|
||||
./run_tool.sh
|
||||
```
|
||||
|
||||
### 2. 配置授权链接
|
||||
|
||||
#### 首次运行配置
|
||||
|
||||
首次运行工具时,如果配置文件不存在或授权链接为空,程序会自动进入配置模式,弹出配置对话框:
|
||||
|
||||
- **授权链接**: 输入完整的授权API链接
|
||||
- **网格布局**: 选择端口显示的行列数(支持预设布局)
|
||||
- **全屏设置**: 选择启动时是否全屏显示
|
||||
|
||||
配置完成后会自动保存到 `config.json` 文件。
|
||||
|
||||
#### 手动配置
|
||||
|
||||
也可以直接编辑 `config.json` 文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"license_url": "https://xiaozhi.me/api/developers/generate-license?token=YOUR_TOKEN&seed=00:00:00:00:00:00",
|
||||
"grid_rows": 4,
|
||||
"grid_cols": 4,
|
||||
"fullscreen_on_startup": true
|
||||
}
|
||||
```
|
||||
|
||||
注意:`seed`参数会被自动替换为设备的MAC地址。授权链接只能通过配置文件设置,不能在界面上修改。
|
||||
|
||||
### 3. 连接ESP32设备
|
||||
|
||||
将ESP32设备通过USB连接到计算机。工具会自动检测到新设备并显示在日志中。
|
||||
|
||||
### 4. 读取设备信息
|
||||
|
||||
点击"读取设备信息"按钮,工具会:
|
||||
- 读取设备的MAC地址
|
||||
- 获取芯片信息
|
||||
- 检查是否已烧录序列号
|
||||
|
||||
### 5. 开始烧录
|
||||
|
||||
如果设备未烧录过,"开始烧录"按钮会变为可用状态。点击后工具会自动执行:
|
||||
|
||||
1. **获取授权信息**: 使用设备MAC地址替换seed参数,请求授权API
|
||||
2. **下载固件**: 从授权响应中获取固件下载链接并下载
|
||||
3. **烧录固件**: 使用esptool烧录固件到设备
|
||||
4. **烧录序列号**: 将序列号烧录到BLOCK_USR_DATA
|
||||
5. **烧录授权密钥**: 将授权密钥烧录到BLOCK_KEY0
|
||||
|
||||
## 授权API响应格式
|
||||
|
||||
工具期望的授权API响应格式:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "授权生成成功",
|
||||
"data": {
|
||||
"product_name": "小智AI语音盒子",
|
||||
"board_name": "kevin-box-2",
|
||||
"serial_number": "TCXZ_KEVINBOX2__38FBDDE984330E50",
|
||||
"license_key": "ioyI4KWmB41BXu0FgfqioLRncXinfttv",
|
||||
"license_algorithm": "hmac-sha256",
|
||||
"created_at": "2025-06-11T18:40:27.000Z",
|
||||
"firmware": {
|
||||
"version": "1.8.1",
|
||||
"image_url": "http://example.com/firmware.bin",
|
||||
"image_size": 3851712,
|
||||
"image_sha256": "ccf0c610643ec35819b360b081ed3bf16b53396c82558e8e050fa791947b03de"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **权限要求**: 工具需要访问串口设备,在Linux系统上可能需要将用户添加到`dialout`组:
|
||||
```bash
|
||||
sudo usermod -a -G dialout $USER
|
||||
```
|
||||
|
||||
2. **设备驱动**: 确保已安装ESP32设备的USB驱动程序
|
||||
|
||||
3. **网络连接**: 烧录过程需要网络连接来获取授权信息和下载固件
|
||||
|
||||
4. **安全性**: 序列号和授权密钥一旦烧录无法更改,请确保数据正确
|
||||
|
||||
5. **固件缓存**: 下载的固件会保存在 `firmware_cache/` 目录中,相同文件名的固件会被复用以提高效率
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 设备检测失败
|
||||
- 检查USB连接
|
||||
- 确认设备驱动已安装
|
||||
- 检查串口权限
|
||||
|
||||
### 授权请求失败
|
||||
- 检查网络连接
|
||||
- 验证授权链接是否正确
|
||||
- 确认API服务器可访问
|
||||
|
||||
### 烧录失败
|
||||
- 确保设备未被其他程序占用
|
||||
- 检查设备是否处于下载模式
|
||||
- 验证固件文件完整性
|
||||
|
||||
## 开发说明
|
||||
|
||||
工具基于以下技术栈开发:
|
||||
- **GUI框架**: tkinter
|
||||
- **ESP32工具**: esptool, espefuse
|
||||
- **网络请求**: requests
|
||||
- **串口检测**: pyserial
|
||||
|
||||
主要模块:
|
||||
- `ESP32ProductionTool`: 主应用类
|
||||
- `monitor_devices()`: USB设备监控
|
||||
- `read_device_info()`: 设备信息读取
|
||||
- `get_license_info()`: 授权信息获取
|
||||
- `download_firmware()`: 固件下载
|
||||
- `flash_firmware()`: 固件烧录
|
||||
- `flash_license_info()`: 授权信息烧录
|
||||
1449
scripts/license_tools/esp32_production_tool.py
Normal file
1449
scripts/license_tools/esp32_production_tool.py
Normal file
File diff suppressed because it is too large
Load Diff
3
scripts/license_tools/requirements.txt
Normal file
3
scripts/license_tools/requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
esptool>=4.0.0
|
||||
pyserial>=3.5
|
||||
requests>=2.25.0
|
||||
15
scripts/license_tools/run_tool.bat
Executable file
15
scripts/license_tools/run_tool.bat
Executable file
@@ -0,0 +1,15 @@
|
||||
|
||||
@echo off
|
||||
setlocal enabledelayedexpansion
|
||||
|
||||
:: <20><>ȡ<EFBFBD>ű<EFBFBD><C5B1><EFBFBD><EFBFBD><EFBFBD>Ŀ¼
|
||||
set "SCRIPT_DIR=%~dp0"
|
||||
set "SCRIPT_DIR=%SCRIPT_DIR:~0,-1%"
|
||||
|
||||
:: <20><><EFBFBD><EFBFBD>Python<6F><6E><EFBFBD><EFBFBD>
|
||||
echo <20><><EFBFBD><EFBFBD>Python<6F><6E><EFBFBD><EFBFBD>...
|
||||
pip install -r "%SCRIPT_DIR%\requirements.txt"
|
||||
|
||||
:: <20><><EFBFBD><EFBFBD>GUI<55><49><EFBFBD><EFBFBD>
|
||||
echo <20><><EFBFBD><EFBFBD>ESP32<33><32><EFBFBD><EFBFBD><EFBFBD>̼<EFBFBD><CCBC><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>...
|
||||
python "%SCRIPT_DIR%\esp32_production_tool.py"
|
||||
14
scripts/license_tools/run_tool.sh
Executable file
14
scripts/license_tools/run_tool.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ESP32生产固件烧录工具启动脚本
|
||||
|
||||
# 获取脚本所在目录
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# 检查是否安装了所需依赖
|
||||
echo "检查Python依赖..."
|
||||
pip3 install -r "$SCRIPT_DIR/requirements.txt"
|
||||
|
||||
# 启动GUI工具
|
||||
echo "启动ESP32生产固件烧录工具..."
|
||||
python3 "$SCRIPT_DIR/esp32_production_tool.py"
|
||||
@@ -82,6 +82,8 @@ def read_binary(dir_path):
|
||||
data = merged_bin_data[0x100000:]
|
||||
elif merged_bin_data[0x200000] == 0xE9:
|
||||
data = merged_bin_data[0x200000:]
|
||||
elif merged_bin_data[0xe0000] == 0xE9:
|
||||
data = merged_bin_data[0xe0000:]
|
||||
else:
|
||||
print(dir_path, "is not a valid image")
|
||||
return
|
||||
|
||||
7
sdkconfig.defaults.esp32
Normal file
7
sdkconfig.defaults.esp32
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions/v1/4m.csv"
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions/v1/4m.csv"
|
||||
CONFIG_SR_WN_WN9_NIHAOXIAOZHI_TTS=y
|
||||
CONFIG_ESP_TASK_WDT_TIMEOUT_S=20
|
||||
@@ -1,3 +1,13 @@
|
||||
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||
CONFIG_SR_WN_WN9S_NIHAOXIAOZHI=y
|
||||
|
||||
CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=3
|
||||
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=6
|
||||
CONFIG_ESP_WIFI_RX_BA_WIN=3
|
||||
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
|
||||
CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=n
|
||||
CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=0
|
||||
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=768
|
||||
CONFIG_LWIP_IPV6=n
|
||||
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=16
|
||||
Reference in New Issue
Block a user