From 97adcec80ec0f31809120e346b221df8f788d2e5 Mon Sep 17 00:00:00 2001
From: jomjol <30766535+jomjol@users.noreply.github.com>
Date: Thu, 10 Sep 2020 22:03:28 +0200
Subject: [PATCH] Update Rolling
DELETE ALL
Restructure CTfLiteAll
---
README.md | 2 +
.../lib/jomjol_fileserver_ota/server_file.cpp | 31 +-
code/lib/jomjol_image_proc/CFindTemplate._h_ | 87 ---
.../lib/jomjol_image_proc/CFindTemplate.cp__p | 366 ------------
.../jomjol_tfliteclass/CTfLiteClass._cpp_old | 254 ++++++++
.../jomjol_tfliteclass/CTfLiteClass._h_old | 72 +++
code/lib/jomjol_tfliteclass/CTfLiteClass.cpp | 44 +-
code/lib/jomjol_tfliteclass/CTfLiteClass.h | 39 +-
code/sdkconfig | 4 +-
code/sdkconfig.old | 565 ++++++++++++++++++
firmware/bootloader.bin | Bin 26448 -> 26448 bytes
firmware/firmware.bin | Bin 1633424 -> 1632704 bytes
firmware/html.zip | Bin 34289 -> 34301 bytes
sd-card/html/gethost.js | 13 +-
sd-card/html/readconfig.js | 4 +
sd-card/html/upload_script.html | 41 +-
16 files changed, 976 insertions(+), 546 deletions(-)
delete mode 100644 code/lib/jomjol_image_proc/CFindTemplate._h_
delete mode 100644 code/lib/jomjol_image_proc/CFindTemplate.cp__p
create mode 100644 code/lib/jomjol_tfliteclass/CTfLiteClass._cpp_old
create mode 100644 code/lib/jomjol_tfliteclass/CTfLiteClass._h_old
create mode 100644 code/sdkconfig.old
diff --git a/README.md b/README.md
index f52cbb53..94cdc706 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,8 @@ A 3d-printable housing can be found here: https://www.thingiverse.com/thing:4571
##### Rolling - (2020-09-10)
+* Optimization of "DELETE ALL" - Autoreload of directory after delete, protection of wlan.ini
+* Internal Optimization (removal of unnessary error messages, restructure CTfLiteClass)
* additional parameter in `wasserzahler.html?noerror=true` to suppress an potential error message in case of consitency check (is equal to `ErrorMessage` = False in `config.ini`)
* update ROI-configurator, in case of no ROIs defined
diff --git a/code/lib/jomjol_fileserver_ota/server_file.cpp b/code/lib/jomjol_fileserver_ota/server_file.cpp
index 7109d7dd..e00f6b84 100644
--- a/code/lib/jomjol_fileserver_ota/server_file.cpp
+++ b/code/lib/jomjol_fileserver_ota/server_file.cpp
@@ -140,13 +140,21 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
///////////////////////////////
+ std::string _zw = std::string(dirpath);
+ _zw = _zw.substr(8, _zw.length() - 8);
+ _zw = "/delete/" + _zw + "?task=deldircontent";
+
/* Send file-list table definition and column labels */
httpd_resp_sendstr_chunk(req,
"
"
""
- "| Name | Type | Size (Bytes) | Delete
|
"
- "");
+ "| Name | Type | Size (Bytes) | Delete "
+ ""
+ " |
\n");
/* Iterate over all files / folders and fetch their names and sizes */
while ((entry = readdir(dir)) != NULL) {
@@ -460,12 +468,19 @@ static esp_err_t delete_post_handler(httpd_req_t *req)
}
zw = std::string(filename);
zw = zw.substr(0, zw.length()-1);
+ directory = "/fileserver" + zw + "/";
zw = "/sdcard" + zw;
printf("Directory to delete: %s\n", zw.c_str());
delete_all_in_directory(zw);
- directory = std::string(filepath);
+// directory = std::string(filepath);
+// directory = "/fileserver" + directory;
printf("Location after delete directory content: %s\n", directory.c_str());
+ /* Redirect onto root to see the updated file list */
+// httpd_resp_set_status(req, "303 See Other");
+// httpd_resp_set_hdr(req, "Location", directory.c_str());
+// httpd_resp_sendstr(req, "File deleted successfully");
+// return ESP_OK;
}
else
{
@@ -544,10 +559,12 @@ void delete_all_in_directory(std::string _directory)
/* Iterate over all files / folders and fetch their names and sizes */
while ((entry = readdir(dir)) != NULL) {
if (!(entry->d_type == DT_DIR)){
- filename = _directory + "/" + std::string(entry->d_name);
- ESP_LOGI(TAG, "Deleting file : %s", filename.c_str());
- /* Delete file */
- unlink(filename.c_str());
+ if (strcmp("wlan.ini", entry->d_name) != 0){ // auf wlan.ini soll nicht zugegriffen werden !!!
+ filename = _directory + "/" + std::string(entry->d_name);
+ ESP_LOGI(TAG, "Deleting file : %s", filename.c_str());
+ /* Delete file */
+ unlink(filename.c_str());
+ }
};
}
closedir(dir);
diff --git a/code/lib/jomjol_image_proc/CFindTemplate._h_ b/code/lib/jomjol_image_proc/CFindTemplate._h_
deleted file mode 100644
index 2f58e38d..00000000
--- a/code/lib/jomjol_image_proc/CFindTemplate._h_
+++ /dev/null
@@ -1,87 +0,0 @@
-#pragma once
-
-
-#ifndef __CFINDTEMPLATE
-#define __CFINGTEMPLATE
-
-#include
-#include
-
-#define _USE_MATH_DEFINES
-#include
-
-#include
-
-#include "stb_image.h"
-#include "stb_image_write.h"
-#include "stb_image_resize.h"
-
-
-
-class CImageBasis
-{
- protected:
- uint8_t* rgb_image;
- int channels;
- int width, height, bpp;
- bool externalImage;
- std::string filename;
-
- void memCopy(uint8_t* _source, uint8_t* _target, int _size);
- public:
- int getWidth(){return this->width;};
- int getHeight(){return this->width;};
- int getChannels(){return this->channels;};
-
- CImageBasis();
- CImageBasis(std::string _image);
- CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp);
- uint8_t GetPixelColor(int x, int y, int ch);
-
- ~CImageBasis();
-
- void SaveToFile(std::string _imageout);
-};
-
-class CFindTemplate : public CImageBasis
-{
- public:
- CFindTemplate(std::string _image);
-
- void FindTemplate(std::string _template, int* found_x, int* found_y, std::string _imageout);
- void FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy, std::string _imageout);
- void FindTemplate(std::string _template, int* found_x, int* found_y);
- void FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy);
-};
-
-class CRotate: public CImageBasis
-{
- public:
- CRotate(std::string _image) : CImageBasis(_image) {};
- CRotate(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp) : CImageBasis(_rgb_image, _channels, _width, _height, _bpp) {};
-
- void Rotate(float _angle);
- void Rotate(float _angle, int _centerx, int _centery);
- void Translate(int _dx, int _dy);
-};
-
-
-class CAlignAndCutImage : public CImageBasis
-{
- public:
- CAlignAndCutImage(std::string _image) : CImageBasis(_image) {};
-
- void Align(std::string _template0, int ref0_x, int ref0_y, std::string _template1, int ref1_x, int ref1_y, int deltax, int deltay);
- void CutAndSave(std::string _template1, int x1, int y1, int dx, int dy);
-};
-
-
-class CResizeImage : public CImageBasis
-{
-public:
- CResizeImage(std::string _image) : CImageBasis(_image) {};
- void Resize(int _new_dx, int _new_dy);
-};
-
-#endif
-
diff --git a/code/lib/jomjol_image_proc/CFindTemplate.cp__p b/code/lib/jomjol_image_proc/CFindTemplate.cp__p
deleted file mode 100644
index 106e2568..00000000
--- a/code/lib/jomjol_image_proc/CFindTemplate.cp__p
+++ /dev/null
@@ -1,366 +0,0 @@
-#include "CFindTemplate.h"
-#include "Helper.h"
-
-#define _USE_MATH_DEFINES
-#include
-#include
-
-#define _ESP32_PSRAM
-
-using namespace std;
-
-#define GET_MEMORY malloc
-
-
-uint8_t CImageBasis::GetPixelColor(int x, int y, int ch)
-{
- stbi_uc* p_source;
- p_source = this->rgb_image + (this->channels * (y * this->width + x));
- return p_source[channels];
-}
-
-void CResizeImage::Resize(int _new_dx, int _new_dy)
-{
- int memsize = _new_dx * _new_dy * this->channels;
- uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
-
- stbir_resize_uint8(this->rgb_image, this->width, this->height, 0, odata, _new_dx, _new_dy, 0, this->channels);
-
- stbi_image_free(this->rgb_image);
- this->rgb_image = (unsigned char*)GET_MEMORY(memsize);
-
- this->memCopy(odata, this->rgb_image, memsize);
- this->width = _new_dx;
- this->height = _new_dy;
- stbi_image_free(odata);
-}
-
-void CRotate::Rotate(float _angle, int _centerx, int _centery)
-{
- float m[2][3];
-
- float x_center = _centerx;
- float y_center = _centery;
- _angle = _angle / 180 * M_PI;
-
- m[0][0] = cos(_angle);
- m[0][1] = sin(_angle);
- m[0][2] = (1 - m[0][0]) * x_center - m[0][1] * y_center;
-
- m[1][0] = -m[0][1];
- m[1][1] = m[0][0];
- m[1][2] = m[0][1] * x_center + (1 - m[0][0]) * y_center;
-
- int memsize = this->width * this->height * this->channels;
- uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
-
- int x_source, y_source;
- stbi_uc* p_target;
- stbi_uc* p_source;
-
- for (int x = 0; x < this->width; ++x)
- for (int y = 0; y < this->height; ++y)
- {
- p_target = odata + (this->channels * (y * this->width + x));
-
- x_source = int(m[0][0] * x + m[0][1] * y);
- y_source = int(m[1][0] * x + m[1][1] * y);
-
- x_source += int(m[0][2]);
- y_source += int(m[1][2]);
-
- if ((x_source >= 0) && (x_source < this->width) && (y_source >= 0) && (y_source < this->height))
- {
- p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
- for (int channels = 0; channels < this->channels; ++channels)
- p_target[channels] = p_source[channels];
- }
- else
- {
- for (int channels = 0; channels < this->channels; ++channels)
- p_target[channels] = 255;
- }
- }
-
- // memcpy(this->rgb_image, odata, memsize);
- this->memCopy(odata, this->rgb_image, memsize);
- stbi_image_free(odata);
-}
-
-void CRotate::Rotate(float _angle)
-{
- this->Rotate(_angle, this->width / 2, this->height / 2);
-}
-
-void CRotate::Translate(int _dx, int _dy)
-{
- int memsize = this->width * this->height * this->channels;
- uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
-
-
- int x_source, y_source;
- stbi_uc* p_target;
- stbi_uc* p_source;
-
- for (int x = 0; x < this->width; ++x)
- for (int y = 0; y < this->height; ++y)
- {
- p_target = odata + (this->channels * (y * this->width + x));
-
- x_source = x - _dx;
- y_source = y - _dy;
-
- if ((x_source >= 0) && (x_source < this->width) && (y_source >= 0) && (y_source < this->height))
- {
- p_source = this->rgb_image + (this->channels * (y_source * this->width + x_source));
- for (int channels = 0; channels < this->channels; ++channels)
- p_target[channels] = p_source[channels];
- }
- else
- {
- for (int channels = 0; channels < this->channels; ++channels)
- p_target[channels] = 255;
- }
- }
-
- // memcpy(this->rgb_image, odata, memsize);
- this->memCopy(odata, this->rgb_image, memsize);
- stbi_image_free(odata);
-}
-
-
-
-CFindTemplate::CFindTemplate(std::string _image)
-{
- this->channels = 1;
- this->rgb_image = stbi_load(_image.c_str(), &(this->width), &(this->height), &(this->bpp), this->channels);
-}
-
-void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y)
-{
- this->FindTemplate(_template, found_x, found_y, 0, 0);
-}
-
-void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy)
-{
- int tpl_width, tpl_height, tpl_bpp;
- uint8_t* rgb_template = stbi_load(_template.c_str(), &tpl_width, &tpl_height, &tpl_bpp, this->channels);
-
- int ow, ow_start, ow_stop;
- int oh, oh_start, oh_stop;
-
- if (_dx == 0)
- {
- _dx = this->width;
- *found_x = 0;
- }
-
- if (_dy == 0)
- {
- _dy = this->height;
- *found_y = 0;
- }
-
-
- ow_start = *found_x - _dx;
- ow_start = std::max(ow_start, 0);
- ow_stop = *found_x + _dx;
- if ((ow_stop + tpl_width) > this->width)
- ow_stop = this->width - tpl_width;
- ow = ow_stop - ow_start + 1;
-
- oh_start = *found_y - _dy;
- oh_start = std::max(oh_start, 0);
- oh_stop = *found_y + _dy;
- if ((oh_stop + tpl_height) > this->height)
- oh_stop = this->height - tpl_height;
- oh = oh_stop - oh_start + 1;
-
- uint8_t* odata = (unsigned char*)GET_MEMORY(ow * oh * this->channels);
-
- double aktSAD;
- double minSAD = pow(tpl_width * tpl_height * 255, 2);
-
- for (int xouter = ow_start; xouter <= ow_stop; xouter++)
- for (int youter = oh_start; youter <= oh_stop; ++youter)
- {
- aktSAD = 0;
- for (int tpl_x = 0; tpl_x < tpl_width; tpl_x++)
- for (int tpl_y = 0; tpl_y < tpl_height; tpl_y++)
- {
- stbi_uc* p_org = this->rgb_image + (this->channels * ((youter + tpl_y) * this->width + (xouter + tpl_x)));
- stbi_uc* p_tpl = rgb_template + (this->channels * (tpl_y * tpl_width + tpl_x));
- aktSAD += pow(p_tpl[0] - p_org[0], 2);
- }
- stbi_uc* p_out = odata + (this->channels * ((youter - oh_start) * ow + (xouter - ow_start)));
-
- p_out[0] = int(sqrt(aktSAD / (tpl_width * tpl_height)));
- if (aktSAD < minSAD)
- {
- minSAD = aktSAD;
- *found_x = xouter;
- *found_y = youter;
- }
- }
-
- stbi_image_free(odata);
- stbi_image_free(rgb_template);
-}
-
-void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, std::string _imageout)
-{
- this->FindTemplate(_template, found_x, found_y);
- this->SaveToFile(_imageout);
-}
-
-void CFindTemplate::FindTemplate(std::string _template, int* found_x, int* found_y, int _dx, int _dy, std::string _imageout)
-{
- this->FindTemplate(_template, found_x, found_y, _dx, _dy);
- this->SaveToFile(_imageout);
-}
-
-
-
-void CImageBasis::memCopy(uint8_t* _source, uint8_t* _target, int _size)
-{
-#ifdef _ESP32_PSRAM
- for (int i = 0; i < _size; ++i)
- *(_target + i) = *(_source + i);
-#else
- memcpy(_target, _source, _size);
-#endif
-}
-
-CImageBasis::CImageBasis()
-{
- this->externalImage = false;
-}
-
-CImageBasis::CImageBasis(std::string _image)
-{
-// printf("Start CImageBasis\n");
- channels = 3;
- externalImage = false;
- filename = _image;
-// printf("CImageBasis before load\n");
-// printf(_image.c_str()); printf("\n");
- rgb_image = stbi_load(_image.c_str(), &width, &height, &bpp, channels);
- if (!rgb_image)
- {
- printf("Datei konnte nicht geoeffnet werden\n");
- return;
- }
-// printf("CImageBasis after load\n");
-// printf("w %d, h %d, b %d, c %d\n", width, height, bpp, channels);
-}
-
-CImageBasis::CImageBasis(uint8_t* _rgb_image, int _channels, int _width, int _height, int _bpp)
-{
- rgb_image = _rgb_image;
- channels = _channels;
- width = _width;
- height = _height;
- bpp = _bpp;
- externalImage = true;
-}
-
-CImageBasis::~CImageBasis()
-{
- if (!externalImage)
- stbi_image_free(rgb_image);
-}
-
-void CImageBasis::SaveToFile(std::string _imageout)
-{
- string typ = getFileType(_imageout);
-
- if ((typ == "jpg") || (typ == "JPG")) // ACHTUNG PROBLEMATISCH IM ESP32
- {
- stbi_write_jpg(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image, 0);
- }
-
- if ((typ == "bmp") || (typ == "BMP"))
- {
- stbi_write_bmp(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image);
- }
- // stbi_write_jpg(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image, 0);
- // stbi_write_bmp(_imageout.c_str(), this->width, this->height, this->channels, this->rgb_image);
-}
-
-
-
-void CAlignAndCutImage::Align(std::string _template0, int ref0_x, int ref0_y, std::string _template1, int ref1_x, int ref1_y, int deltax = 40, int deltay = 40)
-{
- int dx, dy;
- int r0_x, r0_y, r1_x, r1_y;
-
- CFindTemplate* ft = new CFindTemplate(this->filename);
-
- r0_x = ref0_x;
- r0_y = ref0_y;
- ft->FindTemplate(_template0, &r0_x, &r0_y, deltax, deltay);
-
- r1_x = ref1_x;
- r1_y = ref1_y;
- ft->FindTemplate(_template1, &r1_x, &r1_y, deltax, deltay);
-
- delete ft;
-
-
- dx = ref0_x - r0_x;
- dy = ref0_y - r0_y;
-
- r0_x += dx;
- r0_y += dy;
-
- r1_x += dx;
- r1_y += dy;
-
- float w_org, w_ist, d_winkel;
-
- w_org = atan2(ref1_y - ref0_y, ref1_x - ref0_x);
- w_ist = atan2(r1_y - r0_y, r1_x - r0_x);
-
- d_winkel = -(w_org - w_ist) * 180 / M_PI;
-
- CRotate rt(this->rgb_image, this->channels, this->width, this->height, this->bpp);
- rt.Translate(dx, dy);
- rt.Rotate(d_winkel, ref0_x, ref0_y);
- printf("Alignment: dx %d - dy %d - rot %f\n", dx, dy, d_winkel);
-}
-
-void CAlignAndCutImage::CutAndSave(std::string _template1, int x1, int y1, int dx, int dy)
-{
-
- int x2, y2;
-
- x2 = x1 + dx;
- y2 = y1 + dy;
- x2 = min(x2, this->width - 1);
- y2 = min(y2, this->height - 1);
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- int memsize = dx * dy * this->channels;
- uint8_t* odata = (unsigned char*)GET_MEMORY(memsize);
-
-
- int x_source, y_source;
- stbi_uc* p_target;
- stbi_uc* p_source;
-
- for (int x = x1; x < x2; ++x)
- for (int y = y1; y < y2; ++y)
- {
- p_target = odata + (this->channels * ((y - y1) * dx + (x - x1)));
- p_source = this->rgb_image + (this->channels * (y * this->width + x));
- for (int channels = 0; channels < this->channels; ++channels)
- p_target[channels] = p_source[channels];
- }
-
- // stbi_write_jpg(_template1.c_str(), dx, dy, this->channels, odata, 0);
- stbi_write_bmp(_template1.c_str(), dx, dy, this->channels, odata);
-
- stbi_image_free(odata);
-}
diff --git a/code/lib/jomjol_tfliteclass/CTfLiteClass._cpp_old b/code/lib/jomjol_tfliteclass/CTfLiteClass._cpp_old
new file mode 100644
index 00000000..dcd56ce0
--- /dev/null
+++ b/code/lib/jomjol_tfliteclass/CTfLiteClass._cpp_old
@@ -0,0 +1,254 @@
+#include "CTfLiteClass.h"
+
+#include "bitmap_image.hpp"
+
+#include
+
+float CTfLiteClass::GetOutputValue(int nr)
+{
+ TfLiteTensor* output2 = this->interpreter->output(0);
+
+ int numeroutput = output2->dims->data[1];
+ if ((nr+1) > numeroutput)
+ return -1000;
+
+ return output2->data.f[nr];
+}
+
+
+int CTfLiteClass::GetClassFromImage(std::string _fn)
+{
+// printf("Before Load image %s\n", _fn.c_str());
+ if (!LoadInputImage(_fn))
+ return -1000;
+// printf("After Load image %s\n", _fn.c_str());
+
+ Invoke();
+ printf("After Invoke %s\n", _fn.c_str());
+
+ return GetOutClassification();
+// return 0;
+}
+
+int CTfLiteClass::GetOutClassification()
+{
+ TfLiteTensor* output2 = interpreter->output(0);
+
+ float zw_max = 0;
+ float zw;
+ int zw_class = -1;
+
+ if (output2 == NULL)
+ return -1;
+
+ int numeroutput = output2->dims->data[1];
+ for (int i = 0; i < numeroutput; ++i)
+ {
+ zw = output2->data.f[i];
+ if (zw > zw_max)
+ {
+ zw_max = zw;
+ zw_class = i;
+ }
+ }
+// printf("Result Ziffer: %d\n", zw_class);
+ return zw_class;
+}
+
+void CTfLiteClass::GetInputDimension(bool silent = false)
+{
+ TfLiteTensor* input2 = this->interpreter->input(0);
+
+ int numdim = input2->dims->size;
+ if (!silent) printf("NumDimension: %d\n", numdim);
+
+ int sizeofdim;
+ for (int j = 0; j < numdim; ++j)
+ {
+ sizeofdim = input2->dims->data[j];
+ if (!silent) printf("SizeOfDimension %d: %d\n", j, sizeofdim);
+ if (j == 1) im_height = sizeofdim;
+ if (j == 2) im_width = sizeofdim;
+ if (j == 3) im_channel = sizeofdim;
+ }
+}
+
+
+void CTfLiteClass::GetOutPut()
+{
+ TfLiteTensor* output2 = this->interpreter->output(0);
+
+ int numdim = output2->dims->size;
+ printf("NumDimension: %d\n", numdim);
+
+ int sizeofdim;
+ for (int j = 0; j < numdim; ++j)
+ {
+ sizeofdim = output2->dims->data[j];
+ printf("SizeOfDimension %d: %d\n", j, sizeofdim);
+ }
+
+
+ float fo;
+
+ // Process the inference results.
+ int numeroutput = output2->dims->data[1];
+ for (int i = 0; i < numeroutput; ++i)
+ {
+ fo = output2->data.f[i];
+ printf("Result %d: %f\n", i, fo);
+ }
+}
+
+void CTfLiteClass::Invoke()
+{
+ interpreter->Invoke();
+// printf("Invoke Done.\n");
+}
+
+
+bool CTfLiteClass::LoadInputImage(std::string _fn)
+{
+ bitmap_image image(_fn);
+ unsigned int w = image.width();
+ unsigned int h = image.height();
+ unsigned char red, green, blue;
+
+ input_i = 0;
+ float* input_data_ptr = (interpreter->input(0))->data.f;
+
+ for (int y = 0; y < h; ++y)
+ for (int x = 0; x < w; ++x)
+ {
+ red = image.red_channel(x, y);
+ green = image.green_channel(x, y);
+ blue = image.blue_channel(x, y);
+ *(input_data_ptr) = (float) red;
+ input_data_ptr++;
+ *(input_data_ptr) = (float) green;
+ input_data_ptr++;
+ *(input_data_ptr) = (float) blue;
+ input_data_ptr++;
+
+// printf("BMP: %f %f %f\n", (float) red, (float) green, (float) blue);
+
+ }
+ return true;
+}
+
+
+void CTfLiteClass::MakeAllocate()
+{
+/*
+ this->micro_op_resolver.AddBuiltin(
+ tflite::BuiltinOperator_RESHAPE,
+ tflite::ops::micro::Register_RESHAPE());
+ this->micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_CONV_2D,
+ tflite::ops::micro::Register_CONV_2D());
+ this->micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_FULLY_CONNECTED,
+ tflite::ops::micro::Register_FULLY_CONNECTED());
+ this->micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_SOFTMAX,
+ tflite::ops::micro::Register_SOFTMAX());
+ this->micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_DEPTHWISE_CONV_2D,
+ tflite::ops::micro::Register_DEPTHWISE_CONV_2D());
+
+
+ this->interpreter = new tflite::MicroInterpreter(this->model, this->micro_op_resolver, this->tensor_arena, this->kTensorArenaSize, this->error_reporter);
+*/
+
+
+ static tflite::ops::micro::AllOpsResolver resolver;
+ this->interpreter = new tflite::MicroInterpreter(this->model, resolver, this->tensor_arena, this->kTensorArenaSize, this->error_reporter);
+
+ TfLiteStatus allocate_status = this->interpreter->AllocateTensors();
+ if (allocate_status != kTfLiteOk) {
+ TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed");
+ this->GetInputDimension();
+ return;
+ }
+
+ printf("Allocate Done.\n");
+}
+
+void CTfLiteClass::GetInputTensorSize(){
+ float *zw = this->input;
+ int test = sizeof(zw);
+ printf("Input Tensor Dimension: %d\n", test);
+
+ printf("Input Tensor Dimension: %d\n", test);
+}
+
+long CTfLiteClass::GetFileSize(std::string filename)
+{
+ struct stat stat_buf;
+ long rc = stat(filename.c_str(), &stat_buf);
+ return rc == 0 ? stat_buf.st_size : -1;
+}
+
+
+unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
+{
+ long size;
+
+ size = this->GetFileSize(_fn);
+
+ if (size == -1)
+ {
+ printf("\nFile existiert nicht.\n");
+ return NULL;
+ }
+
+
+ unsigned char *result = (unsigned char*) malloc(size);
+
+ if(result != NULL) {
+// printf("\nSpeicher ist reserviert\n");
+ FILE* f = fopen(_fn.c_str(), "rb"); // vorher nur "r"
+ fread(result, 1, size, f);
+ fclose(f);
+ }else {
+ printf("\nKein freier Speicher vorhanden.\n");
+ }
+
+
+ return result;
+}
+
+void CTfLiteClass::LoadModel(std::string _fn){
+
+
+ this->error_reporter = new tflite::MicroErrorReporter;
+
+ unsigned char *rd;
+ rd = this->ReadFileToCharArray(_fn.c_str());
+// printf("loadedfile: %d", (int) rd);
+
+ this->model = tflite::GetModel(rd);
+ free(rd);
+ TFLITE_MINIMAL_CHECK(model != nullptr);
+ printf("tfile Loaded.\n");
+
+}
+
+
+
+CTfLiteClass::CTfLiteClass()
+{
+// this->accessSD = _accessSD;
+ this->model = nullptr;
+ this->interpreter = nullptr;
+ this->input = nullptr;
+ this->output = nullptr;
+ this->kTensorArenaSize = 600 * 1024;
+ this->tensor_arena = new uint8_t[kTensorArenaSize];
+
+// micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_CONV_2D,
+// tflite::ops::micro::Register_CONV_2D());
+}
+
+CTfLiteClass::~CTfLiteClass()
+{
+ delete this->tensor_arena;
+}
+
+
diff --git a/code/lib/jomjol_tfliteclass/CTfLiteClass._h_old b/code/lib/jomjol_tfliteclass/CTfLiteClass._h_old
new file mode 100644
index 00000000..01d972bf
--- /dev/null
+++ b/code/lib/jomjol_tfliteclass/CTfLiteClass._h_old
@@ -0,0 +1,72 @@
+#pragma once
+
+#ifndef __CFINDTEMPLATE
+#define __CFINGTEMPLATE
+
+#define TFLITE_MINIMAL_CHECK(x) \
+ if (!(x)) { \
+ fprintf(stderr, "Error at %s:%d\n", __FILE__, __LINE__); \
+ exit(1); \
+ }
+
+//#include "CAccessSD.h"
+#include "CFindTemplate.h"
+
+#include "tensorflow/lite/micro/kernels/all_ops_resolver.h"
+#include "tensorflow/lite/micro/micro_error_reporter.h"
+#include "tensorflow/lite/micro/micro_interpreter.h"
+#include "tensorflow/lite/schema/schema_generated.h"
+#include "tensorflow/lite/version.h"
+#include "tensorflow/lite/micro/kernels/micro_ops.h"
+#include "esp_err.h"
+#include "esp_log.h"
+
+//extern CAccessSDClass accessSD;
+
+class CTfLiteClass
+{
+ protected:
+// CAccessSDClass *accessSD;
+
+ tflite::ErrorReporter* error_reporter;
+
+ const tflite::Model* model;
+ tflite::MicroInterpreter* interpreter;
+// TfLiteTensor* input = nullptr;
+ TfLiteTensor* output = nullptr;
+ static tflite::ops::micro::AllOpsResolver *resolver;
+
+ tflite::MicroOpResolver<5> micro_op_resolver;
+
+
+ int kTensorArenaSize;
+ uint8_t *tensor_arena;
+
+ float* input;
+ int input_i;
+
+ int im_height, im_width, im_channel;
+
+ long GetFileSize(std::string filename);
+ unsigned char* ReadFileToCharArray(std::string _fn);
+
+ public:
+// CTfLiteClass(CAccessSDClass *_accessSD);
+ CTfLiteClass();
+ ~CTfLiteClass();
+ void LoadModel(std::string _fn);
+ void MakeAllocate();
+ void GetInputTensorSize();
+ bool LoadInputImage(std::string _fn);
+ void Invoke();
+ void GetOutPut();
+ int GetOutClassification();
+ int GetClassFromImage(std::string _fn);
+
+ float GetOutputValue(int nr);
+ void GetInputDimension(bool silent);
+
+};
+
+
+#endif
\ No newline at end of file
diff --git a/code/lib/jomjol_tfliteclass/CTfLiteClass.cpp b/code/lib/jomjol_tfliteclass/CTfLiteClass.cpp
index dcd56ce0..5887436f 100644
--- a/code/lib/jomjol_tfliteclass/CTfLiteClass.cpp
+++ b/code/lib/jomjol_tfliteclass/CTfLiteClass.cpp
@@ -114,6 +114,8 @@ bool CTfLiteClass::LoadInputImage(std::string _fn)
unsigned int h = image.height();
unsigned char red, green, blue;
+// printf("Image: %s size: %d x %d\n", _fn.c_str(), w, h);
+
input_i = 0;
float* input_data_ptr = (interpreter->input(0))->data.f;
@@ -139,24 +141,6 @@ bool CTfLiteClass::LoadInputImage(std::string _fn)
void CTfLiteClass::MakeAllocate()
{
-/*
- this->micro_op_resolver.AddBuiltin(
- tflite::BuiltinOperator_RESHAPE,
- tflite::ops::micro::Register_RESHAPE());
- this->micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_CONV_2D,
- tflite::ops::micro::Register_CONV_2D());
- this->micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_FULLY_CONNECTED,
- tflite::ops::micro::Register_FULLY_CONNECTED());
- this->micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_SOFTMAX,
- tflite::ops::micro::Register_SOFTMAX());
- this->micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_DEPTHWISE_CONV_2D,
- tflite::ops::micro::Register_DEPTHWISE_CONV_2D());
-
-
- this->interpreter = new tflite::MicroInterpreter(this->model, this->micro_op_resolver, this->tensor_arena, this->kTensorArenaSize, this->error_reporter);
-*/
-
-
static tflite::ops::micro::AllOpsResolver resolver;
this->interpreter = new tflite::MicroInterpreter(this->model, resolver, this->tensor_arena, this->kTensorArenaSize, this->error_reporter);
@@ -167,7 +151,7 @@ void CTfLiteClass::MakeAllocate()
return;
}
- printf("Allocate Done.\n");
+// printf("Allocate Done.\n");
}
void CTfLiteClass::GetInputTensorSize(){
@@ -216,8 +200,11 @@ unsigned char* CTfLiteClass::ReadFileToCharArray(std::string _fn)
void CTfLiteClass::LoadModel(std::string _fn){
-
+#ifdef SUPRESS_TFLITE_ERRORS
+ this->error_reporter = new tflite::OwnMicroErrorReporter;
+#else
this->error_reporter = new tflite::MicroErrorReporter;
+#endif
unsigned char *rd;
rd = this->ReadFileToCharArray(_fn.c_str());
@@ -226,7 +213,7 @@ void CTfLiteClass::LoadModel(std::string _fn){
this->model = tflite::GetModel(rd);
free(rd);
TFLITE_MINIMAL_CHECK(model != nullptr);
- printf("tfile Loaded.\n");
+// printf("tfile Loaded.\n");
}
@@ -234,16 +221,12 @@ void CTfLiteClass::LoadModel(std::string _fn){
CTfLiteClass::CTfLiteClass()
{
-// this->accessSD = _accessSD;
this->model = nullptr;
this->interpreter = nullptr;
this->input = nullptr;
this->output = nullptr;
this->kTensorArenaSize = 600 * 1024;
- this->tensor_arena = new uint8_t[kTensorArenaSize];
-
-// micro_op_resolver.AddBuiltin(tflite::BuiltinOperator_CONV_2D,
-// tflite::ops::micro::Register_CONV_2D());
+ this->tensor_arena = new uint8_t[kTensorArenaSize];
}
CTfLiteClass::~CTfLiteClass()
@@ -252,3 +235,12 @@ CTfLiteClass::~CTfLiteClass()
}
+namespace tflite {
+
+ int OwnMicroErrorReporter::Report(const char* format, va_list args) {
+ return 0;
+ }
+
+} // namespace tflite
+
+
diff --git a/code/lib/jomjol_tfliteclass/CTfLiteClass.h b/code/lib/jomjol_tfliteclass/CTfLiteClass.h
index 01d972bf..8beb48ba 100644
--- a/code/lib/jomjol_tfliteclass/CTfLiteClass.h
+++ b/code/lib/jomjol_tfliteclass/CTfLiteClass.h
@@ -1,7 +1,3 @@
-#pragma once
-
-#ifndef __CFINDTEMPLATE
-#define __CFINGTEMPLATE
#define TFLITE_MINIMAL_CHECK(x) \
if (!(x)) { \
@@ -9,9 +5,6 @@
exit(1); \
}
-//#include "CAccessSD.h"
-#include "CFindTemplate.h"
-
#include "tensorflow/lite/micro/kernels/all_ops_resolver.h"
#include "tensorflow/lite/micro/micro_error_reporter.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
@@ -21,37 +14,44 @@
#include "esp_err.h"
#include "esp_log.h"
-//extern CAccessSDClass accessSD;
+
+
+#define SUPRESS_TFLITE_ERRORS // use, to avoid error messages from TFLITE
+
+#ifdef SUPRESS_TFLITE_ERRORS
+#include "tensorflow/lite/core/api/error_reporter.h"
+#include "tensorflow/lite/micro/compatibility.h"
+#include "tensorflow/lite/micro/debug_log.h"
+///// OwnErrorReporter to prevent printing of Errors (especially unavoidable in CalculateActivationRangeQuantized@kerne_util.cc)
+namespace tflite {
+ class OwnMicroErrorReporter : public ErrorReporter {
+ public:
+ int Report(const char* format, va_list args) override;
+ };
+} // namespace tflite
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#endif
class CTfLiteClass
{
protected:
-// CAccessSDClass *accessSD;
-
- tflite::ErrorReporter* error_reporter;
-
+ tflite::ErrorReporter *error_reporter;
const tflite::Model* model;
tflite::MicroInterpreter* interpreter;
-// TfLiteTensor* input = nullptr;
TfLiteTensor* output = nullptr;
static tflite::ops::micro::AllOpsResolver *resolver;
- tflite::MicroOpResolver<5> micro_op_resolver;
-
-
int kTensorArenaSize;
uint8_t *tensor_arena;
float* input;
int input_i;
-
int im_height, im_width, im_channel;
long GetFileSize(std::string filename);
unsigned char* ReadFileToCharArray(std::string _fn);
public:
-// CTfLiteClass(CAccessSDClass *_accessSD);
CTfLiteClass();
~CTfLiteClass();
void LoadModel(std::string _fn);
@@ -65,8 +65,5 @@ class CTfLiteClass
float GetOutputValue(int nr);
void GetInputDimension(bool silent);
-
};
-
-#endif
\ No newline at end of file
diff --git a/code/sdkconfig b/code/sdkconfig
index 8d7e12d6..12a3b16d 100644
--- a/code/sdkconfig
+++ b/code/sdkconfig
@@ -221,7 +221,7 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
CONFIG_ESP_INT_WDT_CHECK_CPU1=y
CONFIG_ESP_TASK_WDT=y
# CONFIG_ESP_TASK_WDT_PANIC is not set
-CONFIG_ESP_TASK_WDT_TIMEOUT_S=5
+CONFIG_ESP_TASK_WDT_TIMEOUT_S=60
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
CONFIG_ETH_USE_ESP32_EMAC=y
@@ -649,7 +649,7 @@ CONFIG_INT_WDT_TIMEOUT_MS=300
CONFIG_INT_WDT_CHECK_CPU1=y
CONFIG_TASK_WDT=y
# CONFIG_TASK_WDT_PANIC is not set
-CONFIG_TASK_WDT_TIMEOUT_S=5
+CONFIG_TASK_WDT_TIMEOUT_S=60
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
# CONFIG_EVENT_LOOP_PROFILING is not set
diff --git a/code/sdkconfig.old b/code/sdkconfig.old
new file mode 100644
index 00000000..41745270
--- /dev/null
+++ b/code/sdkconfig.old
@@ -0,0 +1,565 @@
+#
+# Automatically generated file. DO NOT EDIT.
+# Espressif IoT Development Framework (ESP-IDF) Project Configuration
+#
+CONFIG_IDF_TARGET_ESP32=y
+CONFIG_IDF_TARGET="esp32"
+CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000
+
+#
+# SDK tool configuration
+#
+CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-"
+CONFIG_APP_COMPILE_TIME_DATE=y
+# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set
+# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set
+CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16
+# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set
+CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y
+# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set
+# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set
+CONFIG_BOOTLOADER_LOG_LEVEL=3
+# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set
+CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y
+# CONFIG_BOOTLOADER_FACTORY_RESET is not set
+# CONFIG_BOOTLOADER_APP_TEST is not set
+CONFIG_BOOTLOADER_WDT_ENABLE=y
+# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set
+CONFIG_BOOTLOADER_WDT_TIME_MS=9000
+# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set
+# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set
+# CONFIG_SECURE_BOOT_ENABLED is not set
+# CONFIG_SECURE_FLASH_ENC_ENABLED is not set
+CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200
+# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set
+# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set
+CONFIG_ESPTOOLPY_FLASHMODE_DIO=y
+# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
+CONFIG_ESPTOOLPY_FLASHMODE="dio"
+# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set
+CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
+# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
+# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
+CONFIG_ESPTOOLPY_FLASHFREQ="40m"
+# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
+CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
+# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
+# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
+# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
+CONFIG_ESPTOOLPY_FLASHSIZE="2MB"
+CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
+CONFIG_ESPTOOLPY_BEFORE_RESET=y
+# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
+CONFIG_ESPTOOLPY_BEFORE="default_reset"
+CONFIG_ESPTOOLPY_AFTER_RESET=y
+# CONFIG_ESPTOOLPY_AFTER_NORESET is not set
+CONFIG_ESPTOOLPY_AFTER="hard_reset"
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set
+CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set
+# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set
+CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200
+CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
+CONFIG_PARTITION_TABLE_SINGLE_APP=y
+# CONFIG_PARTITION_TABLE_TWO_OTA is not set
+# CONFIG_PARTITION_TABLE_CUSTOM is not set
+CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
+CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
+CONFIG_PARTITION_TABLE_OFFSET=0x8000
+CONFIG_PARTITION_TABLE_MD5=y
+CONFIG_EXAMPLE_CONNECT_WIFI=y
+# CONFIG_EXAMPLE_CONNECT_ETHERNET is not set
+CONFIG_EXAMPLE_WIFI_SSID="SSID"
+CONFIG_EXAMPLE_WIFI_PASSWORD="passwd"
+CONFIG_EXAMPLE_CONNECT_IPV6=y
+CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y
+# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set
+CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
+# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
+# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
+# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
+CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
+# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
+# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set
+# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set
+# CONFIG_COMPILER_STACK_CHECK is not set
+# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
+# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set
+# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
+CONFIG_ESP32_APPTRACE_DEST_NONE=y
+# CONFIG_ESP32_APPTRACE_ENABLE is not set
+CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
+# CONFIG_BT_ENABLED is not set
+CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0
+# CONFIG_BTDM_CTRL_AUTO_LATENCY_EFF is not set
+CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0
+CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0
+CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0
+CONFIG_BTDM_CTRL_PINNED_TO_CORE=0
+CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1
+CONFIG_BT_RESERVE_DRAM=0
+# CONFIG_BLE_MESH is not set
+# CONFIG_ADC_FORCE_XPD_FSM is not set
+CONFIG_ADC_DISABLE_DAC=y
+# CONFIG_SPI_MASTER_IN_IRAM is not set
+CONFIG_SPI_MASTER_ISR_IN_IRAM=y
+# CONFIG_SPI_SLAVE_IN_IRAM is not set
+CONFIG_SPI_SLAVE_ISR_IN_IRAM=y
+# CONFIG_EFUSE_CUSTOM_TABLE is not set
+# CONFIG_EFUSE_VIRTUAL is not set
+# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set
+CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y
+# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set
+CONFIG_EFUSE_MAX_BLK_LEN=192
+# CONFIG_ESP_TLS_SERVER is not set
+CONFIG_ESP32_REV_MIN_0=y
+# CONFIG_ESP32_REV_MIN_1 is not set
+# CONFIG_ESP32_REV_MIN_2 is not set
+# CONFIG_ESP32_REV_MIN_3 is not set
+CONFIG_ESP32_REV_MIN=0
+CONFIG_ESP32_DPORT_WORKAROUND=y
+# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set
+CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y
+# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set
+CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160
+CONFIG_ESP32_SPIRAM_SUPPORT=y
+CONFIG_SPIRAM_BOOT_INIT=y
+# CONFIG_SPIRAM_IGNORE_NOTFOUND is not set
+# CONFIG_SPIRAM_USE_MEMMAP is not set
+# CONFIG_SPIRAM_USE_CAPS_ALLOC is not set
+CONFIG_SPIRAM_USE_MALLOC=y
+CONFIG_SPIRAM_TYPE_AUTO=y
+# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set
+# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set
+CONFIG_SPIRAM_SIZE=-1
+CONFIG_SPIRAM_SPEED_40M=y
+CONFIG_SPIRAM_MEMTEST=y
+CONFIG_SPIRAM_CACHE_WORKAROUND=y
+CONFIG_SPIRAM_BANKSWITCH_ENABLE=y
+CONFIG_SPIRAM_BANKSWITCH_RESERVE=8
+CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
+# CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP is not set
+CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
+# CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY is not set
+# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
+CONFIG_D0WD_PSRAM_CLK_IO=17
+CONFIG_D0WD_PSRAM_CS_IO=16
+CONFIG_D2WD_PSRAM_CLK_IO=9
+CONFIG_D2WD_PSRAM_CS_IO=10
+CONFIG_PICO_PSRAM_CS_IO=10
+CONFIG_SPIRAM_SPIWP_SD3_PIN=7
+# CONFIG_SPIRAM_2T_MODE is not set
+# CONFIG_ESP32_MEMMAP_TRACEMEM is not set
+# CONFIG_ESP32_MEMMAP_TRACEMEM_TWOBANKS is not set
+# CONFIG_ESP32_TRAX is not set
+CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0
+# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set
+CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y
+CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4
+# CONFIG_ESP32_ULP_COPROC_ENABLED is not set
+CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0
+# CONFIG_ESP32_PANIC_PRINT_HALT is not set
+CONFIG_ESP32_PANIC_PRINT_REBOOT=y
+# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set
+# CONFIG_ESP32_PANIC_GDBSTUB is not set
+CONFIG_ESP32_DEBUG_OCDAWARE=y
+CONFIG_ESP32_DEBUG_STUBS_ENABLE=y
+CONFIG_ESP32_BROWNOUT_DET=y
+CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set
+# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set
+CONFIG_ESP32_BROWNOUT_DET_LVL=0
+CONFIG_ESP32_REDUCE_PHY_TX_POWER=y
+CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
+# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set
+# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set
+# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set
+CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y
+# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set
+# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set
+# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set
+CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024
+CONFIG_ESP32_RTC_XTAL_CAL_RETRY=1
+CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000
+CONFIG_ESP32_XTAL_FREQ_40=y
+# CONFIG_ESP32_XTAL_FREQ_26 is not set
+# CONFIG_ESP32_XTAL_FREQ_AUTO is not set
+CONFIG_ESP32_XTAL_FREQ=40
+# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set
+# CONFIG_ESP32_NO_BLOBS is not set
+# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set
+# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set
+CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5
+# CONFIG_PM_ENABLE is not set
+CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y
+CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y
+CONFIG_ADC_CAL_LUT_ENABLE=y
+# CONFIG_ESP_TIMER_PROFILING is not set
+CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
+CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
+CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
+CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584
+CONFIG_ESP_IPC_TASK_STACK_SIZE=1024
+CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584
+CONFIG_ESP_CONSOLE_UART_DEFAULT=y
+# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
+# CONFIG_ESP_CONSOLE_UART_NONE is not set
+CONFIG_ESP_CONSOLE_UART_NUM=0
+CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200
+CONFIG_ESP_INT_WDT=y
+CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
+CONFIG_ESP_INT_WDT_CHECK_CPU1=y
+CONFIG_ESP_TASK_WDT=y
+# CONFIG_ESP_TASK_WDT_PANIC is not set
+CONFIG_ESP_TASK_WDT_TIMEOUT_S=5
+CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
+CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y
+CONFIG_ETH_USE_ESP32_EMAC=y
+CONFIG_ETH_PHY_INTERFACE_RMII=y
+# CONFIG_ETH_PHY_INTERFACE_MII is not set
+CONFIG_ETH_RMII_CLK_INPUT=y
+# CONFIG_ETH_RMII_CLK_OUTPUT is not set
+CONFIG_ETH_RMII_CLK_IN_GPIO=0
+CONFIG_ETH_DMA_BUFFER_SIZE=512
+CONFIG_ETH_DMA_RX_BUFFER_NUM=10
+CONFIG_ETH_DMA_TX_BUFFER_NUM=10
+CONFIG_ETH_USE_SPI_ETHERNET=y
+CONFIG_ETH_SPI_ETHERNET_DM9051=y
+# CONFIG_ESP_EVENT_LOOP_PROFILING is not set
+CONFIG_ESP_EVENT_POST_FROM_ISR=y
+CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y
+CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
+# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set
+CONFIG_HTTPD_MAX_REQ_HDR_LEN=512
+CONFIG_HTTPD_MAX_URI_LEN=512
+CONFIG_HTTPD_ERR_RESP_NO_DELAY=y
+CONFIG_HTTPD_PURGE_BUF_LEN=32
+# CONFIG_HTTPD_LOG_PURGE_DATA is not set
+# CONFIG_OTA_ALLOW_HTTP is not set
+# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set
+CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
+CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
+CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y
+CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0
+CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16
+# CONFIG_ESP32_WIFI_CSI_ENABLED is not set
+CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y
+CONFIG_ESP32_WIFI_TX_BA_WIN=6
+CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
+CONFIG_ESP32_WIFI_RX_BA_WIN=6
+CONFIG_ESP32_WIFI_NVS_ENABLED=y
+CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
+# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set
+CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
+CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
+# CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE is not set
+CONFIG_ESP32_WIFI_IRAM_OPT=y
+CONFIG_ESP32_WIFI_RX_IRAM_OPT=y
+CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y
+CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y
+# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set
+CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
+CONFIG_ESP32_PHY_MAX_TX_POWER=20
+# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set
+# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
+CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
+# CONFIG_ESP32_ENABLE_COREDUMP is not set
+# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set
+CONFIG_FATFS_CODEPAGE_437=y
+# CONFIG_FATFS_CODEPAGE_720 is not set
+# CONFIG_FATFS_CODEPAGE_737 is not set
+# CONFIG_FATFS_CODEPAGE_771 is not set
+# CONFIG_FATFS_CODEPAGE_775 is not set
+# CONFIG_FATFS_CODEPAGE_850 is not set
+# CONFIG_FATFS_CODEPAGE_852 is not set
+# CONFIG_FATFS_CODEPAGE_855 is not set
+# CONFIG_FATFS_CODEPAGE_857 is not set
+# CONFIG_FATFS_CODEPAGE_860 is not set
+# CONFIG_FATFS_CODEPAGE_861 is not set
+# CONFIG_FATFS_CODEPAGE_862 is not set
+# CONFIG_FATFS_CODEPAGE_863 is not set
+# CONFIG_FATFS_CODEPAGE_864 is not set
+# CONFIG_FATFS_CODEPAGE_865 is not set
+# CONFIG_FATFS_CODEPAGE_866 is not set
+# CONFIG_FATFS_CODEPAGE_869 is not set
+# CONFIG_FATFS_CODEPAGE_932 is not set
+# CONFIG_FATFS_CODEPAGE_936 is not set
+# CONFIG_FATFS_CODEPAGE_949 is not set
+# CONFIG_FATFS_CODEPAGE_950 is not set
+CONFIG_FATFS_CODEPAGE=437
+# CONFIG_FATFS_LFN_NONE is not set
+CONFIG_FATFS_LFN_HEAP=y
+# CONFIG_FATFS_LFN_STACK is not set
+CONFIG_FATFS_MAX_LFN=255
+CONFIG_FATFS_API_ENCODING_ANSI_OEM=y
+# CONFIG_FATFS_API_ENCODING_UTF_16 is not set
+# CONFIG_FATFS_API_ENCODING_UTF_8 is not set
+CONFIG_FATFS_FS_LOCK=0
+CONFIG_FATFS_TIMEOUT_MS=10000
+CONFIG_FATFS_PER_FILE_CACHE=y
+CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
+CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150
+CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200
+CONFIG_FMB_QUEUE_LENGTH=20
+CONFIG_FMB_SERIAL_TASK_STACK_SIZE=2048
+CONFIG_FMB_SERIAL_BUF_SIZE=256
+CONFIG_FMB_SERIAL_TASK_PRIO=10
+# CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT is not set
+CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20
+CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20
+CONFIG_FMB_CONTROLLER_STACK_SIZE=4096
+CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20
+CONFIG_FMB_TIMER_PORT_ENABLED=y
+CONFIG_FMB_TIMER_GROUP=0
+CONFIG_FMB_TIMER_INDEX=0
+# CONFIG_FREERTOS_UNICORE is not set
+CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF
+CONFIG_FREERTOS_CORETIMER_0=y
+# CONFIG_FREERTOS_CORETIMER_1 is not set
+CONFIG_FREERTOS_HZ=100
+CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
+# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
+# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
+CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
+# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
+CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y
+CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
+CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y
+# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set
+# CONFIG_FREERTOS_ASSERT_DISABLE is not set
+CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
+CONFIG_FREERTOS_ISR_STACKSIZE=1536
+# CONFIG_FREERTOS_LEGACY_HOOKS is not set
+CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
+CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y
+# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set
+CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1
+CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048
+CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10
+CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0
+# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
+# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
+# CONFIG_FREERTOS_DEBUG_INTERNALS is not set
+CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y
+CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y
+# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set
+CONFIG_HEAP_POISONING_DISABLED=y
+# CONFIG_HEAP_POISONING_LIGHT is not set
+# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set
+CONFIG_HEAP_TRACING_OFF=y
+# CONFIG_HEAP_TRACING_STANDALONE is not set
+# CONFIG_HEAP_TRACING_TOHOST is not set
+# CONFIG_HEAP_TRACING is not set
+# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
+# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
+# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
+CONFIG_LOG_DEFAULT_LEVEL_INFO=y
+# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
+# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
+CONFIG_LOG_DEFAULT_LEVEL=3
+CONFIG_LOG_COLORS=y
+CONFIG_LWIP_LOCAL_HOSTNAME="espressif"
+# CONFIG_LWIP_L2_TO_L3_COPY is not set
+# CONFIG_LWIP_IRAM_OPTIMIZATION is not set
+CONFIG_LWIP_TIMERS_ONDEMAND=y
+CONFIG_LWIP_MAX_SOCKETS=10
+# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set
+CONFIG_LWIP_SO_REUSE=y
+CONFIG_LWIP_SO_REUSE_RXTOALL=y
+# CONFIG_LWIP_SO_RCVBUF is not set
+CONFIG_LWIP_IP_FRAG=y
+# CONFIG_LWIP_IP_REASSEMBLY is not set
+# CONFIG_LWIP_STATS is not set
+# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set
+CONFIG_LWIP_ESP_GRATUITOUS_ARP=y
+CONFIG_LWIP_GARP_TMR_INTERVAL=60
+CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
+CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
+# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set
+CONFIG_LWIP_DHCPS_LEASE_UNIT=60
+CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8
+# CONFIG_LWIP_AUTOIP is not set
+# CONFIG_LWIP_IPV6_AUTOCONFIG is not set
+CONFIG_LWIP_NETIF_LOOPBACK=y
+CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
+CONFIG_LWIP_MAX_ACTIVE_TCP=16
+CONFIG_LWIP_MAX_LISTENING_TCP=16
+CONFIG_LWIP_TCP_MAXRTX=12
+CONFIG_LWIP_TCP_SYNMAXRTX=6
+CONFIG_LWIP_TCP_MSS=1440
+CONFIG_LWIP_TCP_MSL=60000
+CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744
+CONFIG_LWIP_TCP_WND_DEFAULT=5744
+CONFIG_LWIP_TCP_RECVMBOX_SIZE=6
+CONFIG_LWIP_TCP_QUEUE_OOSEQ=y
+# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set
+CONFIG_LWIP_TCP_OVERSIZE_MSS=y
+# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set
+# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set
+CONFIG_LWIP_MAX_UDP_PCBS=16
+CONFIG_LWIP_UDP_RECVMBOX_SIZE=6
+CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072
+CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y
+# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set
+# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set
+CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF
+# CONFIG_LWIP_PPP_SUPPORT is not set
+# CONFIG_LWIP_MULTICAST_PING is not set
+# CONFIG_LWIP_BROADCAST_PING is not set
+CONFIG_LWIP_MAX_RAW_PCBS=16
+CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1
+CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000
+CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
+# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set
+# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
+# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
+CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
+CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
+CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096
+# CONFIG_MBEDTLS_DEBUG is not set
+# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set
+# CONFIG_MBEDTLS_CMAC_C is not set
+CONFIG_MBEDTLS_HARDWARE_AES=y
+# CONFIG_MBEDTLS_HARDWARE_MPI is not set
+CONFIG_MBEDTLS_HARDWARE_SHA=y
+CONFIG_MBEDTLS_HAVE_TIME=y
+# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
+CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y
+# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set
+# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set
+# CONFIG_MBEDTLS_TLS_DISABLED is not set
+CONFIG_MBEDTLS_TLS_SERVER=y
+CONFIG_MBEDTLS_TLS_CLIENT=y
+CONFIG_MBEDTLS_TLS_ENABLED=y
+# CONFIG_MBEDTLS_PSK_MODES is not set
+CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y
+CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y
+CONFIG_MBEDTLS_SSL_RENEGOTIATION=y
+# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set
+CONFIG_MBEDTLS_SSL_PROTO_TLS1=y
+CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y
+CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y
+# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set
+CONFIG_MBEDTLS_SSL_ALPN=y
+CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y
+CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y
+CONFIG_MBEDTLS_AES_C=y
+# CONFIG_MBEDTLS_CAMELLIA_C is not set
+# CONFIG_MBEDTLS_DES_C is not set
+CONFIG_MBEDTLS_RC4_DISABLED=y
+# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set
+# CONFIG_MBEDTLS_RC4_ENABLED is not set
+# CONFIG_MBEDTLS_BLOWFISH_C is not set
+# CONFIG_MBEDTLS_XTEA_C is not set
+CONFIG_MBEDTLS_CCM_C=y
+CONFIG_MBEDTLS_GCM_C=y
+# CONFIG_MBEDTLS_RIPEMD160_C is not set
+CONFIG_MBEDTLS_PEM_PARSE_C=y
+CONFIG_MBEDTLS_PEM_WRITE_C=y
+CONFIG_MBEDTLS_X509_CRL_PARSE_C=y
+CONFIG_MBEDTLS_X509_CSR_PARSE_C=y
+CONFIG_MBEDTLS_ECP_C=y
+CONFIG_MBEDTLS_ECDH_C=y
+CONFIG_MBEDTLS_ECDSA_C=y
+CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y
+CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y
+CONFIG_MBEDTLS_ECP_NIST_OPTIM=y
+CONFIG_MDNS_MAX_SERVICES=10
+CONFIG_MQTT_PROTOCOL_311=y
+CONFIG_MQTT_TRANSPORT_SSL=y
+CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
+CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
+# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
+# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
+# CONFIG_MQTT_CUSTOM_OUTBOX is not set
+CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y
+# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set
+# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set
+# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set
+# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set
+CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y
+# CONFIG_NEWLIB_NANO_FORMAT is not set
+# CONFIG_OPENSSL_DEBUG is not set
+# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set
+CONFIG_OPENSSL_ASSERT_EXIT=y
+CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5
+CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072
+CONFIG_PTHREAD_STACK_MIN=768
+CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y
+# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set
+# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set
+CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1
+CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread"
+# CONFIG_SPI_FLASH_VERIFY_WRITE is not set
+# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set
+CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y
+CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y
+# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set
+# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set
+# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set
+CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y
+CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y
+CONFIG_SPIFFS_MAX_PARTITIONS=3
+CONFIG_SPIFFS_CACHE=y
+CONFIG_SPIFFS_CACHE_WR=y
+# CONFIG_SPIFFS_CACHE_STATS is not set
+CONFIG_SPIFFS_PAGE_CHECK=y
+CONFIG_SPIFFS_GC_MAX_RUNS=10
+# CONFIG_SPIFFS_GC_STATS is not set
+CONFIG_SPIFFS_PAGE_SIZE=256
+CONFIG_SPIFFS_OBJ_NAME_LEN=32
+CONFIG_SPIFFS_USE_MAGIC=y
+CONFIG_SPIFFS_USE_MAGIC_LENGTH=y
+CONFIG_SPIFFS_META_LENGTH=4
+CONFIG_SPIFFS_USE_MTIME=y
+# CONFIG_SPIFFS_DBG is not set
+# CONFIG_SPIFFS_API_DBG is not set
+# CONFIG_SPIFFS_GC_DBG is not set
+# CONFIG_SPIFFS_CACHE_DBG is not set
+# CONFIG_SPIFFS_CHECK_DBG is not set
+# CONFIG_SPIFFS_TEST_VISUALISATION is not set
+CONFIG_NETIF_IP_LOST_TIMER_INTERVAL=120
+CONFIG_TCPIP_LWIP=y
+CONFIG_UNITY_ENABLE_FLOAT=y
+CONFIG_UNITY_ENABLE_DOUBLE=y
+# CONFIG_UNITY_ENABLE_COLOR is not set
+CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y
+# CONFIG_UNITY_ENABLE_FIXTURE is not set
+# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set
+CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y
+CONFIG_VFS_SUPPORT_TERMIOS=y
+CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1
+CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128
+# CONFIG_WL_SECTOR_SIZE_512 is not set
+CONFIG_WL_SECTOR_SIZE_4096=y
+CONFIG_WL_SECTOR_SIZE=4096
+CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16
+CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30
+CONFIG_WPA_MBEDTLS_CRYPTO=y
+# CONFIG_WPA_TLS_V12 is not set
+# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set
diff --git a/firmware/bootloader.bin b/firmware/bootloader.bin
index a8aaf709b6c0ecbbc0d847121846883e6c6b8311..37db1b316bfbe9295237cecae5f6f966a09f45bf 100644
GIT binary patch
delta 54
zcmV-60LlN*&H>QQ0kBgL1u`%?FgUYV5Z6{AdBeM^-R*#<8#t#OGQ3_;jW%%RyQQ0kBgL1u!@|F*&nX5Z6{Ab5RP5@t{q3AF{j~F&Xewd}chDbjW+@
MXilM%e%W|7MPLILI{*Lx
diff --git a/firmware/firmware.bin b/firmware/firmware.bin
index dda80531a228f6c5830d77a68974a5ba02dc56c0..b501f86e63d5f914e9fc1dfc2e0bfaad9b7d3d65 100644
GIT binary patch
delta 428069
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