working debug on uart1 & fixed other issues

pull/30/head
Ondřej Hruška 8 years ago
parent b0d3c55bbb
commit b31f3b9335
  1. 19
      README.md
  2. 10
      user/cgi_sockets.c
  3. 3
      user/cgi_sockets.h
  4. 17
      user/io.c
  5. 1
      user/io.h
  6. 16
      user/routes.c
  7. 209
      user/serial.c
  8. 34
      user/serial.c.old
  9. 13
      user/serial.h
  10. 9
      user/serial.h.old
  11. 16
      user/uart_driver.c
  12. 249
      user/uart_driver.c.old
  13. 4
      user/uart_driver.h
  14. 201
      user/uart_driver.h.old
  15. 4
      user/uart_handler.c
  16. 6
      user/uart_handler.h
  17. 24
      user/user_main.c

@ -25,15 +25,20 @@ The screen size should be adjustable up to 25x80 (via a special control sequence
*Still far from finished and also there's like zero documentation, but you can give it a spin if you wish.* *Still far from finished and also there's like zero documentation, but you can give it a spin if you wish.*
- Presently we have a working **1-way terminal** (UART->ESP->Browser) with real-time update via websocket. - We have a working **2-way terminal** (UART->ESP->Browser and vice versa) with real-time update via websocket.
The terminal should support multiple sockets at once (not tested).
- All ANSi sequences that make sense, as well as control codes like Backspace and CR / LF are implemented. This means that what you type in the browser is sent to UART0 and what's received on UART0 is processed by the
Set colors with your usual `\e[31;1m` etc (see Wikipedia). `\e` is the hex code 0x18 or dec 27, or ESC. ANSI parser and applied to the internal screen buffer. You'll also immediately see the changes in your browser.
This may be hard to type on a desktop terminal emulator, if you're trying it with a USB-serial dongle.
It'll be easy with the microcontroller, of course.
- The buttons or other input from the browser don't work yet. For a quick test, try connecting the UART0 Rx and Tx to make a loopback interface.
You should then see what you type & can even try out the ANSI sequences.
Arrow keys generate ANSI sequences, ESC sends literal ASCII code 27 - should be all you need to get started.
- All ANSI sequences that make sense, as well as control codes like Backspace and CR / LF are implemented.
Set colors with your usual `\e[31;1m` etc (see Wikipedia). `\e` is the ASCII code 27 (ESC).
- Buttons pressed in the browser UI
- There is also currently no way to set up the WiFi, so it'll use whatever you configured the ESP to - There is also currently no way to set up the WiFi, so it'll use whatever you configured the ESP to
in your previous project. This'll be addressed later. in your previous project. This'll be addressed later.

@ -7,7 +7,9 @@
#include "screen.h" #include "screen.h"
/** /**
* Broadcast screen state to sockets * Broadcast screen state to sockets.
* This is a callback for the Screen module,
* called after each visible screen modification.
*/ */
void ICACHE_FLASH_ATTR screen_notifyChange() void ICACHE_FLASH_ATTR screen_notifyChange()
{ {
@ -28,7 +30,7 @@ void ICACHE_FLASH_ATTR screen_notifyChange()
} }
/** Socket received a message */ /** Socket received a message */
void ICACHE_FLASH_ATTR myWebsocketRecv(Websock *ws, char *data, int len, int flags) void ICACHE_FLASH_ATTR updateSockRx(Websock *ws, char *data, int len, int flags)
{ {
dbg("Sock RX str: %s, len %d", data, len); dbg("Sock RX str: %s, len %d", data, len);
@ -53,8 +55,8 @@ void ICACHE_FLASH_ATTR myWebsocketRecv(Websock *ws, char *data, int len, int fla
} }
/** Socket connected for updates */ /** Socket connected for updates */
void ICACHE_FLASH_ATTR myWebsocketConnect(Websock *ws) void ICACHE_FLASH_ATTR updateSockConnect(Websock *ws)
{ {
info("Socket connected to "URL_WS_UPDATE); info("Socket connected to "URL_WS_UPDATE);
ws->recvCb = myWebsocketRecv; ws->recvCb = updateSockRx;
} }

@ -3,6 +3,7 @@
#define URL_WS_UPDATE "/ws/update.cgi" #define URL_WS_UPDATE "/ws/update.cgi"
void myWebsocketConnect(Websock *ws); /** Update websocket connect callback */
void updateSockConnect(Websock *ws);
#endif //CGI_SOCKETS_H #endif //CGI_SOCKETS_H

@ -11,22 +11,13 @@
#include <esp8266.h> #include <esp8266.h>
#define LEDGPIO 2
#define BTNGPIO 0 #define BTNGPIO 0
/** Set to false if GPIO0 stuck low on boot (after flashing) */
static bool enable_ap_button = false; static bool enable_ap_button = false;
static ETSTimer resetBtntimer; 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<<LEDGPIO), 0, (1<<LEDGPIO), 0);
} else {
gpio_output_set(0, (1<<LEDGPIO), (1<<LEDGPIO), 0);
}
}
static void ICACHE_FLASH_ATTR resetBtnTimerCb(void *arg) { static void ICACHE_FLASH_ATTR resetBtnTimerCb(void *arg) {
static int resetCnt=0; static int resetCnt=0;
if (enable_ap_button && !GPIO_INPUT_GET(BTNGPIO)) { if (enable_ap_button && !GPIO_INPUT_GET(BTNGPIO)) {
@ -43,9 +34,11 @@ static void ICACHE_FLASH_ATTR resetBtnTimerCb(void *arg) {
} }
void ICACHE_FLASH_ATTR ioInit() { void ICACHE_FLASH_ATTR ioInit() {
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2); // GPIO1, GPIO2, GPIO3 - UARTs.
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0);
gpio_output_set(0, 0, (1<<LEDGPIO), (1<<BTNGPIO)); gpio_output_set(0, 0, 0, (1<<BTNGPIO));
os_timer_disarm(&resetBtntimer); os_timer_disarm(&resetBtntimer);
os_timer_setfn(&resetBtntimer, resetBtnTimerCb, NULL); os_timer_setfn(&resetBtntimer, resetBtnTimerCb, NULL);
os_timer_arm(&resetBtntimer, 500, 1); os_timer_arm(&resetBtntimer, 500, 1);

@ -1,7 +1,6 @@
#ifndef IO_H #ifndef IO_H
#define IO_H #define IO_H
void ioLed(int ena);
void ioInit(void); void ioInit(void);
#endif #endif

@ -17,10 +17,13 @@
#define WIFI_AUTH_PASS "password" #define WIFI_AUTH_PASS "password"
#if WIFI_PROTECT #if WIFI_PROTECT
static int ICACHE_FLASH_ATTR myPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen); static int ICACHE_FLASH_ATTR wifiPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass,
int passLen);
#endif #endif
/** Routes */ /**
* Application routes
*/
HttpdBuiltInUrl builtInUrls[] = { HttpdBuiltInUrl builtInUrls[] = {
// redirect func for the captive portal // redirect func for the captive portal
ROUTE_CGI_ARG("*", cgiRedirectApClientToHostname, "esp8266.nonet"), ROUTE_CGI_ARG("*", cgiRedirectApClientToHostname, "esp8266.nonet"),
@ -29,16 +32,15 @@ HttpdBuiltInUrl builtInUrls[] = {
ROUTE_TPL_FILE("/", tplScreen, "term.tpl"), ROUTE_TPL_FILE("/", tplScreen, "term.tpl"),
// --- Sockets --- // --- Sockets ---
ROUTE_WS(URL_WS_UPDATE, myWebsocketConnect), ROUTE_WS(URL_WS_UPDATE, updateSockConnect),
// --- System control --- // --- System control ---
ROUTE_CGI("/system/reset", cgiResetDevice), ROUTE_CGI("/system/reset", cgiResetDevice),
ROUTE_CGI("/system/ping", cgiPing), ROUTE_CGI("/system/ping", cgiPing),
// --- WiFi config --- // --- WiFi config ---
#if WIFI_PROTECT #if WIFI_PROTECT
ROUTE_AUTH("/wifi*", myPassFn), ROUTE_AUTH("/wifi*", wifiPassFn),
#endif #endif
// TODO add those pages // TODO add those pages
// ROUTE_REDIRECT("/wifi/", "/wifi"), // ROUTE_REDIRECT("/wifi/", "/wifi"),
@ -54,6 +56,8 @@ HttpdBuiltInUrl builtInUrls[] = {
ROUTE_END(), ROUTE_END(),
}; };
// --- Wifi password protection ---
#if WIFI_PROTECT #if WIFI_PROTECT
/** /**
* @brief BasicAuth name/password checking function. * @brief BasicAuth name/password checking function.
@ -70,7 +74,7 @@ HttpdBuiltInUrl builtInUrls[] = {
* @param passLen : password buffer size * @param passLen : password buffer size
* @return 0 to end, 1 if more users are available. * @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) static int ICACHE_FLASH_ATTR wifiPassFn(HttpdConnData *connData, int no, char *user, int userLen, char *pass, int passLen)
{ {
(void)connData; (void)connData;
(void)userLen; (void)userLen;

@ -1,18 +1,22 @@
//Stupid bit of code that does the bare minimum to make os_printf work.
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* Jeroen Domburg <jeroen@spritesmods.com> 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 <esp8266.h> #include <esp8266.h>
#include "uart_driver.h" #include "uart_driver.h"
#include "uart_handler.h"
#include "ansi_parser.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(UART1);
UART_SetupAsyncReceiver();
}
/** /**
* Handle a byte received from UART. * Handle a byte received from UART.
* Might do some buffering here maybe * Might do some buffering here maybe
@ -28,186 +32,3 @@ void ICACHE_FLASH_ATTR UART_HandleRxByte(char c)
warn("Bad char %d ('%c')", (unsigned char)c, 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);
}
}

@ -1,34 +0,0 @@
#include <esp8266.h>
#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);
}
}

@ -1,12 +1,9 @@
#ifndef STDOUT_H #ifndef SERIAL_H
#define STDOUT_H #define SERIAL_H
#include <esp8266.h>
/** Init the uarts */ /** Init the uarts */
void serialInit(); void serialInit(void);
/** poll uart while waiting for something */ void UART_HandleRxByte(char c);
void uart_poll(void);
#endif #endif //SERIAL_H

@ -1,9 +0,0 @@
#ifndef SERIAL_H
#define SERIAL_H
/** Init the uarts */
void serialInit(void);
void UART_HandleRxByte(char c);
#endif //SERIAL_H

@ -1,19 +1,12 @@
/* /**
* Driver file for ESP8266 UART, works with the SDK. * Driver file for ESP8266 UART, works with the SDK.
* This is the low level periph interface.
*/ */
#include "uart_driver.h" #include "uart_driver.h"
#include <esp8266.h> #include <esp8266.h>
#include "ets_sys.h"
#include "osapi.h"
#include "mem.h"
#include "os_type.h"
#include "ets_sys_extra.h"
#include "uart_register.h"
//======================================================== //========================================================
@ -148,7 +141,6 @@ void ICACHE_FLASH_ATTR UART_SetPrintPort(UARTn uart_no)
} }
} }
// -------------- Custom UART functions ------------------------- // -------------- Custom UART functions -------------------------
// !!! write handlers are not ICACHE_FLASH_ATTR -> can be used in IRQ !!! // !!! write handlers are not ICACHE_FLASH_ATTR -> can be used in IRQ !!!
@ -183,7 +175,6 @@ STATUS UART_WriteChar(UARTn uart_no, uint8 c, uint32 timeout_us)
return FAIL; return FAIL;
} }
/** /**
* @brief Write a char to UART, translating LF to CRLF and discarding CR. * @brief Write a char to UART, translating LF to CRLF and discarding CR.
* @param uart_no * @param uart_no
@ -210,7 +201,6 @@ STATUS UART_WriteCharCRLF(UARTn uart_no, uint8 c, uint32 timeout_us)
} }
} }
/** /**
* @brief Send a string to UART. * @brief Send a string to UART.
* @param uart_no * @param uart_no
@ -228,8 +218,6 @@ STATUS UART_WriteString(UARTn uart_no, const char *str, uint32 timeout_us)
return OK; return OK;
} }
/** /**
* @brief Send a buffer * @brief Send a buffer
* @param uart_no * @param uart_no

@ -1,249 +0,0 @@
/*
* Driver file for ESP8266 UART, works with the SDK.
*/
#include "uart_driver.h"
#include <esp8266.h>
#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;
}

