summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/esp8266/esp_mphal.c27
-rw-r--r--ports/esp8266/esp_mphal.h7
-rw-r--r--ports/esp8266/main.c20
-rw-r--r--ports/esp8266/modules/inisetup.py2
-rw-r--r--ports/esp8266/moduos.c15
-rw-r--r--ports/esp8266/mpconfigport.h2
-rw-r--r--ports/esp8266/uart.c29
7 files changed, 73 insertions, 29 deletions
diff --git a/ports/esp8266/esp_mphal.c b/ports/esp8266/esp_mphal.c
index 9f4f051fd..df97a7343 100644
--- a/ports/esp8266/esp_mphal.c
+++ b/ports/esp8266/esp_mphal.c
@@ -35,15 +35,18 @@
#include "extmod/misc.h"
#include "lib/utils/pyexec.h"
-STATIC byte input_buf_array[256];
-ringbuf_t input_buf = {input_buf_array, sizeof(input_buf_array)};
+STATIC byte stdin_ringbuf_array[256];
+ringbuf_t stdin_ringbuf = {stdin_ringbuf_array, sizeof(stdin_ringbuf_array), 0, 0};
void mp_hal_debug_tx_strn_cooked(void *env, const char *str, uint32_t len);
const mp_print_t mp_debug_print = {NULL, mp_hal_debug_tx_strn_cooked};
+int uart_attached_to_dupterm;
+
void mp_hal_init(void) {
//ets_wdt_disable(); // it's a pain while developing
mp_hal_rtc_init();
uart_init(UART_BIT_RATE_115200, UART_BIT_RATE_115200);
+ uart_attached_to_dupterm = 0;
}
void mp_hal_delay_us(uint32_t us) {
@@ -55,7 +58,7 @@ void mp_hal_delay_us(uint32_t us) {
int mp_hal_stdin_rx_chr(void) {
for (;;) {
- int c = ringbuf_get(&input_buf);
+ int c = ringbuf_get(&stdin_ringbuf);
if (c != -1) {
return c;
}
@@ -80,19 +83,11 @@ void mp_hal_debug_str(const char *str) {
#endif
void mp_hal_stdout_tx_str(const char *str) {
- const char *last = str;
- while (*str) {
- uart_tx_one_char(UART0, *str++);
- }
- mp_uos_dupterm_tx_strn(last, str - last);
+ mp_uos_dupterm_tx_strn(str, strlen(str));
}
void mp_hal_stdout_tx_strn(const char *str, uint32_t len) {
- const char *last = str;
- while (len--) {
- uart_tx_one_char(UART0, *str++);
- }
- mp_uos_dupterm_tx_strn(last, str - last);
+ mp_uos_dupterm_tx_strn(str, len);
}
void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len) {
@@ -102,13 +97,11 @@ void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len) {
if (str > last) {
mp_uos_dupterm_tx_strn(last, str - last);
}
- uart_tx_one_char(UART0, '\r');
- uart_tx_one_char(UART0, '\n');
mp_uos_dupterm_tx_strn("\r\n", 2);
++str;
last = str;
} else {
- uart_tx_one_char(UART0, *str++);
+ ++str;
}
}
if (str > last) {
@@ -166,7 +159,7 @@ STATIC void dupterm_task_handler(os_event_t *evt) {
if (c < 0) {
break;
}
- ringbuf_put(&input_buf, c);
+ ringbuf_put(&stdin_ringbuf, c);
}
mp_hal_signal_input();
lock = 0;
diff --git a/ports/esp8266/esp_mphal.h b/ports/esp8266/esp_mphal.h
index 940ca4727..56d9fa35f 100644
--- a/ports/esp8266/esp_mphal.h
+++ b/ports/esp8266/esp_mphal.h
@@ -34,12 +34,15 @@ struct _mp_print_t;
// Structure for UART-only output via mp_printf()
extern const struct _mp_print_t mp_debug_print;
-extern ringbuf_t input_buf;
-// Call this after putting data to input_buf
+extern ringbuf_t stdin_ringbuf;
+// Call this after putting data to stdin_ringbuf
void mp_hal_signal_input(void);
// Call this when data is available in dupterm object
void mp_hal_signal_dupterm_input(void);
+// This variable counts how many times the UART is attached to dupterm
+extern int uart_attached_to_dupterm;
+
void mp_hal_init(void);
void mp_hal_rtc_init(void);
diff --git a/ports/esp8266/main.c b/ports/esp8266/main.c
index d2d2c34ec..975262fd1 100644
--- a/ports/esp8266/main.c
+++ b/ports/esp8266/main.c
@@ -33,6 +33,7 @@
#include "py/mperrno.h"
#include "py/mphal.h"
#include "py/gc.h"
+#include "extmod/misc.h"
#include "lib/mp-readline/readline.h"
#include "lib/utils/pyexec.h"
#include "gccollect.h"
@@ -65,6 +66,25 @@ STATIC void mp_reset(void) {
pyexec_file("main.py");
}
#endif
+
+ // Check if there are any dupterm objects registered and if not then
+ // activate UART(0), or else there will never be any chance to get a REPL
+ size_t idx;
+ for (idx = 0; idx < MICROPY_PY_OS_DUPTERM; ++idx) {
+ if (MP_STATE_VM(dupterm_objs[idx]) != MP_OBJ_NULL) {
+ break;
+ }
+ }
+ if (idx == MICROPY_PY_OS_DUPTERM) {
+ mp_obj_t args[2];
+ args[0] = MP_OBJ_NEW_SMALL_INT(0);
+ args[1] = MP_OBJ_NEW_SMALL_INT(115200);
+ args[0] = pyb_uart_type.make_new(&pyb_uart_type, 2, 0, args);
+ args[1] = MP_OBJ_NEW_SMALL_INT(1);
+ extern mp_obj_t os_dupterm(size_t n_args, const mp_obj_t *args);
+ os_dupterm(2, args);
+ mp_hal_stdout_tx_str("Activated UART(0) for REPL\r\n");
+ }
}
void soft_reset(void) {
diff --git a/ports/esp8266/modules/inisetup.py b/ports/esp8266/modules/inisetup.py
index af78dfad5..9184c6c39 100644
--- a/ports/esp8266/modules/inisetup.py
+++ b/ports/esp8266/modules/inisetup.py
@@ -44,6 +44,8 @@ def setup():
# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
+import uos, machine
+uos.dupterm(machine.UART(0, 115200), 1)
import gc
#import webrepl
#webrepl.start()
diff --git a/ports/esp8266/moduos.c b/ports/esp8266/moduos.c
index 93f7aa712..7a32c11c0 100644
--- a/ports/esp8266/moduos.c
+++ b/ports/esp8266/moduos.c
@@ -76,6 +76,19 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom);
+// We wrap the mp_uos_dupterm function to detect if a UART is attached or not
+mp_obj_t os_dupterm(size_t n_args, const mp_obj_t *args) {
+ mp_obj_t prev_obj = mp_uos_dupterm_obj.fun.var(n_args, args);
+ if (mp_obj_get_type(args[0]) == &pyb_uart_type) {
+ ++uart_attached_to_dupterm;
+ }
+ if (mp_obj_get_type(prev_obj) == &pyb_uart_type) {
+ --uart_attached_to_dupterm;
+ }
+ return prev_obj;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_dupterm_obj, 1, 2, os_dupterm);
+
STATIC mp_obj_t os_dupterm_notify(mp_obj_t obj_in) {
(void)obj_in;
mp_hal_signal_dupterm_input();
@@ -88,7 +101,7 @@ STATIC const mp_rom_map_elem_t os_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_uname), MP_ROM_PTR(&os_uname_obj) },
{ MP_ROM_QSTR(MP_QSTR_urandom), MP_ROM_PTR(&os_urandom_obj) },
#if MICROPY_PY_OS_DUPTERM
- { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&mp_uos_dupterm_obj) },
+ { MP_ROM_QSTR(MP_QSTR_dupterm), MP_ROM_PTR(&os_dupterm_obj) },
{ MP_ROM_QSTR(MP_QSTR_dupterm_notify), MP_ROM_PTR(&os_dupterm_notify_obj) },
#endif
#if MICROPY_VFS_FAT
diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h
index 8de28eb96..ec347dae0 100644
--- a/ports/esp8266/mpconfigport.h
+++ b/ports/esp8266/mpconfigport.h
@@ -86,7 +86,7 @@
#define MICROPY_PY_WEBREPL_DELAY (20)
#define MICROPY_PY_FRAMEBUF (1)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
-#define MICROPY_PY_OS_DUPTERM (1)
+#define MICROPY_PY_OS_DUPTERM (2)
#define MICROPY_CPYTHON_COMPAT (1)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
diff --git a/ports/esp8266/uart.c b/ports/esp8266/uart.c
index ec944a97c..52707f981 100644
--- a/ports/esp8266/uart.c
+++ b/ports/esp8266/uart.c
@@ -34,6 +34,11 @@ static int uart_os = UART_OS;
static os_event_t uart_evt_queue[16];
#endif
+// A small, static ring buffer for incoming chars
+// This will only be populated if the UART is not attached to dupterm
+static byte uart_ringbuf_array[16];
+static ringbuf_t uart_ringbuf = {uart_ringbuf_array, sizeof(uart_ringbuf_array), 0, 0};
+
static void uart0_rx_intr_handler(void *para);
void soft_reset(void);
@@ -170,18 +175,26 @@ static void uart0_rx_intr_handler(void *para) {
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;
- if (RcvChar == mp_interrupt_char) {
- mp_keyboard_interrupt();
+ // For efficiency, when connected to dupterm we put incoming chars
+ // directly on stdin_ringbuf, rather than going via uart_ringbuf
+ if (uart_attached_to_dupterm) {
+ if (RcvChar == mp_interrupt_char) {
+ mp_keyboard_interrupt();
+ } else {
+ ringbuf_put(&stdin_ringbuf, RcvChar);
+ }
} else {
- ringbuf_put(&input_buf, RcvChar);
+ ringbuf_put(&uart_ringbuf, RcvChar);
}
}
- mp_hal_signal_input();
-
// Clear pending FIFO interrupts
WRITE_PERI_REG(UART_INT_CLR(UART_REPL), UART_RXFIFO_TOUT_INT_CLR | UART_RXFIFO_FULL_INT_ST);
ETS_UART_INTR_ENABLE();
+
+ if (uart_attached_to_dupterm) {
+ mp_hal_signal_input();
+ }
}
}
@@ -190,7 +203,7 @@ static void uart0_rx_intr_handler(void *para) {
bool uart_rx_wait(uint32_t timeout_us) {
uint32_t start = system_get_time();
for (;;) {
- if (input_buf.iget != input_buf.iput) {
+ if (uart_ringbuf.iget != uart_ringbuf.iput) {
return true; // have at least 1 char ready for reading
}
if (system_get_time() - start >= timeout_us) {
@@ -201,7 +214,7 @@ bool uart_rx_wait(uint32_t timeout_us) {
}
int uart_rx_any(uint8 uart) {
- if (input_buf.iget != input_buf.iput) {
+ if (uart_ringbuf.iget != uart_ringbuf.iput) {
return true; // have at least 1 char ready for reading
}
return false;
@@ -217,7 +230,7 @@ int uart_tx_any_room(uint8 uart) {
// Returns char from the input buffer, else -1 if buffer is empty.
int uart_rx_char(void) {
- return ringbuf_get(&input_buf);
+ return ringbuf_get(&uart_ringbuf);
}
int uart_rx_one_char(uint8 uart_no) {