mirror of
https://github.com/78/xiaozhi-esp32.git
synced 2026-06-30 01:34:42 +08:00
Add M5Stack StickS3 board support. (#2060)
Co-authored-by: luoweiyuan <luoweiyuan@m5stack.com>
This commit is contained in:
@@ -206,6 +206,11 @@ elseif(CONFIG_BOARD_TYPE_M5STACK_CORE_S3)
|
||||
set(BUILTIN_TEXT_FONT font_puhui_basic_20_4)
|
||||
set(BUILTIN_ICON_FONT font_awesome_20_4)
|
||||
set(DEFAULT_EMOJI_COLLECTION twemoji_64)
|
||||
elseif(CONFIG_BOARD_TYPE_M5STACK_STICK_S3)
|
||||
set(BOARD_TYPE "m5stack-stick-s3")
|
||||
set(BUILTIN_TEXT_FONT font_puhui_basic_16_4)
|
||||
set(BUILTIN_ICON_FONT font_awesome_16_4)
|
||||
set(DEFAULT_EMOJI_COLLECTION twemoji_32)
|
||||
elseif(CONFIG_BOARD_TYPE_M5STACK_CORE_TAB5)
|
||||
set(BOARD_TYPE "m5stack-tab5")
|
||||
set(BUILTIN_TEXT_FONT font_puhui_basic_30_4)
|
||||
@@ -1006,6 +1011,11 @@ if(CONFIG_IDF_TARGET_ESP32S3)
|
||||
endif()
|
||||
|
||||
set(MAIN_PRIV_REQUIRES_EXTRA "")
|
||||
if(BOARD_TYPE STREQUAL "m5stack-stick-s3")
|
||||
list(APPEND MAIN_PRIV_REQUIRES_EXTRA
|
||||
m5stack__m5pm1
|
||||
)
|
||||
endif()
|
||||
if(CONFIG_BOARD_TYPE_ESP_VOCAT)
|
||||
list(APPEND MAIN_PRIV_REQUIRES_EXTRA
|
||||
espressif__touch_slider_sensor
|
||||
|
||||
@@ -251,6 +251,9 @@ choice BOARD_TYPE
|
||||
config BOARD_TYPE_M5STACK_CORE_S3
|
||||
bool "M5Stack CoreS3"
|
||||
depends on IDF_TARGET_ESP32S3
|
||||
config BOARD_TYPE_M5STACK_STICK_S3
|
||||
bool "M5Stack StickS3"
|
||||
depends on IDF_TARGET_ESP32S3
|
||||
config BOARD_TYPE_M5STACK_CORE_TAB5
|
||||
bool "M5Stack Tab5"
|
||||
depends on IDF_TARGET_ESP32P4
|
||||
|
||||
133
main/boards/m5stack-stick-s3/README.md
Normal file
133
main/boards/m5stack-stick-s3/README.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# M5Stack Sticks3
|
||||
|
||||
* MCU: ESP32-S3
|
||||
* PSRAM: 8MB
|
||||
* Flash: 8MB
|
||||
* Display: 1.14Inch, 135x240 LCD.
|
||||
|
||||
-----------
|
||||
## Hardware
|
||||
|
||||
* SYS_I2C/I2C0
|
||||
* SCL -- G48
|
||||
* SDA -- G47
|
||||
* PMIC: M5PM1
|
||||
* Interface: I2C0@0x6E
|
||||
* LCD
|
||||
* Power: M5PM1_G2 高电平使能
|
||||
* Resolution: 135x240
|
||||
* Driver: CO5300
|
||||
* Interface: SPI
|
||||
* MOSI -- G39
|
||||
* SCLK -- G40
|
||||
* CS -- G41
|
||||
* RS -- G45
|
||||
* BL -- G38
|
||||
* Audio
|
||||
* Power: M5PM1_G2 高电平使能
|
||||
* ES8311@0x18
|
||||
* Control Interface: SYS_I2C
|
||||
* Data Interface: I2S0
|
||||
* MCLK -- G18
|
||||
* BCLK -- G17
|
||||
* ASDOUT -- G16
|
||||
* LRCK -- G15
|
||||
* DSDIN -- G14
|
||||
* PA -- PM1_G3
|
||||
* Key
|
||||
* KEY1 -- G11
|
||||
* IMU
|
||||
* BMI270@0x68
|
||||
* Interface: SYS_I2C
|
||||
* IR
|
||||
* TX -- G46
|
||||
* RX -- G42
|
||||
|
||||
## 快速构建
|
||||
|
||||
推荐使用 release 脚本生成完整固件包:
|
||||
|
||||
```bash
|
||||
python scripts/release.py m5stack-stick-s3 --name m5stack-stick-s3
|
||||
```
|
||||
|
||||
生成的固件压缩包位于:
|
||||
|
||||
```text
|
||||
releases/v2.2.6_m5stack-stick-s3.zip
|
||||
```
|
||||
|
||||
`config.json` 中的关键构建配置:
|
||||
|
||||
```text
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions/v2/8m.csv"
|
||||
CONFIG_SPIRAM=y
|
||||
```
|
||||
|
||||
## 手动配置
|
||||
|
||||
配置编译目标:
|
||||
|
||||
```bash
|
||||
idf.py set-target esp32s3
|
||||
```
|
||||
|
||||
打开配置菜单:
|
||||
|
||||
```bash
|
||||
idf.py menuconfig
|
||||
```
|
||||
|
||||
选择板卡:
|
||||
|
||||
```text
|
||||
Xiaozhi Assistant -> Board Type -> M5Stack StickS3
|
||||
```
|
||||
|
||||
配置 Flash 大小:
|
||||
|
||||
```text
|
||||
Serial flasher config -> Flash size -> 8 MB
|
||||
```
|
||||
|
||||
配置分区表:
|
||||
|
||||
```text
|
||||
Partition Table -> Custom partition CSV file -> partitions/v2/8m.csv
|
||||
```
|
||||
|
||||
配置 PSRAM:
|
||||
|
||||
```text
|
||||
Component config -> ESP PSRAM -> Support for external, SPI-connected RAM -> Select
|
||||
```
|
||||
|
||||
编译:
|
||||
|
||||
```bash
|
||||
idf.py build
|
||||
```
|
||||
|
||||
## 合并固件
|
||||
|
||||
手动构建后,可使用以下命令合并烧录固件:
|
||||
|
||||
```bash
|
||||
esptool.py --chip esp32s3 merge_bin \
|
||||
--flash_mode dio \
|
||||
--flash_freq 80m \
|
||||
--flash_size 8MB \
|
||||
0x0 build/bootloader/bootloader.bin \
|
||||
0x8000 build/partition_table/partition-table.bin \
|
||||
0xd000 build/ota_data_initial.bin \
|
||||
0x20000 build/xiaozhi.bin \
|
||||
0x600000 build/generated_assets.bin \
|
||||
-o M5Stack-StickS3-XiaoZhi-v2.2.6_0x00.bin
|
||||
```
|
||||
|
||||
烧录合并后的固件:
|
||||
|
||||
```bash
|
||||
esptool.py -b 1500000 write_flash -z 0 M5Stack-StickS3-XiaoZhi-v2.2.6_0x00.bin
|
||||
```
|
||||
52
main/boards/m5stack-stick-s3/config.h
Normal file
52
main/boards/m5stack-stick-s3/config.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef _BOARD_CONFIG_H_
|
||||
#define _BOARD_CONFIG_H_
|
||||
|
||||
#include <driver/gpio.h>
|
||||
|
||||
#define AUDIO_INPUT_SAMPLE_RATE 24000
|
||||
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
|
||||
|
||||
// I2S0 pins
|
||||
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_18
|
||||
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_17
|
||||
#define AUDIO_I2S_GPIO_WS GPIO_NUM_15
|
||||
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_14
|
||||
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_16
|
||||
|
||||
// Audio Codec I2C (SYS_I2C/I2C0)
|
||||
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_47
|
||||
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_48
|
||||
#define AUDIO_CODEC_ES8311_ADDR ES8311_CODEC_DEFAULT_ADDR
|
||||
|
||||
// PA control via PM1_G3 (not a GPIO pin)
|
||||
#define AUDIO_CODEC_GPIO_PA GPIO_NUM_NC
|
||||
|
||||
// Button
|
||||
#define BOOT_BUTTON_GPIO GPIO_NUM_11
|
||||
#define USER_BUTTON_GPIO GPIO_NUM_12
|
||||
|
||||
// Display pins
|
||||
#define DISPLAY_MOSI_PIN GPIO_NUM_39
|
||||
#define DISPLAY_CLK_PIN GPIO_NUM_40
|
||||
#define DISPLAY_CS_PIN GPIO_NUM_41
|
||||
#define DISPLAY_DC_PIN GPIO_NUM_45
|
||||
#define DISPLAY_RST_PIN GPIO_NUM_21
|
||||
#define DISPLAY_BACKLIGHT_PIN GPIO_NUM_38
|
||||
|
||||
// Display configuration
|
||||
#define DISPLAY_WIDTH 135
|
||||
#define DISPLAY_HEIGHT 240
|
||||
#define DISPLAY_MIRROR_X false
|
||||
#define DISPLAY_MIRROR_Y false
|
||||
#define DISPLAY_SWAP_XY false
|
||||
#define DISPLAY_INVERT_COLOR true
|
||||
#define DISPLAY_RGB_ORDER LCD_RGB_ELEMENT_ORDER_RGB
|
||||
#define DISPLAY_OFFSET_X 52
|
||||
#define DISPLAY_OFFSET_Y 40
|
||||
#define DISPLAY_BACKLIGHT_OUTPUT_INVERT false
|
||||
#define DISPLAY_SPI_MODE 0
|
||||
|
||||
// PMIC PM1 address
|
||||
#define PM1_I2C_ADDR 0x6E
|
||||
|
||||
#endif // _BOARD_CONFIG_H_
|
||||
14
main/boards/m5stack-stick-s3/config.json
Normal file
14
main/boards/m5stack-stick-s3/config.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"target": "esp32s3",
|
||||
"builds": [
|
||||
{
|
||||
"name": "m5stack-stick-s3",
|
||||
"sdkconfig_append": [
|
||||
"CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y",
|
||||
"CONFIG_PARTITION_TABLE_CUSTOM_FILENAME=\"partitions/v2/8m.csv\"",
|
||||
"CONFIG_USE_ESP_WAKE_WORD=y",
|
||||
"CONFIG_SPIRAM=y"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
256
main/boards/m5stack-stick-s3/m5stack_stick_s3.cc
Normal file
256
main/boards/m5stack-stick-s3/m5stack_stick_s3.cc
Normal file
@@ -0,0 +1,256 @@
|
||||
#include "wifi_board.h"
|
||||
#include "codecs/es8311_audio_codec.h"
|
||||
#include "display/lcd_display.h"
|
||||
#include "application.h"
|
||||
#include "button.h"
|
||||
#include "config.h"
|
||||
#include "i2c_device.h"
|
||||
#include "assets/lang_config.h"
|
||||
#include "backlight.h"
|
||||
#include "settings.h"
|
||||
#include <driver/i2c_master.h>
|
||||
#include <esp_lcd_panel_vendor.h>
|
||||
#include <esp_lcd_panel_io.h>
|
||||
#include <esp_lcd_panel_ops.h>
|
||||
#include <driver/spi_common.h>
|
||||
#include <esp_log.h>
|
||||
#include <wifi_manager.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include "M5PM1.h"
|
||||
|
||||
#define TAG "M5StackStickS3"
|
||||
|
||||
// reduce the output volume to 60%
|
||||
class Sticks3AudioCodec : public Es8311AudioCodec {
|
||||
public:
|
||||
Sticks3AudioCodec(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, bool pa_inverted = false)
|
||||
: Es8311AudioCodec(i2c_master_handle, i2c_port, input_sample_rate, output_sample_rate,
|
||||
mclk, bclk, ws, dout, din, pa_pin, es8311_addr, use_mclk, pa_inverted) {}
|
||||
|
||||
virtual void SetOutputVolume(int volume) override {
|
||||
if (volume > 100) {
|
||||
volume = 100;
|
||||
}
|
||||
if (volume < 0) {
|
||||
volume = 0;
|
||||
}
|
||||
|
||||
// Scale volume to 60% (x 0.6)
|
||||
int scaled_volume = (int)(volume * 0.6f + 0.5f); // Round to nearest integer
|
||||
ESP_LOGI(TAG, "Requested output volume: %d%%, scaled to hardware: %d%%", volume, scaled_volume);
|
||||
|
||||
// Call parent's SetOutputVolume with scaled value for hardware
|
||||
Es8311AudioCodec::SetOutputVolume(scaled_volume);
|
||||
|
||||
// Update output_volume_ to original value for display
|
||||
output_volume_ = volume;
|
||||
|
||||
// Save original value to settings
|
||||
Settings settings("audio", true);
|
||||
settings.SetInt("output_volume", volume);
|
||||
}
|
||||
};
|
||||
|
||||
class M5StackStickS3Board : public WifiBoard {
|
||||
private:
|
||||
Button boot_button_;
|
||||
Button user_button_;
|
||||
LcdDisplay* display_;
|
||||
i2c_master_bus_handle_t i2c_bus_;
|
||||
M5PM1* pmic_;
|
||||
|
||||
void InitializeI2c() {
|
||||
// Initialize I2C peripheral (SYS_I2C/I2C0)
|
||||
i2c_master_bus_config_t i2c_bus_cfg = {
|
||||
.i2c_port = I2C_NUM_0,
|
||||
.sda_io_num = AUDIO_CODEC_I2C_SDA_PIN,
|
||||
.scl_io_num = AUDIO_CODEC_I2C_SCL_PIN,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.glitch_ignore_cnt = 7,
|
||||
.intr_priority = 0,
|
||||
.trans_queue_depth = 0,
|
||||
.flags = {
|
||||
.enable_internal_pullup = 1,
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_new_master_bus(&i2c_bus_cfg, &i2c_bus_));
|
||||
}
|
||||
|
||||
void InitializePm1() {
|
||||
// Initialize PM1 device
|
||||
ESP_LOGI(TAG, "M5Stack PMIC Init.");
|
||||
pmic_ = new M5PM1();
|
||||
pmic_->begin(i2c_bus_, M5PM1_DEFAULT_ADDR);
|
||||
pmic_->setChargeEnable(true);
|
||||
pmic_->setBoostEnable(false);
|
||||
// Configure PM1 G0 as input for charging status detection
|
||||
// PM1 G0: low = charging, high = not charging
|
||||
pmic_->pinMode(0, INPUT);
|
||||
// Configure PM1 G2 (LCD/Audio Power) as output high
|
||||
pmic_->pinMode(2, OUTPUT);
|
||||
pmic_->gpioSetDrive(M5PM1_GPIO_NUM_2, M5PM1_GPIO_DRIVE_PUSHPULL);
|
||||
pmic_->digitalWrite(2, HIGH);
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
// Configure PM1 G3 (PA) as output high
|
||||
pmic_->pinMode(3, OUTPUT);
|
||||
pmic_->gpioSetDrive(M5PM1_GPIO_NUM_3, M5PM1_GPIO_DRIVE_PUSHPULL);
|
||||
pmic_->digitalWrite(3, HIGH);
|
||||
// Enable double click to shutdown
|
||||
pmic_->setDoubleOffDisable(false);
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
}
|
||||
|
||||
void InitializeSpi() {
|
||||
ESP_LOGI(TAG, "Initialize SPI bus");
|
||||
spi_bus_config_t buscfg = {};
|
||||
buscfg.mosi_io_num = DISPLAY_MOSI_PIN;
|
||||
buscfg.miso_io_num = GPIO_NUM_NC;
|
||||
buscfg.sclk_io_num = DISPLAY_CLK_PIN;
|
||||
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));
|
||||
}
|
||||
|
||||
void InitializeLcdDisplay() {
|
||||
ESP_LOGI(TAG, "Initialize LCD Display");
|
||||
esp_lcd_panel_io_handle_t panel_io = nullptr;
|
||||
esp_lcd_panel_handle_t panel = nullptr;
|
||||
|
||||
// Install panel IO
|
||||
esp_lcd_panel_io_spi_config_t io_config = {};
|
||||
io_config.cs_gpio_num = DISPLAY_CS_PIN;
|
||||
io_config.dc_gpio_num = DISPLAY_DC_PIN;
|
||||
io_config.spi_mode = DISPLAY_SPI_MODE;
|
||||
io_config.pclk_hz = 40 * 1000 * 1000;
|
||||
io_config.trans_queue_depth = 10;
|
||||
io_config.lcd_cmd_bits = 8;
|
||||
io_config.lcd_param_bits = 8;
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi(SPI3_HOST, &io_config, &panel_io));
|
||||
|
||||
// Install LCD driver
|
||||
esp_lcd_panel_dev_config_t panel_config = {};
|
||||
panel_config.reset_gpio_num = DISPLAY_RST_PIN;
|
||||
panel_config.rgb_ele_order = DISPLAY_RGB_ORDER;
|
||||
panel_config.bits_per_pixel = 16;
|
||||
ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(panel_io, &panel_config, &panel));
|
||||
|
||||
esp_lcd_panel_reset(panel);
|
||||
esp_lcd_panel_init(panel);
|
||||
esp_lcd_panel_set_gap(panel, 0, 0);
|
||||
esp_lcd_panel_invert_color(panel, DISPLAY_INVERT_COLOR);
|
||||
esp_lcd_panel_swap_xy(panel, DISPLAY_SWAP_XY);
|
||||
esp_lcd_panel_mirror(panel, DISPLAY_MIRROR_X, DISPLAY_MIRROR_Y);
|
||||
esp_lcd_panel_disp_on_off(panel, true);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void InitializeButtons() {
|
||||
boot_button_.OnClick([this]() {
|
||||
auto& app = Application::GetInstance();
|
||||
if (app.GetDeviceState() == kDeviceStateStarting && !WifiManager::GetInstance().IsConnected()) {
|
||||
EnterWifiConfigMode();
|
||||
}
|
||||
app.ToggleChatState();
|
||||
});
|
||||
|
||||
// User button on GPIO12: single click sets stored volume to 70%
|
||||
user_button_.OnClick([this]() {
|
||||
AudioCodec* codec = GetAudioCodec();
|
||||
if (codec) {
|
||||
// Use base AudioCodec::SetOutputVolume to update stored value
|
||||
// without touching hardware that may not be initialized yet.
|
||||
codec->SetOutputVolume(60);
|
||||
codec->AudioCodec::SetOutputVolume(60);
|
||||
ESP_LOGI(TAG, "User button pressed: stored volume set to 80%%");
|
||||
} else {
|
||||
ESP_LOGW(TAG, "User button pressed but codec is not available yet");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public:
|
||||
M5StackStickS3Board() :
|
||||
boot_button_(BOOT_BUTTON_GPIO),
|
||||
user_button_(USER_BUTTON_GPIO),
|
||||
display_(nullptr),
|
||||
i2c_bus_(nullptr),
|
||||
pmic_(nullptr) {
|
||||
InitializeI2c();
|
||||
InitializePm1(); // Initialize PM1 after I2C, before LCD/Audio
|
||||
InitializeSpi();
|
||||
InitializeLcdDisplay();
|
||||
InitializeButtons();
|
||||
GetBacklight()->SetBrightness(60);
|
||||
}
|
||||
|
||||
virtual AudioCodec* GetAudioCodec() override {
|
||||
static Sticks3AudioCodec audio_codec(
|
||||
i2c_bus_,
|
||||
I2C_NUM_0,
|
||||
AUDIO_INPUT_SAMPLE_RATE,
|
||||
AUDIO_OUTPUT_SAMPLE_RATE,
|
||||
AUDIO_I2S_GPIO_MCLK,
|
||||
AUDIO_I2S_GPIO_BCLK,
|
||||
AUDIO_I2S_GPIO_WS,
|
||||
AUDIO_I2S_GPIO_DOUT,
|
||||
AUDIO_I2S_GPIO_DIN,
|
||||
AUDIO_CODEC_GPIO_PA, // Not used, PA controlled by PM1_G3
|
||||
AUDIO_CODEC_ES8311_ADDR,
|
||||
false);
|
||||
return &audio_codec;
|
||||
}
|
||||
|
||||
virtual Display* GetDisplay() override {
|
||||
return display_;
|
||||
}
|
||||
|
||||
virtual Backlight* GetBacklight() override {
|
||||
static PwmBacklight backlight(DISPLAY_BACKLIGHT_PIN, DISPLAY_BACKLIGHT_OUTPUT_INVERT);
|
||||
return &backlight;
|
||||
}
|
||||
|
||||
virtual bool GetBatteryLevel(int &level, bool& charging, bool& discharging) override {
|
||||
if (!pmic_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get battery voltage in mV
|
||||
uint16_t voltage_mv = 0;
|
||||
if (pmic_->readVbat(&voltage_mv) != M5PM1_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get charging status from PM1_G0 (low = charging, high = not charging)
|
||||
int pm1_g0_level = pmic_->digitalRead(0);
|
||||
if (pm1_g0_level < 0) {
|
||||
return false;
|
||||
}
|
||||
charging = (pm1_g0_level == 0); // Low level means charging
|
||||
discharging = !charging;
|
||||
|
||||
// Convert voltage to battery level percentage
|
||||
// Typical Li-ion battery: 3.0V (0%) to 4.2V (100%)
|
||||
const int BATTERY_MIN_VOLTAGE = 3000; // 3.0V
|
||||
const int BATTERY_MAX_VOLTAGE = 4200; // 4.2V
|
||||
|
||||
if (voltage_mv < BATTERY_MIN_VOLTAGE) {
|
||||
level = 0;
|
||||
} else if (voltage_mv > BATTERY_MAX_VOLTAGE) {
|
||||
level = 100;
|
||||
} else {
|
||||
level = ((voltage_mv - BATTERY_MIN_VOLTAGE) * 100) / (BATTERY_MAX_VOLTAGE - BATTERY_MIN_VOLTAGE);
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Battery: %d%% (%dmV), Charging: %s", level, voltage_mv, charging ? "Yes" : "No");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_BOARD(M5StackStickS3Board);
|
||||
@@ -138,3 +138,4 @@ dependencies:
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: '>=5.5.2'
|
||||
m5stack/m5pm1: ^1.0.5
|
||||
|
||||
Reference in New Issue
Block a user