Skip to content

Commit

Permalink
Merge pull request letscontrolit#5022 from TD-er/bugfix/HWCDC_crash
Browse files Browse the repository at this point in the history
[HWCDC] Fix stability issues and bootloops on C3/C6
  • Loading branch information
TD-er authored Apr 13, 2024
2 parents dabd07e + 1b62590 commit 366041a
Show file tree
Hide file tree
Showing 18 changed files with 186 additions and 90 deletions.
39 changes: 22 additions & 17 deletions lib/ESPEasySerial/Port_ESPEasySerial_USB_HWCDC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,40 +58,46 @@ Port_ESPEasySerial_USB_HWCDC_t::Port_ESPEasySerial_USB_HWCDC_t(const ESPEasySeri

// USB.begin();
if (_hwcdc_serial != nullptr) {
_config.rxBuffSize = _hwcdc_serial->setRxBufferSize(_config.rxBuffSize);
_config.txBuffSize = _hwcdc_serial->setRxBufferSize(_config.txBuffSize);
// _hwcdc_serial->end();

// _config.rxBuffSize = _hwcdc_serial->setRxBufferSize(_config.rxBuffSize);
// _config.txBuffSize = _hwcdc_serial->setTxBufferSize(_config.txBuffSize);

// See: https://github.com/espressif/arduino-esp32/issues/9043
_hwcdc_serial->setTxTimeoutMs(0); // sets no timeout when trying to write to USB HW CDC
// _hwcdc_serial->setTxTimeoutMs(0); // sets no timeout when trying to write to USB HW CDC

_hwcdc_serial->begin();
// _hwcdc_serial->begin();

// _hwcdc_serial->onEvent(hwcdcEventCallback);
}
}

Port_ESPEasySerial_USB_HWCDC_t::~Port_ESPEasySerial_USB_HWCDC_t() {}
Port_ESPEasySerial_USB_HWCDC_t::~Port_ESPEasySerial_USB_HWCDC_t() {
if (_hwcdc_serial != nullptr) {
// _hwcdc_serial->end();
}
}

void Port_ESPEasySerial_USB_HWCDC_t::begin(unsigned long baud)
{
_config.baud = baud;
/*
if (_hwcdc_serial != nullptr) {
_config.rxBuffSize = _hwcdc_serial->setRxBufferSize(_config.rxBuffSize);
_config.txBuffSize = _hwcdc_serial->setRxBufferSize(_config.txBuffSize);
_hwcdc_serial->begin();
delay(10);
_hwcdc_serial->onEvent(hwcdcEventCallback);
delay(1);
}
*/

if (_hwcdc_serial != nullptr) {
_config.rxBuffSize = _hwcdc_serial->setRxBufferSize(_config.rxBuffSize);
_config.txBuffSize = _hwcdc_serial->setTxBufferSize(_config.txBuffSize);
_hwcdc_serial->begin();
delay(10);

// _hwcdc_serial->onEvent(hwcdcEventCallback);
delay(1);
}
}

void Port_ESPEasySerial_USB_HWCDC_t::end() {
// Disabled for now
// See: https://github.com/espressif/arduino-esp32/issues/8224
if (_hwcdc_serial != nullptr) {
_hwcdc_serial->end();
// _hwcdc_serial->end();
}
}

Expand Down Expand Up @@ -204,5 +210,4 @@ bool Port_ESPEasySerial_USB_HWCDC_t::setRS485Mode(int8_t rtsPin, bool enableColl
return false;
}


