gpio checking

This commit is contained in:
proddy
2025-11-22 22:38:46 +01:00
parent c95b43ea69
commit 8016fc4287
5 changed files with 345 additions and 352 deletions

View File

@@ -85,277 +85,173 @@ void WebSettings::read(WebSettings & settings, JsonObject root) {
root["developer_mode"] = settings.developer_mode;
}
// call on initialization and also when settings are updated via web or console
// call on initialization and also when settings are updated/saved via web or console
StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
// load the version from the settings config. This can be blank and later used in System::check_upgrade()
settings.version = root["version"] | EMSESP_DEFAULT_VERSION;
#if defined(EMSESP_DEBUG)
EMSESP::logger().debug("NVS boot value=[%s], board profile=[%s], EMSESP_DEFAULT_BOARD_PROFILE=[%s]",
EMSESP::nvs_.getString("boot").c_str(),
root["board_profile"] | "",
EMSESP_DEFAULT_BOARD_PROFILE);
#endif
// get the current board profile saved in the settings file
String org_board_profile = settings.board_profile;
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE; // this is set at compile time in platformio.ini, other it's "default"
String old_board_profile = settings.board_profile;
// The optional NVS boot value has priority and overrides any board_profile setting.
// We only do this for BBQKees boards
// Note 1: we never set the NVS boot value in the code - this is done on initial pre-loading
// Note 2: The board profile is dynamically changed for the session, but the value in the settings file on the FS remains untouched
if (EMSESP::system_.getBBQKeesGatewayDetails(FUSE_VALUE::MFG).startsWith("BBQKees")) {
String bbq_board = EMSESP::system_.getBBQKeesGatewayDetails(FUSE_VALUE::BOARD);
if (!bbq_board.isEmpty()) {
#if defined(EMSESP_DEBUG)
EMSESP::logger().info("Overriding board profile with fuse value %s", bbq_board.c_str());
#endif
settings.board_profile = bbq_board;
}
}
// load the board profile from the settings, if it's not "default"
std::vector<int8_t> data; // // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode
if (settings.board_profile != "default") {
if (System::load_board_profile(data, settings.board_profile.c_str())) {
if (settings.board_profile == "CUSTOM") { // read pins, fallback to S32 values
data = {(int8_t)(root["led_gpio"] | 2),
(int8_t)(root["dallas_gpio"] | 18),
(int8_t)(root["rx_gpio"] | 23),
(int8_t)(root["tx_gpio"] | 5),
(int8_t)(root["pbutton_gpio"] | 0),
(int8_t)(root["phy_type"] | PHY_type::PHY_TYPE_NONE),
(int8_t)(root["eth_power"] | 0),
(int8_t)(root["eth_phy_addr"] | 0),
(int8_t)(root["eth_clock_mode"] | 0),
#if defined(ARDUINO_LOLIN_C3_MINI) && !defined(BOARD_C3_MINI_V1)
(int8_t)(root["led_type"] | 1)};
#else
(int8_t)(root["led_type"] | 0)}; // 0 = LED, 1 = RGB-LED
#endif
}
// check valid pins for this board profile
if (!EMSESP::system_.check_valid_gpio(data[0], "LED") || !EMSESP::system_.check_valid_gpio(data[1], "Dallas")
|| !EMSESP::system_.check_valid_gpio(data[2], "UART Rx") || !EMSESP::system_.check_valid_gpio(data[3], "UART Tx")
|| !EMSESP::system_.check_valid_gpio(data[4], "Button") || !EMSESP::system_.check_valid_gpio(data[6], "Ethernet")) {
// set status
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_INVALID_GPIO);
settings.board_profile = "default"; // reset to factory default
}
} else {
settings.board_profile = "default"; // can't find profile, use "default"
}
}
// still don't have a valid board profile. Let's see if we can determine one
if (settings.board_profile == "default") {
#if defined(EMSESP_DEBUG)
EMSESP::logger().debug("Trying to detect board and set board profile...");
#endif
#if defined(EMSESP_STANDALONE)
settings.board_profile = "S32";
#elif CONFIG_IDF_TARGET_ESP32
// check for no PSRAM, could be a E32 or S32?
if (!ESP.getPsramSize()) {
#if ESP_ARDUINO_VERSION_MAJOR < 3
if (ETH.begin(1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) {
#else
if (ETH.begin(ETH_PHY_LAN8720, 1, 23, 18, 16, ETH_CLOCK_GPIO0_IN)) {
#endif
settings.board_profile = "E32"; // Ethernet without PSRAM
} else {
settings.board_profile = "S32"; // ESP32 standard WiFi without PSRAM
}
} else {
// check for boards with PSRAM, could be a E32V2 otherwise default back to the S32
#if ESP_ARDUINO_VERSION_MAJOR < 3
if (ETH.begin(0, 15, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_OUT)) {
#else
if (ETH.begin(ETH_PHY_LAN8720, 0, 23, 18, 15, ETH_CLOCK_GPIO0_OUT)) {
#endif
if (analogReadMilliVolts(39) > 700) { // core voltage > 2.6V
settings.board_profile = "E32V2_2"; // Ethernet, PSRAM, internal sensors
} else {
settings.board_profile = "E32V2"; // Ethernet and PSRAM
}
} else {
settings.board_profile = "S32"; // ESP32 standard WiFi with PSRAM
}
}
// override if we know the target from the build config like C3, S2, S3 etc..
#elif CONFIG_IDF_TARGET_ESP32C3
settings.board_profile = "C3MINI";
#elif CONFIG_IDF_TARGET_ESP32S2
settings.board_profile = "S2MINI";
#elif CONFIG_IDF_TARGET_ESP32S3
settings.board_profile = "S32S3"; // BBQKees Gateway S3
#endif
// apply the new board profile setting
System::load_board_profile(data, settings.board_profile.c_str());
}
int prev;
// make a copy of the settings to compare to later
WebSettings original_settings = settings;
reset_flags();
// check if board profile has changed
if (org_board_profile != settings.board_profile) {
if (org_board_profile.isEmpty()) {
EMSESP::logger().info("Setting board profile to %s", settings.board_profile.c_str());
} else {
EMSESP::logger().info("Setting board profile to %s (was %s)", settings.board_profile.c_str(), org_board_profile.c_str());
}
settings.version = root["version"] | EMSESP_DEFAULT_VERSION; // save the version, we use it later in System::check_upgrade()
settings.board_profile = root["board_profile"] | EMSESP_DEFAULT_BOARD_PROFILE;
// get current values that are related to the board profile
settings.led_gpio = root["led_gpio"];
settings.dallas_gpio = root["dallas_gpio"];
settings.rx_gpio = root["rx_gpio"];
settings.tx_gpio = root["tx_gpio"];
settings.pbutton_gpio = root["pbutton_gpio"];
settings.phy_type = root["phy_type"];
settings.eth_power = root["eth_power"];
settings.eth_phy_addr = root["eth_phy_addr"];
settings.eth_clock_mode = root["eth_clock_mode"];
settings.led_type = root["led_type"]; // 1 = RGB-LED
#if defined(EMSESP_DEBUG)
EMSESP::logger().debug("NVS boot value=[%s], current board_profile=[%s], new board_profile=[%s]",
EMSESP::nvs_.getString("boot").c_str(),
original_settings.board_profile.c_str(),
settings.board_profile.c_str());
#endif
// TODO: make sure board profile is loaded when EMS-ESP starts. it will because original_settings.board_profile is empty when EMS-ESP starts
// see if the user has changed the board profile
// this will set: led_gpio, dallas_gpio, rx_gpio, tx_gpio, pbutton_gpio, phy_type, eth_power, eth_phy_addr, eth_clock_mode, led_type
if (original_settings.board_profile != settings.board_profile) {
set_board_profile(settings);
add_flags(ChangeFlags::RESTART);
}
// pins
prev = settings.led_gpio;
settings.led_gpio = data[0];
check_flag(prev, settings.led_gpio, ChangeFlags::LED);
prev = settings.dallas_gpio;
settings.dallas_gpio = data[1];
check_flag(prev, settings.dallas_gpio, ChangeFlags::TEMPERATURE_SENSOR);
prev = settings.rx_gpio;
settings.rx_gpio = data[2];
check_flag(prev, settings.rx_gpio, ChangeFlags::RESTART);
prev = settings.tx_gpio;
settings.tx_gpio = data[3];
check_flag(prev, settings.tx_gpio, ChangeFlags::RESTART);
prev = settings.pbutton_gpio;
settings.pbutton_gpio = data[4];
check_flag(prev, settings.pbutton_gpio, ChangeFlags::BUTTON);
prev = settings.phy_type;
settings.phy_type = data[5];
check_flag(prev, settings.phy_type, ChangeFlags::RESTART);
prev = settings.eth_power;
settings.eth_power = data[6];
check_flag(prev, settings.eth_power, ChangeFlags::RESTART);
prev = settings.eth_phy_addr;
settings.eth_phy_addr = data[7];
check_flag(prev, settings.eth_phy_addr, ChangeFlags::RESTART);
prev = settings.eth_clock_mode;
settings.eth_clock_mode = data[8];
check_flag(prev, settings.eth_clock_mode, ChangeFlags::RESTART);
prev = settings.led_type;
settings.led_type = data[9];
check_flag(prev, settings.led_type, ChangeFlags::LED);
// if any of the GPIOs have changed and re-validate them
bool valid_gpios = true;
// tx_mode, rx and tx pins
prev = settings.tx_mode;
if (check_flag(original_settings.led_gpio, settings.led_gpio, ChangeFlags::LED)) {
if (settings.led_gpio != 0) { // 0 means disabled
valid_gpios = valid_gpios && EMSESP::system_.add_gpio(settings.led_gpio, "LED");
}
}
if (check_flag(original_settings.dallas_gpio, settings.dallas_gpio, ChangeFlags::TEMPERATURE_SENSOR)) {
if (settings.dallas_gpio != 0) { // 0 means disabled
valid_gpios = valid_gpios && EMSESP::system_.add_gpio(settings.dallas_gpio, "Dallas");
}
}
if (check_flag(original_settings.rx_gpio, settings.rx_gpio, ChangeFlags::RESTART)) {
valid_gpios = valid_gpios && EMSESP::system_.add_gpio(settings.rx_gpio, "UART Rx");
}
if (check_flag(original_settings.tx_gpio, settings.tx_gpio, ChangeFlags::RESTART)) {
valid_gpios = valid_gpios && EMSESP::system_.add_gpio(settings.tx_gpio, "UART Tx");
}
if (check_flag(original_settings.pbutton_gpio, settings.pbutton_gpio, ChangeFlags::BUTTON)) {
valid_gpios = valid_gpios && EMSESP::system_.add_gpio(settings.pbutton_gpio, "Button");
}
if (check_flag(original_settings.phy_type, settings.phy_type, ChangeFlags::RESTART)) {
// ETH has changed, so we need to check the ethernet pins. Only if ETH is being used.
if (settings.phy_type != PHY_type::PHY_TYPE_NONE) {
if (settings.eth_power != -1) {
// Ethernet Power -1 means disabled
valid_gpios = valid_gpios && EMSESP::system_.add_gpio(settings.eth_power, "Ethernet Power");
}
// all valid so far, now remove the ethernet pins from list, regardless of whether the GPIOs are valid or not
EMSESP::system_.remove_gpio(23); // MDC
EMSESP::system_.remove_gpio(18); // MDIO
EMSESP::system_.remove_gpio(0); // ETH.clock input
EMSESP::system_.remove_gpio(16); // ETH.clock output
EMSESP::system_.remove_gpio(17); // ETH.clock output
EMSESP::system_.remove_gpio(21); // I2C SDA
EMSESP::system_.remove_gpio(22); // I2C SCL
}
}
// check if the LED type, eth_phy_addr or eth_clock_mode have changed
check_flag(original_settings.led_type, settings.led_type, ChangeFlags::LED);
check_flag(original_settings.eth_phy_addr, settings.eth_phy_addr, ChangeFlags::RESTART);
check_flag(original_settings.eth_clock_mode, settings.eth_clock_mode, ChangeFlags::RESTART);
// tx_mode
settings.tx_mode = root["tx_mode"] | EMSESP_DEFAULT_TX_MODE;
check_flag(prev, settings.tx_mode, ChangeFlags::UART);
check_flag(original_settings.tx_mode, settings.tx_mode, ChangeFlags::UART);
// syslog
prev = settings.syslog_enabled;
settings.syslog_enabled = root["syslog_enabled"] | EMSESP_DEFAULT_SYSLOG_ENABLED;
check_flag(prev, settings.syslog_enabled, ChangeFlags::SYSLOG);
prev = settings.syslog_level;
check_flag(original_settings.syslog_enabled, settings.syslog_enabled, ChangeFlags::SYSLOG);
settings.syslog_level = root["syslog_level"] | EMSESP_DEFAULT_SYSLOG_LEVEL;
check_flag(prev, settings.syslog_level, ChangeFlags::SYSLOG);
prev = settings.syslog_mark_interval;
check_flag(original_settings.syslog_level, settings.syslog_level, ChangeFlags::SYSLOG);
settings.syslog_mark_interval = root["syslog_mark_interval"] | EMSESP_DEFAULT_SYSLOG_MARK_INTERVAL;
check_flag(prev, settings.syslog_mark_interval, ChangeFlags::SYSLOG);
prev = settings.syslog_port;
check_flag(original_settings.syslog_mark_interval, settings.syslog_mark_interval, ChangeFlags::SYSLOG);
settings.syslog_port = root["syslog_port"] | EMSESP_DEFAULT_SYSLOG_PORT;
check_flag(prev, settings.syslog_port, ChangeFlags::SYSLOG);
check_flag(original_settings.syslog_port, settings.syslog_port, ChangeFlags::SYSLOG);
#ifndef EMSESP_STANDALONE
String old_syslog_host = settings.syslog_host;
settings.syslog_host = root["syslog_host"] | EMSESP_DEFAULT_SYSLOG_HOST;
if (old_syslog_host != settings.syslog_host) {
settings.syslog_host = root["syslog_host"] | EMSESP_DEFAULT_SYSLOG_HOST;
if (original_settings.syslog_host != settings.syslog_host) {
add_flags(ChangeFlags::SYSLOG);
}
#endif
// temperature sensor
prev = settings.dallas_parasite;
settings.dallas_parasite = root["dallas_parasite"] | EMSESP_DEFAULT_DALLAS_PARASITE;
check_flag(prev, settings.dallas_parasite, ChangeFlags::TEMPERATURE_SENSOR);
check_flag(original_settings.dallas_parasite, settings.dallas_parasite, ChangeFlags::TEMPERATURE_SENSOR);
// shower
prev = settings.shower_timer;
settings.shower_timer = root["shower_timer"] | EMSESP_DEFAULT_SHOWER_TIMER;
check_flag(prev, settings.shower_timer, ChangeFlags::SHOWER);
prev = settings.shower_alert;
check_flag(original_settings.shower_timer, settings.shower_timer, ChangeFlags::SHOWER);
settings.shower_alert = root["shower_alert"] | EMSESP_DEFAULT_SHOWER_ALERT;
check_flag(prev, settings.shower_alert, ChangeFlags::SHOWER);
prev = settings.shower_alert_trigger;
check_flag(original_settings.shower_alert, settings.shower_alert, ChangeFlags::SHOWER);
settings.shower_alert_trigger = root["shower_alert_trigger"] | EMSESP_DEFAULT_SHOWER_ALERT_TRIGGER;
check_flag(prev, settings.shower_alert_trigger, ChangeFlags::SHOWER);
prev = settings.shower_min_duration;
check_flag(original_settings.shower_alert_trigger, settings.shower_alert_trigger, ChangeFlags::SHOWER);
settings.shower_min_duration = root["shower_min_duration"] | EMSESP_DEFAULT_SHOWER_MIN_DURATION;
check_flag(prev, settings.shower_min_duration, ChangeFlags::SHOWER);
prev = settings.shower_alert_coldshot;
check_flag(original_settings.shower_min_duration, settings.shower_min_duration, ChangeFlags::SHOWER);
settings.shower_alert_coldshot = root["shower_alert_coldshot"] | EMSESP_DEFAULT_SHOWER_ALERT_COLDSHOT;
check_flag(prev, settings.shower_alert_coldshot, ChangeFlags::SHOWER);
check_flag(original_settings.shower_alert_coldshot, settings.shower_alert_coldshot, ChangeFlags::SHOWER);
// led
prev = settings.hide_led;
// LED
settings.hide_led = root["hide_led"] | EMSESP_DEFAULT_HIDE_LED;
check_flag(prev, settings.hide_led, ChangeFlags::LED);
check_flag(original_settings.hide_led, settings.hide_led, ChangeFlags::LED);
// adc
prev = settings.analog_enabled;
settings.analog_enabled = root["analog_enabled"] | EMSESP_DEFAULT_ANALOG_ENABLED;
check_flag(prev, settings.analog_enabled, ChangeFlags::ANALOG_SENSOR);
check_flag(original_settings.analog_enabled, settings.analog_enabled, ChangeFlags::ANALOG_SENSOR);
//
// these need system restarts first before settings are activated...
//
prev = settings.telnet_enabled;
// telnet, ems bus id and low clock
settings.telnet_enabled = root["telnet_enabled"] | EMSESP_DEFAULT_TELNET_ENABLED;
check_flag(prev, settings.telnet_enabled, ChangeFlags::RESTART);
prev = settings.ems_bus_id;
check_flag(original_settings.telnet_enabled, settings.telnet_enabled, ChangeFlags::RESTART);
settings.ems_bus_id = root["ems_bus_id"] | EMSESP_DEFAULT_EMS_BUS_ID;
check_flag(prev, settings.ems_bus_id, ChangeFlags::RESTART);
prev = settings.low_clock;
check_flag(original_settings.ems_bus_id, settings.ems_bus_id, ChangeFlags::RESTART);
settings.low_clock = root["low_clock"];
check_flag(prev, settings.low_clock, ChangeFlags::RESTART);
check_flag(original_settings.low_clock, settings.low_clock, ChangeFlags::RESTART);
// Modbus settings
prev = settings.modbus_enabled;
settings.modbus_enabled = root["modbus_enabled"] | EMSESP_DEFAULT_MODBUS_ENABLED;
check_flag(prev, settings.modbus_enabled, ChangeFlags::RESTART);
prev = settings.modbus_port;
check_flag(original_settings.modbus_enabled, settings.modbus_enabled, ChangeFlags::RESTART);
settings.modbus_port = root["modbus_port"] | EMSESP_DEFAULT_MODBUS_PORT;
check_flag(prev, settings.modbus_port, ChangeFlags::RESTART);
prev = settings.modbus_max_clients;
check_flag(original_settings.modbus_port, settings.modbus_port, ChangeFlags::RESTART);
settings.modbus_max_clients = root["modbus_max_clients"] | EMSESP_DEFAULT_MODBUS_MAX_CLIENTS;
check_flag(prev, settings.modbus_max_clients, ChangeFlags::RESTART);
prev = settings.modbus_timeout;
check_flag(original_settings.modbus_max_clients, settings.modbus_max_clients, ChangeFlags::RESTART);
settings.modbus_timeout = root["modbus_timeout"] | EMSESP_DEFAULT_MODBUS_TIMEOUT;
check_flag(prev, settings.modbus_timeout, ChangeFlags::RESTART);
check_flag(original_settings.modbus_timeout, settings.modbus_timeout, ChangeFlags::RESTART);
//
// these may need mqtt restart to rebuild HA discovery topics
//
prev = settings.bool_format;
settings.bool_format = root["bool_format"] | EMSESP_DEFAULT_BOOL_FORMAT;
EMSESP::system_.bool_format(settings.bool_format);
if (Mqtt::ha_enabled()) {
check_flag(prev, settings.bool_format, ChangeFlags::MQTT);
check_flag(original_settings.bool_format, settings.bool_format, ChangeFlags::MQTT);
}
prev = settings.enum_format;
settings.enum_format = root["enum_format"] | EMSESP_DEFAULT_ENUM_FORMAT;
EMSESP::system_.enum_format(settings.enum_format);
if (Mqtt::ha_enabled()) {
check_flag(prev, settings.enum_format, ChangeFlags::MQTT);
check_flag(original_settings.enum_format, settings.enum_format, ChangeFlags::MQTT);
}
String old_locale = settings.locale;
settings.locale = root["locale"] | EMSESP_DEFAULT_LOCALE;
settings.locale = root["locale"] | EMSESP_DEFAULT_LOCALE;
EMSESP::system_.locale(settings.locale);
if (Mqtt::ha_enabled() && old_locale != settings.locale) {
if (Mqtt::ha_enabled() && original_settings.locale != settings.locale) {
add_flags(ChangeFlags::MQTT);
}
@@ -370,7 +266,7 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
settings.boiler_heatingoff = root["boiler_heatingoff"] | EMSESP_DEFAULT_BOILER_HEATINGOFF;
settings.remote_timeout = root["remote_timeout"] | EMSESP_DEFAULT_REMOTE_TIMEOUT;
settings.remote_timeout_enabled = root["remote_timeout_en"] | EMSESP_DEFAULT_REMOTE_TIMEOUT_EN;
emsesp::Roomctrl::set_timeout(settings.remote_timeout_enabled ? settings.remote_timeout : 0);
Roomctrl::set_timeout(settings.remote_timeout_enabled ? settings.remote_timeout : 0);
settings.fahrenheit = root["fahrenheit"];
EMSESP::system_.fahrenheit(settings.fahrenheit);
@@ -391,12 +287,24 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
if (EMSESP::system_.PSram() > 0) {
settings.weblog_buffer = root["weblog_buffer"] | EMSESP_DEFAULT_WEBLOG_BUFFER;
} else {
settings.weblog_buffer = root["weblog_buffer"] | 25;
settings.weblog_buffer = root["weblog_buffer"] | 25; // limit to 25 messages if no psram
}
// save the settings
if (get_flags() == WebSettings::ChangeFlags::RESTART) {
return StateUpdateResult::CHANGED_RESTART; // tell WebUI that a restart is needed
// save the setting internally, for reference later
EMSESP::system_.store_settings(settings);
// save the settings if changed from the webUI
// if we encountered an invalid GPIO, don't save settings and report the error
if (!valid_gpios) {
#if defined(EMSESP_DEBUG)
EMSESP::logger().debug("Warning: one or more GPIOs are invalid");
#endif
EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_INVALID_GPIO);
return StateUpdateResult::CHANGED; // save the settings anyway, without restart
}
if (has_flags(WebSettings::ChangeFlags::RESTART)) {
return StateUpdateResult::CHANGED_RESTART;
}
return StateUpdateResult::CHANGED;
@@ -440,7 +348,7 @@ void WebSettingsService::onUpdate() {
}
if (WebSettings::has_flags(WebSettings::ChangeFlags::MQTT)) {
emsesp::Mqtt::reset_mqtt(); // reload MQTT, init HA etc
Mqtt::reset_mqtt(); // reload MQTT, init HA etc
}
WebSettings::reset_flags();
@@ -456,7 +364,7 @@ void WebSettingsService::save() {
_fsPersistence.writeToFS();
}
// build the json profile to send back
// send the board profile as JSON
void WebSettingsService::board_profile(AsyncWebServerRequest * request) {
if (request->hasParam("boardProfile")) {
std::string board_profile = request->getParam("boardProfile")->value().c_str();
@@ -464,7 +372,8 @@ void WebSettingsService::board_profile(AsyncWebServerRequest * request) {
auto * response = new AsyncJsonResponse(false);
JsonObject root = response->getRoot();
std::vector<int8_t> data; // led, dallas, rx, tx, button, phy_type, eth_power, eth_phy_addr, eth_clock_mode, led_type
// 0=led, 1=dallas, 2=rx, 3=tx, 4=button, 5=phy_type, 6=eth_power, 7=eth_phy_addr, 8=eth_clock_mode, 9=led_type
std::vector<int8_t> data;
(void)System::load_board_profile(data, board_profile);
root["board_profile"] = board_profile;
root["led_gpio"] = data[0];
@@ -487,4 +396,124 @@ void WebSettingsService::board_profile(AsyncWebServerRequest * request) {
request->send(response);
}
// loads the board profile to set the gpios
// if the board profile is not found, or default, it will try to autodetect the board profile
void WebSettings::set_board_profile(WebSettings & settings) {
// The optional NVS boot value has priority and overrides any board_profile setting.
// This is only done for BBQKees boards
// Note 1: we never set the NVS boot value in the code - this is done on initial pre-loading
// Note 2: The board profile is dynamically changed for the session, but the value in the settings file on the FS remains untouched
if (EMSESP::system_.getBBQKeesGatewayDetails(FUSE_VALUE::MFG).startsWith("BBQKees")) {
String bbq_board = EMSESP::system_.getBBQKeesGatewayDetails(FUSE_VALUE::BOARD);
if (!bbq_board.isEmpty()) {
#if defined(EMSESP_DEBUG)
EMSESP::logger().info("Overriding board profile with fuse value %s", bbq_board.c_str());
#endif
settings.board_profile = bbq_board;
}
}
// load the board profile into the data vector
// 0=led, 1=dallas, 2=rx, 3=tx, 4=button, 5=phy_type, 6=eth_power, 7=eth_phy_addr, 8=eth_clock_mode, 9=led_type
std::vector<int8_t> data(10, 255); // initialize with 255 for all values
if (settings.board_profile != "default") {
if (!System::load_board_profile(data, settings.board_profile.c_str())) {
#if defined(EMSESP_DEBUG)
EMSESP::logger().debug("Unable to identify board profile %s", settings.board_profile.c_str());
#endif
settings.board_profile = "default"; // can't find profile, fallback to "default"
}
}
// we still don't have a valid board profile. Let's see if we can determine one from the build config or hardware
if (settings.board_profile == "default") {
#if defined(EMSESP_DEBUG)
EMSESP::logger().debug("Autodetecting board profile");
#endif
#if CONFIG_IDF_TARGET_ESP32
// check for no PSRAM, could be a E32 or S32?
if (!ESP.getPsramSize()) {
#if ESP_ARDUINO_VERSION_MAJOR < 3
if (ETH.begin(1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) {
#else
if (ETH.begin(ETH_PHY_LAN8720, 1, 23, 18, 16, ETH_CLOCK_GPIO0_IN)) {
#endif
settings.board_profile = "E32"; // Ethernet without PSRAM
} else {
settings.board_profile = "S32"; // ESP32 standard WiFi without PSRAM
}
} else {
// check for boards with PSRAM, could be a E32V2 otherwise default back to the S32
#if ESP_ARDUINO_VERSION_MAJOR < 3
if (ETH.begin(0, 15, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_OUT)) {
#else
if (ETH.begin(ETH_PHY_LAN8720, 0, 23, 18, 15, ETH_CLOCK_GPIO0_OUT)) {
#endif
if (analogReadMilliVolts(39) > 700) { // core voltage > 2.6V
settings.board_profile = "E32V2_2"; // Ethernet, PSRAM, internal sensors
} else {
settings.board_profile = "E32V2"; // Ethernet and PSRAM
}
} else {
settings.board_profile = "S32"; // ESP32 standard WiFi with PSRAM
}
}
// override if we know the target from the build config like C3, S2, S3 etc..
#elif CONFIG_IDF_TARGET_ESP32C3
settings.board_profile = "C3MINI";
#elif CONFIG_IDF_TARGET_ESP32S2
settings.board_profile = "S2MINI";
#elif CONFIG_IDF_TARGET_ESP32S3
settings.board_profile = "S32S3"; // BBQKees Gateway S3
#endif
// apply the new board profile setting
System::load_board_profile(data, settings.board_profile.c_str());
}
EMSESP::logger().info("Loaded board profile: %s", settings.board_profile.c_str());
// apply the new board profile settings
// 0=led, 1=dallas, 2=rx, 3=tx, 4=button, 5=phy_type, 6=eth_power, 7=eth_phy_addr, 8=eth_clock_mode, 9=led_type
settings.led_gpio = data[0]; // LED GPIO
settings.dallas_gpio = data[1]; // Dallas GPIO
settings.rx_gpio = data[2]; // UART Rx GPIO
settings.tx_gpio = data[3]; // UART Tx GPIO
settings.pbutton_gpio = data[4]; // Button GPIO
settings.phy_type = data[5]; // PHY Type
settings.eth_power = data[6]; // Ethernet Power GPIO
settings.eth_phy_addr = data[7]; // Ethernet PHY Address
settings.eth_clock_mode = data[8]; // Ethernet Clock Mode
settings.led_type = data[9]; // LED Type
}
// returns true if the value was changed
bool WebSettings::check_flag(int prev_v, int new_v, uint8_t flag) {
if (prev_v != new_v) {
add_flags(flag);
#if defined(EMSESP_DEBUG)
// EMSESP::logger().debug("check_flag: flag %d, prev_v=%d, new_v=%d", flag, prev_v, new_v);
#endif
return true;
}
return false;
}
void WebSettings::add_flags(uint8_t flags) {
flags_ |= flags;
}
bool WebSettings::has_flags(uint8_t flags) {
return (flags_ & flags) == flags;
}
void WebSettings::reset_flags() {
flags_ = ChangeFlags::NONE;
}
uint8_t WebSettings::get_flags() {
return flags_;
}
} // namespace emsesp