@@ -96,6 +96,20 @@ static bool _has_program_room(uint8_t pio_index, uint8_t program_size) {
96
96
return pio_can_add_program (pio , & program_struct );
97
97
}
98
98
99
+ // from pico-sdk/src/rp2_common/hardware_pio/pio.c
100
+ static bool is_gpio_compatible (PIO pio , uint32_t used_gpio_ranges ) {
101
+ #if PICO_PIO_VERSION > 0
102
+ bool gpio_base = pio_get_gpio_base (pio );
103
+ return !((gpio_base && (used_gpio_ranges & 1 )) ||
104
+ (!gpio_base && (used_gpio_ranges & 4 )));
105
+ #else
106
+ ((void )pio );
107
+ ((void )used_gpio_ranges );
108
+ return true;
109
+ #endif
110
+ }
111
+
112
+
99
113
usb_host_port_obj_t * common_hal_usb_host_port_construct (const mcu_pin_obj_t * dp , const mcu_pin_obj_t * dm ) {
100
114
if (dp -> number + 1 != dm -> number ) {
101
115
raise_ValueError_invalid_pins ();
@@ -113,15 +127,31 @@ usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp,
113
127
assert_pin_free (dp );
114
128
assert_pin_free (dm );
115
129
130
+ #if PICO_PIO_VERSION > 0
131
+ uint32_t used_gpio_ranges = 0 ;
132
+ #else
133
+ uint gpio_base = dm -> number ;
134
+ uint gpio_count = 2 ;
135
+ uint32_t required_gpio_ranges = (1u << (gpio_base >> 4 )) |
136
+ (1u << ((gpio_base + gpio_count - 1 ) >> 4 ));
137
+ #endif
138
+
116
139
pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG ;
117
140
pio_cfg .skip_alarm_pool = true;
118
141
pio_cfg .pin_dp = dp -> number ;
119
142
// Allocating the peripherals like this works on Pico W, where the
120
143
// "preferred PIO" for the cyw43 wifi chip is PIO 1.
121
144
pio_cfg .pio_tx_num = 1 ; // uses 22 instructions and 1 SM
122
145
pio_cfg .pio_rx_num = 0 ; // uses 31 instructions and 2 SM.
123
- if (!_has_program_room (pio_cfg .pio_tx_num , 22 ) || _sm_free_count (pio_cfg .pio_tx_num ) < 1 ||
124
- !_has_program_room (pio_cfg .pio_rx_num , 31 ) || _sm_free_count (pio_cfg .pio_rx_num ) < 2 ) {
146
+ uint8_t tx_sm_free = _sm_free_count (pio_cfg .pio_tx_num );
147
+ uint8_t rx_sm_free = _sm_free_count (pio_cfg .pio_rx_num );
148
+ PIO pio_tx = pio_instances [pio_cfg .pio_tx_num ];
149
+ <
8000
div class="diff-text-inner"> PIO pio_rx = pio_instances [pio_cfg .pio_rx_num ];
150
+
151
+ if (!_has_program_room (pio_cfg .pio_tx_num , 22 ) || tx_sm_free < 1 ||
152
+ !(tx_sm_free == 4 || is_gpio_compatible (pio_tx , used_gpio_ranges )) ||
153
+ !_has_program_room (pio_cfg .pio_rx_num , 31 ) || rx_sm_free < 2 ||
154
+ !(rx_sm_free == 4 || is_gpio_compatible (pio_rx , used_gpio_ranges ))) {
125
155
mp_raise_RuntimeError (MP_ERROR_TEXT ("All state machines in use" ));
126
156
}
127
157
pio_cfg .tx_ch = dma_claim_unused_channel (false); // DMA channel
0 commit comments