/* * SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD * * SPDX-License-Identifier: MIT */ #pragma once #include #include #include #include #include #include #include #include #include #include #include /** * @brief * */ enum class HeadPetGesture { None, Press, Release, SwipeForward, SwipeBackward }; /** * @brief * */ enum class WsSignalSource { Local = 0, Remote, }; /** * @brief * */ struct WsTextMessage_t { std::string name; std::string content; }; /** * @brief * */ enum class ImuMotionEvent { None = 0, Shake, PickUp, }; /** * @brief * */ enum class AppConfigEvent { None = 0, AppConnected, AppDisconnected, TryWifiConnect, WifiConnectFailed, WifiConnected, }; /** * @brief * */ enum class CommonLogLevel { Info = 0, Warning, Error, }; /** * @brief * */ namespace app_center { struct AppInfo_t { std::string name; std::string iconUrl; std::string description; std::string firmwareUrl; }; using AppInfoList_t = std::vector; }; // namespace app_center /** * @brief * */ enum class WifiStatus { None = 0, Low, Medium, High, }; /** * @brief * */ struct UserAccountInfo_t { std::string username; std::string deviceName; }; /** * @brief * */ class BootLogo { public: BootLogo() { _panel = std::make_unique(lv_screen_active()); _panel->setSize(320, 240); _panel->setAlign(LV_ALIGN_CENTER); _panel->setBorderWidth(0); _panel->setBgOpa(0); _panel->setPaddingAll(0); _label_logo = std::make_unique(_panel->get()); _label_logo->setTextFont(&lv_font_montserrat_24); _label_logo->setTextColor(lv_color_hex(0xFFFFFF)); _label_logo->align(LV_ALIGN_CENTER, 0, -14); _label_logo->setText("STACKCHAN"); _label_msg = std::make_unique(_panel->get()); _label_msg->setTextFont(&lv_font_montserrat_16); _label_msg->setTextColor(lv_color_hex(0xBFBFBF)); _label_msg->align(LV_ALIGN_CENTER, 0, 14); _label_msg->setText("Starting up ..."); _label_version = std::make_unique(_panel->get()); _label_version->setTextFont(&lv_font_montserrat_14); _label_version->setTextColor(lv_color_hex(0x8B8B8B)); _label_version->align(LV_ALIGN_BOTTOM_RIGHT, -7, -6); _label_version->setText("V" FIRMWARE_VERSION); } private: std::unique_ptr _panel; std::unique_ptr _label_logo; std::unique_ptr _label_msg; std::unique_ptr _label_version; }; /** * @brief * */ class Hal { public: void init(); /* --------------------------------- System --------------------------------- */ void delay(std::uint32_t ms); std::uint32_t millis(); void feedTheDog(); std::array getFactoryMac(); std::string getFactoryMacString(std::string divider = ""); void reboot(); void updateHeapStatusLog(); uint8_t getBatteryLevel(); bool isBatteryCharging(); void factoryReset(); /* --------------------------------- Display -------------------------------- */ lv_indev_t* lvTouchpad = nullptr; std::unique_ptr bootLogo; void lvglLock(); void lvglUnlock(); void setBackLightBrightness(uint8_t brightness, bool permanent = false); uint8_t getBackLightBrightness(); /* --------------------------------- Xiaozhi -------------------------------- */ void requestXiaozhiStart() { _xiaozhi_start_requested = true; } bool isXiaozhiStartRequested() { return _xiaozhi_start_requested; } void startXiaozhi(); /* ----------------------------------- BLE ---------------------------------- */ uitk::Signal onBleMotionData; uitk::Signal onBleAvatarData; uitk::Signal onBleConfigData; uitk::Signal onBleRgbData; uitk::Signal onAppConfigEvent; void startBleServer(); bool isBleConnected(); void startAppConfigServer(); bool isAppConfiged(); void resetAppConfiged(); /* --------------------------------- HeadPet -------------------------------- */ uitk::Signal onHeadPetGesture; /* ----------------------------------- RGB ---------------------------------- */ void setRgbColor(uint8_t index, uint8_t r, uint8_t g, uint8_t b); void showRgbColor(uint8_t r, uint8_t g, uint8_t b); void refreshRgb(); /* ---------------------------------- Power --------------------------------- */ void setServoPowerEnabled(bool enabled); /* -------------------------------- Websocket ------------------------------- */ uitk::Signal onWsMotionData; uitk::Signal onWsAvatarData; uitk::Signal onWsCallRequest; uitk::Signal onWsCallResponse; uitk::Signal onWsCallEnd; uitk::Signal onWsTextMessage; uitk::Signal onWsVideoModeChange; uitk::Signal> onWsVideoFrame; uitk::Signal onWsDanceData; uitk::Signal onWsLog; void startWebSocketAvatarService(std::function onStartLog); /* ----------------------------------- IMU ---------------------------------- */ uitk::Signal onImuMotionEvent; /* ---------------------------------- Time ---------------------------------- */ void syncRtcTimeToSystem(); void syncSystemTimeToRtc(); void setTimezone(std::string_view tz); std::string getTimezone(); /* --------------------------------- EspNow --------------------------------- */ uitk::Signal&> onEspNowData; void startEspNow(int channel); bool espNowSend(const std::vector& data, const uint8_t* destAddr = nullptr); void setLaserEnabled(bool enabled); /* ------------------------------- Warm Reboot ------------------------------ */ void requestWarmReboot(int appIndex); int getWarmRebootTarget(); void clearWarmRebootRequest(); /* --------------------------------- Network -------------------------------- */ void startNetwork(std::function onLog); WifiStatus getWifiStatus(); void startSntp(); /* -------------------------------- App center ------------------------------- */ app_center::AppInfoList_t fetchAppList(); void launchApp(std::string_view url, std::function onProgress); /* --------------------------------- EzData --------------------------------- */ void startEzDataService(std::function onStartLog); uitk::Signal onEzdataPairCode; /* ------------------------------- User Acount ------------------------------ */ UserAccountInfo_t getUserAccountInfo(); bool updateAccountInfo(std::function onLog); bool unbindAccount(std::function onLog); /* ----------------------------------- OTA ---------------------------------- */ bool updateFirmware(std::function onLog); /* ---------------------------------- Audio --------------------------------- */ void setSpeakerVolume(uint8_t volume, bool permanent = false); uint8_t getSpeakerVolume(); private: bool _xiaozhi_start_requested = false; void xiaozhi_board_init(); void lvgl_init(); void xiaozhi_mcp_init(); void ble_init(bool useAltUuid); void servo_init(); void head_touch_init(); void io_expander_init(); void imu_init(); void rtc_init(); }; Hal& GetHAL(); /** * @brief * */ class LvglLockGuard { public: LvglLockGuard() { GetHAL().lvglLock(); } ~LvglLockGuard() { GetHAL().lvglUnlock(); } };