stm32: Make default USB_VCP stream go through uos.dupterm for main REPL.
Use uos.dupterm for REPL configuration of the main USB_VCP(0) stream on dupterm slot 1, if USB is enabled. This means dupterm can also be used to disable the boot REPL port if desired, via uos.dupterm(None, 1). For efficiency this adds a simple hook to the global uos.dupterm code to work with streams that are known to be native streams.
This commit is contained in:
parent
0fb15fc3f4
commit
9d6f70f715
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user