@ -1,3 +1,7 @@
/**
* Low level UART peripheral support functions
*/
/* /*
* File : uart.h * File : uart.h
* Copyright (C) 2013 - 2016, Espressif Systems * Copyright (C) 2013 - 2016, Espressif Systems

@ -1,201 +0,0 @@
/**
* 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 <http://www.gnu.org/licenses/>.
*/
#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

@ -1,4 +1,6 @@
//Stupid bit of code that does the bare minimum to make os_printf work. /**
* Higher level UART driver that makes os_printf work and supports async Rx on UART0
*/
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------

@ -12,16 +12,16 @@
#include <esp8266.h> #include <esp8266.h>
/** Configure basic UART func and pins */ /** Configure UART periphs and enable pins */
void UART_Init(uint32_t baud0, uint32_t baud1); void UART_Init(uint32_t baud0, uint32_t baud1);
/** Configure Rx on UART0 */ /** Configure async Rx on UART0 */
void UART_SetupAsyncReceiver(void); void UART_SetupAsyncReceiver(void);
/** User must provide this func for handling received bytes */ /** User must provide this func for handling received bytes */
extern void UART_HandleRxByte(char c); extern void UART_HandleRxByte(char c);
/** poll uart while waiting for something */ /** Poll uart manually while waiting for something */
void UART_PollRx(void); void UART_PollRx(void);
#endif #endif

