Files
StackChan/firmware/main/hal/hal.h
T
2026-04-20 16:27:36 +08:00

307 lines
8.1 KiB
C++

/*
* SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
#pragma once
#include <memory>
#include <cstdint>
#include <string>
#include <lvgl.h>
#include <functional>
#include <smooth_ui_toolkit.hpp>
#include <uitk/short_namespace.hpp>
#include <smooth_lvgl.hpp>
#include <array>
#include <lvgl_image.h>
#include <string_view>
/**
* @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<AppInfo_t>;
}; // 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<uitk::lvgl_cpp::Container>(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<uitk::lvgl_cpp::Label>(_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<uitk::lvgl_cpp::Label>(_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<uitk::lvgl_cpp::Label>(_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<uitk::lvgl_cpp::Container> _panel;
std::unique_ptr<uitk::lvgl_cpp::Label> _label_logo;
std::unique_ptr<uitk::lvgl_cpp::Label> _label_msg;
std::unique_ptr<uitk::lvgl_cpp::Label> _label_version;
};
/**
* @brief
*
*/
class Hal {
public:
void init();
/* --------------------------------- System --------------------------------- */
void delay(std::uint32_t ms);
std::uint32_t millis();
void feedTheDog();
std::array<uint8_t, 6> 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> 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<const char*> onBleMotionData;
uitk::Signal<const char*> onBleAvatarData;
uitk::Signal<const char*> onBleConfigData;
uitk::Signal<const char*> onBleRgbData;
uitk::Signal<AppConfigEvent> onAppConfigEvent;
void startBleServer();
bool isBleConnected();
void startAppConfigServer();
bool isAppConfiged();
void resetAppConfiged();
/* --------------------------------- HeadPet -------------------------------- */
uitk::Signal<HeadPetGesture> 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<std::string_view> onWsMotionData;
uitk::Signal<std::string_view> onWsAvatarData;
uitk::Signal<std::string> onWsCallRequest;
uitk::Signal<bool> onWsCallResponse;
uitk::Signal<WsSignalSource> onWsCallEnd;
uitk::Signal<const WsTextMessage_t&> onWsTextMessage;
uitk::Signal<bool> onWsVideoModeChange;
uitk::Signal<std::shared_ptr<LvglImage>> onWsVideoFrame;
uitk::Signal<std::string_view> onWsDanceData;
uitk::Signal<CommonLogLevel, std::string_view> onWsLog;
void startWebSocketAvatarService(std::function<void(std::string_view)> onStartLog);
/* ----------------------------------- IMU ---------------------------------- */
uitk::Signal<ImuMotionEvent> onImuMotionEvent;
/* ---------------------------------- Time ---------------------------------- */
void syncRtcTimeToSystem();
void syncSystemTimeToRtc();
void setTimezone(std::string_view tz);
std::string getTimezone();
/* --------------------------------- EspNow --------------------------------- */
uitk::Signal<const std::vector<uint8_t>&> onEspNowData;
void startEspNow(int channel);
bool espNowSend(const std::vector<uint8_t>& 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<void(std::string_view)> onLog);
WifiStatus getWifiStatus();
void startSntp();
/* -------------------------------- App center ------------------------------- */
app_center::AppInfoList_t fetchAppList();
void launchApp(std::string_view url, std::function<void(int)> onProgress);
/* --------------------------------- EzData --------------------------------- */
void startEzDataService(std::function<void(std::string_view)> onStartLog);
uitk::Signal<std::string_view> onEzdataPairCode;
/* ------------------------------- User Acount ------------------------------ */
UserAccountInfo_t getUserAccountInfo();
bool updateAccountInfo(std::function<void(std::string_view)> onLog);
bool unbindAccount(std::function<void(std::string_view)> onLog);
/* ----------------------------------- OTA ---------------------------------- */
bool updateFirmware(std::function<void(std::string_view)> 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();
}
};