Skip to content

Commit 1629faf

Browse files
committed
Make usb_host.Port a singleton
This allows you to initialize usb_host.Port once successfully and then returns the same object as long as you pass the same arguments in. It does allow you to fix incorrect pins but not switching from one valid set to another. (It needs a reset for that.) This also moves hcd cache operations to RAM so that they don't access the cache when doing maintenance.
1 parent a2002e3 commit 1629faf

File tree

14 files changed

+97
-84
lines changed

14 files changed

+97
-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/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
}

0 commit comments

Comments
 (0)