diff --git a/main/boards/common/sy6970.cc b/main/boards/common/sy6970.cc new file mode 100644 index 00000000..8c4c698e --- /dev/null +++ b/main/boards/common/sy6970.cc @@ -0,0 +1,58 @@ +#include "sy6970.h" +#include "board.h" +#include "display.h" + +#include + +#define TAG "Sy6970" + +Sy6970::Sy6970(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : I2cDevice(i2c_bus, addr) { +} + +int Sy6970::GetChangingStatus() { + return (ReadReg(0x0B) >> 3) & 0x03; +} + +bool Sy6970::IsCharging() { + return GetChangingStatus() != 0; +} + +bool Sy6970::IsPowerGood() { + return (ReadReg(0x0B) & 0x04) != 0; +} + +bool Sy6970::IsChargingDone() { + return GetChangingStatus() == 3; +} + +int Sy6970::GetBatteryVoltage() { + uint8_t value = ReadReg(0x0E); + value &= 0x7F; + if (value == 0) { + return 0; + } + return value * 20 + 2304; +} + +int Sy6970::GetChargeTargetVoltage() { + uint8_t value = ReadReg(0x06); + value = (value & 0xFC) >> 2; + if (value > 0x30) { + return 4608; + } + return value * 16 + 3840; +} + +int Sy6970::GetBatteryLevel() { + int battery_minimum_voltage = 3200; // 电池所能掉电的最低电压 + int battery_voltage = GetBatteryVoltage(); + int charge_voltage_limit = GetChargeTargetVoltage(); + if (battery_voltage > battery_minimum_voltage && charge_voltage_limit > battery_minimum_voltage) { + return (((float) battery_voltage - (float) battery_minimum_voltage) / ((float) charge_voltage_limit - (float) battery_minimum_voltage)) * 100.0; + } + return 0; +} + +void Sy6970::PowerOff() { + WriteReg(0x09,0B01100100); +} diff --git a/main/boards/common/sy6970.h b/main/boards/common/sy6970.h new file mode 100644 index 00000000..a2eaaca4 --- /dev/null +++ b/main/boards/common/sy6970.h @@ -0,0 +1,21 @@ +#ifndef __SY6970_H__ +#define __SY6970_H__ + +#include "i2c_device.h" + +class Sy6970 : public I2cDevice { +public: + Sy6970(i2c_master_bus_handle_t i2c_bus, uint8_t addr); + bool IsCharging(); + bool IsPowerGood(); + bool IsChargingDone(); + int GetBatteryLevel(); + void PowerOff(); + +private: + int GetChangingStatus(); + int GetBatteryVoltage(); + int GetChargeTargetVoltage(); +}; + +#endif \ No newline at end of file diff --git a/main/boards/lilygo-t-cameraplus-s3/README.md b/main/boards/lilygo-t-cameraplus-s3/README.md index 551ce51b..a3a53997 100644 --- a/main/boards/lilygo-t-cameraplus-s3/README.md +++ b/main/boards/lilygo-t-cameraplus-s3/README.md @@ -30,4 +30,4 @@ Component config -> ESP PSRAM -> SPI RAM config -> Mode (QUAD/OCT) -> Quad Mode idf.py build ``` -LILYGO T-CameraPlus-S3 \ No newline at end of file +LILYGO T-CameraPlus-S3 \ No newline at end of file diff --git a/main/boards/lilygo-t-cameraplus-s3/config.h b/main/boards/lilygo-t-cameraplus-s3/config.h index b47daead..f10efae5 100644 --- a/main/boards/lilygo-t-cameraplus-s3/config.h +++ b/main/boards/lilygo-t-cameraplus-s3/config.h @@ -1,8 +1,6 @@ #ifndef _BOARD_CONFIG_H_ #define _BOARD_CONFIG_H_ -// M5Stack CoreS3 Board configuration - #include #include "pin_config.h" diff --git a/main/boards/lilygo-t-cameraplus-s3/config.json b/main/boards/lilygo-t-cameraplus-s3/config.json index 596ae8ce..2b216f02 100644 --- a/main/boards/lilygo-t-cameraplus-s3/config.json +++ b/main/boards/lilygo-t-cameraplus-s3/config.json @@ -3,7 +3,7 @@ "builds": [ { "name": "lilygo-t-cameraplus-s3", - "sdkconfig_append": ["CONFIG_SPIRAM_MODE_OCT=n","CONFIG_SPIRAM_MODE_QUAD=y"] + "sdkconfig_append": ["CONFIG_SPIRAM_MODE_QUAD=y"] } ] } \ No newline at end of file diff --git a/main/boards/lilygo-t-cameraplus-s3/lilygo-t-cameraplus-s3.cc b/main/boards/lilygo-t-cameraplus-s3/lilygo-t-cameraplus-s3.cc index 8f58b6c0..5d2e6770 100644 --- a/main/boards/lilygo-t-cameraplus-s3/lilygo-t-cameraplus-s3.cc +++ b/main/boards/lilygo-t-cameraplus-s3/lilygo-t-cameraplus-s3.cc @@ -7,6 +7,7 @@ #include "power_save_timer.h" #include "i2c_device.h" #include "iot/thing_manager.h" +#include "sy6970.h" #include #include @@ -52,10 +53,24 @@ private: TouchPoint_t tp_; }; +class Pmic : public Sy6970 { +public: + + Pmic(i2c_master_bus_handle_t i2c_bus, uint8_t addr) : Sy6970(i2c_bus, addr) { + uint8_t chip_id = ReadReg(0x14); + ESP_LOGI(TAG, "Get sy6970 chip ID: 0x%02X", (chip_id & 0B00111000)); + + WriteReg(0x00, 0B00001000); // Disable ILIM pin + WriteReg(0x02, 0B11011101); // Enable ADC measurement function + WriteReg(0x07, 0B10001101); // Disable watchdog timer feeding function + } +}; + class LilygoTCameraPlusS3Board : public WifiBoard { private: i2c_master_bus_handle_t i2c_bus_; Cst816x *cst816d_; + Pmic* pmic_; LcdDisplay *display_; Button key1_button_; PowerSaveTimer* power_save_timer_; @@ -75,6 +90,9 @@ private: display->SetEmotion("neutral"); GetBacklight()->RestoreBrightness(); }); + power_save_timer_->OnShutdownRequest([this]() { + pmic_->PowerOff(); + }); power_save_timer_->SetEnabled(true); } @@ -156,6 +174,11 @@ private: ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST, &buscfg, SPI_DMA_CH_AUTO)); } + void InitSy6970() { + ESP_LOGI(TAG, "Init Sy6970"); + pmic_ = new Pmic(i2c_bus_, 0x6A); + } + void InitializeSt7789Display() { esp_lcd_panel_io_handle_t panel_io = nullptr; esp_lcd_panel_handle_t panel = nullptr; @@ -209,12 +232,14 @@ private: auto &thing_manager = iot::ThingManager::GetInstance(); thing_manager.AddThing(iot::CreateThing("Speaker")); thing_manager.AddThing(iot::CreateThing("Screen")); + thing_manager.AddThing(iot::CreateThing("Battery")); } public: LilygoTCameraPlusS3Board() : key1_button_(KEY1_BUTTON_GPIO) { InitializePowerSaveTimer(); InitI2c(); + InitSy6970(); InitCst816d(); I2cDetect(); InitSpi(); @@ -242,6 +267,20 @@ public: return display_; } + virtual bool GetBatteryLevel(int &level, bool& charging, bool& discharging) override { + static bool last_discharging = false; + charging = pmic_->IsCharging(); + bool is_power_good = pmic_->IsPowerGood(); + discharging = !charging && is_power_good; + if (discharging != last_discharging) { + power_save_timer_->SetEnabled(discharging); + last_discharging = discharging; + } + + level = pmic_->GetBatteryLevel(); + return true; + } + virtual void SetPowerSaveMode(bool enabled) override { if (!enabled) { power_save_timer_->WakeUp(); diff --git a/main/boards/lilygo-t-cameraplus-s3/tcamerapluss3_audio_codec.cc b/main/boards/lilygo-t-cameraplus-s3/tcamerapluss3_audio_codec.cc index ae8fa396..f23008c4 100644 --- a/main/boards/lilygo-t-cameraplus-s3/tcamerapluss3_audio_codec.cc +++ b/main/boards/lilygo-t-cameraplus-s3/tcamerapluss3_audio_codec.cc @@ -60,7 +60,7 @@ void Tcamerapluss3AudioCodec::CreateVoiceHardware(gpio_num_t mic_bclk, gpio_num_ .invert_flags = { .mclk_inv = false, .bclk_inv = false, - .ws_inv = true // 默认右通道 + .ws_inv = true // 默认右声道 } } }; diff --git a/main/boards/lilygo-t-circle-s3/config.h b/main/boards/lilygo-t-circle-s3/config.h index e115c77a..03e4fc57 100644 --- a/main/boards/lilygo-t-circle-s3/config.h +++ b/main/boards/lilygo-t-circle-s3/config.h @@ -1,8 +1,6 @@ #ifndef _BOARD_CONFIG_H_ #define _BOARD_CONFIG_H_ -// M5Stack CoreS3 Board configuration - #include #include "pin_config.h" diff --git a/main/boards/lilygo-t-circle-s3/tcircles3_audio_codec.cc b/main/boards/lilygo-t-circle-s3/tcircles3_audio_codec.cc index a107a87b..5fe3ea79 100644 --- a/main/boards/lilygo-t-circle-s3/tcircles3_audio_codec.cc +++ b/main/boards/lilygo-t-circle-s3/tcircles3_audio_codec.cc @@ -4,6 +4,8 @@ #include #include +#include "config.h" + static const char TAG[] = "Tcircles3AudioCodec"; Tcircles3AudioCodec::Tcircles3AudioCodec(int input_sample_rate, int output_sample_rate, @@ -19,7 +21,7 @@ Tcircles3AudioCodec::Tcircles3AudioCodec(int input_sample_rate, int output_sampl CreateVoiceHardware(mic_bclk, mic_ws, mic_data, spkr_bclk, spkr_lrclk, spkr_data); gpio_config_t config; - config.pin_bit_mask = BIT64(45); + config.pin_bit_mask = BIT64(AUDIO_SPKR_ENABLE); config.mode = GPIO_MODE_OUTPUT; config.pull_up_en = GPIO_PULLUP_DISABLE; config.pull_down_en = GPIO_PULLDOWN_ENABLE; @@ -28,7 +30,7 @@ Tcircles3AudioCodec::Tcircles3AudioCodec(int input_sample_rate, int output_sampl config.hys_ctrl_mode = GPIO_HYS_SOFT_ENABLE; #endif gpio_config(&config); - gpio_set_level(gpio_num_t(45), 0); + gpio_set_level(AUDIO_SPKR_ENABLE, 0); ESP_LOGI(TAG, "Tcircles3AudioCodec initialized"); } @@ -116,9 +118,9 @@ void Tcircles3AudioCodec::EnableInput(bool enable) { void Tcircles3AudioCodec::EnableOutput(bool enable) { if (enable){ - gpio_set_level(gpio_num_t(45), 1); + gpio_set_level(AUDIO_SPKR_ENABLE, 1); }else{ - gpio_set_level(gpio_num_t(45), 0); + gpio_set_level(AUDIO_SPKR_ENABLE, 0); } AudioCodec::EnableOutput(enable); }