From dca02976a7a96e72f6c777fff61f42ea3306fe7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Sun, 1 Oct 2017 19:46:14 +0200 Subject: [PATCH] Fixed a horrible MegaBug and added HTTP message sending + D2D sending (no Rx yet) --- libesphttpd | 2 +- user/ansi_parser.c | 50 +++++----- user/ansi_parser.h | 3 + user/ansi_parser.rl | 4 - user/apars_dcs.c | 2 +- user/apars_dcs.h | 2 +- user/apars_pm.c | 20 ++-- user/apars_pm.h | 2 +- user/apars_short.c | 1 + user/apars_string.c | 2 +- user/cgi_d2d.c | 220 ++++++++++++++++++++++++++++++++++++++++++++ user/cgi_d2d.h | 14 +++ user/cgi_sockets.c | 4 +- user/serial.c | 1 - user/uart_buffer.c | 70 +++++++------- user/uart_buffer.h | 2 +- user/uart_handler.c | 6 +- user/version.h | 2 + 18 files changed, 320 insertions(+), 87 deletions(-) create mode 100644 user/cgi_d2d.c create mode 100644 user/cgi_d2d.h diff --git a/libesphttpd b/libesphttpd index 7fce947..a2fe09b 160000 --- a/libesphttpd +++ b/libesphttpd @@ -1 +1 @@ -Subproject commit 7fce9474395e208c83325ff6150fdd21ba16c9a4 +Subproject commit a2fe09bb4d610d08806afcc4cc008fc01c0dcee0 diff --git a/user/ansi_parser.c b/user/ansi_parser.c index 49450d9..a6bbe79 100644 --- a/user/ansi_parser.c +++ b/user/ansi_parser.c @@ -36,10 +36,6 @@ static const int ansi_en_main = 1; /* #line 12 "user/ansi_parser.rl" */ -// Max nr of CSI parameters -#define CSI_N_MAX 10 -#define ANSI_STR_LEN 64 - static volatile int cs = -1; static volatile bool inside_string = false; @@ -123,12 +119,12 @@ ansi_parser(char newchar) // Init Ragel on the first run if (cs == -1) { -/* #line 127 "user/ansi_parser.c" */ +/* #line 123 "user/ansi_parser.c" */ { cs = ansi_start; } -/* #line 101 "user/ansi_parser.rl" */ +/* #line 97 "user/ansi_parser.rl" */ #if DEBUG_ANSI memset(history, 0, sizeof(history)); @@ -209,7 +205,7 @@ ansi_parser(char newchar) // The parser -/* #line 213 "user/ansi_parser.c" */ +/* #line 209 "user/ansi_parser.c" */ { const char *_acts; unsigned int _nacts; @@ -399,7 +395,7 @@ execFuncs: while ( _nacts-- > 0 ) { switch ( *_acts++ ) { case 0: -/* #line 189 "user/ansi_parser.rl" */ +/* #line 185 "user/ansi_parser.rl" */ { ansi_warn("Parser error."); apars_show_context(); @@ -408,7 +404,7 @@ execFuncs: } break; case 1: -/* #line 198 "user/ansi_parser.rl" */ +/* #line 194 "user/ansi_parser.rl" */ { if ((*p) != 0) { apars_handle_plainchar((*p)); @@ -416,7 +412,7 @@ execFuncs: } break; case 2: -/* #line 206 "user/ansi_parser.rl" */ +/* #line 202 "user/ansi_parser.rl" */ { // Reset the CSI builder leadchar = NUL; @@ -433,13 +429,13 @@ execFuncs: } break; case 3: -/* #line 221 "user/ansi_parser.rl" */ +/* #line 217 "user/ansi_parser.rl" */ { leadchar = (*p); } break; case 4: -/* #line 225 "user/ansi_parser.rl" */ +/* #line 221 "user/ansi_parser.rl" */ { if (arg_cnt == 0) arg_cnt = 1; // x10 + digit @@ -449,7 +445,7 @@ execFuncs: } break; case 5: -/* #line 233 "user/ansi_parser.rl" */ +/* #line 229 "user/ansi_parser.rl" */ { if (arg_cnt == 0) arg_cnt = 1; // handle case when first arg is empty arg_cnt++; @@ -457,20 +453,20 @@ execFuncs: } break; case 6: -/* #line 239 "user/ansi_parser.rl" */ +/* #line 235 "user/ansi_parser.rl" */ { interchar = (*p); } break; case 7: -/* #line 243 "user/ansi_parser.rl" */ +/* #line 239 "user/ansi_parser.rl" */ { apars_handle_csi(leadchar, arg, arg_cnt, interchar, (*p)); {cs = 1;goto _again;} } break; case 8: -/* #line 255 "user/ansi_parser.rl" */ +/* #line 251 "user/ansi_parser.rl" */ { leadchar = (*p); str_ni = 0; @@ -480,13 +476,13 @@ execFuncs: } break; case 9: -/* #line 263 "user/ansi_parser.rl" */ +/* #line 259 "user/ansi_parser.rl" */ { string_buffer[str_ni++] = (*p); } break; case 10: -/* #line 267 "user/ansi_parser.rl" */ +/* #line 263 "user/ansi_parser.rl" */ { inside_string = false; string_buffer[str_ni++] = '\0'; @@ -495,41 +491,41 @@ execFuncs: } break; case 11: -/* #line 280 "user/ansi_parser.rl" */ +/* #line 276 "user/ansi_parser.rl" */ { apars_handle_hash_cmd((*p)); {cs = 1;goto _again;} } break; case 12: -/* #line 285 "user/ansi_parser.rl" */ +/* #line 281 "user/ansi_parser.rl" */ { apars_handle_short_cmd((*p)); {cs = 1;goto _again;} } break; case 13: -/* #line 290 "user/ansi_parser.rl" */ +/* #line 286 "user/ansi_parser.rl" */ { apars_handle_space_cmd((*p)); {cs = 1;goto _again;} } break; case 14: -/* #line 297 "user/ansi_parser.rl" */ +/* #line 293 "user/ansi_parser.rl" */ { leadchar = (*p); {cs = 10;goto _again;} } break; case 15: -/* #line 302 "user/ansi_parser.rl" */ +/* #line 298 "user/ansi_parser.rl" */ { apars_handle_chs_designate(leadchar, (*p)); {cs = 1;goto _again;} } break; -/* #line 533 "user/ansi_parser.c" */ +/* #line 529 "user/ansi_parser.c" */ } } goto _again; @@ -547,7 +543,7 @@ _again: while ( __nacts-- > 0 ) { switch ( *__acts++ ) { case 0: -/* #line 189 "user/ansi_parser.rl" */ +/* #line 185 "user/ansi_parser.rl" */ { ansi_warn("Parser error."); apars_show_context(); @@ -557,7 +553,7 @@ _again: goto _again;} } break; -/* #line 561 "user/ansi_parser.c" */ +/* #line 557 "user/ansi_parser.c" */ } } } @@ -565,6 +561,6 @@ goto _again;} _out: {} } -/* #line 325 "user/ansi_parser.rl" */ +/* #line 321 "user/ansi_parser.rl" */ } diff --git a/user/ansi_parser.h b/user/ansi_parser.h index 212aaa4..1aa9528 100644 --- a/user/ansi_parser.h +++ b/user/ansi_parser.h @@ -3,6 +3,9 @@ #include +#define CSI_N_MAX 12 +#define ANSI_STR_LEN 256 + extern volatile bool ansi_parser_inhibit; // discard all characters void ansi_parser_reset(void); diff --git a/user/ansi_parser.rl b/user/ansi_parser.rl index cd1ec26..67b3ef0 100644 --- a/user/ansi_parser.rl +++ b/user/ansi_parser.rl @@ -11,10 +11,6 @@ write data; }%% -// Max nr of CSI parameters -#define CSI_N_MAX 10 -#define ANSI_STR_LEN 64 - static volatile int cs = -1; static volatile bool inside_string = false; diff --git a/user/apars_dcs.c b/user/apars_dcs.c index 7462d26..0bf5129 100644 --- a/user/apars_dcs.c +++ b/user/apars_dcs.c @@ -30,7 +30,7 @@ * @param buffer - the DCS body (after DCS and before ST) */ void ICACHE_FLASH_ATTR -apars_handle_dcs(const char *buffer) +apars_handle_dcs(char *buffer) { char buf[64]; // just about big enough for full-house SGR size_t len = strlen(buffer); diff --git a/user/apars_dcs.h b/user/apars_dcs.h index f9d4ad7..012c6fc 100644 --- a/user/apars_dcs.h +++ b/user/apars_dcs.h @@ -5,6 +5,6 @@ #ifndef ESP_VT100_FIRMWARE_APARS_DCS_H #define ESP_VT100_FIRMWARE_APARS_DCS_H -void apars_handle_dcs(const char *buffer); +void apars_handle_dcs(char *buffer); #endif //ESP_VT100_FIRMWARE_APARS_DCS_H diff --git a/user/apars_pm.c b/user/apars_pm.c index 6defb03..c53ef13 100644 --- a/user/apars_pm.c +++ b/user/apars_pm.c @@ -11,24 +11,24 @@ // #include +#include #include "apars_pm.h" +#include "version.h" #include "ansi_parser_callbacks.h" #include "screen.h" #include "apars_logging.h" +#include "cgi_d2d.h" /** * Helper function to parse incoming DCS (Device Control String) - * @param buffer - the DCS body (after DCS and before ST) + * @param msg - the DCS body (after DCS and before ST) */ void ICACHE_FLASH_ATTR -apars_handle_pm(const char *buffer) +apars_handle_pm(char *msg) { - size_t len = strlen(buffer); - if (false) { - // - } - else { - ansi_warn("Bad DCS: %s", buffer); - apars_show_context(); - } + if (d2d_parse_command(msg)) return; + + return; +fail: + ansi_warn("D2D message error: %s", msg); } diff --git a/user/apars_pm.h b/user/apars_pm.h index 92f7b44..f1b241b 100644 --- a/user/apars_pm.h +++ b/user/apars_pm.h @@ -5,6 +5,6 @@ #ifndef ESP_VT100_FIRMWARE_APARS_PM_H #define ESP_VT100_FIRMWARE_APARS_PM_H -void apars_handle_pm(const char *buffer); +void apars_handle_pm(char *msg); #endif //ESP_VT100_FIRMWARE_APARS_PM_H diff --git a/user/apars_short.c b/user/apars_short.c index e00b2e2..7fb35c5 100644 --- a/user/apars_short.c +++ b/user/apars_short.c @@ -46,6 +46,7 @@ #include "apars_short.h" #include "apars_logging.h" #include "screen.h" +#include "ansi_parser_callbacks.h" // ----- Character Set --- diff --git a/user/apars_string.c b/user/apars_string.c index a4a8781..16bc94f 100644 --- a/user/apars_string.c +++ b/user/apars_string.c @@ -25,7 +25,7 @@ void ICACHE_FLASH_ATTR apars_handle_string_cmd(char leadchar, char *buffer) { switch (leadchar) { - case 'k': // ESC k TITLE ST (defined in GNU screen manpage) + case 'k': // ESC k TITLE ST (defined in GNU screen manpage, probably not standard) screen_set_title(buffer); break; diff --git a/user/cgi_d2d.c b/user/cgi_d2d.c new file mode 100644 index 0000000..cf18c6d --- /dev/null +++ b/user/cgi_d2d.c @@ -0,0 +1,220 @@ +// +// Created by MightyPork on 2017/10/01. +// + +#include +#include "cgi_d2d.h" +#include "apars_logging.h" +#include "version.h" +#include "ansi_parser_callbacks.h" +#include +#include + +#define D2D_TIMEOUT_MS 2000 + +#define D2D_HEADERS \ + "User-Agent: ESPTerm/"FIRMWARE_VERSION"\r\n" \ + "Content-Type: text/plain; charset=utf-8\r\n" \ + "Cache-Control: max-age=0\r\n" + +struct d2d_request_opts { + bool want_body; + bool want_head; + char *nonce; +}; + +static void ICACHE_FLASH_ATTR +requestCb(int http_status, + const char *response_headers, + const char *response_body, + size_t body_size, + void *userArg) +{ + if (userArg == NULL) return; + struct d2d_request_opts *opts = userArg; + + char buff100[100]; + int len = 0; + if (opts->want_head) len += strlen(response_headers); + if (opts->want_body) len += body_size + (opts->want_head*2); + char *bb = buff100; + bb += sprintf(bb, "\x1b^h;%d;", http_status); + const char *comma = ""; + + if (opts->want_head) { + bb += sprintf(bb, "%sH", comma); + comma = ","; + } + + if (opts->want_body) { + bb += sprintf(bb, "%sB", comma); + comma = ","; + } + + if (opts->nonce) { + bb += sprintf(bb, "%sN=%s", comma, opts->nonce); + comma = ","; + } + + if (opts->want_head || opts->want_body) { + bb += sprintf(bb, "%sL=%d", comma, len); + //comma = ","; + } + + // semicolon only if more data is to be sent + if (opts->want_head || opts->want_body) + sprintf(bb, ";"); + + apars_respond(buff100); + + dbg("Response %d, nonce %s", http_status, opts->nonce); + dbg("Headers %s", response_headers); + dbg("Body %s", response_body); + + // head and payload separated by \r\n\r\n (one \r\n is at the end of head - maybe) + if (opts->want_head) { + apars_respond(response_headers); + if(opts->want_body) apars_respond("\r\n"); + } + + if(opts->want_body) { + apars_respond(response_body); + } + + apars_respond("\a"); + + free(opts->nonce); + free(userArg); +} + +bool ICACHE_FLASH_ATTR +d2d_parse_command(char *msg) +{ + char buff40[40]; + char *p; + +#define FIND_NEXT(target, delim) do { \ + p = strchr(msg, (delim)); \ + if (p == NULL) return false; \ + *p = '\0'; \ + (target) = msg; \ + msg = p + 1; \ +} while(0) \ + + if (strstarts(msg, "M;")) { + // Send a esp-esp message + msg += 2; + const char *ip; + FIND_NEXT(ip, ';'); + const char *payload = msg; + + ansi_dbg("D2D Tx,dest=%s,msg=%s", ip, payload); + sprintf(buff40, "http://%s" D2D_MSG_ENDPOINT, ip); + + httpclient_args args; + httpclient_args_init(&args); + args.method = HTTPD_METHOD_POST; + args.body = payload; + args.headers = D2D_HEADERS; + args.timeout = D2D_TIMEOUT_MS; + args.url = buff40; // "escapes scope" warning - can ignore, strdup is used + http_request(&args, NULL); + return true; + } + else if (strstarts(msg, "H;")) { + // Send a esp-esp message + msg += 2; + const char *method = NULL; + const char *params = NULL; + const char *nonce = NULL; + const char *url = NULL; + const char *payload = NULL; + httpd_method methodNum = HTTPD_METHOD_GET; + + FIND_NEXT(method, ';'); + + if (streq(method, "GET")) methodNum = HTTPD_METHOD_GET; + else if (streq(method, "POST")) methodNum = HTTPD_METHOD_POST; + else if (streq(method, "OPTIONS")) methodNum = HTTPD_METHOD_OPTIONS; + else if (streq(method, "PUT")) methodNum = HTTPD_METHOD_PUT; + else if (streq(method, "DELETE")) methodNum = HTTPD_METHOD_DELETE; + else if (streq(method, "PATCH")) methodNum = HTTPD_METHOD_PATCH; + else if (streq(method, "HEAD")) methodNum = HTTPD_METHOD_HEAD; + else { + warn("BAD METHOD: %s, using GET", method); + } + + FIND_NEXT(params, ';'); + + dbg("Method %s", method); + dbg("Params %s", params); + + size_t max_len = HTTPCLIENT_DEF_MAX_LEN; + int timeout = HTTPCLIENT_DEF_TIMEOUT_MS; + bool want_body = 0; + bool want_head = 0; + bool no_resp = 0; + + do { + p = strchr(params, ','); + if (p != NULL) *p = '\0'; + const char *param = params; + if (params[0] == 0) break; // no params + + if(streq(param, "H")) want_head = 1; // Return head + else if(streq(param, "B")) want_body = 1; // Return body + else if(streq(param, "X")) no_resp = 1; // X - no response, no callback + else if(strstarts(param, "L=")) { // max length + max_len = atoi(param+2); + } else if(strstarts(param, "T=")) { // timeout + timeout = atoi(param+2); + } else if(strstarts(param, "N=")) { // Nonce + nonce = param+2; + } else { + warn("BAD PARAM: %s", param); + return false; + } + + dbg("- param %s", params); + + if (p == NULL) break; + params = p + 1; + } while(1); + + p = strchr(msg, '\n'); + if (p != NULL) *p = '\0'; + url = msg; + dbg("URL: %s", url); + + if (p != NULL) { + payload = p + 1; + dbg("Payload: %s", payload); + } else { + payload = NULL; + } + + httpclient_args args; + httpclient_args_init(&args); + args.method = methodNum; + args.body = payload; + args.headers = D2D_HEADERS; + args.timeout = timeout; + args.max_response_len = max_len; + args.url = url; + + if (!no_resp) { + struct d2d_request_opts *opts = malloc(sizeof(struct d2d_request_opts)); + opts->want_body = want_body; + opts->want_head = want_head; + opts->nonce = esp_strdup(nonce); + args.userData = opts; + } + + http_request(&args, no_resp ? NULL : requestCb); + + dbg("Done"); + return true; + } + + return false; +} diff --git a/user/cgi_d2d.h b/user/cgi_d2d.h new file mode 100644 index 0000000..7a22393 --- /dev/null +++ b/user/cgi_d2d.h @@ -0,0 +1,14 @@ +// +// Created by MightyPork on 2017/10/01. +// + +#ifndef ESPTERM_CGI_D2D_H +#define ESPTERM_CGI_D2D_H + +#include + +#define D2D_MSG_ENDPOINT "/api/v1/msg" + +bool d2d_parse_command(char *msg); + +#endif //ESPTERM_CGI_D2D_H diff --git a/user/cgi_sockets.c b/user/cgi_sockets.c index 9d6a087..7a78f95 100644 --- a/user/cgi_sockets.c +++ b/user/cgi_sockets.c @@ -260,7 +260,7 @@ static void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int // TODO base this on the actual buffer empty space, not rx chunk size if ((UART_AsyncTxGetEmptySpace() < 256) && !browser_wants_xon) { - UART_WriteChar(UART1, '-', 100); + //UART_WriteChar(UART1, '-', 100); cgiWebsockBroadcast(URL_WS_UPDATE, "-", 1, 0); browser_wants_xon = true; @@ -365,7 +365,7 @@ ETSTimer xonTim; static void ICACHE_FLASH_ATTR notify_empty_txbuf_cb(void *unused) { - UART_WriteChar(UART1, '+', 100); + //UART_WriteChar(UART1, '+', 100); cgiWebsockBroadcast(URL_WS_UPDATE, "+", 1, 0); resetHeartbeatTimer(); browser_wants_xon = false; diff --git a/user/serial.c b/user/serial.c index 0a960cc..bcbd54c 100644 --- a/user/serial.c +++ b/user/serial.c @@ -92,5 +92,4 @@ void ICACHE_FLASH_ATTR serialInit(void) void ICACHE_FLASH_ATTR UART_HandleRxByte(char c) { ansi_parser(c); - system_soft_wdt_feed(); // so we survive long torrents } diff --git a/user/uart_buffer.c b/user/uart_buffer.c index 20bc3c6..93a770b 100644 --- a/user/uart_buffer.c +++ b/user/uart_buffer.c @@ -8,8 +8,11 @@ #include #include -#define UART_TX_BUFFER_SIZE 512 //Ring buffer length of tx buffer -#define UART_RX_BUFFER_SIZE 600 //Ring buffer length of rx buffer +//#define buf_dbg(format, ...) printf(format "\r\n", ##__VA_ARGS__) +#define buf_dbg(format, ...) (void)format + +#define UART_TX_BUFFER_SIZE 1024 //Ring buffer length of tx buffer +#define UART_RX_BUFFER_SIZE 1024 //Ring buffer length of rx buffer struct UartBuffer { uint32 UartBuffSize; @@ -55,6 +58,13 @@ UART_AsyncBufferInit(uint32 buf_size) } } +static void ICACHE_FLASH_ATTR +UART_AsyncBufferReset(struct UartBuffer *pBuff) +{ + pBuff->pInPos = pBuff->pUartBuff; + pBuff->pOutPos = pBuff->pUartBuff; + pBuff->Space = (uint16) pBuff->UartBuffSize; +} /** * Copy data onto Buffer @@ -67,23 +77,30 @@ UART_WriteToAsyncBuffer(struct UartBuffer *pCur, const char *pdata, uint16 data_ { if (data_len == 0) return; + buf_dbg("WTAB %d, space %d", data_len, pCur->Space); + uint16 tail_len = (uint16) (pCur->pUartBuff + pCur->UartBuffSize - pCur->pInPos); if (tail_len >= data_len) { //do not need to loop back the queue + buf_dbg("tail %d, no fold", tail_len); memcpy(pCur->pInPos, pdata, data_len); pCur->pInPos += (data_len); pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize); pCur->Space -= data_len; } else { + buf_dbg("tail only %d, folding", tail_len); memcpy(pCur->pInPos, pdata, tail_len); + buf_dbg("chunk 1, %d", tail_len); pCur->pInPos += (tail_len); pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize); pCur->Space -= tail_len; + buf_dbg("chunk 2, %d", data_len - tail_len); memcpy(pCur->pInPos, pdata + tail_len, data_len - tail_len); pCur->pInPos += (data_len - tail_len); pCur->pInPos = (pCur->pUartBuff + (pCur->pInPos - pCur->pUartBuff) % pCur->UartBuffSize); pCur->Space -= (data_len - tail_len); } + buf_dbg("new space %d", pCur->Space); } /****************************************************************************** @@ -158,9 +175,8 @@ void UART_RxFifoCollect(void) uint8 fifo_data; fifo_len = (uint8) ((READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT); if (fifo_len >= pRxBuffer->Space) { - // try to read at least the bit we can fifo_len = (uint8) (pRxBuffer->Space - 1); - UART_WriteChar(UART1, '%', 1); + UART_WriteString(UART1, "\r\nRX BUF OVERRUN!!\r\n", 100); // discard contents of the FIFO - would loop forever buf_idx = 0; while (buf_idx < fifo_len) { @@ -199,29 +215,19 @@ u16 ICACHE_FLASH_ATTR UART_AsyncTxGetEmptySpace(void) * @param data_len - can be -1 for strlen */ void ICACHE_FLASH_ATTR -UART_SendAsync(const char *pdata, int16_t data_len) +UART_SendAsync(const char *pdata, int data_len) { - u16 real_len = (u16) data_len; - if (data_len <= 0) real_len = (u16) strlen(pdata); + size_t real_len = (data_len) <= 0 ? strlen(pdata) : (size_t) data_len; -// if (pTxBuffer == NULL) { -// printf("init tx buf\n\r"); -// pTxBuffer = UART_AsyncBufferInit(UART_TX_BUFFER_SIZE); -// if (pTxBuffer != NULL) { -// UART_WriteToAsyncBuffer(pTxBuffer, pdata, real_len); -// } -// else { -// printf("tx alloc fail\r\n"); -// } -// } -// else { - if (real_len <= pTxBuffer->Space) { - UART_WriteToAsyncBuffer(pTxBuffer, pdata, real_len); - } - else { - UART_WriteChar(UART1, '^', 1); - } -// } + buf_dbg("Send Async %d", real_len); + if (real_len <= pTxBuffer->Space) { + buf_dbg("accepted, space %d", pTxBuffer->Space); + UART_WriteToAsyncBuffer(pTxBuffer, pdata, (uint16) real_len); + } + else { + buf_dbg("FULL!"); + UART_WriteString(UART1, "\r\nTX BUF OVERRUN!!\r\n", 100); + } // Here we enable TX empty interrupt that will take care of sending the content SET_PERI_REG_MASK(UART_CONF1(UART0), (UART_TX_EMPTY_THRESH_VAL & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S); @@ -257,8 +263,8 @@ void UART_DispatchFromTxBuffer(uint8 uart_no) uint8 len_tmp; uint16 data_len; -// if (pTxBuffer) { - data_len = (uint8) (pTxBuffer->UartBuffSize - pTxBuffer->Space); + data_len = (uint16) (pTxBuffer->UartBuffSize - pTxBuffer->Space); + buf_dbg("rem %d",data_len); if (data_len > fifo_remain) { len_tmp = fifo_remain; UART_TxFifoEnq(pTxBuffer, len_tmp, uart_no); @@ -268,8 +274,9 @@ void UART_DispatchFromTxBuffer(uint8 uart_no) len_tmp = (uint8) data_len; UART_TxFifoEnq(pTxBuffer, len_tmp, uart_no); - // we get one more IT after fifo ends even if we have 0 more bytes - // for notify + // We get one more IT after fifo ends even if we have 0 more bytes, + // for notify. Otherwise we would say we have space while the FIFO + // was still running if (next_empty_it_only_for_notify) { notify_empty_txbuf(); next_empty_it_only_for_notify = 0; @@ -279,9 +286,4 @@ void UART_DispatchFromTxBuffer(uint8 uart_no) SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); } } - -// } -// else { -// error("pTxBuff null \n\r"); -// } } diff --git a/user/uart_buffer.h b/user/uart_buffer.h index 6b9b362..244b4bf 100644 --- a/user/uart_buffer.h +++ b/user/uart_buffer.h @@ -14,7 +14,7 @@ void UART_AllocBuffers(void); uint16 UART_ReadAsync(char *pdata, uint16 data_len); // write to tx buffer -void UART_SendAsync(const char *pdata, int16_t data_len); +void UART_SendAsync(const char *pdata, int data_len); //move data from uart fifo to rx buffer void UART_RxFifoCollect(void); diff --git a/user/uart_handler.c b/user/uart_handler.c index 1f96d2f..2688379 100755 --- a/user/uart_handler.c +++ b/user/uart_handler.c @@ -25,7 +25,7 @@ static void uart_processTask(os_event_t *events); // Those heavily affect the byte loss ratio #define PROCESS_CHUNK_LEN 1 -#define FIFO_FULL_THRES 32 +#define RX_FIFO_FULL_THRES 16 #define uart_recvTaskPrio 1 #define uart_recvTaskQueueLen 25 @@ -78,8 +78,8 @@ void ICACHE_FLASH_ATTR UART_SetupAsyncReceiver(void) ETS_UART_INTR_ATTACH((void *)uart0_rx_intr_handler, &(UartDev.rcv_buff)); // the buf will be used as an arg // fifo threshold config (max: UART_RXFIFO_FULL_THRHD = 127) - uint32_t conf = ((FIFO_FULL_THRES & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S); - conf |= ((0x10 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S); + uint32_t conf = ((RX_FIFO_FULL_THRES & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S); + conf |= ((0x05 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S); // timeout config conf |= ((0x06 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S); // timeout threshold conf |= UART_RX_TOUT_EN; // enable timeout diff --git a/user/version.h b/user/version.h index 4d20ae7..29abf5a 100644 --- a/user/version.h +++ b/user/version.h @@ -5,6 +5,8 @@ #ifndef ESP_VT100_FIRMWARE_VERSION_H #define ESP_VT100_FIRMWARE_VERSION_H +#include "helpers.h" + #define FW_V_MAJOR 2 #define FW_V_MINOR 1 #define FW_V_PATCH 0