@ -1,7 +1,7 @@
/** /**
* This is the ESP8266 Remote Terminal project main file. * This is the ESP8266 Remote Terminal project main file.
* *
* Front-end URLs and handlers are defined in web.c * Front-end URLs are defined in routes.c, handlers in cgi_*.c
*/ */
/* /*
@ -47,10 +47,9 @@ CgiUploadFlashDef uploadParams={
static ETSTimer prHeapTimer; static ETSTimer prHeapTimer;
/** Blink & show heap usage */ /** Periodically show heap usage */
static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg) static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg)
{ {
static int led = 0;
static unsigned int cnt = 0; static unsigned int cnt = 0;
if (cnt == 5) { if (cnt == 5) {
@ -58,28 +57,24 @@ static void ICACHE_FLASH_ATTR prHeapTimerCb(void *arg)
cnt = 0; cnt = 0;
} }
ioLed(led);
led = !led;
cnt++; cnt++;
} }
//Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done. //Main routine. Initialize stdout, the I/O, filesystem and the webserver and we're done.
void user_init(void) void ICACHE_FLASH_ATTR user_init(void)
{ {
serialInit(); serialInit();
printf("\r\n"); printf("\r\n");
banner("*** ESP8266 Remote Terminal ***"); banner("====== ESP8266 Remote Terminal ======");
banner_info("Firmware (c) Ondrej Hruska, 2017"); banner_info("Firmware (c) Ondrej Hruska, 2017");
banner_info("github.com/MightyPork/esp-vt100-firmware"); banner_info("github.com/MightyPork/esp-vt100-firmware");
banner_info(""); banner_info("");
banner_info("Version " FIRMWARE_VERSION ", built " __DATE__ " at " __TIME__); banner_info("Version " FIRMWARE_VERSION ", built " __DATE__ " at " __TIME__);
banner_info(""); banner_info("");
banner_info("Department of Measurement, CTU Prague"); banner_info("Department of Measurement, CTU Prague");
banner_info(""); printf("\r\n");
captdnsInit();
ioInit(); ioInit();
// 0x40200000 is the base address for spi flash memory mapping, ESPFS_POS is the position // 0x40200000 is the base address for spi flash memory mapping, ESPFS_POS is the position
@ -90,6 +85,10 @@ void user_init(void)
espFsInit((void *) (webpages_espfs_start)); espFsInit((void *) (webpages_espfs_start));
#endif #endif
// Captive portal
captdnsInit();
// Server
httpdInit(builtInUrls, 80); httpdInit(builtInUrls, 80);
// Heap use timer & blink // Heap use timer & blink
@ -105,11 +104,6 @@ void user_init(void)
// ---- unused funcs removed from sdk to save space --- // ---- unused funcs removed from sdk to save space ---
void user_rf_pre_init()
{
//Not needed, but some SDK versions want this defined.
}
// вызывается из phy_chip_v6.o // вызывается из phy_chip_v6.o
void ICACHE_FLASH_ATTR chip_v6_set_sense(void) void ICACHE_FLASH_ATTR chip_v6_set_sense(void)
{ {

Loading…
Cancel
Save