From f8d848f383bcd7e890615f401228e37c62f3e23f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Fri, 27 Jan 2017 01:29:30 +0100 Subject: [PATCH] FIXED STUPID JSON BUG YOOOO --- html/css/app.css | 81 ++++++++------ html/js/app.js | 4 +- html_orig/css/app.css | 81 ++++++++------ html_orig/jssrc/term.js | 4 +- html_orig/sass/_layout.scss | 74 +++++++------ user/ansi_parser.c | 206 ++++++++++++++++++++++++++---------- user/ansi_parser.rl | 51 ++++++++- user/screen.c | 46 +++++--- user/screen.h | 2 +- user/user_main.c | 19 ++-- 10 files changed, 377 insertions(+), 191 deletions(-) diff --git a/html/css/app.css b/html/css/app.css index 5e0927c..ce314f4 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -438,41 +438,52 @@ body { body > * { margin-left: auto; margin-right: auto; } - body h1 { - text-align: center; - font-size: 2.02729em; - margin-top: 0; - margin-bottom: 1rem; } - @media screen and (max-width: 544px) { - body h1 { - font-size: 1.42383em; - margin-bottom: 0.61805rem; } } - @media screen and (min-width: 545px) and (max-width: 1000px) { - body h1 { - font-size: 1.80203em; } } - body h2 { - font-size: 1.26563em; - margin-bottom: 0.61805rem; } - body h2:first-child { - margin-top: 0; } - body td, body th { - padding: 0.38198rem; - white-space: nowrap; } - @media screen and (max-width: 544px) { - body td, body th { - padding: 0.23608rem; } } - body tbody th { - text-align: right; - width: 130px; - color: white; } - @media screen and (max-width: 544px) { - body tbody th { - width: auto; } } - body tbody td input[type="text"], body tbody td input[type="number"] { - width: 10em; } - @media screen and (max-width: 544px) { - body tbody td input[type="text"], body tbody td input[type="number"] { - width: 8em; } } + +h1, h2 { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +h1 { + text-align: center; + font-size: 2.02729em; + margin-top: 0; + margin-bottom: 1rem; } + @media screen and (max-width: 544px) { + h1 { + font-size: 1.42383em; + margin-bottom: 0.61805rem; } } + @media screen and (min-width: 545px) and (max-width: 1000px) { + h1 { + font-size: 1.80203em; } } + +h2 { + font-size: 1.26563em; + margin-bottom: 0.61805rem; } + h2:first-child { + margin-top: 0; } + +td, th { + padding: 0.38198rem; + white-space: nowrap; } + @media screen and (max-width: 544px) { + td, th { + padding: 0.23608rem; } } + +tbody th { + text-align: right; + width: 130px; + color: white; } + @media screen and (max-width: 544px) { + tbody th { + width: auto; } } + +tbody td input[type="text"], tbody td input[type="number"] { + width: 10em; } + @media screen and (max-width: 544px) { + tbody td input[type="text"], tbody td input[type="number"] { + width: 8em; } } #loader { position: absolute; diff --git a/html/js/app.js b/html/js/app.js index aae60c2..bdc2c45 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -894,6 +894,7 @@ $._loader = function(vis) { var W, H; var cursor = {a: false, x: 0, y: 0, suppress: false, hidden: false}; var screen = []; + var blinkIval; /** Colors table */ var CLR = [// dark gray #2E3436 @@ -1071,7 +1072,8 @@ $._loader = function(vis) { } /* Cursor blinking */ - setInterval(function() { + clearInterval(blinkIval); + blinkIval = setInterval(function() { cursor.a = !cursor.a; if (cursor.hidden) { cursor.a = false; diff --git a/html_orig/css/app.css b/html_orig/css/app.css index 5e0927c..ce314f4 100644 --- a/html_orig/css/app.css +++ b/html_orig/css/app.css @@ -438,41 +438,52 @@ body { body > * { margin-left: auto; margin-right: auto; } - body h1 { - text-align: center; - font-size: 2.02729em; - margin-top: 0; - margin-bottom: 1rem; } - @media screen and (max-width: 544px) { - body h1 { - font-size: 1.42383em; - margin-bottom: 0.61805rem; } } - @media screen and (min-width: 545px) and (max-width: 1000px) { - body h1 { - font-size: 1.80203em; } } - body h2 { - font-size: 1.26563em; - margin-bottom: 0.61805rem; } - body h2:first-child { - margin-top: 0; } - body td, body th { - padding: 0.38198rem; - white-space: nowrap; } - @media screen and (max-width: 544px) { - body td, body th { - padding: 0.23608rem; } } - body tbody th { - text-align: right; - width: 130px; - color: white; } - @media screen and (max-width: 544px) { - body tbody th { - width: auto; } } - body tbody td input[type="text"], body tbody td input[type="number"] { - width: 10em; } - @media screen and (max-width: 544px) { - body tbody td input[type="text"], body tbody td input[type="number"] { - width: 8em; } } + +h1, h2 { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + +h1 { + text-align: center; + font-size: 2.02729em; + margin-top: 0; + margin-bottom: 1rem; } + @media screen and (max-width: 544px) { + h1 { + font-size: 1.42383em; + margin-bottom: 0.61805rem; } } + @media screen and (min-width: 545px) and (max-width: 1000px) { + h1 { + font-size: 1.80203em; } } + +h2 { + font-size: 1.26563em; + margin-bottom: 0.61805rem; } + h2:first-child { + margin-top: 0; } + +td, th { + padding: 0.38198rem; + white-space: nowrap; } + @media screen and (max-width: 544px) { + td, th { + padding: 0.23608rem; } } + +tbody th { + text-align: right; + width: 130px; + color: white; } + @media screen and (max-width: 544px) { + tbody th { + width: auto; } } + +tbody td input[type="text"], tbody td input[type="number"] { + width: 10em; } + @media screen and (max-width: 544px) { + tbody td input[type="text"], tbody td input[type="number"] { + width: 8em; } } #loader { position: absolute; diff --git a/html_orig/jssrc/term.js b/html_orig/jssrc/term.js index 9d73eb8..916c2c0 100644 --- a/html_orig/jssrc/term.js +++ b/html_orig/jssrc/term.js @@ -6,6 +6,7 @@ var W, H; var cursor = {a: false, x: 0, y: 0, suppress: false, hidden: false}; var screen = []; + var blinkIval; /** Colors table */ var CLR = [// dark gray #2E3436 @@ -183,7 +184,8 @@ } /* Cursor blinking */ - setInterval(function() { + clearInterval(blinkIval); + blinkIval = setInterval(function() { cursor.a = !cursor.a; if (cursor.hidden) { cursor.a = false; diff --git a/html_orig/sass/_layout.scss b/html_orig/sass/_layout.scss index 9326f07..56c06c3 100644 --- a/html_orig/sass/_layout.scss +++ b/html_orig/sass/_layout.scss @@ -78,55 +78,59 @@ body { margin-left: auto; margin-right: auto; } +} - h1 { - text-align: center; - font-size: fsize(6); - margin-top: 0; - margin-bottom: dist(0); +h1,h2 { + @include noselect(); +} - @include media($phone) { - font-size: fsize(3); - margin-bottom: dist(-1); - } +h1 { + text-align: center; + font-size: fsize(6); + margin-top: 0; + margin-bottom: dist(0); - @include media($tablet) { - font-size: fsize(5); - } + @include media($phone) { + font-size: fsize(3); + margin-bottom: dist(-1); } - h2 { - font-size: fsize(2); - margin-bottom: dist(-1); - &:first-child{margin-top:0} + @include media($tablet) { + font-size: fsize(5); } +} + +h2 { + font-size: fsize(2); + margin-bottom: dist(-1); + &:first-child{margin-top:0} +} - td, th { - padding: dist(-2); - white-space: nowrap; +td, th { + padding: dist(-2); + white-space: nowrap; - @include media($phone) { - padding: dist(-3); - } + @include media($phone) { + padding: dist(-3); } +} - tbody th { - text-align: right; - width: $form-label-w; - color: $c-form-label-fg; +tbody th { + text-align: right; + width: $form-label-w; + color: $c-form-label-fg; - @include media($phone) { - width: auto; - } + @include media($phone) { + width: auto; } +} - tbody td { - input[type="text"], input[type="number"] { - width: 10em; +tbody td { + input[type="text"], input[type="number"] { + width: 10em; - @include media($phone) { - width: 8em; - } + @include media($phone) { + width: 8em; } } } diff --git a/user/ansi_parser.c b/user/ansi_parser.c index 9edd515..9791a7c 100644 --- a/user/ansi_parser.c +++ b/user/ansi_parser.c @@ -182,28 +182,49 @@ handle_plainchar(char c) screen_putchar(c); } +void ICACHE_FLASH_ATTR +handle_OSC_FactoryReset(void) +{ + info("OSC: Factory reset"); + + warn("NOT IMPLEMENTED"); + // TODO +} + +void ICACHE_FLASH_ATTR +handle_OSC_SetScreenSize(int rows, int cols) +{ + info("OSC: Set screen size to %d x %d", rows, cols); + + screen_resize(rows, cols); +} + + /* Ragel constants block */ -/* #line 188 "user/ansi_parser.c" */ +/* #line 206 "user/ansi_parser.c" */ static const char _ansi_actions[] = { 0, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, - 7, 1, 8, 1, 9 + 7, 1, 8, 1, 9, 1, 10 }; static const char _ansi_eof_actions[] = { - 0, 15, 15, 13, 13, 0, 0 + 0, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 0, 0, + 0 }; static const int ansi_start = 1; -static const int ansi_first_final = 5; +static const int ansi_first_final = 14; static const int ansi_error = 0; static const int ansi_en_CSI_body = 3; +static const int ansi_en_OSC_body = 5; static const int ansi_en_main = 1; -/* #line 187 "user/ansi_parser.rl" */ +/* #line 205 "user/ansi_parser.rl" */ /** @@ -240,17 +261,17 @@ ansi_parser(const char *newdata, size_t len) // Init Ragel on the first run if (cs == -1) { -/* #line 244 "user/ansi_parser.c" */ +/* #line 265 "user/ansi_parser.c" */ { cs = ansi_start; } -/* #line 223 "user/ansi_parser.rl" */ +/* #line 241 "user/ansi_parser.rl" */ } // The parser -/* #line 254 "user/ansi_parser.c" */ +/* #line 275 "user/ansi_parser.c" */ { const char *_acts; unsigned int _nacts; @@ -274,79 +295,137 @@ case 2: goto tr2; case 0: goto _out; -case 5: +case 14: if ( (*p) == 27 ) goto tr1; goto tr0; case 3: if ( (*p) == 59 ) - goto tr9; + goto tr8; if ( (*p) < 60 ) { if ( (*p) > 47 ) { if ( 48 <= (*p) && (*p) <= 57 ) - goto tr8; + goto tr7; } else if ( (*p) >= 32 ) - goto tr7; + goto tr6; } else if ( (*p) > 64 ) { if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) - goto tr10; + goto tr9; } else if ( (*p) >= 65 ) - goto tr10; + goto tr9; } else - goto tr7; - goto tr6; + goto tr6; + goto tr2; case 4: if ( (*p) == 59 ) - goto tr9; + goto tr8; if ( (*p) < 65 ) { if ( 48 <= (*p) && (*p) <= 57 ) - goto tr8; + goto tr7; } else if ( (*p) > 90 ) { if ( 97 <= (*p) && (*p) <= 122 ) - goto tr10; + goto tr9; } else - goto tr10; - goto tr6; + goto tr9; + goto tr2; +case 15: + goto tr2; +case 5: + switch( (*p) ) { + case 70: goto tr10; + case 87: goto tr11; + } + goto tr2; case 6: - goto tr6; + if ( (*p) == 82 ) + goto tr12; + goto tr2; +case 7: + switch( (*p) ) { + case 7: goto tr13; + case 27: goto tr14; + } + goto tr2; +case 16: + goto tr2; +case 8: + if ( (*p) == 92 ) + goto tr13; + goto tr2; +case 9: + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr15; + goto tr2; +case 10: + if ( (*p) == 59 ) + goto tr16; + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr15; + goto tr2; +case 11: + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr17; + goto tr2; +case 12: + switch( (*p) ) { + case 7: goto tr18; + case 27: goto tr19; + } + if ( 48 <= (*p) && (*p) <= 57 ) + goto tr17; + goto tr2; +case 13: + if ( (*p) == 92 ) + goto tr18; + goto tr2; } tr2: cs = 0; goto f0; - tr6: cs = 0; goto f5; tr0: cs = 1; goto f1; tr1: cs = 2; goto _again; + tr6: cs = 4; goto f5; tr7: cs = 4; goto f6; tr8: cs = 4; goto f7; - tr9: cs = 4; goto f8; - tr3: cs = 5; goto f2; - tr4: cs = 5; goto f3; - tr5: cs = 5; goto f4; - tr10: cs = 6; goto f9; + tr10: cs = 6; goto _again; + tr12: cs = 7; goto _again; + tr14: cs = 8; goto _again; + tr11: cs = 9; goto _again; + tr15: cs = 10; goto f6; + tr16: cs = 11; goto f7; + tr17: cs = 12; goto f6; + tr19: cs = 13; goto _again; + tr3: cs = 14; goto f2; + tr4: cs = 14; goto f3; + tr5: cs = 14; goto f4; + tr9: cs = 15; goto f8; + tr13: cs = 16; goto f9; + tr18: cs = 16; goto f10; f1: _acts = _ansi_actions + 1; goto execFuncs; f2: _acts = _ansi_actions + 3; goto execFuncs; - f6: _acts = _ansi_actions + 5; goto execFuncs; - f7: _acts = _ansi_actions + 7; goto execFuncs; - f8: _acts = _ansi_actions + 9; goto execFuncs; - f9: _acts = _ansi_actions + 11; goto execFuncs; - f5: _acts = _ansi_actions + 13; goto execFuncs; - f0: _acts = _ansi_actions + 15; goto execFuncs; - f3: _acts = _ansi_actions + 17; goto execFuncs; - f4: _acts = _ansi_actions + 19; goto execFuncs; + f5: _acts = _ansi_actions + 5; goto execFuncs; + f6: _acts = _ansi_actions + 7; goto execFuncs; + f7: _acts = _ansi_actions + 9; goto execFuncs; + f8: _acts = _ansi_actions + 11; goto execFuncs; + f0: _acts = _ansi_actions + 13; goto execFuncs; + f3: _acts = _ansi_actions + 15; goto execFuncs; + f9: _acts = _ansi_actions + 17; goto execFuncs; + f10: _acts = _ansi_actions + 19; goto execFuncs; + f4: _acts = _ansi_actions + 21; goto execFuncs; execFuncs: _nacts = *_acts++; while ( _nacts-- > 0 ) { switch ( *_acts++ ) { case 0: -/* #line 233 "user/ansi_parser.rl" */ +/* #line 251 "user/ansi_parser.rl" */ { handle_plainchar((*p)); } break; case 1: -/* #line 240 "user/ansi_parser.rl" */ +/* #line 258 "user/ansi_parser.rl" */ { /* Reset the CSI builder */ csi_leading = csi_char = 0; @@ -361,13 +440,13 @@ execFuncs: } break; case 2: -/* #line 253 "user/ansi_parser.rl" */ +/* #line 271 "user/ansi_parser.rl" */ { csi_leading = (*p); } break; case 3: -/* #line 257 "user/ansi_parser.rl" */ +/* #line 275 "user/ansi_parser.rl" */ { /* x10 + digit */ if (csi_ni < CSI_N_MAX) { @@ -376,13 +455,13 @@ execFuncs: } break; case 4: -/* #line 264 "user/ansi_parser.rl" */ +/* #line 282 "user/ansi_parser.rl" */ { csi_ni++; } break; case 5: -/* #line 268 "user/ansi_parser.rl" */ +/* #line 286 "user/ansi_parser.rl" */ { csi_char = (*p); @@ -392,33 +471,49 @@ execFuncs: } break; case 6: -/* #line 276 "user/ansi_parser.rl" */ +/* #line 294 "user/ansi_parser.rl" */ { + warn("Invalid escape sequence discarded."); {cs = 1; goto _again;} } break; case 7: -/* #line 280 "user/ansi_parser.rl" */ +/* #line 311 "user/ansi_parser.rl" */ { - {cs = 1; goto _again;} + csi_ni = 0; + + // we reuse the CSI numeric buffer + for(int i = 0; i < CSI_N_MAX; i++) { + csi_n[i] = 0; + } + + {cs = 5; goto _again;} } break; case 8: -/* #line 292 "user/ansi_parser.rl" */ +/* #line 322 "user/ansi_parser.rl" */ { - // TODO implement OS control code parsing + handle_OSC_FactoryReset(); {cs = 1; goto _again;} } break; case 9: -/* #line 297 "user/ansi_parser.rl" */ +/* #line 327 "user/ansi_parser.rl" */ + { + handle_OSC_SetScreenSize(csi_n[0], csi_n[1]); + + {cs = 1; goto _again;} + } + break; + case 10: +/* #line 338 "user/ansi_parser.rl" */ { // Reset screen handle_RESET_cmd(); {cs = 1; goto _again;} } break; -/* #line 422 "user/ansi_parser.c" */ +/* #line 517 "user/ansi_parser.c" */ } } goto _again; @@ -436,18 +531,13 @@ _again: while ( __nacts-- > 0 ) { switch ( *__acts++ ) { case 6: -/* #line 276 "user/ansi_parser.rl" */ - { - {cs = 1; goto _again;} - } - break; - case 7: -/* #line 280 "user/ansi_parser.rl" */ +/* #line 294 "user/ansi_parser.rl" */ { + warn("Invalid escape sequence discarded."); {cs = 1; goto _again;} } break; -/* #line 451 "user/ansi_parser.c" */ +/* #line 541 "user/ansi_parser.c" */ } } } @@ -455,6 +545,6 @@ _again: _out: {} } -/* #line 315 "user/ansi_parser.rl" */ +/* #line 356 "user/ansi_parser.rl" */ } diff --git a/user/ansi_parser.rl b/user/ansi_parser.rl index 46c504d..bab6b71 100644 --- a/user/ansi_parser.rl +++ b/user/ansi_parser.rl @@ -180,6 +180,24 @@ handle_plainchar(char c) screen_putchar(c); } +void ICACHE_FLASH_ATTR +handle_OSC_FactoryReset(void) +{ + info("OSC: Factory reset"); + + warn("NOT IMPLEMENTED"); + // TODO +} + +void ICACHE_FLASH_ATTR +handle_OSC_SetScreenSize(int rows, int cols) +{ + info("OSC: Set screen size to %d x %d", rows, cols); + + screen_resize(rows, cols); +} + + /* Ragel constants block */ %%{ machine ansi; @@ -273,26 +291,49 @@ ansi_parser(const char *newdata, size_t len) fgoto main; } - action CSI_fail { + action errBadSeq { + warn("Invalid escape sequence discarded."); fgoto main; } - action main_fail { + action back2main { fgoto main; } CSI_body := ((32..47|60..64) @CSI_leading)? ((digit @CSI_digit)* ';' @CSI_semi)* - (digit @CSI_digit)* alpha @CSI_end $!CSI_fail; + (digit @CSI_digit)* alpha @CSI_end $!errBadSeq; # --- OSC commands (Operating System Commands) --- # Module parametrisation action OSC_start { - // TODO implement OS control code parsing + csi_ni = 0; + + // we reuse the CSI numeric buffer + for(int i = 0; i < CSI_N_MAX; i++) { + csi_n[i] = 0; + } + + fgoto OSC_body; + } + + action OSC_fr { + handle_OSC_FactoryReset(); + fgoto main; + } + + action OSC_resize { + handle_OSC_SetScreenSize(csi_n[0], csi_n[1]); + fgoto main; } + + OSC_body := ( + ("FR" ('\a' | ESC '\\') @OSC_fr) | + ('W' (digit @CSI_digit)+ ';' @CSI_semi (digit @CSI_digit)+ ('\a' | ESC '\\') @OSC_resize) + ) $!errBadSeq; action RESET_cmd { // Reset screen @@ -309,7 +350,7 @@ ansi_parser(const char *newdata, size_t len) ']' @OSC_start | 'c' @RESET_cmd ) - )+ $!main_fail; + )+ $!errBadSeq; write exec; }%% diff --git a/user/screen.c b/user/screen.c index 5320d39..4f03887 100644 --- a/user/screen.c +++ b/user/screen.c @@ -189,20 +189,28 @@ screen_clear_line(ClearMode mode) /** * Change the screen size * - * @param w - new width - * @param h - new height + * @param cols - new width + * @param rows - new height */ void ICACHE_FLASH_ATTR -screen_resize(Coordinate w, Coordinate h) +screen_resize(Coordinate rows, Coordinate cols) { NOTIFY_LOCK(); // sanitize - if (w < 1) w = 1; - if (h < 1) h = 1; + if (cols < 1 || rows < 1) { + error("Screen size must be positive"); + goto done; + } + + if (cols * rows > MAX_SCREEN_SIZE) { + error("Max screen size exceeded"); + goto done; + } - W = w; - H = h; + W = cols; + H = rows; screen_reset(); +done: NOTIFY_DONE(); } @@ -579,11 +587,11 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data) ss->lastFg = 0; ss->lastChar = '\0'; - bufprint("{\"w\":%d,\"h\":%d,\"x\":%d,\"y\":%d,\"cv\":%d,\"screen\":\"", W, H, cursor.x, cursor.y, cursor.visible); + bufprint("{\n \"w\": %d, \"h\": %d,\n \"x\": %d, \"y\": %d,\n \"cv\": %d,\n \"screen\": \"", W, H, cursor.x, cursor.y, cursor.visible); } int i = ss->index; - while(i < W*H && remain > 6) { + while(i < W*H && remain > 12) { cell = cell0 = &screen[i]; // Count how many times same as previous @@ -598,11 +606,25 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data) } if (repCnt == 0) { + // All this crap is needed because it's JSON and also + // embedded in HTML (hence the angle brackets) + if (cell0->fg == ss->lastFg && cell0->bg == ss->lastBg) { // same colors as previous - bufprint(",%c", cell0->c); + bufprint(","); } else { - bufprint("%X%X%c", cell0->fg, cell0->bg, cell0->c); + bufprint("%X%X", cell0->fg, cell0->bg); + } + + char c = cell0->c; + if (c == '"' || c == '\\') { + bufprint("\\%c", c); + } + else if (c == '<' || c == '>' || c == '\'' || c == '/' || c == '&') { + bufprint("\\u00%02X", (int)c); + } + else { + bufprint("%c", c); } ss->lastFg = cell0->fg; @@ -633,7 +655,7 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data) } if (remain >= 3) { - bufprint("\"}"); + bufprint("\"\n}"); return HTTPD_CGI_DONE; } else { return HTTPD_CGI_MORE; diff --git a/user/screen.h b/user/screen.h index 677b6c4..d8a02ad 100644 --- a/user/screen.h +++ b/user/screen.h @@ -62,7 +62,7 @@ screenSerializeToBuffer(char *buffer, size_t buf_len, void **data); void screen_init(void); /** Change the screen size */ -void screen_resize(Coordinate w, Coordinate h); +void screen_resize(Coordinate rows, Coordinate cols); // --- Clearing --- diff --git a/user/user_main.c b/user/user_main.c index 305c195..0f33295 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -50,17 +50,20 @@ static ETSTimer prHeapTimer; /** Periodically show heap usage */ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) { - static uint32_t cnt = 0; static uint32_t last = 0; - if (cnt == 5) { - uint32_t heap = system_get_free_heap_size(); - dbg("Free heap: %d bytes (~ %d)", heap, (heap-last)); - cnt = 0; - last = heap; + uint32_t heap = system_get_free_heap_size(); + int32_t diff = (heap-last); + const char *cc = "+"; + if (diff<0) cc = ""; + + if (diff == 0) { + dbg("Free heap: %d bytes", heap); + } else { + dbg("Free heap: %d bytes (%s%d)", heap, cc, diff); } - cnt++; + last = heap; } //Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done. @@ -97,7 +100,7 @@ void ICACHE_FLASH_ATTR user_init(void) // Heap use timer & blink os_timer_disarm(&prHeapTimer); os_timer_setfn(&prHeapTimer, prHeapTimerCb, NULL); - os_timer_arm(&prHeapTimer, 1000, 1); + os_timer_arm(&prHeapTimer, 5000, 1); // The terminal screen screen_init();