summaryrefslogtreecommitdiffstatshomepage
path: root/esp8266/uart.c
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2015-06-01 01:27:39 +0300
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2015-06-01 23:57:19 +0300
commit2fc1e643199a97cd38142aaec80547227197db98 (patch)
tree69e2843d882b025a9354d86465a2792a16410c70 /esp8266/uart.c
parent3ac2d06bd13f1cedb8242eaacc6c608ac08c3520 (diff)
downloadmicropython-2fc1e643199a97cd38142aaec80547227197db98.tar.gz
micropython-2fc1e643199a97cd38142aaec80547227197db98.zip
esp8266: Fix lost chars problem when block-xfering data (e.g., when pasting).
Pasting more or less sizable text into ESP8266 REPL leads to random chars missing in the received input. Apparent cause is that using RTOS messages to pass individual chars one by one is to slow and leads to UART FIFO overflow. So, instead of passing chars one by one, use RTOS msg to signal that input data is available in FIFO, and then let task handler to read data directly from FIFO. With this change, lost chars problem is gone, but the pasted text is truncated after some position. At least 500 chars can be pasted reliably (at 115200 baud), but 1K never pastes completely.
Diffstat (limited to 'esp8266/uart.c')
-rw-r--r--esp8266/uart.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/esp8266/uart.c b/esp8266/uart.c
index 69c2f40fa8..55841fe396 100644
--- a/esp8266/uart.c
+++ b/esp8266/uart.c
@@ -20,6 +20,7 @@
#include "esp_mphal.h"
#define RX_BUF_SIZE (256)
+#define UART_REPL UART0
// UartDev is defined and initialized in rom code.
extern UartDevice UartDev;
@@ -135,8 +136,7 @@ static void uart0_rx_intr_handler(void *para) {
* uart1 and uart0 respectively
*/
- uint8 RcvChar;
- uint8 uart_no = UART0;
+ uint8 uart_no = UART_REPL;
if (UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)) {
// frame error
@@ -145,23 +145,22 @@ static void uart0_rx_intr_handler(void *para) {
if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) {
// fifo full
- WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_FULL_INT_CLR);
goto read_chars;
} else if (UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) {
- WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_RXFIFO_TOUT_INT_CLR);
read_chars:
- while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
- RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
#if 1 //MICROPY_REPL_EVENT_DRIVEN is not available here
- system_os_post(UART_TASK_ID, 0, RcvChar);
+ ETS_UART_INTR_DISABLE();
+ system_os_post(UART_TASK_ID, 0, 0);
#else
+ while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
+ uint8 RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
uint16_t rx_buf_in_next = (rx_buf_in + 1) % RX_BUF_SIZE;
if (rx_buf_in_next != rx_buf_out) {
rx_buf[rx_buf_in] = RcvChar;
rx_buf_in = rx_buf_in_next;
}
-#endif
}
+#endif
}
}
@@ -175,6 +174,13 @@ int uart0_rx(void) {
}
}
+int uart_rx_one_char(uint8 uart_no) {
+ if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
+ return READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
+ }
+ return -1;
+}
+
/******************************************************************************
* FunctionName : uart_init
* Description : user interface for init uart
@@ -206,7 +212,19 @@ void ICACHE_FLASH_ATTR uart_reattach() {
void soft_reset(void);
void uart_task_handler(os_event_t *evt) {
- int ret = pyexec_event_repl_process_char(evt->par);
+ int c, ret = 0;
+ while ((c = uart_rx_one_char(UART_REPL)) >= 0) {
+ ret = pyexec_event_repl_process_char(c);
+ if (ret & PYEXEC_FORCED_EXIT) {
+ break;
+ }
+ }
+
+ // Clear pending FIFO interrupts
+ WRITE_PERI_REG(UART_INT_CLR(UART_REPL), UART_RXFIFO_TOUT_INT_CLR | UART_RXFIFO_FULL_INT_ST);
+ // Enable UART interrupts, so our task will receive events again from IRQ handler
+ ETS_UART_INTR_ENABLE();
+
if (ret & PYEXEC_FORCED_EXIT) {
soft_reset();
}