├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE.txt ├── README.md ├── build.sh ├── components ├── HttpServer │ ├── CMakeLists.txt │ ├── HttpServer.cc │ ├── StaticAssetHandler.cc │ ├── WebSockets.cc │ └── include │ │ ├── HttpServer.h │ │ ├── StaticAssetHandler.h │ │ └── WebSockets.h ├── Hub75Display │ ├── CMakeLists.txt │ ├── Hub75Display.c │ ├── i2s_parallel.c │ ├── i2s_parallel.h │ ├── include │ │ └── Hub75Display.h │ ├── val2pwm.c │ └── val2pwm.h └── libwebp │ └── CMakeLists.txt ├── hardware └── v1 │ ├── Backplate-P4.stl │ ├── Frame-P4.stl │ ├── README.md │ └── V1.jpg ├── main ├── Animation.cc ├── Animation.h ├── CMakeLists.txt ├── Config.cc ├── Config.h ├── Display.h ├── Image.h ├── NetManager.cc ├── NetManager.h ├── NvsFlash.cc ├── NvsFlash.h ├── RootPage.cc ├── RootPage.h ├── WebPImage.cc ├── WebPImage.h ├── idf_component.yml ├── main.cc └── nyan_64x32.webp ├── nvs.csv.sample ├── nvs.sh ├── partitions.csv └── sdkconfig /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore vim recovery files 2 | .*.swp 3 | *.bak 4 | 5 | # Ignore build artifacts 6 | **/build/** 7 | 8 | /dependencies.lock 9 | /managed_components/ 10 | 11 | # Ignore the NVS prototypes 12 | /nvs*.bin 13 | /nvs*.csv 14 | 15 | /sdkconfig.old 16 | 17 | **/.nfs* 18 | **/.DS_Store 19 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "components/libnsgif"] 2 | path = components/libnsgif 3 | url = https://github.com/UncleRus/esp-idf-libnsgif.git 4 | [submodule "components/libwebp/libwebp"] 5 | path = components/libwebp/libwebp 6 | url = https://chromium.googlesource.com/webm/libwebp 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # For more information about build system see 2 | # https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html 3 | # The following five lines of boilerplate have to be in your project's 4 | # CMakeLists in this exact order for cmake to work correctly 5 | cmake_minimum_required(VERSION 3.5) 6 | 7 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 8 | project(PixelClient) 9 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PixelClient: Firmware for an ESP-32 board to drive a 32x64 HUB 75 display, 2 | by subscribing to a websocket and streaming pushed images. The corresponding 3 | server is located at https://github.com/joe714/pixelgw 4 | 5 | Mainter: Joe Sunday sunday@csh.rit.edu 6 | GitHub: https://github.com/joe714/pixelfirmware 7 | 8 | # Build and Install 9 | 10 | Pinout for the display is set in components/Hub75Display/Hub75Display.c, 11 | note this is not the same pinout as official Tidbyt hardware and needs 12 | to be set for particular devices. (TODO, make this more configurable at 13 | build time) . Reference schematic / board coming soon. 14 | 15 | To build, you'll need a working Linux machine with Docker installed and 16 | your user in the docker group. After cloning the repository, fetch the 17 | required submodules: 18 | 19 | $ git submodule init 20 | $ git submodule update 21 | 22 | To compile the firmware: 23 | 24 | $ ./build.sh build 25 | 26 | For first setup, copy nvs.csv.sample to nvs.csv and set your WiFi credentials 27 | and endpoint / pixelgw IP address on the appropriate lines, and generate the 28 | initial NVS partion data: 29 | 30 | $ ./build.sh nvs 31 | 32 | To flash, connect the device via USB and flash everything. Note that you 33 | should only flash the NVS data on the first install. Once the device has 34 | registered with the gateway, reflashing NVS will cause the device UUID to 35 | change. 36 | 37 | $ ./build.sh flash 38 | $ ./build.sh flash_nvs 39 | 40 | To do OTA updates once already installed, start a temporary web server: 41 | 42 | $ ./build.sh ota-server 43 | 44 | Then navigate to http://*device-ip*/, verify OTA URL listed, and click "Update Firmware". 45 | Currently it assumes you're running the OTA update from the same machine as the 46 | gateway endpoint, otherwise you'll need to change the IP in the firmware URL. 47 | 48 | # FAQ 49 | - What hardware does this need? 50 | 51 | An ESP-32 board with the HUB75 display wired according to the pin 52 | definitions in components/Hub75Display/Hub75Display.c. 53 | 54 | I'm working on a V1.5 board revision, but I'll publish the 55 | v1 board design when I can. 56 | 57 | - Do you sell hardware? 58 | 59 | Not currently, but inquire and if there's demand I'll see what I can do. 60 | 61 | - Can I run this on Tidbyt Hardware? 62 | 63 | Theoretically, yes but I have not tried it or determined the right 64 | compile options, or determined how to reset it back to factory firmware. 65 | At a minimum, the pin definitions need to be tweaked. If you want to try, 66 | feel free and give me a pull request with changes and instructions, but 67 | I take no responsibility if you brick it. 68 | 69 | # TODO 70 | - Integrate firmware management into the server. 71 | - Web interface to bootstrap / modify configuration 72 | - More device support (including pre-canned config for Tidbyt 1 devices) 73 | 74 | 75 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | # Run the build in a docker image 3 | # https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-docker-image.html# 4 | # 5 | # Run HTTP server for OTA update: 6 | # python -m http.server --directory build 7 | 8 | ESPTOOL="python /mnt/code/esp32/esptool/esptool.py" 9 | if [ -z "$IDF_DOCKER_IMAGE" ]; then 10 | IDF_DOCKER_IMAGE="espressif/idf:release-v5.2" 11 | fi 12 | echo "Using esp-idf image: $IDF_DOCKER_IMAGE" 13 | 14 | if [ -z "$ESPTOOL_PORT" ] ; then 15 | ESPTOOL_PORT=/dev/ttyUSB0 16 | fi 17 | echo "Using serial port: $ESPTOOL_PORT" 18 | 19 | DOCKER_ARGS="--rm -v ${PWD}:/project -e HOME=/tmp" 20 | 21 | # Build we run as the user to not trash permissions in build/ 22 | DOCKER_BUILD_ARGS="${DOCKER_ARGS} -w /project -u `id -u`:`id -g`" 23 | 24 | # Flash we just run as root to use the serial port without a bunch of permissions issues 25 | DOCKER_FLASH_ARGS="${DOCKER_ARGS} -w /project/build --device=${ESPTOOL_PORT}" 26 | 27 | if [ "$1" == "build" ]; then 28 | docker run ${DOCKER_BUILD_ARGS} ${IDF_DOCKER_IMAGE} idf.py build 29 | elif [ $1 == "nvs" ]; then 30 | docker run ${DOCKER_BUILD_ARGS} ${IDF_DOCKER_IMAGE} ./nvs.sh 31 | elif [ "$1" == "interactive" ]; then 32 | docker run ${DOCKER_BUILD_ARGS} -it ${IDF_DOCKER_IMAGE} 33 | elif [ "$1" == "flash" ]; then 34 | docker run ${DOCKER_FLASH_ARGS} ${IDF_DOCKER_IMAGE} \ 35 | esptool.py -p $ESPTOOL_PORT --chip esp32 -b 460800 --before default_reset --after hard_reset \ 36 | write_flash "@flash_args" 37 | elif [ "$1" == "flash_app" ]; then 38 | docker run ${DOCKER_FLASH_ARGS} ${IDF_DOCKER_IMAGE} \ 39 | esptool.py -p $ESPTOOL_PORT --chip esp32 -b 460800 --before default_reset --after hard_reset \ 40 | write_flash "@flash_app_args" 41 | elif [ "$1" == "flash_nvs" ]; then 42 | docker run ${DOCKER_FLASH_ARGS} ${IDF_DOCKER_IMAGE} \ 43 | esptool.py -p $ESPTOOL_PORT --chip esp32 -b 460800 --before default_reset --after hard_reset \ 44 | write_flash "@flash_nvs_args" 45 | elif [ "$1" == "ota-server" ] ; then 46 | python -m http.server --directory build 47 | elif [ "$1" == "monitor" ] ; then 48 | python -m serial.tools.miniterm --rts 0 --dtr 0 --filter direct $ESPTOOL_PORT 115200 49 | else 50 | echo "Usage: $0 [build|nvs|interactive|ota-server|flash|flash-app|flash-nvs|monitor]" 51 | exit 1; 52 | fi 53 | 54 | -------------------------------------------------------------------------------- /components/HttpServer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register( 2 | SRCS "HttpServer.cc" 3 | "StaticAssetHandler.cc" 4 | "WebSockets.cc" 5 | INCLUDE_DIRS "include" 6 | REQUIRES "esp_http_server") 7 | 8 | target_compile_options(${COMPONENT_LIB} PRIVATE "-std=gnu++17") 9 | -------------------------------------------------------------------------------- /components/HttpServer/HttpServer.cc: -------------------------------------------------------------------------------- 1 | #include "HttpServer.h" 2 | #include "WebSockets.h" 3 | #include 4 | #include 5 | 6 | static const char* TAG = "httpd"; 7 | 8 | namespace { 9 | 10 | int ctoh(char c) 11 | { 12 | if (c >= '0' && c <= '9') { 13 | return c - '0'; 14 | } 15 | if (c >= 'a' && c <= 'f') { 16 | return (c - 'a') + 10; 17 | } 18 | if (c >= 'A' && c <= 'F') { 19 | return (c - 'A') + 10; 20 | } 21 | return -1; 22 | } 23 | 24 | } // namespace 25 | namespace httpd { 26 | 27 | std::string urldecode(std::string_view in) 28 | { 29 | std::string out; 30 | out.reserve(in.size()); 31 | auto len = in.size(); 32 | auto i = 0; 33 | while (i < len) { 34 | if (in[i] == '+') { 35 | out.push_back(' '); 36 | ++i; 37 | continue; 38 | } 39 | if (in[i] == '%' && (i + 3) < len) { 40 | int h = ctoh(in[i+1]); 41 | int l = ctoh(in[i+2]); 42 | if (h >= 0 && l >= 0) { 43 | out.push_back((char)((h << 4) | l)); 44 | i += 3; 45 | continue; 46 | } 47 | } 48 | out.push_back(in[i]); 49 | ++i; 50 | } 51 | return out; 52 | } 53 | 54 | std::string Request::requestHeader(const std::string& name) const 55 | { 56 | std::string out; 57 | 58 | size_t len = httpd_req_get_hdr_value_len(request_, name.c_str()); 59 | if (len) { 60 | out.resize(len); 61 | httpd_req_get_hdr_value_str(request_, name.c_str(), out.data(), out.size() + 1); 62 | } 63 | return out; 64 | } 65 | 66 | void 67 | Request::setContentType(const std::string& type) 68 | { 69 | httpd_resp_set_type(request_, type.c_str()); 70 | } 71 | void 72 | Request::sendResponse(std::string_view data) 73 | { 74 | httpd_resp_send(request_, data.data(), data.length()); 75 | } 76 | 77 | void 78 | Request::sendResponse(const char* data, ssize_t len) 79 | { 80 | httpd_resp_send(request_, data, len); 81 | } 82 | 83 | void 84 | Request::sendError(httpd_err_code_t err) 85 | { 86 | httpd_resp_send_err(request_, err, nullptr); 87 | } 88 | 89 | void 90 | Request::sendError(httpd_err_code_t err, const std::string& msg) 91 | { 92 | httpd_resp_send_err(request_, err, msg.c_str()); 93 | } 94 | 95 | Server::Server() 96 | : handle_(nullptr) 97 | { 98 | httpd_config_t config = HTTPD_DEFAULT_CONFIG(); 99 | config.max_uri_handlers = 8; 100 | config.lru_purge_enable = true; 101 | config.uri_match_fn = httpd_uri_match_wildcard; 102 | 103 | ESP_LOGI(TAG, "Starting server on port: %d", config.server_port); 104 | 105 | if (httpd_start(&handle_, &config) != ESP_OK) { 106 | ESP_LOGE(TAG, "Error starting server!"); 107 | } 108 | 109 | } 110 | 111 | Server::~Server() { 112 | if (handle_) { 113 | httpd_stop(handle_); 114 | } 115 | } 116 | 117 | void 118 | Server::registerHandler(const std::string& uri, RequestHandler& handler) 119 | { 120 | // There doesn't seem to be a generated end to the http_method enum, and 121 | // practically for now we only care about a few, so just look for them. 122 | static const httpd_method_t SUPPORTED_METHODS[] = { 123 | HTTP_DELETE, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH 124 | }; 125 | 126 | httpd_uri_t reg = {}; 127 | reg.uri = uri.c_str(); 128 | reg.handler = Server::dispatch; 129 | reg.user_ctx = &handler; 130 | 131 | WSHandler* wsh = dynamic_cast(&handler); 132 | if (wsh) { 133 | ESP_LOGI(TAG, "WebSocket URI %s", uri.c_str()); 134 | reg.method = HTTP_GET; 135 | reg.is_websocket = true; 136 | if (!wsh->subprotocols().empty()) { 137 | reg.supported_subprotocol = wsh->subprotocols().c_str(); 138 | } 139 | reg.handle_ws_control_frames = wsh->controlFrames(); 140 | esp_err_t rv = httpd_register_uri_handler(handle_, ®); 141 | if (ESP_OK != rv) { 142 | ESP_LOGI(TAG, "Failed registering WebSocket handler for %s: %d", uri.c_str(), rv); 143 | } 144 | return; 145 | } 146 | 147 | for (httpd_method_t m : SUPPORTED_METHODS) { 148 | if (handler.canHandle(m)) { 149 | reg.method = m; 150 | esp_err_t rv = httpd_register_uri_handler(handle_, ®); 151 | if (ESP_OK != rv) { 152 | ESP_LOGI(TAG, 153 | "Failed registering handler for %s: %d", 154 | uri.c_str(), 155 | rv); 156 | } 157 | } 158 | }; 159 | } 160 | 161 | esp_err_t 162 | Server::dispatch(httpd_req_t* req) 163 | { 164 | ESP_LOGI(TAG, "Dispatch method %d handler %p", req->method, req->user_ctx); 165 | RequestHandler* h = static_cast(req->user_ctx); 166 | return h->handle(req); 167 | } 168 | 169 | } // namespace httpd 170 | -------------------------------------------------------------------------------- /components/HttpServer/StaticAssetHandler.cc: -------------------------------------------------------------------------------- 1 | #include "StaticAssetHandler.h" 2 | 3 | namespace httpd { 4 | 5 | StaticAssetHandler::StaticAssetHandler(const StaticAsset& asset, 6 | const std::string& contentType) 7 | : asset_(asset), contentType_(contentType) 8 | { 9 | } 10 | 11 | StaticAssetHandler::StaticAssetHandler(const char* data, 12 | size_t len, 13 | const std::string& contentType) 14 | : StaticAssetHandler(StaticAsset{ data, len }, contentType) 15 | { 16 | } 17 | 18 | esp_err_t 19 | StaticAssetHandler::onGet(Request& req) 20 | { 21 | req.setContentType(contentType_); 22 | req.sendResponse(asset_.data, asset_.len); 23 | return ESP_OK; 24 | } 25 | } // namespace httpd 26 | -------------------------------------------------------------------------------- /components/HttpServer/WebSockets.cc: -------------------------------------------------------------------------------- 1 | #include "WebSockets.h" 2 | #include 3 | #include 4 | 5 | static const char* TAG = "WebSockets"; 6 | 7 | namespace httpd { 8 | 9 | esp_err_t WSSocket::send(std::string_view str, httpd_ws_type_t type) 10 | { 11 | return send((uint8_t*)str.data(), str.size(), type); 12 | } 13 | 14 | esp_err_t WSSocket::send(const uint8_t* payload, size_t len, httpd_ws_type_t type) 15 | { 16 | WSFrame frame = { .final = true, 17 | .fragmented = false, 18 | .type = type, 19 | .payload = const_cast(payload), 20 | .len = len }; 21 | return send(frame); 22 | } 23 | 24 | esp_err_t WSSocket::send(const WSFrame& frame) 25 | { 26 | httpd_ws_client_info_t info = httpd_ws_get_fd_info(server_, fd_); 27 | if (info != HTTPD_WS_CLIENT_WEBSOCKET) { 28 | ESP_LOGI(TAG, "Send on closed socket! %d", info); 29 | return ESP_FAIL; 30 | } 31 | 32 | esp_err_t rv = httpd_ws_send_frame_async(server_, fd_, const_cast(&frame)); 33 | return rv; 34 | } 35 | 36 | WSHandler::WSHandler(const std::string& subprotocols, bool controlFrames) 37 | : subprotocols_(subprotocols), controlFrames_(controlFrames) 38 | { 39 | } 40 | 41 | bool WSHandler::canHandle(httpd_method_t m) const 42 | { 43 | return m == HTTP_GET; 44 | } 45 | 46 | esp_err_t 47 | WSHandler::handle(httpd_req_t* req) 48 | { 49 | WSSocket sock(*this, req->handle, httpd_req_to_sockfd(req)); 50 | ESP_LOGI(TAG, "WSHandler::handle fd: %p %p %d", this, sock.server(), sock.fd()); 51 | 52 | esp_err_t rv = ESP_FAIL; 53 | if (HTTP_GET == req->method) { 54 | ESP_LOGI(TAG, "onConnect"); 55 | rv = onConnect(sock); 56 | ESP_LOGI(TAG, "onConnect result: %d", rv); 57 | return rv; 58 | } 59 | 60 | WSFrame frame = {}; 61 | rv = httpd_ws_recv_frame(req, &frame, 0); 62 | if (ESP_OK != rv) { 63 | ESP_LOGE(TAG, "Failed to read frame length from fd %d: %d", 64 | sock.fd(), rv); 65 | onClose(sock); 66 | return rv; 67 | } 68 | 69 | if (frame.len > 2048) { 70 | ESP_LOGI(TAG, "Frame too long: %d", frame.len); 71 | onClose(sock); 72 | return ESP_FAIL; 73 | } 74 | 75 | ESP_LOGI(TAG, "Calling httpd_ws_recv_frame for len %d", frame.len); 76 | std::vector payload(frame.len); 77 | frame.payload = payload.data(); 78 | rv = httpd_ws_recv_frame(req, &frame, payload.size()); 79 | if (ESP_OK != rv) { 80 | ESP_LOGI(TAG, "httpd_ws_recv_frame error: %d", rv); 81 | } else { 82 | ESP_LOGI(TAG, "Handle onReceive"); 83 | rv = onReceive(sock, frame); 84 | ESP_LOGI(TAG, "onReceive result: %d", rv); 85 | } 86 | 87 | if (ESP_OK != rv) { 88 | onClose(sock); 89 | } 90 | 91 | return rv; 92 | } 93 | 94 | } // namespace httpd 95 | 96 | -------------------------------------------------------------------------------- /components/HttpServer/include/HttpServer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace httpd { 11 | 12 | std::string urldecode(std::string_view in); 13 | 14 | class Server; 15 | 16 | class Request { 17 | public: 18 | Request(httpd_req_t* req) : request_(req) {}; 19 | httpd_req_t* request() const { return request_; } 20 | 21 | httpd_method_t method() const { return (httpd_method_t)request_->method; } 22 | std::string_view uri() const { return std::string_view(request_->uri); } 23 | bool isGet() const { return HTTP_GET == method(); } 24 | bool isPost() const { return HTTP_POST == method(); } 25 | 26 | size_t contentLength() const { return request_->content_len; } 27 | 28 | std::string requestHeader(const std::string& name) const; 29 | 30 | void setContentType(const std::string& type); 31 | 32 | void sendResponse(std::string_view data); 33 | void sendResponse(const char* data, ssize_t len); 34 | 35 | void sendError(httpd_err_code_t error); 36 | void sendError(httpd_err_code_t err, const std::string& msg); 37 | 38 | private: 39 | httpd_req_t* request_; 40 | }; 41 | 42 | class RequestHandler { 43 | public: 44 | virtual ~RequestHandler() = default; 45 | virtual bool canHandle(httpd_method_t method) const = 0; 46 | virtual esp_err_t handle(httpd_req_t* req) = 0; 47 | }; 48 | 49 | template 50 | class MethodBase { }; 51 | 52 | #define DECLARE_METHOD(NAME, METHOD) \ 53 | template <> \ 54 | class MethodBase { \ 55 | public: \ 56 | static const httpd_method_t method = METHOD; \ 57 | virtual esp_err_t on##NAME(Request&) = 0; \ 58 | \ 59 | protected: \ 60 | esp_err_t handle_(httpd_req_t* req) \ 61 | { \ 62 | Request r(req); \ 63 | return on##NAME(r); \ 64 | } \ 65 | }; \ 66 | // using NAME = MethodBase; 67 | 68 | DECLARE_METHOD(Delete, HTTP_DELETE); 69 | DECLARE_METHOD(Get, HTTP_GET); 70 | DECLARE_METHOD(Post, HTTP_POST); 71 | DECLARE_METHOD(Patch, HTTP_PATCH); 72 | 73 | #undef DECLARE_METHOD 74 | 75 | template class MethodNode 76 | { 77 | protected: 78 | bool canHandle_(httpd_method_t) const { return false; } 79 | esp_err_t handle_(httpd_req_t*) { return ESP_FAIL; } 80 | }; 81 | 82 | template 83 | class MethodNode : public This, public MethodNode { 84 | private: 85 | using Next = MethodNode; 86 | 87 | protected: 88 | bool canHandle_(httpd_method_t m) const { 89 | return This::method == m || Next::canHandle_(m); 90 | } 91 | 92 | esp_err_t handle_(httpd_req_t* req) { 93 | if (This::method == req->method) { 94 | return This::handle_(req); 95 | } 96 | return Next::handle_(req); 97 | } 98 | }; 99 | 100 | template 101 | class MethodHandler : public RequestHandler, public MethodNode...> 102 | { 103 | private: 104 | using Nodes = MethodNode...>; 105 | 106 | public: 107 | virtual bool canHandle(httpd_method_t method) const override{ 108 | return Nodes::canHandle_(method); 109 | } 110 | 111 | virtual esp_err_t handle(httpd_req_t* req) override 112 | { 113 | return Nodes::handle_(req); 114 | } 115 | }; 116 | 117 | class Server { 118 | public: 119 | Server(); 120 | ~Server(); 121 | 122 | void registerHandler(const std::string& uri, RequestHandler& handler); 123 | 124 | protected: 125 | httpd_handle_t server() const { return handle_; } 126 | 127 | private: 128 | httpd_handle_t handle_; 129 | static esp_err_t dispatch(httpd_req_t* req); 130 | }; 131 | 132 | } // namespace httpd 133 | -------------------------------------------------------------------------------- /components/HttpServer/include/StaticAssetHandler.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "HttpServer.h" 4 | 5 | namespace httpd { 6 | 7 | struct StaticAsset { 8 | const char* data; 9 | size_t len; 10 | }; 11 | 12 | // Initialize a StaticAsset from a file embedded in the build. The ASM address 13 | // lookup must be a statement, so this abuses a lambda to scope it and return. 14 | #define EmbeddedAsset(name__) \ 15 | [] { \ 16 | using httpd::StaticAsset; \ 17 | extern const char start__[] asm("_binary_" #name__ "_start"); \ 18 | extern size_t len__ asm(#name__ "_length"); \ 19 | return StaticAsset{ start__, len__ }; \ 20 | }() 21 | 22 | class StaticAssetHandler : public MethodHandler 23 | { 24 | public: 25 | StaticAssetHandler(const StaticAsset& asset, const std::string& contentType = "text/html"); 26 | StaticAssetHandler(const char* data, size_t len, const std::string& contentType = "text/html"); 27 | 28 | esp_err_t onGet(httpd::Request& req); 29 | 30 | private: 31 | StaticAsset asset_; 32 | std::string contentType_; 33 | }; 34 | 35 | } // namespace httpd 36 | -------------------------------------------------------------------------------- /components/HttpServer/include/WebSockets.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "HttpServer.h" 4 | #include 5 | 6 | #ifdef CONFIG_HTTPD_WS_SUPPORT 7 | 8 | namespace httpd { 9 | class WSHandler; 10 | 11 | using WSFrame = httpd_ws_frame_t; 12 | 13 | class WSSocket { 14 | public: 15 | WSHandler& handler() { return handler_; } 16 | httpd_handle_t server() const { return server_; } 17 | int fd() const { return fd_; } 18 | 19 | esp_err_t send(std::string_view str, httpd_ws_type_t type = HTTPD_WS_TYPE_TEXT); 20 | esp_err_t send(const uint8_t* data, size_t len, httpd_ws_type_t type = HTTPD_WS_TYPE_BINARY); 21 | esp_err_t send(const WSFrame& frame); 22 | 23 | private: 24 | friend class WSHandler; 25 | 26 | WSSocket(WSHandler& handler, httpd_handle_t server, int fd) 27 | : handler_(handler), server_(server), fd_(fd){}; 28 | 29 | WSHandler& handler_; 30 | httpd_handle_t server_; 31 | int fd_; 32 | }; 33 | 34 | class WSHandler : public RequestHandler { 35 | public: 36 | WSHandler(const std::string& subprotocols = std::string(), 37 | bool controlFrames = false); 38 | 39 | const std::string& subprotocols() const { return subprotocols_; } 40 | bool controlFrames() const { return controlFrames_; } 41 | 42 | virtual bool canHandle(httpd_method_t m) const final; 43 | virtual esp_err_t handle(httpd_req_t* req) override; 44 | 45 | virtual esp_err_t onConnect(WSSocket&) = 0; 46 | virtual esp_err_t onReceive(WSSocket&, const WSFrame&) = 0; 47 | virtual void onClose(WSSocket&) {} 48 | 49 | private: 50 | std::string subprotocols_; 51 | bool controlFrames_; 52 | }; 53 | 54 | 55 | } // namespace httpd 56 | 57 | #endif // CONFIG_HTTPD_WS_SUPPORT 58 | -------------------------------------------------------------------------------- /components/Hub75Display/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register( 2 | SRCS "Hub75Display.c" 3 | "i2s_parallel.c" 4 | "val2pwm.c" 5 | INCLUDE_DIRS "include" 6 | REQUIRES "driver" 7 | ) 8 | -------------------------------------------------------------------------------- /components/Hub75Display/Hub75Display.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | #include "Hub75Display.h" 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "freertos/FreeRTOS.h" 21 | #include "freertos/queue.h" 22 | #include "freertos/semphr.h" 23 | #include "freertos/task.h" 24 | 25 | #include "driver/gpio.h" 26 | #include "esp_heap_caps.h" 27 | #include "i2s_parallel.h" 28 | #include "val2pwm.h" 29 | 30 | // This is example code to driver a p3(2121)64*32 -style RGB LED display. These 31 | // types of displays do not have memory and need to be refreshed continuously. 32 | // The display has 2 RGB inputs, 4 inputs to select the active line, a pixel 33 | // clock input, a latch enable input and an output-enable input. The display can 34 | // be seen as 2 64x16 displays consisting of the upper half and the lower half 35 | // of the display. Each half has a separate RGB pixel input, the rest of the 36 | // inputs are shared. 37 | // 38 | // Each display half can only show one line of RGB pixels at a time: to do this, 39 | // the RGB data for the line is input by setting the RGB input pins to the 40 | // desired value for the first pixel, giving the display a clock pulse, setting 41 | // the RGB input pins to the desired value for the second pixel, giving a clock 42 | // pulse, etc. Do this 64 times to clock in an entire row. The pixels will not 43 | // be displayed yet: until the latch input is made high, the display will still 44 | // send out the previously clocked in line. Pulsing the latch input high will 45 | // replace the displayed data with the data just clocked in. 46 | // 47 | // The 4 line select inputs select where the currently active line is displayed: 48 | // when provided with a binary number (0-15), the latched pixel data will 49 | // immediately appear on this line. Note: While clocking in data for a line, the 50 | // *previous* line is still displayed, and these lines should be set to the value 51 | // to reflect the position the *previous* line is supposed to be on. 52 | // 53 | // Finally, the screen has an OE input, which is used to disable the LEDs when 54 | // latching new data and changing the state of the line select inputs: doing so 55 | // hides any artifacts that appear at this time. The OE line is also used to dim 56 | // the display by only turning it on for a limited time every line. 57 | // 58 | // All in all, an image can be displayed by 'scanning' the display, say, 100 59 | // times per second. The slowness of the human eye hides the fact that only one 60 | // line is showed at a time, and the display looks like every pixel is driven at 61 | // the same time. 62 | // 63 | // Now, the RGB inputs for these types of displays are digital, meaning each 64 | // red, green and blue subpixel can only be on or off. This leads to a color 65 | // palette of 8 pixels, not enough to display nice pictures. To get around this, 66 | // we use binary code modulation. 67 | // 68 | // Binary code modulation is somewhat like PWM, but easier to implement in our 69 | // case. First, we define the time we would refresh the display without binary 70 | // code modulation as the 'frame time'. For, say, a four-bit binary code 71 | // modulation, the frame time is divided into 15 ticks of equal length. 72 | // 73 | // We also define 4 subframes (0 to 3), defining which LEDs are on and which 74 | // LEDs are off during that subframe. (Subframes are the same as a normal frame 75 | // in non-binary-coded-modulation mode, but are showed faster.) From our 76 | // (non-monochrome) input image, we take the (8-bit: bit 7 to bit 0) RGB pixel 77 | // values. If the pixel values have bit 7 set, we turn the corresponding LED on 78 | // in subframe 3. If they have bit 6 set, we turn on the corresponding LED in 79 | // subframe 2, if bit 5 is set subframe 1, if bit 4 is set in subframe 0. 80 | // 81 | // Now, in order to (on average within a frame) turn a LED on for the time 82 | // specified in the pixel value in the input data, we need to weigh the 83 | // subframes. We have 15 pixels: if we show subframe 3 for 8 of them, subframe 2 84 | // for 4 of them, subframe 1 for 2 of them and subframe 1 for 1 of them, this 85 | // 'automatically' happens. (We also distribute the subframes evenly over the 86 | // ticks, which reduces flicker.) 87 | // 88 | // 89 | // In this code, we use the I2S peripheral in parallel mode to achieve this. 90 | // Essentially, first we allocate memory for all subframes. This memory contains 91 | // a sequence of all the signals (2xRGB, line select, latch enable, output 92 | // enable) that need to be sent to the display for that subframe. Then we ask 93 | // the I2S-parallel driver to set up a DMA chain so the subframes are sent out 94 | // in a sequence that satisfies the requirement that subframe x has to be sent 95 | // out for (2^x) ticks. Finally, we fill the subframes with image data. 96 | // 97 | // We use a frontbuffer/backbuffer technique here to make sure the display is 98 | // refreshed in one go and drawing artifacts do not reach the display. In 99 | // practice, for small displays this is not really necessarily. 100 | // 101 | // Finally, the binary code modulated intensity of a LED does not correspond to 102 | // the intensity as seen by human eyes. To correct for that, a luminance 103 | // correction is used. See val2pwm.c for more info. 104 | // 105 | // Note: Because every subframe contains one bit of grayscale information, they 106 | // are also referred to as 'bitplanes' by the code below. 107 | 108 | #define matrixHeight 32 109 | #define matrixWidth 64 110 | #define matrixRowsInParallel 2 111 | 112 | #define ESP32_NUM_FRAME_BUFFERS 2 113 | #define ESP32_OE_OFF_CLKS_AFTER_LATCH 1 114 | 115 | // This is the bit depth, per RGB subpixel, of the data that is sent to the 116 | // display. The effective bit depth (in computer pixel terms) is less because of 117 | // the PWM correction. With a bitplane count of 7, you should be able to 118 | // reproduce an 16-bit image more or less faithfully, though. 119 | #define BITPLANE_CNT 7 120 | 121 | // LSBMSB_TRANSITION_BIT defines the color bit that is refreshed once per frame, 122 | // with the same brightness as the bits above it when LSBMSB_TRANSITION_BIT is 123 | // non-zero, all color bits below it will be be refreshed only once, with 124 | // fractional brightness, saving RAM and speeding up refresh LSBMSB_TRANSITION_BIT 125 | // must be < BITPLANE_CNT 126 | #define LSBMSB_TRANSITION_BIT 1 127 | 128 | // 64*32 RGB leds, 2 pixels per 16-bit value... 129 | #define BITPLANE_SZ (matrixWidth * matrixHeight / matrixRowsInParallel) 130 | 131 | // I2S Data Position Definitions 132 | // Upper half RGB 133 | #define BIT_R1 (1 << 0) 134 | #define BIT_G1 (1 << 1) 135 | #define BIT_B1 (1 << 2) 136 | // Lower half RGB 137 | #define BIT_R2 (1 << 3) 138 | #define BIT_G2 (1 << 4) 139 | #define BIT_B2 (1 << 5) 140 | 141 | #define BIT_A (1 << 8) 142 | #define BIT_B (1 << 9) 143 | #define BIT_C (1 << 10) 144 | #define BIT_D (1 << 11) 145 | #define BIT_LAT (1 << 12) 146 | #define BIT_OE (1 << 13) 147 | 148 | // Pin Definitions 149 | #define R1_PIN 21 150 | #define G1_PIN 19 151 | #define B1_PIN 18 152 | #define R2_PIN 5 153 | #define G2_PIN 17 154 | #define B2_PIN 16 155 | 156 | #define A_PIN 4 157 | #define B_PIN 2 158 | #define C_PIN 25 159 | #define D_PIN 15 160 | #define LAT_PIN 26 161 | #define OE_PIN 27 162 | 163 | #define CLK_PIN 22 164 | 165 | // note: sizeof(data) must be multiple of 32 bits, as DMA linked list buffer 166 | // address pointer must be word-aligned. 167 | typedef struct rowBitStruct { 168 | uint16_t data[matrixWidth]; 169 | } rowBitStruct; 170 | 171 | typedef struct rowDataStruct { 172 | rowBitStruct rowbits[BITPLANE_CNT]; 173 | } rowDataStruct; 174 | 175 | typedef struct frameStruct { 176 | rowDataStruct rowdata[matrixHeight / matrixRowsInParallel]; 177 | } frameStruct; 178 | 179 | // Get a pixel from the image at pix, assuming the image is a matrixWidth x 180 | // matrixHeight 8R8G8B8A image. Returns it as an uint32 with the lower 24 181 | // bits containing the RGB values. 182 | static uint32_t 183 | getpixel(const uint8_t* pix, int x, int y) 184 | { 185 | int idx = (y * matrixWidth * 4) + (x * 4); 186 | return ((uint32_t)valToPwm(pix[idx]) << 16) | 187 | ((uint32_t)valToPwm(pix[idx + 1]) << 8) | 188 | ((uint32_t)valToPwm(pix[idx + 2]) << 0); 189 | } 190 | 191 | int brightness = 16; // Change to set the global brightness of the display, 192 | // range 1-matrixWidth Warning when set too high: Do not 193 | // look into LEDs with remaining eye. 194 | 195 | // TODO: find more efficient way of signaling the end of the buffer description 196 | // than adding two extra rows 197 | i2s_parallel_buffer_desc_t bufdesc[2][matrixHeight / matrixRowsInParallel + 1] 198 | [1 << (BITPLANE_CNT - LSBMSB_TRANSITION_BIT - 1)]; 199 | 200 | i2s_parallel_config_t cfg = { 201 | .gpio_bus = { R1_PIN, 202 | G1_PIN, 203 | B1_PIN, 204 | R2_PIN, 205 | G2_PIN, 206 | B2_PIN, 207 | -1, 208 | -1, 209 | A_PIN, 210 | B_PIN, 211 | C_PIN, 212 | D_PIN, 213 | LAT_PIN, 214 | OE_PIN, 215 | -1, 216 | -1 }, 217 | .gpio_clk = CLK_PIN, 218 | .clkspeed_hz = 20 * 1000 * 1000, 219 | .bits = I2S_PARALLEL_BITS_16, 220 | .bufa = bufdesc[0][0], 221 | .bufb = bufdesc[1][0], 222 | }; 223 | 224 | // pixel data is organized from LSB to MSB sequentially by row, from row 0 to row 225 | // matrixHeight/matrixRowsInParallel (two rows of pixels are refreshed in parallel) 226 | frameStruct* bitplane; 227 | 228 | void 229 | hub75DisplaySetup() 230 | { 231 | bitplane = (frameStruct*)heap_caps_malloc(sizeof(frameStruct) * 232 | ESP32_NUM_FRAME_BUFFERS, 233 | MALLOC_CAP_DMA); 234 | assert("Can't allocate bitplane memory"); 235 | 236 | for (int j = 0; j < matrixHeight / matrixRowsInParallel; j++) { 237 | // first set of data is LSB through MSB, single pass - all color bits 238 | // are displayed once, which takes care of everything below and 239 | // inlcluding LSBMSB_TRANSITION_BIT 240 | bufdesc[0][j][0].memory = bitplane[0].rowdata[j].rowbits[0].data; 241 | bufdesc[0][j][0].size = sizeof(rowBitStruct) * BITPLANE_CNT; 242 | bufdesc[1][j][0].memory = bitplane[1].rowdata[j].rowbits[0].data; 243 | bufdesc[1][j][0].size = sizeof(rowBitStruct) * BITPLANE_CNT; 244 | 245 | int nextBufdescIndex = 1; 246 | 247 | for (int i = LSBMSB_TRANSITION_BIT + 1; i < BITPLANE_CNT; i++) { 248 | // binary time division setup: we need 2 of bit 249 | // (LSBMSB_TRANSITION_BIT + 1) four of (LSBMSB_TRANSITION_BIT + 2), 250 | // etc because we sweep through to MSB each time, it divides the 251 | // number of times we have to sweep in half (saving linked list RAM) 252 | // we need 2^(i - LSBMSB_TRANSITION_BIT - 1) == 1 << (i - 253 | // LSBMSB_TRANSITION_BIT - 1) passes from i to MSB 254 | // printf("buffer %d: repeat %d times, size: %d, from %d - %d\r\n", 255 | // nextBufdescIndex, 1<<(i - LSBMSB_TRANSITION_BIT - 1), 256 | // (BITPLANE_CNT - i), i, BITPLANE_CNT-1); 257 | 258 | for (int k = 0; k < 1 << (i - LSBMSB_TRANSITION_BIT - 1); k++) { 259 | bufdesc[0][j][nextBufdescIndex].memory = 260 | bitplane[0].rowdata[j].rowbits[i].data; 261 | bufdesc[0][j][nextBufdescIndex].size = 262 | sizeof(rowBitStruct) * (BITPLANE_CNT - i); 263 | bufdesc[1][j][nextBufdescIndex].memory = 264 | bitplane[1].rowdata[j].rowbits[i].data; 265 | bufdesc[1][j][nextBufdescIndex].size = 266 | sizeof(rowBitStruct) * (BITPLANE_CNT - i); 267 | nextBufdescIndex++; 268 | // printf("i %d, j %d, k %d\r\n", i, j, k); 269 | } 270 | } 271 | } 272 | 273 | // End markers 274 | bufdesc[0][matrixHeight / matrixRowsInParallel][0].memory = NULL; 275 | bufdesc[1][matrixHeight / matrixRowsInParallel][0].memory = NULL; 276 | 277 | // Setup I2S 278 | i2s_parallel_setup(&I2S1, &cfg); 279 | } 280 | 281 | void 282 | hub75DisplayDraw(const uint8_t* pix) 283 | { 284 | static int backbuf_id = 0; // which buffer is the backbuffer, as in, which 285 | // one is not active so we can write to it 286 | 287 | for (unsigned int y = 0; y < matrixHeight / matrixRowsInParallel; y++) { 288 | for (int pl = 0; pl < BITPLANE_CNT; pl++) { 289 | uint16_t* p = 290 | bitplane[backbuf_id].rowdata[y].rowbits[pl].data; // bitplane 291 | // location to 292 | // write to 293 | int mask = 294 | (1 << (8 - BITPLANE_CNT + pl)); // bitmask for pixel data in 295 | // input for this bitplane 296 | int lbits = 0; // Precalculate line bits of the current line, which 297 | // is the one we're displaying now 298 | int rowAddress = y; 299 | 300 | // normally output current rows ADDX, special case for LSB, output 301 | // previous row's ADDX (as previous row is being displayed for one 302 | // latch cycle) 303 | if (pl == 0) 304 | rowAddress = y - 1; 305 | 306 | if (rowAddress & 1) 307 | lbits |= BIT_A; 308 | if (rowAddress & 2) 309 | lbits |= BIT_B; 310 | if (rowAddress & 4) 311 | lbits |= BIT_C; 312 | if (rowAddress & 8) 313 | lbits |= BIT_D; 314 | for (int fx = 0; fx < matrixWidth; fx++) { 315 | int x = fx; 316 | int v = lbits; 317 | // Do not show image while the line bits are changing 318 | if (fx < ESP32_OE_OFF_CLKS_AFTER_LATCH || fx >= (matrixWidth - 1)) 319 | v |= BIT_OE; 320 | 321 | // turn off OE after brightness value is reached - used for MSBs 322 | // and LSB MSBs always output normal brightness LSB outputs 323 | // normal brightness as MSB from previous row is being displayed 324 | if ((pl > LSBMSB_TRANSITION_BIT || !pl) && 325 | fx > brightness + ESP32_OE_OFF_CLKS_AFTER_LATCH) 326 | v |= BIT_OE; 327 | 328 | // special case for the bits *after* LSB through 329 | // (LSBMSB_TRANSITION_BIT) - OE is output after data is shifted, 330 | // so need to set OE to fractional brightness 331 | if (pl && pl <= LSBMSB_TRANSITION_BIT) { 332 | // divide brightness in half for each bit below 333 | // LSBMSB_TRANSITION_BIT 334 | int lsbBrightness = 335 | brightness >> (LSBMSB_TRANSITION_BIT - pl + 1); 336 | if (fx > lsbBrightness + ESP32_OE_OFF_CLKS_AFTER_LATCH) 337 | v |= BIT_OE; 338 | } 339 | 340 | if (fx == matrixWidth - 1) 341 | v |= BIT_LAT; // latch on last bit 342 | 343 | int c1, c2; 344 | c1 = getpixel(pix, x, y); 345 | c2 = getpixel(pix, x, y + (matrixHeight / 2)); 346 | 347 | if (c1 & (mask << 16)) 348 | v |= BIT_R1; 349 | if (c1 & (mask << 8)) 350 | v |= BIT_G1; 351 | if (c1 & (mask << 0)) 352 | v |= BIT_B1; 353 | if (c2 & (mask << 16)) 354 | v |= BIT_R2; 355 | if (c2 & (mask << 8)) 356 | v |= BIT_G2; 357 | if (c2 & (mask << 0)) 358 | v |= BIT_B2; 359 | 360 | // Save the calculated value to the bitplane memory in reverse 361 | // order to account for I2S Tx FIFO mode1 ordering 362 | if (fx % 2) { 363 | *p = v; 364 | p += 2; 365 | } else { 366 | *(p + 1) = v; 367 | } 368 | } 369 | } 370 | } 371 | 372 | // Show our work! 373 | i2s_parallel_flip_to_buffer(&I2S1, backbuf_id); 374 | backbuf_id ^= 1; 375 | } 376 | -------------------------------------------------------------------------------- /components/Hub75Display/i2s_parallel.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "freertos/FreeRTOS.h" 21 | #include "freertos/task.h" 22 | #include "freertos/semphr.h" 23 | #include "freertos/queue.h" 24 | 25 | #include "esp_log.h" 26 | #include "esp_private/periph_ctrl.h" 27 | #include "soc/i2s_struct.h" 28 | #include "soc/i2s_reg.h" 29 | #include "soc/gpio_sig_map.h" 30 | #include "soc/io_mux_reg.h" 31 | #include "driver/gpio.h" 32 | #include "rom/lldesc.h" 33 | #include "rom/gpio.h" 34 | #include "esp_heap_caps.h" 35 | #include "val2pwm.h" 36 | #include "i2s_parallel.h" 37 | 38 | static const char* TAG = "i2s_parallel"; 39 | 40 | typedef struct { 41 | volatile lldesc_t *dmadesc_a, *dmadesc_b; 42 | int desccount_a, desccount_b; 43 | } i2s_parallel_state_t; 44 | 45 | static i2s_parallel_state_t *i2s_state[2]={NULL, NULL}; 46 | 47 | #define DMA_MAX (4096-4) 48 | 49 | //Calculate the amount of dma descs needed for a buffer desc 50 | static int calc_needed_dma_descs_for(i2s_parallel_buffer_desc_t *desc) { 51 | int ret=0; 52 | for (int i=0; desc[i].memory!=NULL; i++) { 53 | ret+=(desc[i].size+DMA_MAX-1)/DMA_MAX; 54 | } 55 | return ret; 56 | } 57 | 58 | static void fill_dma_desc(volatile lldesc_t *dmadesc, i2s_parallel_buffer_desc_t *bufdesc) { 59 | int n=0; 60 | for (int i=0; bufdesc[i].memory!=NULL; i++) { 61 | int len=bufdesc[i].size; 62 | uint8_t *data=(uint8_t*)bufdesc[i].memory; 63 | //printf("fill_dma_desc: n %d data %x size %d\n", n, (uint32_t)bufdesc[i].memory, bufdesc[i].size); 64 | while(len) { 65 | int dmalen=len; 66 | if (dmalen>DMA_MAX) dmalen=DMA_MAX; 67 | dmadesc[n].size=dmalen; 68 | dmadesc[n].length=dmalen; 69 | dmadesc[n].buf=data; 70 | dmadesc[n].eof=0; 71 | dmadesc[n].sosf=0; 72 | dmadesc[n].owner=1; 73 | dmadesc[n].qe.stqe_next=(lldesc_t*)&dmadesc[n+1]; 74 | dmadesc[n].offset=0; 75 | len-=dmalen; 76 | data+=dmalen; 77 | n++; 78 | } 79 | } 80 | //Loop last back to first 81 | dmadesc[n-1].qe.stqe_next=(lldesc_t*)&dmadesc[0]; 82 | printf("fill_dma_desc: filled %d descriptors\n", n); 83 | } 84 | 85 | static void gpio_setup_out(int gpio, int sig) { 86 | ESP_LOGI(TAG, "Pin: %d, Sig: %d", gpio, sig); 87 | if (gpio==-1) return; 88 | gpio_reset_pin(gpio); 89 | gpio_set_direction(gpio, GPIO_MODE_DEF_OUTPUT); 90 | gpio_matrix_out(gpio, sig, false, false); 91 | gpio_dump_io_configuration(stdout, 1<lc_conf.in_rst=1; dev->lc_conf.in_rst=0; 97 | dev->lc_conf.out_rst=1; dev->lc_conf.out_rst=0; 98 | } 99 | 100 | static void fifo_reset(i2s_dev_t *dev) { 101 | dev->conf.rx_fifo_reset=1; dev->conf.rx_fifo_reset=0; 102 | dev->conf.tx_fifo_reset=1; dev->conf.tx_fifo_reset=0; 103 | } 104 | 105 | static int i2snum(i2s_dev_t *dev) { 106 | return (dev==&I2S0)?0:1; 107 | } 108 | 109 | void i2s_parallel_setup(i2s_dev_t *dev, const i2s_parallel_config_t *cfg) { 110 | //Figure out which signal numbers to use for routing 111 | ESP_LOGI(TAG, "Setting up parallel I2S bus at I2S%d\n", i2snum(dev)); 112 | int sig_data_base, sig_clk; 113 | if (dev==&I2S0) { 114 | sig_clk=I2S0O_WS_OUT_IDX; 115 | if (cfg->bits==I2S_PARALLEL_BITS_32) { 116 | sig_data_base=I2S0O_DATA_OUT0_IDX; 117 | } else { 118 | //Because of... reasons... the 16-bit values for i2s0 appear on d8...d23 119 | sig_data_base=I2S0O_DATA_OUT8_IDX; 120 | } 121 | } else { 122 | if (cfg->bits==I2S_PARALLEL_BITS_32) { 123 | sig_data_base=I2S1O_DATA_OUT0_IDX; 124 | } else if (cfg->bits==I2S_PARALLEL_BITS_16) { 125 | //Because of... reasons... the 16-bit values for i2s1 appear on d8...d23 126 | sig_data_base=I2S1O_DATA_OUT8_IDX; 127 | } else { 128 | sig_data_base=I2S1O_DATA_OUT0_IDX; 129 | } 130 | sig_clk=I2S1O_WS_OUT_IDX; 131 | } 132 | 133 | //Route the signals 134 | 135 | for (int x=0; xbits; x++) { 136 | gpio_setup_out(cfg->gpio_bus[x], sig_data_base+x); 137 | } 138 | //ToDo: Clk/WS may need inversion? 139 | gpio_setup_out(cfg->gpio_clk, sig_clk); 140 | 141 | //Power on dev 142 | if (dev==&I2S0) { 143 | periph_module_enable(PERIPH_I2S0_MODULE); 144 | } else { 145 | periph_module_enable(PERIPH_I2S1_MODULE); 146 | } 147 | //Initialize I2S dev 148 | dev->conf.rx_reset=1; dev->conf.rx_reset=0; 149 | dev->conf.tx_reset=1; dev->conf.tx_reset=0; 150 | dma_reset(dev); 151 | fifo_reset(dev); 152 | 153 | //Enable LCD mode 154 | dev->conf2.val=0; 155 | dev->conf2.lcd_en=1; 156 | 157 | dev->sample_rate_conf.val=0; 158 | dev->sample_rate_conf.rx_bits_mod=cfg->bits; 159 | dev->sample_rate_conf.tx_bits_mod=cfg->bits; 160 | dev->sample_rate_conf.rx_bck_div_num=4; //ToDo: Unsure about what this does... 161 | //dev->sample_rate_conf.tx_bck_div_num=4; 162 | dev->sample_rate_conf.tx_bck_div_num=2; // datasheet says this must be 2 or greater (but 1 seems to work) 163 | 164 | dev->clkm_conf.val=0; 165 | dev->clkm_conf.clka_en=0; 166 | dev->clkm_conf.clkm_div_a=63; 167 | dev->clkm_conf.clkm_div_b=63; 168 | //We ignore the possibility for fractional division here. 169 | //dev->clkm_conf.clkm_div_num=80000000L/cfg->clkspeed_hz; 170 | dev->clkm_conf.clkm_div_num=4; // datasheet says this must be 2 or greater (but lower values seem to work) 171 | 172 | // this combination is 25MHz 173 | //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) 174 | //dev->clkm_conf.clkm_div_num=2; // datasheet says this must be 2 or greater (but lower values seem to work) 175 | 176 | // this combination is 20MHz 177 | //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) 178 | //dev->clkm_conf.clkm_div_num=3; // datasheet says this must be 2 or greater (but lower values seem to work) 179 | 180 | // 16 MHz 181 | //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) 182 | //dev->clkm_conf.clkm_div_num=4; // datasheet says this must be 2 or greater (but lower values seem to work) 183 | 184 | // 13MHz 185 | //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) 186 | //dev->clkm_conf.clkm_div_num=5; // datasheet says this must be 2 or greater (but lower values seem to work) 187 | 188 | // 11.3MHz 189 | //dev->sample_rate_conf.tx_bck_div_num=1; // datasheet says this must be 2 or greater (but 1 seems to work) 190 | //dev->clkm_conf.clkm_div_num=6; // datasheet says this must be 2 or greater (but lower values seem to work) 191 | 192 | // 13.x MHz 193 | //dev->sample_rate_conf.tx_bck_div_num=2; // datasheet says this must be 2 or greater (but 1 seems to work) 194 | //dev->clkm_conf.clkm_div_num=2; // datasheet says this must be 2 or greater (but lower values seem to work) 195 | 196 | // 10MHz 197 | //dev->sample_rate_conf.tx_bck_div_num=2; // datasheet says this must be 2 or greater (but 1 seems to work) 198 | //dev->clkm_conf.clkm_div_num=3; // datasheet says this must be 2 or greater (but lower values seem to work) 199 | 200 | // 8MHz 201 | //dev->sample_rate_conf.tx_bck_div_num=2; // datasheet says this must be 2 or greater (but 1 seems to work) 202 | //dev->clkm_conf.clkm_div_num=4; // datasheet says this must be 2 or greater (but lower values seem to work) 203 | 204 | 205 | 206 | dev->fifo_conf.val=0; 207 | dev->fifo_conf.rx_fifo_mod_force_en=1; 208 | dev->fifo_conf.tx_fifo_mod_force_en=1; 209 | //dev->fifo_conf.tx_fifo_mod=1; 210 | dev->fifo_conf.tx_fifo_mod=1; 211 | dev->fifo_conf.rx_data_num=32; //Thresholds. 212 | dev->fifo_conf.tx_data_num=32; 213 | dev->fifo_conf.dscr_en=1; 214 | 215 | dev->conf1.val=0; 216 | dev->conf1.tx_stop_en=0; 217 | dev->conf1.tx_pcm_bypass=1; 218 | 219 | dev->conf_chan.val=0; 220 | dev->conf_chan.tx_chan_mod=1; 221 | dev->conf_chan.rx_chan_mod=1; 222 | 223 | //Invert ws to be active-low... ToDo: make this configurable 224 | //dev->conf.tx_right_first=1; 225 | dev->conf.tx_right_first=0; 226 | //dev->conf.rx_right_first=1; 227 | dev->conf.rx_right_first=0; 228 | 229 | dev->timing.val=0; 230 | 231 | //Allocate DMA descriptors 232 | i2s_state[i2snum(dev)]=malloc(sizeof(i2s_parallel_state_t)); 233 | i2s_parallel_state_t *st=i2s_state[i2snum(dev)]; 234 | st->desccount_a=calc_needed_dma_descs_for(cfg->bufa); 235 | st->desccount_b=calc_needed_dma_descs_for(cfg->bufb); 236 | st->dmadesc_a=heap_caps_malloc(st->desccount_a*sizeof(lldesc_t), MALLOC_CAP_DMA); 237 | st->dmadesc_b=heap_caps_malloc(st->desccount_b*sizeof(lldesc_t), MALLOC_CAP_DMA); 238 | 239 | //and fill them 240 | fill_dma_desc(st->dmadesc_a, cfg->bufa); 241 | fill_dma_desc(st->dmadesc_b, cfg->bufb); 242 | 243 | //Reset FIFO/DMA -> needed? Doesn't dma_reset/fifo_reset do this? 244 | 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; 245 | 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; 246 | dev->conf.tx_reset=1; dev->conf.tx_fifo_reset=1; dev->conf.rx_fifo_reset=1; 247 | dev->conf.tx_reset=0; dev->conf.tx_fifo_reset=0; dev->conf.rx_fifo_reset=0; 248 | 249 | //Start dma on front buffer 250 | dev->lc_conf.val=I2S_OUT_DATA_BURST_EN | I2S_OUTDSCR_BURST_EN | I2S_OUT_DATA_BURST_EN; 251 | dev->out_link.addr=((uint32_t)(&st->dmadesc_a[0])); 252 | dev->out_link.start=1; 253 | dev->conf.tx_start=1; 254 | } 255 | 256 | 257 | //Flip to a buffer: 0 for bufa, 1 for bufb 258 | void i2s_parallel_flip_to_buffer(i2s_dev_t *dev, int bufid) { 259 | int no=i2snum(dev); 260 | if (i2s_state[no]==NULL) return; 261 | lldesc_t *active_dma_chain; 262 | if (bufid==0) { 263 | active_dma_chain=(lldesc_t*)&i2s_state[no]->dmadesc_a[0]; 264 | } else { 265 | active_dma_chain=(lldesc_t*)&i2s_state[no]->dmadesc_b[0]; 266 | } 267 | 268 | i2s_state[no]->dmadesc_a[i2s_state[no]->desccount_a-1].qe.stqe_next=active_dma_chain; 269 | i2s_state[no]->dmadesc_b[i2s_state[no]->desccount_b-1].qe.stqe_next=active_dma_chain; 270 | } 271 | 272 | -------------------------------------------------------------------------------- /components/Hub75Display/i2s_parallel.h: -------------------------------------------------------------------------------- 1 | #ifndef I2S_PARALLEL_H 2 | #define I2S_PARALLEL_H 3 | 4 | #include 5 | #include "soc/i2s_struct.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | typedef enum { 12 | I2S_PARALLEL_BITS_8=8, 13 | I2S_PARALLEL_BITS_16=16, 14 | I2S_PARALLEL_BITS_32=32, 15 | } i2s_parallel_cfg_bits_t; 16 | 17 | typedef struct { 18 | void *memory; 19 | size_t size; 20 | } i2s_parallel_buffer_desc_t; 21 | 22 | typedef struct { 23 | int gpio_bus[24]; 24 | int gpio_clk; 25 | int clkspeed_hz; 26 | i2s_parallel_cfg_bits_t bits; 27 | i2s_parallel_buffer_desc_t *bufa; 28 | i2s_parallel_buffer_desc_t *bufb; 29 | } i2s_parallel_config_t; 30 | 31 | void i2s_parallel_setup(i2s_dev_t *dev, const i2s_parallel_config_t *cfg); 32 | void i2s_parallel_flip_to_buffer(i2s_dev_t *dev, int bufid); 33 | 34 | #ifdef __cplusplus 35 | } // extern "C" 36 | #endif 37 | #endif 38 | -------------------------------------------------------------------------------- /components/Hub75Display/include/Hub75Display.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | void hub75DisplaySetup(); 9 | void hub75DisplayDraw(const uint8_t*); 10 | 11 | #ifdef __cplusplus 12 | } // extern "C" 13 | #endif 14 | -------------------------------------------------------------------------------- /components/Hub75Display/val2pwm.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Espressif Systems (Shanghai) PTE LTD 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | 16 | #include 17 | #include "val2pwm.h" 18 | 19 | //C/p'ed from https://ledshield.wordpress.com/2012/11/13/led-brightness-to-your-eye-gamma-correction-no/ 20 | const uint16_t lumConvTab[]={ 21 | 65535, 65508, 65479, 65451, 65422, 65394, 65365, 65337, 22 | 65308, 65280, 65251, 65223, 65195, 65166, 65138, 65109, 23 | 65081, 65052, 65024, 64995, 64967, 64938, 64909, 64878, 24 | 64847, 64815, 64781, 64747, 64711, 64675, 64637, 64599, 25 | 64559, 64518, 64476, 64433, 64389, 64344, 64297, 64249, 26 | 64200, 64150, 64099, 64046, 63992, 63937, 63880, 63822, 27 | 63763, 63702, 63640, 63577, 63512, 63446, 63379, 63310, 28 | 63239, 63167, 63094, 63019, 62943, 62865, 62785, 62704, 29 | 62621, 62537, 62451, 62364, 62275, 62184, 62092, 61998, 30 | 61902, 61804, 61705, 61604, 61501, 61397, 61290, 61182, 31 | 61072, 60961, 60847, 60732, 60614, 60495, 60374, 60251, 32 | 60126, 59999, 59870, 59739, 59606, 59471, 59334, 59195, 33 | 59053, 58910, 58765, 58618, 58468, 58316, 58163, 58007, 34 | 57848, 57688, 57525, 57361, 57194, 57024, 56853, 56679, 35 | 56503, 56324, 56143, 55960, 55774, 55586, 55396, 55203, 36 | 55008, 54810, 54610, 54408, 54203, 53995, 53785, 53572, 37 | 53357, 53140, 52919, 52696, 52471, 52243, 52012, 51778, 38 | 51542, 51304, 51062, 50818, 50571, 50321, 50069, 49813, 39 | 49555, 49295, 49031, 48764, 48495, 48223, 47948, 47670, 40 | 47389, 47105, 46818, 46529, 46236, 45940, 45641, 45340, 41 | 45035, 44727, 44416, 44102, 43785, 43465, 43142, 42815, 42 | 42486, 42153, 41817, 41478, 41135, 40790, 40441, 40089, 43 | 39733, 39375, 39013, 38647, 38279, 37907, 37531, 37153, 44 | 36770, 36385, 35996, 35603, 35207, 34808, 34405, 33999, 45 | 33589, 33175, 32758, 32338, 31913, 31486, 31054, 30619, 46 | 30181, 29738, 29292, 28843, 28389, 27932, 27471, 27007, 47 | 26539, 26066, 25590, 25111, 24627, 24140, 23649, 23153, 48 | 22654, 22152, 21645, 21134, 20619, 20101, 19578, 19051, 49 | 18521, 17986, 17447, 16905, 16358, 15807, 15252, 14693, 50 | 14129, 13562, 12990, 12415, 11835, 11251, 10662, 10070, 51 | 9473, 8872, 8266, 7657, 7043, 6424, 5802, 5175, 52 | 4543, 3908, 3267, 2623, 1974, 1320, 662, 0}; 53 | 54 | 55 | uint8_t valToPwm(int val) { 56 | if (val<0) val=0; 57 | if (val>255) val=255; 58 | return (65535-lumConvTab[val])>>8; 59 | } 60 | -------------------------------------------------------------------------------- /components/Hub75Display/val2pwm.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | //Converts an 0-255 intensity value to an equivalent 0-255 LED PWM value 5 | uint8_t valToPwm(int val); 6 | #ifdef __cplusplus 7 | } // extern "C" 8 | #endif 9 | -------------------------------------------------------------------------------- /components/libwebp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register( 2 | SRCS 3 | libwebp/src/dec/alpha_dec.c 4 | libwebp/src/dec/buffer_dec.c 5 | libwebp/src/dec/frame_dec.c 6 | libwebp/src/dec/idec_dec.c 7 | libwebp/src/dec/io_dec.c 8 | libwebp/src/dec/quant_dec.c 9 | libwebp/src/dec/tree_dec.c 10 | libwebp/src/dec/vp8_dec.c 11 | libwebp/src/dec/vp8l_dec.c 12 | libwebp/src/dec/webp_dec.c 13 | libwebp/src/demux/anim_decode.c 14 | libwebp/src/demux/demux.c 15 | libwebp/src/dsp/alpha_processing.c 16 | libwebp/src/dsp/alpha_processing_mips_dsp_r2.c 17 | libwebp/src/dsp/alpha_processing_neon.c 18 | libwebp/src/dsp/alpha_processing_sse2.c 19 | libwebp/src/dsp/alpha_processing_sse41.c 20 | libwebp/src/dsp/cost.c 21 | libwebp/src/dsp/cost_mips32.c 22 | libwebp/src/dsp/cost_mips_dsp_r2.c 23 | libwebp/src/dsp/cost_neon.c 24 | libwebp/src/dsp/cost_sse2.c 25 | libwebp/src/dsp/cpu.c 26 | libwebp/src/dsp/dec.c 27 | libwebp/src/dsp/dec_clip_tables.c 28 | libwebp/src/dsp/dec_mips32.c 29 | libwebp/src/dsp/dec_mips_dsp_r2.c 30 | libwebp/src/dsp/dec_msa.c 31 | libwebp/src/dsp/dec_neon.c 32 | libwebp/src/dsp/dec_sse2.c 33 | libwebp/src/dsp/dec_sse41.c 34 | libwebp/src/dsp/enc.c 35 | libwebp/src/dsp/enc_mips32.c 36 | libwebp/src/dsp/enc_mips_dsp_r2.c 37 | libwebp/src/dsp/enc_msa.c 38 | libwebp/src/dsp/enc_neon.c 39 | libwebp/src/dsp/enc_sse2.c 40 | libwebp/src/dsp/enc_sse41.c 41 | libwebp/src/dsp/filters.c 42 | libwebp/src/dsp/filters_mips_dsp_r2.c 43 | libwebp/src/dsp/filters_msa.c 44 | libwebp/src/dsp/filters_neon.c 45 | libwebp/src/dsp/filters_sse2.c 46 | libwebp/src/dsp/lossless.c 47 | libwebp/src/dsp/lossless_enc.c 48 | libwebp/src/dsp/lossless_enc_mips32.c 49 | libwebp/src/dsp/lossless_enc_mips_dsp_r2.c 50 | libwebp/src/dsp/lossless_enc_msa.c 51 | libwebp/src/dsp/lossless_enc_neon.c 52 | libwebp/src/dsp/lossless_enc_sse2.c 53 | libwebp/src/dsp/lossless_enc_sse41.c 54 | libwebp/src/dsp/lossless_mips_dsp_r2.c 55 | libwebp/src/dsp/lossless_msa.c 56 | libwebp/src/dsp/lossless_neon.c 57 | libwebp/src/dsp/lossless_sse2.c 58 | libwebp/src/dsp/lossless_sse41.c 59 | libwebp/src/dsp/rescaler.c 60 | libwebp/src/dsp/rescaler_mips32.c 61 | libwebp/src/dsp/rescaler_mips_dsp_r2.c 62 | libwebp/src/dsp/rescaler_msa.c 63 | libwebp/src/dsp/rescaler_neon.c 64 | libwebp/src/dsp/rescaler_sse2.c 65 | libwebp/src/dsp/ssim.c 66 | libwebp/src/dsp/ssim_sse2.c 67 | libwebp/src/dsp/upsampling.c 68 | libwebp/src/dsp/upsampling_mips_dsp_r2.c 69 | libwebp/src/dsp/upsampling_msa.c 70 | libwebp/src/dsp/upsampling_neon.c 71 | libwebp/src/dsp/upsampling_sse2.c 72 | libwebp/src/dsp/upsampling_sse41.c 73 | libwebp/src/dsp/yuv.c 74 | libwebp/src/dsp/yuv_mips32.c 75 | libwebp/src/dsp/yuv_mips_dsp_r2.c 76 | libwebp/src/dsp/yuv_neon.c 77 | libwebp/src/dsp/yuv_sse2.c 78 | libwebp/src/dsp/yuv_sse41.c 79 | libwebp/src/mux/anim_encode.c 80 | libwebp/src/mux/muxedit.c 81 | libwebp/src/mux/muxinternal.c 82 | libwebp/src/mux/muxread.c 83 | libwebp/src/utils/bit_reader_utils.c 84 | libwebp/src/utils/bit_writer_utils.c 85 | libwebp/src/utils/color_cache_utils.c 86 | libwebp/src/utils/filters_utils.c 87 | libwebp/src/utils/huffman_encode_utils.c 88 | libwebp/src/utils/huffman_utils.c 89 | libwebp/src/utils/quant_levels_dec_utils.c 90 | libwebp/src/utils/quant_levels_utils.c 91 | libwebp/src/utils/random_utils.c 92 | libwebp/src/utils/rescaler_utils.c 93 | libwebp/src/utils/thread_utils.c 94 | libwebp/src/utils/utils.c 95 | INCLUDE_DIRS 96 | libwebp/src 97 | PRIV_INCLUDE_DIRS 98 | libwebp/ 99 | ) 100 | 101 | -------------------------------------------------------------------------------- /hardware/v1/Backplate-P4.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joe714/pixelclient/d52c503c2ac620694c2bf387f14f95b04b4f7ef2/hardware/v1/Backplate-P4.stl -------------------------------------------------------------------------------- /hardware/v1/Frame-P4.stl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joe714/pixelclient/d52c503c2ac620694c2bf387f14f95b04b4f7ef2/hardware/v1/Frame-P4.stl -------------------------------------------------------------------------------- /hardware/v1/README.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | V1 Hub75 driver board. 3 | 4 | Order from OSH Park: https://oshpark.com/shared_projects/DTnHhcQ1 5 | 6 | **The USB port on this board is for power only** for cost reasons. You will need a USB to TTL serial 7 | adapter connected to J2 to do the initial firmware load. 8 | 9 | J3 is the data connector for the HUB 75 panel. There isn't enough clearance to use a keyed shrouded header, 10 | so make sure you get the ribbon cable orientation correct (key should face towards the center of the board). 11 | 12 | Frame-P4 and Backplate-P4.stl match up with P4 HUB75 displays like 13 | this one: https://www.aliexpress.us/item/2251832328529483.html?spm=a2g0o.order_list.order_list_main.11.b1cd1802htAgJk&gatewayAdapt=glo2usa. 14 | Use 3 M3x3 (OD 4.2) heat set inserts and M3x5 screws to fasten the PCB to the backplate, 15 | and 6 M3x40 bolts to fasten the backplate to the panel, sandwiching the frame. 16 | 17 | Note this is a larger display than the original Tidbyt hardware. If you want to 18 | use a different pitch display, you'll need to work out your own mounting. 19 | 20 | # BOM 21 | |Item |Qty |Reference(s) |Value |LibPart|Footprint|Comments | 22 | |-----|-----|--------------|--------|-------|---------|-------------| 23 | |1|1|C1|1uF|Device:C|Capacitor\_SMD:C\_0805\_2012Metric\_Pad1.18x1.45mm\_HandSolder|| 24 | |2|2|C2, C3|10uF|Device:C|Capacitor\_SMD:C\_0805\_2012Metric\_Pad1.18x1.45mm\_HandSolder|| 25 | |3|1|C4|4.7uF|Device:C|Capacitor\_SMD:C\_0805\_2012Metric\_Pad1.18x1.45mm\_HandSolder|| 26 | |4|1|C5|.1uF|Device:C|Capacitor\_SMD:C\_0805\_2012Metric\_Pad1.18x1.45mm\_HandSolder|| 27 | |5|1|D1|LED|Device:LED|LED\_SMD:LED\_0603\_1608Metric|DNP| 28 | |7|1|J1|USB\_C\_Receptacle\_USB2.0|Connector:USB\_C\_Receptacle\_USB2.0|Connector\_TH\_Local:USB\_C\_2.0\_Vertical|https://www.aliexpress.us/item/3256803989627803.html?spm=a2g0o.order_list.order_list_main.10.35971802Oiyejk&gatewayAdapt=glo2usa| 29 | |8|1|J2|ISP|Connector\_Generic:Conn\_02x03\_Odd\_Even|Connector\_PinHeader\_2.54mm:PinHeader\_2x03\_P2.54mm\_Vertical|ISP header| 30 | |9|1|J3|HUB75|Connector\_Generic:Conn\_02x08\_Odd\_Even|Connector\_PinSocket\_2.54mm:PinSocket\_2x08\_P2.54mm\_Vertical|Hub75 data connector| 31 | |10|1|J4|Screw\_Terminal\_01x02|Connector:Screw\_Terminal\_01x02|TerminalBlock\_TE-Connectivity:TerminalBlock\_TE\_282834-2\_1x02\_P2.54mm\_Horizontal|Hub75 power connector| 32 | |11|1|J5|Conn\_01x03\_Male|Connector:Conn\_01x03\_Male|Connector\_JST:JST\_PH\_B3B-PH-K\_1x03\_P2.00mm\_Vertical|DNP, for future use| 33 | |12|1|R1|10K|Device:R|Resistor\_SMD:R\_0603\_1608Metric|| 34 | |13|2|R2, R3|5.1K|Device:R|Resistor\_SMD:R\_0603\_1608Metric|| 35 | |14|1|R4|750|Device:R|Resistor\_SMD:R\_0603\_1608Metric|DNP| 36 | |15|2|R6, R7|DNP|Device:R|Resistor\_SMD:R\_0603\_1608Metric|| 37 | |16|1|SW1|PRG|Switch:SW\_Push|Button\_Switch\_SMD\_Local:ESWITCH\_TL3302G|DNP| 38 | |17|1|SW2|RST|Switch:SW\_Push|Button\_Switch\_SMD\_Local:ESWITCH\_TL3302G|DNP| 39 | |18|1|U1|ESP32-WROOM-32D|RF\_Module:ESP32-WROOM-32D|RF\_Module:ESP32-WROOM-32|https://www.espressif.com/sites/default/files/documentation/esp32-wroom-32d_esp32-wroom-32u_datasheet_en.pdf, use D or later revision and 8MB flash| 40 | |19|1|U2|TLV1117-33|Regulator\_Linear:TLV1117-33|Package\_TO\_SOT\_SMD:SOT-223-3\_TabPin2|http://www.ti.com/lit/ds/symlink/tlv1117.pdf| 41 | 42 | -------------------------------------------------------------------------------- /hardware/v1/V1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joe714/pixelclient/d52c503c2ac620694c2bf387f14f95b04b4f7ef2/hardware/v1/V1.jpg -------------------------------------------------------------------------------- /main/Animation.cc: -------------------------------------------------------------------------------- 1 | #include "Animation.h" 2 | 3 | #include "freertos/FreeRTOS.h" 4 | #include "freertos/task.h" 5 | #include "freertos/semphr.h" 6 | #include "freertos/queue.h" 7 | //#include "esp_log.h" 8 | 9 | #include "Hub75Display.h" 10 | 11 | //const char TAG[] = "Anim"; 12 | 13 | struct QueueEntry { 14 | Image* image; 15 | TaskHandle_t callingTask; 16 | }; 17 | 18 | static QueueHandle_t imageQueue; 19 | 20 | static void 21 | animationTask(void*) 22 | { 23 | hub75DisplaySetup(); 24 | 25 | std::unique_ptr image; 26 | auto delay = portMAX_DELAY; 27 | while (true) { 28 | QueueEntry next{}; 29 | bool qr = xQueueReceive(imageQueue, &next, delay); 30 | if (qr) { 31 | image.reset(next.image); 32 | // Tell the calling task we've released the old buffer 33 | xTaskNotifyGive(next.callingTask); 34 | } 35 | if (image) { 36 | uint32_t nextFrame = image->render(&hub75DisplayDraw); 37 | if (nextFrame == Image::ANIMATION_END) { 38 | delay = portMAX_DELAY; 39 | image.reset(); 40 | } else { 41 | delay = nextFrame / portTICK_PERIOD_MS; 42 | } 43 | } 44 | } 45 | } 46 | 47 | void animationSetup() 48 | { 49 | imageQueue = xQueueCreate(1, sizeof(QueueEntry)); 50 | xTaskCreate(animationTask, "animationTask", 4096, nullptr, 10, nullptr); 51 | } 52 | 53 | void animationStart(std::unique_ptr&& image) 54 | { 55 | // Setup so the animation thread can send a direct to task notification 56 | // back to us once it's released any buffers from the previously running 57 | // animation. This way we can try to maximize the amount of free RAM for 58 | // the incoming animation before allocating it. 59 | QueueEntry e{ image.get(), xTaskGetCurrentTaskHandle() }; 60 | xTaskNotifyStateClear(e.callingTask); 61 | if (xQueueSendToBack(imageQueue, &e, 0)) { 62 | // Successfully enqueued the work item so the animation thread will 63 | // take ownership of the passed Image, so release our ownership of it 64 | // and block until we get the signal from the Animation thread 65 | // any previous buffers are freed. 66 | image.release(); 67 | ulTaskNotifyTake(pdTRUE, portMAX_DELAY); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /main/Animation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | void animationSetup(); 9 | void animationStart(std::unique_ptr&& image); 10 | 11 | -------------------------------------------------------------------------------- /main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "main.cc" 2 | "Animation.cc" 3 | "NetManager.cc" 4 | "Config.cc" 5 | "NvsFlash.cc" 6 | "RootPage.cc" 7 | "WebPImage.cc" 8 | EMBED_FILES nyan_64x32.webp 9 | INCLUDE_DIRS ".") 10 | 11 | target_compile_options(${COMPONENT_LIB} PRIVATE "-std=gnu++17") 12 | -------------------------------------------------------------------------------- /main/Config.cc: -------------------------------------------------------------------------------- 1 | #include "Config.h" 2 | 3 | #include "esp_log.h" 4 | #include "esp_random.h" 5 | 6 | #include "NvsFlash.h" 7 | 8 | static const char* TAG = "CONFIG"; 9 | 10 | namespace { 11 | std::string generateClientId() 12 | { 13 | // Make a v4 UUID per RFC 4122 section 4.4 14 | static int KEYLEN = 16; 15 | static const char ENC[] = "0123456789abcdef"; 16 | uint8_t key[KEYLEN]; 17 | esp_fill_random(key, KEYLEN); 18 | key[8] = (key[8] & 0x3f) | 0x80; 19 | key[6] = (key[6] & 0x0f) | 0x40; 20 | 21 | std::string out; 22 | for (int i = 0; i < KEYLEN; ++i) { 23 | out.push_back(ENC[(key[i] & 0xf0) >> 4]); 24 | out.push_back(ENC[key[i] & 0x0f]); 25 | if (i == 3 || i == 5 || i == 7 || i == 9) { 26 | out.push_back('-'); 27 | } 28 | } 29 | ESP_LOGD(TAG, "Generated device UUID %s", out.c_str()); 30 | return out; 31 | } 32 | } // namespace 33 | 34 | Config& Config::instance() { 35 | static Config cfg; 36 | return cfg; 37 | } 38 | 39 | Config::Config() 40 | { 41 | NvsFlash flash("PixelMatrix", NVS_READWRITE); 42 | 43 | esp_err_t rv = flash.getString("endpoint", endpoint_); 44 | if (ESP_ERR_NVS_NOT_FOUND == rv) { 45 | endpoint_ = "192.168.4.59"; 46 | } 47 | 48 | rv = flash.getU16("port", port_); 49 | if (ESP_ERR_NVS_NOT_FOUND == rv) { 50 | port_ = 8080; 51 | } 52 | 53 | rv = flash.getString("deviceUUID", deviceUUID_); 54 | if (ESP_ERR_NVS_NOT_FOUND == rv) { 55 | // Legacy NVS 56 | rv = flash.getString("clientId", deviceUUID_); 57 | if (ESP_OK == rv) { 58 | (void)flash.setString("deviceUUID", deviceUUID_); 59 | (void)flash.eraseKey("clientId"); 60 | } 61 | } 62 | 63 | if (ESP_ERR_NVS_NOT_FOUND == rv || deviceUUID_.size() != 36) { 64 | deviceUUID_ = generateClientId(); 65 | rv = flash.setString("deviceUUID", deviceUUID_); 66 | ESP_ERROR_CHECK(rv); 67 | rv = flash.commit(); 68 | ESP_ERROR_CHECK(rv); 69 | } 70 | ESP_LOGI(TAG, "Device UUID: %s", deviceUUID_.c_str()); 71 | } 72 | 73 | std::string 74 | Config::imageUri() const { 75 | std::string uri = "ws://"; 76 | uri.append(endpoint_) 77 | .append(":") 78 | .append(std::to_string(port_)) 79 | .append("/ws?device=") 80 | .append(deviceUUID_); 81 | return uri; 82 | } 83 | -------------------------------------------------------------------------------- /main/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Config 5 | { 6 | public: 7 | static Config& instance(); 8 | 9 | std::string imageUri() const; 10 | const std::string& deviceUUID() const { return deviceUUID_; } 11 | const std::string& endpoint() const { return endpoint_; } 12 | 13 | private: 14 | Config(); 15 | 16 | std::string endpoint_; 17 | uint16_t port_; 18 | std::string deviceUUID_; 19 | }; 20 | -------------------------------------------------------------------------------- /main/Display.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | 5 | -------------------------------------------------------------------------------- /main/Image.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | // TODO: This needs to be project-wide and pushed into the Hub75 Driver. 6 | static const uint32_t IMAGE_WIDTH = 64; 7 | static const uint32_t IMAGE_HEIGHT = 32; 8 | 9 | // Abstract base class representing an image (of fixed 10 | // IMAGE_WIDTH * IMAGE_HEIGHT) that can be rendered. 11 | class Image { 12 | public: 13 | virtual ~Image() = default; 14 | 15 | virtual bool valid() const = 0; 16 | 17 | typedef std::function DrawFunction; 18 | static const uint32_t ANIMATION_END = 0xFFFFFFFF; 19 | 20 | // If a frame is available, render the image by passing a bitmap 21 | // in R8G8B8A8 format to the supplied draw function. Returns the 22 | // delay (in ms) until the next call to render(), or ANIMATION_END 23 | // if this image is complete and should be disposed of. 24 | virtual uint32_t render(DrawFunction fn) = 0; 25 | }; 26 | 27 | // Abstract base class representing a bitstream of encoded image data. 28 | class ImageSource { 29 | public: 30 | virtual ~ImageSource() = default; 31 | 32 | virtual const uint8_t* data() const = 0; 33 | virtual size_t size() const = 0; 34 | }; 35 | 36 | // Image bitstream data read directly from flash that does not require 37 | // lifecycle management. 38 | class StaticImageSource : public ImageSource { 39 | public: 40 | constexpr StaticImageSource(const uint8_t* start, const uint8_t* end): data_(start), size_(end - start) {} 41 | virtual ~StaticImageSource() = default; 42 | 43 | virtual const uint8_t* data() const override { return data_; } 44 | virtual size_t size() const override { return size_; } 45 | private: 46 | const uint8_t* data_; 47 | size_t size_; 48 | }; 49 | 50 | // Image bitstream data on the heap that must be freed when no longer 51 | // referenced by an image. 52 | class HeapImageSource : public ImageSource { 53 | public: 54 | HeapImageSource(size_t resv): overrun_(false) { vec_.reserve(resv); } 55 | virtual ~HeapImageSource() = default; 56 | 57 | virtual const uint8_t* data() const override { return vec_.data(); } 58 | virtual size_t size() const override { return vec_.size(); } 59 | size_t capacity() const { return vec_.capacity(); } 60 | 61 | bool append(const uint8_t* buf, size_t len) 62 | { 63 | if (len && !overrun_) { 64 | if (vec_.size() + len < vec_.capacity()) { 65 | vec_.insert(vec_.end(), buf, buf + len); 66 | } else { 67 | overrun_ = true; 68 | } 69 | } 70 | return !overrun_; 71 | } 72 | 73 | std::vector& vec() { return vec_; } 74 | 75 | private: 76 | bool overrun_; 77 | std::vector vec_; 78 | }; 79 | 80 | -------------------------------------------------------------------------------- /main/NetManager.cc: -------------------------------------------------------------------------------- 1 | #include "NetManager.h" 2 | 3 | #include 4 | 5 | #include "freertos/FreeRTOS.h" 6 | #include "freertos/event_groups.h" 7 | 8 | #include "esp_event.h" 9 | #include "esp_log.h" 10 | #include "esp_mac.h" 11 | #include "esp_system.h" 12 | #include "esp_wifi.h" 13 | 14 | #include "lwip/err.h" 15 | #include "lwip/sys.h" 16 | 17 | #include "nvs_flash.h" 18 | 19 | namespace { 20 | const char* TAG = "NetManager"; 21 | 22 | #define WIFI_CONNECTED_BIT BIT0 23 | #define WIFI_FAIL_BIT BIT1 24 | 25 | static void 26 | startEventHandler(void* arg, 27 | esp_event_base_t eventBase, 28 | int32_t eventId, 29 | void* eventData) 30 | { 31 | if (eventBase == WIFI_EVENT) { 32 | switch (eventId) { 33 | case WIFI_EVENT_STA_DISCONNECTED: 34 | ESP_LOGI(TAG, "Attempt reconnect"); 35 | /* Fallthrough */ 36 | case WIFI_EVENT_STA_START: 37 | esp_wifi_connect(); 38 | break; 39 | default: 40 | break; 41 | } 42 | } else if (eventBase == IP_EVENT && eventId == IP_EVENT_STA_GOT_IP) { 43 | EventGroupHandle_t* egroup = static_cast(arg); 44 | xEventGroupSetBits(*egroup, WIFI_CONNECTED_BIT); 45 | } 46 | } 47 | 48 | } // namespace 49 | 50 | NetManager::NetManager() 51 | { 52 | esp_err_t rv = nvs_flash_init(); 53 | if (rv == ESP_ERR_NVS_NO_FREE_PAGES || rv == ESP_ERR_NVS_NEW_VERSION_FOUND) { 54 | ESP_ERROR_CHECK(nvs_flash_erase()); 55 | rv = nvs_flash_init(); 56 | } 57 | ESP_ERROR_CHECK(rv); 58 | 59 | esp_read_mac(stationMac_, ESP_MAC_WIFI_STA); 60 | } 61 | 62 | void 63 | NetManager::start() 64 | { 65 | nvs_handle_t nvsHandle; 66 | esp_err_t rv = nvs_open(TAG, NVS_READONLY, &nvsHandle); 67 | ESP_ERROR_CHECK(rv); 68 | 69 | wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); 70 | 71 | wifi_config_t cfgSta = {}; 72 | cfgSta.sta.threshold.authmode = WIFI_AUTH_WPA_PSK; 73 | cfgSta.sta.pmf_cfg.capable = true; 74 | cfgSta.sta.pmf_cfg.required = false; 75 | 76 | size_t len = sizeof cfgSta.sta.ssid; 77 | rv = nvs_get_str(nvsHandle, "ssid", (char*)cfgSta.sta.ssid, &len); 78 | ESP_ERROR_CHECK(rv); 79 | 80 | len = sizeof cfgSta.sta.password; 81 | rv = nvs_get_str(nvsHandle, "password", (char*)cfgSta.sta.password, &len); 82 | ESP_ERROR_CHECK(rv); 83 | 84 | nvs_close(nvsHandle); 85 | 86 | EventGroupHandle_t eventGroup = xEventGroupCreate(); 87 | 88 | ESP_ERROR_CHECK(esp_netif_init()); 89 | esp_netif_create_default_wifi_sta(); 90 | ESP_ERROR_CHECK(esp_wifi_init(&cfg)); 91 | 92 | esp_event_handler_instance_t wifiEvent; 93 | rv = esp_event_handler_instance_register(WIFI_EVENT, 94 | ESP_EVENT_ANY_ID, 95 | &startEventHandler, 96 | &eventGroup, 97 | &wifiEvent); 98 | ESP_ERROR_CHECK(rv); 99 | 100 | esp_event_handler_instance_t ipEvent; 101 | rv = esp_event_handler_instance_register(IP_EVENT, 102 | IP_EVENT_STA_GOT_IP, 103 | &startEventHandler, 104 | &eventGroup, 105 | &ipEvent); 106 | ESP_ERROR_CHECK(rv); 107 | 108 | ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); 109 | ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &cfgSta)); 110 | ESP_ERROR_CHECK(esp_wifi_start()); 111 | ESP_LOGI(TAG, "esp_wifi_start()"); 112 | 113 | EventBits_t bits = xEventGroupWaitBits(eventGroup, 114 | WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, 115 | pdFALSE, 116 | pdFALSE, 117 | portMAX_DELAY); 118 | 119 | ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, ipEvent)); 120 | ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, wifiEvent)); 121 | vEventGroupDelete(eventGroup); 122 | } 123 | -------------------------------------------------------------------------------- /main/NetManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class NetManager { 5 | public: 6 | NetManager(); 7 | 8 | void start(); 9 | 10 | const uint8_t* stationMac() const { return stationMac_; } 11 | private: 12 | uint8_t stationMac_[6]; 13 | }; 14 | -------------------------------------------------------------------------------- /main/NvsFlash.cc: -------------------------------------------------------------------------------- 1 | #include "NvsFlash.h" 2 | 3 | void 4 | NvsFlash::init() 5 | { 6 | esp_err_t rv = nvs_flash_init(); 7 | if (rv == ESP_ERR_NVS_NO_FREE_PAGES || 8 | rv == ESP_ERR_NVS_NEW_VERSION_FOUND) { 9 | ESP_ERROR_CHECK(nvs_flash_erase()); 10 | rv = nvs_flash_init(); 11 | } 12 | ESP_ERROR_CHECK(rv); 13 | } 14 | 15 | NvsFlash::NvsFlash(const std::string& ns, nvs_open_mode_t openMode) 16 | { 17 | esp_err_t rv = nvs_open(ns.c_str(), openMode, &handle_); 18 | ESP_ERROR_CHECK(rv); 19 | } 20 | 21 | NvsFlash::~NvsFlash() { nvs_close(handle_); } 22 | 23 | esp_err_t 24 | NvsFlash::setString(const std::string& key, const std::string& value) 25 | { 26 | esp_err_t rv = nvs_set_str(handle_, key.c_str(), value.c_str()); 27 | if (rv == ESP_OK) { 28 | dirty_ = true; 29 | } 30 | 31 | return rv; 32 | } 33 | 34 | esp_err_t 35 | NvsFlash::getString(const std::string& key, std::string& value) 36 | { 37 | size_t len = 0; 38 | esp_err_t rv = nvs_get_str(handle_, key.c_str(), nullptr, &len); 39 | if (ESP_OK != rv && ESP_ERR_NVS_INVALID_LENGTH != rv) { 40 | return rv; 41 | } 42 | value.resize(len - 1); 43 | rv = nvs_get_str(handle_, key.c_str(), value.data(), &len); 44 | return rv; 45 | } 46 | 47 | esp_err_t 48 | NvsFlash::getU16(const std::string& key, uint16_t& value) 49 | { 50 | esp_err_t rv = nvs_get_u16(handle_, key.c_str(), &value); 51 | return rv; 52 | } 53 | 54 | esp_err_t 55 | NvsFlash::setU16(const std::string& key, uint16_t value) 56 | { 57 | esp_err_t rv = nvs_set_u16(handle_, key.c_str(), value); 58 | if (ESP_OK == rv) { 59 | dirty_ = true; 60 | } 61 | return rv; 62 | } 63 | 64 | esp_err_t 65 | NvsFlash::eraseKey(const std::string& key) 66 | { 67 | esp_err_t rv = nvs_erase_key(handle_, key.c_str()); 68 | if (ESP_OK == rv) { 69 | dirty_ = true; 70 | } 71 | return rv; 72 | } 73 | 74 | esp_err_t 75 | NvsFlash::commit() 76 | { 77 | if (!dirty_) { 78 | return ESP_OK; 79 | } 80 | 81 | esp_err_t rv = nvs_commit(handle_); 82 | if (ESP_OK == rv) { 83 | dirty_ = false; 84 | } 85 | return rv; 86 | } 87 | -------------------------------------------------------------------------------- /main/NvsFlash.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "nvs_flash.h" 5 | 6 | class NvsFlash { 7 | public: 8 | NvsFlash(const std::string& ns, nvs_open_mode_t openMode = NVS_READONLY); 9 | ~NvsFlash(); 10 | 11 | esp_err_t getString(const std::string& key, std::string& value); 12 | esp_err_t setString(const std::string& key, const std::string& value); 13 | esp_err_t getU16(const std::string& key, uint16_t& value); 14 | esp_err_t setU16(const std::string& key, const uint16_t value); 15 | 16 | esp_err_t eraseKey(const std::string& key); 17 | 18 | bool dirty() const { return dirty_; } 19 | esp_err_t commit(); 20 | 21 | static void init(); 22 | 23 | private: 24 | nvs_handle_t handle_; 25 | bool dirty_{false}; 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /main/RootPage.cc: -------------------------------------------------------------------------------- 1 | #include "RootPage.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "Config.h" 11 | 12 | using namespace httpd; 13 | 14 | static const char* TAG = "RootPage"; 15 | 16 | using namespace std::chrono_literals; 17 | 18 | namespace { 19 | 20 | TickType_t ticks(std::chrono::milliseconds ms) 21 | { 22 | return ms.count() / portTICK_PERIOD_MS; 23 | } 24 | 25 | TimerHandle_t restart; 26 | 27 | void delayedRestart(TimerHandle_t timer) 28 | { 29 | ESP_LOGI(TAG, "Restart"); 30 | esp_restart(); 31 | } 32 | 33 | } // namespace 34 | 35 | esp_err_t 36 | RootPage::onGet(Request& req) 37 | { 38 | ESP_LOGI(TAG, "get"); 39 | char buf[66] = {}; 40 | std::string resp = R"( 41 | 42 | 43 | 44 | 45 | 46 | OTA Update 47 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | )"; 60 | 61 | resp.append("\n") 64 | .append("\n"); 67 | 68 | uint8_t mac[6] ={}; 69 | esp_read_mac(mac, ESP_MAC_WIFI_STA); 70 | snprintf(buf, sizeof buf, "%.2X:%.2X:%.2X:%.2X:%.2X:%.2X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 71 | resp.append("\n"); 74 | 75 | snprintf(buf, 76 | sizeof buf, 77 | "%lu KB", 78 | esp_get_free_heap_size() / 1024); 79 | resp.append("\n"); 82 | 83 | snprintf(buf, 84 | sizeof buf, 85 | "%lu KB", 86 | esp_get_minimum_free_heap_size() / 1024); 87 | resp.append("\n"); 90 | 91 | resp.append(R"( 92 | 93 |
Device Information
Device UUID") 62 | .append(Config::instance().deviceUUID()) 63 | .append("
Endpoint") 65 | .append(Config::instance().endpoint()) 66 | .append("
MAC Address") 72 | .append(buf) 73 | .append("
Free Heap") 80 | .append(buf) 81 | .append("
Min Free Heap") 88 | .append(buf) 89 | .append("
94 |
95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | )"); 103 | 104 | const esp_app_desc_t* app = esp_app_get_description(); 105 | const esp_partition_t* part = esp_ota_get_running_partition(); 106 | 107 | resp.append("\n"); 110 | 111 | resp.append("\n"); 114 | 115 | resp.append("\n"); 120 | 121 | for (int i = 0; i < 32; ++i) { 122 | snprintf(&buf[i*2], 3, "%.2x", app->app_elf_sha256[i]); 123 | } 124 | resp.append("\n"); 127 | 128 | snprintf(buf, sizeof buf, "%s (0x%" PRIX32 ")", part->label, part->address); 129 | resp.append("\n"); 132 | 133 | 134 | resp.append(R"( 135 | 136 |
App Detail
App Version") 108 | .append(app->version) 109 | .append("
IDF Version") 112 | .append(app->idf_ver) 113 | .append("
Compiled") 116 | .append(app->date) 117 | .append(" ") 118 | .append(app->time) 119 | .append("
App SHA256") 125 | .append(buf) 126 | .append("
Running Partition") 130 | .append(buf) 131 | .append("
137 |
138 |
139 |
148 | 149 |
150 | 151 | 152 | )"); 153 | req.sendResponse(resp); 154 | return ESP_OK; 155 | }; 156 | 157 | esp_err_t 158 | RootPage::onPost(Request& req) 159 | { 160 | ESP_LOGI(TAG, "OTA POST"); 161 | using namespace std::string_literals; 162 | const std::string ctype = req.requestHeader("Content-Type"); 163 | 164 | if (ctype != "application/x-www-form-urlencoded"s) { 165 | ESP_LOGI(TAG, "Unsupported Content-Type: '%s'", ctype.c_str()); 166 | httpd_resp_set_status(req.request(), "406 Unsupported Content-Type"); 167 | httpd_resp_set_type(req.request(), "text/plain"); 168 | req.sendResponse("Unsupported Content Type"); 169 | return ESP_OK; 170 | } 171 | 172 | ESP_LOGI(TAG, "POST %d bytes", req.contentLength()); 173 | char buf[128] = {}; 174 | if (req.contentLength() > sizeof buf) { 175 | httpd_resp_set_status(req.request(), "406 Invalid Form Data"); 176 | httpd_resp_set_type(req.request(), "text/plain"); 177 | req.sendResponse("Invalid Form Data"); 178 | return ESP_OK; 179 | } 180 | 181 | int l = httpd_req_recv(req.request(), buf, sizeof buf); 182 | if (l <= 0) { 183 | req.sendResponse("Invalid Form Data"); 184 | return ESP_OK; 185 | } 186 | 187 | std::string_view formData(buf); 188 | size_t pos = formData.find("firmware="); 189 | if (std::string_view::npos == pos) { 190 | ESP_LOGI(TAG, "No firmware value found"); 191 | req.sendResponse("Invalid form data"); 192 | return ESP_OK; 193 | } 194 | formData.remove_prefix(9); 195 | pos = formData.find("&"); 196 | if (pos != std::string_view::npos) { 197 | formData.remove_suffix(formData.size() - pos); 198 | } 199 | std::string uri = urldecode(formData); 200 | ESP_LOGI(TAG, "Firmware URL: %s", uri.c_str()); 201 | esp_http_client_config_t httpcnf = { }; 202 | httpcnf.url = uri.c_str(); 203 | esp_https_ota_config_t config = {}; 204 | config.http_config = &httpcnf; 205 | esp_err_t rv = esp_https_ota(&config); 206 | std::string msg; 207 | if (rv == ESP_OK) { 208 | msg = "Firmware update in process"; 209 | } else if (rv == ESP_ERR_OTA_VALIDATE_FAILED) { 210 | msg = "Image Validation Failed"; 211 | } else { 212 | msg = esp_err_to_name(rv); 213 | } 214 | ESP_LOGI(TAG, "Update result: %s", msg.c_str()); 215 | 216 | std::string resp = R"( 217 | 218 | 219 | 220 | OTA Update 221 | 222 | 223 | )"; 224 | resp.append(msg); 225 | 226 | resp.append(R"( 227 | 228 | 229 | )"); 230 | 231 | req.sendResponse(resp); 232 | if (rv == ESP_OK) { 233 | auto t = ticks(1s); 234 | ESP_LOGI(TAG, "Pending restart in %" PRIu32 " ticks", t); 235 | restart = xTimerCreate("OTA Restart", t, pdFALSE, nullptr, delayedRestart); 236 | if (!restart) { 237 | ESP_LOGI(TAG, "Failed to initialized restart timer!"); 238 | } else { 239 | xTimerStart(restart, 0); 240 | } 241 | } 242 | 243 | return ESP_OK; 244 | } 245 | 246 | -------------------------------------------------------------------------------- /main/RootPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "HttpServer.h" 4 | 5 | class RootPage : public httpd::MethodHandler 6 | { 7 | public: 8 | virtual esp_err_t onGet(httpd::Request& req) override; 9 | virtual esp_err_t onPost(httpd::Request& req) override; 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /main/WebPImage.cc: -------------------------------------------------------------------------------- 1 | #include "WebPImage.h" 2 | #include 3 | #include "esp_log.h" 4 | #include "esp_rom_md5.h" 5 | #include "esp_system.h" 6 | 7 | const char TAG[] = "WebPImage"; 8 | 9 | WebPImage::WebPImage(std::unique_ptr&& buf) 10 | : dec_(nullptr), loop_(0), frame_(0), lastFrameTime_(0) 11 | { 12 | WebPData data { 13 | .bytes = buf->data(), 14 | .size = buf->size() 15 | }; 16 | 17 | dec_ = WebPAnimDecoderNew(&data, nullptr); 18 | if (!dec_) { 19 | ESP_LOGE(TAG, "Failed to create decoder"); 20 | return; 21 | } 22 | 23 | WebPAnimInfo info; 24 | int rv = WebPAnimDecoderGetInfo(dec_, &info); 25 | ESP_LOGI(TAG, 26 | "WebPAnimDecoderGetInfo: %d, Frames: %" PRIu32 " Loop: %" PRIu32 27 | " Width: %" PRIu32 " Height: %" PRIu32, 28 | rv, info.frame_count, info.loop_count, info.canvas_width, 29 | info.canvas_height); 30 | 31 | if (IMAGE_WIDTH != info.canvas_width || IMAGE_HEIGHT != info.canvas_height) { 32 | WebPAnimDecoderDelete(dec_); 33 | dec_ = nullptr; 34 | } 35 | 36 | loop_ = info.loop_count; 37 | data_ = std::move(buf); 38 | } 39 | 40 | WebPImage::~WebPImage() 41 | { 42 | if (dec_) { 43 | WebPAnimDecoderDelete(dec_); 44 | } 45 | } 46 | 47 | uint32_t 48 | WebPImage::render(Image::DrawFunction draw) 49 | { 50 | if (!valid()) { 51 | return ANIMATION_END; 52 | } 53 | 54 | for ( ; ; ) { 55 | if (WebPAnimDecoderHasMoreFrames(dec_)) { 56 | uint8_t* pix; 57 | int timestamp; 58 | 59 | if (!WebPAnimDecoderGetNext(dec_, &pix, ×tamp)) { 60 | MD5Context md5; 61 | unsigned char digest[16]; 62 | char hash[33]; 63 | esp_rom_md5_init(&md5); 64 | esp_rom_md5_update(&md5, (uint8_t*)data_->data(), data_->size()); 65 | esp_rom_md5_final(digest, &md5); 66 | for (int i = 0; i < 16; ++i) { 67 | sprintf(hash + (i*2), "%.2x", digest[i]); 68 | } 69 | ESP_LOGE(TAG, 70 | "WebPAnimDecoderGetNext error on frame %d (len: %u, " 71 | "md5: %s)", 72 | frame_, data_->size(), hash); 73 | ESP_LOGE(TAG, "Free Heap: %lu, Min Free Heap: %lu", 74 | esp_get_free_heap_size(), 75 | esp_get_minimum_free_heap_size()); 76 | return ANIMATION_END; 77 | } 78 | draw(pix); 79 | int rv = timestamp - lastFrameTime_; 80 | lastFrameTime_ = timestamp; 81 | ++frame_; 82 | return rv; 83 | } 84 | 85 | if (1 == loop_) { 86 | // Done animating 87 | return ANIMATION_END; 88 | } 89 | 90 | if (loop_) { 91 | --loop_; 92 | } 93 | WebPAnimDecoderReset(dec_); 94 | frame_ = 0; 95 | lastFrameTime_ = 0; 96 | } 97 | return ANIMATION_END; 98 | } 99 | 100 | -------------------------------------------------------------------------------- /main/WebPImage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #include "Animation.h" 6 | #include "Image.h" 7 | 8 | #include 9 | 10 | class WebPImage : public Image 11 | { 12 | public: 13 | WebPImage(std::unique_ptr&& buf); 14 | virtual ~WebPImage(); 15 | 16 | virtual bool valid() const override { return dec_; } 17 | virtual uint32_t render(Image::DrawFunction fn) override; 18 | 19 | private: 20 | std::unique_ptr data_; 21 | WebPAnimDecoder* dec_; 22 | 23 | uint32_t loop_; 24 | int frame_; 25 | int lastFrameTime_; 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /main/idf_component.yml: -------------------------------------------------------------------------------- 1 | ## IDF Component Manager Manifest File 2 | dependencies: 3 | espressif/esp_websocket_client: "*" 4 | ## Required IDF version 5 | idf: 6 | version: ">=4.1.0" 7 | # # Put list of dependencies here 8 | # # For components maintained by Espressif: 9 | # component: "~1.0.0" 10 | # # For 3rd party components: 11 | # username/component: ">=1.0.0,<2.0.0" 12 | # username2/component2: 13 | # version: "~1.0.0" 14 | # # For transient dependencies `public` flag can be set. 15 | # # `public` flag doesn't have an effect dependencies of the `main` component. 16 | # # All dependencies of `main` are public by default. 17 | # public: true 18 | -------------------------------------------------------------------------------- /main/main.cc: -------------------------------------------------------------------------------- 1 | #define INCLUDE_vTaskDelay 1 2 | 3 | #include 4 | #include 5 | 6 | #include "driver/gpio.h" 7 | #include "rom/gpio.h" 8 | #include "nvs_flash.h" 9 | #include "esp_err.h" 10 | #include "esp_log.h" 11 | #include "esp_event.h" 12 | #include "esp_http_client.h" 13 | #include "esp_websocket_client.h" 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | #include "Config.h" 20 | #include "RootPage.h" 21 | #include "Display.h" 22 | #include "WebPImage.h" 23 | #include "NvsFlash.h" 24 | 25 | static const char* TAG = "PIXEL"; 26 | static const size_t CAPACITY = 68*1024; 27 | static uint8_t imgbuf[CAPACITY]; 28 | 29 | extern const uint8_t nyan_webp_start[] asm("_binary_nyan_64x32_webp_start"); 30 | extern const uint8_t nyan_webp_end[] asm("_binary_nyan_64x32_webp_end"); 31 | 32 | StaticImageSource NyanWebPSrc(nyan_webp_start, nyan_webp_end); 33 | 34 | const gpio_num_t LED_BUILTIN = GPIO_NUM_12; 35 | 36 | std::unique_ptr netMgr; 37 | std::unique_ptr httpServer; 38 | 39 | // Simple fixed allocation buffer with a used size we can append chunks to as 40 | // they come in from the network. 41 | class ImageBuffer { 42 | public: 43 | ImageBuffer() : buf_(imgbuf) {}; 44 | bool append(const uint8_t* buf, size_t len) 45 | { 46 | if (len && !overrun_) { 47 | if (size_ + len < CAPACITY) { 48 | memcpy(buf_ + size_, buf, len); 49 | size_ += len; 50 | } else { 51 | overrun_ = true; 52 | } 53 | } 54 | return !overrun_; 55 | } 56 | 57 | void reset() { 58 | size_ = 0; 59 | overrun_ = false; 60 | } 61 | 62 | const uint8_t* begin() const { return buf_; } 63 | const uint8_t* end() const { return overrun_ ? buf_ : buf_ + size_; } 64 | size_t size() const { return size_; } 65 | 66 | private: 67 | uint8_t* buf_; 68 | size_t size_{0}; 69 | bool overrun_{false}; 70 | }; 71 | 72 | struct user_ctx { 73 | ImageBuffer buffer; 74 | uint32_t delay = 10000; 75 | bool valid{true}; 76 | 77 | void reset() { 78 | buffer.reset(); 79 | valid = true; 80 | } 81 | }; 82 | 83 | void wsEventHandler(void *args, esp_event_base_t base, int32_t eventId, void* eventData) 84 | { 85 | esp_websocket_event_data_t *data = (esp_websocket_event_data_t*)eventData; 86 | user_ctx* ctx = (user_ctx*)data->user_context; 87 | 88 | switch (eventId) { 89 | case WEBSOCKET_EVENT_CONNECTED: 90 | ESP_LOGI(TAG, "Websocket connected"); 91 | break; 92 | case WEBSOCKET_EVENT_DISCONNECTED: 93 | ESP_LOGI(TAG, "Websocket disconnected"); 94 | break; 95 | case WEBSOCKET_EVENT_DATA: 96 | ESP_LOGI(TAG, 97 | "WS Recv op_code: %X, fin: %d, payload_len: %u, " 98 | "payload_offset: %u, data_len: %u", 99 | data->op_code, data->fin, data->payload_len, 100 | data->payload_offset, data->data_len); 101 | switch (data->op_code) { 102 | case 0x1: // Text 103 | ctx->valid = false; 104 | break; 105 | case 0x2: // BINARY 106 | if (!data->payload_offset) { 107 | // This stops the current animation on the current 108 | // frame, and releases the underlying WebP buffers 109 | // so we have as much RAM as possible to load the 110 | // incoming animation into. 111 | animationStart(nullptr); 112 | ctx->reset(); 113 | } 114 | /* fallthrough */ 115 | case 0x0: // Continue 116 | if (!ctx->valid) { 117 | ESP_LOGE(TAG, "No buffer for incoming WS data"); 118 | return; 119 | } 120 | if (!ctx->buffer.append((uint8_t*)data->data_ptr, data->data_len)) { 121 | ESP_LOGE( 122 | TAG, 123 | "Image buffer overrun for %u bytes at offset %u", 124 | data->data_len, ctx->buffer.size()); 125 | ctx->valid = false; 126 | } 127 | if (ctx->valid && data->fin) { 128 | // This is really a hack to prove not reallocating the 129 | // incoming buffer every time and should be cleaned up. 130 | std::unique_ptr img = 131 | std::make_unique( 132 | std::make_unique( 133 | ctx->buffer.begin(), ctx->buffer.end())); 134 | if (img->valid()) { 135 | animationStart(std::move(img)); 136 | } 137 | ctx->valid = false; 138 | } 139 | break; 140 | case 0x9: // Ping 141 | case 0xA: // Pong 142 | break; 143 | default: 144 | ESP_LOGE(TAG, "Invalid frame opcode %X", data->op_code); 145 | // If we're in the middle of a payload, it's likely garbage now. 146 | ctx->reset(); 147 | break; 148 | } 149 | break; 150 | case WEBSOCKET_EVENT_ERROR: 151 | ESP_LOGI(TAG, "Websocket error"); 152 | break; 153 | } 154 | } 155 | 156 | extern "C" { 157 | void app_main(void) 158 | { 159 | ESP_ERROR_CHECK(esp_event_loop_create_default()); 160 | 161 | animationSetup(); 162 | 163 | auto nyan = std::make_unique( 164 | std::make_unique(NyanWebPSrc)); 165 | if (nyan->valid()) { 166 | animationStart(std::move(nyan)); 167 | } 168 | 169 | 170 | gpio_pad_select_gpio(LED_BUILTIN); 171 | gpio_set_direction(LED_BUILTIN, GPIO_MODE_OUTPUT); 172 | gpio_set_level(LED_BUILTIN, 0); 173 | 174 | netMgr = std::make_unique(); 175 | netMgr->start(); 176 | 177 | ESP_LOGI(TAG, "WiFi up"); 178 | 179 | // Note - Config::instance() depends on WiFi being initialized already for the RNG. 180 | const auto uri = Config::instance().imageUri(); 181 | 182 | RootPage root; 183 | 184 | httpServer = std::make_unique(); 185 | httpServer->registerHandler("/", root); 186 | 187 | gpio_set_level(LED_BUILTIN, 1); 188 | user_ctx *ctx = new user_ctx(); 189 | if (!ctx) { 190 | ESP_LOGE(TAG, "Failed to allocate WS Context"); 191 | } 192 | 193 | esp_websocket_client_config_t wsCfg = {}; 194 | wsCfg.uri = uri.c_str(); 195 | wsCfg.user_context = ctx; 196 | wsCfg.buffer_size = 1024; 197 | 198 | ESP_LOGI(TAG, "Websocket Connect %s", uri.c_str()); 199 | esp_websocket_client_handle_t client = esp_websocket_client_init(&wsCfg); 200 | esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, wsEventHandler, 201 | client); 202 | esp_websocket_client_start(client); 203 | 204 | // This method must not return! 205 | for (;;) { 206 | vTaskDelay(10000 / portTICK_PERIOD_MS); 207 | } 208 | } 209 | 210 | } // extern "C" 211 | -------------------------------------------------------------------------------- /main/nyan_64x32.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joe714/pixelclient/d52c503c2ac620694c2bf387f14f95b04b4f7ef2/main/nyan_64x32.webp -------------------------------------------------------------------------------- /nvs.csv.sample: -------------------------------------------------------------------------------- 1 | key,type,encoding,value 2 | NetManager,namespace,, 3 | ssid,data,string,WIFI_SSID_HERE 4 | password,data,string,WIFI_PASSWD_HERE 5 | PixelMatrix,namespace 6 | endpoint,data,string,192.168.1.100 7 | port,data,u16,8080 8 | -------------------------------------------------------------------------------- /nvs.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | # Build script to create the an NVS partition data. Copy nvs.csv.sample to 3 | # nvs.csv and replace the following values: 4 | # ssid: WIFI_SSID_HERE 5 | # password: WIFI_PASSWD_HERE 6 | # endpoint: 192.168.1.100 ## This should be the IP of your pixelgw server 7 | # port: 8080 ## Replace with 8081 for the test server deployment 8 | # This is meant to be run under docker via 'build.sh nvs'. 9 | 10 | NVS=nvs.csv 11 | if [ ! -z $1 ] ; then 12 | NVS=$1 13 | fi 14 | 15 | if [ ! -f $NVS ] ; then 16 | echo file $NVS not found 17 | exit 1 18 | fi 19 | 20 | PINFO=`/opt/esp/idf/components/partition_table/parttool.py -f partitions.csv get_partition_info --partition-name nvs` 21 | OFFSET=`echo $PINFO | awk '{print $1}'` 22 | SIZE=`echo $PINFO | awk '{print $2}'` 23 | 24 | /opt/esp/idf/components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py generate \ 25 | $NVS build/nvs.bin $SIZE 26 | head -1 build/flash_args > build/flash_nvs_args 27 | echo $OFFSET nvs.bin >> build/flash_nvs_args 28 | 29 | -------------------------------------------------------------------------------- /partitions.csv: -------------------------------------------------------------------------------- 1 | #Name, Type, Subtype, Offset, Size, Flags 2 | otadata, data, ota, 0x9000, 0x2000, 3 | nvs, data, nvs, , 0x4000, 4 | ota_0, app, ota_0, 0x10000, 3M, 5 | ota_1, app, ota_1, , 3M, 6 | spiffs, data, spiffs, , 1M, 7 | 8 | 9 | -------------------------------------------------------------------------------- /sdkconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated file. DO NOT EDIT. 3 | # Espressif IoT Development Framework (ESP-IDF) 5.2.2 Project Configuration 4 | # 5 | CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined" 6 | CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined" 7 | CONFIG_SOC_DPORT_WORKAROUND="Not determined" 8 | CONFIG_SOC_CAPS_ECO_VER_MAX=301 9 | CONFIG_SOC_ADC_SUPPORTED=y 10 | CONFIG_SOC_DAC_SUPPORTED=y 11 | CONFIG_SOC_UART_SUPPORTED=y 12 | CONFIG_SOC_MCPWM_SUPPORTED=y 13 | CONFIG_SOC_GPTIMER_SUPPORTED=y 14 | CONFIG_SOC_SDMMC_HOST_SUPPORTED=y 15 | CONFIG_SOC_BT_SUPPORTED=y 16 | CONFIG_SOC_PCNT_SUPPORTED=y 17 | CONFIG_SOC_WIFI_SUPPORTED=y 18 | CONFIG_SOC_SDIO_SLAVE_SUPPORTED=y 19 | CONFIG_SOC_TWAI_SUPPORTED=y 20 | CONFIG_SOC_EFUSE_SUPPORTED=y 21 | CONFIG_SOC_EMAC_SUPPORTED=y 22 | CONFIG_SOC_ULP_SUPPORTED=y 23 | CONFIG_SOC_CCOMP_TIMER_SUPPORTED=y 24 | CONFIG_SOC_RTC_FAST_MEM_SUPPORTED=y 25 | CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED=y 26 | CONFIG_SOC_RTC_MEM_SUPPORTED=y 27 | CONFIG_SOC_I2S_SUPPORTED=y 28 | CONFIG_SOC_RMT_SUPPORTED=y 29 | CONFIG_SOC_SDM_SUPPORTED=y 30 | CONFIG_SOC_GPSPI_SUPPORTED=y 31 | CONFIG_SOC_LEDC_SUPPORTED=y 32 | CONFIG_SOC_I2C_SUPPORTED=y 33 | CONFIG_SOC_SUPPORT_COEXISTENCE=y 34 | CONFIG_SOC_AES_SUPPORTED=y 35 | CONFIG_SOC_MPI_SUPPORTED=y 36 | CONFIG_SOC_SHA_SUPPORTED=y 37 | CONFIG_SOC_FLASH_ENC_SUPPORTED=y 38 | CONFIG_SOC_SECURE_BOOT_SUPPORTED=y 39 | CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y 40 | CONFIG_SOC_BOD_SUPPORTED=y 41 | CONFIG_SOC_ULP_FSM_SUPPORTED=y 42 | CONFIG_SOC_CLK_TREE_SUPPORTED=y 43 | CONFIG_SOC_MPU_SUPPORTED=y 44 | CONFIG_SOC_WDT_SUPPORTED=y 45 | CONFIG_SOC_SPI_FLASH_SUPPORTED=y 46 | CONFIG_SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL=5 47 | CONFIG_SOC_XTAL_SUPPORT_26M=y 48 | CONFIG_SOC_XTAL_SUPPORT_40M=y 49 | CONFIG_SOC_XTAL_SUPPORT_AUTO_DETECT=y 50 | CONFIG_SOC_ADC_RTC_CTRL_SUPPORTED=y 51 | CONFIG_SOC_ADC_DIG_CTRL_SUPPORTED=y 52 | CONFIG_SOC_ADC_DMA_SUPPORTED=y 53 | CONFIG_SOC_ADC_PERIPH_NUM=2 54 | CONFIG_SOC_ADC_MAX_CHANNEL_NUM=10 55 | CONFIG_SOC_ADC_ATTEN_NUM=4 56 | CONFIG_SOC_ADC_DIGI_CONTROLLER_NUM=2 57 | CONFIG_SOC_ADC_PATT_LEN_MAX=16 58 | CONFIG_SOC_ADC_DIGI_MIN_BITWIDTH=9 59 | CONFIG_SOC_ADC_DIGI_MAX_BITWIDTH=12 60 | CONFIG_SOC_ADC_DIGI_RESULT_BYTES=2 61 | CONFIG_SOC_ADC_DIGI_DATA_BYTES_PER_CONV=4 62 | CONFIG_SOC_ADC_DIGI_MONITOR_NUM=0 63 | CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_HIGH=2 64 | CONFIG_SOC_ADC_SAMPLE_FREQ_THRES_LOW=20 65 | CONFIG_SOC_ADC_RTC_MIN_BITWIDTH=9 66 | CONFIG_SOC_ADC_RTC_MAX_BITWIDTH=12 67 | CONFIG_SOC_ADC_SHARED_POWER=y 68 | CONFIG_SOC_SHARED_IDCACHE_SUPPORTED=y 69 | CONFIG_SOC_IDCACHE_PER_CORE=y 70 | CONFIG_SOC_CPU_CORES_NUM=2 71 | CONFIG_SOC_CPU_INTR_NUM=32 72 | CONFIG_SOC_CPU_HAS_FPU=y 73 | CONFIG_SOC_HP_CPU_HAS_MULTIPLE_CORES=y 74 | CONFIG_SOC_CPU_BREAKPOINTS_NUM=2 75 | CONFIG_SOC_CPU_WATCHPOINTS_NUM=2 76 | CONFIG_SOC_CPU_WATCHPOINT_MAX_REGION_SIZE=64 77 | CONFIG_SOC_DAC_CHAN_NUM=2 78 | CONFIG_SOC_DAC_RESOLUTION=8 79 | CONFIG_SOC_DAC_DMA_16BIT_ALIGN=y 80 | CONFIG_SOC_GPIO_PORT=1 81 | CONFIG_SOC_GPIO_PIN_COUNT=40 82 | CONFIG_SOC_GPIO_VALID_GPIO_MASK=0xFFFFFFFFFF 83 | CONFIG_SOC_GPIO_IN_RANGE_MAX=39 84 | CONFIG_SOC_GPIO_OUT_RANGE_MAX=33 85 | CONFIG_SOC_GPIO_VALID_DIGITAL_IO_PAD_MASK=0xEF0FEA 86 | CONFIG_SOC_GPIO_CLOCKOUT_BY_IO_MUX=y 87 | CONFIG_SOC_I2C_NUM=2 88 | CONFIG_SOC_I2C_FIFO_LEN=32 89 | CONFIG_SOC_I2C_CMD_REG_NUM=16 90 | CONFIG_SOC_I2C_SUPPORT_SLAVE=y 91 | CONFIG_SOC_I2C_SUPPORT_APB=y 92 | CONFIG_SOC_I2C_STOP_INDEPENDENT=y 93 | CONFIG_SOC_I2S_NUM=2 94 | CONFIG_SOC_I2S_HW_VERSION_1=y 95 | CONFIG_SOC_I2S_SUPPORTS_APLL=y 96 | CONFIG_SOC_I2S_SUPPORTS_PLL_F160M=y 97 | CONFIG_SOC_I2S_SUPPORTS_PDM=y 98 | CONFIG_SOC_I2S_SUPPORTS_PDM_TX=y 99 | CONFIG_SOC_I2S_PDM_MAX_TX_LINES=1 100 | CONFIG_SOC_I2S_SUPPORTS_PDM_RX=y 101 | CONFIG_SOC_I2S_PDM_MAX_RX_LINES=1 102 | CONFIG_SOC_I2S_SUPPORTS_ADC_DAC=y 103 | CONFIG_SOC_I2S_SUPPORTS_ADC=y 104 | CONFIG_SOC_I2S_SUPPORTS_DAC=y 105 | CONFIG_SOC_I2S_SUPPORTS_LCD_CAMERA=y 106 | CONFIG_SOC_I2S_TRANS_SIZE_ALIGN_WORD=y 107 | CONFIG_SOC_I2S_LCD_I80_VARIANT=y 108 | CONFIG_SOC_LCD_I80_SUPPORTED=y 109 | CONFIG_SOC_LCD_I80_BUSES=2 110 | CONFIG_SOC_LCD_I80_BUS_WIDTH=24 111 | CONFIG_SOC_LEDC_HAS_TIMER_SPECIFIC_MUX=y 112 | CONFIG_SOC_LEDC_SUPPORT_APB_CLOCK=y 113 | CONFIG_SOC_LEDC_SUPPORT_REF_TICK=y 114 | CONFIG_SOC_LEDC_SUPPORT_HS_MODE=y 115 | CONFIG_SOC_LEDC_CHANNEL_NUM=8 116 | CONFIG_SOC_LEDC_TIMER_BIT_WIDTH=20 117 | CONFIG_SOC_MCPWM_GROUPS=2 118 | CONFIG_SOC_MCPWM_TIMERS_PER_GROUP=3 119 | CONFIG_SOC_MCPWM_OPERATORS_PER_GROUP=3 120 | CONFIG_SOC_MCPWM_COMPARATORS_PER_OPERATOR=2 121 | CONFIG_SOC_MCPWM_GENERATORS_PER_OPERATOR=2 122 | CONFIG_SOC_MCPWM_TRIGGERS_PER_OPERATOR=2 123 | CONFIG_SOC_MCPWM_GPIO_FAULTS_PER_GROUP=3 124 | CONFIG_SOC_MCPWM_CAPTURE_TIMERS_PER_GROUP=y 125 | CONFIG_SOC_MCPWM_CAPTURE_CHANNELS_PER_TIMER=3 126 | CONFIG_SOC_MCPWM_GPIO_SYNCHROS_PER_GROUP=3 127 | CONFIG_SOC_MMU_PERIPH_NUM=2 128 | CONFIG_SOC_MMU_LINEAR_ADDRESS_REGION_NUM=3 129 | CONFIG_SOC_MPU_MIN_REGION_SIZE=0x20000000 130 | CONFIG_SOC_MPU_REGIONS_MAX_NUM=8 131 | CONFIG_SOC_PCNT_GROUPS=1 132 | CONFIG_SOC_PCNT_UNITS_PER_GROUP=8 133 | CONFIG_SOC_PCNT_CHANNELS_PER_UNIT=2 134 | CONFIG_SOC_PCNT_THRES_POINT_PER_UNIT=2 135 | CONFIG_SOC_RMT_GROUPS=1 136 | CONFIG_SOC_RMT_TX_CANDIDATES_PER_GROUP=8 137 | CONFIG_SOC_RMT_RX_CANDIDATES_PER_GROUP=8 138 | CONFIG_SOC_RMT_CHANNELS_PER_GROUP=8 139 | CONFIG_SOC_RMT_MEM_WORDS_PER_CHANNEL=64 140 | CONFIG_SOC_RMT_SUPPORT_REF_TICK=y 141 | CONFIG_SOC_RMT_SUPPORT_APB=y 142 | CONFIG_SOC_RMT_CHANNEL_CLK_INDEPENDENT=y 143 | CONFIG_SOC_RTCIO_PIN_COUNT=18 144 | CONFIG_SOC_RTCIO_INPUT_OUTPUT_SUPPORTED=y 145 | CONFIG_SOC_RTCIO_HOLD_SUPPORTED=y 146 | CONFIG_SOC_RTCIO_WAKE_SUPPORTED=y 147 | CONFIG_SOC_SDM_GROUPS=1 148 | CONFIG_SOC_SDM_CHANNELS_PER_GROUP=8 149 | CONFIG_SOC_SDM_CLK_SUPPORT_APB=y 150 | CONFIG_SOC_SPI_HD_BOTH_INOUT_SUPPORTED=y 151 | CONFIG_SOC_SPI_AS_CS_SUPPORTED=y 152 | CONFIG_SOC_SPI_PERIPH_NUM=3 153 | CONFIG_SOC_SPI_DMA_CHAN_NUM=2 154 | CONFIG_SOC_SPI_MAX_CS_NUM=3 155 | CONFIG_SOC_SPI_SUPPORT_CLK_APB=y 156 | CONFIG_SOC_SPI_MAXIMUM_BUFFER_SIZE=64 157 | CONFIG_SOC_SPI_MAX_PRE_DIVIDER=8192 158 | CONFIG_SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED=y 159 | CONFIG_SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED=y 160 | CONFIG_SOC_MEMSPI_SRC_FREQ_26M_SUPPORTED=y 161 | CONFIG_SOC_MEMSPI_SRC_FREQ_20M_SUPPORTED=y 162 | CONFIG_SOC_TIMER_GROUPS=2 163 | CONFIG_SOC_TIMER_GROUP_TIMERS_PER_GROUP=2 164 | CONFIG_SOC_TIMER_GROUP_COUNTER_BIT_WIDTH=64 165 | CONFIG_SOC_TIMER_GROUP_TOTAL_TIMERS=4 166 | CONFIG_SOC_TIMER_GROUP_SUPPORT_APB=y 167 | CONFIG_SOC_TOUCH_VERSION_1=y 168 | CONFIG_SOC_TOUCH_SENSOR_NUM=10 169 | CONFIG_SOC_TOUCH_PAD_MEASURE_WAIT_MAX=0xFF 170 | CONFIG_SOC_TWAI_CONTROLLER_NUM=1 171 | CONFIG_SOC_TWAI_BRP_MIN=2 172 | CONFIG_SOC_TWAI_CLK_SUPPORT_APB=y 173 | CONFIG_SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT=y 174 | CONFIG_SOC_UART_NUM=3 175 | CONFIG_SOC_UART_HP_NUM=3 176 | CONFIG_SOC_UART_SUPPORT_APB_CLK=y 177 | CONFIG_SOC_UART_SUPPORT_REF_TICK=y 178 | CONFIG_SOC_UART_FIFO_LEN=128 179 | CONFIG_SOC_UART_BITRATE_MAX=5000000 180 | CONFIG_SOC_SPIRAM_SUPPORTED=y 181 | CONFIG_SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE=y 182 | CONFIG_SOC_SHA_SUPPORT_PARALLEL_ENG=y 183 | CONFIG_SOC_SHA_ENDIANNESS_BE=y 184 | CONFIG_SOC_SHA_SUPPORT_SHA1=y 185 | CONFIG_SOC_SHA_SUPPORT_SHA256=y 186 | CONFIG_SOC_SHA_SUPPORT_SHA384=y 187 | CONFIG_SOC_SHA_SUPPORT_SHA512=y 188 | CONFIG_SOC_MPI_MEM_BLOCKS_NUM=4 189 | CONFIG_SOC_MPI_OPERATIONS_NUM=y 190 | CONFIG_SOC_RSA_MAX_BIT_LEN=4096 191 | CONFIG_SOC_AES_SUPPORT_AES_128=y 192 | CONFIG_SOC_AES_SUPPORT_AES_192=y 193 | CONFIG_SOC_AES_SUPPORT_AES_256=y 194 | CONFIG_SOC_SECURE_BOOT_V1=y 195 | CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS=y 196 | CONFIG_SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX=32 197 | CONFIG_SOC_PHY_DIG_REGS_MEM_SIZE=21 198 | CONFIG_SOC_PM_SUPPORT_EXT0_WAKEUP=y 199 | CONFIG_SOC_PM_SUPPORT_EXT1_WAKEUP=y 200 | CONFIG_SOC_PM_SUPPORT_EXT_WAKEUP=y 201 | CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP=y 202 | CONFIG_SOC_PM_SUPPORT_RTC_PERIPH_PD=y 203 | CONFIG_SOC_PM_SUPPORT_RTC_FAST_MEM_PD=y 204 | CONFIG_SOC_PM_SUPPORT_RTC_SLOW_MEM_PD=y 205 | CONFIG_SOC_PM_SUPPORT_RC_FAST_PD=y 206 | CONFIG_SOC_PM_SUPPORT_VDDSDIO_PD=y 207 | CONFIG_SOC_PM_SUPPORT_MODEM_PD=y 208 | CONFIG_SOC_CONFIGURABLE_VDDSDIO_SUPPORTED=y 209 | CONFIG_SOC_CLK_APLL_SUPPORTED=y 210 | CONFIG_SOC_CLK_RC_FAST_D256_SUPPORTED=y 211 | CONFIG_SOC_RTC_SLOW_CLK_SUPPORT_RC_FAST_D256=y 212 | CONFIG_SOC_CLK_RC_FAST_SUPPORT_CALIBRATION=y 213 | CONFIG_SOC_CLK_XTAL32K_SUPPORTED=y 214 | CONFIG_SOC_SDMMC_USE_IOMUX=y 215 | CONFIG_SOC_SDMMC_NUM_SLOTS=2 216 | CONFIG_SOC_WIFI_WAPI_SUPPORT=y 217 | CONFIG_SOC_WIFI_CSI_SUPPORT=y 218 | CONFIG_SOC_WIFI_MESH_SUPPORT=y 219 | CONFIG_SOC_WIFI_SUPPORT_VARIABLE_BEACON_WINDOW=y 220 | CONFIG_SOC_WIFI_NAN_SUPPORT=y 221 | CONFIG_SOC_BLE_SUPPORTED=y 222 | CONFIG_SOC_BLE_MESH_SUPPORTED=y 223 | CONFIG_SOC_BT_CLASSIC_SUPPORTED=y 224 | CONFIG_SOC_BLUFI_SUPPORTED=y 225 | CONFIG_SOC_ULP_HAS_ADC=y 226 | CONFIG_SOC_PHY_COMBO_MODULE=y 227 | CONFIG_IDF_CMAKE=y 228 | CONFIG_IDF_TOOLCHAIN="gcc" 229 | CONFIG_IDF_TARGET_ARCH_XTENSA=y 230 | CONFIG_IDF_TARGET_ARCH="xtensa" 231 | CONFIG_IDF_TARGET="esp32" 232 | CONFIG_IDF_INIT_VERSION="5.2.1" 233 | CONFIG_IDF_TARGET_ESP32=y 234 | CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 235 | 236 | # 237 | # Build type 238 | # 239 | CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y 240 | # CONFIG_APP_BUILD_TYPE_RAM is not set 241 | CONFIG_APP_BUILD_GENERATE_BINARIES=y 242 | CONFIG_APP_BUILD_BOOTLOADER=y 243 | CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y 244 | # CONFIG_APP_REPRODUCIBLE_BUILD is not set 245 | # CONFIG_APP_NO_BLOBS is not set 246 | # CONFIG_APP_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set 247 | # CONFIG_APP_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set 248 | # end of Build type 249 | 250 | # 251 | # Bootloader config 252 | # 253 | 254 | # 255 | # Bootloader manager 256 | # 257 | CONFIG_BOOTLOADER_COMPILE_TIME_DATE=y 258 | CONFIG_BOOTLOADER_PROJECT_VER=1 259 | # end of Bootloader manager 260 | 261 | CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 262 | CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y 263 | # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set 264 | # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set 265 | # CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set 266 | # CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set 267 | # CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set 268 | # CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set 269 | CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y 270 | # CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set 271 | # CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set 272 | CONFIG_BOOTLOADER_LOG_LEVEL=3 273 | 274 | # 275 | # Serial Flash Configurations 276 | # 277 | # CONFIG_BOOTLOADER_FLASH_DC_AWARE is not set 278 | CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT=y 279 | # end of Serial Flash Configurations 280 | 281 | # CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set 282 | CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y 283 | # CONFIG_BOOTLOADER_FACTORY_RESET is not set 284 | # CONFIG_BOOTLOADER_APP_TEST is not set 285 | CONFIG_BOOTLOADER_REGION_PROTECTION_ENABLE=y 286 | CONFIG_BOOTLOADER_WDT_ENABLE=y 287 | # CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set 288 | CONFIG_BOOTLOADER_WDT_TIME_MS=9000 289 | # CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set 290 | # CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set 291 | # CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set 292 | # CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set 293 | CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 294 | # CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set 295 | # end of Bootloader config 296 | 297 | # 298 | # Security features 299 | # 300 | CONFIG_SECURE_BOOT_V1_SUPPORTED=y 301 | # CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set 302 | # CONFIG_SECURE_BOOT is not set 303 | # CONFIG_SECURE_FLASH_ENC_ENABLED is not set 304 | # end of Security features 305 | 306 | # 307 | # Application manager 308 | # 309 | CONFIG_APP_COMPILE_TIME_DATE=y 310 | # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set 311 | # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set 312 | # CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set 313 | CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 314 | # end of Application manager 315 | 316 | CONFIG_ESP_ROM_HAS_CRC_LE=y 317 | CONFIG_ESP_ROM_HAS_CRC_BE=y 318 | CONFIG_ESP_ROM_HAS_MZ_CRC32=y 319 | CONFIG_ESP_ROM_HAS_JPEG_DECODE=y 320 | CONFIG_ESP_ROM_HAS_UART_BUF_SWITCH=y 321 | CONFIG_ESP_ROM_NEEDS_SWSETUP_WORKAROUND=y 322 | CONFIG_ESP_ROM_HAS_NEWLIB_NANO_FORMAT=y 323 | CONFIG_ESP_ROM_HAS_SW_FLOAT=y 324 | CONFIG_ESP_ROM_USB_SERIAL_DEVICE_NUM=-1 325 | 326 | # 327 | # Serial flasher config 328 | # 329 | # CONFIG_ESPTOOLPY_NO_STUB is not set 330 | # CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set 331 | # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set 332 | CONFIG_ESPTOOLPY_FLASHMODE_DIO=y 333 | # CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set 334 | CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y 335 | CONFIG_ESPTOOLPY_FLASHMODE="dio" 336 | # CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set 337 | CONFIG_ESPTOOLPY_FLASHFREQ_40M=y 338 | # CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set 339 | # CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set 340 | CONFIG_ESPTOOLPY_FLASHFREQ="40m" 341 | # CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set 342 | # CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set 343 | # CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set 344 | CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y 345 | # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set 346 | # CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set 347 | # CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set 348 | # CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set 349 | CONFIG_ESPTOOLPY_FLASHSIZE="8MB" 350 | # CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE is not set 351 | CONFIG_ESPTOOLPY_BEFORE_RESET=y 352 | # CONFIG_ESPTOOLPY_BEFORE_NORESET is not set 353 | CONFIG_ESPTOOLPY_BEFORE="default_reset" 354 | CONFIG_ESPTOOLPY_AFTER_RESET=y 355 | # CONFIG_ESPTOOLPY_AFTER_NORESET is not set 356 | CONFIG_ESPTOOLPY_AFTER="hard_reset" 357 | CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 358 | # end of Serial flasher config 359 | 360 | # 361 | # Partition Table 362 | # 363 | # CONFIG_PARTITION_TABLE_SINGLE_APP is not set 364 | # CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE is not set 365 | # CONFIG_PARTITION_TABLE_TWO_OTA is not set 366 | CONFIG_PARTITION_TABLE_CUSTOM=y 367 | CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" 368 | CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" 369 | CONFIG_PARTITION_TABLE_OFFSET=0x8000 370 | CONFIG_PARTITION_TABLE_MD5=y 371 | # end of Partition Table 372 | 373 | # 374 | # Compiler options 375 | # 376 | CONFIG_COMPILER_OPTIMIZATION_DEBUG=y 377 | # CONFIG_COMPILER_OPTIMIZATION_SIZE is not set 378 | # CONFIG_COMPILER_OPTIMIZATION_PERF is not set 379 | # CONFIG_COMPILER_OPTIMIZATION_NONE is not set 380 | CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y 381 | # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set 382 | # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set 383 | CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB=y 384 | CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL=2 385 | # CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT is not set 386 | CONFIG_COMPILER_HIDE_PATHS_MACROS=y 387 | # CONFIG_COMPILER_CXX_EXCEPTIONS is not set 388 | CONFIG_COMPILER_CXX_RTTI=y 389 | CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y 390 | # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set 391 | # CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set 392 | # CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set 393 | # CONFIG_COMPILER_WARN_WRITE_STRINGS is not set 394 | # CONFIG_COMPILER_DISABLE_GCC12_WARNINGS is not set 395 | # CONFIG_COMPILER_DISABLE_GCC13_WARNINGS is not set 396 | # CONFIG_COMPILER_DUMP_RTL_FILES is not set 397 | CONFIG_COMPILER_RT_LIB_GCCLIB=y 398 | CONFIG_COMPILER_RT_LIB_NAME="gcc" 399 | # CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING is not set 400 | CONFIG_COMPILER_ORPHAN_SECTIONS_PLACE=y 401 | # end of Compiler options 402 | 403 | # 404 | # Component config 405 | # 406 | 407 | # 408 | # Application Level Tracing 409 | # 410 | # CONFIG_APPTRACE_DEST_JTAG is not set 411 | CONFIG_APPTRACE_DEST_NONE=y 412 | # CONFIG_APPTRACE_DEST_UART1 is not set 413 | # CONFIG_APPTRACE_DEST_UART2 is not set 414 | CONFIG_APPTRACE_DEST_UART_NONE=y 415 | CONFIG_APPTRACE_UART_TASK_PRIO=1 416 | CONFIG_APPTRACE_LOCK_ENABLE=y 417 | # end of Application Level Tracing 418 | 419 | # 420 | # Bluetooth 421 | # 422 | # CONFIG_BT_ENABLED is not set 423 | CONFIG_BT_ALARM_MAX_NUM=50 424 | # end of Bluetooth 425 | 426 | # 427 | # Driver Configurations 428 | # 429 | 430 | # 431 | # Legacy ADC Configuration 432 | # 433 | CONFIG_ADC_DISABLE_DAC=y 434 | # CONFIG_ADC_SUPPRESS_DEPRECATE_WARN is not set 435 | 436 | # 437 | # Legacy ADC Calibration Configuration 438 | # 439 | CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y 440 | CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y 441 | CONFIG_ADC_CAL_LUT_ENABLE=y 442 | # CONFIG_ADC_CALI_SUPPRESS_DEPRECATE_WARN is not set 443 | # end of Legacy ADC Calibration Configuration 444 | # end of Legacy ADC Configuration 445 | 446 | # 447 | # SPI Configuration 448 | # 449 | # CONFIG_SPI_MASTER_IN_IRAM is not set 450 | CONFIG_SPI_MASTER_ISR_IN_IRAM=y 451 | # CONFIG_SPI_SLAVE_IN_IRAM is not set 452 | CONFIG_SPI_SLAVE_ISR_IN_IRAM=y 453 | # end of SPI Configuration 454 | 455 | # 456 | # TWAI Configuration 457 | # 458 | # CONFIG_TWAI_ISR_IN_IRAM is not set 459 | # CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC is not set 460 | # CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST is not set 461 | # CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID is not set 462 | # CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set 463 | # CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM is not set 464 | # end of TWAI Configuration 465 | 466 | # 467 | # UART Configuration 468 | # 469 | # CONFIG_UART_ISR_IN_IRAM is not set 470 | # end of UART Configuration 471 | 472 | # 473 | # GPIO Configuration 474 | # 475 | # CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set 476 | # CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set 477 | # end of GPIO Configuration 478 | 479 | # 480 | # Sigma Delta Modulator Configuration 481 | # 482 | # CONFIG_SDM_CTRL_FUNC_IN_IRAM is not set 483 | # CONFIG_SDM_SUPPRESS_DEPRECATE_WARN is not set 484 | # CONFIG_SDM_ENABLE_DEBUG_LOG is not set 485 | # end of Sigma Delta Modulator Configuration 486 | 487 | # 488 | # GPTimer Configuration 489 | # 490 | CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y 491 | # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set 492 | # CONFIG_GPTIMER_ISR_IRAM_SAFE is not set 493 | # CONFIG_GPTIMER_SUPPRESS_DEPRECATE_WARN is not set 494 | # CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set 495 | # end of GPTimer Configuration 496 | 497 | # 498 | # PCNT Configuration 499 | # 500 | # CONFIG_PCNT_CTRL_FUNC_IN_IRAM is not set 501 | # CONFIG_PCNT_ISR_IRAM_SAFE is not set 502 | # CONFIG_PCNT_SUPPRESS_DEPRECATE_WARN is not set 503 | # CONFIG_PCNT_ENABLE_DEBUG_LOG is not set 504 | # end of PCNT Configuration 505 | 506 | # 507 | # RMT Configuration 508 | # 509 | # CONFIG_RMT_ISR_IRAM_SAFE is not set 510 | # CONFIG_RMT_RECV_FUNC_IN_IRAM is not set 511 | # CONFIG_RMT_SUPPRESS_DEPRECATE_WARN is not set 512 | # CONFIG_RMT_ENABLE_DEBUG_LOG is not set 513 | # end of RMT Configuration 514 | 515 | # 516 | # MCPWM Configuration 517 | # 518 | # CONFIG_MCPWM_ISR_IRAM_SAFE is not set 519 | # CONFIG_MCPWM_CTRL_FUNC_IN_IRAM is not set 520 | # CONFIG_MCPWM_SUPPRESS_DEPRECATE_WARN is not set 521 | # CONFIG_MCPWM_ENABLE_DEBUG_LOG is not set 522 | # end of MCPWM Configuration 523 | 524 | # 525 | # I2S Configuration 526 | # 527 | # CONFIG_I2S_ISR_IRAM_SAFE is not set 528 | # CONFIG_I2S_SUPPRESS_DEPRECATE_WARN is not set 529 | # CONFIG_I2S_ENABLE_DEBUG_LOG is not set 530 | # end of I2S Configuration 531 | 532 | # 533 | # DAC Configuration 534 | # 535 | # CONFIG_DAC_CTRL_FUNC_IN_IRAM is not set 536 | # CONFIG_DAC_ISR_IRAM_SAFE is not set 537 | # CONFIG_DAC_SUPPRESS_DEPRECATE_WARN is not set 538 | # CONFIG_DAC_ENABLE_DEBUG_LOG is not set 539 | CONFIG_DAC_DMA_AUTO_16BIT_ALIGN=y 540 | # end of DAC Configuration 541 | 542 | # 543 | # LEDC Configuration 544 | # 545 | # CONFIG_LEDC_CTRL_FUNC_IN_IRAM is not set 546 | # end of LEDC Configuration 547 | 548 | # 549 | # I2C Configuration 550 | # 551 | # CONFIG_I2C_ISR_IRAM_SAFE is not set 552 | # CONFIG_I2C_ENABLE_DEBUG_LOG is not set 553 | # end of I2C Configuration 554 | # end of Driver Configurations 555 | 556 | # 557 | # eFuse Bit Manager 558 | # 559 | # CONFIG_EFUSE_CUSTOM_TABLE is not set 560 | # CONFIG_EFUSE_VIRTUAL is not set 561 | # CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set 562 | CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y 563 | # CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set 564 | CONFIG_EFUSE_MAX_BLK_LEN=192 565 | # end of eFuse Bit Manager 566 | 567 | # 568 | # ESP-TLS 569 | # 570 | CONFIG_ESP_TLS_USING_MBEDTLS=y 571 | # CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set 572 | # CONFIG_ESP_TLS_CLIENT_SESSION_TICKETS is not set 573 | # CONFIG_ESP_TLS_SERVER is not set 574 | # CONFIG_ESP_TLS_PSK_VERIFICATION is not set 575 | # CONFIG_ESP_TLS_INSECURE is not set 576 | # end of ESP-TLS 577 | 578 | # 579 | # ADC and ADC Calibration 580 | # 581 | # CONFIG_ADC_ONESHOT_CTRL_FUNC_IN_IRAM is not set 582 | # CONFIG_ADC_CONTINUOUS_ISR_IRAM_SAFE is not set 583 | 584 | # 585 | # ADC Calibration Configurations 586 | # 587 | CONFIG_ADC_CALI_EFUSE_TP_ENABLE=y 588 | CONFIG_ADC_CALI_EFUSE_VREF_ENABLE=y 589 | CONFIG_ADC_CALI_LUT_ENABLE=y 590 | # end of ADC Calibration Configurations 591 | 592 | CONFIG_ADC_DISABLE_DAC_OUTPUT=y 593 | # end of ADC and ADC Calibration 594 | 595 | # 596 | # Wireless Coexistence 597 | # 598 | # end of Wireless Coexistence 599 | 600 | # 601 | # Common ESP-related 602 | # 603 | CONFIG_ESP_ERR_TO_NAME_LOOKUP=y 604 | # end of Common ESP-related 605 | 606 | # 607 | # Ethernet 608 | # 609 | # CONFIG_ETH_USE_ESP32_EMAC is not set 610 | # CONFIG_ETH_USE_SPI_ETHERNET is not set 611 | # CONFIG_ETH_USE_OPENETH is not set 612 | # end of Ethernet 613 | 614 | # 615 | # Event Loop Library 616 | # 617 | # CONFIG_ESP_EVENT_LOOP_PROFILING is not set 618 | CONFIG_ESP_EVENT_POST_FROM_ISR=y 619 | CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y 620 | # end of Event Loop Library 621 | 622 | # 623 | # GDB Stub 624 | # 625 | CONFIG_ESP_GDBSTUB_ENABLED=y 626 | # CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME is not set 627 | CONFIG_ESP_GDBSTUB_SUPPORT_TASKS=y 628 | CONFIG_ESP_GDBSTUB_MAX_TASKS=32 629 | # end of GDB Stub 630 | 631 | # 632 | # ESP HTTP client 633 | # 634 | CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y 635 | # CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set 636 | CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y 637 | # end of ESP HTTP client 638 | 639 | # 640 | # HTTP Server 641 | # 642 | CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 643 | CONFIG_HTTPD_MAX_URI_LEN=512 644 | CONFIG_HTTPD_ERR_RESP_NO_DELAY=y 645 | CONFIG_HTTPD_PURGE_BUF_LEN=32 646 | # CONFIG_HTTPD_LOG_PURGE_DATA is not set 647 | CONFIG_HTTPD_WS_SUPPORT=y 648 | # CONFIG_HTTPD_QUEUE_WORK_BLOCKING is not set 649 | # end of HTTP Server 650 | 651 | # 652 | # ESP HTTPS OTA 653 | # 654 | # CONFIG_ESP_HTTPS_OTA_DECRYPT_CB is not set 655 | CONFIG_ESP_HTTPS_OTA_ALLOW_HTTP=y 656 | # end of ESP HTTPS OTA 657 | 658 | # 659 | # ESP HTTPS server 660 | # 661 | # CONFIG_ESP_HTTPS_SERVER_ENABLE is not set 662 | # end of ESP HTTPS server 663 | 664 | # 665 | # Hardware Settings 666 | # 667 | 668 | # 669 | # Chip revision 670 | # 671 | CONFIG_ESP32_REV_MIN_0=y 672 | # CONFIG_ESP32_REV_MIN_1 is not set 673 | # CONFIG_ESP32_REV_MIN_1_1 is not set 674 | # CONFIG_ESP32_REV_MIN_2 is not set 675 | # CONFIG_ESP32_REV_MIN_3 is not set 676 | # CONFIG_ESP32_REV_MIN_3_1 is not set 677 | CONFIG_ESP32_REV_MIN=0 678 | CONFIG_ESP32_REV_MIN_FULL=0 679 | CONFIG_ESP_REV_MIN_FULL=0 680 | 681 | # 682 | # Maximum Supported ESP32 Revision (Rev v3.99) 683 | # 684 | CONFIG_ESP32_REV_MAX_FULL=399 685 | CONFIG_ESP_REV_MAX_FULL=399 686 | # end of Chip revision 687 | 688 | # 689 | # MAC Config 690 | # 691 | CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y 692 | CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y 693 | CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y 694 | CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y 695 | CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES_FOUR=y 696 | # CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set 697 | CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y 698 | CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 699 | # CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR is not set 700 | # CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC is not set 701 | # end of MAC Config 702 | 703 | # 704 | # Sleep Config 705 | # 706 | CONFIG_ESP_SLEEP_POWER_DOWN_FLASH=y 707 | CONFIG_ESP_SLEEP_RTC_BUS_ISO_WORKAROUND=y 708 | # CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND is not set 709 | CONFIG_ESP_SLEEP_WAIT_FLASH_READY_EXTRA_DELAY=2000 710 | # CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION is not set 711 | # CONFIG_ESP_SLEEP_DEBUG is not set 712 | CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS=y 713 | # end of Sleep Config 714 | 715 | # 716 | # RTC Clock Config 717 | # 718 | CONFIG_RTC_CLK_SRC_INT_RC=y 719 | # CONFIG_RTC_CLK_SRC_EXT_CRYS is not set 720 | # CONFIG_RTC_CLK_SRC_EXT_OSC is not set 721 | # CONFIG_RTC_CLK_SRC_INT_8MD256 is not set 722 | CONFIG_RTC_CLK_CAL_CYCLES=1024 723 | # end of RTC Clock Config 724 | 725 | # 726 | # Peripheral Control 727 | # 728 | CONFIG_PERIPH_CTRL_FUNC_IN_IRAM=y 729 | # end of Peripheral Control 730 | 731 | # 732 | # Main XTAL Config 733 | # 734 | # CONFIG_XTAL_FREQ_26 is not set 735 | CONFIG_XTAL_FREQ_40=y 736 | # CONFIG_XTAL_FREQ_AUTO is not set 737 | CONFIG_XTAL_FREQ=40 738 | # end of Main XTAL Config 739 | # end of Hardware Settings 740 | 741 | # 742 | # LCD and Touch Panel 743 | # 744 | 745 | # 746 | # LCD Touch Drivers are maintained in the IDF Component Registry 747 | # 748 | 749 | # 750 | # LCD Peripheral Configuration 751 | # 752 | CONFIG_LCD_PANEL_IO_FORMAT_BUF_SIZE=32 753 | # CONFIG_LCD_ENABLE_DEBUG_LOG is not set 754 | # end of LCD Peripheral Configuration 755 | # end of LCD and Touch Panel 756 | 757 | # 758 | # ESP NETIF Adapter 759 | # 760 | CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 761 | CONFIG_ESP_NETIF_TCPIP_LWIP=y 762 | # CONFIG_ESP_NETIF_LOOPBACK is not set 763 | CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y 764 | # CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set 765 | # CONFIG_ESP_NETIF_L2_TAP is not set 766 | # CONFIG_ESP_NETIF_BRIDGE_EN is not set 767 | # end of ESP NETIF Adapter 768 | 769 | # 770 | # Partition API Configuration 771 | # 772 | # end of Partition API Configuration 773 | 774 | # 775 | # PHY 776 | # 777 | CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y 778 | # CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set 779 | CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 780 | CONFIG_ESP_PHY_MAX_TX_POWER=20 781 | CONFIG_ESP_PHY_REDUCE_TX_POWER=y 782 | CONFIG_ESP_PHY_RF_CAL_PARTIAL=y 783 | # CONFIG_ESP_PHY_RF_CAL_NONE is not set 784 | # CONFIG_ESP_PHY_RF_CAL_FULL is not set 785 | CONFIG_ESP_PHY_CALIBRATION_MODE=0 786 | # CONFIG_ESP_PHY_PLL_TRACK_DEBUG is not set 787 | # end of PHY 788 | 789 | # 790 | # Power Management 791 | # 792 | # CONFIG_PM_ENABLE is not set 793 | # end of Power Management 794 | 795 | # 796 | # ESP PSRAM 797 | # 798 | # CONFIG_SPIRAM is not set 799 | # end of ESP PSRAM 800 | 801 | # 802 | # ESP Ringbuf 803 | # 804 | # CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH is not set 805 | # end of ESP Ringbuf 806 | 807 | # 808 | # ESP System Settings 809 | # 810 | # CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set 811 | CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y 812 | # CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set 813 | CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160 814 | 815 | # 816 | # Memory 817 | # 818 | # CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set 819 | 820 | # 821 | # Non-backward compatible options 822 | # 823 | # CONFIG_ESP_SYSTEM_ESP32_SRAM1_REGION_AS_IRAM is not set 824 | # end of Non-backward compatible options 825 | # end of Memory 826 | 827 | # 828 | # Trace memory 829 | # 830 | # CONFIG_ESP32_TRAX is not set 831 | CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 832 | # end of Trace memory 833 | 834 | # CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set 835 | CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y 836 | # CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set 837 | # CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set 838 | CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0 839 | 840 | # 841 | # Memory protection 842 | # 843 | # end of Memory protection 844 | 845 | CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 846 | CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 847 | CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 848 | CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y 849 | # CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set 850 | # CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set 851 | CONFIG_ESP_MAIN_TASK_AFFINITY=0x0 852 | CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 853 | CONFIG_ESP_CONSOLE_UART_DEFAULT=y 854 | # CONFIG_ESP_CONSOLE_UART_CUSTOM is not set 855 | # CONFIG_ESP_CONSOLE_NONE is not set 856 | CONFIG_ESP_CONSOLE_UART=y 857 | CONFIG_ESP_CONSOLE_UART_NUM=0 858 | CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 859 | CONFIG_ESP_INT_WDT=y 860 | CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 861 | CONFIG_ESP_INT_WDT_CHECK_CPU1=y 862 | CONFIG_ESP_TASK_WDT_EN=y 863 | CONFIG_ESP_TASK_WDT_INIT=y 864 | # CONFIG_ESP_TASK_WDT_PANIC is not set 865 | CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 866 | CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y 867 | CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y 868 | # CONFIG_ESP_PANIC_HANDLER_IRAM is not set 869 | # CONFIG_ESP_DEBUG_STUBS_ENABLE is not set 870 | CONFIG_ESP_DEBUG_OCDAWARE=y 871 | # CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_5 is not set 872 | CONFIG_ESP_SYSTEM_CHECK_INT_LEVEL_4=y 873 | 874 | # 875 | # Brownout Detector 876 | # 877 | CONFIG_ESP_BROWNOUT_DET=y 878 | CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0=y 879 | # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_1 is not set 880 | # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_2 is not set 881 | # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_3 is not set 882 | # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_4 is not set 883 | # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_5 is not set 884 | # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_6 is not set 885 | # CONFIG_ESP_BROWNOUT_DET_LVL_SEL_7 is not set 886 | CONFIG_ESP_BROWNOUT_DET_LVL=0 887 | # end of Brownout Detector 888 | 889 | # CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set 890 | CONFIG_ESP_SYSTEM_BROWNOUT_INTR=y 891 | # end of ESP System Settings 892 | 893 | # 894 | # IPC (Inter-Processor Call) 895 | # 896 | CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 897 | CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y 898 | CONFIG_ESP_IPC_ISR_ENABLE=y 899 | # end of IPC (Inter-Processor Call) 900 | 901 | # 902 | # High resolution timer (esp_timer) 903 | # 904 | # CONFIG_ESP_TIMER_PROFILING is not set 905 | CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y 906 | CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y 907 | CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 908 | CONFIG_ESP_TIMER_INTERRUPT_LEVEL=1 909 | # CONFIG_ESP_TIMER_SHOW_EXPERIMENTAL is not set 910 | CONFIG_ESP_TIMER_TASK_AFFINITY=0x0 911 | CONFIG_ESP_TIMER_TASK_AFFINITY_CPU0=y 912 | CONFIG_ESP_TIMER_ISR_AFFINITY=0x1 913 | CONFIG_ESP_TIMER_ISR_AFFINITY_CPU0=y 914 | # CONFIG_ESP_TIMER_SUPPORTS_ISR_DISPATCH_METHOD is not set 915 | CONFIG_ESP_TIMER_IMPL_TG0_LAC=y 916 | # end of High resolution timer (esp_timer) 917 | 918 | # 919 | # Wi-Fi 920 | # 921 | CONFIG_ESP_WIFI_ENABLED=y 922 | CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=10 923 | CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=16 924 | # CONFIG_ESP_WIFI_STATIC_TX_BUFFER is not set 925 | CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y 926 | CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1 927 | CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=16 928 | CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y 929 | # CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set 930 | CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0 931 | CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5 932 | # CONFIG_ESP_WIFI_CSI_ENABLED is not set 933 | CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y 934 | CONFIG_ESP_WIFI_TX_BA_WIN=6 935 | CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y 936 | CONFIG_ESP_WIFI_RX_BA_WIN=6 937 | CONFIG_ESP_WIFI_NVS_ENABLED=y 938 | CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y 939 | # CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set 940 | CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752 941 | CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32 942 | CONFIG_ESP_WIFI_IRAM_OPT=y 943 | # CONFIG_ESP_WIFI_EXTRA_IRAM_OPT is not set 944 | CONFIG_ESP_WIFI_RX_IRAM_OPT=y 945 | CONFIG_ESP_WIFI_ENABLE_WPA3_SAE=y 946 | CONFIG_ESP_WIFI_ENABLE_SAE_PK=y 947 | CONFIG_ESP_WIFI_SOFTAP_SAE_SUPPORT=y 948 | CONFIG_ESP_WIFI_ENABLE_WPA3_OWE_STA=y 949 | # CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set 950 | CONFIG_ESP_WIFI_SLP_DEFAULT_MIN_ACTIVE_TIME=50 951 | CONFIG_ESP_WIFI_SLP_DEFAULT_MAX_ACTIVE_TIME=10 952 | CONFIG_ESP_WIFI_SLP_DEFAULT_WAIT_BROADCAST_DATA_TIME=15 953 | # CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set 954 | # CONFIG_ESP_WIFI_GMAC_SUPPORT is not set 955 | CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y 956 | # CONFIG_ESP_WIFI_SLP_BEACON_LOST_OPT is not set 957 | CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=7 958 | # CONFIG_ESP_WIFI_NAN_ENABLE is not set 959 | CONFIG_ESP_WIFI_MBEDTLS_CRYPTO=y 960 | CONFIG_ESP_WIFI_MBEDTLS_TLS_CLIENT=y 961 | # CONFIG_ESP_WIFI_WAPI_PSK is not set 962 | # CONFIG_ESP_WIFI_11KV_SUPPORT is not set 963 | # CONFIG_ESP_WIFI_MBO_SUPPORT is not set 964 | # CONFIG_ESP_WIFI_DPP_SUPPORT is not set 965 | # CONFIG_ESP_WIFI_11R_SUPPORT is not set 966 | # CONFIG_ESP_WIFI_WPS_SOFTAP_REGISTRAR is not set 967 | 968 | # 969 | # WPS Configuration Options 970 | # 971 | # CONFIG_ESP_WIFI_WPS_STRICT is not set 972 | # CONFIG_ESP_WIFI_WPS_PASSPHRASE is not set 973 | # end of WPS Configuration Options 974 | 975 | # CONFIG_ESP_WIFI_DEBUG_PRINT is not set 976 | # CONFIG_ESP_WIFI_TESTING_OPTIONS is not set 977 | CONFIG_ESP_WIFI_ENTERPRISE_SUPPORT=y 978 | # CONFIG_ESP_WIFI_ENT_FREE_DYNAMIC_BUFFER is not set 979 | # end of Wi-Fi 980 | 981 | # 982 | # Core dump 983 | # 984 | # CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set 985 | # CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set 986 | CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y 987 | # end of Core dump 988 | 989 | # 990 | # FAT Filesystem support 991 | # 992 | CONFIG_FATFS_VOLUME_COUNT=2 993 | CONFIG_FATFS_LFN_NONE=y 994 | # CONFIG_FATFS_LFN_HEAP is not set 995 | # CONFIG_FATFS_LFN_STACK is not set 996 | # CONFIG_FATFS_SECTOR_512 is not set 997 | CONFIG_FATFS_SECTOR_4096=y 998 | # CONFIG_FATFS_CODEPAGE_DYNAMIC is not set 999 | CONFIG_FATFS_CODEPAGE_437=y 1000 | # CONFIG_FATFS_CODEPAGE_720 is not set 1001 | # CONFIG_FATFS_CODEPAGE_737 is not set 1002 | # CONFIG_FATFS_CODEPAGE_771 is not set 1003 | # CONFIG_FATFS_CODEPAGE_775 is not set 1004 | # CONFIG_FATFS_CODEPAGE_850 is not set 1005 | # CONFIG_FATFS_CODEPAGE_852 is not set 1006 | # CONFIG_FATFS_CODEPAGE_855 is not set 1007 | # CONFIG_FATFS_CODEPAGE_857 is not set 1008 | # CONFIG_FATFS_CODEPAGE_860 is not set 1009 | # CONFIG_FATFS_CODEPAGE_861 is not set 1010 | # CONFIG_FATFS_CODEPAGE_862 is not set 1011 | # CONFIG_FATFS_CODEPAGE_863 is not set 1012 | # CONFIG_FATFS_CODEPAGE_864 is not set 1013 | # CONFIG_FATFS_CODEPAGE_865 is not set 1014 | # CONFIG_FATFS_CODEPAGE_866 is not set 1015 | # CONFIG_FATFS_CODEPAGE_869 is not set 1016 | # CONFIG_FATFS_CODEPAGE_932 is not set 1017 | # CONFIG_FATFS_CODEPAGE_936 is not set 1018 | # CONFIG_FATFS_CODEPAGE_949 is not set 1019 | # CONFIG_FATFS_CODEPAGE_950 is not set 1020 | CONFIG_FATFS_CODEPAGE=437 1021 | CONFIG_FATFS_FS_LOCK=0 1022 | CONFIG_FATFS_TIMEOUT_MS=10000 1023 | CONFIG_FATFS_PER_FILE_CACHE=y 1024 | # CONFIG_FATFS_USE_FASTSEEK is not set 1025 | CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0 1026 | # CONFIG_FATFS_IMMEDIATE_FSYNC is not set 1027 | # end of FAT Filesystem support 1028 | 1029 | # 1030 | # FreeRTOS 1031 | # 1032 | 1033 | # 1034 | # Kernel 1035 | # 1036 | # CONFIG_FREERTOS_SMP is not set 1037 | # CONFIG_FREERTOS_UNICORE is not set 1038 | CONFIG_FREERTOS_HZ=100 1039 | # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set 1040 | # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set 1041 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y 1042 | CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 1043 | CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 1044 | # CONFIG_FREERTOS_USE_IDLE_HOOK is not set 1045 | # CONFIG_FREERTOS_USE_TICK_HOOK is not set 1046 | CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 1047 | # CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY is not set 1048 | CONFIG_FREERTOS_TIMER_SERVICE_TASK_NAME="Tmr Svc" 1049 | CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 1050 | CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 1051 | CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 1052 | CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 1053 | CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=1 1054 | # CONFIG_FREERTOS_USE_TRACE_FACILITY is not set 1055 | # CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set 1056 | # CONFIG_FREERTOS_USE_APPLICATION_TASK_TAG is not set 1057 | # end of Kernel 1058 | 1059 | # 1060 | # Port 1061 | # 1062 | CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y 1063 | # CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set 1064 | CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS=y 1065 | # CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK is not set 1066 | # CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set 1067 | CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y 1068 | CONFIG_FREERTOS_ISR_STACKSIZE=1536 1069 | CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y 1070 | # CONFIG_FREERTOS_FPU_IN_ISR is not set 1071 | CONFIG_FREERTOS_TICK_SUPPORT_CORETIMER=y 1072 | CONFIG_FREERTOS_CORETIMER_0=y 1073 | # CONFIG_FREERTOS_CORETIMER_1 is not set 1074 | CONFIG_FREERTOS_SYSTICK_USES_CCOUNT=y 1075 | # CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set 1076 | # CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set 1077 | # end of Port 1078 | 1079 | CONFIG_FREERTOS_PORT=y 1080 | CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF 1081 | CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y 1082 | CONFIG_FREERTOS_DEBUG_OCDAWARE=y 1083 | CONFIG_FREERTOS_ENABLE_TASK_SNAPSHOT=y 1084 | CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y 1085 | # end of FreeRTOS 1086 | 1087 | # 1088 | # Hardware Abstraction Layer (HAL) and Low Level (LL) 1089 | # 1090 | CONFIG_HAL_ASSERTION_EQUALS_SYSTEM=y 1091 | # CONFIG_HAL_ASSERTION_DISABLE is not set 1092 | # CONFIG_HAL_ASSERTION_SILENT is not set 1093 | # CONFIG_HAL_ASSERTION_ENABLE is not set 1094 | CONFIG_HAL_DEFAULT_ASSERTION_LEVEL=2 1095 | CONFIG_HAL_SPI_MASTER_FUNC_IN_IRAM=y 1096 | CONFIG_HAL_SPI_SLAVE_FUNC_IN_IRAM=y 1097 | # end of Hardware Abstraction Layer (HAL) and Low Level (LL) 1098 | 1099 | # 1100 | # Heap memory debugging 1101 | # 1102 | CONFIG_HEAP_POISONING_DISABLED=y 1103 | # CONFIG_HEAP_POISONING_LIGHT is not set 1104 | # CONFIG_HEAP_POISONING_COMPREHENSIVE is not set 1105 | CONFIG_HEAP_TRACING_OFF=y 1106 | # CONFIG_HEAP_TRACING_STANDALONE is not set 1107 | # CONFIG_HEAP_TRACING_TOHOST is not set 1108 | # CONFIG_HEAP_USE_HOOKS is not set 1109 | # CONFIG_HEAP_TASK_TRACKING is not set 1110 | # CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set 1111 | # CONFIG_HEAP_PLACE_FUNCTION_INTO_FLASH is not set 1112 | # end of Heap memory debugging 1113 | 1114 | # 1115 | # Log output 1116 | # 1117 | # CONFIG_LOG_DEFAULT_LEVEL_NONE is not set 1118 | # CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set 1119 | # CONFIG_LOG_DEFAULT_LEVEL_WARN is not set 1120 | CONFIG_LOG_DEFAULT_LEVEL_INFO=y 1121 | # CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set 1122 | # CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set 1123 | CONFIG_LOG_DEFAULT_LEVEL=3 1124 | CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y 1125 | # CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set 1126 | # CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set 1127 | CONFIG_LOG_MAXIMUM_LEVEL=3 1128 | # CONFIG_LOG_MASTER_LEVEL is not set 1129 | CONFIG_LOG_COLORS=y 1130 | CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y 1131 | # CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set 1132 | # end of Log output 1133 | 1134 | # 1135 | # LWIP 1136 | # 1137 | CONFIG_LWIP_ENABLE=y 1138 | CONFIG_LWIP_LOCAL_HOSTNAME="espressif" 1139 | # CONFIG_LWIP_NETIF_API is not set 1140 | CONFIG_LWIP_TCPIP_TASK_PRIO=18 1141 | # CONFIG_LWIP_TCPIP_CORE_LOCKING is not set 1142 | # CONFIG_LWIP_CHECK_THREAD_SAFETY is not set 1143 | CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y 1144 | # CONFIG_LWIP_L2_TO_L3_COPY is not set 1145 | # CONFIG_LWIP_IRAM_OPTIMIZATION is not set 1146 | # CONFIG_LWIP_EXTRA_IRAM_OPTIMIZATION is not set 1147 | CONFIG_LWIP_TIMERS_ONDEMAND=y 1148 | CONFIG_LWIP_MAX_SOCKETS=10 1149 | # CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set 1150 | # CONFIG_LWIP_SO_LINGER is not set 1151 | CONFIG_LWIP_SO_REUSE=y 1152 | CONFIG_LWIP_SO_REUSE_RXTOALL=y 1153 | # CONFIG_LWIP_SO_RCVBUF is not set 1154 | # CONFIG_LWIP_NETBUF_RECVINFO is not set 1155 | CONFIG_LWIP_IP_DEFAULT_TTL=64 1156 | CONFIG_LWIP_IP4_FRAG=y 1157 | # CONFIG_LWIP_IP4_REASSEMBLY is not set 1158 | CONFIG_LWIP_IP_REASS_MAX_PBUFS=10 1159 | # CONFIG_LWIP_IP_FORWARD is not set 1160 | # CONFIG_LWIP_STATS is not set 1161 | CONFIG_LWIP_ESP_GRATUITOUS_ARP=y 1162 | CONFIG_LWIP_GARP_TMR_INTERVAL=60 1163 | CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 1164 | CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y 1165 | # CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set 1166 | CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y 1167 | # CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set 1168 | CONFIG_LWIP_DHCP_OPTIONS_LEN=68 1169 | CONFIG_LWIP_NUM_NETIF_CLIENT_DATA=0 1170 | CONFIG_LWIP_DHCP_COARSE_TIMER_SECS=1 1171 | 1172 | # 1173 | # DHCP server 1174 | # 1175 | CONFIG_LWIP_DHCPS=y 1176 | CONFIG_LWIP_DHCPS_LEASE_UNIT=60 1177 | CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 1178 | CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y 1179 | # end of DHCP server 1180 | 1181 | # CONFIG_LWIP_AUTOIP is not set 1182 | CONFIG_LWIP_IPV4=y 1183 | # CONFIG_LWIP_IPV6 is not set 1184 | # CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set 1185 | CONFIG_LWIP_NETIF_LOOPBACK=y 1186 | CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 1187 | 1188 | # 1189 | # TCP 1190 | # 1191 | CONFIG_LWIP_MAX_ACTIVE_TCP=16 1192 | CONFIG_LWIP_MAX_LISTENING_TCP=16 1193 | CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y 1194 | CONFIG_LWIP_TCP_MAXRTX=12 1195 | CONFIG_LWIP_TCP_SYNMAXRTX=12 1196 | CONFIG_LWIP_TCP_MSS=1440 1197 | CONFIG_LWIP_TCP_TMR_INTERVAL=250 1198 | CONFIG_LWIP_TCP_MSL=60000 1199 | CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 1200 | CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 1201 | CONFIG_LWIP_TCP_WND_DEFAULT=5744 1202 | CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 1203 | CONFIG_LWIP_TCP_QUEUE_OOSEQ=y 1204 | CONFIG_LWIP_TCP_OOSEQ_TIMEOUT=6 1205 | CONFIG_LWIP_TCP_OOSEQ_MAX_PBUFS=4 1206 | # CONFIG_LWIP_TCP_SACK_OUT is not set 1207 | CONFIG_LWIP_TCP_OVERSIZE_MSS=y 1208 | # CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set 1209 | # CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set 1210 | CONFIG_LWIP_TCP_RTO_TIME=1500 1211 | # end of TCP 1212 | 1213 | # 1214 | # UDP 1215 | # 1216 | CONFIG_LWIP_MAX_UDP_PCBS=16 1217 | CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 1218 | # end of UDP 1219 | 1220 | # 1221 | # Checksums 1222 | # 1223 | # CONFIG_LWIP_CHECKSUM_CHECK_IP is not set 1224 | # CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set 1225 | CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y 1226 | # end of Checksums 1227 | 1228 | CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 1229 | CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y 1230 | # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set 1231 | # CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set 1232 | CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF 1233 | # CONFIG_LWIP_PPP_SUPPORT is not set 1234 | # CONFIG_LWIP_SLIP_SUPPORT is not set 1235 | 1236 | # 1237 | # ICMP 1238 | # 1239 | CONFIG_LWIP_ICMP=y 1240 | # CONFIG_LWIP_MULTICAST_PING is not set 1241 | # CONFIG_LWIP_BROADCAST_PING is not set 1242 | # end of ICMP 1243 | 1244 | # 1245 | # LWIP RAW API 1246 | # 1247 | CONFIG_LWIP_MAX_RAW_PCBS=16 1248 | # end of LWIP RAW API 1249 | 1250 | # 1251 | # SNTP 1252 | # 1253 | CONFIG_LWIP_SNTP_MAX_SERVERS=1 1254 | # CONFIG_LWIP_DHCP_GET_NTP_SRV is not set 1255 | CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 1256 | # end of SNTP 1257 | 1258 | # 1259 | # DNS 1260 | # 1261 | CONFIG_LWIP_DNS_MAX_SERVERS=3 1262 | # CONFIG_LWIP_FALLBACK_DNS_SERVER_SUPPORT is not set 1263 | # end of DNS 1264 | 1265 | CONFIG_LWIP_BRIDGEIF_MAX_PORTS=7 1266 | CONFIG_LWIP_ESP_LWIP_ASSERT=y 1267 | 1268 | # 1269 | # Hooks 1270 | # 1271 | # CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set 1272 | CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y 1273 | # CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set 1274 | CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y 1275 | # CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set 1276 | # CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set 1277 | # end of Hooks 1278 | 1279 | # CONFIG_LWIP_DEBUG is not set 1280 | # end of LWIP 1281 | 1282 | # 1283 | # mbedTLS 1284 | # 1285 | CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y 1286 | # CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set 1287 | # CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set 1288 | CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y 1289 | CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 1290 | CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 1291 | # CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set 1292 | # CONFIG_MBEDTLS_DEBUG is not set 1293 | 1294 | # 1295 | # mbedTLS v3.x related 1296 | # 1297 | # CONFIG_MBEDTLS_SSL_PROTO_TLS1_3 is not set 1298 | # CONFIG_MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH is not set 1299 | # CONFIG_MBEDTLS_X509_TRUSTED_CERT_CALLBACK is not set 1300 | # CONFIG_MBEDTLS_SSL_CONTEXT_SERIALIZATION is not set 1301 | CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=y 1302 | CONFIG_MBEDTLS_PKCS7_C=y 1303 | # end of mbedTLS v3.x related 1304 | 1305 | # 1306 | # Certificate Bundle 1307 | # 1308 | CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y 1309 | CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y 1310 | # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set 1311 | # CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set 1312 | # CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set 1313 | CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_MAX_CERTS=200 1314 | # end of Certificate Bundle 1315 | 1316 | # CONFIG_MBEDTLS_ECP_RESTARTABLE is not set 1317 | CONFIG_MBEDTLS_CMAC_C=y 1318 | CONFIG_MBEDTLS_HARDWARE_AES=y 1319 | # CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER is not set 1320 | CONFIG_MBEDTLS_HARDWARE_MPI=y 1321 | # CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set 1322 | CONFIG_MBEDTLS_HARDWARE_SHA=y 1323 | CONFIG_MBEDTLS_ROM_MD5=y 1324 | # CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set 1325 | # CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set 1326 | CONFIG_MBEDTLS_HAVE_TIME=y 1327 | # CONFIG_MBEDTLS_PLATFORM_TIME_ALT is not set 1328 | # CONFIG_MBEDTLS_HAVE_TIME_DATE is not set 1329 | CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y 1330 | CONFIG_MBEDTLS_SHA512_C=y 1331 | CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y 1332 | # CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set 1333 | # CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set 1334 | # CONFIG_MBEDTLS_TLS_DISABLED is not set 1335 | CONFIG_MBEDTLS_TLS_SERVER=y 1336 | CONFIG_MBEDTLS_TLS_CLIENT=y 1337 | CONFIG_MBEDTLS_TLS_ENABLED=y 1338 | 1339 | # 1340 | # TLS Key Exchange Methods 1341 | # 1342 | # CONFIG_MBEDTLS_PSK_MODES is not set 1343 | CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y 1344 | CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y 1345 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y 1346 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y 1347 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y 1348 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y 1349 | # end of TLS Key Exchange Methods 1350 | 1351 | CONFIG_MBEDTLS_SSL_RENEGOTIATION=y 1352 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y 1353 | # CONFIG_MBEDTLS_SSL_PROTO_GMTSSL1_1 is not set 1354 | # CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set 1355 | CONFIG_MBEDTLS_SSL_ALPN=y 1356 | CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y 1357 | CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y 1358 | 1359 | # 1360 | # Symmetric Ciphers 1361 | # 1362 | CONFIG_MBEDTLS_AES_C=y 1363 | # CONFIG_MBEDTLS_CAMELLIA_C is not set 1364 | # CONFIG_MBEDTLS_DES_C is not set 1365 | # CONFIG_MBEDTLS_BLOWFISH_C is not set 1366 | # CONFIG_MBEDTLS_XTEA_C is not set 1367 | CONFIG_MBEDTLS_CCM_C=y 1368 | CONFIG_MBEDTLS_GCM_C=y 1369 | # CONFIG_MBEDTLS_NIST_KW_C is not set 1370 | # end of Symmetric Ciphers 1371 | 1372 | # CONFIG_MBEDTLS_RIPEMD160_C is not set 1373 | 1374 | # 1375 | # Certificates 1376 | # 1377 | CONFIG_MBEDTLS_PEM_PARSE_C=y 1378 | CONFIG_MBEDTLS_PEM_WRITE_C=y 1379 | CONFIG_MBEDTLS_X509_CRL_PARSE_C=y 1380 | CONFIG_MBEDTLS_X509_CSR_PARSE_C=y 1381 | # end of Certificates 1382 | 1383 | CONFIG_MBEDTLS_ECP_C=y 1384 | # CONFIG_MBEDTLS_DHM_C is not set 1385 | CONFIG_MBEDTLS_ECDH_C=y 1386 | CONFIG_MBEDTLS_ECDSA_C=y 1387 | # CONFIG_MBEDTLS_ECJPAKE_C is not set 1388 | CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y 1389 | CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y 1390 | CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y 1391 | CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y 1392 | CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y 1393 | CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y 1394 | CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y 1395 | CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y 1396 | CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y 1397 | CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y 1398 | CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y 1399 | CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y 1400 | CONFIG_MBEDTLS_ECP_NIST_OPTIM=y 1401 | CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM=y 1402 | # CONFIG_MBEDTLS_POLY1305_C is not set 1403 | # CONFIG_MBEDTLS_CHACHA20_C is not set 1404 | # CONFIG_MBEDTLS_HKDF_C is not set 1405 | # CONFIG_MBEDTLS_THREADING_C is not set 1406 | CONFIG_MBEDTLS_ERROR_STRINGS=y 1407 | # end of mbedTLS 1408 | 1409 | # 1410 | # ESP-MQTT Configurations 1411 | # 1412 | CONFIG_MQTT_PROTOCOL_311=y 1413 | # CONFIG_MQTT_PROTOCOL_5 is not set 1414 | CONFIG_MQTT_TRANSPORT_SSL=y 1415 | CONFIG_MQTT_TRANSPORT_WEBSOCKET=y 1416 | CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y 1417 | # CONFIG_MQTT_MSG_ID_INCREMENTAL is not set 1418 | # CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set 1419 | # CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set 1420 | # CONFIG_MQTT_USE_CUSTOM_CONFIG is not set 1421 | # CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set 1422 | # CONFIG_MQTT_CUSTOM_OUTBOX is not set 1423 | # end of ESP-MQTT Configurations 1424 | 1425 | # 1426 | # Newlib 1427 | # 1428 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y 1429 | # CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set 1430 | # CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set 1431 | # CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set 1432 | # CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set 1433 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y 1434 | # CONFIG_NEWLIB_NANO_FORMAT is not set 1435 | CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y 1436 | # CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC is not set 1437 | # CONFIG_NEWLIB_TIME_SYSCALL_USE_HRT is not set 1438 | # CONFIG_NEWLIB_TIME_SYSCALL_USE_NONE is not set 1439 | # end of Newlib 1440 | 1441 | # 1442 | # NVS 1443 | # 1444 | # CONFIG_NVS_ASSERT_ERROR_CHECK is not set 1445 | # CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set 1446 | # end of NVS 1447 | 1448 | # 1449 | # OpenThread 1450 | # 1451 | # CONFIG_OPENTHREAD_ENABLED is not set 1452 | 1453 | # 1454 | # Thread Operational Dataset 1455 | # 1456 | CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP" 1457 | CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64" 1458 | CONFIG_OPENTHREAD_NETWORK_CHANNEL=15 1459 | CONFIG_OPENTHREAD_NETWORK_PANID=0x1234 1460 | CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe" 1461 | CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff" 1462 | CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53" 1463 | # end of Thread Operational Dataset 1464 | 1465 | CONFIG_OPENTHREAD_XTAL_ACCURACY=130 1466 | # CONFIG_OPENTHREAD_SPINEL_ONLY is not set 1467 | CONFIG_OPENTHREAD_RX_ON_WHEN_IDLE=y 1468 | 1469 | # 1470 | # Thread Address Query Config 1471 | # 1472 | # end of Thread Address Query Config 1473 | # end of OpenThread 1474 | 1475 | # 1476 | # Protocomm 1477 | # 1478 | CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0=y 1479 | CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1=y 1480 | CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2=y 1481 | # end of Protocomm 1482 | 1483 | # 1484 | # PThreads 1485 | # 1486 | CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 1487 | CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 1488 | CONFIG_PTHREAD_STACK_MIN=768 1489 | CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y 1490 | # CONFIG_PTHREAD_DEFAULT_CORE_0 is not set 1491 | # CONFIG_PTHREAD_DEFAULT_CORE_1 is not set 1492 | CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 1493 | CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" 1494 | # end of PThreads 1495 | 1496 | # 1497 | # MMU Config 1498 | # 1499 | CONFIG_MMU_PAGE_SIZE_64KB=y 1500 | CONFIG_MMU_PAGE_MODE="64KB" 1501 | CONFIG_MMU_PAGE_SIZE=0x10000 1502 | # end of MMU Config 1503 | 1504 | # 1505 | # Main Flash configuration 1506 | # 1507 | 1508 | # 1509 | # SPI Flash behavior when brownout 1510 | # 1511 | CONFIG_SPI_FLASH_BROWNOUT_RESET_XMC=y 1512 | CONFIG_SPI_FLASH_BROWNOUT_RESET=y 1513 | # end of SPI Flash behavior when brownout 1514 | 1515 | # 1516 | # Optional and Experimental Features (READ DOCS FIRST) 1517 | # 1518 | 1519 | # 1520 | # Features here require specific hardware (READ DOCS FIRST!) 1521 | # 1522 | # end of Optional and Experimental Features (READ DOCS FIRST) 1523 | # end of Main Flash configuration 1524 | 1525 | # 1526 | # SPI Flash driver 1527 | # 1528 | # CONFIG_SPI_FLASH_VERIFY_WRITE is not set 1529 | # CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set 1530 | CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y 1531 | CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y 1532 | # CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set 1533 | # CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set 1534 | # CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set 1535 | # CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set 1536 | CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y 1537 | CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 1538 | CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 1539 | CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 1540 | # CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set 1541 | # CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set 1542 | # CONFIG_SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST is not set 1543 | 1544 | # 1545 | # Auto-detect flash chips 1546 | # 1547 | CONFIG_SPI_FLASH_VENDOR_XMC_SUPPORTED=y 1548 | CONFIG_SPI_FLASH_VENDOR_GD_SUPPORTED=y 1549 | CONFIG_SPI_FLASH_VENDOR_ISSI_SUPPORTED=y 1550 | CONFIG_SPI_FLASH_VENDOR_MXIC_SUPPORTED=y 1551 | CONFIG_SPI_FLASH_VENDOR_WINBOND_SUPPORTED=y 1552 | CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y 1553 | CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y 1554 | CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y 1555 | CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y 1556 | # CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP is not set 1557 | # CONFIG_SPI_FLASH_SUPPORT_TH_CHIP is not set 1558 | # end of Auto-detect flash chips 1559 | 1560 | CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y 1561 | # end of SPI Flash driver 1562 | 1563 | # 1564 | # SPIFFS Configuration 1565 | # 1566 | CONFIG_SPIFFS_MAX_PARTITIONS=3 1567 | 1568 | # 1569 | # SPIFFS Cache Configuration 1570 | # 1571 | CONFIG_SPIFFS_CACHE=y 1572 | CONFIG_SPIFFS_CACHE_WR=y 1573 | # CONFIG_SPIFFS_CACHE_STATS is not set 1574 | # end of SPIFFS Cache Configuration 1575 | 1576 | CONFIG_SPIFFS_PAGE_CHECK=y 1577 | CONFIG_SPIFFS_GC_MAX_RUNS=10 1578 | # CONFIG_SPIFFS_GC_STATS is not set 1579 | CONFIG_SPIFFS_PAGE_SIZE=256 1580 | CONFIG_SPIFFS_OBJ_NAME_LEN=32 1581 | # CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set 1582 | CONFIG_SPIFFS_USE_MAGIC=y 1583 | CONFIG_SPIFFS_USE_MAGIC_LENGTH=y 1584 | CONFIG_SPIFFS_META_LENGTH=4 1585 | CONFIG_SPIFFS_USE_MTIME=y 1586 | 1587 | # 1588 | # Debug Configuration 1589 | # 1590 | # CONFIG_SPIFFS_DBG is not set 1591 | # CONFIG_SPIFFS_API_DBG is not set 1592 | # CONFIG_SPIFFS_GC_DBG is not set 1593 | # CONFIG_SPIFFS_CACHE_DBG is not set 1594 | # CONFIG_SPIFFS_CHECK_DBG is not set 1595 | # CONFIG_SPIFFS_TEST_VISUALISATION is not set 1596 | # end of Debug Configuration 1597 | # end of SPIFFS Configuration 1598 | 1599 | # 1600 | # TCP Transport 1601 | # 1602 | 1603 | # 1604 | # Websocket 1605 | # 1606 | CONFIG_WS_TRANSPORT=y 1607 | CONFIG_WS_BUFFER_SIZE=1024 1608 | # CONFIG_WS_DYNAMIC_BUFFER is not set 1609 | # end of Websocket 1610 | # end of TCP Transport 1611 | 1612 | # 1613 | # Ultra Low Power (ULP) Co-processor 1614 | # 1615 | # CONFIG_ULP_COPROC_ENABLED is not set 1616 | # end of Ultra Low Power (ULP) Co-processor 1617 | 1618 | # 1619 | # Unity unit testing library 1620 | # 1621 | CONFIG_UNITY_ENABLE_FLOAT=y 1622 | CONFIG_UNITY_ENABLE_DOUBLE=y 1623 | # CONFIG_UNITY_ENABLE_64BIT is not set 1624 | # CONFIG_UNITY_ENABLE_COLOR is not set 1625 | CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y 1626 | # CONFIG_UNITY_ENABLE_FIXTURE is not set 1627 | # CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set 1628 | # end of Unity unit testing library 1629 | 1630 | # 1631 | # Virtual file system 1632 | # 1633 | CONFIG_VFS_SUPPORT_IO=y 1634 | CONFIG_VFS_SUPPORT_DIR=y 1635 | CONFIG_VFS_SUPPORT_SELECT=y 1636 | CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y 1637 | # CONFIG_VFS_SELECT_IN_RAM is not set 1638 | CONFIG_VFS_SUPPORT_TERMIOS=y 1639 | CONFIG_VFS_MAX_COUNT=8 1640 | 1641 | # 1642 | # Host File System I/O (Semihosting) 1643 | # 1644 | CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 1645 | # end of Host File System I/O (Semihosting) 1646 | # end of Virtual file system 1647 | 1648 | # 1649 | # Wear Levelling 1650 | # 1651 | # CONFIG_WL_SECTOR_SIZE_512 is not set 1652 | CONFIG_WL_SECTOR_SIZE_4096=y 1653 | CONFIG_WL_SECTOR_SIZE=4096 1654 | # end of Wear Levelling 1655 | 1656 | # 1657 | # Wi-Fi Provisioning Manager 1658 | # 1659 | CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 1660 | CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 1661 | CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION=y 1662 | CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y 1663 | # CONFIG_WIFI_PROV_STA_FAST_SCAN is not set 1664 | # end of Wi-Fi Provisioning Manager 1665 | 1666 | # 1667 | # ESP WebSocket client 1668 | # 1669 | # CONFIG_ESP_WS_CLIENT_ENABLE_DYNAMIC_BUFFER is not set 1670 | # end of ESP WebSocket client 1671 | # end of Component config 1672 | 1673 | # CONFIG_IDF_EXPERIMENTAL_FEATURES is not set 1674 | 1675 | # Deprecated options for backward compatibility 1676 | # CONFIG_APP_BUILD_TYPE_ELF_RAM is not set 1677 | # CONFIG_NO_BLOBS is not set 1678 | # CONFIG_ESP32_NO_BLOBS is not set 1679 | # CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set 1680 | # CONFIG_ESP32_COMPATIBLE_PRE_V3_1_BOOTLOADERS is not set 1681 | # CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set 1682 | # CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set 1683 | # CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set 1684 | CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y 1685 | # CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set 1686 | # CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set 1687 | CONFIG_LOG_BOOTLOADER_LEVEL=3 1688 | # CONFIG_APP_ROLLBACK_ENABLE is not set 1689 | # CONFIG_FLASH_ENCRYPTION_ENABLED is not set 1690 | # CONFIG_FLASHMODE_QIO is not set 1691 | # CONFIG_FLASHMODE_QOUT is not set 1692 | CONFIG_FLASHMODE_DIO=y 1693 | # CONFIG_FLASHMODE_DOUT is not set 1694 | CONFIG_MONITOR_BAUD=115200 1695 | CONFIG_OPTIMIZATION_LEVEL_DEBUG=y 1696 | CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y 1697 | CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y 1698 | # CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set 1699 | # CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set 1700 | CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y 1701 | # CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set 1702 | # CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set 1703 | CONFIG_OPTIMIZATION_ASSERTION_LEVEL=2 1704 | # CONFIG_CXX_EXCEPTIONS is not set 1705 | CONFIG_STACK_CHECK_NONE=y 1706 | # CONFIG_STACK_CHECK_NORM is not set 1707 | # CONFIG_STACK_CHECK_STRONG is not set 1708 | # CONFIG_STACK_CHECK_ALL is not set 1709 | # CONFIG_WARN_WRITE_STRINGS is not set 1710 | # CONFIG_ESP32_APPTRACE_DEST_TRAX is not set 1711 | CONFIG_ESP32_APPTRACE_DEST_NONE=y 1712 | CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y 1713 | CONFIG_ADC2_DISABLE_DAC=y 1714 | # CONFIG_MCPWM_ISR_IN_IRAM is not set 1715 | # CONFIG_EVENT_LOOP_PROFILING is not set 1716 | CONFIG_POST_EVENTS_FROM_ISR=y 1717 | CONFIG_POST_EVENTS_FROM_IRAM_ISR=y 1718 | CONFIG_GDBSTUB_SUPPORT_TASKS=y 1719 | CONFIG_GDBSTUB_MAX_TASKS=32 1720 | CONFIG_OTA_ALLOW_HTTP=y 1721 | # CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set 1722 | CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y 1723 | CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 1724 | CONFIG_ESP_SYSTEM_PD_FLASH=y 1725 | CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 1726 | CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY=2000 1727 | CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y 1728 | CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y 1729 | # CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set 1730 | # CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set 1731 | # CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set 1732 | # CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set 1733 | # CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set 1734 | # CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set 1735 | CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 1736 | # CONFIG_ESP32_XTAL_FREQ_26 is not set 1737 | CONFIG_ESP32_XTAL_FREQ_40=y 1738 | # CONFIG_ESP32_XTAL_FREQ_AUTO is not set 1739 | CONFIG_ESP32_XTAL_FREQ=40 1740 | CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y 1741 | # CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set 1742 | CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 1743 | CONFIG_ESP32_PHY_MAX_TX_POWER=20 1744 | CONFIG_REDUCE_PHY_TX_POWER=y 1745 | CONFIG_ESP32_REDUCE_PHY_TX_POWER=y 1746 | # CONFIG_SPIRAM_SUPPORT is not set 1747 | # CONFIG_ESP32_SPIRAM_SUPPORT is not set 1748 | # CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set 1749 | CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y 1750 | # CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set 1751 | CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 1752 | CONFIG_TRACEMEM_RESERVE_DRAM=0x0 1753 | # CONFIG_ESP32_PANIC_PRINT_HALT is not set 1754 | CONFIG_ESP32_PANIC_PRINT_REBOOT=y 1755 | # CONFIG_ESP32_PANIC_SILENT_REBOOT is not set 1756 | # CONFIG_ESP32_PANIC_GDBSTUB is not set 1757 | CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 1758 | CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 1759 | CONFIG_MAIN_TASK_STACK_SIZE=3584 1760 | CONFIG_CONSOLE_UART_DEFAULT=y 1761 | # CONFIG_CONSOLE_UART_CUSTOM is not set 1762 | # CONFIG_CONSOLE_UART_NONE is not set 1763 | # CONFIG_ESP_CONSOLE_UART_NONE is not set 1764 | CONFIG_CONSOLE_UART=y 1765 | CONFIG_CONSOLE_UART_NUM=0 1766 | CONFIG_CONSOLE_UART_BAUDRATE=115200 1767 | CONFIG_INT_WDT=y 1768 | CONFIG_INT_WDT_TIMEOUT_MS=300 1769 | CONFIG_INT_WDT_CHECK_CPU1=y 1770 | CONFIG_TASK_WDT=y 1771 | CONFIG_ESP_TASK_WDT=y 1772 | # CONFIG_TASK_WDT_PANIC is not set 1773 | CONFIG_TASK_WDT_TIMEOUT_S=5 1774 | CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y 1775 | CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y 1776 | # CONFIG_ESP32_DEBUG_STUBS_ENABLE is not set 1777 | CONFIG_ESP32_DEBUG_OCDAWARE=y 1778 | CONFIG_BROWNOUT_DET=y 1779 | CONFIG_ESP32_BROWNOUT_DET=y 1780 | CONFIG_BROWNOUT_DET_LVL_SEL_0=y 1781 | CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y 1782 | # CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set 1783 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set 1784 | # CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set 1785 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set 1786 | # CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set 1787 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set 1788 | # CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set 1789 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set 1790 | # CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set 1791 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set 1792 | # CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set 1793 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set 1794 | # CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set 1795 | # CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set 1796 | CONFIG_BROWNOUT_DET_LVL=0 1797 | CONFIG_ESP32_BROWNOUT_DET_LVL=0 1798 | # CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set 1799 | CONFIG_IPC_TASK_STACK_SIZE=1024 1800 | CONFIG_TIMER_TASK_STACK_SIZE=3584 1801 | CONFIG_ESP32_WIFI_ENABLED=y 1802 | CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 1803 | CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=16 1804 | # CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set 1805 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y 1806 | CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 1807 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=16 1808 | # CONFIG_ESP32_WIFI_CSI_ENABLED is not set 1809 | CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y 1810 | CONFIG_ESP32_WIFI_TX_BA_WIN=6 1811 | CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y 1812 | CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y 1813 | CONFIG_ESP32_WIFI_RX_BA_WIN=6 1814 | CONFIG_ESP32_WIFI_RX_BA_WIN=6 1815 | CONFIG_ESP32_WIFI_NVS_ENABLED=y 1816 | CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y 1817 | # CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set 1818 | CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 1819 | CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 1820 | CONFIG_ESP32_WIFI_IRAM_OPT=y 1821 | CONFIG_ESP32_WIFI_RX_IRAM_OPT=y 1822 | CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y 1823 | CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y 1824 | CONFIG_WPA_MBEDTLS_CRYPTO=y 1825 | CONFIG_WPA_MBEDTLS_TLS_CLIENT=y 1826 | # CONFIG_WPA_WAPI_PSK is not set 1827 | # CONFIG_WPA_11KV_SUPPORT is not set 1828 | # CONFIG_WPA_MBO_SUPPORT is not set 1829 | # CONFIG_WPA_DPP_SUPPORT is not set 1830 | # CONFIG_WPA_11R_SUPPORT is not set 1831 | # CONFIG_WPA_WPS_SOFTAP_REGISTRAR is not set 1832 | # CONFIG_WPA_WPS_STRICT is not set 1833 | # CONFIG_WPA_DEBUG_PRINT is not set 1834 | # CONFIG_WPA_TESTING_OPTIONS is not set 1835 | # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set 1836 | # CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set 1837 | CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y 1838 | CONFIG_TIMER_TASK_PRIORITY=1 1839 | CONFIG_TIMER_TASK_STACK_DEPTH=2048 1840 | CONFIG_TIMER_QUEUE_LENGTH=10 1841 | # CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set 1842 | # CONFIG_HAL_ASSERTION_SILIENT is not set 1843 | # CONFIG_L2_TO_L3_COPY is not set 1844 | CONFIG_ESP_GRATUITOUS_ARP=y 1845 | CONFIG_GARP_TMR_INTERVAL=60 1846 | CONFIG_TCPIP_RECVMBOX_SIZE=32 1847 | CONFIG_TCP_MAXRTX=12 1848 | CONFIG_TCP_SYNMAXRTX=12 1849 | CONFIG_TCP_MSS=1440 1850 | CONFIG_TCP_MSL=60000 1851 | CONFIG_TCP_SND_BUF_DEFAULT=5744 1852 | CONFIG_TCP_WND_DEFAULT=5744 1853 | CONFIG_TCP_RECVMBOX_SIZE=6 1854 | CONFIG_TCP_QUEUE_OOSEQ=y 1855 | CONFIG_TCP_OVERSIZE_MSS=y 1856 | # CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set 1857 | # CONFIG_TCP_OVERSIZE_DISABLE is not set 1858 | CONFIG_UDP_RECVMBOX_SIZE=6 1859 | CONFIG_TCPIP_TASK_STACK_SIZE=3072 1860 | CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y 1861 | # CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set 1862 | # CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set 1863 | CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF 1864 | # CONFIG_PPP_SUPPORT is not set 1865 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC_HRT=y 1866 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y 1867 | # CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set 1868 | # CONFIG_ESP32_TIME_SYSCALL_USE_HRT is not set 1869 | # CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set 1870 | # CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set 1871 | CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 1872 | CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 1873 | CONFIG_ESP32_PTHREAD_STACK_MIN=768 1874 | CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y 1875 | # CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set 1876 | # CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set 1877 | CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 1878 | CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" 1879 | CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y 1880 | # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set 1881 | # CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set 1882 | # CONFIG_ESP32_ULP_COPROC_ENABLED is not set 1883 | CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y 1884 | CONFIG_SUPPORT_TERMIOS=y 1885 | CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 1886 | # End of deprecated options 1887 | --------------------------------------------------------------------------------