From a619587c03ced4284383fef2e6ba2343bb119bb2 Mon Sep 17 00:00:00 2001 From: CarlosDerSeher Date: Wed, 12 Jun 2024 16:12:21 +0200 Subject: [PATCH] Improv wifi (#85) * - add wifi credential reset o press reset button (nRESET pin) 3 times but wait about 1s between button presses the button press counter is reset 5s after boot * add wifi provisioning service through improv wifi (fix #75) Signed-off-by: Karl Osterseher --- .gitmodules | 3 + .project | 49 +-- components/audio_board/Kconfig.projbuild | 9 +- components/improv_wifi/CMakeLists.txt | 11 + components/improv_wifi/Improv-WiFi-Library | 1 + components/improv_wifi/improvWifi.cpp | 414 ++++++++++++++++++ components/improv_wifi/improv_wrapper.cpp | 100 +++++ .../improv_wifi/include/wifi_provisioning.h | 22 + .../improv_wifi/priv_include/improvWifi.h | 215 +++++++++ .../improv_wifi/priv_include/improv_wrapper.h | 42 ++ components/improv_wifi/wifi_provisioning.c | 249 +++++++++++ components/lightsnapcast/player.c | 3 + components/wifi_interface/CMakeLists.txt | 3 +- components/wifi_interface/Kconfig.projbuild | 18 +- components/wifi_interface/wifi_interface.c | 173 +------- main/CMakeLists.txt | 4 +- main/main.c | 41 +- sdkconfig | 47 +- sdkconfig.old | 147 ++----- 19 files changed, 1191 insertions(+), 360 deletions(-) create mode 100644 components/improv_wifi/CMakeLists.txt create mode 160000 components/improv_wifi/Improv-WiFi-Library create mode 100644 components/improv_wifi/improvWifi.cpp create mode 100644 components/improv_wifi/improv_wrapper.cpp create mode 100644 components/improv_wifi/include/wifi_provisioning.h create mode 100644 components/improv_wifi/priv_include/improvWifi.h create mode 100644 components/improv_wifi/priv_include/improv_wrapper.h create mode 100644 components/improv_wifi/wifi_provisioning.c diff --git a/.gitmodules b/.gitmodules index edb11e1..abe18d8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "components/opus/opus"] path = components/opus/opus url = https://github.com/xiph/opus +[submodule "components/improv_wifi/Improv-WiFi-Library"] + path = components/improv_wifi/Improv-WiFi-Library + url = https://github.com/jnthas/Improv-WiFi-Library.git diff --git a/.project b/.project index dec6168..64c0eb7 100644 --- a/.project +++ b/.project @@ -262,35 +262,26 @@ build/ide/esp_idf_components/esp_partition/partition_target.c 1 /home/karl/espressif/esp-idf-v5.1.1/components/esp_partition/partition_target.c - - - build/ide/esp_idf_components/esp_pm/pm_impl.c - 1 - /home/karl/espressif/esp-idf-v5.1.1/components/esp_pm/pm_impl.c - - - build/ide/esp_idf_components/esp_pm/pm_locks.c - 1 - /home/karl/espressif/esp-idf-v5.1.1/components/esp_pm/pm_locks.c - - - build/ide/esp_idf_components/esp_pm/pm_trace.c - 1 - /home/karl/espressif/esp-idf-v5.1.1/components/esp_pm/pm_trace.c - - - build/ide/esp_idf_components/esp_psram/esp_psram.c - 1 - /home/karl/espressif/esp-idf-v5.1.1/components/esp_psram/esp_psram.c + build/ide/esp_idf_components/esp_psram/mmu_psram_flash.c 1 - /home/karl/espressif/esp-idf-v5.1.1/components/esp_psram/mmu_psram_flash.c + /home/karl/espressif/esp-idf-v5.1.1/components/esp_pm/pm_impl.c build/ide/esp_idf_components/esp_ringbuf/ringbuf.c 1 + /home/karl/espressif/esp-idf-v5.1.1/components/esp_pm/pm_locks.c + + + build/ide/esp_idf_components/esp_system/crosscore_int.c + 1 + /home/karl/espressif/esp-idf-v5.1.1/components/esp_pm/pm_trace.c + + + build/ide/esp_idf_components/esp_system/debug_stubs.c + 1 /home/karl/espressif/esp-idf-v5.1.1/components/esp_ringbuf/ringbuf.c @@ -322,6 +313,7 @@ build/ide/esp_idf_components/esp_system/freertos_hooks.c 1 /home/karl/espressif/esp-idf-v5.1.1/components/esp_system/freertos_hooks.c + build/ide/esp_idf_components/esp_system/int_wdt.c @@ -1643,21 +1635,6 @@ 1 /home/karl/espressif/esp-idf-v5.1.1/components/esp_phy/src/phy_override.c - - build/ide/esp_idf_components/esp_psram/esp32/esp_himem.c - 1 - /home/karl/espressif/esp-idf-v5.1.1/components/esp_psram/esp32/esp_himem.c - - - build/ide/esp_idf_components/esp_psram/esp32/esp_psram_extram_cache.c - 1 - /home/karl/espressif/esp-idf-v5.1.1/components/esp_psram/esp32/esp_psram_extram_cache.c - - - build/ide/esp_idf_components/esp_psram/esp32/esp_psram_impl_quad.c - 1 - /home/karl/espressif/esp-idf-v5.1.1/components/esp_psram/esp32/esp_psram_impl_quad.c - build/ide/esp_idf_components/esp_rom/patches/esp_rom_crc.c 1 diff --git a/components/audio_board/Kconfig.projbuild b/components/audio_board/Kconfig.projbuild index d0c2dba..2a3b024 100644 --- a/components/audio_board/Kconfig.projbuild +++ b/components/audio_board/Kconfig.projbuild @@ -101,11 +101,10 @@ menu "Audio Board" config DAC_TAS5805M bool "Texas Instruments TAS5805M" - - config DAC_PT8211 - bool "Princeton Technology PT8211" - select I2S_USE_MSB_FORMAT - + + config DAC_PT8211 + bool "Princeton Technology PT8211" + select I2S_USE_MSB_FORMAT endchoice menu "DAC I2C control interface" diff --git a/components/improv_wifi/CMakeLists.txt b/components/improv_wifi/CMakeLists.txt new file mode 100644 index 0000000..5c41231 --- /dev/null +++ b/components/improv_wifi/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.15) + +# Build as an ESP-IDF component + idf_component_register( + SRCS "improvWifi.cpp" "improv_wrapper.cpp" "wifi_provisioning.c" + PRIV_INCLUDE_DIRS "Improv-WiFi-Library/src" "priv_include" + INCLUDE_DIRS "include" + PRIV_REQUIRES driver esp_wifi wifi_interface + #SRCS "Improv-WiFi-Library/src/ImprovWiFiLibrary.cpp" "wifi_provisioning.c" + #INCLUDE_DIRS "Improv-WiFi-Library/src" "include" + ) diff --git a/components/improv_wifi/Improv-WiFi-Library b/components/improv_wifi/Improv-WiFi-Library new file mode 160000 index 0000000..f02cb67 --- /dev/null +++ b/components/improv_wifi/Improv-WiFi-Library @@ -0,0 +1 @@ +Subproject commit f02cb672639ad6c62d61180dee2c98576f7fdb43 diff --git a/components/improv_wifi/improvWifi.cpp b/components/improv_wifi/improvWifi.cpp new file mode 100644 index 0000000..0fa4de2 --- /dev/null +++ b/components/improv_wifi/improvWifi.cpp @@ -0,0 +1,414 @@ +/* + * improvWifi.cpp + * + * Created on: Apr 29, 2024 + * Author: karl + */ +#include "improvWifi.h" + +#include + +void ImprovWiFi::handleSerial(const uint8_t *data, size_t length) { + while (data && (length > 0)) { + uint8_t b = *data; + + if (parseImprovSerial(_position, b, _buffer)) { + _buffer[_position++] = b; + } else { + _position = 0; + } + + length--; + data++; + } +} + +void ImprovWiFi::SerialWriteCallback(const unsigned char *txData, int length) { + if (serWriteCallback) { + serWriteCallback(txData, length); + } +} + +void ImprovWiFi::onErrorCallback(ImprovTypes::Error err) { + if (onImproErrorCallback) { + onImproErrorCallback(err); + } +} + +bool ImprovWiFi::onCommandCallback(ImprovTypes::ImprovCommand cmd) { + switch (cmd.command) { + case ImprovTypes::Command::GET_CURRENT_STATE: { + if (isConnected()) { + setState(ImprovTypes::State::STATE_PROVISIONED); + sendDeviceUrl(cmd.command); + } else { + setState(ImprovTypes::State::STATE_AUTHORIZED); + } + + break; + } + + case ImprovTypes::Command::WIFI_SETTINGS: { + if (cmd.ssid.empty()) { + setError(ImprovTypes::Error::ERROR_INVALID_RPC); + break; + } + + setState(ImprovTypes::STATE_PROVISIONING); + + bool success = false; + + if (customConnectWiFiCallback) { + success = + customConnectWiFiCallback(cmd.ssid.c_str(), cmd.password.c_str()); + } + + if (success) { + setError(ImprovTypes::Error::ERROR_NONE); + setState(ImprovTypes::STATE_PROVISIONED); + sendDeviceUrl(cmd.command); + if (onImprovConnectedCallback) { + onImprovConnectedCallback(cmd.ssid.c_str(), cmd.password.c_str()); + } + } else { + setState(ImprovTypes::STATE_STOPPED); + setError(ImprovTypes::ERROR_UNABLE_TO_CONNECT); + onErrorCallback(ImprovTypes::ERROR_UNABLE_TO_CONNECT); + } + + break; + } + + case ImprovTypes::Command::GET_DEVICE_INFO: { + std::vector infos = { + // Firmware name + improvWiFiParams.firmwareName, + // Firmware version + improvWiFiParams.firmwareVersion, + // Hardware chip/variant + CHIP_FAMILY_DESC[improvWiFiParams.chipFamily], + // Device name + improvWiFiParams.deviceName}; + std::vector data = + build_rpc_response(ImprovTypes::GET_DEVICE_INFO, infos, false); + sendResponse(data); + break; + } + + case ImprovTypes::Command::GET_WIFI_NETWORKS: { + getAvailableWifiNetworks(); + break; + } + + default: { + setError(ImprovTypes::ERROR_UNKNOWN_RPC); + return false; + } + } + + return true; +} +void ImprovWiFi::setDeviceInfo(ImprovTypes::ChipFamily chipFamily, + const char *firmwareName, + const char *firmwareVersion, + const char *deviceName) { + improvWiFiParams.chipFamily = chipFamily; + improvWiFiParams.firmwareName = firmwareName; + improvWiFiParams.firmwareVersion = firmwareVersion; + improvWiFiParams.deviceName = deviceName; +} +void ImprovWiFi::setDeviceInfo(ImprovTypes::ChipFamily chipFamily, + const char *firmwareName, + const char *firmwareVersion, + const char *deviceName, const char *deviceUrl) { + setDeviceInfo(chipFamily, firmwareName, firmwareVersion, deviceName); + improvWiFiParams.deviceUrl = deviceUrl; +} + +bool ImprovWiFi::isConnected() { + if (customIsConnectedCallback) { + customIsConnectedCallback(); + } + + return 0; +} + +void ImprovWiFi::sendDeviceUrl(ImprovTypes::Command cmd) { + // URL where user can finish onboarding or use device + // Recommended to use website hosted by device + + uint8_t address[4] = {0, 0, 0, 0}; + char buffer[16]; + + if (customGetLocalIpCallback) { + customGetLocalIpCallback(address); + } + sprintf(buffer, "%d.%d.%d.%d", address[0], address[1], address[2], + address[3]); + std::string ipStr = std::string{buffer}; + + if (improvWiFiParams.deviceUrl.empty()) { + improvWiFiParams.deviceUrl = "http://" + ipStr; + } else { + replaceAll(improvWiFiParams.deviceUrl, "{LOCAL_IPV4}", ipStr); + } + + std::vector data = + build_rpc_response(cmd, {improvWiFiParams.deviceUrl}, false); + sendResponse(data); +} + +void ImprovWiFi::serialWrite(SerialWrite *serWriteCb) { + serWriteCallback = serWriteCb; +} + +void ImprovWiFi::onImprovError(OnImprovError *errorCallback) { + onImproErrorCallback = errorCallback; +} + +void ImprovWiFi::onImprovConnected(OnImprovConnected *connectedCallback) { + onImprovConnectedCallback = connectedCallback; +} + +void ImprovWiFi::setCustomConnectWiFi(CustomConnectWiFi *connectWiFiCallBack) { + customConnectWiFiCallback = connectWiFiCallBack; +} + +void ImprovWiFi::setCustomScanWiFi(CustomScanWiFi *scanWiFiCallBack) { + customScanWiFiCallback = scanWiFiCallBack; +} + +void ImprovWiFi::setCustomisConnected(CustomIsConnected *isConnectedCallBack) { + customIsConnectedCallback = isConnectedCallBack; +} + +void ImprovWiFi::setCustomGetLocalIpCallback( + CustomGetLocalIpCallback *getLocalIpCallback) { + customGetLocalIpCallback = getLocalIpCallback; +} + +// for string delimiter +std::vector ImprovWiFi::split(std::string s, + std::string delimiter) { + size_t pos_start = 0, pos_end, delim_len = delimiter.length(); + std::string token; + std::vector res; + + while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) { + token = s.substr(pos_start, pos_end - pos_start); + pos_start = pos_end + delim_len; + res.push_back(token); + } + + res.push_back(s.substr(pos_start)); + return res; +} + +void ImprovWiFi::getAvailableWifiNetworks() { + unsigned char apBuffer[256] = { + 0, + }; + uint16_t networkNum = 0; + int bufLen = sizeof(apBuffer); + + // printf("scanning\n"); + + if (customScanWiFiCallback) { + customScanWiFiCallback(apBuffer, bufLen, &networkNum); + } + + size_t pos = 0; + std::string token; + std::string delimiter = "\n"; + std::string apString{std::begin(apBuffer), std::end(apBuffer)}; + + for (int id = 0; id < networkNum; ++id) { + if ((pos = apString.find(delimiter)) != std::string::npos) { + token = apString.substr(0, pos); + + std::vector splitStr = split(token.c_str(), ","); + + std::vector wifinetworks = {splitStr}; + + std::vector data = build_rpc_response( + ImprovTypes::GET_WIFI_NETWORKS, wifinetworks, false); + sendResponse(data); + + apString.erase(0, pos + delimiter.length()); + } + } + // final response + std::vector data = build_rpc_response( + ImprovTypes::GET_WIFI_NETWORKS, std::vector{}, false); + sendResponse(data); +} + +inline void ImprovWiFi::replaceAll(std::string &str, const std::string &from, + const std::string &to) { + size_t start_pos = 0; + while ((start_pos = str.find(from, start_pos)) != std::string::npos) { + str.replace(start_pos, from.length(), to); + start_pos += to.length(); + } +} + +bool ImprovWiFi::parseImprovSerial(size_t position, uint8_t byte, + const uint8_t *buffer) { + if (position == 0) return byte == 'I'; + if (position == 1) return byte == 'M'; + if (position == 2) return byte == 'P'; + if (position == 3) return byte == 'R'; + if (position == 4) return byte == 'O'; + if (position == 5) return byte == 'V'; + + if (position == 6) { + return byte == ImprovTypes::IMPROV_SERIAL_VERSION; + } + + if (position <= 8) return true; + + uint8_t type = buffer[7]; + uint8_t data_len = buffer[8]; + + if (position <= 8 + data_len) return true; + + if (position == 8 + data_len + 1) { + uint8_t checksum = 0x00; + for (size_t i = 0; i < position; i++) checksum += buffer[i]; + + if (checksum != byte) { + _position = 0; + onErrorCallback(ImprovTypes::Error::ERROR_INVALID_RPC); + return false; + } + + if (type == ImprovTypes::ImprovSerialType::TYPE_RPC) { + _position = 0; + auto command = parseImprovData(&buffer[9], data_len, false); + return onCommandCallback(command); + } + } + + return false; +} + +ImprovTypes::ImprovCommand ImprovWiFi::parseImprovData( + const std::vector &data, bool check_checksum) { + return parseImprovData(data.data(), data.size(), check_checksum); +} + +ImprovTypes::ImprovCommand ImprovWiFi::parseImprovData(const uint8_t *data, + size_t length, + bool check_checksum) { + ImprovTypes::ImprovCommand improv_command; + ImprovTypes::Command command = (ImprovTypes::Command)data[0]; + uint8_t data_length = data[1]; + + if (data_length != length - 2 - check_checksum) { + improv_command.command = ImprovTypes::Command::UNKNOWN; + return improv_command; + } + + if (check_checksum) { + uint8_t checksum = data[length - 1]; + + uint32_t calculated_checksum = 0; + for (uint8_t i = 0; i < length - 1; i++) { + calculated_checksum += data[i]; + } + + if ((uint8_t)calculated_checksum != checksum) { + improv_command.command = ImprovTypes::Command::BAD_CHECKSUM; + return improv_command; + } + } + + if (command == ImprovTypes::Command::WIFI_SETTINGS) { + uint8_t ssid_length = data[2]; + uint8_t ssid_start = 3; + size_t ssid_end = ssid_start + ssid_length; + + uint8_t pass_length = data[ssid_end]; + size_t pass_start = ssid_end + 1; + size_t pass_end = pass_start + pass_length; + + std::string ssid(data + ssid_start, data + ssid_end); + std::string password(data + pass_start, data + pass_end); + + return {.command = command, .ssid = ssid, .password = password}; + } + + improv_command.command = command; + + return improv_command; +} + +void ImprovWiFi::setState(ImprovTypes::State state) { + std::vector data = {'I', 'M', 'P', 'R', 'O', 'V'}; + data.resize(11); + data[6] = ImprovTypes::IMPROV_SERIAL_VERSION; + data[7] = ImprovTypes::TYPE_CURRENT_STATE; + data[8] = 1; + data[9] = state; + + uint8_t checksum = 0x00; + for (uint8_t d : data) checksum += d; + data[10] = checksum; + + SerialWriteCallback(data.data(), data.size()); +} + +void ImprovWiFi::setError(ImprovTypes::Error error) { + std::vector data = {'I', 'M', 'P', 'R', 'O', 'V'}; + data.resize(11); + data[6] = ImprovTypes::IMPROV_SERIAL_VERSION; + data[7] = ImprovTypes::TYPE_ERROR_STATE; + data[8] = 1; + data[9] = error; + + uint8_t checksum = 0x00; + for (uint8_t d : data) checksum += d; + data[10] = checksum; + + SerialWriteCallback(data.data(), data.size()); +} + +void ImprovWiFi::sendResponse(std::vector &response) { + std::vector data = {'I', 'M', 'P', 'R', 'O', 'V'}; + data.resize(9); + data[6] = ImprovTypes::IMPROV_SERIAL_VERSION; + data[7] = ImprovTypes::TYPE_RPC_RESPONSE; + data[8] = response.size(); + data.insert(data.end(), response.begin(), response.end()); + + uint8_t checksum = 0x00; + for (uint8_t d : data) checksum += d; + data.push_back(checksum); + + SerialWriteCallback(data.data(), data.size()); +} + +std::vector ImprovWiFi::build_rpc_response( + ImprovTypes::Command command, const std::vector &datum, + bool add_checksum) { + std::vector out; + uint32_t length = 0; + out.push_back(command); + for (const auto &str : datum) { + uint8_t len = str.length(); + length += len + 1; + out.push_back(len); + out.insert(out.end(), str.begin(), str.end()); + } + out.insert(out.begin() + 1, length); + + if (add_checksum) { + uint32_t calculated_checksum = 0; + + for (uint8_t byte : out) { + calculated_checksum += byte; + } + out.push_back(calculated_checksum); + } + return out; +} diff --git a/components/improv_wifi/improv_wrapper.cpp b/components/improv_wifi/improv_wrapper.cpp new file mode 100644 index 0000000..14d408f --- /dev/null +++ b/components/improv_wifi/improv_wrapper.cpp @@ -0,0 +1,100 @@ +/* + * improv_wrapper.cpp + * + * Created on: Apr 28, 2024 + * Author: karl + */ +#include "improv_wrapper.h" + +ImprovWiFi *c = NULL; + +extern "C" void improv_wifi_create(void) { + if (c != NULL) { + delete c; + } + + c = new ImprovWiFi(); +} + +extern "C" void improv_wifi_destroy(void) { + if (c != NULL) { + delete c; + c = NULL; + } +} + +extern "C" int improv_wifi_handle_serial(const uint8_t *data, size_t length) { + if (c != NULL) { + c->handleSerial(data, length); + + return 0; + } + + return -1; +} + +extern "C" void improv_wifi_set_device_info(uint8_t chipFamily, + const char *firmwareName, + const char *firmwareVersion, + const char *deviceName, + const char *deviceUrl) { + if (c != NULL) { + c->setDeviceInfo((ImprovTypes::ChipFamily)chipFamily, firmwareName, + firmwareVersion, deviceName, deviceUrl); + } +} + +extern "C" void improv_wifi_serialWrite(void *serWriteCb) { + ImprovWiFi::SerialWrite *cb = (ImprovWiFi::SerialWrite *)serWriteCb; + if (c != NULL) { + c->serialWrite(cb); + } +} + +extern "C" void improv_wifi_onImprovError(void *onImprovErrorCb) { + ImprovWiFi::OnImprovError *cb = (ImprovWiFi::OnImprovError *)onImprovErrorCb; + if (c != NULL) { + c->onImprovError(cb); + } +} + +extern "C" void improv_wifi_onImprovConnected(void *onImprovConnectedCb) { + ImprovWiFi::OnImprovConnected *cb = + (ImprovWiFi::OnImprovConnected *)onImprovConnectedCb; + if (c != NULL) { + c->onImprovConnected(cb); + } +} + +extern "C" void improv_wifi_setCustomConnectWiFi(void *setCustomConnectWiFiCb) { + ImprovWiFi::CustomConnectWiFi *cb = + (ImprovWiFi::CustomConnectWiFi *)setCustomConnectWiFiCb; + if (c != NULL) { + c->setCustomConnectWiFi(cb); + } +} + +extern "C" void improv_wifi_setCustomScanWiFi(void *setCustomScanWiFiCb) { + ImprovWiFi::CustomScanWiFi *cb = + (ImprovWiFi::CustomScanWiFi *)setCustomScanWiFiCb; + if (c != NULL) { + c->setCustomScanWiFi(cb); + } +} + +extern "C" void improv_wifi_setCustomIsConnected(void *setCustomIsConnected) { + ImprovWiFi::CustomIsConnected *cb = + (ImprovWiFi::CustomIsConnected *)setCustomIsConnected; + if (c != NULL) { + c->setCustomisConnected(cb); + } +} + +extern "C" void improv_wifi_setCustomGetLocalIpCallback( + void *getLocalIpCallback) { + ImprovWiFi::CustomGetLocalIpCallback *cb = + (ImprovWiFi::CustomGetLocalIpCallback *)getLocalIpCallback; + if (c != NULL) { + c->setCustomGetLocalIpCallback(cb); + } +} diff --git a/components/improv_wifi/include/wifi_provisioning.h b/components/improv_wifi/include/wifi_provisioning.h new file mode 100644 index 0000000..7fd2c98 --- /dev/null +++ b/components/improv_wifi/include/wifi_provisioning.h @@ -0,0 +1,22 @@ +/* + * wifi_provisioning.h + * + * Created on: Apr 28, 2024 + * Author: karl + */ + +#ifndef COMPONENTS_WIFI_PROVISIONING_H_ +#define COMPONENTS_WIFI_PROVISIONING_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void improv_init(void); +void improv_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* COMPONENTS_WIFI_PROVISIONING_H_ */ diff --git a/components/improv_wifi/priv_include/improvWifi.h b/components/improv_wifi/priv_include/improvWifi.h new file mode 100644 index 0000000..02e4842 --- /dev/null +++ b/components/improv_wifi/priv_include/improvWifi.h @@ -0,0 +1,215 @@ +/* + * improvWifi.h + * + * Created on: Apr 29, 2024 + * Author: karl + */ + +#ifndef COMPONENTS_IMPROV_WIFI_INCLUDE_IMPROVWIFI_H_ +#define COMPONENTS_IMPROV_WIFI_INCLUDE_IMPROVWIFI_H_ + +#include + +#include "ImprovTypes.h" + +/** + * Improv WiFi class + * + * ### Description + * + * Handles the Improv WiFi Serial protocol (https://www.improv-wifi.com/serial/) + * + * ### Example + * + * Simple example of using ImprovWiFi lib. A complete one can be seen in + * `examples/` folder. + * + * ```cpp + * #include + * + * ImprovWiFi improvSerial(&Serial); + * + * void setup() { + * improvSerial.setDeviceInfo(ImprovTypes::ChipFamily::CF_ESP32, + * "My-Device-9a4c2b", "2.1.5", "My Device"); + * } + * + * void loop() { + * improvSerial.handleSerial(); + * } + * ``` + * + */ +class ImprovWiFi { + private: + const char *const CHIP_FAMILY_DESC[5] = {"ESP32", "ESP32-C3", "ESP32-S2", + "ESP32-S3", "ESP8266"}; + ImprovTypes::ImprovWiFiParamsStruct improvWiFiParams; + + uint8_t _buffer[128]; + uint8_t _position = 0; + + // void *serial; + + void sendDeviceUrl(ImprovTypes::Command cmd); + void SerialWriteCallback(const unsigned char *txData, int length); + bool onCommandCallback(ImprovTypes::ImprovCommand cmd); + void onErrorCallback(ImprovTypes::Error err); + void setState(ImprovTypes::State state); + void sendResponse(std::vector &response); + void setError(ImprovTypes::Error error); + void getAvailableWifiNetworks(); + inline void replaceAll(std::string &str, const std::string &from, + const std::string &to); + + // improv SDK + bool parseImprovSerial(size_t position, uint8_t byte, const uint8_t *buffer); + ImprovTypes::ImprovCommand parseImprovData(const std::vector &data, + bool check_checksum = true); + ImprovTypes::ImprovCommand parseImprovData(const uint8_t *data, size_t length, + bool check_checksum = true); + std::vector build_rpc_response(ImprovTypes::Command command, + const std::vector &datum, + bool add_checksum); + + public: + /** + * ## Constructors + **/ + + /** + * Create an instance of ImprovWiFi + * + * # Parameters + * + * - `serial` - Pointer to stream object used to handle requests, for the most + * cases use `Serial` + */ + ImprovWiFi(void) {} + + /** + * ## Type definition + */ + + /** + * serial write function passed through user + */ + typedef void(SerialWrite)(const unsigned char *txData, int length); + + /** + * Callback function called when any error occurs during the protocol handling + * or wifi connection. + */ + typedef void(OnImprovError)(ImprovTypes::Error); + + /** + * Callback function called when the attempt of wifi connection is successful. + * It informs the SSID and Password used to that, it's a perfect time to save + * them for further use. + */ + typedef void(OnImprovConnected)(const char *ssid, const char *password); + + /** + * Callback function to customize the wifi connection if you needed. Optional. + */ + typedef bool(CustomConnectWiFi)(const char *ssid, const char *password); + + typedef void(CustomScanWiFi)(unsigned char *scanResponse, int bufLen, + uint16_t *count); + + typedef bool(CustomIsConnected)(void); + + typedef void(CustomGetLocalIpCallback)(uint8_t *addrIp4); + + /** + * ## Methods + **/ + + /** + * Check if a communication via serial is happening. Put this call on your + * loop(). + * + */ + void handleSerial(const uint8_t *data, size_t length); + + /** + * Set details of your device. + * + * # Parameters + * + * - `chipFamily` - Chip variant, supported are CF_ESP32, CF_ESP32_C3, + * CF_ESP32_S2, CF_ESP32_S3, CF_ESP8266. Consult ESP Home + * [docs](https://esphome.io/components/esp32.html) for more information. + * - `firmwareName` - Firmware name + * - `firmwareVersion` - Firmware version + * - `deviceName` - Your device name + * - `deviceUrl`- The local URL to access your device. A placeholder called + * {LOCAL_IPV4} is available to form elaboreted URLs. E.g. + * `http://{LOCAL_IPV4}?name=Guest`. There is overloaded method without + * `deviceUrl`, in this case the URL will be the local IP. + * + */ + void setDeviceInfo(ImprovTypes::ChipFamily chipFamily, + const char *firmwareName, const char *firmwareVersion, + const char *deviceName, const char *deviceUrl); + void setDeviceInfo(ImprovTypes::ChipFamily chipFamily, + const char *firmwareName, const char *firmwareVersion, + const char *deviceName); + + /** + * Method to set serial write callback + */ + void serialWrite(SerialWrite *serWriteCb); + + /** + * Method to set the typedef OnImprovError callback. + */ + void onImprovError(OnImprovError *errorCallback); + + /** + * Method to set the typedef OnImprovConnected callback. + */ + void onImprovConnected(OnImprovConnected *connectedCallback); + + /** + * Method to set the typedef CustomConnectWiFi callback. + */ + void setCustomConnectWiFi(CustomConnectWiFi *connectWiFiCallBack); + + void setCustomScanWiFi(CustomScanWiFi *scanWiFiCallBack); + + void setCustomisConnected(CustomIsConnected *isConnectedCallBack); + + void setCustomGetLocalIpCallback( + CustomGetLocalIpCallback *getLocalIpCallback); + // + // /** + // * Default method to connect in a WiFi network. + // * It waits `DELAY_MS_WAIT_WIFI_CONNECTION` milliseconds (default 500) + // during + // * `MAX_ATTEMPTS_WIFI_CONNECTION` (default 20) until it get connected. If + // it + // * does not happen, an error `ERROR_UNABLE_TO_CONNECT` is thrown. + // * + // */ + // bool tryConnectToWifi(const char *ssid, const char *password); + + /** + * Check if connection is established using `WiFi.status() == WL_CONNECTED` + * + */ + bool isConnected(); + + std::vector split(std::string s, std::string delimiter); + + private: + SerialWrite *serWriteCallback = NULL; + OnImprovError *onImproErrorCallback = NULL; + OnImprovConnected *onImprovConnectedCallback = NULL; + CustomConnectWiFi *customConnectWiFiCallback = NULL; + CustomScanWiFi *customScanWiFiCallback = NULL; + CustomIsConnected *customIsConnectedCallback = NULL; + CustomGetLocalIpCallback *customGetLocalIpCallback = NULL; +}; + +#endif /* COMPONENTS_IMPROV_WIFI_INCLUDE_IMPROVWIFI_H_ */ diff --git a/components/improv_wifi/priv_include/improv_wrapper.h b/components/improv_wifi/priv_include/improv_wrapper.h new file mode 100644 index 0000000..2a05925 --- /dev/null +++ b/components/improv_wifi/priv_include/improv_wrapper.h @@ -0,0 +1,42 @@ +/* + * improv_wrapper.h + * + * Created on: Apr 29, 2024 + * Author: karl + */ + +#ifndef COMPONENTS_IMPROV_WIFI_INCLUDE_IMPROV_WRAPPER_H_ +#define COMPONENTS_IMPROV_WIFI_INCLUDE_IMPROV_WRAPPER_H_ + +#ifdef __cplusplus +#include "improvWifi.h" +extern "C" { +#else +enum ChipFamily_e { + CF_ESP32, + CF_ESP32_C3, + CF_ESP32_S2, + CF_ESP32_S3, + CF_ESP8266 +}; +#endif + +void improv_wifi_create(void); +void improv_wifi_destroy(void); +int improv_wifi_handle_serial(const uint8_t *data, size_t length); +void improv_wifi_set_device_info(uint8_t chipFamily, const char *firmwareName, + const char *firmwareVersion, + const char *deviceName, const char *deviceUrl); +void improv_wifi_serialWrite(void *cb); +void improv_wifi_onImprovError(void *onImprovErrorCb); +void improv_wifi_onImprovConnected(void *onImprovConnectedCb); +void improv_wifi_setCustomConnectWiFi(void *setCustomConnectWiFiCb); +void improv_wifi_setCustomScanWiFi(void *setCustomScanWiFiCb); +void improv_wifi_setCustomIsConnected(void *setCustomIsConnected); +void improv_wifi_setCustomGetLocalIpCallback(void *getLocalIpCallback); + +#ifdef __cplusplus +} +#endif + +#endif /* COMPONENTS_IMPROV_WIFI_INCLUDE_IMPROV_WRAPPER_H_ */ diff --git a/components/improv_wifi/wifi_provisioning.c b/components/improv_wifi/wifi_provisioning.c new file mode 100644 index 0000000..d34d5c4 --- /dev/null +++ b/components/improv_wifi/wifi_provisioning.c @@ -0,0 +1,249 @@ +/* + * wifi_provisioning.c + * + * Created on: Apr 28, 2024 + * Author: karl + */ + +#include "wifi_provisioning.h" + +#include + +#include "driver/uart.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" +#include "improv_wrapper.h" +#include "wifi_interface.h" + +#define TAG "IMPROV" + +#define RD_BUF_SIZE (UART_FIFO_LEN) +#define PATTERN_CHR_NUM (3) + +static TaskHandle_t t_improv_task = NULL; + +static const int uart_buffer_size = 2 * RD_BUF_SIZE; +static QueueHandle_t uart0_queue; + +void uart_event_handler(void) { + uart_event_t event; + uint8_t dtmp[RD_BUF_SIZE]; + size_t buffered_size; + + // Waiting for UART event. + if (xQueueReceive(uart0_queue, (void *)&event, (TickType_t)portMAX_DELAY)) { + bzero(dtmp, RD_BUF_SIZE); + // ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_0); + switch (event.type) { + // Event of UART receving data + /*We'd better handler data event fast, there would be much more data + events than other types of events. If we take too much time on data event, + the queue might be full.*/ + case UART_DATA: + // ESP_LOGI(TAG, "[UART DATA]: %d", event.size); + + uart_read_bytes(UART_NUM_0, dtmp, event.size, portMAX_DELAY); + // ESP_LOGI(TAG, "[DATA EVT]:"); + + improv_wifi_handle_serial(dtmp, event.size); + break; + // Event of HW FIFO overflow detected + case UART_FIFO_OVF: + // ESP_LOGI(TAG, "hw fifo overflow"); + + // If fifo overflow happened, you should consider adding flow control + // for your application. The ISR has already reset the rx FIFO, As an + // example, we directly flush the rx buffer here in order to read more + // data. + uart_flush_input(UART_NUM_0); + xQueueReset(uart0_queue); + break; + // Event of UART ring buffer full + case UART_BUFFER_FULL: + // ESP_LOGI(TAG, "ring buffer full"); + // If buffer full happened, you should consider increasing your buffer + // size As an example, we directly flush the rx buffer here in order to + // read more data. + uart_flush_input(UART_NUM_0); + xQueueReset(uart0_queue); + break; + // Others + default: + // ESP_LOGI(TAG, "uart event type: %d", event.type); + break; + } + } +} + +static void improv_task(void *pvParameters) { + while (1) { + uart_event_handler(); + } +} + +void uart_write(const unsigned char *txData, int length) { + uart_write_bytes(UART_NUM_0, txData, length); +} + +void improv_wifi_scan(unsigned char *scanResponse, int bufLen, + uint16_t *count) { + uint16_t number = 16; + wifi_ap_record_t ap_info[16]; + + memset(ap_info, 0, sizeof(ap_info)); + + if (esp_wifi_scan_start(NULL, true) == ESP_ERR_WIFI_STATE) { + wifi_ap_record_t ap_info_tmp; + + do { + esp_wifi_disconnect(); + vTaskDelay(pdMS_TO_TICKS(500)); + } while (esp_wifi_sta_get_ap_info(&ap_info_tmp) != + ESP_ERR_WIFI_NOT_CONNECT); + + esp_wifi_scan_start(NULL, true); + } + // ESP_LOGI(TAG, "Max AP number ap_info can hold = %u", number); + ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info)); + ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(count)); + // ESP_LOGI(TAG, "Total APs scanned = %u, actual AP number ap_info holds = + // %u", + // *count, number); + + scanResponse[0] = 0; + for (int i = 0; i < number; i++) { + char rssiStr[8] = { + 0, + }; + char cipherStr[8] = { + 0, + }; + uint16_t neededLen; + + itoa(ap_info[i].rssi, rssiStr, 10); + if (ap_info[i].authmode != WIFI_AUTH_OPEN) { + strcat(cipherStr, "YES"); + } else { + strcat(cipherStr, "NO"); + } + neededLen = strlen((const char *)ap_info[i].ssid) + strlen(rssiStr) + + strlen(cipherStr) + 3; + + if ((bufLen - neededLen) > 0) { + strcat((char *)scanResponse, (char *)ap_info[i].ssid); + strcat((char *)scanResponse, (char *)","); + strcat((char *)scanResponse, (char *)rssiStr); + strcat((char *)scanResponse, (char *)","); + strcat((char *)scanResponse, (char *)cipherStr); + strcat((char *)scanResponse, (char *)"\n"); + + bufLen -= neededLen; + } + } + + // ESP_LOGI(TAG, "APs \t\t%s", scanResponse); +} + +bool improv_wifi_connect(const char *ssid, const char *password) { + uint8_t count = 0; + wifi_ap_record_t apRec; + esp_err_t err; + + while ((err = esp_wifi_sta_get_ap_info(&apRec)) != ESP_ERR_WIFI_NOT_CONNECT) { + esp_wifi_disconnect(); + vTaskDelay(pdMS_TO_TICKS(100)); + } + + wifi_config_t wifi_config; + ESP_ERROR_CHECK(esp_wifi_get_config(WIFI_IF_STA, &wifi_config)); + strcpy((char *)wifi_config.sta.ssid, ssid); + strcpy((char *)wifi_config.sta.password, password); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + + esp_wifi_connect(); + while (esp_wifi_sta_get_ap_info(&apRec) != ESP_OK) { + vTaskDelay(pdMS_TO_TICKS(500)); + if (count > 20) { + esp_wifi_disconnect(); + return false; + } + count++; + } + + return true; +} + +bool improv_wifi_is_connected(void) { + wifi_ap_record_t apRec; + + if (esp_wifi_sta_get_ap_info(&apRec) == ESP_OK) { + // printf("connected\n"); + + return true; + } + + // printf("NOT connected\n"); + + return false; +} + +void improv_wifi_get_local_ip(uint8_t *address) { + esp_netif_ip_info_t ip_info; + + // TODO: find a better way to do this + do { + esp_netif_get_ip_info(get_current_netif(), &ip_info); + vTaskDelay(pdMS_TO_TICKS(200)); + } while (ip_info.ip.addr == 0); + + address[0] = ip_info.ip.addr >> 0; + address[1] = ip_info.ip.addr >> 8; + address[2] = ip_info.ip.addr >> 16; + address[3] = ip_info.ip.addr >> 24; + + // ESP_LOGI(TAG, "%d.%d.%d.%d", address[0], address[1], address[2], + // address[3]); +} + +void improv_init(void) { + uint8_t webPortStr[6] = {0}; + uint16_t webPort = CONFIG_WEB_PORT; + uint8_t urlStr[26] = "http://{LOCAL_IPV4}:"; + + utoa(webPort, (char *)webPortStr, 10); + strcat((char *)urlStr, (char *)webPortStr); + + improv_wifi_create(); + improv_wifi_serialWrite(uart_write); + improv_wifi_set_device_info(CF_ESP32, "esp32_snapclient", "0.0.3", + "snapclient", (const char *)urlStr); + + improv_wifi_setCustomConnectWiFi(improv_wifi_connect); + improv_wifi_setCustomScanWiFi(improv_wifi_scan); + improv_wifi_setCustomIsConnected(improv_wifi_is_connected); + improv_wifi_setCustomGetLocalIpCallback(improv_wifi_get_local_ip); + + // Set UART pins(TX: IO4, RX: IO5, RTS: IO18, CTS: IO19) + // ESP_ERROR_CHECK(uart_set_pin(UART_NUM_0, 1, 3, -1, -1)); + + // Install UART driver using an event queue here + ESP_ERROR_CHECK(uart_driver_install(UART_NUM_0, uart_buffer_size, + uart_buffer_size, 10, &uart0_queue, 0)); + + xTaskCreatePinnedToCore(&improv_task, "improv", 4 * 1024, NULL, 4, + &t_improv_task, tskNO_AFFINITY); +} + +void improv_deinit(void) { + if (t_improv_task) { + vTaskDelete(t_improv_task); + uart_driver_delete(UART_NUM_0); + + t_improv_task = NULL; + } + improv_wifi_destroy(); +} diff --git a/components/lightsnapcast/player.c b/components/lightsnapcast/player.c index d966408..903faa6 100644 --- a/components/lightsnapcast/player.c +++ b/components/lightsnapcast/player.c @@ -275,14 +275,17 @@ static esp_err_t player_setup_i2s(i2s_port_t i2sNum, { #if CONFIG_INVERT_MCLK_LEVEL .mclk_inv = true, + #else .mclk_inv = false, #endif + #if CONFIG_INVERT_BCLK_LEVEL .bclk_inv = true, #else .bclk_inv = false, #endif + #if CONFIG_INVERT_WORD_SELECT_LEVEL .ws_inv = true, #else diff --git a/components/wifi_interface/CMakeLists.txt b/components/wifi_interface/CMakeLists.txt index b0977c1..de2f7e2 100644 --- a/components/wifi_interface/CMakeLists.txt +++ b/components/wifi_interface/CMakeLists.txt @@ -1,3 +1,4 @@ idf_component_register(SRCS "wifi_interface.c" INCLUDE_DIRS "include" - REQUIRES wifi_provisioning esp_event esp_wifi esp_hw_support nvs_flash) + REQUIRES wifi_provisioning esp_event esp_wifi esp_hw_support nvs_flash improv_wifi) + diff --git a/components/wifi_interface/Kconfig.projbuild b/components/wifi_interface/Kconfig.projbuild index 3b717a3..f75d244 100644 --- a/components/wifi_interface/Kconfig.projbuild +++ b/components/wifi_interface/Kconfig.projbuild @@ -3,21 +3,7 @@ menu "Wifi Configuration" bool "enable WiFi provisioning" default n help - Enable WiFi provisioning so espressif APP can be used to provison WiFi credentials - - config WIFI_PROVISIONING_SSID - string "WiFi provisioning SSID" - default "prov_snapclient" - depends on ENABLE_WIFI_PROVISIONING - help - SSID (network name) to use for provisioning access point. Shouldn't be longer than 20 characters. - - config WIFI_PROVISIONING_PASSWORD - string "WiFi provisioning password" - default "12345678" - depends on ENABLE_WIFI_PROVISIONING - help - WiFi password (WPA or WPA2) to use for provisioning access point + Enable WiFi provisioning through improv WiFi (https://github.com/improv-wifi), try it using https://web.esphome.io/ config WIFI_SSID string "WiFi SSID" @@ -34,7 +20,7 @@ menu "Wifi Configuration" WiFi password (WPA or WPA2) for the example to use. config WIFI_MAXIMUM_RETRY - int "Maximum retry" + int "Maximum connection retry" default 5 help Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent. diff --git a/components/wifi_interface/wifi_interface.c b/components/wifi_interface/wifi_interface.c index bc6e575..bf5db6a 100644 --- a/components/wifi_interface/wifi_interface.c +++ b/components/wifi_interface/wifi_interface.c @@ -16,11 +16,7 @@ #if ENABLE_WIFI_PROVISIONING #include // for memcpy -#include -#include - -static const char *provPwd = CONFIG_WIFI_PROVISIONING_PASSWORD; -static const char *provSsid = CONFIG_WIFI_PROVISIONING_SSID; +#include "wifi_provisioning.h" #endif static const char *TAG = "WIFI"; @@ -36,8 +32,6 @@ static int s_retry_num = 0; static esp_netif_t *esp_wifi_netif = NULL; #if ENABLE_WIFI_PROVISIONING -static wifi_config_t wifi_config; - static esp_timer_handle_t resetReasonTimerHandle = NULL; static const esp_timer_create_args_t resetReasonTimerArgs = { .callback = &reset_reason_timer_counter_cb, @@ -69,10 +63,6 @@ static void reset_reason_timer_counter_cb(void *args) { } #endif -/* FreeRTOS event group to signal when we are connected & ready to make a - * request */ -// static EventGroupHandle_t wifi_event_group; - /* The event group allows multiple bits for each event, but we only care about one event - are we connected to the AP with an IP? */ @@ -100,61 +90,9 @@ static void event_handler(void *arg, esp_event_base_t event_base, int event_id, xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); } ESP_LOGI(TAG, "connect to the AP fail"); - } else { -#if ENABLE_WIFI_PROVISIONING - if (event_base == WIFI_PROV_EVENT) { - switch (event_id) { - case WIFI_PROV_START: - ESP_LOGI(TAG, "Provisioning started"); - break; - case WIFI_PROV_CRED_RECV: { - wifi_sta_config_t *wifi_sta_cfg = (wifi_sta_config_t *)event_data; - ESP_LOGI(TAG, - "Received Wi-Fi credentials" - "\n\tSSID : %s\n\tPassword : %s", - (const char *)wifi_sta_cfg->ssid, - (const char *)wifi_sta_cfg->password); - memcpy(&(wifi_config.sta), wifi_sta_cfg, sizeof(wifi_sta_config_t)); - break; - } - case WIFI_PROV_CRED_FAIL: { - wifi_prov_sta_fail_reason_t *reason = - (wifi_prov_sta_fail_reason_t *)event_data; - ESP_LOGE(TAG, - "Provisioning failed!\n\tReason : %s" - "\n\tPlease reset to factory and retry provisioning", - (*reason == WIFI_PROV_STA_AUTH_ERROR) - ? "Wi-Fi station authentication failed" - : "Wi-Fi access-point not found"); - break; - } - case WIFI_PROV_CRED_SUCCESS: - ESP_LOGI(TAG, "Provisioning successful"); - break; - case WIFI_PROV_END: - /* De-initialize manager once provisioning is finished */ - ESP_LOGI(TAG, "Provisioning end"); - break; - default: - break; - } - } -#endif } } -#if ENABLE_WIFI_PROVISIONING -static void get_device_service_name(char *service_name, size_t max) { - uint8_t eth_mac[6]; - const char *ssid_prefix = provSsid; - - esp_wifi_get_mac(WIFI_IF_STA, eth_mac); - - snprintf(service_name, max, "%s_%02X%02X%02X", ssid_prefix, eth_mac[3], - eth_mac[4], eth_mac[5]); -} -#endif - void wifi_init(void) { s_wifi_event_group = xEventGroupCreate(); @@ -167,40 +105,21 @@ void wifi_init(void) { ESP_ERROR_CHECK( esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, (esp_event_handler_t)&event_handler, NULL)); -#if ENABLE_WIFI_PROVISIONING - ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, - &event_handler, NULL)); -#endif esp_wifi_netif = esp_netif_create_default_wifi_sta(); -#if ENABLE_WIFI_PROVISIONING - esp_netif_create_default_wifi_ap(); -#endif wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); // esp_wifi_set_bandwidth (WIFI_IF_STA, WIFI_BW_HT20); esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT40); - esp_wifi_set_protocol( WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); - // esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G); - // esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B); // esp_wifi_set_ps(WIFI_PS_MIN_MODEM); // esp_wifi_set_ps(WIFI_PS_NONE); #if ENABLE_WIFI_PROVISIONING - // Configuration for the provisioning manager - wifi_prov_mgr_config_t config = { - .scheme = wifi_prov_scheme_softap, - .scheme_event_handler = WIFI_PROV_EVENT_HANDLER_NONE}; - - // Initialize provisioning manager with the - // configuration parameters set above - ESP_ERROR_CHECK(wifi_prov_mgr_init(config)); - esp_reset_reason_t resetReason = esp_reset_reason(); ESP_LOGI(TAG, "reset reason was: %d", resetReason); esp_timer_create(&resetReasonTimerArgs, &resetReasonTimerHandle); @@ -215,7 +134,7 @@ void wifi_init(void) { ESP_LOGI(TAG, "get POR reset counter ..."); err |= nvs_get_u8(nvs_handle, "restart_counter", &resetReasonCounter); - ESP_LOGE(TAG, "counter %d", resetReasonCounter); + ESP_LOGI(TAG, "reset counter %d", resetReasonCounter); resetReasonCounter++; @@ -224,7 +143,12 @@ void wifi_init(void) { resetReasonCounter = 0; - wifi_prov_mgr_reset_provisioning(); + esp_wifi_restore(); + // esp_wifi_set_bandwidth (WIFI_IF_STA, WIFI_BW_HT20); + esp_wifi_set_bandwidth(WIFI_IF_STA, WIFI_BW_HT40); + esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | + WIFI_PROTOCOL_11G | + WIFI_PROTOCOL_11N); esp_timer_stop(resetReasonTimerHandle); esp_timer_delete(resetReasonTimerHandle); @@ -238,87 +162,26 @@ void wifi_init(void) { } } - bool provisioned = false; - /* Let's find out if the device is provisioned */ - ESP_ERROR_CHECK(wifi_prov_mgr_is_provisioned(&provisioned)); + /* Start Wi-Fi station */ + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - /* If device is not yet provisioned start provisioning service */ - if (!provisioned) { - ESP_LOGI(TAG, "Starting provisioning"); + wifi_config_t wifi_config; + ESP_ERROR_CHECK(esp_wifi_get_config(WIFI_IF_STA, &wifi_config)); + wifi_config.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); - // Wi-Fi SSID when scheme is wifi_prov_scheme_softap - char service_name[27]; - get_device_service_name(service_name, sizeof(service_name)); + ESP_ERROR_CHECK(esp_wifi_start()); - /* What is the security level that we want (0 or 1): - * - WIFI_PROV_SECURITY_0 is simply plain text communication. - * - WIFI_PROV_SECURITY_1 is secure communication which consists of - * secure handshake using X25519 key exchange and proof of possession - * (pop) and AES-CTR for encryption/decryption of messages. - */ - wifi_prov_security_t security = WIFI_PROV_SECURITY_1; + ESP_LOGI(TAG, "Starting provisioning"); - /* Do we want a proof-of-possession (ignored if Security 0 is selected): - * - this should be a string with length > 0 - * - NULL if not used - */ - const char *pop = NULL; //"abcd1234"; - - /* What is the service key (could be NULL) - * This translates to : - * - Wi-Fi password when scheme is wifi_prov_scheme_softap - * - simply ignored when scheme is wifi_prov_scheme_ble - */ - const char *service_key = provPwd; - - /* An optional endpoint that applications can create if they expect to - * get some additional custom data during provisioning workflow. - * The endpoint name can be anything of your choice. - * This call must be made before starting the provisioning. - */ - // wifi_prov_mgr_endpoint_create("custom-data"); - /* Start provisioning service */ - ESP_ERROR_CHECK(wifi_prov_mgr_start_provisioning( - security, pop, service_name, service_key)); - - /* The handler for the optional endpoint created above. - * This call must be made after starting the provisioning, and only if - * the endpoint has already been created above. - */ - // wifi_prov_mgr_endpoint_register("custom-data", - // custom_prov_data_handler, NULL); - - /* Uncomment the following to wait for the provisioning to finish and - * then release the resources of the manager. Since in this case - * de-initialization is triggered by the default event loop handler, we - * don't need to call the following */ - wifi_prov_mgr_wait(); - wifi_prov_mgr_deinit(); - } else { - ESP_LOGI(TAG, "Already provisioned, starting Wi-Fi STA"); - - /* We don't need the manager as device is already provisioned, - * so let's release it's resources */ - wifi_prov_mgr_deinit(); - - /* Start Wi-Fi station */ - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - - wifi_config_t wifi_config; - ESP_ERROR_CHECK(esp_wifi_get_config(WIFI_IF_STA, &wifi_config)); - wifi_config.sta.sort_method = WIFI_CONNECT_AP_BY_SIGNAL; - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); - - ESP_ERROR_CHECK(esp_wifi_start()); - - ESP_LOGI(TAG, "wifi_init_sta finished."); - } + improv_init(); #else wifi_config_t wifi_config = { .sta = { .ssid = WIFI_SSID, .password = WIFI_PASSWORD, + .sort_method = WIFI_CONNECT_AP_BY_SIGNAL, .threshold.authmode = WIFI_AUTH_WPA2_PSK, .pmf_cfg = {.capable = true, .required = false}, }, diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 4aa7443..a0e2aaf 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,5 +1,5 @@ idf_component_register(SRCS "main.c" INCLUDE_DIRS "." - PRIV_REQUIRES esp_timer esp_wifi eth_interface nvs_flash wifi_interface audio_board audio_hal audio_sal net_functions opus flac ota_server - ui_http_server + PRIV_REQUIRES esp_timer esp_wifi nvs_flash wifi_interface audio_board audio_hal audio_sal net_functions opus flac ota_server + ui_http_server improv_wifi ) diff --git a/main/main.c b/main/main.c index 5d68fd7..e1ec07d 100644 --- a/main/main.c +++ b/main/main.c @@ -26,6 +26,8 @@ #include "wifi_interface.h" // Minimum ESP-IDF stuff only hardware abstraction stuff +#include + #include "board.h" #include "es8388.h" #include "esp_netif.h" @@ -81,7 +83,7 @@ static QueueHandle_t decoderTaskQHdl = NULL; SemaphoreHandle_t decoderReadSemaphore = NULL; SemaphoreHandle_t decoderWriteSemaphore = NULL; -const char *VERSION_STRING = "0.0.2"; +const char *VERSION_STRING = "0.0.3"; #define HTTP_TASK_PRIORITY (configMAX_PRIORITIES - 2) // 9 #define HTTP_TASK_CORE_ID 1 // 1 // tskNO_AFFINITY @@ -2747,14 +2749,15 @@ void app_main(void) { ESP_ERROR_CHECK(ret); esp_log_level_set("*", ESP_LOG_INFO); - // esp_log_level_set("c_I2S", ESP_LOG_NONE); // if enabled these cause a timer srv stack overflow esp_log_level_set("HEADPHONE", ESP_LOG_NONE); - esp_log_level_set("gpio", ESP_LOG_NONE); - // esp_log_level_set("i2s_std", ESP_LOG_DEBUG); - // esp_log_level_set("i2s_common", ESP_LOG_DEBUG); - + esp_log_level_set("gpio", ESP_LOG_WARN); + esp_log_level_set("uart", ESP_LOG_WARN); + // esp_log_level_set("i2s_std", ESP_LOG_DEBUG); + // esp_log_level_set("i2s_common", ESP_LOG_DEBUG); + esp_log_level_set("wifi", ESP_LOG_WARN); + esp_log_level_set("wifi_init", ESP_LOG_WARN); esp_log_level_set("wifi", ESP_LOG_WARN); esp_log_level_set("wifi_init", ESP_LOG_WARN); @@ -2859,6 +2862,32 @@ void app_main(void) { ESP_LOGI(TAG, "init player"); init_player(); + + // ensure there is no noise from DAC + { + board_i2s_pin_t pin_config0; + get_i2s_pins(I2S_NUM_0, &pin_config0); + + gpio_config_t gpioCfg = { + .pin_bit_mask = + BIT64(pin_config0.mck_io_num) | BIT64(pin_config0.data_out_num) | + BIT64(pin_config0.bck_io_num) | BIT64(pin_config0.ws_io_num), + .mode = GPIO_MODE_OUTPUT, + .pull_up_en = GPIO_PULLUP_DISABLE, + .pull_down_en = GPIO_PULLDOWN_DISABLE, + .intr_type = GPIO_INTR_DISABLE, + }; + gpio_config(&gpioCfg); + gpio_set_level(pin_config0.mck_io_num, 0); + gpio_set_level(pin_config0.data_out_num, 0); + gpio_set_level(pin_config0.bck_io_num, 0); + gpio_set_level(pin_config0.ws_io_num, 0); + + gpioCfg.pin_bit_mask = BIT64(pin_config0.data_in_num); + gpioCfg.mode = GPIO_MODE_INPUT; + gpioCfg.pull_up_en = GPIO_PULLUP_ENABLE; + gpio_config(&gpioCfg); + } // ensure there is no noise from DAC { diff --git a/sdkconfig b/sdkconfig index 2024409..cec76dc 100644 --- a/sdkconfig +++ b/sdkconfig @@ -392,8 +392,6 @@ CONFIG_SNTP_SERVER="pool.ntp.org" # Wifi Configuration # CONFIG_ENABLE_WIFI_PROVISIONING=y -CONFIG_WIFI_PROVISIONING_SSID="prov_snapclient" -CONFIG_WIFI_PROVISIONING_PASSWORD="12345678" CONFIG_WIFI_MAXIMUM_RETRY=0 # end of Wifi Configuration @@ -1111,14 +1109,17 @@ CONFIG_IEEE802154_PENDING_TABLE_SIZE=20 # # Log output # -# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set # CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set # CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=3 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +CONFIG_LOG_DEFAULT_LEVEL=0 +# CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT is not set +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +CONFIG_LOG_MAXIMUM_LEVEL_INFO=y # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set # CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set CONFIG_LOG_MAXIMUM_LEVEL=3 @@ -1649,23 +1650,6 @@ CONFIG_WEBSOCKET_SERVER_TASK_PRIORITY=5 # CONFIG_WEBSOCKET_SERVER_PINNED is not set # end of WebSocket Server -# -# DSP Library -# -CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y -# CONFIG_DSP_ANSI is not set -CONFIG_DSP_OPTIMIZED=y -CONFIG_DSP_OPTIMIZATION=1 -# CONFIG_DSP_MAX_FFT_SIZE_512 is not set -# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set -# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set -CONFIG_DSP_MAX_FFT_SIZE_4096=y -# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set -# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set -# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set -CONFIG_DSP_MAX_FFT_SIZE=4096 -# end of DSP Library - # # mDNS # @@ -1695,6 +1679,23 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_MDNS_PREDEF_NETIF_ETH=y # end of MDNS Predefined interfaces # end of mDNS + +# +# DSP Library +# +CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y +# CONFIG_DSP_ANSI is not set +CONFIG_DSP_OPTIMIZED=y +CONFIG_DSP_OPTIMIZATION=1 +# CONFIG_DSP_MAX_FFT_SIZE_512 is not set +# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set +# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set +CONFIG_DSP_MAX_FFT_SIZE_4096=y +# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set +# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set +# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set +CONFIG_DSP_MAX_FFT_SIZE=4096 +# end of DSP Library # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set diff --git a/sdkconfig.old b/sdkconfig.old index 9dd97b2..cec76dc 100644 --- a/sdkconfig.old +++ b/sdkconfig.old @@ -392,8 +392,6 @@ CONFIG_SNTP_SERVER="pool.ntp.org" # Wifi Configuration # CONFIG_ENABLE_WIFI_PROVISIONING=y -CONFIG_WIFI_PROVISIONING_SSID="prov_snapclient" -CONFIG_WIFI_PROVISIONING_PASSWORD="12345678" CONFIG_WIFI_MAXIMUM_RETRY=0 # end of Wifi Configuration @@ -716,9 +714,7 @@ CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 # # Sleep Config # -CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND=y -CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND=y -# CONFIG_ESP_SLEEP_MSPI_NEED_ALL_IO_PU is not set +CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 @@ -806,86 +802,7 @@ CONFIG_ESP_PHY_CALIBRATION_MODE=0 # # ESP PSRAM # -CONFIG_SPIRAM=y - -# -# SPI RAM config -# -CONFIG_SPIRAM_MODE_QUAD=y -CONFIG_SPIRAM_TYPE_AUTO=y -# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set -# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set -# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set -# CONFIG_SPIRAM_SPEED_40M is not set -CONFIG_SPIRAM_SPEED_80M=y -CONFIG_SPIRAM_SPEED=80 -CONFIG_SPIRAM_BOOT_INIT=y -# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set -# CONFIG_SPIRAM_USE_MEMMAP is not set -# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set -CONFIG_SPIRAM_USE_MALLOC=y -CONFIG_SPIRAM_MEMTEST=y -CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=2048 -# CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set -CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 -# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set -# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set -CONFIG_SPIRAM_CACHE_WORKAROUND=y - -# -# SPIRAM cache workaround debugging -# -CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW=y -# CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST is not set -# CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_NOPS is not set -# end of SPIRAM cache workaround debugging - -# -# SPIRAM workaround libraries placement -# -CONFIG_SPIRAM_CACHE_LIBJMP_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBMATH_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBNUMPARSER_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBIO_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBTIME_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBCHAR_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBMEM_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBSTR_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBRAND_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBENV_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBFILE_IN_IRAM=y -CONFIG_SPIRAM_CACHE_LIBMISC_IN_IRAM=y -# end of SPIRAM workaround libraries placement - -CONFIG_SPIRAM_BANKSWITCH_ENABLE=y -CONFIG_SPIRAM_BANKSWITCH_RESERVE=8 -# CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is not set -# CONFIG_SPIRAM_OCCUPY_HSPI_HOST is not set -CONFIG_SPIRAM_OCCUPY_VSPI_HOST=y -# CONFIG_SPIRAM_OCCUPY_NO_HOST is not set - -# -# PSRAM clock and cs IO for ESP32-DOWD -# -CONFIG_D0WD_PSRAM_CLK_IO=17 -CONFIG_D0WD_PSRAM_CS_IO=16 -# end of PSRAM clock and cs IO for ESP32-DOWD - -# -# PSRAM clock and cs IO for ESP32-D2WD -# -CONFIG_D2WD_PSRAM_CLK_IO=9 -CONFIG_D2WD_PSRAM_CS_IO=10 -# end of PSRAM clock and cs IO for ESP32-D2WD - -# -# PSRAM clock and cs IO for ESP32-PICO -# -CONFIG_PICO_PSRAM_CS_IO=10 -# end of PSRAM clock and cs IO for ESP32-PICO - -# CONFIG_SPIRAM_2T_MODE is not set -# end of SPI RAM config +# CONFIG_SPIRAM is not set # end of ESP PSRAM # @@ -979,7 +896,6 @@ CONFIG_ESP_BROWNOUT_DET_LVL=4 # end of Brownout Detector # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set -CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y # end of ESP System Settings @@ -1015,15 +931,14 @@ CONFIG_ESP_WIFI_ENABLED=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=8 CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=64 CONFIG_ESP_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP_WIFI_STATIC_TX_BUFFER_NUM=8 -CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=32 # CONFIG_ESP_WIFI_CSI_ENABLED is not set CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP_WIFI_TX_BA_WIN=8 CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP_WIFI_RX_BA_WIN=16 -# CONFIG_ESP_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP_WIFI_NVS_ENABLED=y CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set @@ -1106,7 +1021,6 @@ CONFIG_FATFS_CODEPAGE=437 CONFIG_FATFS_FS_LOCK=0 CONFIG_FATFS_TIMEOUT_MS=10000 CONFIG_FATFS_PER_FILE_CACHE=y -CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y # CONFIG_FATFS_USE_FASTSEEK is not set CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 # end of FAT Filesystem support @@ -1195,14 +1109,17 @@ CONFIG_IEEE802154_PENDING_TABLE_SIZE=20 # # Log output # -# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +CONFIG_LOG_DEFAULT_LEVEL_NONE=y # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set # CONFIG_LOG_DEFAULT_LEVEL_WARN is not set -CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set # CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set -CONFIG_LOG_DEFAULT_LEVEL=3 -CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y +CONFIG_LOG_DEFAULT_LEVEL=0 +# CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT is not set +# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set +# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set +CONFIG_LOG_MAXIMUM_LEVEL_INFO=y # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set # CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set CONFIG_LOG_MAXIMUM_LEVEL=3 @@ -1370,7 +1287,6 @@ CONFIG_LWIP_HOOK_IP6_INPUT_NONE=y # mbedTLS # CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y -# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set # CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set # CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y @@ -1734,23 +1650,6 @@ CONFIG_WEBSOCKET_SERVER_TASK_PRIORITY=5 # CONFIG_WEBSOCKET_SERVER_PINNED is not set # end of WebSocket Server -# -# DSP Library -# -CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y -# CONFIG_DSP_ANSI is not set -CONFIG_DSP_OPTIMIZED=y -CONFIG_DSP_OPTIMIZATION=1 -# CONFIG_DSP_MAX_FFT_SIZE_512 is not set -# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set -# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set -CONFIG_DSP_MAX_FFT_SIZE_4096=y -# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set -# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set -# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set -CONFIG_DSP_MAX_FFT_SIZE=4096 -# end of DSP Library - # # mDNS # @@ -1780,6 +1679,23 @@ CONFIG_MDNS_PREDEF_NETIF_AP=y CONFIG_MDNS_PREDEF_NETIF_ETH=y # end of MDNS Predefined interfaces # end of mDNS + +# +# DSP Library +# +CONFIG_DSP_OPTIMIZATIONS_SUPPORTED=y +# CONFIG_DSP_ANSI is not set +CONFIG_DSP_OPTIMIZED=y +CONFIG_DSP_OPTIMIZATION=1 +# CONFIG_DSP_MAX_FFT_SIZE_512 is not set +# CONFIG_DSP_MAX_FFT_SIZE_1024 is not set +# CONFIG_DSP_MAX_FFT_SIZE_2048 is not set +CONFIG_DSP_MAX_FFT_SIZE_4096=y +# CONFIG_DSP_MAX_FFT_SIZE_8192 is not set +# CONFIG_DSP_MAX_FFT_SIZE_16384 is not set +# CONFIG_DSP_MAX_FFT_SIZE_32768 is not set +CONFIG_DSP_MAX_FFT_SIZE=4096 +# end of DSP Library # end of Component config # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set @@ -1831,6 +1747,7 @@ CONFIG_POST_EVENTS_FROM_ISR=y # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +CONFIG_ESP_SYSTEM_PD_FLASH=y CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y @@ -1851,9 +1768,8 @@ CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 CONFIG_REDUCE_PHY_TX_POWER=y CONFIG_ESP32_REDUCE_PHY_TX_POWER=y -CONFIG_SPIRAM_SUPPORT=y -CONFIG_ESP32_SPIRAM_SUPPORT=y -# CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST is not set +# CONFIG_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_SPIRAM_SUPPORT is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set # CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y @@ -1911,9 +1827,9 @@ CONFIG_ESP32_WIFI_ENABLED=y CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=8 CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=64 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y +# CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER is not set CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=8 -CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 # CONFIG_ESP32_WIFI_CSI_ENABLED is not set CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=8 @@ -1921,7 +1837,6 @@ CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP32_WIFI_RX_BA_WIN=16 CONFIG_ESP32_WIFI_RX_BA_WIN=16 -# CONFIG_ESP32_WIFI_AMSDU_TX_ENABLED is not set CONFIG_ESP32_WIFI_NVS_ENABLED=y CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set