From ef369249cb406758ec1caa9a212478ef69fd7ff0 Mon Sep 17 00:00:00 2001 From: Daniel Campora Date: Fri, 25 Sep 2015 15:20:07 +0200 Subject: [PATCH] cc3200: Implement support for os.dupterm(). --- cc3200/hal/cc3200_hal.c | 61 +++++++++++++++++++++++++++-------------- cc3200/hal/cc3200_hal.h | 5 ---- cc3200/mods/modpyb.c | 23 ---------------- cc3200/mods/moduos.c | 31 +++++++++++++++++++-- cc3200/mods/moduos.h | 14 ++++++++++ cc3200/mods/pybuart.c | 16 ++--------- cc3200/mods/pybuart.h | 1 - cc3200/mpconfigport.h | 3 +- cc3200/mptask.c | 11 -------- cc3200/qstrdefsport.h | 18 ++++++------ cc3200/telnet/telnet.c | 34 ++--------------------- cc3200/telnet/telnet.h | 3 -- tests/wipy/uart.py | 5 ++-- tests/wipy/uart_irq.py | 3 +- 14 files changed, 102 insertions(+), 126 deletions(-) diff --git a/cc3200/hal/cc3200_hal.c b/cc3200/hal/cc3200_hal.c index 827b59f65e..7ea243d1b2 100644 --- a/cc3200/hal/cc3200_hal.c +++ b/cc3200/hal/cc3200_hal.c @@ -36,6 +36,7 @@ #include "inc/hw_nvic.h" #include "hw_memmap.h" #include "py/mpstate.h" +#include "py/runtime.h" #include MICROPY_HAL_H #include "rom_map.h" #include "interrupt.h" @@ -47,6 +48,7 @@ #include "pybuart.h" #include "utils.h" #include "irq.h" +#include "moduos.h" #ifdef USE_FREERTOS #include "FreeRTOS.h" @@ -67,11 +69,6 @@ static void hal_TickInit (void); ******************************************************************************/ static volatile uint32_t HAL_tickCount; -/****************************************************************************** - DECLARE PUBLIC DATA - ******************************************************************************/ -struct _pyb_uart_obj_t *pyb_stdio_uart; - /****************************************************************************** DECLARE IMPORTED DATA ******************************************************************************/ @@ -141,34 +138,56 @@ void mp_hal_stdout_tx_str(const char *str) { } void mp_hal_stdout_tx_strn(const char *str, uint32_t len) { - // send stdout to UART - if (pyb_stdio_uart != NULL) { - uart_tx_strn(pyb_stdio_uart, str, len); + if (MP_STATE_PORT(os_term_dup_obj)) { + if (MP_OBJ_IS_TYPE(MP_STATE_PORT(os_term_dup_obj)->stream_o, &pyb_uart_type)) { + uart_tx_strn(MP_STATE_PORT(os_term_dup_obj)->stream_o, str, len); + } else { + MP_STATE_PORT(os_term_dup_obj)->write[2] = mp_obj_new_bytes((const byte*)str, len); + mp_call_method_n_kw(1, 0, MP_STATE_PORT(os_term_dup_obj)->write); + } } // and also to telnet - if (telnet_is_active()) { - telnet_tx_strn(str, len); - } + telnet_tx_strn(str, len); } -void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len) { - // send stdout to UART - if (pyb_stdio_uart != NULL) { - uart_tx_strn_cooked(pyb_stdio_uart, str, len); +void mp_hal_stdout_tx_strn_cooked (const char *str, uint32_t len) { + int32_t nslen = 0; + const char *_str = str; + + for (int i = 0; i < len; i++) { + if (str[i] == '\n') { + mp_hal_stdout_tx_strn(_str, nslen); + mp_hal_stdout_tx_strn("\r\n", 2); + _str += nslen + 1; + nslen = 0; + } else { + nslen++; + } } - // and also to telnet - if (telnet_is_active()) { - telnet_tx_strn_cooked(str, len); + if (_str < str + len) { + mp_hal_stdout_tx_strn(_str, nslen); } } int mp_hal_stdin_rx_chr(void) { for ( ;; ) { + // read telnet first if (telnet_rx_any()) { return telnet_rx_char(); - } - else if (pyb_stdio_uart != NULL && uart_rx_any(pyb_stdio_uart)) { - return uart_rx_char(pyb_stdio_uart); + } else if (MP_STATE_PORT(os_term_dup_obj)) { // then the stdio_dup + if (MP_OBJ_IS_TYPE(MP_STATE_PORT(os_term_dup_obj)->stream_o, &pyb_uart_type)) { + if (uart_rx_any(MP_STATE_PORT(os_term_dup_obj)->stream_o)) { + return uart_rx_char(MP_STATE_PORT(os_term_dup_obj)->stream_o); + } + } else { + MP_STATE_PORT(os_term_dup_obj)->read[2] = mp_obj_new_int(1); + mp_obj_t rbytes = mp_call_method_n_kw(1, 0, MP_STATE_PORT(os_term_dup_obj)->read); + if (rbytes != mp_const_none) { + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(rbytes, &bufinfo, MP_BUFFER_READ); + return ((int *)(bufinfo.buf))[0]; + } + } } HAL_Delay(1); } diff --git a/cc3200/hal/cc3200_hal.h b/cc3200/hal/cc3200_hal.h index ccf5d493ca..21be524d3a 100644 --- a/cc3200/hal/cc3200_hal.h +++ b/cc3200/hal/cc3200_hal.h @@ -55,11 +55,6 @@ " isb \n"); \ } -/****************************************************************************** - DECLARE PUBLIC DATA - ******************************************************************************/ -extern struct _pyb_uart_obj_t *pyb_stdio_uart; - /****************************************************************************** DECLARE PUBLIC FUNCTIONS ******************************************************************************/ diff --git a/cc3200/mods/modpyb.c b/cc3200/mods/modpyb.c index c32ea6c90b..45fa565697 100644 --- a/cc3200/mods/modpyb.c +++ b/cc3200/mods/modpyb.c @@ -141,28 +141,6 @@ STATIC mp_obj_t pyb_unique_id(void) { } STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_unique_id_obj, pyb_unique_id); -/// \function repl_uart(uart) -/// Get or set the UART object that the REPL is repeated on. -STATIC mp_obj_t pyb_repl_uart(uint n_args, const mp_obj_t *args) { - if (n_args == 0) { - if (pyb_stdio_uart == NULL) { - return mp_const_none; - } else { - return pyb_stdio_uart; - } - } else { - if (args[0] == mp_const_none) { - pyb_stdio_uart = NULL; - } else if (mp_obj_get_type(args[0]) == &pyb_uart_type) { - pyb_stdio_uart = args[0]; - } else { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments)); - } - return mp_const_none; - } -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_repl_uart_obj, 0, 1, pyb_repl_uart); - MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c STATIC const mp_map_elem_t pyb_module_globals_table[] = { @@ -174,7 +152,6 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { #endif { MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_freq_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&pyb_unique_id_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_repl_uart), (mp_obj_t)&pyb_repl_uart_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj }, diff --git a/cc3200/mods/moduos.c b/cc3200/mods/moduos.c index 8dc7716b56..096e9c393c 100644 --- a/cc3200/mods/moduos.c +++ b/cc3200/mods/moduos.c @@ -34,7 +34,7 @@ #include "py/objstr.h" #include "py/runtime.h" #include "genhdr/mpversion.h" -#include "ff.h" +#include "moduos.h" #include "diskio.h" #include "sflash_diskio.h" #include "file.h" @@ -42,8 +42,8 @@ #include "mpexception.h" #include "version.h" #include "timeutils.h" -#include "moduos.h" #include "pybsd.h" +#include "pybuart.h" /// \module os - basic "operating system" services /// @@ -60,6 +60,7 @@ DECLARE PRIVATE DATA ******************************************************************************/ STATIC uint32_t os_num_mounted_devices; +STATIC os_term_dup_obj_t os_term_dup_obj; /****************************************************************************** DEFINE PUBLIC FUNCTIONS @@ -536,6 +537,31 @@ STATIC mp_obj_t os_mkfs(mp_obj_t device) { } STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_mkfs_obj, os_mkfs); +STATIC mp_obj_t os_dupterm(uint n_args, const mp_obj_t *args) { + if (n_args == 0) { + if (MP_STATE_PORT(os_term_dup_obj) == MP_OBJ_NULL) { + return mp_const_none; + } else { + return MP_STATE_PORT(os_term_dup_obj)->stream_o; + } + } else { + mp_obj_t stream_o = args[0]; + if (stream_o == mp_const_none) { + MP_STATE_PORT(os_term_dup_obj) = MP_OBJ_NULL; + } else { + if (!MP_OBJ_IS_TYPE(stream_o, &pyb_uart_type)) { + // must be a stream-like object providing at least read and write methods + mp_load_method(stream_o, MP_QSTR_read, os_term_dup_obj.read); + mp_load_method(stream_o, MP_QSTR_write, os_term_dup_obj.write); + } + os_term_dup_obj.stream_o = stream_o; + MP_STATE_PORT(os_term_dup_obj) = &os_term_dup_obj; + } + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_dupterm_obj, 0, 1, os_dupterm); + STATIC const mp_map_elem_t os_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_uos) }, @@ -554,6 +580,7 @@ STATIC const mp_map_elem_t os_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_mount), (mp_obj_t)&os_mount_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_unmount), (mp_obj_t)&os_unmount_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_mkfs), (mp_obj_t)&os_mkfs_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_dupterm), (mp_obj_t)&os_dupterm_obj }, /// \constant sep - separation character used in paths { MP_OBJ_NEW_QSTR(MP_QSTR_sep), MP_OBJ_NEW_QSTR(MP_QSTR__slash_) }, diff --git a/cc3200/mods/moduos.h b/cc3200/mods/moduos.h index 99172b7061..fa59071257 100644 --- a/cc3200/mods/moduos.h +++ b/cc3200/mods/moduos.h @@ -28,6 +28,11 @@ #ifndef MODUOS_H_ #define MODUOS_H_ +#include "ff.h" + +/****************************************************************************** + DEFINE PUBLIC TYPES + ******************************************************************************/ typedef struct _os_fs_mount_t { mp_obj_t device; const char *path; @@ -40,6 +45,15 @@ typedef struct _os_fs_mount_t { uint8_t vol; } os_fs_mount_t; +typedef struct _os_term_dup_obj_t { + mp_obj_t stream_o; + mp_obj_t read[3]; + mp_obj_t write[3]; +} os_term_dup_obj_t; + +/****************************************************************************** + DECLARE PUBLIC FUNCTIONS + ******************************************************************************/ void moduos_init0 (void); os_fs_mount_t *osmount_find_by_path (const char *path); os_fs_mount_t *osmount_find_by_volume (uint8_t vol); diff --git a/cc3200/mods/pybuart.c b/cc3200/mods/pybuart.c index 2130009757..41819d4f5a 100644 --- a/cc3200/mods/pybuart.c +++ b/cc3200/mods/pybuart.c @@ -55,6 +55,7 @@ #include "pin.h" #include "pybpin.h" #include "pins.h" +#include "moduos.h" /// \moduleref pyb /// \class UART - duplex serial communication bus @@ -168,15 +169,6 @@ bool uart_tx_strn(pyb_uart_obj_t *self, const char *str, uint len) { return true; } -void uart_tx_strn_cooked(pyb_uart_obj_t *self, const char *str, uint len) { - for (const char *top = str + len; str < top; str++) { - if (*str == '\n') { - uart_tx_char(self, '\r'); - } - uart_tx_char(self, *str); - } -} - /****************************************************************************** DEFINE PRIVATE FUNCTIONS ******************************************************************************/ @@ -261,12 +253,10 @@ STATIC void UARTGenericIntHandler(uint32_t uart_id) { MAP_UARTIntClear(self->reg, UART_INT_RX | UART_INT_RT); while (UARTCharsAvail(self->reg)) { int data = MAP_UARTCharGetNonBlocking(self->reg); - if (pyb_stdio_uart == self && data == user_interrupt_char) { + if (MP_STATE_PORT(os_term_dup_obj) && MP_STATE_PORT(os_term_dup_obj)->stream_o == self && data == user_interrupt_char) { // raise an exception when interrupts are finished mpexception_keyboard_nlr_jump(); - } - // there's always a read buffer available - else { + } else { // there's always a read buffer available uint16_t next_head = (self->read_buf_head + 1) % PYBUART_RX_BUFFER_LEN; if (next_head != self->read_buf_tail) { // only store data if room in buf diff --git a/cc3200/mods/pybuart.h b/cc3200/mods/pybuart.h index 74871cbab0..19bc93607d 100644 --- a/cc3200/mods/pybuart.h +++ b/cc3200/mods/pybuart.h @@ -42,6 +42,5 @@ uint32_t uart_rx_any(pyb_uart_obj_t *uart_obj); int uart_rx_char(pyb_uart_obj_t *uart_obj); bool uart_tx_char(pyb_uart_obj_t *self, int c); bool uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len); -void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len); #endif // PYBUART_H_ diff --git a/cc3200/mpconfigport.h b/cc3200/mpconfigport.h index 92d96d63b1..1527938bfe 100644 --- a/cc3200/mpconfigport.h +++ b/cc3200/mpconfigport.h @@ -160,10 +160,11 @@ extern const struct _mp_obj_module_t mp_module_ussl; mp_obj_t mp_const_user_interrupt; \ mp_obj_t pyb_config_main; \ mp_obj_list_t pybsleep_obj_list; \ - mp_obj_list_t mp_irq_obj_list; \ + mp_obj_list_t mp_irq_obj_list; \ mp_obj_list_t pyb_timer_channel_obj_list; \ mp_obj_list_t mount_obj_list; \ struct _pyb_uart_obj_t *pyb_uart_objs[2]; \ + struct _os_term_dup_obj_t *os_term_dup_obj; \ // type definitions for the specific machine diff --git a/cc3200/mptask.c b/cc3200/mptask.c index f3d662af0d..3f9b8817b2 100644 --- a/cc3200/mptask.c +++ b/cc3200/mptask.c @@ -138,17 +138,6 @@ soft_reset: moduos_init0(); rng_init0(); -#ifdef LAUNCHXL - // instantiate the stdio uart on the default pins - mp_obj_t args[2] = { - mp_obj_new_int(MICROPY_STDIO_UART), - mp_obj_new_int(MICROPY_STDIO_UART_BAUD), - }; - pyb_stdio_uart = pyb_uart_type.make_new((mp_obj_t)&pyb_uart_type, MP_ARRAY_SIZE(args), 0, args); -#else - pyb_stdio_uart = MP_OBJ_NULL; -#endif - pybsleep_reset_cause_t rstcause = pybsleep_get_reset_cause(); if (rstcause < PYB_SLP_SOFT_RESET) { if (rstcause == PYB_SLP_HIB_RESET) { diff --git a/cc3200/qstrdefsport.h b/cc3200/qstrdefsport.h index 65a391046c..2c4d12f828 100644 --- a/cc3200/qstrdefsport.h +++ b/cc3200/qstrdefsport.h @@ -25,25 +25,21 @@ * THE SOFTWARE. */ -// qstrs specific to this port -Q(__name__) -Q(help) +// for pyb module Q(pyb) +Q(help) +#ifdef DEBUG Q(info) +#endif Q(reset) Q(main) Q(sync) -Q(gc) Q(rng) -Q(toggle) -Q(write) -Q(input) Q(freq) Q(unique_id) Q(disable_irq) Q(enable_irq) -Q(flush) -Q(repl_uart) + // entries for sys.path Q(/flash) Q(/flash/lib) @@ -81,6 +77,7 @@ Q(urandom) Q(mkfs) Q(mount) Q(unmount) +Q(dupterm) Q(readonly) Q(readblocks) Q(writeblocks) @@ -90,6 +87,8 @@ Q(count) // for file class Q(seek) Q(tell) +Q(input) +Q(flush) // for Pin class Q(Pin) @@ -348,7 +347,6 @@ Q(read) Q(readinto) Q(write_readinto) Q(nbytes) -Q(write) Q(buf) Q(MASTER) Q(MSB) diff --git a/cc3200/telnet/telnet.c b/cc3200/telnet/telnet.c index aa15afd9e6..966dde130e 100644 --- a/cc3200/telnet/telnet.c +++ b/cc3200/telnet/telnet.c @@ -244,34 +244,14 @@ void telnet_run (void) { } void telnet_tx_strn (const char *str, int len) { - if (len > 0 && telnet_data.n_sd > 0) { + if (telnet_data.n_sd > 0 && telnet_data.state == E_TELNET_STE_LOGGED_IN && len > 0) { telnet_send_with_retries(telnet_data.n_sd, str, len); } } -void telnet_tx_strn_cooked (const char *str, uint len) { - int32_t nslen = 0; - const char *_str = str; - - for (int i = 0; i < len; i++) { - if (str[i] == '\n') { - telnet_send_with_retries(telnet_data.n_sd, _str, nslen); - telnet_send_with_retries(telnet_data.n_sd, "\r\n", 2); - _str += nslen + 1; - nslen = 0; - } - else { - nslen++; - } - } - if (_str < str + len) { - telnet_send_with_retries(telnet_data.n_sd, _str, nslen); - } -} - bool telnet_rx_any (void) { - return (telnet_data.n_sd > 0) ? ((telnet_data.rxRindex != telnet_data.rxWindex) && - (telnet_data.state == E_TELNET_STE_LOGGED_IN)) : false; + return (telnet_data.n_sd > 0) ? (telnet_data.rxRindex != telnet_data.rxWindex && + telnet_data.state == E_TELNET_STE_LOGGED_IN) : false; } int telnet_rx_char (void) { @@ -300,14 +280,6 @@ void telnet_reset (void) { telnet_data.state = E_TELNET_STE_START; } -bool telnet_is_enabled (void) { - return telnet_data.enabled; -} - -bool telnet_is_active (void) { - return (telnet_data.state == E_TELNET_STE_LOGGED_IN); -} - /****************************************************************************** DEFINE PRIVATE FUNCTIONS ******************************************************************************/ diff --git a/cc3200/telnet/telnet.h b/cc3200/telnet/telnet.h index 983a774c8b..aa55313940 100644 --- a/cc3200/telnet/telnet.h +++ b/cc3200/telnet/telnet.h @@ -33,13 +33,10 @@ extern void telnet_init (void); extern void telnet_run (void); extern void telnet_tx_strn (const char *str, int len); -extern void telnet_tx_strn_cooked (const char *str, uint len); extern bool telnet_rx_any (void); extern int telnet_rx_char (void); extern void telnet_enable (void); extern void telnet_disable (void); extern void telnet_reset (void); -extern bool telnet_is_enabled (void); -extern bool telnet_is_active (void); #endif /* TELNET_H_ */ diff --git a/tests/wipy/uart.py b/tests/wipy/uart.py index d700c29d08..a69300d8f6 100644 --- a/tests/wipy/uart.py +++ b/tests/wipy/uart.py @@ -6,7 +6,6 @@ UART0 and UART1 must be connected together for this test to pass. from pyb import UART from pyb import Pin import os -import pyb import time machine = os.uname().machine @@ -19,8 +18,8 @@ elif 'WiPy' in machine: else: raise Exception('Board not supported!') -# just in case we have stdio duplicated on any of the uarts -pyb.repl_uart(None) +# just in case we have the repl duplicated on any of the uarts +os.dupterm(None) for uart_id in uart_id_range: uart = UART(uart_id, 38400) diff --git a/tests/wipy/uart_irq.py b/tests/wipy/uart_irq.py index 3f1084cce3..322be9e8b5 100644 --- a/tests/wipy/uart_irq.py +++ b/tests/wipy/uart_irq.py @@ -4,7 +4,6 @@ UART IRQ test for the CC3200 based boards. from pyb import UART import os -import pyb import time machine = os.uname().machine @@ -16,7 +15,7 @@ else: raise Exception('Board not supported!') # just in case we have stdio duplicated on any of the uarts -pyb.repl_uart(None) +os.dupterm(None) uart0 = UART(0, 1000000, pins=uart_pins[0][0]) uart1 = UART(1, 1000000, pins=uart_pins[1][0])