mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-07 08:19:52 +03:00
standardizing is_valid_gpio
This commit is contained in:
@@ -106,7 +106,7 @@ board_build.filesystem = littlefs
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
bblanchon/ArduinoJson @ 7.4.2
|
bblanchon/ArduinoJson @ 7.4.2
|
||||||
ESP32Async/AsyncTCP @ 3.4.9
|
ESP32Async/AsyncTCP @ 3.4.9
|
||||||
ESP32Async/ESPAsyncWebServer @ 3.8.1
|
ESP32Async/ESPAsyncWebServer @ 3.9.0
|
||||||
https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8
|
https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -187,8 +187,8 @@ void AnalogSensor::reload(bool get_nvs) {
|
|||||||
for (auto & sensor : sensors_) {
|
for (auto & sensor : sensors_) {
|
||||||
sensor.ha_registered = false; // force HA configs to be re-created
|
sensor.ha_registered = false; // force HA configs to be re-created
|
||||||
|
|
||||||
// first check if the GPIO is valid. If not, force set it to disabled
|
// first check if the GPIO is valid. If not, force set the sensor to disabled, but don't remove it
|
||||||
if (!System::is_valid_gpio(sensor.gpio())) {
|
if (!EMSESP::system_.is_valid_gpio(sensor.gpio())) {
|
||||||
LOG_WARNING("Bad GPIO %d for Sensor %s. Disabling.", sensor.gpio(), sensor.name().c_str());
|
LOG_WARNING("Bad GPIO %d for Sensor %s. Disabling.", sensor.gpio(), sensor.name().c_str());
|
||||||
sensor.set_type(AnalogType::NOTUSED); // set disabled
|
sensor.set_type(AnalogType::NOTUSED); // set disabled
|
||||||
continue; // skip this loop pass
|
continue; // skip this loop pass
|
||||||
@@ -542,7 +542,7 @@ bool AnalogSensor::update(uint8_t gpio, std::string & name, double offset, doubl
|
|||||||
|
|
||||||
// return false if it's an invalid GPIO, an error will show in WebUI
|
// return false if it's an invalid GPIO, an error will show in WebUI
|
||||||
// and reported as an error in the log
|
// and reported as an error in the log
|
||||||
return System::is_valid_gpio(gpio);
|
return EMSESP::system_.is_valid_gpio(gpio);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check to see if values have been updated
|
// check to see if values have been updated
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ void EMSESP::uart_init() {
|
|||||||
EMSuart::stop();
|
EMSuart::stop();
|
||||||
|
|
||||||
// don't start UART if we have invalid GPIOs
|
// don't start UART if we have invalid GPIOs
|
||||||
if (System::is_valid_gpio(rx_gpio) && System::is_valid_gpio(tx_gpio)) {
|
if (EMSESP::system_.is_valid_gpio(rx_gpio) && EMSESP::system_.is_valid_gpio(tx_gpio)) {
|
||||||
EMSuart::start(tx_mode, rx_gpio, tx_gpio); // start UART
|
EMSuart::start(tx_mode, rx_gpio, tx_gpio); // start UART
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING("Invalid UART Rx/Tx GPIOs. Check config.");
|
LOG_WARNING("Invalid UART Rx/Tx GPIOs. Check config.");
|
||||||
|
|||||||
@@ -448,31 +448,9 @@ void System::reload_settings() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for valid ESP32 pins. This is very dependent on which ESP32 board is being used.
|
// check for valid ESP32 pins
|
||||||
// Typically you can't use 1, 6-11, 20, 24, 28-31 and 40+
|
bool System::is_valid_gpio(uint8_t pin) {
|
||||||
// we allow 0 as it has a special function on the NodeMCU apparently
|
return std::find(valid_gpio_list().begin(), valid_gpio_list().end(), pin) != valid_gpio_list().end();
|
||||||
// See https://diyprojects.io/esp32-how-to-use-gpio-digital-io-arduino-code/#.YFpVEq9KhjG
|
|
||||||
// and https://nodemcu.readthedocs.io/en/dev-esp32/modules/gpio/
|
|
||||||
bool System::is_valid_gpio(uint8_t pin, bool has_psram) {
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32 || defined(EMSESP_STANDALONE)
|
|
||||||
if ((pin == 1) || (pin >= 6 && pin <= 11) || (pin == 20) || (pin == 24) || (pin >= 28 && pin <= 31) || (pin > 40)
|
|
||||||
|| ((EMSESP::system_.PSram() > 0 || has_psram) && pin >= 16 && pin <= 17)) {
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
|
||||||
if ((pin >= 19 && pin <= 20) || (pin >= 22 && pin <= 32) || (pin > 40)) {
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
|
||||||
// https://www.wemos.cc/en/latest/c3/c3_mini.html
|
|
||||||
if ((pin >= 11 && pin <= 19) || (pin > 21)) {
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
|
||||||
if ((pin >= 19 && pin <= 20) || (pin >= 22 && pin <= 37) || (pin >= 39 && pin <= 42) || (pin > 48)) {
|
|
||||||
#endif
|
|
||||||
return false; // bad pin
|
|
||||||
}
|
|
||||||
|
|
||||||
// extra check for pins 21 and 22 (I2C) when ethernet is onboard
|
|
||||||
if ((EMSESP::system_.ethernet_connected() || EMSESP::system_.phy_type_ != PHY_type::PHY_TYPE_NONE) && (pin >= 21 && pin <= 22)) {
|
|
||||||
return false; // bad pin
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts up the UART Serial bridge
|
// Starts up the UART Serial bridge
|
||||||
@@ -2320,30 +2298,60 @@ uint8_t System::systemStatus() {
|
|||||||
return systemStatus_;
|
return systemStatus_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// take a string range like "6-11, 1, 23, 24-48" which has optional ranges and single values convert to a vector of ints
|
||||||
|
std::vector<uint8_t> System::string_range_to_vector(const std::string & range) {
|
||||||
|
std::vector<uint8_t> valid_gpios;
|
||||||
|
std::string::size_type pos = 0;
|
||||||
|
std::string::size_type prev = 0;
|
||||||
|
while ((pos = range.find(',', prev)) != std::string::npos) {
|
||||||
|
valid_gpios.push_back(std::stoi(range.substr(prev, pos - prev)));
|
||||||
|
prev = pos + 1;
|
||||||
|
}
|
||||||
|
valid_gpios.push_back(std::stoi(range.substr(prev)));
|
||||||
|
return valid_gpios;
|
||||||
|
}
|
||||||
|
|
||||||
// return the list of valid GPIOs
|
// return the list of valid GPIOs
|
||||||
std::vector<uint8_t> System::valid_gpio_list() const {
|
// note: we do not allow 0, which is used sometimes to indicate a disabled pin
|
||||||
// get free gpios based on board type
|
std::vector<uint8_t> System::valid_gpio_list() {
|
||||||
|
// get free gpios based on board/platform type
|
||||||
#if CONFIG_IDF_TARGET_ESP32C3
|
#if CONFIG_IDF_TARGET_ESP32C3
|
||||||
std::vector<uint8_t> valid_gpios = {11, 19, 21};
|
// https://www.wemos.cc/en/latest/c3/c3_mini.html
|
||||||
|
std::vector<uint8_t> valid_gpios = string_range_to_vector("11-19, 21"); // can go higher than 21 on some boards
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||||
std::vector<uint8_t> valid_gpios = {19, 20, 22, 32, 40};
|
std::vector<uint8_t> valid_gpios = string_range_to_vector("19-20, 22-32, 40");
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||||
std::vector<uint8_t> valid_gpios = {19, 20, 22, 37, 39, 42, 48};
|
std::vector<uint8_t> valid_gpios = string_range_to_vector("19-20, 22-37, 39-42, 48");
|
||||||
#elif CONFIG_IDF_TARGET_ESP32
|
#elif CONFIG_IDF_TARGET_ESP32 || defined(EMSESP_STANDALONE)
|
||||||
std::vector<uint8_t> valid_gpios = {6, 11, 20, 24, 28, 31, 1, 40};
|
std::vector<uint8_t> valid_gpios = string_range_to_vector("1, 6-11, 16-17, 20, 24, 28-31, 40");
|
||||||
#else
|
#else
|
||||||
std::vector<uint8_t> valid_gpios = {};
|
std::vector<uint8_t> valid_gpios = {};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_IDF_TARGET_ESP32
|
||||||
|
// if psram is enabled remove pins 16 and 17 from the list
|
||||||
|
if (ESP.getPsramSize() > 0) {
|
||||||
|
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), 16), valid_gpios.end());
|
||||||
|
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), 17), valid_gpios.end());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// if ethernet is enabled, remove pins 21 and 22 (I2C)
|
||||||
|
if ((EMSESP::system_.ethernet_connected() || EMSESP::system_.phy_type_ != PHY_type::PHY_TYPE_NONE)) {
|
||||||
|
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), 21), valid_gpios.end());
|
||||||
|
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), 22), valid_gpios.end());
|
||||||
|
}
|
||||||
|
|
||||||
// filter out GPIOs already used in application settings
|
// filter out GPIOs already used in application settings
|
||||||
for (const auto & gpio : valid_gpios) {
|
for (const auto & gpio : valid_gpios) {
|
||||||
if (gpio == pbutton_gpio_ || gpio == led_gpio_ || gpio == dallas_gpio_ || gpio == rx_gpio_ || gpio == tx_gpio_) {
|
if (gpio == EMSESP::system_.pbutton_gpio_ || gpio == EMSESP::system_.led_gpio_ || gpio == EMSESP::system_.dallas_gpio_
|
||||||
|
|| gpio == EMSESP::system_.rx_gpio_ || gpio == EMSESP::system_.tx_gpio_) {
|
||||||
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), gpio), valid_gpios.end());
|
valid_gpios.erase(std::remove(valid_gpios.begin(), valid_gpios.end(), gpio), valid_gpios.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter out GPIOs already used in analog sensors, if enabled
|
// filter out GPIOs already used in analog sensors, if enabled
|
||||||
if (analog_enabled_) {
|
if (EMSESP::system_.analog_enabled_) {
|
||||||
for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
|
for (const auto & sensor : EMSESP::analogsensor_.sensors()) {
|
||||||
if (std::find(valid_gpios.begin(), valid_gpios.end(), sensor.gpio()) != valid_gpios.end()) {
|
if (std::find(valid_gpios.begin(), valid_gpios.end(), sensor.gpio()) != valid_gpios.end()) {
|
||||||
valid_gpios.erase(std::find(valid_gpios.begin(), valid_gpios.end(), sensor.gpio()));
|
valid_gpios.erase(std::find(valid_gpios.begin(), valid_gpios.end(), sensor.gpio()));
|
||||||
|
|||||||
@@ -137,12 +137,10 @@ class System {
|
|||||||
void systemStatus(uint8_t status_code);
|
void systemStatus(uint8_t status_code);
|
||||||
uint8_t systemStatus();
|
uint8_t systemStatus();
|
||||||
|
|
||||||
std::vector<uint8_t> valid_gpio_list() const;
|
|
||||||
|
|
||||||
static void extractSettings(const char * filename, const char * section, JsonObject output);
|
static void extractSettings(const char * filename, const char * section, JsonObject output);
|
||||||
static bool saveSettings(const char * filename, const char * section, JsonObject input);
|
static bool saveSettings(const char * filename, const char * section, JsonObject input);
|
||||||
|
|
||||||
static bool is_valid_gpio(uint8_t pin, bool has_psram = false);
|
bool is_valid_gpio(uint8_t pin);
|
||||||
static bool load_board_profile(std::vector<int8_t> & data, const std::string & board_profile);
|
static bool load_board_profile(std::vector<int8_t> & data, const std::string & board_profile);
|
||||||
|
|
||||||
static bool readCommand(const char * data);
|
static bool readCommand(const char * data);
|
||||||
@@ -305,6 +303,7 @@ class System {
|
|||||||
uint32_t PSram() {
|
uint32_t PSram() {
|
||||||
return psram_;
|
return psram_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t appFree() {
|
uint32_t appFree() {
|
||||||
return appfree_;
|
return appfree_;
|
||||||
}
|
}
|
||||||
@@ -338,6 +337,8 @@ class System {
|
|||||||
test_set_all_active_ = n;
|
test_set_all_active_ = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::vector<uint8_t> valid_gpio_list();
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
|
#if CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S2
|
||||||
float temperature() {
|
float temperature() {
|
||||||
return temperature_;
|
return temperature_;
|
||||||
@@ -383,6 +384,8 @@ class System {
|
|||||||
void led_monitor();
|
void led_monitor();
|
||||||
void system_check();
|
void system_check();
|
||||||
|
|
||||||
|
static std::vector<uint8_t> string_range_to_vector(const std::string & range);
|
||||||
|
|
||||||
int8_t wifi_quality(int8_t dBm);
|
int8_t wifi_quality(int8_t dBm);
|
||||||
|
|
||||||
uint8_t healthcheck_ = HEALTHCHECK_NO_NETWORK | HEALTHCHECK_NO_BUS; // start with all flags set, no wifi and no ems bus connection
|
uint8_t healthcheck_ = HEALTHCHECK_NO_NETWORK | HEALTHCHECK_NO_BUS; // start with all flags set, no wifi and no ems bus connection
|
||||||
|
|||||||
@@ -90,12 +90,6 @@ 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()
|
// 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;
|
settings.version = root["version"] | EMSESP_DEFAULT_VERSION;
|
||||||
|
|
||||||
#ifndef EMSESP_STANDALONE
|
|
||||||
bool psram = ESP.getPsramSize() > 0; // System::PSram() is initialized later
|
|
||||||
#else
|
|
||||||
bool psram = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(EMSESP_DEBUG)
|
#if defined(EMSESP_DEBUG)
|
||||||
EMSESP::logger().debug("NVS boot value=[%s], board profile=[%s], EMSESP_DEFAULT_BOARD_PROFILE=[%s]",
|
EMSESP::logger().debug("NVS boot value=[%s], board profile=[%s], EMSESP_DEFAULT_BOARD_PROFILE=[%s]",
|
||||||
EMSESP::nvs_.getString("boot").c_str(),
|
EMSESP::nvs_.getString("boot").c_str(),
|
||||||
@@ -143,8 +137,8 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
// check valid pins in this board profile
|
// check valid pins in this board profile
|
||||||
if (!System::is_valid_gpio(data[0], psram) || !System::is_valid_gpio(data[1], psram) || !System::is_valid_gpio(data[2], psram)
|
if (!EMSESP::system_.is_valid_gpio(data[0]) || !EMSESP::system_.is_valid_gpio(data[1]) || !EMSESP::system_.is_valid_gpio(data[2])
|
||||||
|| !System::is_valid_gpio(data[3], psram) || !System::is_valid_gpio(data[4], psram) || !System::is_valid_gpio(data[6], psram)) {
|
|| !EMSESP::system_.is_valid_gpio(data[3]) || !EMSESP::system_.is_valid_gpio(data[4]) || !EMSESP::system_.is_valid_gpio(data[6])) {
|
||||||
settings.board_profile = "default"; // reset to factory default
|
settings.board_profile = "default"; // reset to factory default
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -161,8 +155,8 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) {
|
|||||||
#if defined(EMSESP_STANDALONE)
|
#if defined(EMSESP_STANDALONE)
|
||||||
settings.board_profile = "S32";
|
settings.board_profile = "S32";
|
||||||
#elif CONFIG_IDF_TARGET_ESP32
|
#elif CONFIG_IDF_TARGET_ESP32
|
||||||
// check for no PSRAM, could be a E32 or S32
|
// check for no PSRAM, could be a E32 or S32?
|
||||||
if (!psram) {
|
if (!ESP.getPsramSize()) {
|
||||||
#if ESP_ARDUINO_VERSION_MAJOR < 3
|
#if ESP_ARDUINO_VERSION_MAJOR < 3
|
||||||
if (ETH.begin(1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) {
|
if (ETH.begin(1, 16, 23, 18, ETH_PHY_LAN8720, ETH_CLOCK_GPIO0_IN)) {
|
||||||
#else
|
#else
|
||||||
|
|||||||
Reference in New Issue
Block a user