diff options
-rw-r--r-- | extmod/misc.h | 1 | ||||
-rw-r--r-- | extmod/uos_dupterm.c | 25 | ||||
-rw-r--r-- | ports/stm32/main.c | 4 | ||||
-rw-r--r-- | ports/stm32/moduos.c | 13 | ||||
-rw-r--r-- | ports/stm32/mpconfigport.h | 3 | ||||
-rw-r--r-- | ports/stm32/mphalport.c | 12 | ||||
-rw-r--r-- | ports/stm32/usb.c | 27 | ||||
-rw-r--r-- | ports/stm32/usb.h | 5 | ||||
-rw-r--r-- | ports/stm32/usbd_cdc_interface.c | 5 |
9 files changed, 70 insertions, 25 deletions
diff --git a/extmod/misc.h b/extmod/misc.h index d6f6d859c..dae6bec4a 100644 --- a/extmod/misc.h +++ b/extmod/misc.h @@ -35,6 +35,7 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_uos_dupterm_obj); #if MICROPY_PY_OS_DUPTERM +bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream); int mp_uos_dupterm_rx_chr(void); void mp_uos_dupterm_tx_strn(const char *str, size_t len); void mp_uos_deactivate(size_t dupterm_idx, const char *msg, mp_obj_t exc); diff --git a/extmod/uos_dupterm.c b/extmod/uos_dupterm.c index dec3e1a40..42cb21444 100644 --- a/extmod/uos_dupterm.c +++ b/extmod/uos_dupterm.c @@ -32,6 +32,7 @@ #include "py/objtuple.h" #include "py/objarray.h" #include "py/stream.h" +#include "extmod/misc.h" #include "lib/utils/interrupt_char.h" #if MICROPY_PY_OS_DUPTERM @@ -58,6 +59,20 @@ int mp_uos_dupterm_rx_chr(void) { continue; } + #if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM + if (mp_uos_dupterm_is_builtin_stream(MP_STATE_VM(dupterm_objs[idx]))) { + byte buf[1]; + int errcode = 0; + const mp_stream_p_t *stream_p = mp_get_stream(MP_STATE_VM(dupterm_objs[idx])); + mp_uint_t out_sz = stream_p->read(MP_STATE_VM(dupterm_objs[idx]), buf, 1, &errcode); + if (errcode == 0 && out_sz != 0) { + return buf[0]; + } else { + continue; + } + } + #endif + nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { byte buf[1]; @@ -98,6 +113,16 @@ void mp_uos_dupterm_tx_strn(const char *str, size_t len) { if (MP_STATE_VM(dupterm_objs[idx]) == MP_OBJ_NULL) { continue; } + + #if MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM + if (mp_uos_dupterm_is_builtin_stream(MP_STATE_VM(dupterm_objs[idx]))) { + int errcode = 0; + const mp_stream_p_t *stream_p = mp_get_stream(MP_STATE_VM(dupterm_objs[idx])); + stream_p->write(MP_STATE_VM(dupterm_objs[idx]), str, len, &errcode); + continue; + } + #endif + nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { mp_stream_write(MP_STATE_VM(dupterm_objs[idx]), str, len, MP_STREAM_RW_WRITE); diff --git a/ports/stm32/main.c b/ports/stm32/main.c index 48b4692bc..c1d27a968 100644 --- a/ports/stm32/main.c +++ b/ports/stm32/main.c @@ -630,6 +630,10 @@ soft_reset: #if MICROPY_HW_ENABLE_USB pyb_usb_init0(); + + // Activate USB_VCP(0) on dupterm slot 1 for the REPL + MP_STATE_VM(dupterm_objs[1]) = MP_OBJ_FROM_PTR(&pyb_usb_vcp_obj); + usb_vcp_attach_to_repl(&pyb_usb_vcp_obj, true); #endif // Initialise the local flash filesystem. diff --git a/ports/stm32/moduos.c b/ports/stm32/moduos.c index f492b0b75..ffecccd17 100644 --- a/ports/stm32/moduos.c +++ b/ports/stm32/moduos.c @@ -38,6 +38,7 @@ #include "extmod/vfs_fat.h" #include "genhdr/mpversion.h" #include "rng.h" +#include "usb.h" #include "uart.h" #include "portmodules.h" @@ -108,14 +109,26 @@ STATIC mp_obj_t os_urandom(mp_obj_t num) { STATIC MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); #endif +bool mp_uos_dupterm_is_builtin_stream(mp_const_obj_t stream) { + mp_obj_type_t *type = mp_obj_get_type(stream); + return type == &pyb_uart_type || type == &pyb_usb_vcp_type; +} + STATIC mp_obj_t uos_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(prev_obj) == &pyb_uart_type) { uart_attach_to_repl(MP_OBJ_TO_PTR(prev_obj), false); } + if (mp_obj_get_type(prev_obj) == &pyb_usb_vcp_type) { + usb_vcp_attach_to_repl(MP_OBJ_TO_PTR(prev_obj), false); + } + if (mp_obj_get_type(args[0]) == &pyb_uart_type) { uart_attach_to_repl(MP_OBJ_TO_PTR(args[0]), true); } + if (mp_obj_get_type(args[0]) == &pyb_usb_vcp_type) { + usb_vcp_attach_to_repl(MP_OBJ_TO_PTR(args[0]), true); + } return prev_obj; } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(uos_dupterm_obj, 1, 2, uos_dupterm); diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 86f65fda2..7cb67a115 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -145,7 +145,8 @@ #define MICROPY_PY_USELECT (1) #define MICROPY_PY_UTIMEQ (1) #define MICROPY_PY_UTIME_MP_HAL (1) -#define MICROPY_PY_OS_DUPTERM (1) +#define MICROPY_PY_OS_DUPTERM (3) +#define MICROPY_PY_UOS_DUPTERM_BUILTIN_STREAM (1) #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c index 9e59eb613..c770b62d2 100644 --- a/ports/stm32/mphalport.c +++ b/ports/stm32/mphalport.c @@ -30,13 +30,6 @@ MP_WEAK int mp_hal_stdin_rx_chr(void) { } #endif #endif - - #if MICROPY_HW_ENABLE_USB - byte c; - if (usb_vcp_recv_byte(&c) != 0) { - return c; - } - #endif if (MP_STATE_PORT(pyb_stdio_uart) != NULL && uart_rx_any(MP_STATE_PORT(pyb_stdio_uart))) { return uart_rx_char(MP_STATE_PORT(pyb_stdio_uart)); } @@ -59,11 +52,6 @@ MP_WEAK void mp_hal_stdout_tx_strn(const char *str, size_t len) { #if 0 && defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD lcd_print_strn(str, len); #endif - #if MICROPY_HW_ENABLE_USB - if (usb_vcp_is_enabled()) { - usb_vcp_send_strn(str, len); - } - #endif mp_uos_dupterm_tx_strn(str, len); } diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 1ff62b4ab..1db32c9ae 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -111,6 +111,10 @@ const mp_rom_obj_tuple_t pyb_usb_hid_keyboard_obj = { }; void pyb_usb_init0(void) { + usb_device.usbd_cdc_itf.attached_to_repl = false; + #if MICROPY_HW_USB_ENABLE_CDC2 + usb_device.usbd_cdc2_itf.attached_to_repl = false; + #endif mp_hal_set_interrupt_char(-1); MP_STATE_PORT(pyb_hid_report_desc) = MP_OBJ_NULL; } @@ -380,7 +384,7 @@ typedef struct _pyb_usb_vcp_obj_t { usbd_cdc_itf_t *cdc_itf; } pyb_usb_vcp_obj_t; -STATIC const pyb_usb_vcp_obj_t pyb_usb_vcp_obj = {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc_itf}; +const pyb_usb_vcp_obj_t pyb_usb_vcp_obj = {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc_itf}; #if MICROPY_HW_USB_ENABLE_CDC2 STATIC const pyb_usb_vcp_obj_t pyb_usb_vcp2_obj = {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc2_itf}; #endif @@ -390,6 +394,10 @@ STATIC void pyb_usb_vcp_print(const mp_print_t *print, mp_obj_t self_in, mp_prin mp_printf(print, "USB_VCP(%u)", id); } +void usb_vcp_attach_to_repl(const pyb_usb_vcp_obj_t *self, bool attached) { + self->cdc_itf->attached_to_repl = attached; +} + /// \classmethod \constructor() /// Create a new USB_VCP object. STATIC mp_obj_t pyb_usb_vcp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { @@ -566,13 +574,18 @@ STATIC mp_uint_t pyb_usb_vcp_read(mp_obj_t self_in, void *buf, mp_uint_t size, i STATIC mp_uint_t pyb_usb_vcp_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) { pyb_usb_vcp_obj_t *self = MP_OBJ_TO_PTR(self_in); - int ret = usbd_cdc_tx(self->cdc_itf, (const byte*)buf, size, 0); - if (ret == 0) { - // return EAGAIN error to indicate non-blocking - *errcode = MP_EAGAIN; - return MP_STREAM_ERROR; + if (self->cdc_itf->attached_to_repl) { + usbd_cdc_tx_always(self->cdc_itf, (const byte*)buf, size); + return size; + } else { + int ret = usbd_cdc_tx(self->cdc_itf, (const byte*)buf, size, 0); + if (ret == 0) { + // return EAGAIN error to indicate non-blocking + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } + return ret; } - return ret; } STATIC mp_uint_t pyb_usb_vcp_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { diff --git a/ports/stm32/usb.h b/ports/stm32/usb.h index 45a05882a..2a3861f21 100644 --- a/ports/stm32/usb.h +++ b/ports/stm32/usb.h @@ -49,12 +49,16 @@ typedef enum { USB_PHY_HS_ID = 1, } USB_PHY_ID; +typedef struct _pyb_usb_vcp_obj_t pyb_usb_vcp_obj_t; + extern mp_uint_t pyb_usb_flags; extern pyb_usb_storage_medium_t pyb_usb_storage_medium; extern const struct _mp_rom_obj_tuple_t pyb_usb_hid_mouse_obj; extern const struct _mp_rom_obj_tuple_t pyb_usb_hid_keyboard_obj; extern const mp_obj_type_t pyb_usb_vcp_type; extern const mp_obj_type_t pyb_usb_hid_type; +extern const pyb_usb_vcp_obj_t pyb_usb_vcp_obj; + MP_DECLARE_CONST_FUN_OBJ_KW(pyb_usb_mode_obj); MP_DECLARE_CONST_FUN_OBJ_0(pyb_have_cdc_obj); // deprecated MP_DECLARE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj); // deprecated @@ -65,6 +69,7 @@ void pyb_usb_dev_deinit(void); bool usb_vcp_is_enabled(void); int usb_vcp_recv_byte(uint8_t *c); // if a byte is available, return 1 and put the byte in *c, else return 0 void usb_vcp_send_strn(const char* str, int len); +void usb_vcp_attach_to_repl(const pyb_usb_vcp_obj_t *self, bool attached); void pyb_usb_host_init(void); void pyb_usb_host_process(void); diff --git a/ports/stm32/usbd_cdc_interface.c b/ports/stm32/usbd_cdc_interface.c index bc35ff50c..586f2d525 100644 --- a/ports/stm32/usbd_cdc_interface.c +++ b/ports/stm32/usbd_cdc_interface.c @@ -74,11 +74,6 @@ uint8_t *usbd_cdc_init(usbd_cdc_state_t *cdc_in) { cdc->tx_buf_ptr_out_shadow = 0; cdc->tx_need_empty_packet = 0; cdc->connect_state = USBD_CDC_CONNECT_STATE_DISCONNECTED; - #if MICROPY_HW_USB_ENABLE_CDC2 - cdc->attached_to_repl = &cdc->base == cdc->base.usbd->cdc; - #else - cdc->attached_to_repl = 1; - #endif // Return the buffer to place the first USB OUT packet return cdc->rx_packet_buf; |