summaryrefslogtreecommitdiff
path: root/ports/esp8266/uart.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2018-05-15 15:13:58 +1000
committerDamien George <damien.p.george@gmail.com>2018-05-21 11:31:59 +1000
commitafd0701bf7a9dcb50c5ab46b0ae88b303fec6ed3 (patch)
tree9adfd980d2f367a6dd5417f490bcced1e385fbb8 /ports/esp8266/uart.c
parent2923671a0cd62f370a2b33bbd52354c7b5624300 (diff)
esp8266: Change UART(0) to attach to REPL via uos.dupterm interface.
This patch makes it so that UART(0) can by dynamically attached to and detached from the REPL by using the uos.dupterm function. Since WebREPL uses dupterm slot 0 the UART uses dupterm slot 1 (a slot which is newly introduced by this patch). UART(0) must now be attached manually in boot.py (or otherwise) and inisetup.py is changed to provide code to do this. For example, to attach use: import uos, machine uart = machine.UART(0, 115200) uos.dupterm(uart, 1) and to detach use: uos.dupterm(None, 1) When attached, all incoming chars on UART(0) go straight to stdin so uart.read() will always return None. Use sys.stdin.read() if it's needed to read characters from the UART(0) while it's also used for the REPL (or detach, read, then reattach). When detached the UART(0) can be used for other purposes. If there are no objects in any of the dupterm slots when the REPL is started (on hard or soft reset) then UART(0) is automatically attached. Without this, the only way to recover a board without a REPL would be to completely erase and reflash (which would install the default boot.py which attaches the REPL).
Diffstat (limited to 'ports/esp8266/uart.c')
-rw-r--r--ports/esp8266/uart.c29
1 files changed, 21 insertions, 8 deletions
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) {