summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extmod/misc.h1
-rw-r--r--extmod/uos_dupterm.c25
-rw-r--r--ports/stm32/main.c4
-rw-r--r--ports/stm32/moduos.c13
-rw-r--r--ports/stm32/mpconfigport.h3
-rw-r--r--ports/stm32/mphalport.c12
-rw-r--r--ports/stm32/usb.c27
-rw-r--r--ports/stm32/usb.h5
-rw-r--r--ports/stm32/usbd_cdc_interface.c5
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;