forked from xiaozhi/xiaozhi-esp32
adjust board structure
This commit is contained in:
31
main/boards/common/i2c_device.cc
Normal file
31
main/boards/common/i2c_device.cc
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "i2c_device.h"
|
||||
|
||||
#include <esp_log.h>
|
||||
|
||||
#define TAG "I2cDevice"
|
||||
|
||||
|
||||
I2cDevice::I2cDevice(i2c_master_bus_handle_t i2c_bus, uint8_t addr) {
|
||||
i2c_device_config_t i2c_device_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = addr,
|
||||
.scl_speed_hz = 100000,
|
||||
.scl_wait_us = 0,
|
||||
.flags = {
|
||||
.disable_ack_check = 0,
|
||||
},
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_master_bus_add_device(i2c_bus, &i2c_device_cfg, &i2c_device_));
|
||||
assert(i2c_device_ != NULL);
|
||||
}
|
||||
|
||||
void I2cDevice::WriteReg(uint8_t reg, uint8_t value) {
|
||||
uint8_t buffer[2] = {reg, value};
|
||||
ESP_ERROR_CHECK(i2c_master_transmit(i2c_device_, buffer, 2, 100));
|
||||
}
|
||||
|
||||
uint8_t I2cDevice::ReadReg(uint8_t reg) {
|
||||
uint8_t buffer[1];
|
||||
ESP_ERROR_CHECK(i2c_master_transmit_receive(i2c_device_, ®, 1, buffer, 1, 100));
|
||||
return buffer[0];
|
||||
}
|
||||
17
main/boards/common/i2c_device.h
Normal file
17
main/boards/common/i2c_device.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef I2C_DEVICE_H
|
||||
#define I2C_DEVICE_H
|
||||
|
||||
#include <driver/i2c_master.h>
|
||||
|
||||
class I2cDevice {
|
||||
public:
|
||||
I2cDevice(i2c_master_bus_handle_t i2c_bus, uint8_t addr);
|
||||
|
||||
protected:
|
||||
i2c_master_dev_handle_t i2c_device_;
|
||||
|
||||
void WriteReg(uint8_t reg, uint8_t value);
|
||||
uint8_t ReadReg(uint8_t reg);
|
||||
};
|
||||
|
||||
#endif // I2C_DEVICE_H
|
||||
120
main/boards/common/ml307_board.cc
Normal file
120
main/boards/common/ml307_board.cc
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "ml307_board.h"
|
||||
#include "application.h"
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <esp_timer.h>
|
||||
#include <ml307_http.h>
|
||||
#include <ml307_ssl_transport.h>
|
||||
#include <web_socket.h>
|
||||
#include <ml307_mqtt.h>
|
||||
#include <ml307_udp.h>
|
||||
|
||||
static const char *TAG = "Ml307Board";
|
||||
|
||||
static std::string csq_to_string(int csq) {
|
||||
if (csq == -1) {
|
||||
return "No network";
|
||||
} else if (csq >= 0 && csq <= 9) {
|
||||
return "Very bad";
|
||||
} else if (csq >= 10 && csq <= 14) {
|
||||
return "Bad";
|
||||
} else if (csq >= 15 && csq <= 19) {
|
||||
return "Fair";
|
||||
} else if (csq >= 20 && csq <= 24) {
|
||||
return "Good";
|
||||
} else if (csq >= 25 && csq <= 31) {
|
||||
return "Very good";
|
||||
}
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
|
||||
Ml307Board::Ml307Board(gpio_num_t tx_pin, gpio_num_t rx_pin, size_t rx_buffer_size) : modem_(tx_pin, rx_pin, rx_buffer_size) {
|
||||
}
|
||||
|
||||
void Ml307Board::StartNetwork() {
|
||||
auto display = Board::GetInstance().GetDisplay();
|
||||
display->SetText(std::string("Starting modem"));
|
||||
modem_.SetDebug(false);
|
||||
modem_.SetBaudRate(921600);
|
||||
|
||||
auto& application = Application::GetInstance();
|
||||
// If low power, the material ready event will be triggered by the modem because of a reset
|
||||
modem_.OnMaterialReady([this, &application]() {
|
||||
ESP_LOGI(TAG, "ML307 material ready");
|
||||
application.Schedule([this, &application]() {
|
||||
application.SetChatState(kChatStateIdle);
|
||||
WaitForNetworkReady();
|
||||
});
|
||||
});
|
||||
|
||||
WaitForNetworkReady();
|
||||
}
|
||||
|
||||
void Ml307Board::WaitForNetworkReady() {
|
||||
auto& application = Application::GetInstance();
|
||||
auto display = Board::GetInstance().GetDisplay();
|
||||
display->SetText(std::string("Wait for network\n"));
|
||||
int result = modem_.WaitForNetworkReady();
|
||||
if (result == -1) {
|
||||
application.Alert("Error", "PIN is not ready");
|
||||
return;
|
||||
} else if (result == -2) {
|
||||
application.Alert("Error", "Registration denied");
|
||||
return;
|
||||
}
|
||||
|
||||
// Print the ML307 modem information
|
||||
std::string module_name = modem_.GetModuleName();
|
||||
std::string imei = modem_.GetImei();
|
||||
std::string iccid = modem_.GetIccid();
|
||||
ESP_LOGI(TAG, "ML307 Module: %s", module_name.c_str());
|
||||
ESP_LOGI(TAG, "ML307 IMEI: %s", imei.c_str());
|
||||
ESP_LOGI(TAG, "ML307 ICCID: %s", iccid.c_str());
|
||||
}
|
||||
|
||||
void Ml307Board::Initialize() {
|
||||
ESP_LOGI(TAG, "Initializing Ml307Board");
|
||||
}
|
||||
|
||||
Http* Ml307Board::CreateHttp() {
|
||||
return new Ml307Http(modem_);
|
||||
}
|
||||
|
||||
WebSocket* Ml307Board::CreateWebSocket() {
|
||||
return new WebSocket(new Ml307SslTransport(modem_, 0));
|
||||
}
|
||||
|
||||
Mqtt* Ml307Board::CreateMqtt() {
|
||||
return new Ml307Mqtt(modem_, 0);
|
||||
}
|
||||
|
||||
Udp* Ml307Board::CreateUdp() {
|
||||
return new Ml307Udp(modem_, 0);
|
||||
}
|
||||
|
||||
bool Ml307Board::GetNetworkState(std::string& network_name, int& signal_quality, std::string& signal_quality_text) {
|
||||
if (!modem_.network_ready()) {
|
||||
return false;
|
||||
}
|
||||
network_name = modem_.GetCarrierName();
|
||||
signal_quality = modem_.GetCsq();
|
||||
signal_quality_text = csq_to_string(signal_quality);
|
||||
return signal_quality != -1;
|
||||
}
|
||||
|
||||
std::string Ml307Board::GetBoardJson() {
|
||||
// Set the board type for OTA
|
||||
std::string board_type = BOARD_TYPE;
|
||||
std::string board_json = std::string("{\"type\":\"" + board_type + "\",");
|
||||
board_json += "\"revision\":\"" + modem_.GetModuleName() + "\",";
|
||||
board_json += "\"carrier\":\"" + modem_.GetCarrierName() + "\",";
|
||||
board_json += "\"csq\":\"" + std::to_string(modem_.GetCsq()) + "\",";
|
||||
board_json += "\"imei\":\"" + modem_.GetImei() + "\",";
|
||||
board_json += "\"iccid\":\"" + modem_.GetIccid() + "\"}";
|
||||
return board_json;
|
||||
}
|
||||
|
||||
void Ml307Board::SetPowerSaveMode(bool enabled) {
|
||||
// TODO: Implement power save mode for ML307
|
||||
}
|
||||
26
main/boards/common/ml307_board.h
Normal file
26
main/boards/common/ml307_board.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef ML307_BOARD_H
|
||||
#define ML307_BOARD_H
|
||||
|
||||
#include "board.h"
|
||||
#include <ml307_at_modem.h>
|
||||
|
||||
class Ml307Board : public Board {
|
||||
protected:
|
||||
Ml307AtModem modem_;
|
||||
|
||||
virtual std::string GetBoardJson() override;
|
||||
void WaitForNetworkReady();
|
||||
|
||||
public:
|
||||
Ml307Board(gpio_num_t tx_pin, gpio_num_t rx_pin, size_t rx_buffer_size = 4096);
|
||||
virtual void Initialize() override;
|
||||
virtual void StartNetwork() override;
|
||||
virtual Http* CreateHttp() override;
|
||||
virtual WebSocket* CreateWebSocket() override;
|
||||
virtual Mqtt* CreateMqtt() override;
|
||||
virtual Udp* CreateUdp() override;
|
||||
virtual bool GetNetworkState(std::string& network_name, int& signal_quality, std::string& signal_quality_text) override;
|
||||
virtual void SetPowerSaveMode(bool enabled) override;
|
||||
};
|
||||
|
||||
#endif // ML307_BOARD_H
|
||||
72
main/boards/common/system_reset.cc
Normal file
72
main/boards/common/system_reset.cc
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "system_reset.h"
|
||||
|
||||
#include <esp_log.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <driver/gpio.h>
|
||||
#include <esp_partition.h>
|
||||
#include <esp_system.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
|
||||
|
||||
#define TAG "SystemReset"
|
||||
|
||||
|
||||
SystemReset::SystemReset(gpio_num_t reset_nvs_pin, gpio_num_t reset_factory_pin) : reset_nvs_pin_(reset_nvs_pin), reset_factory_pin_(reset_factory_pin) {
|
||||
// Configure GPIO1, GPIO2 as INPUT, reset NVS flash if the button is pressed
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pin_bit_mask = (1ULL << reset_nvs_pin_) | (1ULL << reset_factory_pin_);
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
gpio_config(&io_conf);
|
||||
}
|
||||
|
||||
|
||||
void SystemReset::CheckButtons() {
|
||||
if (gpio_get_level(reset_factory_pin_) == 0) {
|
||||
ESP_LOGI(TAG, "Button is pressed, reset to factory");
|
||||
ResetNvsFlash();
|
||||
ResetToFactory();
|
||||
}
|
||||
|
||||
if (gpio_get_level(reset_nvs_pin_) == 0) {
|
||||
ESP_LOGI(TAG, "Button is pressed, reset NVS flash");
|
||||
ResetNvsFlash();
|
||||
}
|
||||
}
|
||||
|
||||
void SystemReset::ResetNvsFlash() {
|
||||
ESP_LOGI(TAG, "Resetting NVS flash");
|
||||
esp_err_t ret = nvs_flash_erase();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to erase NVS flash");
|
||||
}
|
||||
ret = nvs_flash_init();
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to initialize NVS flash");
|
||||
}
|
||||
}
|
||||
|
||||
void SystemReset::ResetToFactory() {
|
||||
ESP_LOGI(TAG, "Resetting to factory");
|
||||
// Erase otadata partition
|
||||
const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (partition == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to find otadata partition");
|
||||
return;
|
||||
}
|
||||
esp_partition_erase_range(partition, 0, partition->size);
|
||||
ESP_LOGI(TAG, "Erased otadata partition");
|
||||
|
||||
// Reboot in 3 seconds
|
||||
RestartInSeconds(3);
|
||||
}
|
||||
|
||||
void SystemReset::RestartInSeconds(int seconds) {
|
||||
for (int i = seconds; i > 0; i--) {
|
||||
ESP_LOGI(TAG, "Resetting in %d seconds", i);
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
}
|
||||
esp_restart();
|
||||
}
|
||||
21
main/boards/common/system_reset.h
Normal file
21
main/boards/common/system_reset.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef _SYSTEM_RESET_H
|
||||
#define _SYSTEM_RESET_H
|
||||
|
||||
#include <driver/gpio.h>
|
||||
|
||||
class SystemReset {
|
||||
public:
|
||||
SystemReset(gpio_num_t reset_nvs_pin, gpio_num_t reset_factory_pin); // 构造函数私有化
|
||||
void CheckButtons();
|
||||
|
||||
private:
|
||||
gpio_num_t reset_nvs_pin_;
|
||||
gpio_num_t reset_factory_pin_;
|
||||
|
||||
void ResetNvsFlash();
|
||||
void ResetToFactory();
|
||||
void RestartInSeconds(int seconds);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
121
main/boards/common/wifi_board.cc
Normal file
121
main/boards/common/wifi_board.cc
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "wifi_board.h"
|
||||
#include "application.h"
|
||||
#include "system_info.h"
|
||||
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <esp_http.h>
|
||||
#include <esp_mqtt.h>
|
||||
#include <esp_udp.h>
|
||||
#include <tcp_transport.h>
|
||||
#include <tls_transport.h>
|
||||
#include <web_socket.h>
|
||||
#include <esp_log.h>
|
||||
|
||||
#include <wifi_station.h>
|
||||
#include <wifi_configuration_ap.h>
|
||||
|
||||
static const char *TAG = "WifiBoard";
|
||||
|
||||
static std::string rssi_to_string(int rssi) {
|
||||
if (rssi >= -55) {
|
||||
return "Very good";
|
||||
} else if (rssi >= -65) {
|
||||
return "Good";
|
||||
} else if (rssi >= -75) {
|
||||
return "Fair";
|
||||
} else if (rssi >= -85) {
|
||||
return "Poor";
|
||||
} else {
|
||||
return "No network";
|
||||
}
|
||||
}
|
||||
|
||||
void WifiBoard::StartNetwork() {
|
||||
auto& application = Application::GetInstance();
|
||||
auto display = Board::GetInstance().GetDisplay();
|
||||
auto builtin_led = Board::GetInstance().GetBuiltinLed();
|
||||
|
||||
// Try to connect to WiFi, if failed, launch the WiFi configuration AP
|
||||
auto& wifi_station = WifiStation::GetInstance();
|
||||
display->SetText(std::string("Connect to WiFi\n") + wifi_station.GetSsid());
|
||||
wifi_station.Start();
|
||||
if (!wifi_station.IsConnected()) {
|
||||
builtin_led->SetBlue();
|
||||
builtin_led->Blink(1000, 500);
|
||||
auto& wifi_ap = WifiConfigurationAp::GetInstance();
|
||||
wifi_ap.SetSsidPrefix("Xiaozhi");
|
||||
wifi_ap.Start();
|
||||
// 播报配置 WiFi 的提示
|
||||
application.Alert("Info", "Configuring WiFi");
|
||||
// 显示 WiFi 配置 AP 的 SSID 和 Web 服务器 URL
|
||||
display->SetText(wifi_ap.GetSsid() + "\n" + wifi_ap.GetWebServerUrl());
|
||||
// Wait forever until reset after configuration
|
||||
while (true) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WifiBoard::Initialize() {
|
||||
ESP_LOGI(TAG, "Initializing WifiBoard");
|
||||
}
|
||||
|
||||
Http* WifiBoard::CreateHttp() {
|
||||
return new EspHttp();
|
||||
}
|
||||
|
||||
WebSocket* WifiBoard::CreateWebSocket() {
|
||||
std::string url = CONFIG_WEBSOCKET_URL;
|
||||
if (url.find("wss://") == 0) {
|
||||
return new WebSocket(new TlsTransport());
|
||||
} else {
|
||||
return new WebSocket(new TcpTransport());
|
||||
}
|
||||
}
|
||||
|
||||
Mqtt* WifiBoard::CreateMqtt() {
|
||||
return new EspMqtt();
|
||||
}
|
||||
|
||||
Udp* WifiBoard::CreateUdp() {
|
||||
return new EspUdp();
|
||||
}
|
||||
|
||||
bool WifiBoard::GetNetworkState(std::string& network_name, int& signal_quality, std::string& signal_quality_text) {
|
||||
if (wifi_config_mode_) {
|
||||
auto& wifi_ap = WifiConfigurationAp::GetInstance();
|
||||
network_name = wifi_ap.GetSsid();
|
||||
signal_quality = -99;
|
||||
signal_quality_text = wifi_ap.GetWebServerUrl();
|
||||
return true;
|
||||
}
|
||||
auto& wifi_station = WifiStation::GetInstance();
|
||||
if (!wifi_station.IsConnected()) {
|
||||
return false;
|
||||
}
|
||||
network_name = wifi_station.GetSsid();
|
||||
signal_quality = wifi_station.GetRssi();
|
||||
signal_quality_text = rssi_to_string(signal_quality);
|
||||
return signal_quality != -1;
|
||||
}
|
||||
|
||||
std::string WifiBoard::GetBoardJson() {
|
||||
// Set the board type for OTA
|
||||
auto& wifi_station = WifiStation::GetInstance();
|
||||
std::string board_type = BOARD_TYPE;
|
||||
std::string board_json = std::string("{\"type\":\"" + board_type + "\",");
|
||||
if (!wifi_config_mode_) {
|
||||
board_json += "\"ssid\":\"" + wifi_station.GetSsid() + "\",";
|
||||
board_json += "\"rssi\":" + std::to_string(wifi_station.GetRssi()) + ",";
|
||||
board_json += "\"channel\":" + std::to_string(wifi_station.GetChannel()) + ",";
|
||||
board_json += "\"ip\":\"" + wifi_station.GetIpAddress() + "\",";
|
||||
}
|
||||
board_json += "\"mac\":\"" + SystemInfo::GetMacAddress() + "\"}";
|
||||
return board_json;
|
||||
}
|
||||
|
||||
void WifiBoard::SetPowerSaveMode(bool enabled) {
|
||||
auto& wifi_station = WifiStation::GetInstance();
|
||||
wifi_station.SetPowerSaveMode(enabled);
|
||||
}
|
||||
23
main/boards/common/wifi_board.h
Normal file
23
main/boards/common/wifi_board.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef WIFI_BOARD_H
|
||||
#define WIFI_BOARD_H
|
||||
|
||||
#include "board.h"
|
||||
|
||||
class WifiBoard : public Board {
|
||||
protected:
|
||||
bool wifi_config_mode_ = false;
|
||||
|
||||
virtual std::string GetBoardJson() override;
|
||||
|
||||
public:
|
||||
virtual void Initialize() override;
|
||||
virtual void StartNetwork() override;
|
||||
virtual Http* CreateHttp() override;
|
||||
virtual WebSocket* CreateWebSocket() override;
|
||||
virtual Mqtt* CreateMqtt() override;
|
||||
virtual Udp* CreateUdp() override;
|
||||
virtual bool GetNetworkState(std::string& network_name, int& signal_quality, std::string& signal_quality_text) override;
|
||||
virtual void SetPowerSaveMode(bool enabled) override;
|
||||
};
|
||||
|
||||
#endif // WIFI_BOARD_H
|
||||
Reference in New Issue
Block a user