diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..11f4777 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# Ignore vim recovery files +.*.swp +*.bak + +# Ignore build artifacts +**/build/** + +/dependencies.lock +/managed_components/ + +# Ignore the NVS prototypes +/nvs*.bin +/nvs*.csv + +/sdkconfig.old + +**/.nfs* +**/.DS_Store diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..661f2fc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "components/libnsgif"] + path = components/libnsgif + url = https://github.com/UncleRus/esp-idf-libnsgif.git +[submodule "components/libwebp/libwebp"] + path = components/libwebp/libwebp + url = https://chromium.googlesource.com/webm/libwebp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d870347 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +# For more information about build system see +# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html +# The following five lines of boilerplate have to be in your project's +# CMakeLists in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(PixelClient) diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..3a562dc --- /dev/null +++ b/README.md @@ -0,0 +1,74 @@ +PixelClient: Firmware for an ESP-32 board to drive a 32x64 HUB 75 display, +by subscribing to a websocket and streaming pushed images. The corresponding +server is located at https://github.com/joe714/pixelgw + +Mainter: Joe Sunday sunday@csh.rit.edu +GitHub: https://github.com/joe714/pixelfirmware + +# Build and Install + +Pinout for the display is set in components/Hub75Display/Hub75Display.c, +note this is not the same pinout as official Tidbyt hardware and needs +to be set for particular devices. (TODO, make this more configurable at +build time) . Reference schematic / board coming soon. + +To build, you'll need a working Linux machine with Docker installed and +your user in the docker group. After cloning the repository, fetch the +required submodules: + + $ git submodule init + $ git submodule update + +To compile the firmware: + + $ ./build.sh build + +For first setup, copy nvs.csv.sample to nvs.csv and set your WiFi credentials +and endpoint / pixelgw IP address on the appropriate lines, and generate the +initial NVS partion data: + + $ ./build.sh nvs + +To flash, connect the device via USB and flash everything. Note that you +should only flash the NVS data on the first install. Once the device has +registered with the gateway, reflashing NVS will cause the device UUID to +change. + + $ ./build.sh flash + $ ./build.sh flash_nvs + +To do OTA updates once already installed, start a temporary web server: + + $ ./build.sh ota-server + +Then navigate to http://*device-ip*/, verify OTA URL listed, and click "Update Firmware". +Currently it assumes you're running the OTA update from the same machine as the +gateway endpoint, otherwise you'll need to change the IP in the firmware URL. + +# FAQ +- What hardware does this need? + + An ESP-32 board with the HUB75 display wired according to the pin + definitions in components/Hub75Display/Hub75Display.c. + + I'm working on a V1.5 board revision, but I'll publish the + v1 board design when I can. + +- Do you sell hardware? + + Not currently, but inquire and if there's demand I'll see what I can do. + +- Can I run this on Tidbyt Hardware? + + Theoretically, yes but I have not tried it or determined the right + compile options, or determined how to reset it back to factory firmware. + At a minimum, the pin definitions need to be tweaked. If you want to try, + feel free and give me a pull request with changes and instructions, but + I take no responsibility if you brick it. + +# TODO +- Integrate firmware management into the server. +- Web interface to bootstrap / modify configuration +- More device support (including pre-canned config for Tidbyt 1 devices) + + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..613bfe7 --- /dev/null +++ b/build.sh @@ -0,0 +1,53 @@ +#/bin/bash +# Run the build in a docker image +# https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html# +# +# Run HTTP server for OTA update: +# python -m http.server --directory build + +ESPTOOL="python /mnt/code/esp32/esptool/esptool.py" +if [ -z "$IDF_DOCKER_IMAGE" ]; then + IDF_DOCKER_IMAGE="espressif/idf:release-v5.2" +fi +echo "Using esp-idf image: $IDF_DOCKER_IMAGE" + +if [ -z "$ESPTOOL_PORT" ] ; then + ESPTOOL_PORT=/dev/ttyUSB0 +fi +echo "Using serial port: $ESPTOOL_PORT" + +DOCKER_ARGS="--rm -v ${PWD}:/project -e HOME=/tmp" + +# Build we run as the user to not trash permissions in build/ +DOCKER_BUILD_ARGS="${DOCKER_ARGS} -w /project -u `id -u`:`id -g`" + +# Flash we just run as root to use the serial port without a bunch of permissions issues +DOCKER_FLASH_ARGS="${DOCKER_ARGS} -w /project/build --device=${ESPTOOL_PORT}" + +if [ "$1" == "build" ]; then + docker run ${DOCKER_BUILD_ARGS} ${IDF_DOCKER_IMAGE} idf.py build +elif [ $1 == "nvs" ]; then + docker run ${DOCKER_BUILD_ARGS} ${IDF_DOCKER_IMAGE} ./nvs.sh +elif [ "$1" == "interactive" ]; then + docker run ${DOCKER_BUILD_ARGS} -it ${IDF_DOCKER_IMAGE} +elif [ "$1" == "flash" ]; then + docker run ${DOCKER_FLASH_ARGS} ${IDF_DOCKER_IMAGE} \ + esptool.py -p $ESPTOOL_PORT --chip esp32 -b 460800 --before default_reset --after hard_reset \ + write_flash "@flash_args" +elif [ "$1" == "flash_app" ]; then + docker run ${DOCKER_FLASH_ARGS} ${IDF_DOCKER_IMAGE} \ + esptool.py -p $ESPTOOL_PORT --chip esp32 -b 460800 --before default_reset --after hard_reset \ + write_flash "@flash_app_args" +elif [ "$1" == "flash_nvs" ]; then + docker run ${DOCKER_FLASH_ARGS} ${IDF_DOCKER_IMAGE} \ + esptool.py -p $ESPTOOL_PORT --chip esp32 -b 460800 --before default_reset --after hard_reset \ + write_flash "@flash_nvs_args" +elif [ "$1" == "ota-server" ] ; then + python -m http.server --directory build +elif [ "$1" == "monitor" ] ; then + python -m serial.tools.miniterm --rts 0 --dtr 0 --filter direct $ESPTOOL_PORT 115200 +else + echo "Usage: $0 [build|nvs|interactive|ota-server|flash|flash-app|flash-nvs|monitor]" + exit 1; +fi + diff --git a/components/HttpServer/CMakeLists.txt b/components/HttpServer/CMakeLists.txt new file mode 100644 index 0000000..ef4617b --- /dev/null +++ b/components/HttpServer/CMakeLists.txt @@ -0,0 +1,8 @@ +idf_component_register( + SRCS "HttpServer.cc" + "StaticAssetHandler.cc" + "WebSockets.cc" + INCLUDE_DIRS "include" + REQUIRES "esp_http_server") + +target_compile_options(${COMPONENT_LIB} PRIVATE "-std=gnu++17") diff --git a/components/HttpServer/HttpServer.cc b/components/HttpServer/HttpServer.cc new file mode 100644 index 0000000..e188da6 --- /dev/null +++ b/components/HttpServer/HttpServer.cc @@ -0,0 +1,169 @@ +#include "HttpServer.h" +#include "WebSockets.h" +#include +#include + +static const char* TAG = "httpd"; + +namespace { + +int ctoh(char c) +{ + if (c >= '0' && c <= '9') { + return c - '0'; + } + if (c >= 'a' && c <= 'f') { + return (c - 'a') + 10; + } + if (c >= 'A' && c <= 'F') { + return (c - 'A') + 10; + } + return -1; +} + +} // namespace +namespace httpd { + +std::string urldecode(std::string_view in) +{ + std::string out; + out.reserve(in.size()); + auto len = in.size(); + auto i = 0; + while (i < len) { + if (in[i] == '+') { + out.push_back(' '); + ++i; + continue; + } + if (in[i] == '%' && (i + 3) < len) { + int h = ctoh(in[i+1]); + int l = ctoh(in[i+2]); + if (h >= 0 && l >= 0) { + out.push_back((char)((h << 4) | l)); + i += 3; + continue; + } + } + out.push_back(in[i]); + ++i; + } + return out; +} + +std::string Request::requestHeader(const std::string& name) const +{ + std::string out; + + size_t len = httpd_req_get_hdr_value_len(request_, name.c_str()); + if (len) { + out.resize(len); + httpd_req_get_hdr_value_str(request_, name.c_str(), out.data(), out.size() + 1); + } + return out; +} + +void +Request::setContentType(const std::string& type) +{ + httpd_resp_set_type(request_, type.c_str()); +} +void +Request::sendResponse(std::string_view data) +{ + httpd_resp_send(request_, data.data(), data.length()); +} + +void +Request::sendResponse(const char* data, ssize_t len) +{ + httpd_resp_send(request_, data, len); +} + +void +Request::sendError(httpd_err_code_t err) +{ + httpd_resp_send_err(request_, err, nullptr); +} + +void +Request::sendError(httpd_err_code_t err, const std::string& msg) +{ + httpd_resp_send_err(request_, err, msg.c_str()); +} + +Server::Server() + : handle_(nullptr) +{ + httpd_config_t config = HTTPD_DEFAULT_CONFIG(); + config.max_uri_handlers = 8; + config.lru_purge_enable = true; + config.uri_match_fn = httpd_uri_match_wildcard; + + ESP_LOGI(TAG, "Starting server on port: %d", config.server_port); + + if (httpd_start(&handle_, &config) != ESP_OK) { + ESP_LOGE(TAG, "Error starting server!"); + } + +} + +Server::~Server() { + if (handle_) { + httpd_stop(handle_); + } +} + +void +Server::registerHandler(const std::string& uri, RequestHandler& handler) +{ + // There doesn't seem to be a generated end to the http_method enum, and + // practically for now we only care about a few, so just look for them. + static const httpd_method_t SUPPORTED_METHODS[] = { + HTTP_DELETE, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH + }; + + httpd_uri_t reg = {}; + reg.uri = uri.c_str(); + reg.handler = Server::dispatch; + reg.user_ctx = &handler; + + WSHandler* wsh = dynamic_cast(&handler); + if (wsh) { + ESP_LOGI(TAG, "WebSocket URI %s", uri.c_str()); + reg.method = HTTP_GET; + reg.is_websocket = true; + if (!wsh->subprotocols().empty()) { + reg.supported_subprotocol = wsh->subprotocols().c_str(); + } + reg.handle_ws_control_frames = wsh->controlFrames(); + esp_err_t rv = httpd_register_uri_handler(handle_, ®); + if (ESP_OK != rv) { + ESP_LOGI(TAG, "Failed registering WebSocket handler for %s: %d", uri.c_str(), rv); + } + return; + } + + for (httpd_method_t m : SUPPORTED_METHODS) { + if (handler.canHandle(m)) { + reg.method = m; + esp_err_t rv = httpd_register_uri_handler(handle_, ®); + if (ESP_OK != rv) { + ESP_LOGI(TAG, + "Failed registering handler for %s: %d", + uri.c_str(), + rv); + } + } + }; +} + +esp_err_t +Server::dispatch(httpd_req_t* req) +{ + ESP_LOGI(TAG, "Dispatch method %d handler %p", req->method, req->user_ctx); + RequestHandler* h = static_cast(req->user_ctx); + return h->handle(req); +} + +} // namespace httpd diff --git a/components/HttpServer/StaticAssetHandler.cc b/components/HttpServer/StaticAssetHandler.cc new file mode 100644 index 0000000..281cbbd --- /dev/null +++ b/components/HttpServer/StaticAssetHandler.cc @@ -0,0 +1,25 @@ +#include "StaticAssetHandler.h" + +namespace httpd { + +StaticAssetHandler::StaticAssetHandler(const StaticAsset& asset, + const std::string& contentType) + : asset_(asset), contentType_(contentType) +{ +} + +StaticAssetHandler::StaticAssetHandler(const char* data, + size_t len, + const std::string& contentType) + : StaticAssetHandler(StaticAsset{ data, len }, contentType) +{ +} + +esp_err_t +StaticAssetHandler::onGet(Request& req) +{ + req.setContentType(contentType_); + req.sendResponse(asset_.data, asset_.len); + return ESP_OK; +} +} // namespace httpd diff --git a/components/HttpServer/WebSockets.cc b/components/HttpServer/WebSockets.cc new file mode 100644 index 0000000..84b608d --- /dev/null +++ b/components/HttpServer/WebSockets.cc @@ -0,0 +1,95 @@ +#include "WebSockets.h" +#include +#include + +static const char* TAG = "WebSockets"; + +namespace httpd { + +esp_err_t WSSocket::send(std::string_view str, httpd_ws_type_t type) +{ + return send((uint8_t*)str.data(), str.size(), type); +} + +esp_err_t WSSocket::send(const uint8_t* payload, size_t len, httpd_ws_type_t type) +{ + WSFrame frame = { .final = true, + .fragmented = false, + .type = type, + .payload = const_cast(payload), + .len = len }; + return send(frame); +} + +esp_err_t WSSocket::send(const WSFrame& frame) +{ + httpd_ws_client_info_t info = httpd_ws_get_fd_info(server_, fd_); + if (info != HTTPD_WS_CLIENT_WEBSOCKET) { + ESP_LOGI(TAG, "Send on closed socket! %d", info); + return ESP_FAIL; + } + + esp_err_t rv = httpd_ws_send_frame_async(server_, fd_, const_cast(&frame)); + return rv; +} + +WSHandler::WSHandler(const std::string& subprotocols, bool controlFrames) + : subprotocols_(subprotocols), controlFrames_(controlFrames) +{ +} + +bool WSHandler::canHandle(httpd_method_t m) const +{ + return m == HTTP_GET; +} + +esp_err_t +WSHandler::handle(httpd_req_t* req) +{ + WSSocket sock(*this, req->handle, httpd_req_to_sockfd(req)); + ESP_LOGI(TAG, "WSHandler::handle fd: %p %p %d", this, sock.server(), sock.fd()); + + esp_err_t rv = ESP_FAIL; + if (HTTP_GET == req->method) { + ESP_LOGI(TAG, "onConnect"); + rv = onConnect(sock); + ESP_LOGI(TAG, "onConnect result: %d", rv); + return rv; + } + + WSFrame frame = {}; + rv = httpd_ws_recv_frame(req, &frame, 0); + if (ESP_OK != rv) { + ESP_LOGE(TAG, "Failed to read frame length from fd %d: %d", + sock.fd(), rv); + onClose(sock); + return rv; + } + + if (frame.len > 2048) { + ESP_LOGI(TAG, "Frame too long: %d", frame.len); + onClose(sock); + return ESP_FAIL; + } + + ESP_LOGI(TAG, "Calling httpd_ws_recv_frame for len %d", frame.len); + std::vector payload(frame.len); + frame.payload = payload.data(); + rv = httpd_ws_recv_frame(req, &frame, payload.size()); + if (ESP_OK != rv) { + ESP_LOGI(TAG, "httpd_ws_recv_frame error: %d", rv); + } else { + ESP_LOGI(TAG, "Handle onReceive"); + rv = onReceive(sock, frame); + ESP_LOGI(TAG, "onReceive result: %d", rv); + } + + if (ESP_OK != rv) { + onClose(sock); + } + + return rv; +} + +} // namespace httpd + diff --git a/components/HttpServer/include/HttpServer.h b/components/HttpServer/include/HttpServer.h new file mode 100644 index 0000000..790e2a5 --- /dev/null +++ b/components/HttpServer/include/HttpServer.h @@ -0,0 +1,132 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace httpd { + +std::string urldecode(std::string_view in); + +class Server; + +class Request { +public: + Request(httpd_req_t* req) : request_(req) {}; + httpd_req_t* request() const { return request_; } + + httpd_method_t method() const { return (httpd_method_t)request_->method; } + std::string_view uri() const { return std::string_view(request_->uri); } + bool isGet() const { return HTTP_GET == method(); } + bool isPost() const { return HTTP_POST == method(); } + + size_t contentLength() const { return request_->content_len; } + + std::string requestHeader(const std::string& name) const; + + void setContentType(const std::string& type); + + void sendResponse(std::string_view data); + void sendResponse(const char* data, ssize_t len); + + void sendError(httpd_err_code_t error); + void sendError(httpd_err_code_t err, const std::string& msg); + +private: + httpd_req_t* request_; +}; + +class RequestHandler { +public: + virtual ~RequestHandler() = default; + virtual bool canHandle(httpd_method_t method) const = 0; + virtual esp_err_t handle(httpd_req_t* req) = 0; +}; + +template +class MethodBase { }; + +#define DECLARE_METHOD(NAME, METHOD) \ + template <> \ + class MethodBase { \ + public: \ + static const httpd_method_t method = METHOD; \ + virtual esp_err_t on##NAME(Request&) = 0; \ + \ + protected: \ + esp_err_t handle_(httpd_req_t* req) \ + { \ + Request r(req); \ + return on##NAME(r); \ + } \ + }; \ +// using NAME = MethodBase; + +DECLARE_METHOD(Delete, HTTP_DELETE); +DECLARE_METHOD(Get, HTTP_GET); +DECLARE_METHOD(Post, HTTP_POST); +DECLARE_METHOD(Patch, HTTP_PATCH); + +#undef DECLARE_METHOD + +template class MethodNode +{ +protected: + bool canHandle_(httpd_method_t) const { return false; } + esp_err_t handle_(httpd_req_t*) { return ESP_FAIL; } +}; + +template +class MethodNode : public This, public MethodNode { +private: + using Next = MethodNode; + +protected: + bool canHandle_(httpd_method_t m) const { + return This::method == m || Next::canHandle_(m); + } + + esp_err_t handle_(httpd_req_t* req) { + if (This::method == req->method) { + return This::handle_(req); + } + return Next::handle_(req); + } +}; + +template +class MethodHandler : public RequestHandler, public MethodNode...> +{ +private: + using Nodes = MethodNode...>; + +public: + virtual bool canHandle(httpd_method_t method) const override{ + return Nodes::canHandle_(method); + } + + virtual esp_err_t handle(httpd_req_t* req) override + { + return Nodes::handle_(req); + } +}; + +class Server { +public: + Server(); + ~Server(); + + void registerHandler(const std::string& uri, RequestHandler& handler); + +protected: + httpd_handle_t server() const { return handle_; } + +private: + httpd_handle_t handle_; + static esp_err_t dispatch(httpd_req_t* req); +}; + +} // namespace httpd diff --git a/components/HttpServer/include/StaticAssetHandler.h b/components/HttpServer/include/StaticAssetHandler.h new file mode 100644 index 0000000..9fa3aca --- /dev/null +++ b/components/HttpServer/include/StaticAssetHandler.h @@ -0,0 +1,35 @@ +#pragma once + +#include "HttpServer.h" + +namespace httpd { + +struct StaticAsset { + const char* data; + size_t len; +}; + +// Initialize a StaticAsset from a file embedded in the build. The ASM address +// lookup must be a statement, so this abuses a lambda to scope it and return. +#define EmbeddedAsset(name__) \ + [] { \ + using httpd::StaticAsset; \ + extern const char start__[] asm("_binary_" #name__ "_start"); \ + extern size_t len__ asm(#name__ "_length"); \ + return StaticAsset{ start__, len__ }; \ + }() + +class StaticAssetHandler : public MethodHandler +{ +public: + StaticAssetHandler(const StaticAsset& asset, const std::string& contentType = "text/html"); + StaticAssetHandler(const char* data, size_t len, const std::string& contentType = "text/html"); + + esp_err_t onGet(httpd::Request& req); + +private: + StaticAsset asset_; + std::string contentType_; +}; + +} // namespace httpd diff --git a/components/HttpServer/include/WebSockets.h b/components/HttpServer/include/WebSockets.h new file mode 100644 index 0000000..c26e103 --- /dev/null +++ b/components/HttpServer/include/WebSockets.h @@ -0,0 +1,57 @@ +#pragma once + +#include "HttpServer.h" +#include + +#ifdef CONFIG_HTTPD_WS_SUPPORT + +namespace httpd { +class WSHandler; + +using WSFrame = httpd_ws_frame_t; + +class WSSocket { +public: + WSHandler& handler() { return handler_; } + httpd_handle_t server() const { return server_; } + int fd() const { return fd_; } + + esp_err_t send(std::string_view str, httpd_ws_type_t type = HTTPD_WS_TYPE_TEXT); + esp_err_t send(const uint8_t* data, size_t len, httpd_ws_type_t type = HTTPD_WS_TYPE_BINARY); + esp_err_t send(const WSFrame& frame); + +private: + friend class WSHandler; + + WSSocket(WSHandler& handler, httpd_handle_t server, int fd) + : handler_(handler), server_(server), fd_(fd){}; + + WSHandler& handler_; + httpd_handle_t server_; + int fd_; +}; + +class WSHandler : public RequestHandler { +public: + WSHandler(const std::string& subprotocols = std::string(), + bool controlFrames = false); + + const std::string& subprotocols() const { return subprotocols_; } + bool controlFrames() const { return controlFrames_; } + + virtual bool canHandle(httpd_method_t m) const final; + virtual esp_err_t handle(httpd_req_t* req) override; + + virtual esp_err_t onConnect(WSSocket&) = 0; + virtual esp_err_t onReceive(WSSocket&, const WSFrame&) = 0; + virtual void onClose(WSSocket&) {} + +private: + std::string subprotocols_; + bool controlFrames_; +}; + + +} // namespace httpd + +#endif // CONFIG_HTTPD_WS_SUPPORT diff --git a/components/Hub75Display/CMakeLists.txt b/components/Hub75Display/CMakeLists.txt new file mode 100644 index 0000000..61a34fd --- /dev/null +++ b/components/Hub75Display/CMakeLists.txt @@ -0,0 +1,7 @@ +idf_component_register( + SRCS "Hub75Display.c" + "i2s_parallel.c" + "val2pwm.c" + INCLUDE_DIRS "include" + REQUIRES "driver" + ) diff --git a/components/Hub75Display/Hub75Display.c b/components/Hub75Display/Hub75Display.c new file mode 100644 index 0000000..72a92ad --- /dev/null +++ b/components/Hub75Display/Hub75Display.c @@ -0,0 +1,375 @@ +// Copyright 2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "Hub75Display.h" +#include +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" +#include "freertos/semphr.h" +#include "freertos/task.h" + +#include "driver/gpio.h" +#include "esp_heap_caps.h" +#include "i2s_parallel.h" +#include "val2pwm.h" + +// This is example code to driver a p3(2121)64*32 -style RGB LED display. These +// types of displays do not have memory and need to be refreshed continuously. +// The display has 2 RGB inputs, 4 inputs to select the active line, a pixel +// clock input, a latch enable input and an output-enable input. The display can +// be seen as 2 64x16 displays consisting of the upper half and the lower half +// of the display. Each half has a separate RGB pixel input, the rest of the +// inputs are shared. +// +// Each display half can only show one line of RGB pixels at a time: to do this, +// the RGB data for the line is input by setting the RGB input pins to the +// desired value for the first pixel, giving the display a clock pulse, setting +// the RGB input pins to the desired value for the second pixel, giving a clock +// pulse, etc. Do this 64 times to clock in an entire row. The pixels will not +// be displayed yet: until the latch input is made high, the display will still +// send out the previously clocked in line. Pulsing the latch input high will +// replace the displayed data with the data just clocked in. +// +// The 4 line select inputs select where the currently active line is displayed: +// when provided with a binary number (0-15), the latched pixel data will +// immediately appear on this line. Note: While clocking in data for a line, the +// *previous* line is still displayed, and these lines should be set to the value +// to reflect the position the *previous* line is supposed to be on. +// +// Finally, the screen has an OE input, which is used to disable the LEDs when +// latching new data and changing the state of the line select inputs: doing so +// hides any artifacts that appear at this time. The OE line is also used to dim +// the display by only turning it on for a limited time every line. +// +// All in all, an image can be displayed by 'scanning' the display, say, 100 +// times per second. The slowness of the human eye hides the fact that only one +// line is showed at a time, and the display looks like every pixel is driven at +// the same time. +// +// Now, the RGB inputs for these types of displays are digital, meaning each +// red, green and blue subpixel can only be on or off. This leads to a color +// palette of 8 pixels, not enough to display nice pictures. To get around this, +// we use binary code modulation. +// +// Binary code modulation is somewhat like PWM, but easier to implement in our +// case. First, we define the time we would refresh the display without binary +// code modulation as the 'frame time'. For, say, a four-bit binary code +// modulation, the frame time is divided into 15 ticks of equal length. +// +// We also define 4 subframes (0 to 3), defining which LEDs are on and which +// LEDs are off during that subframe. (Subframes are the same as a normal frame +// in non-binary-coded-modulation mode, but are showed faster.) From our +// (non-monochrome) input image, we take the (8-bit: bit 7 to bit 0) RGB pixel +// values. If the pixel values have bit 7 set, we turn the corresponding LED on +// in subframe 3. If they have bit 6 set, we turn on the corresponding LED in +// subframe 2, if bit 5 is set subframe 1, if bit 4 is set in subframe 0. +// +// Now, in order to (on average within a frame) turn a LED on for the time +// specified in the pixel value in the input data, we need to weigh the +// subframes. We have 15 pixels: if we show subframe 3 for 8 of them, subframe 2 +// for 4 of them, subframe 1 for 2 of them and subframe 1 for 1 of them, this +// 'automatically' happens. (We also distribute the subframes evenly over the +// ticks, which reduces flicker.) +// +// +// In this code, we use the I2S peripheral in parallel mode to achieve this. +// Essentially, first we allocate memory for all subframes. This memory contains +// a sequence of all the signals (2xRGB, line select, latch enable, output +// enable) that need to be sent to the display for that subframe. Then we ask +// the I2S-parallel driver to set up a DMA chain so the subframes are sent out +// in a sequence that satisfies the requirement that subframe x has to be sent +// out for (2^x) ticks. Finally, we fill the subframes with image data. +// +// We use a frontbuffer/backbuffer technique here to make sure the display is +// refreshed in one go and drawing artifacts do not reach the display. In +// practice, for small displays this is not really necessarily. +// +// Finally, the binary code modulated intensity of a LED does not correspond to +// the intensity as seen by human eyes. To correct for that, a luminance +// correction is used. See val2pwm.c for more info. +// +// Note: Because every subframe contains one bit of grayscale information, they +// are also referred to as 'bitplanes' by the code below. + +#define matrixHeight 32 +#define matrixWidth 64 +#define matrixRowsInParallel 2 + +#define ESP32_NUM_FRAME_BUFFERS 2 +#define ESP32_OE_OFF_CLKS_AFTER_LATCH 1 + +// This is the bit depth, per RGB subpixel, of the data that is sent to the +// display. The effective bit depth (in computer pixel terms) is less because of +// the PWM correction. With a bitplane count of 7, you should be able to +// reproduce an 16-bit image more or less faithfully, though. +#define BITPLANE_CNT 7 + +// LSBMSB_TRANSITION_BIT defines the color bit that is refreshed once per frame, +// with the same brightness as the bits above it when LSBMSB_TRANSITION_BIT is +// non-zero, all color bits below it will be be refreshed only once, with +// fractional brightness, saving RAM and speeding up refresh LSBMSB_TRANSITION_BIT +// must be < BITPLANE_CNT +#define LSBMSB_TRANSITION_BIT 1 + +// 64*32 RGB leds, 2 pixels per 16-bit value... +#define BITPLANE_SZ (matrixWidth * matrixHeight / matrixRowsInParallel) + +// I2S Data Position Definitions +// Upper half RGB +#define BIT_R1 (1 << 0) +#define BIT_G1 (1 << 1) +#define BIT_B1 (1 << 2) +// Lower half RGB +#define BIT_R2 (1 << 3) +#define BIT_G2 (1 << 4) +#define BIT_B2 (1 << 5) + +#define BIT_A (1 << 8) +#define BIT_B (1 << 9) +#define BIT_C (1 << 10) +#define BIT_D (1 << 11) +#define BIT_LAT (1 << 12) +#define BIT_OE (1 << 13) + +// Pin Definitions +#define R1_PIN 21 +#define G1_PIN 19 +#define B1_PIN 18 +#define R2_PIN 5 +#define G2_PIN 17 +#define B2_PIN 16 + +#define A_PIN 4 +#define B_PIN 2 +#define C_PIN 25 +#define D_PIN 15 +#define LAT_PIN 26 +#define OE_PIN 27 + +#define CLK_PIN 22 + +// note: sizeof(data) must be multiple of 32 bits, as DMA linked list buffer +// address pointer must be word-aligned. +typedef struct rowBitStruct { + uint16_t data[matrixWidth]; +} rowBitStruct; + +typedef struct rowDataStruct { + rowBitStruct rowbits[BITPLANE_CNT]; +} rowDataStruct; + +typedef struct frameStruct { + rowDataStruct rowdata[matrixHeight / matrixRowsInParallel]; +} frameStruct; + +// Get a pixel from the image at pix, assuming the image is a matrixWidth x +// matrixHeight 8R8G8B8A image. Returns it as an uint32 with the lower 24 +// bits containing the RGB values. +static uint32_t +getpixel(const uint8_t* pix, int x, int y) +{ + int idx = (y * matrixWidth * 4) + (x * 4); + return ((uint32_t)valToPwm(pix[idx]) << 16) | + ((uint32_t)valToPwm(pix[idx + 1]) << 8) | + ((uint32_t)valToPwm(pix[idx + 2]) << 0); +} + +int brightness = 16; // Change to set the global brightness of the display, + // range 1-matrixWidth Warning when set too high: Do not + // look into LEDs with remaining eye. + +// TODO: find more efficient way of signaling the end of the buffer description +// than adding two extra rows +i2s_parallel_buffer_desc_t bufdesc[2][matrixHeight / matrixRowsInParallel + 1] + [1 << (BITPLANE_CNT - LSBMSB_TRANSITION_BIT - 1)]; + +i2s_parallel_config_t cfg = { + .gpio_bus = { R1_PIN, + G1_PIN, + B1_PIN, + R2_PIN, + G2_PIN, + B2_PIN, + -1, + -1, + A_PIN, + B_PIN, + C_PIN, + D_PIN, + LAT_PIN, + OE_PIN, + -1, + -1 }, + .gpio_clk = CLK_PIN, + .clkspeed_hz = 20 * 1000 * 1000, + .bits = I2S_PARALLEL_BITS_16, + .bufa = bufdesc[0][0], + .bufb = bufdesc[1][0], +}; + +// pixel data is organized from LSB to MSB sequentially by row, from row 0 to row +// matrixHeight/matrixRowsInParallel (two rows of pixels are refreshed in parallel) +frameStruct* bitplane; + +void +hub75DisplaySetup() +{ + bitplane = (frameStruct*)heap_caps_malloc(sizeof(frameStruct) * + ESP32_NUM_FRAME_BUFFERS, + MALLOC_CAP_DMA); + assert("Can't allocate bitplane memory"); + + for (int j = 0; j < matrixHeight / matrixRowsInParallel; j++) { + // first set of data is LSB through MSB, single pass - all color bits + // are displayed once, which takes care of everything below and + // inlcluding LSBMSB_TRANSITION_BIT + bufdesc[0][j][0].memory = bitplane[0].rowdata[j].rowbits[0].data; + bufdesc[0][j][0].size = sizeof(rowBitStruct) * BITPLANE_CNT; + bufdesc[1][j][0].memory = bitplane[1].rowdata[j].rowbits[0].data; + bufdesc[1][j][0].size = sizeof(rowBitStruct) * BITPLANE_CNT; + + int nextBufdescIndex = 1; + + for (int i = LSBMSB_TRANSITION_BIT + 1; i < BITPLANE_CNT; i++) { + // binary time division setup: we need 2 of bit + // (LSBMSB_TRANSITION_BIT + 1) four of (LSBMSB_TRANSITION_BIT + 2), + // etc because we sweep through to MSB each time, it divides the + // number of times we have to sweep in half (saving linked list RAM) + // we need 2^(i - LSBMSB_TRANSITION_BIT - 1) == 1 << (i - + // LSBMSB_TRANSITION_BIT - 1) passes from i to MSB + // printf("buffer %d: repeat %d times, size: %d, from %d - %d\r\n", + // nextBufdescIndex, 1<<(i - LSBMSB_TRANSITION_BIT - 1), + // (BITPLANE_CNT - i), i, BITPLANE_CNT-1); + + for (int k = 0; k < 1 << (i - LSBMSB_TRANSITION_BIT - 1); k++) { + bufdesc[0][j][nextBufdescIndex].memory = + bitplane[0].rowdata[j].rowbits[i].data; + bufdesc[0][j][nextBufdescIndex].size = + sizeof(rowBitStruct) * (BITPLANE_CNT - i); + bufdesc[1][j][nextBufdescIndex].memory = + bitplane[1].rowdata[j].rowbits[i].data; + bufdesc[1][j][nextBufdescIndex].size = + sizeof(rowBitStruct) * (BITPLANE_CNT - i); + nextBufdescIndex++; + // printf("i %d, j %d, k %d\r\n", i, j, k); + } + } + } + + // End markers + bufdesc[0][matrixHeight / matrixRowsInParallel][0].memory = NULL; + bufdesc[1][matrixHeight / matrixRowsInParallel][0].memory = NULL; + + // Setup I2S + i2s_parallel_setup(&I2S1, &cfg); +} + +void +hub75DisplayDraw(const uint8_t* pix) +{ + static int backbuf_id = 0; // which buffer is the backbuffer, as in, which + // one is not active so we can write to it + + for (unsigned int y = 0; y < matrixHeight / matrixRowsInParallel; y++) { + for (int pl = 0; pl < BITPLANE_CNT; pl++) { + uint16_t* p = + bitplane[backbuf_id].rowdata[y].rowbits[pl].data; // bitplane + // location to + // write to + int mask = + (1 << (8 - BITPLANE_CNT + pl)); // bitmask for pixel data in + // input for this bitplane + int lbits = 0; // Precalculate line bits of the current line, which + // is the one we're displaying now + int rowAddress = y; + + // normally output current rows ADDX, special case for LSB, output + // previous row's ADDX (as previous row is being displayed for one + // latch cycle) + if (pl == 0) + rowAddress = y - 1; + + if (rowAddress & 1) + lbits |= BIT_A; + if (rowAddress & 2) + lbits |= BIT_B; + if (rowAddress & 4) + lbits |= BIT_C; + if (rowAddress & 8) + lbits |= BIT_D; + for (int fx = 0; fx < matrixWidth; fx++) { + int x = fx; + int v = lbits; + // Do not show image while the line bits are changing + if (fx < ESP32_OE_OFF_CLKS_AFTER_LATCH || fx >= (matrixWidth - 1)) + v |= BIT_OE; + + // turn off OE after brightness value is reached - used for MSBs + // and LSB MSBs always output normal brightness LSB outputs + // normal brightness as MSB from previous row is being displayed + if ((pl > LSBMSB_TRANSITION_BIT || !pl) && + fx > brightness + ESP32_OE_OFF_CLKS_AFTER_LATCH) + v |= BIT_OE; + + // special case for the bits *after* LSB through + // (LSBMSB_TRANSITION_BIT) - OE is output after data is shifted, + // so need to set OE to fractional brightness + if (pl && pl <= LSBMSB_TRANSITION_BIT) { + // divide brightness in half for each bit below + // LSBMSB_TRANSITION_BIT + int lsbBrightness = + brightness >> (LSBMSB_TRANSITION_BIT - pl + 1); + if (fx > lsbBrightness + ESP32_OE_OFF_CLKS_AFTER_LATCH) + v |= BIT_OE; + } + + if (fx == matrixWidth - 1) + v |= BIT_LAT; // latch on last bit + + int c1, c2; + c1 = getpixel(pix, x, y); + c2 = getpixel(pix, x, y + (matrixHeight / 2)); + + if (c1 & (mask << 16)) + v |= BIT_R1; + if (c1 & (mask << 8)) + v |= BIT_G1; + if (c1 & (mask << 0)) + v |= BIT_B1; + if (c2 & (mask << 16)) + v |= BIT_R2; + if (c2 & (mask << 8)) + v |= BIT_G2; + if (c2 & (mask << 0)) + v |= BIT_B2; + + // Save the calculated value to the bitplane memory in reverse + // order to account for I2S Tx FIFO mode1 ordering + if (fx % 2) { + *p = v; + p += 2; + } else { + *(p + 1) = v; + } + } + } + } + + // Show our work! + i2s_parallel_flip_to_buffer(&I2S1, backbuf_id); + backbuf_id ^= 1; +} diff --git a/components/Hub75Display/i2s_parallel.c b/components/Hub75Display/i2s_parallel.c new file mode 100644 index 0000000..61e365b --- /dev/null +++ b/components/Hub75Display/i2s_parallel.c @@ -0,0 +1,271 @@ +// Copyright 2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include +#include +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" + +#include "esp_log.h" +#include "esp_private/periph_ctrl.h" +#include "soc/i2s_struct.h" +#include "soc/i2s_reg.h" +#include "soc/gpio_sig_map.h" +#include "soc/io_mux_reg.h" +#include "driver/gpio.h" +#include "rom/lldesc.h" +#include "rom/gpio.h" +#include "esp_heap_caps.h" +#include "val2pwm.h" +#include "i2s_parallel.h" + +static const char* TAG = "i2s_parallel"; + +typedef struct { + volatile lldesc_t *dmadesc_a, *dmadesc_b; + int desccount_a, desccount_b; +} i2s_parallel_state_t; + +static i2s_parallel_state_t *i2s_state[2]={NULL, NULL}; + +#define DMA_MAX (4096-4) + +//Calculate the amount of dma descs needed for a buffer desc +static int calc_needed_dma_descs_for(i2s_parallel_buffer_desc_t *desc) { + int ret=0; + for (int i=0; desc[i].memory!=NULL; i++) { + ret+=(desc[i].size+DMA_MAX-1)/DMA_MAX; + } + return ret; +} + +static void fill_dma_desc(volatile lldesc_t *dmadesc, i2s_parallel_buffer_desc_t *bufdesc) { + int n=0; + for (int i=0; bufdesc[i].memory!=NULL; i++) { + int len=bufdesc[i].size; + uint8_t *data=(uint8_t*)bufdesc[i].memory; + //printf("fill_dma_desc: n %d data %x size %d\n", n, (uint32_t)bufdesc[i].memory, bufdesc[i].size); + while(len) { + int dmalen=len; + if (dmalen>DMA_MAX) dmalen=DMA_MAX; + dmadesc[n].size=dmalen; + dmadesc[n].length=dmalen; + dmadesc[n].buf=data; + dmadesc[n].eof=0; + dmadesc[n].sosf=0; + dmadesc[n].owner=1; + dmadesc[n].qe.stqe_next=(lldesc_t*)&dmadesc[n+1]; + dmadesc[n].offset=0; + len-=dmalen; + data+=dmalen; + n++; + } + } + //Loop last back to first + dmadesc[n-1].qe.stqe_next=(lldesc_t*)&dmadesc[0]; + printf("fill_dma_desc: filled %d descriptors\n", n); +} + +static void gpio_setup_out(int gpio, int sig) { + ESP_LOGI(TAG, "Pin: %d, Sig: %d", gpio, sig); + if (gpio==-1) return; + gpio_reset_pin(gpio); + gpio_set_direction(gpio, GPIO_MODE_DEF_OUTPUT); + gpio_matrix_out(gpio, sig, false, false); + gpio_dump_io_configuration(stdout, 1<lc_conf.in_rst=1; dev->lc_conf.in_rst=0; + dev->lc_conf.out_rst=1; dev->lc_conf.out_rst=0; +} + +static void fifo_reset(i2s_dev_t *dev) { + dev->conf.rx_fifo_reset=1; dev->conf.rx_fifo_reset=0; + dev->conf.tx_fifo_reset=1; dev->conf.tx_fifo_reset=0; +} + +static int i2snum(i2s_dev_t *dev) { + return (dev==&I2S0)?0:1; +} + +void i2s_parallel_setup(i2s_dev_t *dev, const i2s_parallel_config_t *cfg) { + //Figure out which signal numbers to use for routing + ESP_LOGI(TAG, "Setting up parallel I2S bus at I2S%d\n", i2snum(dev)); + int sig_data_base, sig_clk; + if (dev==&I2S0) { + sig_clk=I2S0O_WS_OUT_IDX; + if (cfg->bits==I2S_PARALLEL_BITS_32) { + sig_data_base=I2S0O_DATA_OUT0_IDX; + } else { + //Because of... reasons... the 16-bit values for i2s0 appear on d8...d23 + sig_data_base=I2S0O_DATA_OUT8_IDX; + } + } else { + if (cfg->bits==I2S_PARALLEL_BITS_32) { + sig_data_base=I2S1O_DATA_OUT0_IDX; + } else if (cfg->bits==I2S_PARALLEL_BITS_16) { + //Because of... reasons... the 16-bit values for i2s1 appear on d8...d23 + sig_data_base=I2S1O_DATA_OUT8_IDX; + } else { + sig_data_base=I2S1O_DATA_OUT0_IDX; + } + sig_clk=I2S1O_WS_OUT_IDX; + } + + //Route the signals + + for (int x=0; xbits; x++) { + gpio_setup_out(cfg->gpio_bus[x], sig_data_base+x); + } + //ToDo: Clk/WS may need inversion? + gpio_setup_out(cfg->gpio_clk, sig_clk); + + //Power on dev + if (dev==&I2S0) { + periph_module_enable(PERIPH_I2S0_MODULE); + } else { + periph_module_enable(PERIPH_I2S1_MODULE); + } + //Initialize I2S dev + dev->conf.rx_reset=1; dev->conf.rx_reset=0; + dev->conf.tx_reset=1; dev->conf.tx_reset=0; + dma_reset(dev); + fifo_reset(dev); + + //Enable LCD mode + dev->conf2.val=0; + dev->conf2.lcd_en=1; + + dev->sample_rate_conf.val=0; + dev->sample_rate_conf.rx_bits_mod=cfg->bits; + dev->sample_rate_conf.tx_bits_mod=cfg->bits; + dev->sample_rate_conf.rx_bck_div_num=4; //ToDo: Unsure about what this does... + //dev->sample_rate_conf.tx_bck_div_num=4; + dev->sample_rate_conf.tx_bck_div_num=2; // datasheet says this must be 2 or greater (but 1 seems to work) + + dev->clkm_conf.val=0; + dev->clkm_conf.clka_en=0; + dev->clkm_conf.clkm_div_a=63; + dev->clkm_conf.clkm_div_b=63; + //We ignore the possibility for fractional division here. + //dev->clkm_conf.clkm_div_num=80000000L/cfg->clkspeed_hz; + dev->clkm_conf.clkm_div_num=4; // datasheet says this must be 2 or greater (but lower values seem to work) + + // this combination is 25MHz + //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) + //dev->clkm_conf.clkm_div_num=2; // datasheet says this must be 2 or greater (but lower values seem to work) + + // this combination is 20MHz + //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) + //dev->clkm_conf.clkm_div_num=3; // datasheet says this must be 2 or greater (but lower values seem to work) + + // 16 MHz + //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) + //dev->clkm_conf.clkm_div_num=4; // datasheet says this must be 2 or greater (but lower values seem to work) + + // 13MHz + //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) + //dev->clkm_conf.clkm_div_num=5; // datasheet says this must be 2 or greater (but lower values seem to work) + + // 11.3MHz + //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) + //dev->clkm_conf.clkm_div_num=6; // datasheet says this must be 2 or greater (but lower values seem to work) + + // 13.x MHz + //dev->sample_rate_conf.tx_bck_div_num=2; // datasheet says this must be 2 or greater (but 1 seems to work) + //dev->clkm_conf.clkm_div_num=2; // datasheet says this must be 2 or greater (but lower values seem to work) + + // 10MHz + //dev->sample_rate_conf.tx_bck_div_num=2; // datasheet says this must be 2 or greater (but 1 seems to work) + //dev->clkm_conf.clkm_div_num=3; // datasheet says this must be 2 or greater (but lower values seem to work) + + // 8MHz + //dev->sample_rate_conf.tx_bck_div_num=2; // datasheet says this must be 2 or greater (but 1 seems to work) + //dev->clkm_conf.clkm_div_num=4; // datasheet says this must be 2 or greater (but lower values seem to work) + + + + dev->fifo_conf.val=0; + dev->fifo_conf.rx_fifo_mod_force_en=1; + dev->fifo_conf.tx_fifo_mod_force_en=1; + //dev->fifo_conf.tx_fifo_mod=1; + dev->fifo_conf.tx_fifo_mod=1; + dev->fifo_conf.rx_data_num=32; //Thresholds. + dev->fifo_conf.tx_data_num=32; + dev->fifo_conf.dscr_en=1; + + dev->conf1.val=0; + dev->conf1.tx_stop_en=0; + dev->conf1.tx_pcm_bypass=1; + + dev->conf_chan.val=0; + dev->conf_chan.tx_chan_mod=1; + dev->conf_chan.rx_chan_mod=1; + + //Invert ws to be active-low... ToDo: make this configurable + //dev->conf.tx_right_first=1; + dev->conf.tx_right_first=0; + //dev->conf.rx_right_first=1; + dev->conf.rx_right_first=0; + + dev->timing.val=0; + + //Allocate DMA descriptors + i2s_state[i2snum(dev)]=malloc(sizeof(i2s_parallel_state_t)); + i2s_parallel_state_t *st=i2s_state[i2snum(dev)]; + st->desccount_a=calc_needed_dma_descs_for(cfg->bufa); + st->desccount_b=calc_needed_dma_descs_for(cfg->bufb); + st->dmadesc_a=heap_caps_malloc(st->desccount_a*sizeof(lldesc_t), MALLOC_CAP_DMA); + st->dmadesc_b=heap_caps_malloc(st->desccount_b*sizeof(lldesc_t), MALLOC_CAP_DMA); + + //and fill them + fill_dma_desc(st->dmadesc_a, cfg->bufa); + fill_dma_desc(st->dmadesc_b, cfg->bufb); + + //Reset FIFO/DMA -> needed? Doesn't dma_reset/fifo_reset do this? + dev->lc_conf.in_rst=1; dev->lc_conf.out_rst=1; dev->lc_conf.ahbm_rst=1; dev->lc_conf.ahbm_fifo_rst=1; + dev->lc_conf.in_rst=0; dev->lc_conf.out_rst=0; dev->lc_conf.ahbm_rst=0; dev->lc_conf.ahbm_fifo_rst=0; + dev->conf.tx_reset=1; dev->conf.tx_fifo_reset=1; dev->conf.rx_fifo_reset=1; + dev->conf.tx_reset=0; dev->conf.tx_fifo_reset=0; dev->conf.rx_fifo_reset=0; + + //Start dma on front buffer + dev->lc_conf.val=I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN | I2S_OUT_DATA_BURST_EN; + dev->out_link.addr=((uint32_t)(&st->dmadesc_a[0])); + dev->out_link.start=1; + dev->conf.tx_start=1; +} + + +//Flip to a buffer: 0 for bufa, 1 for bufb +void i2s_parallel_flip_to_buffer(i2s_dev_t *dev, int bufid) { + int no=i2snum(dev); + if (i2s_state[no]==NULL) return; + lldesc_t *active_dma_chain; + if (bufid==0) { + active_dma_chain=(lldesc_t*)&i2s_state[no]->dmadesc_a[0]; + } else { + active_dma_chain=(lldesc_t*)&i2s_state[no]->dmadesc_b[0]; + } + + i2s_state[no]->dmadesc_a[i2s_state[no]->desccount_a-1].qe.stqe_next=active_dma_chain; + i2s_state[no]->dmadesc_b[i2s_state[no]->desccount_b-1].qe.stqe_next=active_dma_chain; +} + diff --git a/components/Hub75Display/i2s_parallel.h b/components/Hub75Display/i2s_parallel.h new file mode 100644 index 0000000..2b98765 --- /dev/null +++ b/components/Hub75Display/i2s_parallel.h @@ -0,0 +1,37 @@ +#ifndef I2S_PARALLEL_H +#define I2S_PARALLEL_H + +#include +#include "soc/i2s_struct.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + I2S_PARALLEL_BITS_8=8, + I2S_PARALLEL_BITS_16=16, + I2S_PARALLEL_BITS_32=32, +} i2s_parallel_cfg_bits_t; + +typedef struct { + void *memory; + size_t size; +} i2s_parallel_buffer_desc_t; + +typedef struct { + int gpio_bus[24]; + int gpio_clk; + int clkspeed_hz; + i2s_parallel_cfg_bits_t bits; + i2s_parallel_buffer_desc_t *bufa; + i2s_parallel_buffer_desc_t *bufb; +} i2s_parallel_config_t; + +void i2s_parallel_setup(i2s_dev_t *dev, const i2s_parallel_config_t *cfg); +void i2s_parallel_flip_to_buffer(i2s_dev_t *dev, int bufid); + +#ifdef __cplusplus +} // extern "C" +#endif +#endif diff --git a/components/Hub75Display/include/Hub75Display.h b/components/Hub75Display/include/Hub75Display.h new file mode 100644 index 0000000..cc2b1c1 --- /dev/null +++ b/components/Hub75Display/include/Hub75Display.h @@ -0,0 +1,13 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void hub75DisplaySetup(); +void hub75DisplayDraw(const uint8_t*); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/components/Hub75Display/val2pwm.c b/components/Hub75Display/val2pwm.c new file mode 100644 index 0000000..cb3df5e --- /dev/null +++ b/components/Hub75Display/val2pwm.c @@ -0,0 +1,59 @@ +// Copyright 2017 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +#include +#include "val2pwm.h" + +//C/p'ed from https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ +const uint16_t lumConvTab[]={ + 65535, 65508, 65479, 65451, 65422, 65394, 65365, 65337, + 65308, 65280, 65251, 65223, 65195, 65166, 65138, 65109, + 65081, 65052, 65024, 64995, 64967, 64938, 64909, 64878, + 64847, 64815, 64781, 64747, 64711, 64675, 64637, 64599, + 64559, 64518, 64476, 64433, 64389, 64344, 64297, 64249, + 64200, 64150, 64099, 64046, 63992, 63937, 63880, 63822, + 63763, 63702, 63640, 63577, 63512, 63446, 63379, 63310, + 63239, 63167, 63094, 63019, 62943, 62865, 62785, 62704, + 62621, 62537, 62451, 62364, 62275, 62184, 62092, 61998, + 61902, 61804, 61705, 61604, 61501, 61397, 61290, 61182, + 61072, 60961, 60847, 60732, 60614, 60495, 60374, 60251, + 60126, 59999, 59870, 59739, 59606, 59471, 59334, 59195, + 59053, 58910, 58765, 58618, 58468, 58316, 58163, 58007, + 57848, 57688, 57525, 57361, 57194, 57024, 56853, 56679, + 56503, 56324, 56143, 55960, 55774, 55586, 55396, 55203, + 55008, 54810, 54610, 54408, 54203, 53995, 53785, 53572, + 53357, 53140, 52919, 52696, 52471, 52243, 52012, 51778, + 51542, 51304, 51062, 50818, 50571, 50321, 50069, 49813, + 49555, 49295, 49031, 48764, 48495, 48223, 47948, 47670, + 47389, 47105, 46818, 46529, 46236, 45940, 45641, 45340, + 45035, 44727, 44416, 44102, 43785, 43465, 43142, 42815, + 42486, 42153, 41817, 41478, 41135, 40790, 40441, 40089, + 39733, 39375, 39013, 38647, 38279, 37907, 37531, 37153, + 36770, 36385, 35996, 35603, 35207, 34808, 34405, 33999, + 33589, 33175, 32758, 32338, 31913, 31486, 31054, 30619, + 30181, 29738, 29292, 28843, 28389, 27932, 27471, 27007, + 26539, 26066, 25590, 25111, 24627, 24140, 23649, 23153, + 22654, 22152, 21645, 21134, 20619, 20101, 19578, 19051, + 18521, 17986, 17447, 16905, 16358, 15807, 15252, 14693, + 14129, 13562, 12990, 12415, 11835, 11251, 10662, 10070, + 9473, 8872, 8266, 7657, 7043, 6424, 5802, 5175, + 4543, 3908, 3267, 2623, 1974, 1320, 662, 0}; + + +uint8_t valToPwm(int val) { + if (val<0) val=0; + if (val>255) val=255; + return (65535-lumConvTab[val])>>8; +} diff --git a/components/Hub75Display/val2pwm.h b/components/Hub75Display/val2pwm.h new file mode 100644 index 0000000..218ab4a --- /dev/null +++ b/components/Hub75Display/val2pwm.h @@ -0,0 +1,8 @@ +#ifdef __cplusplus +extern "C" { +#endif +//Converts an 0-255 intensity value to an equivalent 0-255 LED PWM value +uint8_t valToPwm(int val); +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/components/libwebp/CMakeLists.txt b/components/libwebp/CMakeLists.txt new file mode 100644 index 0000000..1d7fc31 --- /dev/null +++ b/components/libwebp/CMakeLists.txt @@ -0,0 +1,100 @@ +idf_component_register( + SRCS + libwebp/src/dec/alpha_dec.c + libwebp/src/dec/buffer_dec.c + libwebp/src/dec/frame_dec.c + libwebp/src/dec/idec_dec.c + libwebp/src/dec/io_dec.c + libwebp/src/dec/quant_dec.c + libwebp/src/dec/tree_dec.c + libwebp/src/dec/vp8_dec.c + libwebp/src/dec/vp8l_dec.c + libwebp/src/dec/webp_dec.c + libwebp/src/demux/anim_decode.c + libwebp/src/demux/demux.c + libwebp/src/dsp/alpha_processing.c + libwebp/src/dsp/alpha_processing_mips_dsp_r2.c + libwebp/src/dsp/alpha_processing_neon.c + libwebp/src/dsp/alpha_processing_sse2.c + libwebp/src/dsp/alpha_processing_sse41.c + libwebp/src/dsp/cost.c + libwebp/src/dsp/cost_mips32.c + libwebp/src/dsp/cost_mips_dsp_r2.c + libwebp/src/dsp/cost_neon.c + libwebp/src/dsp/cost_sse2.c + libwebp/src/dsp/cpu.c + libwebp/src/dsp/dec.c + libwebp/src/dsp/dec_clip_tables.c + libwebp/src/dsp/dec_mips32.c + libwebp/src/dsp/dec_mips_dsp_r2.c + libwebp/src/dsp/dec_msa.c + libwebp/src/dsp/dec_neon.c + libwebp/src/dsp/dec_sse2.c + libwebp/src/dsp/dec_sse41.c + libwebp/src/dsp/enc.c + libwebp/src/dsp/enc_mips32.c + libwebp/src/dsp/enc_mips_dsp_r2.c + libwebp/src/dsp/enc_msa.c + libwebp/src/dsp/enc_neon.c + libwebp/src/dsp/enc_sse2.c + libwebp/src/dsp/enc_sse41.c + libwebp/src/dsp/filters.c + libwebp/src/dsp/filters_mips_dsp_r2.c + libwebp/src/dsp/filters_msa.c + libwebp/src/dsp/filters_neon.c + libwebp/src/dsp/filters_sse2.c + libwebp/src/dsp/lossless.c + libwebp/src/dsp/lossless_enc.c + libwebp/src/dsp/lossless_enc_mips32.c + libwebp/src/dsp/lossless_enc_mips_dsp_r2.c + libwebp/src/dsp/lossless_enc_msa.c + libwebp/src/dsp/lossless_enc_neon.c + libwebp/src/dsp/lossless_enc_sse2.c + libwebp/src/dsp/lossless_enc_sse41.c + libwebp/src/dsp/lossless_mips_dsp_r2.c + libwebp/src/dsp/lossless_msa.c + libwebp/src/dsp/lossless_neon.c + libwebp/src/dsp/lossless_sse2.c + libwebp/src/dsp/lossless_sse41.c + libwebp/src/dsp/rescaler.c + libwebp/src/dsp/rescaler_mips32.c + libwebp/src/dsp/rescaler_mips_dsp_r2.c + libwebp/src/dsp/rescaler_msa.c + libwebp/src/dsp/rescaler_neon.c + libwebp/src/dsp/rescaler_sse2.c + libwebp/src/dsp/ssim.c + libwebp/src/dsp/ssim_sse2.c + libwebp/src/dsp/upsampling.c + libwebp/src/dsp/upsampling_mips_dsp_r2.c + libwebp/src/dsp/upsampling_msa.c + libwebp/src/dsp/upsampling_neon.c + libwebp/src/dsp/upsampling_sse2.c + libwebp/src/dsp/upsampling_sse41.c + libwebp/src/dsp/yuv.c + libwebp/src/dsp/yuv_mips32.c + libwebp/src/dsp/yuv_mips_dsp_r2.c + libwebp/src/dsp/yuv_neon.c + libwebp/src/dsp/yuv_sse2.c + libwebp/src/dsp/yuv_sse41.c + libwebp/src/mux/anim_encode.c + libwebp/src/mux/muxedit.c + libwebp/src/mux/muxinternal.c + libwebp/src/mux/muxread.c + libwebp/src/utils/bit_reader_utils.c + libwebp/src/utils/bit_writer_utils.c + libwebp/src/utils/color_cache_utils.c + libwebp/src/utils/filters_utils.c + libwebp/src/utils/huffman_encode_utils.c + libwebp/src/utils/huffman_utils.c + libwebp/src/utils/quant_levels_dec_utils.c + libwebp/src/utils/quant_levels_utils.c + libwebp/src/utils/random_utils.c + libwebp/src/utils/rescaler_utils.c + libwebp/src/utils/thread_utils.c + libwebp/src/utils/utils.c + INCLUDE_DIRS + libwebp/src + PRIV_INCLUDE_DIRS + libwebp/ +) + diff --git a/components/libwebp/libwebp b/components/libwebp/libwebp new file mode 160000 index 0000000..eba03ac --- /dev/null +++ b/components/libwebp/libwebp @@ -0,0 +1 @@ +Subproject commit eba03acb05383c4cd8ff9a3d18a213fbdcda865d diff --git a/main/Animation.cc b/main/Animation.cc new file mode 100644 index 0000000..50a2101 --- /dev/null +++ b/main/Animation.cc @@ -0,0 +1,69 @@ +#include "Animation.h" + +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/semphr.h" +#include "freertos/queue.h" +//#include "esp_log.h" + +#include "Hub75Display.h" + +//const char TAG[] = "Anim"; + +struct QueueEntry { + Image* image; + TaskHandle_t callingTask; +}; + +static QueueHandle_t imageQueue; + +static void +animationTask(void*) +{ + hub75DisplaySetup(); + + std::unique_ptr image; + auto delay = portMAX_DELAY; + while (true) { + QueueEntry next{}; + bool qr = xQueueReceive(imageQueue, &next, delay); + if (qr) { + image.reset(next.image); + // Tell the calling task we've released the old buffer + xTaskNotifyGive(next.callingTask); + } + if (image) { + uint32_t nextFrame = image->render(&hub75DisplayDraw); + if (nextFrame == Image::ANIMATION_END) { + delay = portMAX_DELAY; + image.reset(); + } else { + delay = nextFrame / portTICK_PERIOD_MS; + } + } + } +} + +void animationSetup() +{ + imageQueue = xQueueCreate(1, sizeof(QueueEntry)); + xTaskCreate(animationTask, "animationTask", 4096, nullptr, 10, nullptr); +} + +void animationStart(std::unique_ptr&& image) +{ + // Setup so the animation thread can send a direct to task notification + // back to us once it's released any buffers from the previously running + // animation. This way we can try to maximize the amount of free RAM for + // the incoming animation before allocating it. + QueueEntry e{ image.get(), xTaskGetCurrentTaskHandle() }; + xTaskNotifyStateClear(e.callingTask); + if (xQueueSendToBack(imageQueue, &e, 0)) { + // Successfully enqueued the work item so the animation thread will + // take ownership of the passed Image, so release our ownership of it + // and block until we get the signal from the Animation thread + // any previous buffers are freed. + image.release(); + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + } +} diff --git a/main/Animation.h b/main/Animation.h new file mode 100644 index 0000000..d8f0d42 --- /dev/null +++ b/main/Animation.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include + +#include + +void animationSetup(); +void animationStart(std::unique_ptr&& image); + diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 0000000..5f5c148 --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,11 @@ +idf_component_register(SRCS "main.cc" + "Animation.cc" + "NetManager.cc" + "Config.cc" + "NvsFlash.cc" + "RootPage.cc" + "WebPImage.cc" + EMBED_FILES nyan_64x32.webp + INCLUDE_DIRS ".") + +target_compile_options(${COMPONENT_LIB} PRIVATE "-std=gnu++17") diff --git a/main/Config.cc b/main/Config.cc new file mode 100644 index 0000000..c74987a --- /dev/null +++ b/main/Config.cc @@ -0,0 +1,82 @@ +#include "Config.h" + +#include "esp_log.h" +#include "esp_random.h" + +#include "NvsFlash.h" + +static const char* TAG = "CONFIG"; + +namespace { +std::string generateClientId() +{ + // Make a v4 UUID per RFC 4122 section 4.4 + static int KEYLEN = 16; + static const char ENC[] = "0123456789abcdef"; + uint8_t key[KEYLEN]; + esp_fill_random(key, KEYLEN); + key[8] = (key[8] & 0x3f) | 0x80; + key[6] = (key[6] & 0x0f) | 0x40; + + std::string out; + for (int i = 0; i < KEYLEN; ++i) { + out.push_back(ENC[(key[i] & 0xf0) >> 4]); + out.push_back(ENC[key[i] & 0x0f]); + if (i == 3 || i == 5 || i == 7 || i == 9) { + out.push_back('-'); + } + } + ESP_LOGD(TAG, "Generated device UUID %s", out.c_str()); + return out; +} +} // namespace + +Config& Config::instance() { + static Config cfg; + return cfg; +} + +Config::Config() +{ + NvsFlash flash("PixelMatrix", NVS_READWRITE); + + esp_err_t rv = flash.getString("endpoint", endpoint_); + if (ESP_ERR_NVS_NOT_FOUND == rv) { + endpoint_ = "192.168.4.59"; + } + + rv = flash.getU16("port", port_); + if (ESP_ERR_NVS_NOT_FOUND == rv) { + port_ = 8080; + } + + rv = flash.getString("deviceUUID", deviceUUID_); + if (ESP_ERR_NVS_NOT_FOUND == rv) { + // Legacy NVS + rv = flash.getString("clientId", deviceUUID_); + if (ESP_OK == rv) { + (void)flash.setString("deviceUUID", deviceUUID_); + (void)flash.eraseKey("clientId"); + } + } + + if (ESP_ERR_NVS_NOT_FOUND == rv || deviceUUID_.size() != 36) { + deviceUUID_ = generateClientId(); + rv = flash.setString("deviceUUID", deviceUUID_); + ESP_ERROR_CHECK(rv); + rv = flash.commit(); + ESP_ERROR_CHECK(rv); + } + ESP_LOGI(TAG, "Device UUID: %s", deviceUUID_.c_str()); +} + +std::string +Config::imageUri() const { + std::string uri = "ws://"; + uri.append(endpoint_) + .append(":") + .append(std::to_string(port_)) + .append("/ws?device=") + .append(deviceUUID_); + return uri; +} diff --git a/main/Config.h b/main/Config.h new file mode 100644 index 0000000..a07cb23 --- /dev/null +++ b/main/Config.h @@ -0,0 +1,19 @@ +#pragma once +#include + +class Config +{ +public: + static Config& instance(); + + std::string imageUri() const; + const std::string& deviceUUID() const { return deviceUUID_; } + const std::string& endpoint() const { return endpoint_; } + +private: + Config(); + + std::string endpoint_; + uint16_t port_; + std::string deviceUUID_; +}; diff --git a/main/Display.h b/main/Display.h new file mode 100644 index 0000000..ad83e3e --- /dev/null +++ b/main/Display.h @@ -0,0 +1,4 @@ +#pragma once +#include + + diff --git a/main/Image.h b/main/Image.h new file mode 100644 index 0000000..e5b8064 --- /dev/null +++ b/main/Image.h @@ -0,0 +1,79 @@ +#pragma once +#include +#include + +// TODO: This needs to be project-wide and pushed into the Hub75 Driver. +static const uint32_t IMAGE_WIDTH = 64; +static const uint32_t IMAGE_HEIGHT = 32; + +// Abstract base class representing an image (of fixed +// IMAGE_WIDTH * IMAGE_HEIGHT) that can be rendered. +class Image { +public: + virtual ~Image() = default; + + virtual bool valid() const = 0; + + typedef std::function DrawFunction; + static const uint32_t ANIMATION_END = 0xFFFFFFFF; + + // If a frame is available, render the image by passing a bitmap + // in R8G8B8A8 format to the supplied draw function. Returns the + // delay (in ms) until the next call to render(), or ANIMATION_END + // if this image is complete and should be disposed of. + virtual uint32_t render(DrawFunction fn) = 0; +}; + +// Abstract base class representing a bitstream of encoded image data. +class ImageSource { +public: + virtual ~ImageSource() = default; + + virtual const uint8_t* data() const = 0; + virtual size_t size() const = 0; +}; + +// Image bitstream data read directly from flash that does not require +// lifecycle management. +class StaticImageSource : public ImageSource { +public: + constexpr StaticImageSource(const uint8_t* start, const uint8_t* end): data_(start), size_(end - start) {} + virtual ~StaticImageSource() = default; + + virtual const uint8_t* data() const override { return data_; } + virtual size_t size() const override { return size_; } +private: + const uint8_t* data_; + size_t size_; +}; + +// Image bitstream data on the heap that must be freed when no longer +// referenced by an image. +class HeapImageSource : public ImageSource { +public: + HeapImageSource(size_t resv): overrun_(false) { vec_.reserve(resv); } + virtual ~HeapImageSource() = default; + + virtual const uint8_t* data() const override { return vec_.data(); } + virtual size_t size() const override { return vec_.size(); } + size_t capacity() const { return vec_.capacity(); } + + bool append(const uint8_t* buf, size_t len) + { + if (len && !overrun_) { + if (vec_.size() + len < vec_.capacity()) { + vec_.insert(vec_.end(), buf, buf + len); + } else { + overrun_ = true; + } + } + return !overrun_; + } + + std::vector& vec() { return vec_; } + +private: + bool overrun_; + std::vector vec_; +}; + diff --git a/main/NetManager.cc b/main/NetManager.cc new file mode 100644 index 0000000..4518aa4 --- /dev/null +++ b/main/NetManager.cc @@ -0,0 +1,122 @@ +#include "NetManager.h" + +#include + +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" + +#include "esp_event.h" +#include "esp_log.h" +#include "esp_mac.h" +#include "esp_system.h" +#include "esp_wifi.h" + +#include "lwip/err.h" +#include "lwip/sys.h" + +#include "nvs_flash.h" + +namespace { +const char* TAG = "NetManager"; + +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static void +startEventHandler(void* arg, + esp_event_base_t eventBase, + int32_t eventId, + void* eventData) +{ + if (eventBase == WIFI_EVENT) { + switch (eventId) { + case WIFI_EVENT_STA_DISCONNECTED: + ESP_LOGI(TAG, "Attempt reconnect"); + /* Fallthrough */ + case WIFI_EVENT_STA_START: + esp_wifi_connect(); + break; + default: + break; + } + } else if (eventBase == IP_EVENT && eventId == IP_EVENT_STA_GOT_IP) { + EventGroupHandle_t* egroup = static_cast(arg); + xEventGroupSetBits(*egroup, WIFI_CONNECTED_BIT); + } +} + +} // namespace + +NetManager::NetManager() +{ + esp_err_t rv = nvs_flash_init(); + if (rv == ESP_ERR_NVS_NO_FREE_PAGES || rv == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + rv = nvs_flash_init(); + } + ESP_ERROR_CHECK(rv); + + esp_read_mac(stationMac_, ESP_MAC_WIFI_STA); +} + +void +NetManager::start() +{ + nvs_handle_t nvsHandle; + esp_err_t rv = nvs_open(TAG, NVS_READONLY, &nvsHandle); + ESP_ERROR_CHECK(rv); + + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + + wifi_config_t cfgSta = {}; + cfgSta.sta.threshold.authmode = WIFI_AUTH_WPA_PSK; + cfgSta.sta.pmf_cfg.capable = true; + cfgSta.sta.pmf_cfg.required = false; + + size_t len = sizeof cfgSta.sta.ssid; + rv = nvs_get_str(nvsHandle, "ssid", (char*)cfgSta.sta.ssid, &len); + ESP_ERROR_CHECK(rv); + + len = sizeof cfgSta.sta.password; + rv = nvs_get_str(nvsHandle, "password", (char*)cfgSta.sta.password, &len); + ESP_ERROR_CHECK(rv); + + nvs_close(nvsHandle); + + EventGroupHandle_t eventGroup = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_netif_init()); + esp_netif_create_default_wifi_sta(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + esp_event_handler_instance_t wifiEvent; + rv = esp_event_handler_instance_register(WIFI_EVENT, + ESP_EVENT_ANY_ID, + &startEventHandler, + &eventGroup, + &wifiEvent); + ESP_ERROR_CHECK(rv); + + esp_event_handler_instance_t ipEvent; + rv = esp_event_handler_instance_register(IP_EVENT, + IP_EVENT_STA_GOT_IP, + &startEventHandler, + &eventGroup, + &ipEvent); + ESP_ERROR_CHECK(rv); + + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &cfgSta)); + ESP_ERROR_CHECK(esp_wifi_start()); + ESP_LOGI(TAG, "esp_wifi_start()"); + + EventBits_t bits = xEventGroupWaitBits(eventGroup, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, + pdFALSE, + portMAX_DELAY); + + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, ipEvent)); + ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, wifiEvent)); + vEventGroupDelete(eventGroup); +} diff --git a/main/NetManager.h b/main/NetManager.h new file mode 100644 index 0000000..9b2c468 --- /dev/null +++ b/main/NetManager.h @@ -0,0 +1,13 @@ +#pragma once +#include + +class NetManager { +public: + NetManager(); + + void start(); + + const uint8_t* stationMac() const { return stationMac_; } +private: + uint8_t stationMac_[6]; +}; diff --git a/main/NvsFlash.cc b/main/NvsFlash.cc new file mode 100644 index 0000000..503db03 --- /dev/null +++ b/main/NvsFlash.cc @@ -0,0 +1,86 @@ +#include "NvsFlash.h" + +void +NvsFlash::init() +{ + esp_err_t rv = nvs_flash_init(); + if (rv == ESP_ERR_NVS_NO_FREE_PAGES || + rv == ESP_ERR_NVS_NEW_VERSION_FOUND) { + ESP_ERROR_CHECK(nvs_flash_erase()); + rv = nvs_flash_init(); + } + ESP_ERROR_CHECK(rv); +} + +NvsFlash::NvsFlash(const std::string& ns, nvs_open_mode_t openMode) +{ + esp_err_t rv = nvs_open(ns.c_str(), openMode, &handle_); + ESP_ERROR_CHECK(rv); +} + +NvsFlash::~NvsFlash() { nvs_close(handle_); } + +esp_err_t +NvsFlash::setString(const std::string& key, const std::string& value) +{ + esp_err_t rv = nvs_set_str(handle_, key.c_str(), value.c_str()); + if (rv == ESP_OK) { + dirty_ = true; + } + + return rv; +} + +esp_err_t +NvsFlash::getString(const std::string& key, std::string& value) +{ + size_t len = 0; + esp_err_t rv = nvs_get_str(handle_, key.c_str(), nullptr, &len); + if (ESP_OK != rv && ESP_ERR_NVS_INVALID_LENGTH != rv) { + return rv; + } + value.resize(len - 1); + rv = nvs_get_str(handle_, key.c_str(), value.data(), &len); + return rv; +} + +esp_err_t +NvsFlash::getU16(const std::string& key, uint16_t& value) +{ + esp_err_t rv = nvs_get_u16(handle_, key.c_str(), &value); + return rv; +} + +esp_err_t +NvsFlash::setU16(const std::string& key, uint16_t value) +{ + esp_err_t rv = nvs_set_u16(handle_, key.c_str(), value); + if (ESP_OK == rv) { + dirty_ = true; + } + return rv; +} + +esp_err_t +NvsFlash::eraseKey(const std::string& key) +{ + esp_err_t rv = nvs_erase_key(handle_, key.c_str()); + if (ESP_OK == rv) { + dirty_ = true; + } + return rv; +} + +esp_err_t +NvsFlash::commit() +{ + if (!dirty_) { + return ESP_OK; + } + + esp_err_t rv = nvs_commit(handle_); + if (ESP_OK == rv) { + dirty_ = false; + } + return rv; +} diff --git a/main/NvsFlash.h b/main/NvsFlash.h new file mode 100644 index 0000000..0c9cd5a --- /dev/null +++ b/main/NvsFlash.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include "nvs_flash.h" + +class NvsFlash { +public: + NvsFlash(const std::string& ns, nvs_open_mode_t openMode = NVS_READONLY); + ~NvsFlash(); + + esp_err_t getString(const std::string& key, std::string& value); + esp_err_t setString(const std::string& key, const std::string& value); + esp_err_t getU16(const std::string& key, uint16_t& value); + esp_err_t setU16(const std::string& key, const uint16_t value); + + esp_err_t eraseKey(const std::string& key); + + bool dirty() const { return dirty_; } + esp_err_t commit(); + + static void init(); + +private: + nvs_handle_t handle_; + bool dirty_{false}; +}; + diff --git a/main/RootPage.cc b/main/RootPage.cc new file mode 100644 index 0000000..2dce8c9 --- /dev/null +++ b/main/RootPage.cc @@ -0,0 +1,245 @@ +#include "RootPage.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "Config.h" + +using namespace httpd; + +static const char* TAG = "RootPage"; + +using namespace std::chrono_literals; + +namespace { + +TickType_t ticks(std::chrono::milliseconds ms) +{ + return ms.count() / portTICK_PERIOD_MS; +} + +TimerHandle_t restart; + +void delayedRestart(TimerHandle_t timer) +{ + ESP_LOGI(TAG, "Restart"); + esp_restart(); +} + +} // namespace + +esp_err_t +RootPage::onGet(Request& req) +{ + ESP_LOGI(TAG, "get"); + char buf[66] = {}; + std::string resp = R"( + + + + + + OTA Update + + + + + + + + + + + )"; + + resp.append("\n") + .append("\n"); + + uint8_t mac[6] ={}; + esp_read_mac(mac, ESP_MAC_WIFI_STA); + snprintf(buf, sizeof buf, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + resp.append("\n"); + + snprintf(buf, + sizeof buf, + "%lu KB", + esp_get_free_heap_size() / 1024); + resp.append("\n"); + + snprintf(buf, + sizeof buf, + "%lu KB", + esp_get_minimum_free_heap_size() / 1024); + resp.append("\n"); + + resp.append(R"( + +
Device Information
Device UUID") + .append(Config::instance().deviceUUID()) + .append("
Endpoint") + .append(Config::instance().endpoint()) + .append("
MAC Address") + .append(buf) + .append("
Free Heap") + .append(buf) + .append("
Min Free Heap") + .append(buf) + .append("
+
+ + + + + + + +)"); + + const esp_app_desc_t* app = esp_app_get_description(); + const esp_partition_t* part = esp_ota_get_running_partition(); + + resp.append("\n"); + + resp.append("\n"); + + resp.append("\n"); + + for (int i = 0; i < 32; ++i) { + snprintf(&buf[i*2], 3, "%.2x", app->app_elf_sha256[i]); + } + resp.append("\n"); + + snprintf(buf, sizeof buf, "%s (0x%" PRIX32 ")", part->label, part->address); + resp.append("\n"); + + + resp.append(R"( + +
App Detail
App Version") + .append(app->version) + .append("
IDF Version") + .append(app->idf_ver) + .append("
Compiled") + .append(app->date) + .append(" ") + .append(app->time) + .append("
App SHA256") + .append(buf) + .append("
Running Partition") + .append(buf) + .append("
+
+
+
+ +
+ + +)"); + req.sendResponse(resp); + return ESP_OK; +}; + +esp_err_t +RootPage::onPost(Request& req) +{ + ESP_LOGI(TAG, "OTA POST"); + using namespace std::string_literals; + const std::string ctype = req.requestHeader("Content-Type"); + + if (ctype != "application/x-www-form-urlencoded"s) { + ESP_LOGI(TAG, "Unsupported Content-Type: '%s'", ctype.c_str()); + httpd_resp_set_status(req.request(), "406 Unsupported Content-Type"); + httpd_resp_set_type(req.request(), "text/plain"); + req.sendResponse("Unsupported Content Type"); + return ESP_OK; + } + + ESP_LOGI(TAG, "POST %d bytes", req.contentLength()); + char buf[128] = {}; + if (req.contentLength() > sizeof buf) { + httpd_resp_set_status(req.request(), "406 Invalid Form Data"); + httpd_resp_set_type(req.request(), "text/plain"); + req.sendResponse("Invalid Form Data"); + return ESP_OK; + } + + int l = httpd_req_recv(req.request(), buf, sizeof buf); + if (l <= 0) { + req.sendResponse("Invalid Form Data"); + return ESP_OK; + } + + std::string_view formData(buf); + size_t pos = formData.find("firmware="); + if (std::string_view::npos == pos) { + ESP_LOGI(TAG, "No firmware value found"); + req.sendResponse("Invalid form data"); + return ESP_OK; + } + formData.remove_prefix(9); + pos = formData.find("&"); + if (pos != std::string_view::npos) { + formData.remove_suffix(formData.size() - pos); + } + std::string uri = urldecode(formData); + ESP_LOGI(TAG, "Firmware URL: %s", uri.c_str()); + esp_http_client_config_t httpcnf = { }; + httpcnf.url = uri.c_str(); + esp_https_ota_config_t config = {}; + config.http_config = &httpcnf; + esp_err_t rv = esp_https_ota(&config); + std::string msg; + if (rv == ESP_OK) { + msg = "Firmware update in process"; + } else if (rv == ESP_ERR_OTA_VALIDATE_FAILED) { + msg = "Image Validation Failed"; + } else { + msg = esp_err_to_name(rv); + } + ESP_LOGI(TAG, "Update result: %s", msg.c_str()); + + std::string resp = R"( + + + + OTA Update + + +)"; + resp.append(msg); + + resp.append(R"( + + +)"); + + req.sendResponse(resp); + if (rv == ESP_OK) { + auto t = ticks(1s); + ESP_LOGI(TAG, "Pending restart in %" PRIu32 " ticks", t); + restart = xTimerCreate("OTA Restart", t, pdFALSE, nullptr, delayedRestart); + if (!restart) { + ESP_LOGI(TAG, "Failed to initialized restart timer!"); + } else { + xTimerStart(restart, 0); + } + } + + return ESP_OK; +} + diff --git a/main/RootPage.h b/main/RootPage.h new file mode 100644 index 0000000..c7368e2 --- /dev/null +++ b/main/RootPage.h @@ -0,0 +1,11 @@ +#pragma once + +#include "HttpServer.h" + +class RootPage : public httpd::MethodHandler +{ +public: + virtual esp_err_t onGet(httpd::Request& req) override; + virtual esp_err_t onPost(httpd::Request& req) override; +}; + diff --git a/main/WebPImage.cc b/main/WebPImage.cc new file mode 100644 index 0000000..0277046 --- /dev/null +++ b/main/WebPImage.cc @@ -0,0 +1,99 @@ +#include "WebPImage.h" +#include +#include "esp_log.h" +#include "esp_rom_md5.h" +#include "esp_system.h" + +const char TAG[] = "WebPImage"; + +WebPImage::WebPImage(std::unique_ptr&& buf) + : dec_(nullptr), loop_(0), frame_(0), lastFrameTime_(0) +{ + WebPData data { + .bytes = buf->data(), + .size = buf->size() + }; + + dec_ = WebPAnimDecoderNew(&data, nullptr); + if (!dec_) { + ESP_LOGE(TAG, "Failed to create decoder"); + return; + } + + WebPAnimInfo info; + int rv = WebPAnimDecoderGetInfo(dec_, &info); + ESP_LOGI(TAG, + "WebPAnimDecoderGetInfo: %d, Frames: %" PRIu32 " Loop: %" PRIu32 + " Width: %" PRIu32 " Height: %" PRIu32, + rv, info.frame_count, info.loop_count, info.canvas_width, + info.canvas_height); + + if (IMAGE_WIDTH != info.canvas_width || IMAGE_HEIGHT != info.canvas_height) { + WebPAnimDecoderDelete(dec_); + dec_ = nullptr; + } + + loop_ = info.loop_count; + data_ = std::move(buf); +} + +WebPImage::~WebPImage() +{ + if (dec_) { + WebPAnimDecoderDelete(dec_); + } +} + +uint32_t +WebPImage::render(Image::DrawFunction draw) +{ + if (!valid()) { + return ANIMATION_END; + } + + for ( ; ; ) { + if (WebPAnimDecoderHasMoreFrames(dec_)) { + uint8_t* pix; + int timestamp; + + if (!WebPAnimDecoderGetNext(dec_, &pix, ×tamp)) { + MD5Context md5; + unsigned char digest[16]; + char hash[33]; + esp_rom_md5_init(&md5); + esp_rom_md5_update(&md5, (uint8_t*)data_->data(), data_->size()); + esp_rom_md5_final(digest, &md5); + for (int i = 0; i < 16; ++i) { + sprintf(hash + (i*2), "%.2x", digest[i]); + } + ESP_LOGE(TAG, + "WebPAnimDecoderGetNext error on frame %d (len: %u, " + "md5: %s)", + frame_, data_->size(), hash); + ESP_LOGE(TAG, "Free Heap: %lu, Min Free Heap: %lu", + esp_get_free_heap_size(), + esp_get_minimum_free_heap_size()); + return ANIMATION_END; + } + draw(pix); + int rv = timestamp - lastFrameTime_; + lastFrameTime_ = timestamp; + ++frame_; + return rv; + } + + if (1 == loop_) { + // Done animating + return ANIMATION_END; + } + + if (loop_) { + --loop_; + } + WebPAnimDecoderReset(dec_); + frame_ = 0; + lastFrameTime_ = 0; + } + return ANIMATION_END; +} + diff --git a/main/WebPImage.h b/main/WebPImage.h new file mode 100644 index 0000000..4d06653 --- /dev/null +++ b/main/WebPImage.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include + +#include "Animation.h" +#include "Image.h" + +#include + +class WebPImage : public Image +{ +public: + WebPImage(std::unique_ptr&& buf); + virtual ~WebPImage(); + + virtual bool valid() const override { return dec_; } + virtual uint32_t render(Image::DrawFunction fn) override; + +private: + std::unique_ptr data_; + WebPAnimDecoder* dec_; + + uint32_t loop_; + int frame_; + int lastFrameTime_; +}; + diff --git a/main/idf_component.yml b/main/idf_component.yml new file mode 100644 index 0000000..8f5cc97 --- /dev/null +++ b/main/idf_component.yml @@ -0,0 +1,17 @@ +## IDF Component Manager Manifest File +dependencies: + espressif/esp_websocket_client: "*" + ## Required IDF version + idf: + version: ">=4.1.0" + # # Put list of dependencies here + # # For components maintained by Espressif: + # component: "~1.0.0" + # # For 3rd party components: + # username/component: ">=1.0.0,<2.0.0" + # username2/component2: + # version: "~1.0.0" + # # For transient dependencies `public` flag can be set. + # # `public` flag doesn't have an effect dependencies of the `main` component. + # # All dependencies of `main` are public by default. + # public: true diff --git a/main/main.cc b/main/main.cc new file mode 100644 index 0000000..45bd981 --- /dev/null +++ b/main/main.cc @@ -0,0 +1,210 @@ +#define INCLUDE_vTaskDelay 1 + +#include +#include + +#include "driver/gpio.h" +#include "rom/gpio.h" +#include "nvs_flash.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_event.h" +#include "esp_http_client.h" +#include "esp_websocket_client.h" + +#include +#include + +#include +#include "Config.h" +#include "RootPage.h" +#include "Display.h" +#include "WebPImage.h" +#include "NvsFlash.h" + +static const char* TAG = "PIXEL"; +static const size_t CAPACITY = 68*1024; +static uint8_t imgbuf[CAPACITY]; + +extern const uint8_t nyan_webp_start[] asm("_binary_nyan_64x32_webp_start"); +extern const uint8_t nyan_webp_end[] asm("_binary_nyan_64x32_webp_end"); + +StaticImageSource NyanWebPSrc(nyan_webp_start, nyan_webp_end); + +const gpio_num_t LED_BUILTIN = GPIO_NUM_12; + +std::unique_ptr netMgr; +std::unique_ptr httpServer; + +// Simple fixed allocation buffer with a used size we can append chunks to as +// they come in from the network. +class ImageBuffer { + public: + ImageBuffer() : buf_(imgbuf) {}; + bool append(const uint8_t* buf, size_t len) + { + if (len && !overrun_) { + if (size_ + len < CAPACITY) { + memcpy(buf_ + size_, buf, len); + size_ += len; + } else { + overrun_ = true; + } + } + return !overrun_; + } + + void reset() { + size_ = 0; + overrun_ = false; + } + + const uint8_t* begin() const { return buf_; } + const uint8_t* end() const { return overrun_ ? buf_ : buf_ + size_; } + size_t size() const { return size_; } + + private: + uint8_t* buf_; + size_t size_{0}; + bool overrun_{false}; +}; + +struct user_ctx { + ImageBuffer buffer; + uint32_t delay = 10000; + bool valid{true}; + + void reset() { + buffer.reset(); + valid = true; + } +}; + +void wsEventHandler(void *args, esp_event_base_t base, int32_t eventId, void* eventData) +{ + esp_websocket_event_data_t *data = (esp_websocket_event_data_t*)eventData; + user_ctx* ctx = (user_ctx*)data->user_context; + + switch (eventId) { + case WEBSOCKET_EVENT_CONNECTED: + ESP_LOGI(TAG, "Websocket connected"); + break; + case WEBSOCKET_EVENT_DISCONNECTED: + ESP_LOGI(TAG, "Websocket disconnected"); + break; + case WEBSOCKET_EVENT_DATA: + ESP_LOGI(TAG, + "WS Recv op_code: %X, fin: %d, payload_len: %u, " + "payload_offset: %u, data_len: %u", + data->op_code, data->fin, data->payload_len, + data->payload_offset, data->data_len); + switch (data->op_code) { + case 0x1: // Text + ctx->valid = false; + break; + case 0x2: // BINARY + if (!data->payload_offset) { + // This stops the current animation on the current + // frame, and releases the underlying WebP buffers + // so we have as much RAM as possible to load the + // incoming animation into. + animationStart(nullptr); + ctx->reset(); + } + /* fallthrough */ + case 0x0: // Continue + if (!ctx->valid) { + ESP_LOGE(TAG, "No buffer for incoming WS data"); + return; + } + if (!ctx->buffer.append((uint8_t*)data->data_ptr, data->data_len)) { + ESP_LOGE( + TAG, + "Image buffer overrun for %u bytes at offset %u", + data->data_len, ctx->buffer.size()); + ctx->valid = false; + } + if (ctx->valid && data->fin) { + // This is really a hack to prove not reallocating the + // incoming buffer every time and should be cleaned up. + std::unique_ptr img = + std::make_unique( + std::make_unique( + ctx->buffer.begin(), ctx->buffer.end())); + if (img->valid()) { + animationStart(std::move(img)); + } + ctx->valid = false; + } + break; + case 0x9: // Ping + case 0xA: // Pong + break; + default: + ESP_LOGE(TAG, "Invalid frame opcode %X", data->op_code); + // If we're in the middle of a payload, it's likely garbage now. + ctx->reset(); + break; + } + break; + case WEBSOCKET_EVENT_ERROR: + ESP_LOGI(TAG, "Websocket error"); + break; + } +} + +extern "C" { +void app_main(void) +{ + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + animationSetup(); + + auto nyan = std::make_unique( + std::make_unique(NyanWebPSrc)); + if (nyan->valid()) { + animationStart(std::move(nyan)); + } + + + gpio_pad_select_gpio(LED_BUILTIN); + gpio_set_direction(LED_BUILTIN, GPIO_MODE_OUTPUT); + gpio_set_level(LED_BUILTIN, 0); + + netMgr = std::make_unique(); + netMgr->start(); + + ESP_LOGI(TAG, "WiFi up"); + + // Note - Config::instance() depends on WiFi being initialized already for the RNG. + const auto uri = Config::instance().imageUri(); + + RootPage root; + + httpServer = std::make_unique(); + httpServer->registerHandler("/", root); + + gpio_set_level(LED_BUILTIN, 1); + user_ctx *ctx = new user_ctx(); + if (!ctx) { + ESP_LOGE(TAG, "Failed to allocate WS Context"); + } + + esp_websocket_client_config_t wsCfg = {}; + wsCfg.uri = uri.c_str(); + wsCfg.user_context = ctx; + wsCfg.buffer_size = 1024; + + ESP_LOGI(TAG, "Websocket Connect %s", uri.c_str()); + esp_websocket_client_handle_t client = esp_websocket_client_init(&wsCfg); + esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, wsEventHandler, + client); + esp_websocket_client_start(client); + + // This method must not return! + for (;;) { + vTaskDelay(10000 / portTICK_PERIOD_MS); + } +} + +} // extern "C" diff --git a/main/nyan_64x32.webp b/main/nyan_64x32.webp new file mode 100644 index 0000000..f2029bb Binary files /dev/null and b/main/nyan_64x32.webp differ diff --git a/nvs.csv.sample b/nvs.csv.sample new file mode 100644 index 0000000..ba27d76 --- /dev/null +++ b/nvs.csv.sample @@ -0,0 +1,7 @@ +key,type,encoding,value +NetManager,namespace,, +ssid,data,string,WIFI_SSID_HERE +password,data,string,WIFI_PASSWD_HERE +PixelMatrix,namespace +endpoint,data,string,192.168.1.100 +port,data,u16,8080 diff --git a/nvs.sh b/nvs.sh new file mode 100755 index 0000000..5a53e8f --- /dev/null +++ b/nvs.sh @@ -0,0 +1,28 @@ +#/bin/bash +# Build script to create the an NVS partition data. Copy nvs.csv.sample to +# nvs.csv and replace the following values: +# ssid: WIFI_SSID_HERE +# password: WIFI_PASSWD_HERE +# endpoint: 192.168.1.100 ## This should be the IP of your pixelgw server +# port: 8080 ## Replace with 8081 for the test server deployment +# This is meant to be run under docker via 'build.sh nvs'. + +NVS=nvs.csv +if [ ! -z $1 ] ; then + NVS=$1 +fi + +if [ ! -f $NVS ] ; then + echo file $NVS not found + exit 1 +fi + +PINFO=`/opt/esp/idf/components/partition_table/parttool.py -f partitions.csv get_partition_info --partition-name nvs` +OFFSET=`echo $PINFO | awk '{print $1}'` +SIZE=`echo $PINFO | awk '{print $2}'` + +/opt/esp/idf/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py generate \ + $NVS build/nvs.bin $SIZE +head -1 build/flash_args > build/flash_nvs_args +echo $OFFSET nvs.bin >> build/flash_nvs_args + diff --git a/partitions.csv b/partitions.csv new file mode 100644 index 0000000..ce2b896 --- /dev/null +++ b/partitions.csv @@ -0,0 +1,8 @@ +#Name, Type, Subtype, Offset, Size, Flags +otadata, data, ota, 0x9000, 0x2000, +nvs, data, nvs, , 0x4000, +ota_0, app, ota_0, 0x10000, 3M, +ota_1, app, ota_1, , 3M, +spiffs, data, spiffs, , 1M, + + diff --git a/sdkconfig b/sdkconfig new file mode 100644 index 0000000..3449142 --- /dev/null +++ b/sdkconfig @@ -0,0 +1,1886 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) 5.2.2 Project Configuration +# +CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" +CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" +CONFIG_SOC_DPORT_WORKAROUND="Not determined" +CONFIG_SOC_CAPS_ECO_VER_MAX=301 +CONFIG_SOC_ADC_SUPPORTED=y +CONFIG_SOC_DAC_SUPPORTED=y +CONFIG_SOC_UART_SUPPORTED=y +CONFIG_SOC_MCPWM_SUPPORTED=y +CONFIG_SOC_GPTIMER_SUPPORTED=y +CONFIG_SOC_SDMMC_HOST_SUPPORTED=y +CONFIG_SOC_BT_SUPPORTED=y +CONFIG_SOC_PCNT_SUPPORTED=y +CONFIG_SOC_WIFI_SUPPORTED=y +CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y +CONFIG_SOC_TWAI_SUPPORTED=y +CONFIG_SOC_EFUSE_SUPPORTED=y +CONFIG_SOC_EMAC_SUPPORTED=y +CONFIG_SOC_ULP_SUPPORTED=y +CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y +CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y +CONFIG_SOC_RTC_MEM_SUPPORTED=y +CONFIG_SOC_I2S_SUPPORTED=y +CONFIG_SOC_RMT_SUPPORTED=y +CONFIG_SOC_SDM_SUPPORTED=y +CONFIG_SOC_GPSPI_SUPPORTED=y +CONFIG_SOC_LEDC_SUPPORTED=y +CONFIG_SOC_I2C_SUPPORTED=y +CONFIG_SOC_SUPPORT_COEXISTENCE=y +CONFIG_SOC_AES_SUPPORTED=y +CONFIG_SOC_MPI_SUPPORTED=y +CONFIG_SOC_SHA_SUPPORTED=y +CONFIG_SOC_FLASH_ENC_SUPPORTED=y +CONFIG_SOC_SECURE_BOOT_SUPPORTED=y +CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y +CONFIG_SOC_BOD_SUPPORTED=y +CONFIG_SOC_ULP_FSM_SUPPORTED=y +CONFIG_SOC_CLK_TREE_SUPPORTED=y +CONFIG_SOC_MPU_SUPPORTED=y +CONFIG_SOC_WDT_SUPPORTED=y +CONFIG_SOC_SPI_FLASH_SUPPORTED=y +CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 +CONFIG_SOC_XTAL_SUPPORT_26M=y +CONFIG_SOC_XTAL_SUPPORT_40M=y +CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y +CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y +CONFIG_SOC_ADC_DMA_SUPPORTED=y +CONFIG_SOC_ADC_PERIPH_NUM=2 +CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 +CONFIG_SOC_ADC_ATTEN_NUM=4 +CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 +CONFIG_SOC_ADC_PATT_LEN_MAX=16 +CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 +CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 +CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 +CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 +CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 +CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 +CONFIG_SOC_ADC_SHARED_POWER=y +CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y +CONFIG_SOC_IDCACHE_PER_CORE=y +CONFIG_SOC_CPU_CORES_NUM=2 +CONFIG_SOC_CPU_INTR_NUM=32 +CONFIG_SOC_CPU_HAS_FPU=y +CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y +CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 +CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 +CONFIG_SOC_DAC_CHAN_NUM=2 +CONFIG_SOC_DAC_RESOLUTION=8 +CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y +CONFIG_SOC_GPIO_PORT=1 +CONFIG_SOC_GPIO_PIN_COUNT=40 +CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF +CONFIG_SOC_GPIO_IN_RANGE_MAX=39 +CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 +CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA +CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y +CONFIG_SOC_I2C_NUM=2 +CONFIG_SOC_I2C_FIFO_LEN=32 +CONFIG_SOC_I2C_CMD_REG_NUM=16 +CONFIG_SOC_I2C_SUPPORT_SLAVE=y +CONFIG_SOC_I2C_SUPPORT_APB=y +CONFIG_SOC_I2C_STOP_INDEPENDENT=y +CONFIG_SOC_I2S_NUM=2 +CONFIG_SOC_I2S_HW_VERSION_1=y +CONFIG_SOC_I2S_SUPPORTS_APLL=y +CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y +CONFIG_SOC_I2S_SUPPORTS_PDM=y +CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y +CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y +CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 +CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y +CONFIG_SOC_I2S_SUPPORTS_ADC=y +CONFIG_SOC_I2S_SUPPORTS_DAC=y +CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y +CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y +CONFIG_SOC_I2S_LCD_I80_VARIANT=y +CONFIG_SOC_LCD_I80_SUPPORTED=y +CONFIG_SOC_LCD_I80_BUSES=2 +CONFIG_SOC_LCD_I80_BUS_WIDTH=24 +CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y +CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y +CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y +CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y +CONFIG_SOC_LEDC_CHANNEL_NUM=8 +CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 +CONFIG_SOC_MCPWM_GROUPS=2 +CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 +CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 +CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 +CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 +CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y +CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 +CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 +CONFIG_SOC_MMU_PERIPH_NUM=2 +CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 +CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 +CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 +CONFIG_SOC_PCNT_GROUPS=1 +CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 +CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 +CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 +CONFIG_SOC_RMT_GROUPS=1 +CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 +CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 +CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 +CONFIG_SOC_RMT_SUPPORT_REF_TICK=y +CONFIG_SOC_RMT_SUPPORT_APB=y +CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y +CONFIG_SOC_RTCIO_PIN_COUNT=18 +CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y +CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y +CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y +CONFIG_SOC_SDM_GROUPS=1 +CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 +CONFIG_SOC_SDM_CLK_SUPPORT_APB=y +CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y +CONFIG_SOC_SPI_AS_CS_SUPPORTED=y +CONFIG_SOC_SPI_PERIPH_NUM=3 +CONFIG_SOC_SPI_DMA_CHAN_NUM=2 +CONFIG_SOC_SPI_MAX_CS_NUM=3 +CONFIG_SOC_SPI_SUPPORT_CLK_APB=y +CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 +CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 +CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y +CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y +CONFIG_SOC_TIMER_GROUPS=2 +CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 +CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 +CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 +CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y +CONFIG_SOC_TOUCH_VERSION_1=y +CONFIG_SOC_TOUCH_SENSOR_NUM=10 +CONFIG_SOC_TOUCH_PAD_MEASURE_WAIT_MAX=0xFF +CONFIG_SOC_TWAI_CONTROLLER_NUM=1 +CONFIG_SOC_TWAI_BRP_MIN=2 +CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y +CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y +CONFIG_SOC_UART_NUM=3 +CONFIG_SOC_UART_HP_NUM=3 +CONFIG_SOC_UART_SUPPORT_APB_CLK=y +CONFIG_SOC_UART_SUPPORT_REF_TICK=y +CONFIG_SOC_UART_FIFO_LEN=128 +CONFIG_SOC_UART_BITRATE_MAX=5000000 +CONFIG_SOC_SPIRAM_SUPPORTED=y +CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y +CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y +CONFIG_SOC_SHA_ENDIANNESS_BE=y +CONFIG_SOC_SHA_SUPPORT_SHA1=y +CONFIG_SOC_SHA_SUPPORT_SHA256=y +CONFIG_SOC_SHA_SUPPORT_SHA384=y +CONFIG_SOC_SHA_SUPPORT_SHA512=y +CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 +CONFIG_SOC_MPI_OPERATIONS_NUM=y +CONFIG_SOC_RSA_MAX_BIT_LEN=4096 +CONFIG_SOC_AES_SUPPORT_AES_128=y +CONFIG_SOC_AES_SUPPORT_AES_192=y +CONFIG_SOC_AES_SUPPORT_AES_256=y +CONFIG_SOC_SECURE_BOOT_V1=y +CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y +CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 +CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 +CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y +CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y +CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y +CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y +CONFIG_SOC_PM_SUPPORT_MODEM_PD=y +CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y +CONFIG_SOC_CLK_APLL_SUPPORTED=y +CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y +CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y +CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y +CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y +CONFIG_SOC_SDMMC_USE_IOMUX=y +CONFIG_SOC_SDMMC_NUM_SLOTS=2 +CONFIG_SOC_WIFI_WAPI_SUPPORT=y +CONFIG_SOC_WIFI_CSI_SUPPORT=y +CONFIG_SOC_WIFI_MESH_SUPPORT=y +CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y +CONFIG_SOC_WIFI_NAN_SUPPORT=y +CONFIG_SOC_BLE_SUPPORTED=y +CONFIG_SOC_BLE_MESH_SUPPORTED=y +CONFIG_SOC_BT_CLASSIC_SUPPORTED=y +CONFIG_SOC_BLUFI_SUPPORTED=y +CONFIG_SOC_ULP_HAS_ADC=y +CONFIG_SOC_PHY_COMBO_MODULE=y +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TOOLCHAIN="gcc" +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET_ARCH="xtensa" +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_INIT_VERSION="5.2.1" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# CONFIG_APP_REPRODUCIBLE_BUILD is not set +# CONFIG_APP_NO_BLOBS is not set +# CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# end of Build type + +# +# Bootloader config +# + +# +# Bootloader manager +# +CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y +CONFIG_BOOTLOADER_PROJECT_VER=1 +# end of Bootloader manager + +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 + +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set +CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y +# end of Serial Flash Configurations + +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +CONFIG_SECURE_BOOT_V1_SUPPORTED=y +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +CONFIG_ESP_ROM_HAS_CRC_LE=y +CONFIG_ESP_ROM_HAS_CRC_BE=y +CONFIG_ESP_ROM_HAS_MZ_CRC32=y +CONFIG_ESP_ROM_HAS_JPEG_DECODE=y +CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y +CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y +CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y +CONFIG_ESP_ROM_HAS_SW_FLOAT=y +CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 + +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="8MB" +# CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set +CONFIG_COMPILER_HIDE_PATHS_MACROS=y +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +CONFIG_COMPILER_CXX_RTTI=y +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set +# CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +CONFIG_COMPILER_RT_LIB_GCCLIB=y +CONFIG_COMPILER_RT_LIB_NAME="gcc" +# CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set +CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_JTAG is not set +CONFIG_APPTRACE_DEST_NONE=y +# CONFIG_APPTRACE_DEST_UART1 is not set +# CONFIG_APPTRACE_DEST_UART2 is not set +CONFIG_APPTRACE_DEST_UART_NONE=y +CONFIG_APPTRACE_UART_TASK_PRIO=1 +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +CONFIG_BT_ALARM_MAX_NUM=50 +# end of Bluetooth + +# +# Driver Configurations +# + +# +# Legacy ADC Configuration +# +CONFIG_ADC_DISABLE_DAC=y +# CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set + +# +# Legacy ADC Calibration Configuration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set +# end of Legacy ADC Calibration Configuration +# end of Legacy ADC Configuration + +# +# SPI Configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI Configuration + +# +# TWAI Configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +# CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC is not set +# CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST is not set +# CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID is not set +# CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set +# CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM is not set +# end of TWAI Configuration + +# +# UART Configuration +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of UART Configuration + +# +# GPIO Configuration +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set +# end of GPIO Configuration + +# +# Sigma Delta Modulator Configuration +# +# CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_SDM_ENABLE_DEBUG_LOG is not set +# end of Sigma Delta Modulator Configuration + +# +# GPTimer Configuration +# +CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y +# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set +# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set +# CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set +# end of GPTimer Configuration + +# +# PCNT Configuration +# +# CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_PCNT_ISR_IRAM_SAFE is not set +# CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_PCNT_ENABLE_DEBUG_LOG is not set +# end of PCNT Configuration + +# +# RMT Configuration +# +# CONFIG_RMT_ISR_IRAM_SAFE is not set +# CONFIG_RMT_RECV_FUNC_IN_IRAM is not set +# CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_RMT_ENABLE_DEBUG_LOG is not set +# end of RMT Configuration + +# +# MCPWM Configuration +# +# CONFIG_MCPWM_ISR_IRAM_SAFE is not set +# CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set +# CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set +# end of MCPWM Configuration + +# +# I2S Configuration +# +# CONFIG_I2S_ISR_IRAM_SAFE is not set +# CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_I2S_ENABLE_DEBUG_LOG is not set +# end of I2S Configuration + +# +# DAC Configuration +# +# CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set +# CONFIG_DAC_ISR_IRAM_SAFE is not set +# CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set +# CONFIG_DAC_ENABLE_DEBUG_LOG is not set +CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y +# end of DAC Configuration + +# +# LEDC Configuration +# +# CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set +# end of LEDC Configuration + +# +# I2C Configuration +# +# CONFIG_I2C_ISR_IRAM_SAFE is not set +# CONFIG_I2C_ENABLE_DEBUG_LOG is not set +# end of I2C Configuration +# end of Driver Configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set +# CONFIG_ESP_TLS_SERVER is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ADC and ADC Calibration +# +# CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set +# CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set + +# +# ADC Calibration Configurations +# +CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y +CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CALI_LUT_ENABLE=y +# end of ADC Calibration Configurations + +CONFIG_ADC_DISABLE_DAC_OUTPUT=y +# end of ADC and ADC Calibration + +# +# Wireless Coexistence +# +# end of Wireless Coexistence + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +# end of Common ESP-related + +# +# Ethernet +# +# CONFIG_ETH_USE_ESP32_EMAC is not set +# CONFIG_ETH_USE_SPI_ETHERNET is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +CONFIG_ESP_GDBSTUB_ENABLED=y +# CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set +CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y +CONFIG_ESP_GDBSTUB_MAX_TASKS=32 +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +CONFIG_HTTPD_WS_SUPPORT=y +# CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set +CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP=y +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# Hardware Settings +# + +# +# Chip revision +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_1_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +# CONFIG_ESP32_REV_MIN_3_1 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_REV_MIN_FULL=0 +CONFIG_ESP_REV_MIN_FULL=0 + +# +# Maximum Supported ESP32 Revision (Rev v3.99) +# +CONFIG_ESP32_REV_MAX_FULL=399 +CONFIG_ESP_REV_MAX_FULL=399 +# end of Chip revision + +# +# MAC Config +# +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set +# CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set +# end of MAC Config + +# +# Sleep Config +# +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_WAIT_FLASH_READY_EXTRA_DELAY=2000 +# CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set +# CONFIG_ESP_SLEEP_DEBUG is not set +CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y +# end of Sleep Config + +# +# RTC Clock Config +# +CONFIG_RTC_CLK_SRC_INT_RC=y +# CONFIG_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_RTC_CLK_CAL_CYCLES=1024 +# end of RTC Clock Config + +# +# Peripheral Control +# +CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y +# end of Peripheral Control + +# +# Main XTAL Config +# +# CONFIG_XTAL_FREQ_26 is not set +CONFIG_XTAL_FREQ_40=y +# CONFIG_XTAL_FREQ_AUTO is not set +CONFIG_XTAL_FREQ=40 +# end of Main XTAL Config +# end of Hardware Settings + +# +# LCD and Touch Panel +# + +# +# LCD Touch Drivers are maintained in the IDF Component Registry +# + +# +# LCD Peripheral Configuration +# +CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 +# CONFIG_LCD_ENABLE_DEBUG_LOG is not set +# end of LCD Peripheral Configuration +# end of LCD and Touch Panel + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y +# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set +# CONFIG_ESP_NETIF_L2_TAP is not set +# CONFIG_ESP_NETIF_BRIDGE_EN is not set +# end of ESP NETIF Adapter + +# +# Partition API Configuration +# +# end of Partition API Configuration + +# +# PHY +# +CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP_PHY_MAX_TX_POWER=20 +CONFIG_ESP_PHY_REDUCE_TX_POWER=y +CONFIG_ESP_PHY_RF_CAL_PARTIAL=y +# CONFIG_ESP_PHY_RF_CAL_NONE is not set +# CONFIG_ESP_PHY_RF_CAL_FULL is not set +CONFIG_ESP_PHY_CALIBRATION_MODE=0 +# CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set +# end of PHY + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# end of Power Management + +# +# ESP PSRAM +# +# CONFIG_SPIRAM is not set +# end of ESP PSRAM + +# +# ESP Ringbuf +# +# CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set +# end of ESP Ringbuf + +# +# ESP System Settings +# +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 + +# +# Memory +# +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set + +# +# Non-backward compatible options +# +# CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set +# end of Non-backward compatible options +# end of Memory + +# +# Trace memory +# +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# end of Trace memory + +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 + +# +# Memory protection +# +# end of Memory protection + +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y +# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set +# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT_EN=y +CONFIG_ESP_TASK_WDT_INIT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +# CONFIG_ESP_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP_DEBUG_OCDAWARE=y +# CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set +CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y + +# +# Brownout Detector +# +CONFIG_ESP_BROWNOUT_DET=y +CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP_BROWNOUT_DET_LVL=0 +# end of Brownout Detector + +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y +# end of ESP System Settings + +# +# IPC (Inter-Processor Call) +# +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_IPC_ISR_ENABLE=y +# end of IPC (Inter-Processor Call) + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 +# CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set +CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 +CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y +CONFIG_ESP_TIMER_ISR_AFFINITY=0x1 +CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y +# CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_ENABLED=y +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=16 +# CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=16 +CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y +# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set +CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 +CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 +# CONFIG_ESP_WIFI_CSI_ENABLED is not set +CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP_WIFI_TX_BA_WIN=6 +CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP_WIFI_RX_BA_WIN=6 +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 +CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP_WIFI_IRAM_OPT=y +# CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set +CONFIG_ESP_WIFI_RX_IRAM_OPT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP_WIFI_ENABLE_SAE_PK=y +CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y +CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 +CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 +CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# CONFIG_ESP_WIFI_GMAC_SUPPORT is not set +CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y +# CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set +CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 +# CONFIG_ESP_WIFI_NAN_ENABLE is not set +CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y +CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y +# CONFIG_ESP_WIFI_WAPI_PSK is not set +# CONFIG_ESP_WIFI_11KV_SUPPORT is not set +# CONFIG_ESP_WIFI_MBO_SUPPORT is not set +# CONFIG_ESP_WIFI_DPP_SUPPORT is not set +# CONFIG_ESP_WIFI_11R_SUPPORT is not set +# CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set + +# +# WPS Configuration Options +# +# CONFIG_ESP_WIFI_WPS_STRICT is not set +# CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set +# end of WPS Configuration Options + +# CONFIG_ESP_WIFI_DEBUG_PRINT is not set +# CONFIG_ESP_WIFI_TESTING_OPTIONS is not set +CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y +# CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set +# end of Wi-Fi + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +CONFIG_FATFS_VOLUME_COUNT=2 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +# CONFIG_FATFS_SECTOR_512 is not set +CONFIG_FATFS_SECTOR_4096=y +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 +# CONFIG_FATFS_IMMEDIATE_FSYNC is not set +# end of FAT Filesystem support + +# +# FreeRTOS +# + +# +# Kernel +# +# CONFIG_FREERTOS_SMP is not set +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_HZ=100 +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 +# CONFIG_FREERTOS_USE_IDLE_HOOK is not set +# CONFIG_FREERTOS_USE_TICK_HOOK is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +# CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set +CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +# CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set +# end of Kernel + +# +# Port +# +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y +# CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# end of Port + +CONFIG_FREERTOS_PORT=y +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y +CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y +# end of FreeRTOS + +# +# Hardware Abstraction Layer (HAL) and Low Level (LL) +# +CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y +# CONFIG_HAL_ASSERTION_DISABLE is not set +# CONFIG_HAL_ASSERTION_SILENT is not set +# CONFIG_HAL_ASSERTION_ENABLE is not set +CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 +CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y +CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y +# end of Hardware Abstraction Layer (HAL) and Low Level (LL) + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_USE_HOOKS is not set +# CONFIG_HEAP_TASK_TRACKING is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set +# end of Heap memory debugging + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# 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_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_MAXIMUM_LEVEL_DEBUG is not set +# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set +CONFIG_LOG_MAXIMUM_LEVEL=3 +# CONFIG_LOG_MASTER_LEVEL is not set +CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_ENABLE=y +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +# CONFIG_LWIP_NETIF_API is not set +CONFIG_LWIP_TCPIP_TASK_PRIO=18 +# CONFIG_LWIP_TCPIP_CORE_LOCKING is not set +# CONFIG_LWIP_CHECK_THREAD_SAFETY is not set +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +# CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP_DEFAULT_TTL=64 +CONFIG_LWIP_IP4_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set +CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set +CONFIG_LWIP_DHCP_OPTIONS_LEN=68 +CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 +CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 + +# +# DHCP server +# +CONFIG_LWIP_DHCPS=y +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV4=y +# CONFIG_LWIP_IPV6 is not set +# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 +CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 +# CONFIG_LWIP_TCP_SACK_OUT is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +CONFIG_LWIP_ICMP=y +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_SNTP_MAX_SERVERS=1 +# CONFIG_LWIP_DHCP_GET_NTP_SRV is not set +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +# +# DNS +# +CONFIG_LWIP_DNS_MAX_SERVERS=3 +# CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set +# end of DNS + +CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# mbedTLS v3.x related +# +# CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set +# CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set +# CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set +# CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set +CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y +CONFIG_MBEDTLS_PKCS7_C=y +# end of mbedTLS v3.x related + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +CONFIG_MBEDTLS_CMAC_C=y +CONFIG_MBEDTLS_HARDWARE_AES=y +# CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER is not set +CONFIG_MBEDTLS_HARDWARE_MPI=y +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# CONFIG_MBEDTLS_NIST_KW_C is not set +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +# CONFIG_MBEDTLS_DHM_C is not set +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y +# end of mbedTLS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +# CONFIG_MQTT_PROTOCOL_5 is not set +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y +# CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set +# CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set +# end of Newlib + +# +# NVS +# +# CONFIG_NVS_ASSERT_ERROR_CHECK is not set +# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set +# end of NVS + +# +# OpenThread +# +# CONFIG_OPENTHREAD_ENABLED is not set + +# +# Thread Operational Dataset +# +CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" +CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" +CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 +CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 +CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" +CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" +CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" +# end of Thread Operational Dataset + +CONFIG_OPENTHREAD_XTAL_ACCURACY=130 +# CONFIG_OPENTHREAD_SPINEL_ONLY is not set +CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y + +# +# Thread Address Query Config +# +# end of Thread Address Query Config +# end of OpenThread + +# +# Protocomm +# +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y +CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y +# end of Protocomm + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# MMU Config +# +CONFIG_MMU_PAGE_SIZE_64KB=y +CONFIG_MMU_PAGE_MODE="64KB" +CONFIG_MMU_PAGE_SIZE=0x10000 +# end of MMU Config + +# +# Main Flash configuration +# + +# +# SPI Flash behavior when brownout +# +CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y +CONFIG_SPI_FLASH_BROWNOUT_RESET=y +# end of SPI Flash behavior when brownout + +# +# Optional and Experimental Features (READ DOCS FIRST) +# + +# +# Features here require specific hardware (READ DOCS FIRST!) +# +# end of Optional and Experimental Features (READ DOCS FIRST) +# end of Main Flash configuration + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set +# CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y +CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set +# CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# + +# +# Websocket +# +CONFIG_WS_TRANSPORT=y +CONFIG_WS_BUFFER_SIZE=1024 +# CONFIG_WS_DYNAMIC_BUFFER is not set +# end of Websocket +# end of TCP Transport + +# +# Ultra Low Power (ULP) Co-processor +# +# CONFIG_ULP_COPROC_ENABLED is not set +# end of Ultra Low Power (ULP) Co-processor + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_64BIT is not set +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +# CONFIG_VFS_SELECT_IN_RAM is not set +CONFIG_VFS_SUPPORT_TERMIOS=y +CONFIG_VFS_MAX_COUNT=8 + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION=y +CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y +# CONFIG_WIFI_PROV_STA_FAST_SCAN is not set +# end of Wi-Fi Provisioning Manager + +# +# ESP WebSocket client +# +# CONFIG_ESP_WS_CLIENT_ENABLE_DYNAMIC_BUFFER is not set +# end of ESP WebSocket client +# end of Component config + +# CONFIG_IDF_EXPERIMENTAL_FEATURES is not set + +# Deprecated options for backward compatibility +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +CONFIG_MONITOR_BAUD=115200 +CONFIG_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_MCPWM_ISR_IN_IRAM is not set +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +CONFIG_GDBSTUB_SUPPORT_TASKS=y +CONFIG_GDBSTUB_MAX_TASKS=32 +CONFIG_OTA_ALLOW_HTTP=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_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +# CONFIG_ESP32_XTAL_FREQ_26 is not set +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +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 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=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_PANIC_PRINT_HALT is not set +CONFIG_ESP32_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32_PANIC_GDBSTUB is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_CONSOLE_UART_NONE is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_BROWNOUT_DET_LVL=0 +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_TIMER_TASK_STACK_SIZE=3584 +CONFIG_ESP32_WIFI_ENABLED=y +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=16 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=16 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +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 +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y +CONFIG_WPA_MBEDTLS_CRYPTO=y +CONFIG_WPA_MBEDTLS_TLS_CLIENT=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# CONFIG_WPA_MBO_SUPPORT is not set +# CONFIG_WPA_DPP_SUPPORT is not set +# CONFIG_WPA_11R_SUPPORT is not set +# CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set +# CONFIG_WPA_WPS_STRICT is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +# CONFIG_HAL_ASSERTION_SILIENT is not set +# CONFIG_L2_TO_L3_COPY is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +# End of deprecated options