diff --git a/html/console.tpl b/html/console.tpl index 7d9ef2b..57f8aa8 100644 --- a/html/console.tpl +++ b/html/console.tpl @@ -1,10 +1,12 @@ -Console - ESP Link +MCU Console - ESP Link
%topnav%
-

esp link - Debug Console

+

esp link - Microcontroller Console

+

The Microcontroller console shows the last 1024 characters received from UART0, to which +a microcontroller is tpically attached.

 %console%
 
diff --git a/html/favicon.ico b/html/favicon.ico new file mode 100644 index 0000000..a002df3 Binary files /dev/null and b/html/favicon.ico differ diff --git a/html/log.tpl b/html/log.tpl new file mode 100644 index 0000000..d5db1cf --- /dev/null +++ b/html/log.tpl @@ -0,0 +1,14 @@ +Log - ESP Link + + + +
+
%topnav%
+

esp link - Debug Log

+

The debug log shows the 1024 last characters printed by the esp-link software itself to +its own debug log.

+
+%log%
+
+
+ diff --git a/httpd/httpd.c b/httpd/httpd.c index 0fde367..6aabddc 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -63,6 +63,7 @@ static const MimeMap mimeTypes[]={ {"jpg", "image/jpeg"}, {"jpeg", "image/jpeg"}, {"png", "image/png"}, + {"tpl", "text/html; charset=UTF-8"}, {NULL, "text/html"}, //default value }; @@ -214,7 +215,7 @@ void ICACHE_FLASH_ATTR httpdEndHeaders(HttpdConnData *conn) { void ICACHE_FLASH_ATTR httpdRedirect(HttpdConnData *conn, char *newUrl) { char buff[1024]; int l; - l=os_sprintf(buff, "HTTP/1.1 302 Found\r\nServer: esp8266-httpd/"HTTPDVER"\r\nConnection: close\r\nLocation: %s\r\n\r\nMoved to %s\r\n", newUrl, newUrl); + l=os_sprintf(buff, "HTTP/1.0 302 Found\r\nServer: esp8266-httpd/"HTTPDVER"\r\nConnection: close\r\nLocation: %s\r\n\r\nRedirecting to %s\r\n", newUrl, newUrl); httpdSend(conn, buff, l); } diff --git a/httpd/httpdespfs.c b/httpd/httpdespfs.c index 1caf8d8..6f5cf86 100644 --- a/httpd/httpdespfs.c +++ b/httpd/httpdespfs.c @@ -5,9 +5,9 @@ Connector to let httpd use the espfs filesystem to serve the files in it. /* * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): - * Jeroen Domburg wrote this file. As long as you retain - * this notice you can do whatever you want with this stuff. If we meet some day, - * and you think this stuff is worth it, you can buy me a beer in return. + * Jeroen Domburg wrote this file. As long as you retain + * this notice you can do whatever you want with this stuff. If we meet some day, + * and you think this stuff is worth it, you can buy me a beer in return. * ---------------------------------------------------------------------------- */ @@ -30,7 +30,7 @@ int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) { char buff[1024]; char acceptEncodingBuffer[64]; int isGzip; - + if (connData->conn==NULL) { //Connection aborted. Clean up. espFsClose(file); diff --git a/serial/console.c b/serial/console.c new file mode 100644 index 0000000..096f366 --- /dev/null +++ b/serial/console.c @@ -0,0 +1,65 @@ +#include +#include "uart.h" +#include "cgi.h" +#include "console.h" + +// Microcontroller console capturing the last 1024 characters received on the uart so +// they can be shown on a web page + +#define BUF_MAX (1024) +static char console_buf[BUF_MAX]; +static int console_wr, console_rd; +static int console_pos; // offset since reset of console_rd position + +static void ICACHE_FLASH_ATTR +console_write(char c) { + int wr = (console_wr+1)%BUF_MAX; + if (wr == console_rd) { + console_rd = (console_rd+1) % BUF_MAX; // full, eat first char + console_pos++; + } + console_buf[console_wr] = c; + console_wr = wr; +} + +// return previous character in console, 0 if at start +static char ICACHE_FLASH_ATTR +console_prev(void) { + if (console_wr == console_rd) return 0; + return console_buf[(console_wr+1+BUF_MAX)%BUF_MAX]; +} + +void ICACHE_FLASH_ATTR +console_write_char(char c) { + if (c == '\n' && console_prev() != '\r') console_write('\r'); + console_write(c); +} + +//===== Display a web page with the console +int ICACHE_FLASH_ATTR +tplConsole(HttpdConnData *connData, char *token, void **arg) { + if (token==NULL) return HTTPD_CGI_DONE; + char buff[256]; + + if (os_strcmp(token, "console") == 0) { + if (console_wr > console_rd) { + httpdSend(connData, console_buf+console_rd, console_wr-console_rd); + } else if (console_rd != console_wr) { + httpdSend(connData, console_buf+console_rd, BUF_MAX-console_rd); + httpdSend(connData, console_buf, console_wr); + } + } else if (os_strcmp(token, "topnav")==0) { + printNav(buff); + httpdSend(connData, buff, -1); + } else { + httpdSend(connData, "Unknown\n", -1); + } + return HTTPD_CGI_DONE; +} + +void ICACHE_FLASH_ATTR consoleInit() { + console_wr = 0; + console_rd = 0; +} + + diff --git a/user/console.h b/serial/console.h similarity index 75% rename from user/console.h rename to serial/console.h index b51d3a3..325377f 100644 --- a/user/console.h +++ b/serial/console.h @@ -4,7 +4,7 @@ #include "httpd.h" void consoleInit(void); -void ICACHE_FLASH_ATTR console_uart(bool enable); +void ICACHE_FLASH_ATTR console_write_char(char c); int tplConsole(HttpdConnData *connData, char *token, void **arg); #endif diff --git a/serial/serbridge.c b/serial/serbridge.c index 1bce1fa..bec6545 100644 --- a/serial/serbridge.c +++ b/serial/serbridge.c @@ -8,6 +8,7 @@ #include "uart.h" #include "serbridge.h" +#include "console.h" #if 1 // GPIO for esp-03 module with gpio12->reset, gpio13->isp, gpio2->"ser" LED @@ -290,11 +291,12 @@ static void ICACHE_FLASH_ATTR serbridgeConnectCb(void *arg) { // callback with a buffer of characters that have arrived on the uart void ICACHE_FLASH_ATTR serbridgeUartCb(char *buf, int length) { + // push the buffer into the microcontroller console + for (int i=0; i #include "cgi.h" -#include "io.h" //cause I can't be bothered to write an ioGetLed() @@ -34,7 +33,7 @@ int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) { len=httpdFindArg(connData->post->buff, "led", buff, sizeof(buff)); if (len!=0) { currLedState=atoi(buff); - ioLed(currLedState); + //ioLed(currLedState); } httpdRedirect(connData, "led.tpl"); @@ -82,8 +81,8 @@ int ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **ar } static char *navLinks[][2] = { - { "Home", "/index.tpl" }, { "Wifi", "/wifi/wifi.tpl" }, { "Serial", "/index.tpl" }, - { "Esp log", "/console.tpl" }, { "Help", "/help.tpl" }, + { "Home", "/index.tpl" }, { "Wifi", "/wifi/wifi.tpl" }, { "\xC2\xB5""C Console", "/console.tpl" }, + { "Esp log", "/log.tpl" }, { "Help", "/help.tpl" }, { 0, 0 }, }; diff --git a/user/cgiwifi.c b/user/cgiwifi.c index d468ff2..feb677d 100644 --- a/user/cgiwifi.c +++ b/user/cgiwifi.c @@ -16,7 +16,7 @@ Cgi/template routines for the /wifi url. #include "cgiwifi.h" #include "cgi.h" #include "status.h" -#include "console.h" +#include "log.h" //Enable this to disallow any changes in AP settings //#define DEMO_MODE @@ -239,17 +239,15 @@ static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) { wifi_set_opmode(1); os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); } - os_printf("Turning off uart console\n"); - os_delay_us(4*1000L); // time for uart to flush - console_uart(false); + log_uart(false); // no more resetTimer at this point, gotta use physical reset to recover if in trouble } else { if (m != 3) { os_printf("Wifi connect failed. Going into STA+AP mode..\n"); wifi_set_opmode(3); } - console_uart(true); - os_printf("Enabling/continuing uart console\n"); + log_uart(true); + os_printf("Enabling/continuing uart log\n"); os_timer_arm(&resetTimer, RESET_TIMEOUT, 0); } } diff --git a/user/console.c b/user/console.c index 955d1ad..0e32c08 100644 --- a/user/console.c +++ b/user/console.c @@ -3,63 +3,35 @@ #include "cgi.h" #include "console.h" -// Web console for the esp8266 to replace outputting to uart1. -// The web console has a 1KB circular in-memory buffer which os_printf prints into and -// the HTTP handler simply displays the buffer content on a web page. +// Microcontroller console capturing the last 1024 characters received on the uart so +// they can be shown on a web page #define BUF_MAX (1024) static char console_buf[BUF_MAX]; static int console_wr, console_rd; -static bool console_no_uart; // start out printing to uart -static bool console_newline; // at start of a new line - -void ICACHE_FLASH_ATTR -console_uart(bool enable) { - if (!enable && !console_no_uart) { - os_printf("Turning OFF uart console\n"); - os_delay_us(4*1000L); // time for uart to flush - console_no_uart = !enable; - } else if (enable && console_no_uart) { - console_no_uart = !enable; - os_printf("Turning ON uart console\n"); - } -} +static int console_pos; // offset since reset of console_rd position static void ICACHE_FLASH_ATTR console_write(char c) { int wr = (console_wr+1)%BUF_MAX; - if (wr == console_rd) + if (wr == console_rd) { console_rd = (console_rd+1) % BUF_MAX; // full, eat first char + console_pos++; + } console_buf[console_wr] = c; console_wr = wr; } -#if 0 +// return previous character in console, 0 if at start static char ICACHE_FLASH_ATTR -console_read(void) { - char c = 0; - if (console_rd != console_wr) { - c = console_buf[console_rd]; - console_rd = (console_rd+1) % BUF_MAX; - } - return c; +console_prev(void) { + if (console_wr == console_rd) return 0; + return console_buf[(console_wr-1+BUF_MAX)%BUF_MAX]; } -#endif -static void ICACHE_FLASH_ATTR +void ICACHE_FLASH_ATTR console_write_char(char c) { - // Uart output unless disabled - if (!console_no_uart) { - if (console_newline) { - uart0_write_char('>'); - uart0_write_char(' '); - console_newline = false; - } - uart0_write_char(c); - console_newline = c == '\n'; - } - // Store in console buffer - if (c == '\n') console_write('\r'); + if (c == '\n' && console_prev() != '\r') console_write('\r'); console_write(c); } @@ -88,7 +60,6 @@ tplConsole(HttpdConnData *connData, char *token, void **arg) { void ICACHE_FLASH_ATTR consoleInit() { console_wr = 0; console_rd = 0; - os_install_putc1((void *)console_write_char); } diff --git a/user/io.c b/user/io.c deleted file mode 100644 index a342dbd..0000000 --- a/user/io.c +++ /dev/null @@ -1,51 +0,0 @@ - -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * Jeroen Domburg wrote this file. As long as you retain - * this notice you can do whatever you want with this stuff. If we meet some day, - * and you think this stuff is worth it, you can buy me a beer in return. - * ---------------------------------------------------------------------------- - */ - - -#include - -#define LEDGPIO 2 -#define BTNGPIO 0 - -static ETSTimer resetBtntimer; - -void ICACHE_FLASH_ATTR ioLed(int ena) { - //gpio_output_set is overkill. ToDo: use better mactos - if (ena) { - gpio_output_set((1<=6) { //3 sec pressed - wifi_station_disconnect(); - wifi_set_opmode(0x3); //reset to AP+STA mode - os_printf("Reset to AP mode. Restarting system...\n"); - system_restart(); - } - resetCnt=0; - } -} - -void ioInit() { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); - gpio_output_set(0, 0, (1< +#include "uart.h" +#include "cgi.h" +#include "log.h" + +// Web log for the esp8266 to replace outputting to uart1. +// The web log has a 1KB circular in-memory buffer which os_printf prints into and +// the HTTP handler simply displays the buffer content on a web page. + +#define BUF_MAX (1024) +static char log_buf[BUF_MAX]; +static int log_wr, log_rd; +static bool log_no_uart; // start out printing to uart +static bool log_newline; // at start of a new line + +void ICACHE_FLASH_ATTR +log_uart(bool enable) { + if (!enable && !log_no_uart) { + os_printf("Turning OFF uart log\n"); + os_delay_us(4*1000L); // time for uart to flush + log_no_uart = !enable; + } else if (enable && log_no_uart) { + log_no_uart = !enable; + os_printf("Turning ON uart log\n"); + } +} + +static void ICACHE_FLASH_ATTR +log_write(char c) { + int wr = (log_wr+1)%BUF_MAX; + if (wr == log_rd) + log_rd = (log_rd+1) % BUF_MAX; // full, eat first char + log_buf[log_wr] = c; + log_wr = wr; +} + +#if 0 +static char ICACHE_FLASH_ATTR +log_read(void) { + char c = 0; + if (log_rd != log_wr) { + c = log_buf[log_rd]; + log_rd = (log_rd+1) % BUF_MAX; + } + return c; +} +#endif + +static void ICACHE_FLASH_ATTR +log_write_char(char c) { + // Uart output unless disabled + if (!log_no_uart) { + if (log_newline) { + uart0_write_char('>'); + uart0_write_char(' '); + log_newline = false; + } + uart0_write_char(c); + log_newline = c == '\n'; + } + // Store in log buffer + if (c == '\n') log_write('\r'); + log_write(c); +} + +//===== Display a web page with the log +int ICACHE_FLASH_ATTR +tplLog(HttpdConnData *connData, char *token, void **arg) { + if (token==NULL) return HTTPD_CGI_DONE; + char buff[256]; + + if (os_strcmp(token, "log") == 0) { + if (log_wr > log_rd) { + httpdSend(connData, log_buf+log_rd, log_wr-log_rd); + } else if (log_rd != log_wr) { + httpdSend(connData, log_buf+log_rd, BUF_MAX-log_rd); + httpdSend(connData, log_buf, log_wr); + } + } else if (os_strcmp(token, "topnav")==0) { + printNav(buff); + httpdSend(connData, buff, -1); + } else { + httpdSend(connData, "Unknown\n", -1); + } + return HTTPD_CGI_DONE; +} + +void ICACHE_FLASH_ATTR logInit() { + log_wr = 0; + log_rd = 0; + os_install_putc1((void *)log_write_char); +} + + diff --git a/user/log.h b/user/log.h new file mode 100644 index 0000000..fbeb18e --- /dev/null +++ b/user/log.h @@ -0,0 +1,10 @@ +#ifndef LOG_H +#define LOG_H + +#include "httpd.h" + +void logInit(void); +void ICACHE_FLASH_ATTR log_uart(bool enable); +int tplLog(HttpdConnData *connData, char *token, void **arg); + +#endif diff --git a/user/stdout.c b/user/stdout.c deleted file mode 100644 index ce1a1b6..0000000 --- a/user/stdout.c +++ /dev/null @@ -1,47 +0,0 @@ -//Stupid bit of code that does the bare minimum to make os_printf work. - -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * Jeroen Domburg wrote this file. As long as you retain - * this notice you can do whatever you want with this stuff. If we meet some day, - * and you think this stuff is worth it, you can buy me a beer in return. - * ---------------------------------------------------------------------------- - */ - - -#include - -static void ICACHE_FLASH_ATTR stdoutUartTxd(char c) { - //Wait until there is room in the FIFO - while (((READ_PERI_REG(UART_STATUS(0))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT)>=126) ; - //Send the character - WRITE_PERI_REG(UART_FIFO(0), c); -} - -static void ICACHE_FLASH_ATTR stdoutPutchar(char c) { - //convert \n -> \r\n - if (c=='\n') stdoutUartTxd('\r'); - stdoutUartTxd(c); -} - - -void stdoutInit() { - //Enable TxD pin - PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); - - //Set baud rate and other serial parameters to 115200,n,8,1 - uart_div_modify(0, UART_CLK_FREQ/BIT_RATE_115200); - WRITE_PERI_REG(UART_CONF0(0), (STICK_PARITY_DIS)|(ONE_STOP_BIT << UART_STOP_BIT_NUM_S)| \ - (EIGHT_BITS << UART_BIT_NUM_S)); - - //Reset tx & rx fifo - SET_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST); - CLEAR_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST); - //Clear pending interrupts - WRITE_PERI_REG(UART_INT_CLR(0), 0xffff); - - //Install our own putchar handler - os_install_putc1((void *)stdoutPutchar); -} diff --git a/user/stdout.h b/user/stdout.h deleted file mode 100644 index a8d872d..0000000 --- a/user/stdout.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef STDOUT_H -#define STDOUT_H - -void stdoutInit(); - -#endif \ No newline at end of file diff --git a/user/user_main.c b/user/user_main.c index 586a7e7..219eea4 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -12,18 +12,17 @@ #include #include "httpd.h" -#include "io.h" #include "httpdespfs.h" #include "cgi.h" #include "cgiwifi.h" #include "cgiflash.h" -#include "stdout.h" #include "auth.h" #include "espfs.h" #include "uart.h" #include "serbridge.h" #include "status.h" #include "console.h" +#include "log.h" #define MCU_RESET 12 #define MCU_ISP 13 #include @@ -60,13 +59,13 @@ should be placed above the URLs they protect. */ HttpdBuiltInUrl builtInUrls[]={ {"/", cgiRedirect, "/index.tpl"}, - {"/flash/download", cgiReadFlash, NULL}, + {"/flash/read", cgiReadFlash, NULL}, {"/flash/next", cgiGetFirmwareNext, NULL}, {"/flash/upload", cgiUploadFirmware, NULL}, {"/flash/reboot", cgiRebootFirmware, NULL}, {"/index.tpl", cgiEspFsTemplate, tplCounter}, {"/help.tpl", cgiEspFsTemplate, tplCounter}, - {"/led.cgi", cgiLed, NULL}, + {"/log.tpl", cgiEspFsTemplate, tplLog}, {"/console.tpl", cgiEspFsTemplate, tplConsole}, //Routines to make the /wifi URL and everything beneath it work. @@ -105,8 +104,8 @@ extern uint32_t _binary_espfs_img_start; void user_init(void) { // init gpio pins used to reset&reprogram attached microcontrollers gpio_init(); - GPIO_OUTPUT_SET(MCU_ISP, 1); - GPIO_OUTPUT_SET(MCU_RESET, 0); + // put MCU into reset in case it interferes with serial-programming of the esp8266 + //GPIO_OUTPUT_SET(MCU_RESET, 0); // init UART uart_init(BIT_RATE_115200, BIT_RATE_115200); // say hello (leave some time to cause break in TX after boot loader's msg @@ -130,5 +129,5 @@ void user_init(void) { os_timer_arm(&prHeapTimer, 3000, 1); #endif os_printf("** esp-link ready\n"); - consoleInit(); + logInit(); } diff --git a/wiflash b/wiflash index b67e9d4..e9f2671 100755 --- a/wiflash +++ b/wiflash @@ -100,7 +100,7 @@ while true; do esac done -silent=-s +#silent=-s [[ -n "$verbose" ]] && silent= res=`curl $silent -XPOST --data-binary "@$fw" "http://$hostname/flash/upload"` if [[ $? != 0 ]]; then