Skip to content

Commit 3fc3a92

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents b2c3297 + 3053039 commit 3fc3a92

File tree

15 files changed

+128
-84
lines changed

15 files changed

+128
-84
lines changed

lib/tinyusb

Submodule tinyusb updated 57 files

ports/mimxrt10xx/boards/imxrt1060_evk/board.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "supervisor/board.h"
2929
#include "shared-bindings/microcontroller/Pin.h"
3030

31+
#include "shared-bindings/usb_host/Port.h"
32+
3133
// These pins should never ever be reset; doing so could interfere with basic operation.
3234
// Used in common-hal/microcontroller/Pin.c
3335
const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = {
@@ -55,4 +57,8 @@ const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = {
5557
NULL, // Must end in NULL.
5658
};
5759

60+
void board_init(void) {
61+
common_hal_usb_host_port_construct(&pin_USB_OTG2_DP, &pin_USB_OTG2_DN);
62+
}
63+
5864
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.

ports/mimxrt10xx/boards/imxrt1060_evkb/board.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "supervisor/board.h"
2929
#include "shared-bindings/microcontroller/Pin.h"
3030

31+
#include "shared-bindings/usb_host/Port.h"
32+
3133
// These pins should never ever be reset; doing so could interfere with basic operation.
3234
// Used in common-hal/microcontroller/Pin.c
3335
const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = {
@@ -52,7 +54,11 @@ const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = {
5254
// USB Pins
5355
&pin_GPIO_AD_B0_01, // ID Pin
5456
&pin_GPIO_AD_B0_03, // OC/Fault Pin
55-
NULL, // Must end in NULL.
57+
NULL, // Must end in NULL.
5658
};
5759

60+
void board_init(void) {
61+
common_hal_usb_host_port_construct(&pin_USB_OTG2_DP, &pin_USB_OTG2_DN);
62+
}
63+
5864
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.

ports/mimxrt10xx/boards/teensy41/board.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include "supervisor/board.h"
2929
#include "shared-bindings/microcontroller/Pin.h"
3030

31+
#include "shared-bindings/usb_host/Port.h"
32+
3133
// These pins should never ever be reset; doing so could interfere with basic operation.
3234
// Used in common-hal/microcontroller/Pin.c
3335
const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = {
@@ -54,4 +56,8 @@ const mcu_pin_obj_t *mimxrt10xx_reset_forbidden_pins[] = {
5456
NULL, // Must end in NULL.
5557
};
5658

59+
void board_init(void) {
60+
common_hal_usb_host_port_construct(&pin_USB_OTG2_DP, &pin_USB_OTG2_DN);
61+
}
62+
5763
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.

ports/mimxrt10xx/common-hal/usb_host/Port.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,13 @@
2929

3030
#include "py/runtime.h"
3131

32-
bool usb_host_init;
32+
#include "tusb.h"
3333

34-
void common_hal_usb_host_port_construct(usb_host_port_obj_t *self, const mcu_pin_obj_t *dp, const mcu_pin_obj_t *dm) {
34+
#include "imx_usb.h"
35+
36+
usb_host_port_obj_t usb_host_instance;
37+
38+
usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, const mcu_pin_obj_t *dm) {
3539
const mcu_pin_obj_t *supported_dp;
3640
const mcu_pin_obj_t *supported_dm;
3741
if (CIRCUITPY_USB_HOST_INSTANCE == 0) {
@@ -41,18 +45,27 @@ void common_hal_usb_host_port_construct(usb_host_port_obj_t *self, const mcu_pin
4145
supported_dp = &pin_USB_OTG2_DP;
4246
supported_dm = &pin_USB_OTG2_DN;
4347
}
48+
// Return the singleton if given the same pins.
49+
usb_host_port_obj_t *self = &usb_host_instance;
50+
if (self->dp != NULL) {
51+
if (self->dp != dp || self->dm != dm) {
52+
mp_raise_msg_varg(&mp_type_RuntimeError, translate("%q in use"), MP_QSTR_usb_host);
53+
}
54+
return self;
55+
}
4456
if (dp != supported_dp || dm != supported_dm) {
4557
raise_ValueError_invalid_pins();
4658
}
47-
self->init = true;
48-
usb_host_init = true;
49-
}
5059

51-
void common_hal_usb_host_port_deinit(usb_host_port_obj_t *self) {
52-
self->init = false;
53-
usb_host_init = false;
54-
}
60+
assert_pin_free(dp);
61+
assert_pin_free(dm);
62+
63+
init_usb_instance(CIRCUITPY_USB_HOST_INSTANCE);
64+
tuh_init(TUH_OPT_RHPORT);
65+
66+
self->base.type = &usb_host_port_type;
67+
self->dp = dp;
68+
self->dm = dm;
5569

56-
bool common_hal_usb_host_port_deinited(usb_host_port_obj_t *self) {
57-
return !self->init;
70+
return self;
5871
}

ports/mimxrt10xx/common-hal/usb_host/Port.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,8 @@
3131

3232
typedef struct {
3333
mp_obj_base_t base;
34-
bool init;
34+
const mcu_pin_obj_t *dp;
35+
const mcu_pin_obj_t *dm;
3536
} usb_host_port_obj_t;
3637

37-
// Cheater state so that the usb module knows if it should return the TinyUSB
38-
// state.
39-
extern bool usb_host_init;
40-
4138
#endif // MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_USB_HOST_PORT_H

ports/mimxrt10xx/imx_usb.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#pragma once
28+
29+
// Provided by supervisor/usb.c that has a shared, non-port-specific header. So,
30+
// just define it here.
31+
void init_usb_instance(mp_int_t instance);

ports/mimxrt10xx/linking/common.ld

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ SECTIONS
7171
. = ALIGN(4);
7272
*(EXCLUDE_FILE(
7373
*fsl_flexspi.o
74-
*dcd_ci_hs.o
74+
*cd_ci_hs.o
7575
*ehci.o
7676
*tusb_fifo.o
7777
*usbd.o
@@ -88,6 +88,9 @@ SECTIONS
8888
/* Keep USB processing functions out of RAM because we don't know which will be used.
8989
We try to only keep USB interrupt related functions. */
9090
*dcd_ci_hs.o(.text.process_*_request .text.dcd_edpt* .text.dcd_init .text.dcd_set_address)
91+
/* Move hcd_dcache* routines to RAM so that we don't cross execution from
92+
the cache during cache maintenance. Weird things happen when we do. */
93+
*hcd_ci_hs.o(.text.hcd_i*)
9194
*usbd.o(.text.process_*_request .text.process_[gs]et* .text.tud_* .text.usbd_* .text.configuration_reset .text.invoke_*)
9295
*ehci.o(.text.hcd_edpt* .text.hcd_setup* .text.ehci_init* .text.hcd_port* .text.hcd_device* .text.qtd_init* .text.list_remove*)
9396

ports/mimxrt10xx/supervisor/usb.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
#include "supervisor/linker.h"
3232
#include "supervisor/usb.h"
3333

34-
STATIC void init_usb_instance(mp_int_t instance) {
34+
#include "imx_usb.h"
35+
36+
void init_usb_instance(mp_int_t instance) {
3537
if (instance < 0) {
3638
return;
3739
}
@@ -72,9 +74,6 @@ STATIC void init_usb_instance(mp_int_t instance) {
7274

7375
void init_usb_hardware(void) {
7476
init_usb_instance(CIRCUITPY_USB_DEVICE_INSTANCE);
75-
// We can't dynamically start the USB Host port at the moment, so do it
76-
// up front.
77-
init_usb_instance(CIRCUITPY_USB_HOST_INSTANCE);
7877
}
7978

8079
// Provide the prototypes for the interrupt handlers. The iMX RT SDK doesn't.

ports/raspberrypi/boards/adafruit_feather_rp2040_usb_host/board.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,12 @@
3131

3232
// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here.
3333

34-
usb_host_port_obj_t _host_port;
3534
digitalio_digitalinout_obj_t _host_power;
3635

3736
void board_init(void) {
3837
common_hal_digitalio_digitalinout_construct(&_host_power, &pin_GPIO18);
3938
common_hal_digitalio_digitalinout_never_reset(&_host_power);
4039
common_hal_digitalio_digitalinout_switch_to_output(&_host_power, true, DRIVE_MODE_PUSH_PULL);
4140

42-
common_hal_usb_host_port_construct(&_host_port, &pin_GPIO16, &pin_GPIO17);
41+
common_hal_usb_host_port_construct(&pin_GPIO16, &pin_GPIO17);
4342
}

ports/raspberrypi/common-hal/usb_host/Port.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
#include "supervisor/serial.h"
4747

48-
bool usb_host_init;
48+
usb_host_port_obj_t usb_host_instance;
4949

5050
STATIC PIO pio_instances[2] = {pio0, pio1};
5151
volatile bool _core1_ready = false;
@@ -102,10 +102,23 @@ STATIC bool _has_program_room(uint8_t pio_index, uint8_t program_size) {
102102
return pio_can_add_program(pio, &program_struct);
103103
}
104104

105-
void common_hal_usb_host_port_construct(usb_host_port_obj_t *self, const mcu_pin_obj_t *dp, const mcu_pin_obj_t *dm) {
105+
usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, const mcu_pin_obj_t *dm) {
106106
if (dp->number + 1 != dm->number) {
107107
raise_ValueError_invalid_pins();
108108
}
109+
usb_host_port_obj_t *self = &usb_host_instance;
110+
111+
// Return the singleton if given the same pins.
112+
if (self->dp != NULL) {
113+
if (self->dp != dp || self->dm != dm) {
114+
mp_raise_msg_varg(&mp_type_RuntimeError, translate("%q in use"), MP_QSTR_usb_host);
115+
}
116+
return self;
117+
}
118+
119+
assert_pin_free(dp);
120+
assert_pin_free(dm);
121+
109122
pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG;
110123
pio_cfg.skip_alarm_pool = true;
111124
pio_cfg.pin_dp = dp->number;
@@ -122,6 +135,10 @@ void common_hal_usb_host_port_construct(usb_host_port_obj_t *self, const mcu_pin
122135
mp_raise_RuntimeError(translate("All dma channels in use"));
123136
}
124137

138+
self->base.type = &usb_host_port_type;
139+
self->dp = dp;
140+
self->dm = dm;
141+
125142
PIO tx_pio = pio_instances[pio_cfg.pio_tx_num];
126143
pio_cfg.sm_tx = pio_claim_unused_sm(tx_pio, false);
127144
PIO rx_pio = pio_instances[pio_cfg.pio_rx_num];
@@ -151,15 +168,5 @@ void common_hal_usb_host_port_construct(usb_host_port_obj_t *self, const mcu_pin
151168
tuh_configure(TUH_OPT_RHPORT, TUH_CFGID_RPI_PIO_USB_CONFIGURATION, &pio_cfg);
152169
tuh_init(TUH_OPT_RHPORT);
153170

154-
self->init = true;
155-
usb_host_init = true;
156-
}
157-
158-
void common_hal_usb_host_port_deinit(usb_host_port_obj_t *self) {
159-
self->init = false;
160-
usb_host_init = false;
161-
}
162-
163-
bool common_hal_usb_host_port_deinited(usb_host_port_obj_t *self) {
164-
return !self->init;
171+
return self;
165172
}

ports/raspberrypi/common-hal/usb_host/Port.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@
3030

3131
typedef struct {
3232
mp_obj_base_t base;
33-
bool init;
33+
const mcu_pin_obj_t *dp;
34+
const mcu_pin_obj_t *dm;
3435
} usb_host_port_obj_t;
35-
36-
// Cheater state so that the usb module knows if it should return the TinyUSB
37-
// state.
38-
extern bool usb_host_init;

shared-bindings/usb_host/Port.c

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -35,59 +35,36 @@
3535
//|
3636
//| def __init__(self, dp: microcontroller.Pin, dm: microcontroller.Pin) -> None:
3737
//| """Create a USB host port on the given pins. Access attached devices
38-
//| through the `usb` module. Keep this object referenced while
39-
//| interacting with devices, otherwise they will be disconnected.
38+
//| through the `usb` module.
39+
//|
40+
//| The resulting object lives longer than the CircuitPython VM so that
41+
//| USB devices such as keyboards can continue to be used. Subsequent
42+
//| calls to this constructor will return the same object and *not*
43+
//| reinitialize the USB host port. It will raise an exception when
44+
//| given different arguments from the first successful call.
4045
//|
4146
//| :param ~microcontroller.Pin dp: The data plus pin
4247
//| :param ~microcontroller.Pin dm: The data minus pin
4348
//| """
4449
//| ...
50+
//|
4551
STATIC mp_obj_t usb_host_port_make_new(const mp_obj_type_t *type,
4652
size_t n_args, size_t n_kw, const mp_obj_t *args) {
4753
// check number of arguments
4854
mp_arg_check_num(n_args, n_kw, 2, 2, false);
4955

50-
const mcu_pin_obj_t *dp = validate_obj_is_free_pin(args[0], MP_QSTR_dp);
51-
const mcu_pin_obj_t *dm = validate_obj_is_free_pin(args[1], MP_QSTR_dm);
52-
53-
usb_host_port_obj_t *self = m_new_obj(usb_host_port_obj_t);
54-
self->base.type = &usb_host_port_type;
55-
common_hal_usb_host_port_construct(self, dp, dm);
56-
57-
return (mp_obj_t)self;
58-
}
56+
const mcu_pin_obj_t *dp = validate_obj_is_pin(args[0], MP_QSTR_dp);
57+
const mcu_pin_obj_t *dm = validate_obj_is_pin(args[1], MP_QSTR_dm);
5958

60-
//| def deinit(self) -> None:
61-
//| """Turn off the USB host port and release the pins for other use."""
62-
//| ...
63-
STATIC mp_obj_t usb_host_port_obj_deinit(mp_obj_t self_in) {
64-
usb_host_port_obj_t *self = MP_OBJ_TO_PTR(self_in);
65-
common_hal_usb_host_port_deinit(self);
66-
return mp_const_none;
67-
}
68-
MP_DEFINE_CONST_FUN_OBJ_1(usb_host_port_deinit_obj, usb_host_port_obj_deinit);
59+
// Pin in use checks happen in the implementation so they can be ignored
60+
// when returning the singleton.
6961

70-
//| def __enter__(self) -> Port:
71-
//| """No-op used by Context Managers."""
72-
//| ...
73-
// Provided by context manager helper.
62+
usb_host_port_obj_t *self = common_hal_usb_host_port_construct(dp, dm);
7463

75-
//| def __exit__(self) -> None:
76-
//| """Automatically deinitializes the hardware when exiting a context. See
77-
//| :ref:`lifetime-and-contextmanagers` for more info."""
78-
//| ...
79-
//|
80-
STATIC mp_obj_t usb_host_port_obj___exit__(size_t n_args, const mp_obj_t *args) {
81-
(void)n_args;
82-
common_hal_usb_host_port_deinit(MP_OBJ_TO_PTR(args[0]));
83-
return mp_const_none;
64+
return (mp_obj_t)self;
8465
}
85-
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(usb_host_port_obj___exit___obj, 4, 4, usb_host_port_obj___exit__);
8666

8767
STATIC const mp_rom_map_elem_t usb_host_port_locals_dict_table[] = {
88-
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&usb_host_port_deinit_obj) },
89-
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
90-
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&usb_host_port_obj___exit___obj) },
9168
};
9269

9370
STATIC MP_DEFINE_CONST_DICT(usb_host_port_locals_dict, usb_host_port_locals_dict_table);

shared-bindings/usb_host/Port.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,10 @@
3535

3636
extern const mp_obj_type_t usb_host_port_type;
3737

38-
void common_hal_usb_host_port_construct(usb_host_port_obj_t *self, const mcu_pin_obj_t *dp, const mcu_pin_obj_t *dm);
39-
void common_hal_usb_host_port_deinit(usb_host_port_obj_t *self);
40-
bool common_hal_usb_host_port_deinited(usb_host_port_obj_t *self);
38+
// This is unique to common_hal constructs because it returns a globally stored
39+
// object instead of taking on in that may be on the heap. This allows the
40+
// method to check the internals of the global object against the given arguments
41+
// to determine whether to return the singleton or raise an exception.
42+
usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, const mcu_pin_obj_t *dm);
4143

4244
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_USB_HOST_PORT_H

supervisor/shared/usb/tusb_config.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ extern "C" {
152152
#endif
153153

154154
#define CFG_TUH_HID 2
155-
#define CFG_TUH_HUB 1
155+
// 2 hubs so we can support "7 port" hubs which have two internal hubs.
156+
#define CFG_TUH_HUB 2
156157
#define CFG_TUH_CDC 0
157158
#define CFG_TUH_MSC 0
158159
#define CFG_TUH_VENDOR 0

0 commit comments

Comments
 (0)