Skip to content

Commit 98af891

Browse files
committed
esp8266: Implement input part of dupterm handling.
The idea is following: underlying interrupt-driven or push-style data source signals that more data is available for dupterm processing via call to mp_hal_signal_dupterm_input(). This triggers a task which pumps data between actual dupterm object (which may perform additional processing on data from low-level data source) and input ring buffer.
1 parent 61fa7c8 commit 98af891

3 files changed

Lines changed: 62 additions & 0 deletions

File tree

esp8266/esp_mphal.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "py/obj.h"
3535
#include "py/mpstate.h"
3636
#include "extmod/misc.h"
37+
#include "lib/utils/pyexec.h"
3738

3839
extern void ets_wdt_disable(void);
3940
extern void wdt_feed(void);
@@ -157,3 +158,59 @@ void __assert_func(const char *file, int line, const char *func, const char *exp
157158
void mp_hal_signal_input(void) {
158159
system_os_post(UART_TASK_ID, 0, 0);
159160
}
161+
162+
static int call_dupterm_read(void) {
163+
if (MP_STATE_PORT(term_obj) == NULL) {
164+
return -1;
165+
}
166+
167+
nlr_buf_t nlr;
168+
if (nlr_push(&nlr) == 0) {
169+
mp_obj_t read_m[3];
170+
mp_load_method(MP_STATE_PORT(term_obj), MP_QSTR_read, read_m);
171+
read_m[2] = MP_OBJ_NEW_SMALL_INT(1);
172+
mp_obj_t res = mp_call_method_n_kw(1, 0, read_m);
173+
if (res == mp_const_none) {
174+
return -2;
175+
}
176+
mp_buffer_info_t bufinfo;
177+
mp_get_buffer_raise(res, &bufinfo, MP_BUFFER_READ);
178+
if (bufinfo.len == 0) {
179+
mp_printf(&mp_plat_print, "dupterm: EOF received, deactivating\n");
180+
MP_STATE_PORT(term_obj) = NULL;
181+
return -1;
182+
}
183+
nlr_pop();
184+
return *(byte*)bufinfo.buf;
185+
} else {
186+
// Temporarily disable dupterm to avoid infinite recursion
187+
mp_obj_t save_term = MP_STATE_PORT(term_obj);
188+
MP_STATE_PORT(term_obj) = NULL;
189+
mp_printf(&mp_plat_print, "dupterm: ");
190+
mp_obj_print_exception(&mp_plat_print, nlr.ret_val);
191+
MP_STATE_PORT(term_obj) = save_term;
192+
}
193+
194+
return -1;
195+
}
196+
197+
STATIC void dupterm_task_handler(os_event_t *evt) {
198+
while (1) {
199+
int c = call_dupterm_read();
200+
if (c < 0) {
201+
break;
202+
}
203+
ringbuf_put(&input_buf, c);
204+
}
205+
mp_hal_signal_input();
206+
}
207+
208+
STATIC os_event_t dupterm_evt_queue[4];
209+
210+
void dupterm_task_init() {
211+
system_os_task(dupterm_task_handler, DUPTERM_TASK_ID, dupterm_evt_queue, MP_ARRAY_SIZE(dupterm_evt_queue));
212+
}
213+
214+
void mp_hal_signal_dupterm_input(void) {
215+
system_os_post(DUPTERM_TASK_ID, 0, 0);
216+
}

esp8266/esp_mphal.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ extern const struct _mp_print_t mp_debug_print;
3636
extern ringbuf_t input_buf;
3737
// Call this after putting data to input_buf
3838
void mp_hal_signal_input(void);
39+
// Call this when data is available in dupterm object
40+
void mp_hal_signal_dupterm_input(void);
3941

4042
void mp_hal_init(void);
4143
void mp_hal_rtc_init(void);
@@ -47,7 +49,9 @@ void mp_hal_set_interrupt_char(int c);
4749
uint32_t mp_hal_get_cpu_freq(void);
4850

4951
#define UART_TASK_ID 0
52+
#define DUPTERM_TASK_ID 1
5053
void uart_task_init();
54+
void dupterm_task_init();
5155

5256
void ets_event_poll(void);
5357
#define ETS_POLL_WHILE(cond) { while (cond) ets_event_poll(); }

esp8266/main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ void init_done(void) {
6969
mp_reset();
7070
mp_hal_stdout_tx_str("\r\n");
7171
pyexec_event_repl_init();
72+
dupterm_task_init();
7273
}
7374

7475
void user_init(void) {

0 commit comments

Comments
 (0)