From b0d3c55bbb63c5b8c7fc5cca177fefda95edcb21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 24 Jan 2017 12:05:41 +0100 Subject: [PATCH] attempt to fix uart1 but nnot working --- user/cgi_main.c | 34 +++ user/cgi_main.h | 6 + user/cgi_ping.c | 20 ++ user/cgi_ping.h | 11 + user/cgi_reset.c | 31 +++ user/cgi_reset.h | 9 + user/{web.c => cgi_sockets.c} | 54 +---- user/cgi_sockets.h | 8 + user/routes.c | 91 +++++++ user/{web.h => routes.h} | 6 +- user/serial.c | 209 ++++++++++++++-- user/serial.c.old | 34 +++ user/serial.h | 13 +- user/serial.h.old | 9 + user/uart_driver.c.old | 249 ++++++++++++++++++++ user/uart_driver.h | 4 - user/uart_driver.h.old | 201 ++++++++++++++++ user/{uart_handler.c => uart_handler.c.old} | 0 user/{uart_handler.h => uart_handler.h.old} | 0 user/user_main.c | 2 +- 20 files changed, 911 insertions(+), 80 deletions(-) create mode 100644 user/cgi_main.c create mode 100644 user/cgi_main.h create mode 100755 user/cgi_ping.c create mode 100755 user/cgi_ping.h create mode 100755 user/cgi_reset.c create mode 100755 user/cgi_reset.h rename user/{web.c => cgi_sockets.c} (57%) create mode 100644 user/cgi_sockets.h create mode 100644 user/routes.c rename user/{web.h => routes.h} (74%) mode change 100644 => 100755 user/serial.c create mode 100644 user/serial.c.old mode change 100644 => 100755 user/serial.h create mode 100644 user/serial.h.old create mode 100755 user/uart_driver.c.old create mode 100755 user/uart_driver.h.old rename user/{uart_handler.c => uart_handler.c.old} (100%) rename user/{uart_handler.h => uart_handler.h.old} (100%) diff --git a/user/cgi_main.c b/user/cgi_main.c new file mode 100644 index 0000000..0804af4 --- /dev/null +++ b/user/cgi_main.c @@ -0,0 +1,34 @@ +#include +#include + +#include "cgi_main.h" +#include "screen.h" + +/** + * Main page template substitution + * + * @param connData + * @param token + * @param arg + * @return + */ +httpd_cgi_state ICACHE_FLASH_ATTR tplScreen(HttpdConnData *connData, char *token, void **arg) +{ + if (token == NULL) { + // Release data object + screenSerializeToBuffer(NULL, 0, arg); + return HTTPD_CGI_DONE; + } + + const int bufsiz = 512; + char buff[bufsiz]; + + if (streq(token, "screenData")) { + httpd_cgi_state cont = screenSerializeToBuffer(buff, bufsiz, arg); + httpdSend(connData, buff, -1); + return cont; + } + + return HTTPD_CGI_DONE; +} + diff --git a/user/cgi_main.h b/user/cgi_main.h new file mode 100644 index 0000000..7f55458 --- /dev/null +++ b/user/cgi_main.h @@ -0,0 +1,6 @@ +#ifndef CGI_MAIN_H +#define CGI_MAIN_H + +httpd_cgi_state tplScreen(HttpdConnData *connData, char *token, void **arg); + +#endif // CGI_MAIN_H diff --git a/user/cgi_ping.c b/user/cgi_ping.c new file mode 100755 index 0000000..5cde827 --- /dev/null +++ b/user/cgi_ping.c @@ -0,0 +1,20 @@ +#include +#include + +#include "cgi_ping.h" + +httpd_cgi_state ICACHE_FLASH_ATTR cgiPing(HttpdConnData *connData) +{ + if (connData->conn==NULL) { + //Connection aborted. Clean up. + return HTTPD_CGI_DONE; + } + + httpdStartResponse(connData, 200); + httpdHeader(connData, "Content-Type", "text/plain"); + httpdEndHeaders(connData); + + httpdSend(connData, "pong\n", -1); + + return HTTPD_CGI_DONE; +} diff --git a/user/cgi_ping.h b/user/cgi_ping.h new file mode 100755 index 0000000..c500697 --- /dev/null +++ b/user/cgi_ping.h @@ -0,0 +1,11 @@ +#ifndef CGI_PING_H +#define CGI_PING_H + +#include +#include + +// this is used by the UI to check if server is already restarted and working again. + +httpd_cgi_state cgiPing(HttpdConnData *connData); + +#endif // CGI_PING_H diff --git a/user/cgi_reset.c b/user/cgi_reset.c new file mode 100755 index 0000000..aea3f87 --- /dev/null +++ b/user/cgi_reset.c @@ -0,0 +1,31 @@ +#include +#include + +#include "cgi_reset.h" + +static ETSTimer tmr; + +static void ICACHE_FLASH_ATTR tmrCb(void *arg) +{ + system_restart(); +} + +httpd_cgi_state ICACHE_FLASH_ATTR cgiResetDevice(HttpdConnData *connData) +{ + if (connData->conn==NULL) { + //Connection aborted. Clean up. + return HTTPD_CGI_DONE; + } + + httpdStartResponse(connData, 200); + httpdHeader(connData, "Content-Type", "text/plain"); + httpdEndHeaders(connData); + + os_timer_disarm(&tmr); + os_timer_setfn(&tmr, tmrCb, NULL); + os_timer_arm(&tmr, 100, false); + + httpdSend(connData, "system reset\n", -1); + + return HTTPD_CGI_DONE; +} diff --git a/user/cgi_reset.h b/user/cgi_reset.h new file mode 100755 index 0000000..a7b6927 --- /dev/null +++ b/user/cgi_reset.h @@ -0,0 +1,9 @@ +#ifndef CGI_RESET_H +#define CGI_RESET_H + +#include +#include + +httpd_cgi_state cgiResetDevice(HttpdConnData *connData); + +#endif // CGI_RESET_H diff --git a/user/web.c b/user/cgi_sockets.c similarity index 57% rename from user/web.c rename to user/cgi_sockets.c index 2a07af0..015ccba 100644 --- a/user/web.c +++ b/user/cgi_sockets.c @@ -1,46 +1,10 @@ #include #include #include -#include -#include "web.h" -#include "screen.h" +#include "cgi_sockets.h" #include "uart_driver.h" - -#define URL_WS_UPDATE "/ws/update.cgi" - -/* Routes are defined at the bottom of the file */ - -/** - * Main page template substitution - * - * @param connData - * @param token - * @param arg - * @return - */ -httpd_cgi_state ICACHE_FLASH_ATTR tplScreen(HttpdConnData *connData, char *token, void **arg) -{ - if (token == NULL) { - // Release data object - screenSerializeToBuffer(NULL, 0, arg); - return HTTPD_CGI_DONE; - } - - const int bufsiz = 512; - char buff[bufsiz]; - - if (streq(token, "screenData")) { - httpd_cgi_state cont = screenSerializeToBuffer(buff, bufsiz, arg); - httpdSend(connData, buff, -1); - return cont; - } - - return HTTPD_CGI_DONE; -} - -// --- Sockets --- - +#include "screen.h" /** * Broadcast screen state to sockets @@ -94,17 +58,3 @@ void ICACHE_FLASH_ATTR myWebsocketConnect(Websock *ws) info("Socket connected to "URL_WS_UPDATE); ws->recvCb = myWebsocketRecv; } - -/** Routes */ -HttpdBuiltInUrl builtInUrls[] = { //ICACHE_RODATA_ATTR - // redirect func for the captive portal - ROUTE_CGI_ARG("*", cgiRedirectApClientToHostname, "esp8266.nonet"), - - ROUTE_WS(URL_WS_UPDATE, myWebsocketConnect), - - // TODO add funcs for WiFi management (when web UI is added) - - ROUTE_TPL_FILE("/", tplScreen, "term.tpl"), - ROUTE_FILESYSTEM(), - ROUTE_END(), -}; diff --git a/user/cgi_sockets.h b/user/cgi_sockets.h new file mode 100644 index 0000000..2c2d608 --- /dev/null +++ b/user/cgi_sockets.h @@ -0,0 +1,8 @@ +#ifndef CGI_SOCKETS_H +#define CGI_SOCKETS_H + +#define URL_WS_UPDATE "/ws/update.cgi" + +void myWebsocketConnect(Websock *ws); + +#endif //CGI_SOCKETS_H diff --git a/user/routes.c b/user/routes.c new file mode 100644 index 0000000..4cac707 --- /dev/null +++ b/user/routes.c @@ -0,0 +1,91 @@ +#include +#include +#include +#include +#include +#include + +#include "routes.h" + +#include "cgi_reset.h" +#include "cgi_ping.h" +#include "cgi_main.h" +#include "cgi_sockets.h" + +#define WIFI_PROTECT 1 +#define WIFI_AUTH_NAME "admin" +#define WIFI_AUTH_PASS "password" + +#if WIFI_PROTECT +static int ICACHE_FLASH_ATTR myPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen); +#endif + +/** Routes */ +HttpdBuiltInUrl builtInUrls[] = { + // redirect func for the captive portal + ROUTE_CGI_ARG("*", cgiRedirectApClientToHostname, "esp8266.nonet"), + + // --- Web pages --- + ROUTE_TPL_FILE("/", tplScreen, "term.tpl"), + + // --- Sockets --- + ROUTE_WS(URL_WS_UPDATE, myWebsocketConnect), + + // --- System control --- + ROUTE_CGI("/system/reset", cgiResetDevice), + ROUTE_CGI("/system/ping", cgiPing), + + + // --- WiFi config --- +#if WIFI_PROTECT + ROUTE_AUTH("/wifi*", myPassFn), +#endif + // TODO add those pages +// ROUTE_REDIRECT("/wifi/", "/wifi"), +// ROUTE_TPL_FILE("/wifi", tplWlan, "/pages/wifi.tpl"), + + ROUTE_CGI("/wifi/scan", cgiWiFiScan), + ROUTE_CGI("/wifi/connect", cgiWiFiConnect), + ROUTE_CGI("/wifi/connstatus", cgiWiFiConnStatus), + ROUTE_CGI("/wifi/setmode", cgiWiFiSetMode), + ROUTE_CGI("/wifi/setchannel", cgiWiFiSetChannel), + + ROUTE_FILESYSTEM(), + ROUTE_END(), +}; + +#if WIFI_PROTECT +/** + * @brief BasicAuth name/password checking function. + * + * It's invoked by the authBasic() built-in route handler + * until it returns 0. Each time it populates the provided + * name and password buffer. + * + * @param connData : connection context + * @param no : user number (incremented each time it's called) + * @param user : user buffer + * @param userLen : user buffer size + * @param pass : password buffer + * @param passLen : password buffer size + * @return 0 to end, 1 if more users are available. + */ +static int ICACHE_FLASH_ATTR myPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen) +{ + (void)connData; + (void)userLen; + (void)passLen; + + if (no == 0) { + os_strcpy(user, WIFI_AUTH_NAME); + os_strcpy(pass, WIFI_AUTH_PASS); + return 1; +//Add more users this way. Check against incrementing no for each user added. +// } else if (no==1) { +// os_strcpy(user, "user1"); +// os_strcpy(pass, "something"); +// return 1; + } + return 0; +} +#endif diff --git a/user/web.h b/user/routes.h similarity index 74% rename from user/web.h rename to user/routes.h index c33ede5..4006d53 100644 --- a/user/web.h +++ b/user/routes.h @@ -1,5 +1,5 @@ -#ifndef WEB_H -#define WEB_H +#ifndef ROUTES_H +#define ROUTES_H #include #include @@ -9,4 +9,4 @@ extern HttpdBuiltInUrl builtInUrls[]; /** Broadcast screen state to sockets */ void screen_notifyChange(); -#endif //WEB_H +#endif //ROUTES_H diff --git a/user/serial.c b/user/serial.c old mode 100644 new mode 100755 index 65b6eb9..b852ee1 --- a/user/serial.c +++ b/user/serial.c @@ -1,22 +1,18 @@ +//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 #include "uart_driver.h" -#include "uart_handler.h" #include "ansi_parser.h" -// Here the bitrates are defined -#define UART0_BAUD BIT_RATE_115200 -#define UART1_BAUD BIT_RATE_115200 - -/** - * Init the serial ports - */ -void ICACHE_FLASH_ATTR serialInit(void) -{ - UART_Init(UART0_BAUD, UART1_BAUD); - UART_SetPrintPort(UART0); - UART_SetupAsyncReceiver(); -} - /** * Handle a byte received from UART. * Might do some buffering here maybe @@ -32,3 +28,186 @@ void ICACHE_FLASH_ATTR UART_HandleRxByte(char c) warn("Bad char %d ('%c')", (unsigned char)c, c); } } + +// --- OLD CODE --- + +static void uart0_rx_intr_handler(void *para); +static void uart_recvTask(os_event_t *events); + +#define uart_recvTaskPrio 1 +#define uart_recvTaskQueueLen 10 +static os_event_t uart_recvTaskQueue[uart_recvTaskQueueLen]; + + +/** Clear the fifos */ +void ICACHE_FLASH_ATTR clear_rxtx(int uart_no) +{ + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); +} + + +/** + * @brief Configure UART 115200-8-N-1 + * @param uart_no + */ +static void ICACHE_FLASH_ATTR my_uart_init(UARTn uart_no, uint32 baud) +{ + UART_SetParity(uart_no, PARITY_NONE); + UART_SetStopBits(uart_no, ONE_STOP_BIT); + UART_SetWordLength(uart_no, EIGHT_BITS); + UART_SetBaudrate(uart_no, baud); + UART_ResetFifo(uart_no); +} + + +/** Configure basic UART func and pins */ +static void ICACHE_FLASH_ATTR conf_uart_pins(void) +{ + // U0TXD + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + + // U0RXD + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD); + + // U1TXD (GPIO2) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); + + // Configure the UART peripherals + my_uart_init(UART0, BIT_RATE_460800); // main + my_uart_init(UART1, BIT_RATE_115200); // debug (output only) + + // Select debug port + UART_SetPrintPort(UART1); +} + +/** Configure Rx on UART0 */ +static void ICACHE_FLASH_ATTR conf_uart_receiver(void) +{ + // + // Start the Rx reading task + system_os_task(uart_recvTask, uart_recvTaskPrio, uart_recvTaskQueue, uart_recvTaskQueueLen); + // set handler + ETS_UART_INTR_ATTACH((void *)uart0_rx_intr_handler, &(UartDev.rcv_buff)); // the buf will be used as an arg + + // fifo threshold config + uint32_t conf = ((100 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S); + conf |= ((0x10 & UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S); + // timeout config + conf |= ((0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S); // timeout threshold + conf |= UART_RX_TOUT_EN; // enable timeout + WRITE_PERI_REG(UART_CONF1(UART0), conf); + + // enable TOUT and ERR irqs + SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_RXFIFO_TOUT_INT_ENA | UART_FRM_ERR_INT_ENA); + /* clear interrupt flags */ + WRITE_PERI_REG(UART_INT_CLR(UART0), 0xffff); + /* enable RX interrupts */ + SET_PERI_REG_MASK(UART_INT_ENA(UART0), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_OVF_INT_ENA); + + // Enable IRQ in Extensa + ETS_UART_INTR_ENABLE(); +} + + +void ICACHE_FLASH_ATTR serialInit() +{ + conf_uart_pins(); + conf_uart_receiver(); +} + + +// ---- async receive stuff ---- + + +void uart_rx_intr_disable(uint8 uart_no) +{ + CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA); +} + + +void uart_rx_intr_enable(uint8 uart_no) +{ + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA); +} + + +/** + * @brief get number of bytes in UART tx fifo + * @param UART number + */ +#define UART_GetRxFifoCount(uart_no) ((READ_PERI_REG(UART_STATUS((uart_no))) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT) + + +void ICACHE_FLASH_ATTR uart_poll(void) +{ + uint8 fifo_len = UART_GetRxFifoCount(UART0); + + for (uint8 idx = 0; idx < fifo_len; idx++) { + uint8 d_tmp = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF; + UART_HandleRxByte(d_tmp); + } +} + + +static void ICACHE_FLASH_ATTR uart_recvTask(os_event_t *events) +{ + if (events->sig == 0) { + uart_poll(); + + // clear irq flags + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR | UART_RXFIFO_TOUT_INT_CLR); + // enable rx irq again + uart_rx_intr_enable(UART0); + } else if (events->sig == 1) { + // ??? + } +} + + +/****************************************************************************** + * FunctionName : uart0_rx_intr_handler + * Description : Internal used function + * UART0 interrupt handler, add self handle code inside + * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg + * Returns : NONE +*******************************************************************************/ +static void +uart0_rx_intr_handler(void *para) +{ + (void)para; + + uint32_t status_reg = READ_PERI_REG(UART_INT_ST(UART0)); + + if (status_reg & UART_FRM_ERR_INT_ST) { + // Framing Error + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_FRM_ERR_INT_CLR); + } + + if (status_reg & UART_RXFIFO_FULL_INT_ST) { + // RX fifo full + uart_rx_intr_disable(UART0); + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR); + + // run handler + system_os_post(uart_recvTaskPrio, 0, 0); /* -> notify the polling thread */ + } + + if (status_reg & UART_RXFIFO_TOUT_INT_ST) { + // Fifo timeout + uart_rx_intr_disable(UART0); + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR); + + // run handler + system_os_post(uart_recvTaskPrio, 0, 0); /* -> notify the polling thread */ + } + + if (status_reg & UART_TXFIFO_EMPTY_INT_ST) { + CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); + } + + if (status_reg & UART_RXFIFO_OVF_INT_ST) { + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_OVF_INT_CLR); + } +} diff --git a/user/serial.c.old b/user/serial.c.old new file mode 100644 index 0000000..65b6eb9 --- /dev/null +++ b/user/serial.c.old @@ -0,0 +1,34 @@ +#include +#include "uart_driver.h" +#include "uart_handler.h" +#include "ansi_parser.h" + +// Here the bitrates are defined +#define UART0_BAUD BIT_RATE_115200 +#define UART1_BAUD BIT_RATE_115200 + +/** + * Init the serial ports + */ +void ICACHE_FLASH_ATTR serialInit(void) +{ + UART_Init(UART0_BAUD, UART1_BAUD); + UART_SetPrintPort(UART0); + UART_SetupAsyncReceiver(); +} + +/** + * Handle a byte received from UART. + * Might do some buffering here maybe + * + * @param c + */ +void ICACHE_FLASH_ATTR UART_HandleRxByte(char c) +{ + if (c > 0 && c < 127) { + // TODO buffering, do not run parser after just 1 char + ansi_parser(&c, 1); + } else { + warn("Bad char %d ('%c')", (unsigned char)c, c); + } +} diff --git a/user/serial.h b/user/serial.h old mode 100644 new mode 100755 index eda2e5b..b3e4dc5 --- a/user/serial.h +++ b/user/serial.h @@ -1,9 +1,12 @@ -#ifndef SERIAL_H -#define SERIAL_H +#ifndef STDOUT_H +#define STDOUT_H + +#include /** Init the uarts */ -void serialInit(void); +void serialInit(); -void UART_HandleRxByte(char c); +/** poll uart while waiting for something */ +void uart_poll(void); -#endif //SERIAL_H +#endif diff --git a/user/serial.h.old b/user/serial.h.old new file mode 100644 index 0000000..eda2e5b --- /dev/null +++ b/user/serial.h.old @@ -0,0 +1,9 @@ +#ifndef SERIAL_H +#define SERIAL_H + +/** Init the uarts */ +void serialInit(void); + +void UART_HandleRxByte(char c); + +#endif //SERIAL_H diff --git a/user/uart_driver.c.old b/user/uart_driver.c.old new file mode 100755 index 0000000..48f20f8 --- /dev/null +++ b/user/uart_driver.c.old @@ -0,0 +1,249 @@ +/* +* Driver file for ESP8266 UART, works with the SDK. +*/ + +#include "uart_driver.h" + +#include + +#include "ets_sys.h" +#include "osapi.h" +#include "mem.h" +#include "os_type.h" + +#include "ets_sys_extra.h" +#include "uart_register.h" + +//======================================================== + + +void ICACHE_FLASH_ATTR UART_SetWordLength(UARTn uart_no, UartBitsNum4Char len) +{ + SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_BIT_NUM, len, UART_BIT_NUM_S); +} + + +void ICACHE_FLASH_ATTR UART_SetStopBits(UARTn uart_no, UartStopBitsNum bit_num) +{ + SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_STOP_BIT_NUM, bit_num, UART_STOP_BIT_NUM_S); +} + + +void ICACHE_FLASH_ATTR UART_SetLineInverse(UARTn uart_no, UART_LineLevelInverse inverse_mask) +{ + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK); + SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask); +} + + +void ICACHE_FLASH_ATTR UART_SetParity(UARTn uart_no, UartParityMode Parity_mode) +{ + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY | UART_PARITY_EN); + if (Parity_mode == PARITY_NONE) { + } else { + SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode | UART_PARITY_EN); + } +} + + +void ICACHE_FLASH_ATTR UART_SetBaudrate(UARTn uart_no, uint32 baud_rate) +{ + uart_div_modify(uart_no, UART_CLK_FREQ / baud_rate); +} + + +void ICACHE_FLASH_ATTR UART_SetFlowCtrl(UARTn uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh) +{ + if (flow_ctrl & USART_HWFlow_RTS) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); + SET_PERI_REG_BITS(UART_CONF1(uart_no), UART_RX_FLOW_THRHD, rx_thresh, UART_RX_FLOW_THRHD_S); + SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); + } else { + CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); + } + + if (flow_ctrl & USART_HWFlow_CTS) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS); + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); + } else { + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); + } +} + + +void ICACHE_FLASH_ATTR UART_WaitTxFifoEmpty(UARTn uart_no , uint32 time_out_us) //do not use if tx flow control enabled +{ + uint32 t_s = system_get_time(); + while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)) { + + if ((system_get_time() - t_s) > time_out_us) { + break; + } + + system_soft_wdt_feed(); + } +} + + +bool ICACHE_FLASH_ATTR UART_CheckOutputFinished(UARTn uart_no, uint32 time_out_us) +{ + uint32 t_start = system_get_time(); + uint8 tx_fifo_len; + + while (1) { + tx_fifo_len = UART_TxQueLen(uart_no); + + // TODO If using output circbuf, check if empty + + if (tx_fifo_len == 0) { + return TRUE; + } + + if (system_get_time() - t_start > time_out_us) { + return FALSE; + } + + system_soft_wdt_feed(); + } +} + + +void ICACHE_FLASH_ATTR UART_ResetFifo(UARTn uart_no) +{ + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); +} + + +void ICACHE_FLASH_ATTR UART_ClearIntrStatus(UARTn uart_no, uint32 clr_mask) +{ + WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask); +} + + +void ICACHE_FLASH_ATTR UART_SetIntrEna(UARTn uart_no, uint32 ena_mask) +{ + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask); +} + + +LOCAL void u0_putc_crlf(char c) +{ + UART_WriteCharCRLF(UART0, (u8)c, UART_TIMEOUT_US); +} + + +LOCAL void u1_putc_crlf(char c) +{ + UART_WriteCharCRLF(UART1, (u8)c, UART_TIMEOUT_US); +} + + +void ICACHE_FLASH_ATTR UART_SetPrintPort(UARTn uart_no) +{ + if (uart_no == UART0) { + os_install_putc1((void *)u0_putc_crlf); + } else { + os_install_putc1((void *)u1_putc_crlf); + } +} + + +// -------------- Custom UART functions ------------------------- + +// !!! write handlers are not ICACHE_FLASH_ATTR -> can be used in IRQ !!! + +/** + * @brief Write a char to UART. + * @param uart_no + * @param c + * @param timeout_us - how long to max wait for space in FIFO. + * @return write success + */ +STATUS UART_WriteChar(UARTn uart_no, uint8 c, uint32 timeout_us) +{ + if (timeout_us == 0) { + timeout_us = UART_TIMEOUT_US; + } + + + uint32 t_s = system_get_time(); + + while ((system_get_time() - t_s) < timeout_us) { + uint8 fifo_cnt = UART_TxQueLen(uart_no); + + if (fifo_cnt < UART_TX_FULL_THRESH_VAL) { + WRITE_PERI_REG(UART_FIFO(uart_no), c); + return OK; + } + + system_soft_wdt_feed(); + } + + return FAIL; +} + + +/** + * @brief Write a char to UART, translating LF to CRLF and discarding CR. + * @param uart_no + * @param c + * @param timeout_us - how long to max wait for space in FIFO. + * @return write success + */ +STATUS UART_WriteCharCRLF(UARTn uart_no, uint8 c, uint32 timeout_us) +{ + STATUS st; + + if (c == '\r') { + return OK; + } else if (c == '\n') { + + st = UART_WriteChar(uart_no, '\r', timeout_us); + if (st != OK) return st; + + st = UART_WriteChar(uart_no, '\n', timeout_us); + return st; + + } else { + return UART_WriteChar(uart_no, c, timeout_us); + } +} + + +/** + * @brief Send a string to UART. + * @param uart_no + * @param str + * @param timeout_us - how long to max wait for space in FIFO. + * @return write success + */ +STATUS UART_WriteString(UARTn uart_no, const char *str, uint32 timeout_us) +{ + while (*str) { + STATUS suc = UART_WriteChar(uart_no, (u8) * str++, timeout_us); + if (suc != OK) return suc; + } + + return OK; +} + + + +/** + * @brief Send a buffer + * @param uart_no + * @param buffer - buffer to send + * @param len - buffer size + * @param timeout_us - how long to max wait for space in FIFO. + * @return write success + */ +STATUS UART_WriteBuffer(UARTn uart_no, const uint8 *buffer, size_t len, uint32 timeout_us) +{ + for (size_t i = 0; i < len; i++) { + STATUS suc = UART_WriteChar(uart_no, (u8) * buffer++, timeout_us); + if (suc != OK) return suc; + } + + return OK; +} diff --git a/user/uart_driver.h b/user/uart_driver.h index 8a95c0d..cadc0fc 100755 --- a/user/uart_driver.h +++ b/user/uart_driver.h @@ -1,7 +1,3 @@ -/** - * Low level UART peripheral support functions - */ - /* * File : uart.h * Copyright (C) 2013 - 2016, Espressif Systems diff --git a/user/uart_driver.h.old b/user/uart_driver.h.old new file mode 100755 index 0000000..8a95c0d --- /dev/null +++ b/user/uart_driver.h.old @@ -0,0 +1,201 @@ +/** + * Low level UART peripheral support functions + */ + +/* + * File : uart.h + * Copyright (C) 2013 - 2016, Espressif Systems + * Copyright (C) 2016, Ondřej Hruška (cleaning, modif.) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of version 3 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + + +#ifndef UART_APP_H +#define UART_APP_H + +#include "uart_register.h" + +#include "eagle_soc.h" +#include "c_types.h" + + +// =========== + +// timeout for sending / receiving a char (default) +#define UART_TIMEOUT_US 5000 + +#define UART_TX_FULL_THRESH_VAL (UART_FIFO_LEN - 2) // if more than this many bytes in queue, don't write more +#define UART_TX_EMPTY_THRESH_VAL 16 + +// =========== + + +typedef enum { + UART0 = 0, + UART1 = 1 +} UARTn; + + +typedef enum { + FIVE_BITS = 0x0, + SIX_BITS = 0x1, + SEVEN_BITS = 0x2, + EIGHT_BITS = 0x3 +} UartBitsNum4Char; + + +typedef enum { + ONE_STOP_BIT = 0x1, + ONE_HALF_STOP_BIT = 0x2, + TWO_STOP_BIT = 0x3 +} UartStopBitsNum; + + +typedef enum { + PARITY_NONE = 0x2, + PARITY_ODD = 1, + PARITY_EVEN = 0 +} UartParityMode; + + +typedef enum { + PARITY_DIS = 0, + PARITY_EN = 1 +} UartExistParity; + + +typedef enum { + UART_None_Inverse = 0x0, + UART_Rxd_Inverse = UART_RXD_INV, + UART_CTS_Inverse = UART_CTS_INV, + UART_Txd_Inverse = UART_TXD_INV, + UART_RTS_Inverse = UART_RTS_INV, +} UART_LineLevelInverse; + + +typedef enum { + BIT_RATE_300 = 300, + BIT_RATE_600 = 600, + BIT_RATE_1200 = 1200, + BIT_RATE_2400 = 2400, + BIT_RATE_4800 = 4800, + BIT_RATE_9600 = 9600, + BIT_RATE_19200 = 19200, + BIT_RATE_38400 = 38400, + BIT_RATE_57600 = 57600, + BIT_RATE_74880 = 74880, + BIT_RATE_115200 = 115200, + BIT_RATE_230400 = 230400, + BIT_RATE_460800 = 460800, + BIT_RATE_921600 = 921600, + BIT_RATE_1843200 = 1843200, + BIT_RATE_3686400 = 3686400, +} UartBautRate; + + +typedef enum { + NONE_CTRL, + HARDWARE_CTRL, + XON_XOFF_CTRL +} UartFlowCtrl; + + +typedef enum { + USART_HWFlow_None = 0x0, + USART_HWFlow_RTS = 0x1, + USART_HWFlow_CTS = 0x2, + USART_HWFlow_CTS_RTS = 0x3 +} UART_HwFlowCtrl; + + +typedef enum { + EMPTY, + UNDER_WRITE, + WRITE_OVER +} RcvMsgBuffState; + + +typedef struct { + uint32 RcvBuffSize; + uint8 *pRcvMsgBuff; + uint8 *pWritePos; + uint8 *pReadPos; + uint8 TrigLvl; //JLU: may need to pad + RcvMsgBuffState BuffState; +} RcvMsgBuff; + + +typedef struct { + uint32 TrxBuffSize; + uint8 *pTrxBuff; +} TrxMsgBuff; + + +typedef enum { + BAUD_RATE_DET, + WAIT_SYNC_FRM, + SRCH_MSG_HEAD, + RCV_MSG_BODY, + RCV_ESC_CHAR, +} RcvMsgState; + + +typedef struct { + UartBautRate baut_rate; + UartBitsNum4Char data_bits; + UartExistParity exist_parity; + UartParityMode parity; + UartStopBitsNum stop_bits; + UartFlowCtrl flow_ctrl; + RcvMsgBuff rcv_buff; + TrxMsgBuff trx_buff; + RcvMsgState rcv_state; + int received; + int buff_uart_no; //indicate which uart use tx/rx buffer +} UartDevice; + +// UartDev is defined and initialized in rom code. +extern UartDevice UartDev; + + +//============================================== + +// FIFO used count +#define UART_TxQueLen(uart_no) ((READ_PERI_REG(UART_STATUS((uart_no))) >> UART_TXFIFO_CNT_S) & UART_TXFIFO_CNT) +#define UART_RxQueLen(uart_no) ((READ_PERI_REG(UART_STATUS((uart_no))) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT) + +STATUS UART_WriteCharCRLF(UARTn uart_no, uint8 c, uint32 timeout_us); +STATUS UART_WriteChar(UARTn uart_no, uint8 c, uint32 timeout_us); +STATUS UART_WriteString(UARTn uart_no, const char *str, uint32 timeout_us); +STATUS UART_WriteBuffer(UARTn uart_no, const uint8 *buffer, size_t len, uint32 timeout_us); + +//============================================== + +void UART_SetWordLength(UARTn uart_no, UartBitsNum4Char len); +void UART_SetStopBits(UARTn uart_no, UartStopBitsNum bit_num); +void UART_SetLineInverse(UARTn uart_no, UART_LineLevelInverse inverse_mask); +void UART_SetParity(UARTn uart_no, UartParityMode Parity_mode); +void UART_SetBaudrate(UARTn uart_no, uint32 baud_rate); +void UART_SetFlowCtrl(UARTn uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh); +void UART_WaitTxFifoEmpty(UARTn uart_no , uint32 time_out_us); //do not use if tx flow control enabled +void UART_ResetFifo(UARTn uart_no); +void UART_ClearIntrStatus(UARTn uart_no, uint32 clr_mask); +void UART_SetIntrEna(UARTn uart_no, uint32 ena_mask); +void UART_SetPrintPort(UARTn uart_no); +bool UART_CheckOutputFinished(UARTn uart_no, uint32 time_out_us); + +//============================================== + +#endif + diff --git a/user/uart_handler.c b/user/uart_handler.c.old similarity index 100% rename from user/uart_handler.c rename to user/uart_handler.c.old diff --git a/user/uart_handler.h b/user/uart_handler.h.old similarity index 100% rename from user/uart_handler.h rename to user/uart_handler.h.old diff --git a/user/user_main.c b/user/user_main.c index 040ea66..c550748 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -21,7 +21,7 @@ #include "serial.h" #include "io.h" #include "screen.h" -#include "web.h" +#include "routes.h" #define FIRMWARE_VERSION "0.1"