From f12ea7c7ed1ef97ee48c4356dbbc808cc2bdee4a Mon Sep 17 00:00:00 2001
From: Paul Sokolovsky <pfalcon@users.sourceforge.net>
Date: Fri, 16 Jan 2015 01:54:40 +0200
Subject: [PATCH] esp8266: Implement task-based, event-driven interface with
 UART.

This enables proper interfacing with underlying OS - MicroPython doesn't
run the main loop, OS does, MicroPython just gets called when some event
takes place.
---
 esp8266/esp_mphal.h    |  3 +++
 esp8266/main.c         |  7 +++++++
 esp8266/mpconfigport.h |  3 ++-
 esp8266/uart.c         | 20 ++++++++++++++++++++
 4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/esp8266/esp_mphal.h b/esp8266/esp_mphal.h
index e80ede9c9..369b375d9 100644
--- a/esp8266/esp_mphal.h
+++ b/esp8266/esp_mphal.h
@@ -40,4 +40,7 @@ void HAL_Delay(uint32_t Delay);
 void mp_hal_set_interrupt_char(int c);
 uint32_t mp_hal_get_cpu_freq(void);
 
+#define UART_TASK_ID 0
+void uart_task_init();
+
 #endif // _INCLUDED_MPHAL_H_
diff --git a/esp8266/main.c b/esp8266/main.c
index 68d015a26..86f306cbe 100644
--- a/esp8266/main.c
+++ b/esp8266/main.c
@@ -52,6 +52,12 @@ soft_reset:
 
     printf("\n");
 
+#if MICROPY_REPL_EVENT_DRIVEN
+    pyexec_friendly_repl_init();
+    uart_task_init();
+    return;
+    goto soft_reset;
+#else
     for (;;) {
         if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
             if (pyexec_raw_repl() != 0) {
@@ -65,6 +71,7 @@ soft_reset:
     }
 
     goto soft_reset;
+#endif
 }
 
 mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h
index 2782ceace..c1cdcb340 100644
--- a/esp8266/mpconfigport.h
+++ b/esp8266/mpconfigport.h
@@ -9,7 +9,8 @@
 #define MICROPY_MEM_STATS           (0)
 #define MICROPY_DEBUG_PRINTERS      (0)
 #define MICROPY_ENABLE_GC           (1)
-#define MICROPY_STACK_CHECK         (1)
+#define MICROPY_STACK_CHECK         (0)
+#define MICROPY_REPL_EVENT_DRIVEN   (1)
 #define MICROPY_HELPER_REPL         (1)
 #define MICROPY_HELPER_LEXER_UNIX   (0)
 #define MICROPY_ENABLE_SOURCE_LINE  (1)
diff --git a/esp8266/uart.c b/esp8266/uart.c
index c037b997a..6087668a7 100644
--- a/esp8266/uart.c
+++ b/esp8266/uart.c
@@ -16,6 +16,8 @@
 #include "uart_register.h"
 #include "etshal.h"
 #include "c_types.h"
+#include "user_interface.h"
+#include "esp_mphal.h"
 
 #define RX_BUF_SIZE (256)
 
@@ -27,6 +29,8 @@ static uint16_t rx_buf_in;
 static uint16_t rx_buf_out;
 static uint8_t rx_buf[RX_BUF_SIZE];
 
+static os_event_t uart_evt_queue[16];
+
 static void uart0_rx_intr_handler(void *para);
 
 /******************************************************************************
@@ -148,11 +152,15 @@ static void uart0_rx_intr_handler(void *para) {
         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);
+#else
             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
         }
     }
 }
@@ -189,3 +197,15 @@ void ICACHE_FLASH_ATTR uart_init(UartBautRate uart0_br, UartBautRate uart1_br) {
 void ICACHE_FLASH_ATTR uart_reattach() {
     uart_init(UART_BIT_RATE_74880, UART_BIT_RATE_74880);
 }
+
+// Task-based UART interface
+
+int pyexec_friendly_repl_process_char(int c);
+
+void uart_task_handler(os_event_t *evt) {
+    pyexec_friendly_repl_process_char(evt->par);
+}
+
+void uart_task_init() {
+    system_os_task(uart_task_handler, UART_TASK_ID, uart_evt_queue, sizeof(uart_evt_queue) / sizeof(*uart_evt_queue));
+}
-- 
GitLab