Skip to content

Fix usb_cdc.enable(console=False, data=True) #4848

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ports/atmel-samd/boards/metro_m4_express/pins.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA19) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA17) },

{ MP_OBJ_NEW_QSTR(MP_QSTR_LED),MP_ROM_PTR(&pin_PA16) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_D13),MP_ROM_PTR(&pin_PA16) },

{ MP_OBJ_NEW_QSTR(MP_QSTR_SDA),MP_ROM_PTR(&pin_PB02) },
Expand Down
18 changes: 14 additions & 4 deletions shared-module/usb_cdc/__init__.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,26 +147,26 @@ static const char data_cdc_comm_interface_name[] = USB_INTERFACE_NAME " CDC2 con
static const char console_cdc_data_interface_name[] = USB_INTERFACE_NAME " CDC data";
static const char data_cdc_data_interface_name[] = USB_INTERFACE_NAME " CDC2 data";

// .idx is set later.

static usb_cdc_serial_obj_t usb_cdc_console_obj = {
.base.type = &usb_cdc_serial_type,
.timeout = -1.0f,
.write_timeout = -1.0f,
.idx = 0,
};

static usb_cdc_serial_obj_t usb_cdc_data_obj = {
.base.type = &usb_cdc_serial_type,
.timeout = -1.0f,
.write_timeout = -1.0f,
.idx = 1,
};

static bool usb_cdc_console_is_enabled;
static bool usb_cdc_data_is_enabled;

void usb_cdc_set_defaults(void) {
usb_cdc_console_is_enabled = CIRCUITPY_USB_CDC_CONSOLE_ENABLED_DEFAULT;
usb_cdc_data_is_enabled = CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT;
common_hal_usb_cdc_enable(CIRCUITPY_USB_CDC_CONSOLE_ENABLED_DEFAULT,
CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT);
}

bool usb_cdc_console_enabled(void) {
Expand Down Expand Up @@ -241,11 +241,21 @@ bool common_hal_usb_cdc_enable(bool console, bool data) {
// Right now these objects contain no heap objects, but if that changes,
// they will need to be protected against gc.

// Assign only as many idx values as necessary. They must start at 0.
uint8_t idx = 0;
usb_cdc_console_is_enabled = console;
usb_cdc_set_console(console ? MP_OBJ_FROM_PTR(&usb_cdc_console_obj) : mp_const_none);
if (console) {
usb_cdc_console_obj.idx = idx;
idx++;
}

usb_cdc_data_is_enabled = data;
usb_cdc_set_data(data ? MP_OBJ_FROM_PTR(&usb_cdc_data_obj) : mp_const_none);
if (data) {
usb_cdc_data_obj.idx = idx;
}


return true;
}
26 changes: 19 additions & 7 deletions supervisor/shared/usb/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,15 @@ void usb_init(void) {

post_usb_init();

#if MICROPY_KBD_EXCEPTION
#if MICROPY_KBD_EXCEPTION && CIRCUITPY_USB_CDC
// Set Ctrl+C as wanted char, tud_cdc_rx_wanted_cb() usb_callback will be invoked when Ctrl+C is received
// This usb_callback always got invoked regardless of mp_interrupt_char value since we only set it once here
tud_cdc_set_wanted_char(CHAR_CTRL_C);

// Don't watch for ctrl-C if there is no REPL.
if (usb_cdc_console_enabled()) {
// Console will always be itf 0.
tud_cdc_set_wanted_char(CHAR_CTRL_C);
}
#endif
}

Expand All @@ -103,7 +108,7 @@ void usb_set_defaults(void) {
#endif
};

// Some dynamic USB data must be saved after boot.py. How much is needed
// Some dynamic USB data must be saved after boot.py. How much is needed?
size_t usb_boot_py_data_size(void) {
size_t size = 0;

Expand Down Expand Up @@ -151,7 +156,13 @@ void usb_background(void) {
#if CFG_TUSB_OS == OPT_OS_NONE
tud_task();
#endif
tud_cdc_write_flush();
// No need to flush if there's no REPL.
#if CIRCUITPY_USB_CDC
if (usb_cdc_console_enabled()) {
// Console will always be itf 0.
tud_cdc_write_flush();
}
#endif
}
}

Expand Down Expand Up @@ -205,6 +216,7 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
// DTR = false is counted as disconnected
if (!dtr) {
cdc_line_coding_t coding;
// Use whichever CDC is itf 0.
tud_cdc_get_line_coding(&coding);

if (coding.bit_rate == 1200) {
Expand Down Expand Up @@ -274,13 +286,13 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
* @param itf Interface index (for multiple cdc interfaces)
* @param wanted_char The wanted char (set previously)
*/
void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) {
(void)itf; // not used

// Only called when console is enabled.
void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) {
// Workaround for using lib/utils/interrupt_char.c
// Compare mp_interrupt_char with wanted_char and ignore if not matched
if (mp_interrupt_char == wanted_char) {
tud_cdc_read_flush(); // flush read fifo
tud_cdc_n_read_flush(itf); // flush read fifo
mp_keyboard_interrupt();
}
}
Expand Down