├── Makefile ├── README.md ├── components └── fft │ ├── component.mk │ ├── fft.c │ └── include │ └── fft.h ├── main ├── component.mk └── test_fft.c ├── performance ├── fft_runtime.png ├── frame_percent.png └── performance.csv └── sdkconfig /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # This is a project Makefile. It is assumed the directory this Makefile resides in is a 3 | # project subdirectory. 4 | # 5 | 6 | PROJECT_NAME := test_fft 7 | 8 | include $(IDF_PATH)/make/project.mk 9 | 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ESP32 FFT 2 | ========= 3 | 4 | This provides a vanilla radix-2 FFT out-of-place implementation and a test example. 5 | 6 | Author 7 | ------ 8 | 9 | This code was written by [Robin Scheibler](http://www.robinscheibler.org) during rainy days in October 2017. 10 | 11 | Example 12 | ------- 13 | 14 | #include "fft.h" 15 | 16 | ... 17 | 18 | // Create the FFT config structure 19 | fft_config_t *real_fft_plan = fft_init(NFFT, FFT_REAL, FFT_FORWARD, NULL, NULL); 20 | 21 | // Fill array with some data 22 | for (k = 0 ; k < fft_analysis->size ; k++) 23 | real_fft_plan->input[k] = (float)k; 24 | 25 | // Execute transformation 26 | fft_execute(real_fft_plan); 27 | 28 | // Now do something with the output 29 | printf("DC component : %f\n", real_fft_plan->output[0]); // DC is at [0] 30 | for (k = 1 ; k < real_fft_plan->size / 2 ; k++) 31 | printf("%d-th freq : %f+j%f\n", k, real_fft_plan->output[2*k], real_fft_plan->output[2*k+1]); 32 | printf("Middle component : %f\n", real_fft_plan->output[1]); // N/2 is real and stored at [1] 33 | 34 | // Don't forget to clean up at the end to free all the memory that was allocated 35 | fft_destroy(real_fft_plan) 36 | 37 | 38 | Documentation 39 | ------------- 40 | 41 | 1. Create the FFT configuration by running 42 | `fft_init`. 43 | 44 | fft_config_t *fft_init(int size, fft_type_t type, fft_direction_t direction, float *input, float *output) 45 | 46 | Parameters 47 | ---------- 48 | size : int 49 | The FFT size (should be a power of two), if not, returns NULL. 50 | type : fft_type_t 51 | The type of FFT, FFT_REAL or FFT_COMPLEX 52 | direction : fft_direction_t 53 | The direction, FFT_FORWARD or FFT_BACKWARD (inverse transformation) 54 | input : float * 55 | A pointer to a buffer of the correct size. If NULL, a buffer is allocated dynamically 56 | output : float * 57 | A pointer to a buffer of the correct size. If NULL, a buffer is allocated dynamically. 58 | 59 | Returns 60 | ------- 61 | A pointer to an `fft_config_t` structure that holds pointers to the buffers and 62 | all the necessary configuration options. 63 | 64 | 2. Fill data in the `input` buffer 65 | 66 | 3. Call `fft_execute` to run the FFT 67 | 68 | 4. Use the transformed data located in the `output` buffer 69 | 70 | 5. Possibly free up memory by calling `fft_destroy` on the configuration structure 71 | 72 | ### Note about Inverse Real FFT 73 | 74 | When doing an inverse real FFT, the data in the input buffer is destroyed. 75 | 76 | ### Buffer sizes and data organization 77 | 78 | * For `FFT_REAL` FFTs (forward as well as backward) of size `NFFT`, the buffer is of size `NFFT`. 79 | Then, the input data is organized as 80 | 81 | Input : [ x[0], x[1], x[2], ..., x[NFFT-1] ] 82 | Output : [ X[0], X[NFFT/2], Re(X[1]), Im(X[1]), ..., Re(X[NFFT/2-1]), Im(X[NFFT/2-1]) ] 83 | 84 | * For `FFT_COMPLEX` of size `NFFT`, the buffer is of size `2 * NFFT` as both real and imaginary parts should be saved. 85 | 86 | Input : [ Re(x[0]), Im(x[0]), ..., Re(x[NFFT-1]), Im(x[NFFT-1]) ] 87 | Output : [ Re(X[0]), Im(X[0]), ..., Re(X[NFFT-1]), Im(X[NFFT-1]) ] 88 | 89 | License 90 | ------- 91 | 92 | This software is released under the MIT license. 93 | 94 | Copyright (c) 2017 Robin Scheibler 95 | 96 | Permission is hereby granted, free of charge, to any person obtaining a copy 97 | of this software and associated documentation files (the "Software"), to deal 98 | in the Software without restriction, including without limitation the rights 99 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 100 | copies of the Software, and to permit persons to whom the Software is 101 | furnished to do so, subject to the following conditions: 102 | 103 | The above copyright notice and this permission notice shall be included in all 104 | copies or substantial portions of the Software. 105 | 106 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 107 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 108 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 109 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 110 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 111 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 112 | SOFTWARE. 113 | -------------------------------------------------------------------------------- /components/fft/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Main Makefile. This is basically the same as a component makefile. 3 | # 4 | # This Makefile should, at the very least, just include $(SDK_PATH)/make/component_common.mk. By default, 5 | # this will take the sources in the src/ directory, compile them and link them into 6 | # lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable, 7 | # please read the ESP-IDF documents if you need to do this. 8 | # 9 | 10 | COMPONENT_SRCDIRS := . 11 | # CFLAGS += -------------------------------------------------------------------------------- /components/fft/fft.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | ESP32 FFT 4 | ========= 5 | 6 | This provides a vanilla radix-2 FFT implementation and a test example. 7 | 8 | Author 9 | ------ 10 | 11 | This code was written by [Robin Scheibler](http://www.robinscheibler.org) during rainy days in October 2017. 12 | 13 | License 14 | ------- 15 | 16 | Copyright (c) 2017 Robin Scheibler 17 | 18 | Permission is hereby granted, free of charge, to any person obtaining a copy 19 | of this software and associated documentation files (the "Software"), to deal 20 | in the Software without restriction, including without limitation the rights 21 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | copies of the Software, and to permit persons to whom the Software is 23 | furnished to do so, subject to the following conditions: 24 | 25 | The above copyright notice and this permission notice shall be included in all 26 | copies or substantial portions of the Software. 27 | 28 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 | SOFTWARE. 35 | 36 | */ 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "fft.h" 43 | 44 | #define TWO_PI 6.28318530 45 | #define USE_SPLIT_RADIX 1 46 | #define LARGE_BASE_CASE 1 47 | 48 | fft_config_t *fft_init(int size, fft_type_t type, fft_direction_t direction, float *input, float *output) 49 | { 50 | /* 51 | * Prepare an FFT of correct size and types. 52 | * 53 | * If no input or output buffers are provided, they will be allocated. 54 | */ 55 | int k,m; 56 | 57 | fft_config_t *config = (fft_config_t *)malloc(sizeof(fft_config_t)); 58 | 59 | // Check if the size is a power of two 60 | if ((size & (size-1)) != 0) // tests if size is a power of two 61 | return NULL; 62 | 63 | // start configuration 64 | config->flags = 0; 65 | config->type = type; 66 | config->direction = direction; 67 | config->size = size; 68 | 69 | // Allocate and precompute twiddle factors 70 | config->twiddle_factors = (float *)malloc(2 * config->size * sizeof(float)); 71 | 72 | float two_pi_by_n = TWO_PI / config->size; 73 | 74 | for (k = 0, m = 0 ; k < config->size ; k++, m+=2) 75 | { 76 | config->twiddle_factors[m] = cosf(two_pi_by_n * k); // real 77 | config->twiddle_factors[m+1] = sinf(two_pi_by_n * k); // imag 78 | } 79 | 80 | // Allocate input buffer 81 | if (input != NULL) 82 | config->input = input; 83 | else 84 | { 85 | if (config->type == FFT_REAL) 86 | config->input = (float *)malloc(config->size * sizeof(float)); 87 | else if (config->type == FFT_COMPLEX) 88 | config->input = (float *)malloc(2 * config->size * sizeof(float)); 89 | 90 | config->flags |= FFT_OWN_INPUT_MEM; 91 | } 92 | 93 | if (config->input == NULL) 94 | return NULL; 95 | 96 | // Allocate output buffer 97 | if (output != NULL) 98 | config->output = output; 99 | else 100 | { 101 | if (config->type == FFT_REAL) 102 | config->output = (float *)malloc(config->size * sizeof(float)); 103 | else if (config->type == FFT_COMPLEX) 104 | config->output = (float *)malloc(2 * config->size * sizeof(float)); 105 | 106 | config->flags |= FFT_OWN_OUTPUT_MEM; 107 | } 108 | 109 | if (config->output == NULL) 110 | return NULL; 111 | 112 | return config; 113 | } 114 | 115 | void fft_destroy(fft_config_t *config) 116 | { 117 | if (config->flags & FFT_OWN_INPUT_MEM) 118 | free(config->input); 119 | 120 | if (config->flags & FFT_OWN_OUTPUT_MEM) 121 | free(config->output); 122 | 123 | free(config->twiddle_factors); 124 | free(config); 125 | } 126 | 127 | void fft_execute(fft_config_t *config) 128 | { 129 | if (config->type == FFT_REAL && config->direction == FFT_FORWARD) 130 | rfft(config->input, config->output, config->twiddle_factors, config->size); 131 | else if (config->type == FFT_REAL && config->direction == FFT_BACKWARD) 132 | irfft(config->input, config->output, config->twiddle_factors, config->size); 133 | else if (config->type == FFT_COMPLEX && config->direction == FFT_FORWARD) 134 | fft(config->input, config->output, config->twiddle_factors, config->size); 135 | else if (config->type == FFT_COMPLEX && config->direction == FFT_BACKWARD) 136 | ifft(config->input, config->output, config->twiddle_factors, config->size); 137 | } 138 | 139 | void fft(float *input, float *output, float *twiddle_factors, int n) 140 | { 141 | /* 142 | * Forward fast Fourier transform 143 | * DIT, radix-2, out-of-place implementation 144 | * 145 | * Parameters 146 | * ---------- 147 | * input (float *) 148 | * The input array containing the complex samples with 149 | * real/imaginary parts interleaved [Re(x0), Im(x0), ..., Re(x_n-1), Im(x_n-1)] 150 | * output (float *) 151 | * The output array containing the complex samples with 152 | * real/imaginary parts interleaved [Re(x0), Im(x0), ..., Re(x_n-1), Im(x_n-1)] 153 | * n (int) 154 | * The FFT size, should be a power of 2 155 | */ 156 | 157 | #if USE_SPLIT_RADIX 158 | split_radix_fft(input, output, n, 2, twiddle_factors, 2); 159 | #else 160 | fft_primitive(input, output, n, 2, twiddle_factors, 2); 161 | #endif 162 | } 163 | 164 | void ifft(float *input, float *output, float *twiddle_factors, int n) 165 | { 166 | /* 167 | * Inverse fast Fourier transform 168 | * DIT, radix-2, out-of-place implementation 169 | * 170 | * Parameters 171 | * ---------- 172 | * input (float *) 173 | * The input array containing the complex samples with 174 | * real/imaginary parts interleaved [Re(x0), Im(x0), ..., Re(x_n-1), Im(x_n-1)] 175 | * output (float *) 176 | * The output array containing the complex samples with 177 | * real/imaginary parts interleaved [Re(x0), Im(x0), ..., Re(x_n-1), Im(x_n-1)] 178 | * n (int) 179 | * The FFT size, should be a power of 2 180 | */ 181 | ifft_primitive(input, output, n, 2, twiddle_factors, 2); 182 | } 183 | 184 | void rfft(float *x, float *y, float *twiddle_factors, int n) 185 | { 186 | 187 | // This code uses the two-for-the-price-of-one strategy 188 | #if USE_SPLIT_RADIX 189 | split_radix_fft(x, y, n / 2, 2, twiddle_factors, 4); 190 | #else 191 | fft_primitive(x, y, n / 2, 2, twiddle_factors, 4); 192 | #endif 193 | 194 | // Now apply post processing to recover positive 195 | // frequencies of the real FFT 196 | float t = y[0]; 197 | y[0] = t + y[1]; // DC coefficient 198 | y[1] = t - y[1]; // Center coefficient 199 | 200 | // Apply post processing to quarter element 201 | // this boils down to taking complex conjugate 202 | y[n/2+1] = -y[n/2+1]; 203 | 204 | // Now process all the other frequencies 205 | int k; 206 | for (k = 2 ; k < n / 2 ; k += 2) 207 | { 208 | float xer, xei, xor, xoi, c, s, tr, ti; 209 | 210 | c = twiddle_factors[k]; 211 | s = twiddle_factors[k+1]; 212 | 213 | // even half coefficient 214 | xer = 0.5 * (y[k] + y[n-k]); 215 | xei = 0.5 * (y[k+1] - y[n-k+1]); 216 | 217 | // odd half coefficient 218 | xor = 0.5 * (y[k+1] + y[n-k+1]); 219 | xoi = - 0.5 * (y[k] - y[n-k]); 220 | 221 | tr = c * xor + s * xoi; 222 | ti = -s * xor + c * xoi; 223 | 224 | y[k] = xer + tr; 225 | y[k+1] = xei + ti; 226 | 227 | y[n-k] = xer - tr; 228 | y[n-k+1] = -(xei - ti); 229 | } 230 | } 231 | 232 | void irfft(float *x, float *y, float *twiddle_factors, int n) 233 | { 234 | /* 235 | * Destroys content of input vector 236 | */ 237 | int k; 238 | 239 | // Here we need to apply a pre-processing first 240 | float t = x[0]; 241 | x[0] = 0.5 * (t + x[1]); 242 | x[1] = 0.5 * (t - x[1]); 243 | 244 | x[n/2+1] = -x[n/2+1]; 245 | 246 | for (k = 2 ; k < n / 2 ; k += 2) 247 | { 248 | float xer, xei, xor, xoi, c, s, tr, ti; 249 | 250 | c = twiddle_factors[k]; 251 | s = twiddle_factors[k+1]; 252 | 253 | xer = 0.5 * (x[k] + x[n-k]); 254 | tr = 0.5 * (x[k] - x[n-k]); 255 | 256 | xei = 0.5 * (x[k+1] - x[n-k+1]); 257 | ti = 0.5 * (x[k+1] + x[n-k+1]); 258 | 259 | xor = c * tr - s * ti; 260 | xoi = s * tr + c * ti; 261 | 262 | x[k] = xer - xoi; 263 | x[k+1] = xor + xei; 264 | 265 | x[n-k] = xer + xoi; 266 | x[n-k+1] = xor - xei; 267 | } 268 | 269 | ifft_primitive(x, y, n / 2, 2, twiddle_factors, 4); 270 | } 271 | 272 | void fft_primitive(float *x, float *y, int n, int stride, float *twiddle_factors, int tw_stride) 273 | { 274 | /* 275 | * This code will compute the FFT of the input vector x 276 | * 277 | * The input data is assumed to be real/imag interleaved 278 | * 279 | * The size n should be a power of two 280 | * 281 | * y is an output buffer of size 2n to accomodate for complex numbers 282 | * 283 | * Forward fast Fourier transform 284 | * DIT, radix-2, out-of-place implementation 285 | * 286 | * For a complex FFT, call first stage as: 287 | * fft(x, y, n, 2, 2); 288 | * 289 | * Parameters 290 | * ---------- 291 | * x (float *) 292 | * The input array containing the complex samples with 293 | * real/imaginary parts interleaved [Re(x0), Im(x0), ..., Re(x_n-1), Im(x_n-1)] 294 | * y (float *) 295 | * The output array containing the complex samples with 296 | * real/imaginary parts interleaved [Re(x0), Im(x0), ..., Re(x_n-1), Im(x_n-1)] 297 | * n (int) 298 | * The FFT size, should be a power of 2 299 | * stride (int) 300 | * The number of elements to skip between two successive samples 301 | * tw_stride (int) 302 | * The number of elements to skip between two successive twiddle factors 303 | */ 304 | int k; 305 | float t; 306 | 307 | #if LARGE_BASE_CASE 308 | // End condition, stop at n=8 to avoid one trivial recursion 309 | if (n == 8) 310 | { 311 | fft8(x, stride, y, 2); 312 | return; 313 | } 314 | #else 315 | // End condition, stop at n=2 to avoid one trivial recursion 316 | if (n == 2) 317 | { 318 | y[0] = x[0] + x[stride]; 319 | y[1] = x[1] + x[stride + 1]; 320 | y[2] = x[0] - x[stride]; 321 | y[3] = x[1] - x[stride + 1]; 322 | return; 323 | } 324 | #endif 325 | 326 | // Recursion -- Decimation In Time algorithm 327 | fft_primitive(x, y, n / 2, 2 * stride, twiddle_factors, 2 * tw_stride); // even half 328 | fft_primitive(x + stride, y+n, n / 2, 2 * stride, twiddle_factors, 2 * tw_stride); // odd half 329 | 330 | // Stitch back together 331 | 332 | // We can a few multiplications in the first step 333 | t = y[0]; 334 | y[0] = t + y[n]; 335 | y[n] = t - y[n]; 336 | 337 | t = y[1]; 338 | y[1] = t + y[n+1]; 339 | y[n+1] = t - y[n+1]; 340 | 341 | for (k = 1 ; k < n / 2 ; k++) 342 | { 343 | float x1r, x1i, x2r, x2i, c, s; 344 | c = twiddle_factors[k * tw_stride]; 345 | s = twiddle_factors[k * tw_stride + 1]; 346 | 347 | x1r = y[2 * k]; 348 | x1i = y[2 * k + 1]; 349 | x2r = c * y[n + 2 * k] + s * y[n + 2 * k + 1]; 350 | x2i = -s * y[n + 2 * k] + c * y[n + 2 * k + 1]; 351 | 352 | y[2 * k] = x1r + x2r; 353 | y[2 * k + 1] = x1i + x2i; 354 | 355 | y[n + 2 * k] = x1r - x2r; 356 | y[n + 2 * k + 1] = x1i - x2i; 357 | } 358 | 359 | } 360 | 361 | void split_radix_fft(float *x, float *y, int n, int stride, float *twiddle_factors, int tw_stride) 362 | { 363 | /* 364 | * This code will compute the FFT of the input vector x 365 | * 366 | * The input data is assumed to be real/imag interleaved 367 | * 368 | * The size n should be a power of two 369 | * 370 | * y is an output buffer of size 2n to accomodate for complex numbers 371 | * 372 | * Forward fast Fourier transform 373 | * Split-Radix 374 | * DIT, radix-2, out-of-place implementation 375 | * 376 | * For a complex FFT, call first stage as: 377 | * fft(x, y, n, 2, 2); 378 | * 379 | * Parameters 380 | * ---------- 381 | * x (float *) 382 | * The input array containing the complex samples with 383 | * real/imaginary parts interleaved [Re(x0), Im(x0), ..., Re(x_n-1), Im(x_n-1)] 384 | * y (float *) 385 | * The output array containing the complex samples with 386 | * real/imaginary parts interleaved [Re(x0), Im(x0), ..., Re(x_n-1), Im(x_n-1)] 387 | * n (int) 388 | * The FFT size, should be a power of 2 389 | * stride (int) 390 | * The number of elements to skip between two successive samples 391 | * twiddle_factors (float *) 392 | * The array of twiddle factors 393 | * tw_stride (int) 394 | * The number of elements to skip between two successive twiddle factors 395 | */ 396 | int k; 397 | 398 | #if LARGE_BASE_CASE 399 | // End condition, stop at n=2 to avoid one trivial recursion 400 | if (n == 8) 401 | { 402 | fft8(x, stride, y, 2); 403 | return; 404 | } 405 | else if (n == 4) 406 | { 407 | fft4(x, stride, y, 2); 408 | return; 409 | } 410 | #else 411 | // End condition, stop at n=2 to avoid one trivial recursion 412 | if (n == 2) 413 | { 414 | y[0] = x[0] + x[stride]; 415 | y[1] = x[1] + x[stride + 1]; 416 | y[2] = x[0] - x[stride]; 417 | y[3] = x[1] - x[stride + 1]; 418 | return; 419 | } 420 | else if (n == 1) 421 | { 422 | y[0] = x[0]; 423 | y[1] = x[1]; 424 | return; 425 | } 426 | #endif 427 | 428 | // Recursion -- Decimation In Time algorithm 429 | split_radix_fft(x, y, n / 2, 2 * stride, twiddle_factors, 2 * tw_stride); 430 | split_radix_fft(x + stride, y + n, n / 4, 4 * stride, twiddle_factors, 4 * tw_stride); 431 | split_radix_fft(x + 3 * stride, y + n + n / 2, n / 4, 4 * stride, twiddle_factors, 4 * tw_stride); 432 | 433 | // Stitch together the output 434 | float u1r, u1i, u2r, u2i, x1r, x1i, x2r, x2i; 435 | float t; 436 | 437 | // We can save a few multiplications in the first step 438 | u1r = y[0]; 439 | u1i = y[1]; 440 | u2r = y[n / 2]; 441 | u2i = y[n / 2 + 1]; 442 | 443 | x1r = y[n]; 444 | x1i = y[n + 1]; 445 | x2r = y[n / 2 + n]; 446 | x2i = y[n / 2 + n + 1]; 447 | 448 | t = x1r + x2r; 449 | y[0] = u1r + t; 450 | y[n] = u1r - t; 451 | 452 | t = x1i + x2i; 453 | y[1] = u1i + t; 454 | y[n + 1] = u1i - t; 455 | 456 | t = x2i - x1i; 457 | y[n / 2] = u2r - t; 458 | y[n + n / 2] = u2r + t; 459 | 460 | t = x1r - x2r; 461 | y[n / 2 + 1] = u2i - t; 462 | y[n + n / 2 + 1] = u2i + t; 463 | 464 | for (k = 1 ; k < n / 4 ; k++) 465 | { 466 | float u1r, u1i, u2r, u2i, x1r, x1i, x2r, x2i, c1, s1, c2, s2; 467 | c1 = twiddle_factors[k * tw_stride]; 468 | s1 = twiddle_factors[k * tw_stride + 1]; 469 | c2 = twiddle_factors[3 * k * tw_stride]; 470 | s2 = twiddle_factors[3 * k * tw_stride + 1]; 471 | 472 | u1r = y[2 * k]; 473 | u1i = y[2 * k + 1]; 474 | u2r = y[2 * k + n / 2]; 475 | u2i = y[2 * k + n / 2 + 1]; 476 | 477 | x1r = c1 * y[n + 2 * k] + s1 * y[n + 2 * k + 1]; 478 | x1i = -s1 * y[n + 2 * k] + c1 * y[n + 2 * k + 1]; 479 | x2r = c2 * y[n / 2 + n + 2 * k] + s2 * y[n / 2 + n + 2 * k + 1]; 480 | x2i = -s2 * y[n / 2 + n + 2 * k] + c2 * y[n / 2 + n + 2 * k + 1]; 481 | 482 | t = x1r + x2r; 483 | y[2 * k] = u1r + t; 484 | y[2 * k + n] = u1r - t; 485 | 486 | t = x1i + x2i; 487 | y[2 * k + 1] = u1i + t; 488 | y[2 * k + n + 1] = u1i - t; 489 | 490 | t = x2i - x1i; 491 | y[2 * k + n / 2] = u2r - t; 492 | y[2 * k + n + n / 2] = u2r + t; 493 | 494 | t = x1r - x2r; 495 | y[2 * k + n / 2 + 1] = u2i - t; 496 | y[2 * k + n + n / 2 + 1] = u2i + t; 497 | } 498 | 499 | } 500 | 501 | 502 | void ifft_primitive(float *input, float *output, int n, int stride, float *twiddle_factors, int tw_stride) 503 | { 504 | 505 | #if USE_SPLIT_RADIX 506 | split_radix_fft(input, output, n, stride, twiddle_factors, tw_stride); 507 | #else 508 | fft_primitive(input, output, n, stride, twiddle_factors, tw_stride); 509 | #endif 510 | 511 | int ks; 512 | 513 | int ns = n * stride; 514 | 515 | // reverse all coefficients from 1 to n / 2 - 1 516 | for (ks = stride ; ks < ns / 2 ; ks += stride) 517 | { 518 | float t; 519 | 520 | t = output[ks]; 521 | output[ks] = output[ns-ks]; 522 | output[ns-ks] = t; 523 | 524 | t = output[ks+1]; 525 | output[ks+1] = output[ns-ks+1]; 526 | output[ns-ks+1] = t; 527 | } 528 | 529 | // Apply normalization 530 | float norm = 1. / n; 531 | for (ks = 0 ; ks < ns ; ks += stride) 532 | { 533 | output[ks] *= norm; 534 | output[ks+1] *= norm; 535 | } 536 | 537 | } 538 | 539 | inline void fft8(float *input, int stride_in, float *output, int stride_out) 540 | { 541 | /* 542 | * Unrolled implementation of FFT8 for a little more performance 543 | */ 544 | float a0r, a1r, a2r, a3r, a4r, a5r, a6r, a7r; 545 | float a0i, a1i, a2i, a3i, a4i, a5i, a6i, a7i; 546 | float b0r, b1r, b2r, b3r, b4r, b5r, b6r, b7r; 547 | float b0i, b1i, b2i, b3i, b4i, b5i, b6i, b7i; 548 | float t; 549 | float sin_pi_4 = 0.7071067812; 550 | 551 | a0r = input[0]; 552 | a0i = input[1]; 553 | a1r = input[stride_in]; 554 | a1i = input[stride_in+1]; 555 | a2r = input[2*stride_in]; 556 | a2i = input[2*stride_in+1]; 557 | a3r = input[3*stride_in]; 558 | a3i = input[3*stride_in+1]; 559 | a4r = input[4*stride_in]; 560 | a4i = input[4*stride_in+1]; 561 | a5r = input[5*stride_in]; 562 | a5i = input[5*stride_in+1]; 563 | a6r = input[6*stride_in]; 564 | a6i = input[6*stride_in+1]; 565 | a7r = input[7*stride_in]; 566 | a7i = input[7*stride_in+1]; 567 | 568 | // Stage 1 569 | 570 | b0r = a0r + a4r; 571 | b0i = a0i + a4i; 572 | 573 | b1r = a1r + a5r; 574 | b1i = a1i + a5i; 575 | 576 | b2r = a2r + a6r; 577 | b2i = a2i + a6i; 578 | 579 | b3r = a3r + a7r; 580 | b3i = a3i + a7i; 581 | 582 | b4r = a0r - a4r; 583 | b4i = a0i - a4i; 584 | 585 | b5r = a1r - a5r; 586 | b5i = a1i - a5i; 587 | // W_8^1 = 1/sqrt(2) - j / sqrt(2) 588 | t = b5r + b5i; 589 | b5i = (b5i - b5r) * sin_pi_4; 590 | b5r = t * sin_pi_4; 591 | 592 | // W_8^2 = -j 593 | b6r = a2i - a6i; 594 | b6i = a6r - a2r; 595 | 596 | b7r = a3r - a7r; 597 | b7i = a3i - a7i; 598 | // W_8^3 = -1 / sqrt(2) + j / sqrt(2) 599 | t = sin_pi_4 * (b7i - b7r); 600 | b7i = - (b7r + b7i) * sin_pi_4; 601 | b7r = t; 602 | 603 | // Stage 2 604 | 605 | a0r = b0r + b2r; 606 | a0i = b0i + b2i; 607 | 608 | a1r = b1r + b3r; 609 | a1i = b1i + b3i; 610 | 611 | a2r = b0r - b2r; 612 | a2i = b0i - b2i; 613 | 614 | // * j 615 | a3r = b1i - b3i; 616 | a3i = b3r - b1r; 617 | 618 | a4r = b4r + b6r; 619 | a4i = b4i + b6i; 620 | 621 | a5r = b5r + b7r; 622 | a5i = b5i + b7i; 623 | 624 | a6r = b4r - b6r; 625 | a6i = b4i - b6i; 626 | 627 | // * j 628 | a7r = b5i - b7i; 629 | a7i = b7r - b5r; 630 | 631 | // Stage 3 632 | 633 | // X[0] 634 | output[0] = a0r + a1r; 635 | output[1] = a0i + a1i; 636 | 637 | // X[4] 638 | output[4*stride_out] = a0r - a1r; 639 | output[4*stride_out+1] = a0i - a1i; 640 | 641 | // X[2] 642 | output[2*stride_out] = a2r + a3r; 643 | output[2*stride_out+1] = a2i + a3i; 644 | 645 | // X[6] 646 | output[6*stride_out] = a2r - a3r; 647 | output[6*stride_out+1] = a2i - a3i; 648 | 649 | // X[1] 650 | output[stride_out] = a4r + a5r; 651 | output[stride_out+1] = a4i + a5i; 652 | 653 | // X[5] 654 | output[5*stride_out] = a4r - a5r; 655 | output[5*stride_out+1] = a4i - a5i; 656 | 657 | // X[3] 658 | output[3*stride_out] = a6r + a7r; 659 | output[3*stride_out+1] = a6i + a7i; 660 | 661 | // X[7] 662 | output[7*stride_out] = a6r - a7r; 663 | output[7*stride_out+1] = a6i - a7i; 664 | 665 | } 666 | 667 | inline void fft4(float *input, int stride_in, float *output, int stride_out) 668 | { 669 | /* 670 | * Unrolled implementation of FFT4 for a little more performance 671 | */ 672 | float t1, t2; 673 | 674 | t1 = input[0] + input[2*stride_in]; 675 | t2 = input[stride_in] + input[3*stride_in]; 676 | output[0] = t1 + t2; 677 | output[2*stride_out] = t1 - t2; 678 | 679 | t1 = input[1] + input[2*stride_in+1]; 680 | t2 = input[stride_in+1] + input[3*stride_in+1]; 681 | output[1] = t1 + t2; 682 | output[2*stride_out+1] = t1 - t2; 683 | 684 | t1 = input[0] - input[2*stride_in]; 685 | t2 = input[stride_in+1] - input[3*stride_in+1]; 686 | output[stride_out] = t1 + t2; 687 | output[3*stride_out] = t1 - t2; 688 | 689 | t1 = input[1] - input[2*stride_in+1]; 690 | t2 = input[3*stride_in] - input[stride_in]; 691 | output[stride_out+1] = t1 + t2; 692 | output[3*stride_out+1] = t1 - t2; 693 | } 694 | -------------------------------------------------------------------------------- /components/fft/include/fft.h: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | ESP32 FFT 4 | ========= 5 | 6 | This provides a vanilla radix-2 FFT implementation and a test example. 7 | 8 | Author 9 | ------ 10 | 11 | This code was written by [Robin Scheibler](http://www.robinscheibler.org) during rainy days in October 2017. 12 | 13 | License 14 | ------- 15 | 16 | Copyright (c) 2017 Robin Scheibler 17 | 18 | Permission is hereby granted, free of charge, to any person obtaining a copy 19 | of this software and associated documentation files (the "Software"), to deal 20 | in the Software without restriction, including without limitation the rights 21 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 22 | copies of the Software, and to permit persons to whom the Software is 23 | furnished to do so, subject to the following conditions: 24 | 25 | The above copyright notice and this permission notice shall be included in all 26 | copies or substantial portions of the Software. 27 | 28 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 33 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34 | SOFTWARE. 35 | 36 | */ 37 | #ifndef __FFT_H__ 38 | #define __FFT_H__ 39 | 40 | typedef enum 41 | { 42 | FFT_REAL, 43 | FFT_COMPLEX 44 | } fft_type_t; 45 | 46 | typedef enum 47 | { 48 | FFT_FORWARD, 49 | FFT_BACKWARD 50 | } fft_direction_t; 51 | 52 | #define FFT_OWN_INPUT_MEM 1 53 | #define FFT_OWN_OUTPUT_MEM 2 54 | 55 | typedef struct 56 | { 57 | int size; // FFT size 58 | float *input; // pointer to input buffer 59 | float *output; // pointer to output buffer 60 | float *twiddle_factors; // pointer to buffer holding twiddle factors 61 | fft_type_t type; // real or complex 62 | fft_direction_t direction; // forward or backward 63 | unsigned int flags; // FFT flags 64 | } fft_config_t; 65 | 66 | fft_config_t *fft_init(int size, fft_type_t type, fft_direction_t direction, float *input, float *output); 67 | void fft_destroy(fft_config_t *config); 68 | void fft_execute(fft_config_t *config); 69 | void fft(float *input, float *output, float *twiddle_factors, int n); 70 | void ifft(float *input, float *output, float *twiddle_factors, int n); 71 | void rfft(float *x, float *y, float *twiddle_factors, int n); 72 | void irfft(float *x, float *y, float *twiddle_factors, int n); 73 | void fft_primitive(float *x, float *y, int n, int stride, float *twiddle_factors, int tw_stride); 74 | void split_radix_fft(float *x, float *y, int n, int stride, float *twiddle_factors, int tw_stride); 75 | void ifft_primitive(float *input, float *output, int n, int stride, float *twiddle_factors, int tw_stride); 76 | void fft8(float *input, int stride_in, float *output, int stride_out); 77 | void fft4(float *input, int stride_in, float *output, int stride_out); 78 | 79 | #endif // __FFT_H__ 80 | -------------------------------------------------------------------------------- /main/component.mk: -------------------------------------------------------------------------------- 1 | # 2 | # "main" pseudo-component makefile. 3 | # 4 | # (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) 5 | -------------------------------------------------------------------------------- /main/test_fft.c: -------------------------------------------------------------------------------- 1 | /* FFT Example 2 | 3 | This example runs a few FFTs and measure the timing. 4 | 5 | Author: Robin Scheibler, 2017 6 | This code is released under MIT license. See the README for more details.§ 7 | */ 8 | #include 9 | #include 10 | #include "freertos/FreeRTOS.h" 11 | #include "freertos/task.h" 12 | #include "sdkconfig.h" 13 | 14 | #include "soc/timer_group_struct.h" 15 | #include "driver/periph_ctrl.h" 16 | #include "driver/timer.h" 17 | 18 | #include "fft.h" 19 | 20 | /* Can run 'make menuconfig' to choose the GPIO to blink, 21 | or you can edit the following line and set a number here. 22 | */ 23 | #define REP 100 24 | #define MIN_LOG_N 6 25 | #define MAX_LOG_N 12 26 | 27 | #define GPIO_OUTPUT 27 28 | 29 | double start, end; 30 | 31 | timer_config_t timer_config = { 32 | .alarm_en = false, 33 | .counter_en = true, 34 | .counter_dir = TIMER_COUNT_UP, 35 | .divider = 80 /* 1 us per tick */ 36 | }; 37 | 38 | gpio_config_t gpio_conf = { 39 | // disable interrupt 40 | .intr_type = GPIO_PIN_INTR_DISABLE, 41 | //set as output mode 42 | .mode = GPIO_MODE_OUTPUT, 43 | //bit mask of the pins that you want to set,e.g.GPIO18/19 44 | .pin_bit_mask = (1 << GPIO_OUTPUT), 45 | //disable pull-down mode 46 | .pull_down_en = 0, 47 | //disable pull-up mode 48 | .pull_up_en = 0 49 | }; 50 | 51 | 52 | void clock_init() 53 | { 54 | timer_init(TIMER_GROUP_0, TIMER_0, &timer_config); 55 | timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); 56 | timer_start(TIMER_GROUP_0, TIMER_0); 57 | } 58 | 59 | void fft4_test_task() 60 | { 61 | int k; 62 | float input[8] = { 7, 8, 4, 4, 1, 1, 6, 8 }; 63 | float output[8]; 64 | float gt[8] = { 18., 21., 2., 9., -2., -3., 10., 5. }; 65 | 66 | fft4(input, 2, output, 2); 67 | 68 | printf("-----------\n"); 69 | for (k = 0 ; k < 8 ; k+=2) 70 | printf("%.2f%+.2fj ", output[k], output[k+1]); 71 | printf("\n"); 72 | for (k = 0 ; k < 8 ; k+=2) 73 | printf("%.2f%+.2fj ", gt[k], gt[k+1]); 74 | printf("\n"); 75 | printf("-----------\n"); 76 | } 77 | 78 | void fft8_test_task() 79 | { 80 | int k; 81 | float input[16] = { 7, 8, 4, 4, 1, 1, 6, 8, 1, 1, 9, 6, 0, 8, 7, 4 }; 82 | float output[16]; 83 | float gt[16] = { 35., 40., -2.41421356, 6., 5.00000000, 0., 17.24264069, 16.48528137, -17., -4., 0.41421356, 6., 9.00000000, 0., 8.75735931, -0.48528137 }; 84 | 85 | fft8(input, 2, output, 2); 86 | 87 | printf("-----------\n"); 88 | for (k = 0 ; k < 16 ; k+=2) 89 | printf("%.2f+%.2fj ", output[k], output[k+1]); 90 | printf("\n"); 91 | for (k = 0 ; k < 16 ; k+=2) 92 | printf("%.2f+%.2fj ", gt[k], gt[k+1]); 93 | printf("\n"); 94 | printf("-----------\n"); 95 | } 96 | 97 | void fft_test_task() 98 | { 99 | int k, n; 100 | 101 | for (n = MIN_LOG_N ; n <= MAX_LOG_N ; n++) 102 | { 103 | int NFFT = 1 << n; 104 | 105 | // Create fft plan and let it allocate arrays 106 | fft_config_t *fft_analysis = fft_init(NFFT, FFT_COMPLEX, FFT_FORWARD, NULL, NULL); 107 | fft_config_t *fft_synthesis = fft_init(NFFT, FFT_COMPLEX, FFT_BACKWARD, fft_analysis->output, NULL); 108 | 109 | // Fill array with some dummy data 110 | for (k = 0 ; k < fft_analysis->size ; k++) 111 | { 112 | fft_analysis->input[2*k] = (float)k / (float)fft_analysis->size; 113 | fft_analysis->input[2*k+1] = (float)(k-1) / (float)fft_analysis->size; 114 | } 115 | 116 | // Test accuracy 117 | fft_execute(fft_analysis); 118 | fft_execute(fft_synthesis); 119 | 120 | int n_errors = 0; 121 | for (k = 0 ; k < 2 * fft_analysis->size ; k++) 122 | if (abs(fft_analysis->input[k] - fft_synthesis->output[k]) > 1e-5) 123 | { 124 | printf("bin=%d input=%.4f output=%.4f\n err=%f", 125 | k, fft_analysis->input[k], fft_synthesis->output[k], 126 | fabsf(fft_analysis->input[k] - fft_synthesis->output[k])); 127 | n_errors++; 128 | } 129 | if (n_errors == 0) 130 | printf("Transform seems to work!\n"); 131 | 132 | // Now measure execution time 133 | timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &start); 134 | gpio_set_level(GPIO_OUTPUT, 1); 135 | for (k = 0 ; k < REP ; k++) 136 | fft_execute(fft_analysis); 137 | gpio_set_level(GPIO_OUTPUT, 0); 138 | timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &end); 139 | printf(" FFT size=%d runtime=%f ms\n", NFFT, 1000 * (end - start) / REP); 140 | 141 | vTaskDelay(10 / portTICK_RATE_MS); 142 | 143 | timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &start); 144 | gpio_set_level(GPIO_OUTPUT, 1); 145 | for (k = 0 ; k < REP ; k++) 146 | fft_execute(fft_synthesis); 147 | gpio_set_level(GPIO_OUTPUT, 0); 148 | timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &end); 149 | printf("iFFT size=%d runtime=%f ms\n", NFFT, 1000 * (end - start) / REP); 150 | 151 | fft_destroy(fft_analysis); 152 | fft_destroy(fft_synthesis); 153 | } 154 | } 155 | 156 | void rfft_test_task() 157 | { 158 | int k, n; 159 | 160 | for (n = MIN_LOG_N ; n <= MAX_LOG_N ; n++) 161 | { 162 | int NFFT = 1 << n; 163 | 164 | // Create fft plan and let it allocate arrays 165 | fft_config_t *fft_analysis = fft_init(NFFT, FFT_REAL, FFT_FORWARD, NULL, NULL); 166 | fft_config_t *fft_synthesis = fft_init(NFFT, FFT_REAL, FFT_BACKWARD, fft_analysis->output, NULL); 167 | 168 | // Fill array with some dummy data 169 | for (k = 0 ; k < fft_analysis->size ; k++) 170 | fft_analysis->input[k] = (float)k / (float)fft_analysis->size; 171 | 172 | // Test accuracy 173 | fft_execute(fft_analysis); 174 | fft_execute(fft_synthesis); 175 | 176 | int n_errors = 0; 177 | for (k = 0 ; k < fft_analysis->size ; k++) 178 | if (abs(fft_analysis->input[k] - fft_synthesis->output[k]) > 1e-5) 179 | { 180 | printf("bin=%d input=%.4f output=%.4f\n err=%f", 181 | k, fft_analysis->input[k], fft_synthesis->output[k], 182 | fabsf(fft_analysis->input[k] - fft_synthesis->output[k])); 183 | n_errors++; 184 | } 185 | if (n_errors == 0) 186 | printf("Transform seems to work!\n"); 187 | 188 | // Now measure execution time 189 | timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &start); 190 | gpio_set_level(GPIO_OUTPUT, 1); 191 | for (k = 0 ; k < REP ; k++) 192 | fft_execute(fft_analysis); 193 | gpio_set_level(GPIO_OUTPUT, 0); 194 | timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &end); 195 | printf(" Real FFT size=%d runtime=%f ms\n", NFFT, 1000 * (end - start) / REP); 196 | 197 | vTaskDelay(10 / portTICK_RATE_MS); 198 | 199 | timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &start); 200 | gpio_set_level(GPIO_OUTPUT, 1); 201 | for (k = 0 ; k < REP ; k++) 202 | fft_execute(fft_synthesis); 203 | gpio_set_level(GPIO_OUTPUT, 0); 204 | timer_get_counter_time_sec(TIMER_GROUP_0, TIMER_0, &end); 205 | printf("Real iFFT size=%d runtime=%f ms\n", NFFT, 1000 * (end - start) / REP); 206 | 207 | fft_destroy(fft_analysis); 208 | fft_destroy(fft_synthesis); 209 | } 210 | } 211 | 212 | 213 | void app_main() 214 | { 215 | gpio_config(&gpio_conf); 216 | gpio_set_level(GPIO_OUTPUT, 0); 217 | 218 | clock_init(); 219 | 220 | while (1) 221 | { 222 | fft_test_task(); 223 | rfft_test_task(); 224 | //fft8_test_task(); 225 | //fft4_test_task(); 226 | vTaskDelay(1000 / portTICK_RATE_MS); 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /performance/fft_runtime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakufaku/esp32-fft/4cbea56f5bb1a71633156f42ec760b40cc60754f/performance/fft_runtime.png -------------------------------------------------------------------------------- /performance/frame_percent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fakufaku/esp32-fft/4cbea56f5bb1a71633156f42ec760b40cc60754f/performance/frame_percent.png -------------------------------------------------------------------------------- /performance/performance.csv: -------------------------------------------------------------------------------- 1 | algorithm,type,direction,size,runtime [ms] 2 | radix-2,Complex,FFT,64,0.071550 3 | radix-2,Complex,iFFT,64,0.087510 4 | radix-2,Complex,FFT,128,0.164480 5 | radix-2,Complex,iFFT,128,0.193350 6 | radix-2,Complex,FFT,256,0.373940 7 | radix-2,Complex,iFFT,256,0.428130 8 | radix-2,Complex,FFT,512,0.838710 9 | radix-2,Complex,iFFT,512,0.943210 10 | radix-2,Complex,FFT,1024,1.859330 11 | radix-2,Complex,iFFT,1024,2.064680 12 | radix-2,Complex,FFT,2048,4.082970 13 | radix-2,Complex,iFFT,2048,4.490060 14 | radix-2,Complex,FFT,4096,8.895520 15 | radix-2,Complex,iFFT,4096,9.706230 16 | radix-2,Real,FFT,64,0.037980 17 | radix-2,Real,iFFT,64,0.047800 18 | radix-2,Real,FFT,128,0.087430 19 | radix-2,Real,iFFT,128,0.103170 20 | radix-2,Real,FFT,256,0.197360 21 | radix-2,Real,iFFT,256,0.225090 22 | radix-2,Real,FFT,512,0.440110 23 | radix-2,Real,iFFT,512,0.491820 24 | radix-2,Real,FFT,1024,0.971210 25 | radix-2,Real,iFFT,1024,1.070960 26 | radix-2,Real,FFT,2048,2.124690 27 | radix-2,Real,iFFT,2048,2.320580 28 | radix-2,Real,FFT,4096,4.614210 29 | radix-2,Real,iFFT,4096,5.001990 30 | radix-2 large-base,Complex,FFT,64,0.050680 31 | radix-2 large-base,Complex,iFFT,64,0.067380 32 | radix-2 large-base,Complex,FFT,128,0.124200 33 | radix-2 large-base,Complex,iFFT,128,0.153780 34 | radix-2 large-base,Complex,FFT,256,0.293500 35 | radix-2 large-base,Complex,iFFT,256,0.349210 36 | radix-2 large-base,Complex,FFT,512,0.677610 37 | radix-2 large-base,Complex,iFFT,512,0.785430 38 | radix-2 large-base,Complex,FFT,1024,1.537340 39 | radix-2 large-base,Complex,iFFT,1024,1.749170 40 | radix-2 large-base,Complex,FFT,2048,3.439260 41 | radix-2 large-base,Complex,iFFT,2048,3.859080 42 | radix-2 large-base,Complex,FFT,4096,7.607700 43 | radix-2 large-base,Complex,iFFT,4096,8.444080 44 | radix-2 large-base,Real,FFT,64,0.027710 45 | radix-2 large-base,Real,iFFT,64,0.037480 46 | radix-2 large-base,Real,FFT,128,0.066990 47 | radix-2 large-base,Real,iFFT,128,0.083050 48 | radix-2 large-base,Real,FFT,256,0.156960 49 | radix-2 large-base,Real,iFFT,256,0.185450 50 | radix-2 large-base,Real,FFT,512,0.359510 51 | radix-2 large-base,Real,iFFT,512,0.412960 52 | radix-2 large-base,Real,FFT,1024,0.810180 53 | radix-2 large-base,Real,iFFT,1024,0.913200 54 | radix-2 large-base,Real,FFT,2048,1.802790 55 | radix-2 large-base,Real,iFFT,2048,2.004930 56 | radix-2 large-base,Real,FFT,4096,3.970300 57 | radix-2 large-base,Real,iFFT,4096,4.371150 58 | split-radix,Complex,FFT,64,0.064460 59 | split-radix,Complex,iFFT,64,0.081200 60 | split-radix,Complex,FFT,128,0.147280 61 | split-radix,Complex,iFFT,128,0.176860 62 | split-radix,Complex,FFT,256,0.332030 63 | split-radix,Complex,iFFT,256,0.387730 64 | split-radix,Complex,FFT,512,0.738540 65 | split-radix,Complex,iFFT,512,0.846330 66 | split-radix,Complex,FFT,1024,1.628480 67 | split-radix,Complex,iFFT,1024,1.840320 68 | split-radix,Complex,FFT,2048,3.558920 69 | split-radix,Complex,iFFT,2048,3.978830 70 | split-radix,Complex,FFT,4096,7.723840 71 | split-radix,Complex,iFFT,4096,8.560070 72 | split-radix,Real,FFT,64,0.035360 73 | split-radix,Real,iFFT,64,0.045250 74 | split-radix,Real,FFT,128,0.080810 75 | split-radix,Real,iFFT,128,0.096880 76 | split-radix,Real,FFT,256,0.180100 77 | split-radix,Real,iFFT,256,0.208590 78 | split-radix,Real,FFT,512,0.398130 79 | split-radix,Real,iFFT,512,0.451470 80 | split-radix,Real,FFT,1024,0.871140 81 | split-radix,Real,iFFT,1024,0.974060 82 | split-radix,Real,FFT,2048,1.893940 83 | split-radix,Real,iFFT,2048,2.096150 84 | split-radix,Real,FFT,4096,4.090060 85 | split-radix,Real,iFFT,4096,4.490880 86 | split-radix large-base,Complex,FFT,64,0.047070 87 | split-radix large-base,Complex,iFFT,64,0.063390 88 | split-radix large-base,Complex,FFT,128,0.111170 89 | split-radix large-base,Complex,iFFT,128,0.140820 90 | split-radix large-base,Complex,FFT,256,0.260740 91 | split-radix large-base,Complex,iFFT,256,0.316440 92 | split-radix large-base,Complex,FFT,512,0.595650 93 | split-radix large-base,Complex,iFFT,512,0.703430 94 | split-radix large-base,Complex,FFT,1024,1.342810 95 | split-radix large-base,Complex,iFFT,1024,1.554700 96 | split-radix large-base,Complex,FFT,2048,2.987360 97 | split-radix large-base,Complex,iFFT,2048,3.407310 98 | split-radix large-base,Complex,FFT,4096,6.581050 99 | split-radix large-base,Complex,iFFT,4096,7.417370 100 | split-radix large-base,Real,FFT,64,0.026230 101 | split-radix large-base,Real,iFFT,64,0.036000 102 | split-radix large-base,Real,FFT,128,0.062910 103 | split-radix large-base,Real,iFFT,128,0.078980 104 | split-radix large-base,Real,FFT,256,0.143980 105 | split-radix large-base,Real,iFFT,256,0.172490 106 | split-radix large-base,Real,FFT,512,0.326750 107 | split-radix large-base,Real,iFFT,512,0.380100 108 | split-radix large-base,Real,FFT,1024,0.728130 109 | split-radix large-base,Real,iFFT,1024,0.831150 110 | split-radix large-base,Real,FFT,2048,1.608290 111 | split-radix large-base,Real,iFFT,2048,1.810590 112 | split-radix large-base,Real,FFT,4096,3.518550 113 | split-radix large-base,Real,iFFT,4096,3.919390 114 | -------------------------------------------------------------------------------- /sdkconfig: -------------------------------------------------------------------------------- 1 | # 2 | # Automatically generated file; DO NOT EDIT. 3 | # Espressif IoT Development Framework Configuration 4 | # 5 | CONFIG_IDF_TARGET="esp32" 6 | 7 | # 8 | # SDK tool configuration 9 | # 10 | CONFIG_TOOLPREFIX="xtensa-esp32-elf-" 11 | CONFIG_PYTHON="python" 12 | CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y 13 | 14 | # 15 | # Application manager 16 | # 17 | CONFIG_APP_COMPILE_TIME_DATE=y 18 | CONFIG_APP_EXCLUDE_PROJECT_VER_VAR= 19 | CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR= 20 | 21 | # 22 | # Bootloader config 23 | # 24 | CONFIG_LOG_BOOTLOADER_LEVEL_NONE= 25 | CONFIG_LOG_BOOTLOADER_LEVEL_ERROR= 26 | CONFIG_LOG_BOOTLOADER_LEVEL_WARN= 27 | CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y 28 | CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG= 29 | CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE= 30 | CONFIG_LOG_BOOTLOADER_LEVEL=3 31 | CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V= 32 | CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y 33 | CONFIG_BOOTLOADER_FACTORY_RESET= 34 | CONFIG_BOOTLOADER_APP_TEST= 35 | CONFIG_BOOTLOADER_WDT_ENABLE=y 36 | CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE= 37 | CONFIG_BOOTLOADER_WDT_TIME_MS=9000 38 | CONFIG_APP_ROLLBACK_ENABLE= 39 | 40 | # 41 | # Security features 42 | # 43 | CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT= 44 | CONFIG_SECURE_BOOT_ENABLED= 45 | CONFIG_FLASH_ENCRYPTION_ENABLED= 46 | 47 | # 48 | # Serial flasher config 49 | # 50 | CONFIG_ESPTOOLPY_PORT="/dev/tty.SLAB_USBtoUART" 51 | CONFIG_ESPTOOLPY_BAUD_115200B=y 52 | CONFIG_ESPTOOLPY_BAUD_230400B= 53 | CONFIG_ESPTOOLPY_BAUD_921600B= 54 | CONFIG_ESPTOOLPY_BAUD_2MB= 55 | CONFIG_ESPTOOLPY_BAUD_OTHER= 56 | CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 57 | CONFIG_ESPTOOLPY_BAUD=115200 58 | CONFIG_ESPTOOLPY_COMPRESSED=y 59 | CONFIG_FLASHMODE_QIO= 60 | CONFIG_FLASHMODE_QOUT= 61 | CONFIG_FLASHMODE_DIO=y 62 | CONFIG_FLASHMODE_DOUT= 63 | CONFIG_ESPTOOLPY_FLASHMODE="dio" 64 | CONFIG_ESPTOOLPY_FLASHFREQ_80M= 65 | CONFIG_ESPTOOLPY_FLASHFREQ_40M=y 66 | CONFIG_ESPTOOLPY_FLASHFREQ_26M= 67 | CONFIG_ESPTOOLPY_FLASHFREQ_20M= 68 | CONFIG_ESPTOOLPY_FLASHFREQ="40m" 69 | CONFIG_ESPTOOLPY_FLASHSIZE_1MB= 70 | CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y 71 | CONFIG_ESPTOOLPY_FLASHSIZE_4MB= 72 | CONFIG_ESPTOOLPY_FLASHSIZE_8MB= 73 | CONFIG_ESPTOOLPY_FLASHSIZE_16MB= 74 | CONFIG_ESPTOOLPY_FLASHSIZE="2MB" 75 | CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y 76 | CONFIG_ESPTOOLPY_BEFORE_RESET=y 77 | CONFIG_ESPTOOLPY_BEFORE_NORESET= 78 | CONFIG_ESPTOOLPY_BEFORE="default_reset" 79 | CONFIG_ESPTOOLPY_AFTER_RESET=y 80 | CONFIG_ESPTOOLPY_AFTER_NORESET= 81 | CONFIG_ESPTOOLPY_AFTER="hard_reset" 82 | CONFIG_MONITOR_BAUD_9600B= 83 | CONFIG_MONITOR_BAUD_57600B= 84 | CONFIG_MONITOR_BAUD_115200B=y 85 | CONFIG_MONITOR_BAUD_230400B= 86 | CONFIG_MONITOR_BAUD_921600B= 87 | CONFIG_MONITOR_BAUD_2MB= 88 | CONFIG_MONITOR_BAUD_OTHER= 89 | CONFIG_MONITOR_BAUD_OTHER_VAL=115200 90 | CONFIG_MONITOR_BAUD=115200 91 | 92 | # 93 | # Partition Table 94 | # 95 | CONFIG_PARTITION_TABLE_SINGLE_APP=y 96 | CONFIG_PARTITION_TABLE_TWO_OTA= 97 | CONFIG_PARTITION_TABLE_CUSTOM= 98 | CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" 99 | CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" 100 | CONFIG_PARTITION_TABLE_OFFSET=0x8000 101 | CONFIG_PARTITION_TABLE_MD5=y 102 | 103 | # 104 | # Compiler options 105 | # 106 | CONFIG_OPTIMIZATION_LEVEL_DEBUG=y 107 | CONFIG_OPTIMIZATION_LEVEL_RELEASE= 108 | CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y 109 | CONFIG_OPTIMIZATION_ASSERTIONS_SILENT= 110 | CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED= 111 | CONFIG_CXX_EXCEPTIONS= 112 | CONFIG_STACK_CHECK_NONE=y 113 | CONFIG_STACK_CHECK_NORM= 114 | CONFIG_STACK_CHECK_STRONG= 115 | CONFIG_STACK_CHECK_ALL= 116 | CONFIG_STACK_CHECK= 117 | CONFIG_WARN_WRITE_STRINGS= 118 | CONFIG_DISABLE_GCC8_WARNINGS= 119 | 120 | # 121 | # Component config 122 | # 123 | 124 | # 125 | # Application Level Tracing 126 | # 127 | CONFIG_ESP32_APPTRACE_DEST_TRAX= 128 | CONFIG_ESP32_APPTRACE_DEST_NONE=y 129 | CONFIG_ESP32_APPTRACE_ENABLE= 130 | CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y 131 | CONFIG_AWS_IOT_SDK= 132 | 133 | # 134 | # Bluetooth 135 | # 136 | CONFIG_BT_ENABLED= 137 | CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0 138 | CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 139 | CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 140 | CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 141 | CONFIG_BT_RESERVE_DRAM=0 142 | 143 | # 144 | # Driver configurations 145 | # 146 | 147 | # 148 | # ADC configuration 149 | # 150 | CONFIG_ADC_FORCE_XPD_FSM= 151 | CONFIG_ADC2_DISABLE_DAC=y 152 | 153 | # 154 | # SPI configuration 155 | # 156 | CONFIG_SPI_MASTER_IN_IRAM= 157 | CONFIG_SPI_MASTER_ISR_IN_IRAM=y 158 | CONFIG_SPI_SLAVE_IN_IRAM= 159 | CONFIG_SPI_SLAVE_ISR_IN_IRAM=y 160 | 161 | # 162 | # ESP32-specific 163 | # 164 | CONFIG_IDF_TARGET_ESP32=y 165 | CONFIG_ESP32_DEFAULT_CPU_FREQ_80= 166 | CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y 167 | CONFIG_ESP32_DEFAULT_CPU_FREQ_240= 168 | CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 169 | CONFIG_SPIRAM_SUPPORT= 170 | CONFIG_MEMMAP_TRACEMEM= 171 | CONFIG_MEMMAP_TRACEMEM_TWOBANKS= 172 | CONFIG_ESP32_TRAX= 173 | CONFIG_TRACEMEM_RESERVE_DRAM=0x0 174 | 175 | # 176 | # Core dump 177 | # 178 | CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH= 179 | CONFIG_ESP32_ENABLE_COREDUMP_TO_UART= 180 | CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y 181 | CONFIG_ESP32_ENABLE_COREDUMP= 182 | CONFIG_TWO_UNIVERSAL_MAC_ADDRESS= 183 | CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y 184 | CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 185 | CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 186 | CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=4096 187 | CONFIG_MAIN_TASK_STACK_SIZE=4096 188 | CONFIG_IPC_TASK_STACK_SIZE=1024 189 | CONFIG_TIMER_TASK_STACK_SIZE=4096 190 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y 191 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF= 192 | CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR= 193 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF= 194 | CONFIG_NEWLIB_STDIN_LINE_ENDING_LF= 195 | CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y 196 | CONFIG_NEWLIB_NANO_FORMAT= 197 | CONFIG_CONSOLE_UART_DEFAULT=y 198 | CONFIG_CONSOLE_UART_CUSTOM= 199 | CONFIG_CONSOLE_UART_NONE= 200 | CONFIG_CONSOLE_UART_NUM=0 201 | CONFIG_CONSOLE_UART_BAUDRATE=115200 202 | CONFIG_ULP_COPROC_ENABLED= 203 | CONFIG_ULP_COPROC_RESERVE_MEM=0 204 | CONFIG_ESP32_PANIC_PRINT_HALT= 205 | CONFIG_ESP32_PANIC_PRINT_REBOOT=y 206 | CONFIG_ESP32_PANIC_SILENT_REBOOT= 207 | CONFIG_ESP32_PANIC_GDBSTUB= 208 | CONFIG_ESP32_DEBUG_OCDAWARE=y 209 | CONFIG_ESP32_DEBUG_STUBS_ENABLE=y 210 | CONFIG_INT_WDT=y 211 | CONFIG_INT_WDT_TIMEOUT_MS=300 212 | CONFIG_INT_WDT_CHECK_CPU1=y 213 | CONFIG_TASK_WDT=y 214 | CONFIG_TASK_WDT_PANIC= 215 | CONFIG_TASK_WDT_TIMEOUT_S=5 216 | CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y 217 | CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y 218 | CONFIG_BROWNOUT_DET=y 219 | CONFIG_BROWNOUT_DET_LVL_SEL_0=y 220 | CONFIG_BROWNOUT_DET_LVL_SEL_1= 221 | CONFIG_BROWNOUT_DET_LVL_SEL_2= 222 | CONFIG_BROWNOUT_DET_LVL_SEL_3= 223 | CONFIG_BROWNOUT_DET_LVL_SEL_4= 224 | CONFIG_BROWNOUT_DET_LVL_SEL_5= 225 | CONFIG_BROWNOUT_DET_LVL_SEL_6= 226 | CONFIG_BROWNOUT_DET_LVL_SEL_7= 227 | CONFIG_BROWNOUT_DET_LVL=0 228 | CONFIG_REDUCE_PHY_TX_POWER=y 229 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y 230 | CONFIG_ESP32_TIME_SYSCALL_USE_RTC= 231 | CONFIG_ESP32_TIME_SYSCALL_USE_FRC1= 232 | CONFIG_ESP32_TIME_SYSCALL_USE_NONE= 233 | CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y 234 | CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL= 235 | CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC= 236 | CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256= 237 | CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 238 | CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 239 | CONFIG_ESP32_XTAL_FREQ_40=y 240 | CONFIG_ESP32_XTAL_FREQ_26= 241 | CONFIG_ESP32_XTAL_FREQ_AUTO= 242 | CONFIG_ESP32_XTAL_FREQ=40 243 | CONFIG_DISABLE_BASIC_ROM_CONSOLE= 244 | CONFIG_NO_BLOBS= 245 | CONFIG_ESP_TIMER_PROFILING= 246 | CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS= 247 | CONFIG_ESP_ERR_TO_NAME_LOOKUP=y 248 | 249 | # 250 | # Wi-Fi 251 | # 252 | CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 253 | CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 254 | CONFIG_ESP32_WIFI_STATIC_TX_BUFFER= 255 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y 256 | CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 257 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 258 | CONFIG_ESP32_WIFI_CSI_ENABLED= 259 | CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y 260 | CONFIG_ESP32_WIFI_TX_BA_WIN=6 261 | CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y 262 | CONFIG_ESP32_WIFI_RX_BA_WIN=6 263 | CONFIG_ESP32_WIFI_NVS_ENABLED=y 264 | CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y 265 | CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1= 266 | CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 267 | CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE= 268 | 269 | # 270 | # PHY 271 | # 272 | CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y 273 | CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION= 274 | CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 275 | CONFIG_ESP32_PHY_MAX_TX_POWER=20 276 | 277 | # 278 | # Power Management 279 | # 280 | CONFIG_PM_ENABLE= 281 | 282 | # 283 | # ADC-Calibration 284 | # 285 | CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y 286 | CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y 287 | CONFIG_ADC_CAL_LUT_ENABLE=y 288 | 289 | # 290 | # Event Loop Library 291 | # 292 | CONFIG_EVENT_LOOP_PROFILING= 293 | 294 | # 295 | # ESP HTTP client 296 | # 297 | CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y 298 | 299 | # 300 | # HTTP Server 301 | # 302 | CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 303 | CONFIG_HTTPD_MAX_URI_LEN=512 304 | 305 | # 306 | # Ethernet 307 | # 308 | CONFIG_DMA_RX_BUF_NUM=10 309 | CONFIG_DMA_TX_BUF_NUM=10 310 | CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE= 311 | CONFIG_EMAC_CHECK_LINK_PERIOD_MS=2000 312 | CONFIG_EMAC_TASK_PRIORITY=20 313 | CONFIG_EMAC_TASK_STACK_SIZE=3072 314 | 315 | # 316 | # FAT Filesystem support 317 | # 318 | CONFIG_FATFS_CODEPAGE_DYNAMIC= 319 | CONFIG_FATFS_CODEPAGE_437=y 320 | CONFIG_FATFS_CODEPAGE_720= 321 | CONFIG_FATFS_CODEPAGE_737= 322 | CONFIG_FATFS_CODEPAGE_771= 323 | CONFIG_FATFS_CODEPAGE_775= 324 | CONFIG_FATFS_CODEPAGE_850= 325 | CONFIG_FATFS_CODEPAGE_852= 326 | CONFIG_FATFS_CODEPAGE_855= 327 | CONFIG_FATFS_CODEPAGE_857= 328 | CONFIG_FATFS_CODEPAGE_860= 329 | CONFIG_FATFS_CODEPAGE_861= 330 | CONFIG_FATFS_CODEPAGE_862= 331 | CONFIG_FATFS_CODEPAGE_863= 332 | CONFIG_FATFS_CODEPAGE_864= 333 | CONFIG_FATFS_CODEPAGE_865= 334 | CONFIG_FATFS_CODEPAGE_866= 335 | CONFIG_FATFS_CODEPAGE_869= 336 | CONFIG_FATFS_CODEPAGE_932= 337 | CONFIG_FATFS_CODEPAGE_936= 338 | CONFIG_FATFS_CODEPAGE_949= 339 | CONFIG_FATFS_CODEPAGE_950= 340 | CONFIG_FATFS_CODEPAGE=437 341 | CONFIG_FATFS_LFN_NONE=y 342 | CONFIG_FATFS_LFN_HEAP= 343 | CONFIG_FATFS_LFN_STACK= 344 | CONFIG_FATFS_FS_LOCK=0 345 | CONFIG_FATFS_TIMEOUT_MS=10000 346 | CONFIG_FATFS_PER_FILE_CACHE=y 347 | 348 | # 349 | # Modbus configuration 350 | # 351 | CONFIG_MB_QUEUE_LENGTH=20 352 | CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048 353 | CONFIG_MB_SERIAL_BUF_SIZE=256 354 | CONFIG_MB_SERIAL_TASK_PRIO=10 355 | CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT= 356 | CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 357 | CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 358 | CONFIG_MB_CONTROLLER_STACK_SIZE=4096 359 | CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 360 | CONFIG_MB_TIMER_PORT_ENABLED=y 361 | CONFIG_MB_TIMER_GROUP=0 362 | CONFIG_MB_TIMER_INDEX=0 363 | 364 | # 365 | # FreeRTOS 366 | # 367 | CONFIG_FREERTOS_UNICORE= 368 | CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF 369 | CONFIG_FREERTOS_CORETIMER_0=y 370 | CONFIG_FREERTOS_CORETIMER_1= 371 | CONFIG_FREERTOS_HZ=100 372 | CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y 373 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE= 374 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL= 375 | CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y 376 | CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK= 377 | CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y 378 | CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 379 | CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y 380 | CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE= 381 | CONFIG_FREERTOS_ASSERT_DISABLE= 382 | CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024 383 | CONFIG_FREERTOS_ISR_STACKSIZE=1536 384 | CONFIG_FREERTOS_LEGACY_HOOKS= 385 | CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 386 | CONFIG_SUPPORT_STATIC_ALLOCATION= 387 | CONFIG_TIMER_TASK_PRIORITY=1 388 | CONFIG_TIMER_TASK_STACK_DEPTH=2048 389 | CONFIG_TIMER_QUEUE_LENGTH=10 390 | CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 391 | CONFIG_FREERTOS_USE_TRACE_FACILITY= 392 | CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS= 393 | CONFIG_FREERTOS_DEBUG_INTERNALS= 394 | CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y 395 | 396 | # 397 | # Heap memory debugging 398 | # 399 | CONFIG_HEAP_POISONING_DISABLED=y 400 | CONFIG_HEAP_POISONING_LIGHT= 401 | CONFIG_HEAP_POISONING_COMPREHENSIVE= 402 | CONFIG_HEAP_TRACING= 403 | 404 | # 405 | # libsodium 406 | # 407 | CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y 408 | 409 | # 410 | # Log output 411 | # 412 | CONFIG_LOG_DEFAULT_LEVEL_NONE= 413 | CONFIG_LOG_DEFAULT_LEVEL_ERROR= 414 | CONFIG_LOG_DEFAULT_LEVEL_WARN= 415 | CONFIG_LOG_DEFAULT_LEVEL_INFO=y 416 | CONFIG_LOG_DEFAULT_LEVEL_DEBUG= 417 | CONFIG_LOG_DEFAULT_LEVEL_VERBOSE= 418 | CONFIG_LOG_DEFAULT_LEVEL=3 419 | CONFIG_LOG_COLORS=y 420 | 421 | # 422 | # LWIP 423 | # 424 | CONFIG_L2_TO_L3_COPY= 425 | CONFIG_LWIP_IRAM_OPTIMIZATION= 426 | CONFIG_LWIP_MAX_SOCKETS=10 427 | CONFIG_USE_ONLY_LWIP_SELECT= 428 | CONFIG_LWIP_SO_REUSE=y 429 | CONFIG_LWIP_SO_REUSE_RXTOALL=y 430 | CONFIG_LWIP_SO_RCVBUF= 431 | CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 432 | CONFIG_LWIP_IP_FRAG= 433 | CONFIG_LWIP_IP_REASSEMBLY= 434 | CONFIG_LWIP_STATS= 435 | CONFIG_LWIP_ETHARP_TRUST_IP_MAC=y 436 | CONFIG_ESP_GRATUITOUS_ARP=y 437 | CONFIG_GARP_TMR_INTERVAL=60 438 | CONFIG_TCPIP_RECVMBOX_SIZE=32 439 | CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y 440 | CONFIG_LWIP_DHCP_RESTORE_LAST_IP= 441 | 442 | # 443 | # DHCP server 444 | # 445 | CONFIG_LWIP_DHCPS_LEASE_UNIT=60 446 | CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 447 | CONFIG_LWIP_AUTOIP= 448 | CONFIG_LWIP_NETIF_LOOPBACK=y 449 | CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 450 | 451 | # 452 | # TCP 453 | # 454 | CONFIG_LWIP_MAX_ACTIVE_TCP=16 455 | CONFIG_LWIP_MAX_LISTENING_TCP=16 456 | CONFIG_TCP_MAXRTX=12 457 | CONFIG_TCP_SYNMAXRTX=6 458 | CONFIG_TCP_MSS=1436 459 | CONFIG_TCP_MSL=60000 460 | CONFIG_TCP_SND_BUF_DEFAULT=5744 461 | CONFIG_TCP_WND_DEFAULT=5744 462 | CONFIG_TCP_RECVMBOX_SIZE=6 463 | CONFIG_TCP_QUEUE_OOSEQ=y 464 | CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES= 465 | CONFIG_TCP_OVERSIZE_MSS=y 466 | CONFIG_TCP_OVERSIZE_QUARTER_MSS= 467 | CONFIG_TCP_OVERSIZE_DISABLE= 468 | 469 | # 470 | # UDP 471 | # 472 | CONFIG_LWIP_MAX_UDP_PCBS=16 473 | CONFIG_UDP_RECVMBOX_SIZE=6 474 | CONFIG_TCPIP_TASK_STACK_SIZE=2560 475 | CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y 476 | CONFIG_TCPIP_TASK_AFFINITY_CPU0= 477 | CONFIG_TCPIP_TASK_AFFINITY_CPU1= 478 | CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF 479 | CONFIG_PPP_SUPPORT= 480 | 481 | # 482 | # ICMP 483 | # 484 | CONFIG_LWIP_MULTICAST_PING= 485 | CONFIG_LWIP_BROADCAST_PING= 486 | 487 | # 488 | # LWIP RAW API 489 | # 490 | CONFIG_LWIP_MAX_RAW_PCBS=16 491 | 492 | # 493 | # mbedTLS 494 | # 495 | CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y 496 | CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC= 497 | CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC= 498 | CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 499 | CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN= 500 | CONFIG_MBEDTLS_DEBUG= 501 | CONFIG_MBEDTLS_HARDWARE_AES=y 502 | CONFIG_MBEDTLS_HARDWARE_MPI= 503 | CONFIG_MBEDTLS_HARDWARE_SHA= 504 | CONFIG_MBEDTLS_HAVE_TIME=y 505 | CONFIG_MBEDTLS_HAVE_TIME_DATE= 506 | CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y 507 | CONFIG_MBEDTLS_TLS_SERVER_ONLY= 508 | CONFIG_MBEDTLS_TLS_CLIENT_ONLY= 509 | CONFIG_MBEDTLS_TLS_DISABLED= 510 | CONFIG_MBEDTLS_TLS_SERVER=y 511 | CONFIG_MBEDTLS_TLS_CLIENT=y 512 | CONFIG_MBEDTLS_TLS_ENABLED=y 513 | 514 | # 515 | # TLS Key Exchange Methods 516 | # 517 | CONFIG_MBEDTLS_PSK_MODES= 518 | CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y 519 | CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y 520 | CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y 521 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y 522 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y 523 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y 524 | CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y 525 | CONFIG_MBEDTLS_SSL_RENEGOTIATION=y 526 | CONFIG_MBEDTLS_SSL_PROTO_SSL3= 527 | CONFIG_MBEDTLS_SSL_PROTO_TLS1=y 528 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y 529 | CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y 530 | CONFIG_MBEDTLS_SSL_PROTO_DTLS= 531 | CONFIG_MBEDTLS_SSL_ALPN=y 532 | CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y 533 | 534 | # 535 | # Symmetric Ciphers 536 | # 537 | CONFIG_MBEDTLS_AES_C=y 538 | CONFIG_MBEDTLS_CAMELLIA_C= 539 | CONFIG_MBEDTLS_DES_C= 540 | CONFIG_MBEDTLS_RC4_DISABLED=y 541 | CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT= 542 | CONFIG_MBEDTLS_RC4_ENABLED= 543 | CONFIG_MBEDTLS_BLOWFISH_C= 544 | CONFIG_MBEDTLS_XTEA_C= 545 | CONFIG_MBEDTLS_CCM_C=y 546 | CONFIG_MBEDTLS_GCM_C=y 547 | CONFIG_MBEDTLS_RIPEMD160_C= 548 | 549 | # 550 | # Certificates 551 | # 552 | CONFIG_MBEDTLS_PEM_PARSE_C=y 553 | CONFIG_MBEDTLS_PEM_WRITE_C=y 554 | CONFIG_MBEDTLS_X509_CRL_PARSE_C=y 555 | CONFIG_MBEDTLS_X509_CSR_PARSE_C=y 556 | CONFIG_MBEDTLS_ECP_C=y 557 | CONFIG_MBEDTLS_ECDH_C=y 558 | CONFIG_MBEDTLS_ECDSA_C=y 559 | CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y 560 | CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y 561 | CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y 562 | CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y 563 | CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y 564 | CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y 565 | CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y 566 | CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y 567 | CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y 568 | CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y 569 | CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y 570 | CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y 571 | CONFIG_MBEDTLS_ECP_NIST_OPTIM=y 572 | 573 | # 574 | # mDNS 575 | # 576 | CONFIG_MDNS_MAX_SERVICES=10 577 | 578 | # 579 | # ESP-MQTT Configurations 580 | # 581 | CONFIG_MQTT_PROTOCOL_311=y 582 | CONFIG_MQTT_TRANSPORT_SSL=y 583 | CONFIG_MQTT_TRANSPORT_WEBSOCKET=y 584 | CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y 585 | CONFIG_MQTT_USE_CUSTOM_CONFIG= 586 | CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED= 587 | CONFIG_MQTT_CUSTOM_OUTBOX= 588 | 589 | # 590 | # NVS 591 | # 592 | 593 | # 594 | # OpenSSL 595 | # 596 | CONFIG_OPENSSL_DEBUG= 597 | CONFIG_OPENSSL_ASSERT_DO_NOTHING=y 598 | CONFIG_OPENSSL_ASSERT_EXIT= 599 | 600 | # 601 | # PThreads 602 | # 603 | CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 604 | CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=2048 605 | CONFIG_PTHREAD_STACK_MIN=768 606 | CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y 607 | CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0= 608 | CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1= 609 | CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 610 | CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" 611 | 612 | # 613 | # SPI Flash driver 614 | # 615 | CONFIG_SPI_FLASH_VERIFY_WRITE= 616 | CONFIG_SPI_FLASH_ENABLE_COUNTERS= 617 | CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y 618 | CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y 619 | CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS= 620 | CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED= 621 | 622 | # 623 | # SPIFFS Configuration 624 | # 625 | CONFIG_SPIFFS_MAX_PARTITIONS=3 626 | 627 | # 628 | # SPIFFS Cache Configuration 629 | # 630 | CONFIG_SPIFFS_CACHE=y 631 | CONFIG_SPIFFS_CACHE_WR=y 632 | CONFIG_SPIFFS_CACHE_STATS= 633 | CONFIG_SPIFFS_PAGE_CHECK=y 634 | CONFIG_SPIFFS_GC_MAX_RUNS=10 635 | CONFIG_SPIFFS_GC_STATS= 636 | CONFIG_SPIFFS_PAGE_SIZE=256 637 | CONFIG_SPIFFS_OBJ_NAME_LEN=32 638 | CONFIG_SPIFFS_USE_MAGIC=y 639 | CONFIG_SPIFFS_USE_MAGIC_LENGTH=y 640 | CONFIG_SPIFFS_META_LENGTH=4 641 | CONFIG_SPIFFS_USE_MTIME=y 642 | 643 | # 644 | # Debug Configuration 645 | # 646 | CONFIG_SPIFFS_DBG= 647 | CONFIG_SPIFFS_API_DBG= 648 | CONFIG_SPIFFS_GC_DBG= 649 | CONFIG_SPIFFS_CACHE_DBG= 650 | CONFIG_SPIFFS_CHECK_DBG= 651 | CONFIG_SPIFFS_TEST_VISUALISATION= 652 | 653 | # 654 | # TCP/IP Adapter 655 | # 656 | CONFIG_IP_LOST_TIMER_INTERVAL=120 657 | CONFIG_TCPIP_LWIP=y 658 | 659 | # 660 | # Unity unit testing library 661 | # 662 | CONFIG_UNITY_ENABLE_FLOAT=y 663 | CONFIG_UNITY_ENABLE_DOUBLE=y 664 | CONFIG_UNITY_ENABLE_COLOR= 665 | CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y 666 | CONFIG_UNITY_ENABLE_FIXTURE= 667 | 668 | # 669 | # Virtual file system 670 | # 671 | CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y 672 | CONFIG_SUPPORT_TERMIOS=y 673 | 674 | # 675 | # Wear Levelling 676 | # 677 | CONFIG_WL_SECTOR_SIZE_512= 678 | CONFIG_WL_SECTOR_SIZE_4096=y 679 | CONFIG_WL_SECTOR_SIZE=4096 680 | --------------------------------------------------------------------------------