#endif // if USES_HWCDC
8 changes: 2 additions & 6 deletions lib/ESPEasySerial/Port_ESPEasySerial_USB_HWCDC.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class Port_ESPEasySerial_USB_HWCDC_t : public Port_ESPEasySerial_base {
public:

Port_ESPEasySerial_USB_HWCDC_t(const ESPEasySerialConfig& config);
explicit Port_ESPEasySerial_USB_HWCDC_t(const ESPEasySerialConfig& config);

virtual ~Port_ESPEasySerial_USB_HWCDC_t();

Expand Down Expand Up @@ -44,11 +44,7 @@ class Port_ESPEasySerial_USB_HWCDC_t : public Port_ESPEasySerial_base {

private:

# if ARDUINO_USB_CDC_ON_BOOT // Serial used for USB CDC
HWCDC *_hwcdc_serial = &Serial;
# else // if ARDUINO_USB_CDC_ON_BOOT
HWCDC *_hwcdc_serial = &USBSerial;
# endif // if ARDUINO_USB_CDC_ON_BOOT
HWCDC *_hwcdc_serial= nullptr;
};


Expand Down
2 changes: 2 additions & 0 deletions lib/ImprovWiFi/src/ImprovTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ enum Error : uint8_t {
ERROR_UNKNOWN_RPC = 0x02,
ERROR_UNABLE_TO_CONNECT = 0x03,
ERROR_NOT_AUTHORIZED = 0x04,
ERROR_INVALID_CHECKSUM = 0x05,
ERROR_EMPTY_SSID = 0x06,
ERROR_UNKNOWN = 0xFF,
};

Expand Down
21 changes: 14 additions & 7 deletions lib/ImprovWiFi/src/ImprovWiFiLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ bool ImprovWiFi::onCommandCallback(ImprovTypes::ImprovCommand cmd)
{
if (cmd.ssid.empty())
{
setError(ImprovTypes::Error::ERROR_INVALID_RPC);
setError(ImprovTypes::Error::ERROR_EMPTY_SSID);
break;
}

Expand Down Expand Up @@ -298,17 +298,19 @@ ImprovTypes::ParseState ImprovWiFi::parseImprovSerial(size_t position, uint8_t b

if (position == (8u + data_len + 1u))
{
/*
if (computeChecksum(buffer, position - 1) != byte)
{
_position = 0;
onErrorCallback(ImprovTypes::Error::ERROR_INVALID_RPC);
onErrorCallback(ImprovTypes::Error::ERROR_INVALID_CHECKSUM);
return ImprovTypes::ParseState::INVALID;
}
*/

if (type == ImprovTypes::ImprovSerialType::TYPE_RPC)
{
_position = 0;
auto command = parseImprovData(&buffer[9], data_len, false);
auto command = parseImprovData(&buffer[9], data_len + 1, false);
return onCommandCallback(command) ? ImprovTypes::ParseState::VALID_COMPLETE : ImprovTypes::ParseState::INVALID;
}
}
Expand All @@ -332,19 +334,23 @@ ImprovTypes::ImprovCommand ImprovWiFi::parseImprovData(const uint8_t *data, size
}
const ImprovTypes::Command command = (ImprovTypes::Command)data[0];
const uint8_t data_length = data[1];
const uint8_t data_start = 2;
const size_t data_end = data_start + data_length;

// if (data_end >= length)
if (data_length != (length - 2 - check_checksum))
{
return improv_command;
// return improv_command;
}

if (check_checksum)
{
const uint8_t checksum = data[length - 1];
const uint8_t checksum = data[data_end];

if (computeChecksum(data, length - 1) != checksum)
if (computeChecksum(data, data_end - 1) != checksum)
{
improv_command.command = ImprovTypes::Command::BAD_CHECKSUM;
setError(ImprovTypes::Error::ERROR_INVALID_CHECKSUM);
return improv_command;
}
}
Expand All @@ -363,7 +369,7 @@ ImprovTypes::ImprovCommand ImprovWiFi::parseImprovData(const uint8_t *data, size
const size_t pass_start = ssid_end + 1;
const size_t pass_end = pass_start + pass_length;

if (pass_end >= length) {
if (pass_end > length) {
return improv_command;
}

Expand Down Expand Up @@ -394,6 +400,7 @@ void ImprovWiFi::setError(ImprovTypes::Error error)
const std::vector<uint8_t> response = { error };

send(ImprovTypes::TYPE_ERROR_STATE, response);
onErrorCallback(error);
}

void ImprovWiFi::sendResponse(const std::vector<uint8_t>& response)
Expand Down
1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extra_configs =

;default_envs = normal_ESP32_4M
default_envs = max_ESP32_16M8M_LittleFS
;default_envs = normal_ESP32c6_4M316k_LittleFS_CDC
; default_envs = custom_ESP8266_4M1M

;default_envs = normal_ESP8266_4M1M
Expand Down
13 changes: 9 additions & 4 deletions platformio_core_defs.ini
Original file line number Diff line number Diff line change
Expand Up @@ -208,19 +208,24 @@ lib_ignore =

; ESP_IDF 5.1
[core_esp32_IDF5_1__3_0_0]
;platform = https://github.com/Jason2866/platform-espressif32.git
platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.02.10/platform-espressif32.zip
;platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.02.10/platform-espressif32.zip
;platform_packages =
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2119/framework-arduinoespressif32-release_v5.1-a28d368.zip
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2180/framework-arduinoespressif32-all-release_v5.1-735d740.zip
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2189/framework-arduinoespressif32-all-release_v5.1-be1a568.zip
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2189/framework-arduinoespressif32-all-release_v5.1-be1a568.zip
; Build with HWCDC fix.
;platform = https://github.com/Jason2866/platform-espressif32.git
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2261/framework-arduinoespressif32-all-release_v5.1-11140aa.zip
platform = https://github.com/tasmota/platform-espressif32/releases/download/2024.04.11/platform-espressif32.zip
;platform_packages =
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2286/framework-arduinoespressif32-all-release_v5.1-11140aa.zip
build_flags = -DESP32_STAGE
-DESP_IDF_VERSION_MAJOR=5
-DLIBRARIES_NO_LOG=1
-DDISABLE_SC16IS752_SPI
-DCONFIG_PM_ENABLE
; -DCONFIG_LWIP_L2_TO_L3_COPY
-DETH_SPI_SUPPORTS_NO_IRQ=1
; -DETH_SPI_SUPPORTS_NO_IRQ=1
-DCONFIG_FREERTOS_USE_TICKLESS_IDLE=1
-DCONFIG_FREERTOS_IDLE_TIME_BEFORE_SLEEP=3
-DNEOPIXEL_ESP32_RMT_DEFAULT
Expand Down
2 changes: 1 addition & 1 deletion platformio_esp32_solo1.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ build_unflags = ${esp32_base.build_unflags}
; IDF 5.1.2
[esp32_solo1_common_LittleFS]
extends = esp32_base_idf5
platform_packages = framework-arduino-solo1 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2038/framework-arduinoespressif32-solo1-release_v5.1-246cad0.zip
;platform_packages = framework-arduino-solo1 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2038/framework-arduinoespressif32-solo1-release_v5.1-246cad0.zip
build_flags = ${esp32_base_idf5.build_flags}
-DFEATURE_ARDUINO_OTA=1
-DUSE_LITTLEFS
Expand Down
11 changes: 10 additions & 1 deletion src/src/DataStructs/EthernetEventData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,24 +176,33 @@ void EthernetEventData_t::markDisconnect() {
}
lastConnectMoment.clear();
processedDisconnect = false;
#if ESP_IDF_VERSION_MAJOR >= 5
WiFi.STA.setDefault();
#endif
}

void EthernetEventData_t::markConnected() {
lastConnectMoment.setNow();
processedConnect = false;
#if ESP_IDF_VERSION_MAJOR >= 5
ETH.setDefault();
#endif

#if FEATURE_USE_IPV6
ETH.enableIPv6(true);
/*
// workaround for the race condition in LWIP, see https://github.com/espressif/arduino-esp32/pull/9016#discussion_r1451774885
{
uint32_t i = 5; // try 5 times only
while (esp_netif_create_ip6_linklocal(get_esp_interface_netif(ESP_IF_ETH)) != ESP_OK) {
while (esp_netif_create_ip6_linklocal(ETH.netif()) != ESP_OK) {
delay(1);
if (i-- == 0) {
// addLog(LOG_LEVEL_ERROR, ">>>> HELP");
break;
}
}
}
*/
#endif
}

Expand Down
20 changes: 10 additions & 10 deletions src/src/DataStructs_templ/SettingsStruct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -882,24 +882,24 @@ spi_host_device_t SettingsStruct_tmpl<N_TASKS>::getSPI_host() const
switch (SPI_selection) {
case SPI_Options_e::Vspi_Fspi:
{
#if CONFIG_IDF_TARGET_ESP32
return static_cast<spi_host_device_t>(VSPI);
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
return static_cast<spi_host_device_t>(FSPI_HOST);
#else
return static_cast<spi_host_device_t>(FSPI);
return static_cast<spi_host_device_t>(VSPI_HOST);
#endif
}
#ifdef ESP32_CLASSIC
case SPI_Options_e::Hspi:
{
return static_cast<spi_host_device_t>(HSPI);
return static_cast<spi_host_device_t>(HSPI_HOST);
}
#endif
case SPI_Options_e::UserDefined:
{
#if CONFIG_IDF_TARGET_ESP32
return static_cast<spi_host_device_t>(VSPI);
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
return static_cast<spi_host_device_t>(FSPI_HOST);
#else
return static_cast<spi_host_device_t>(FSPI);
return static_cast<spi_host_device_t>(VSPI_HOST);
#endif
}
case SPI_Options_e::None:
Expand All @@ -908,10 +908,10 @@ spi_host_device_t SettingsStruct_tmpl<N_TASKS>::getSPI_host() const

}
#if ESP_IDF_VERSION_MAJOR < 5
#if CONFIG_IDF_TARGET_ESP32
return static_cast<spi_host_device_t>(VSPI);
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
return static_cast<spi_host_device_t>(FSPI_HOST);
#else
return static_cast<spi_host_device_t>(FSPI);
return static_cast<spi_host_device_t>(VSPI_HOST);
#endif
#else
return spi_host_device_t::SPI_HOST_MAX;
Expand Down
30 changes: 22 additions & 8 deletions src/src/ESPEasyCore/ESPEasyEth_ProcessEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# include "../Globals/NetworkState.h"
# include "../Globals/Settings.h"

# include "../Helpers/LongTermTimer.h"
# include "../Helpers/Network.h"
# include "../Helpers/Networking.h"
# include "../Helpers/PeriodicalActions.h"
Expand Down Expand Up @@ -164,14 +165,19 @@ void processEthernetGotIP() {
IPAddress dns0 = ETH.dnsIP(0);
IPAddress dns1 = ETH.dnsIP(1);
const LongTermTimer::Duration dhcp_duration = EthEventData.lastConnectMoment.timeDiff(EthEventData.lastGetIPmoment);

if (!dns0 && !dns1) {
addLog(LOG_LEVEL_ERROR, F("ETH : No DNS server received via DHCP, use cached DNS IP"));
setDNS(0, EthEventData.dns0_cache);
setDNS(1, EthEventData.dns1_cache);
} else {
EthEventData.dns0_cache = dns0;
EthEventData.dns1_cache = dns1;
#if ESP_IDF_VERSION_MAJOR >= 5
const bool mustRequestDHCP = (!dns0 && !dns1) && !ethUseStaticIP();
#endif

if (!ethUseStaticIP()) {
if (!dns0 && !dns1) {
addLog(LOG_LEVEL_ERROR, F("ETH : No DNS server received via DHCP, use cached DNS IP"));
if (EthEventData.dns0_cache) setDNS(0, EthEventData.dns0_cache);
if (EthEventData.dns1_cache) setDNS(1, EthEventData.dns1_cache);
} else {
EthEventData.dns0_cache = dns0;
EthEventData.dns1_cache = dns1;
}
}

if (loglevelActiveFor(LOG_LEVEL_INFO))
Expand Down Expand Up @@ -244,6 +250,14 @@ void processEthernetGotIP() {
logConnectionStatus();

EthEventData.processedGotIP = true;
#if ESP_IDF_VERSION_MAJOR >= 5
if (mustRequestDHCP /*&& EthEventData.lastConnectMoment.millisPassedSince() < 10000*/) {
// FIXME TD-er: Must add some check other than fixed timeout here to not constantly make DHCP requests.
// Force new DHCP request.
ETH.config();
}
#endif

EthEventData.setEthGotIP();
CheckRunningServices();
}
Expand Down
8 changes: 8 additions & 0 deletions src/src/ESPEasyCore/ESPEasyNetwork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,21 @@ void setNetworkMedium(NetworkMedium_t new_medium) {
// ETH.end();
if (new_medium == NetworkMedium_t::WIFI) {
WiFiEventData.clearAll();
#if ESP_IDF_VERSION_MAJOR >= 5
WiFi.STA.setDefault();
#endif
}
#endif
break;
case NetworkMedium_t::WIFI:
WiFiEventData.timerAPoff.setMillisFromNow(WIFI_AP_OFF_TIMER_DURATION);
WiFiEventData.timerAPstart.clear();
if (new_medium == NetworkMedium_t::Ethernet) {
#if ESP_IDF_VERSION_MAJOR >= 5
#if FEATURE_ETHERNET
ETH.setDefault();
#endif
#endif
WifiDisconnect();
}
break;
Expand Down
Loading

0 comments on commit 366041a

Please sign in to comment.