3333
3434usb_host_port_obj_t usb_host_instance ;
3535
36- static PIO pio_instances [2 ] = {pio0 , pio1 };
3736volatile bool _core1_ready = false;
3837
3938static void __not_in_flash_func (core1_main )(void ) {
@@ -76,7 +75,7 @@ static void __not_in_flash_func(core1_main)(void) {
7675}
7776
7877static uint8_t _sm_free_count (uint8_t pio_index ) {
79- PIO pio = pio_instances [ pio_index ] ;
78+ PIO pio = pio_get_instance ( pio_index ) ;
8079 uint8_t free_count = 0 ;
8180 for (size_t j = 0 ; j < NUM_PIO_STATE_MACHINES ; j ++ ) {
8281 if (!pio_sm_is_claimed (pio , j )) {
@@ -87,7 +86,7 @@ static uint8_t _sm_free_count(uint8_t pio_index) {
8786}
8887
8988static bool _has_program_room (uint8_t pio_index , uint8_t program_size ) {
90- PIO pio = pio_instances [ pio_index ] ;
89+ PIO pio = pio_get_instance ( pio_index ) ;
9190 pio_program_t program_struct = {
9291 .instructions = NULL ,
9392 .length = program_size ,
@@ -96,22 +95,26 @@ static bool _has_program_room(uint8_t pio_index, uint8_t program_size) {
9695 return pio_can_add_program (pio , & program_struct );
9796}
9897
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
98+ // As of 0.6.1, the PIO resource requirement is 1 PIO with 3 state machines &
99+ // 32 instructions. Since there are only 32 instructions in a state machine, it should
100+ // be impossible to have an allocated state machine but 32 instruction slots available;
101+ // go ahead and check for it anyway.
102+ //
103+ // Since we check that ALL state machines are available, it's not possible for the GPIO
104+ // ranges to mismatch on rp2350b
105+ static size_t get_usb_pio (void ) {
106+ for (size_t i = 0 ; i < NUM_PIOS ; i ++ ) {
107+ if (_has_program_room (i , 32 ) && _sm_free_count (i ) == NUM_PIO_STATE_MACHINES ) {
108+ return i ;
109+ }
110+ }
111+ mp_raise_RuntimeError (MP_ERROR_TEXT ("All state machines in use" ));
110112}
111113
112114
113115usb_host_port_obj_t * common_hal_usb_host_port_construct (const mcu_pin_obj_t * dp , const mcu_pin_obj_t * dm ) {
114- if (dp -> number + 1 != dm -> number ) {
116+ if ((dp -> number + 1 != dm -> number )
117+ && (dp -> number - 1 != dm -> number )) {
115118 raise_ValueError_invalid_pins ();
116119 }
117120 usb_host_port_obj_t * self = & usb_host_instance ;
@@ -127,33 +130,14 @@ usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp,
127130 assert_pin_free (dp );
128131 assert_pin_free (dm );
129132
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 used_gpio_ranges = (1u << (gpio_base >> 4 )) |
136- (1u << ((gpio_base + gpio_count - 1 ) >> 4 ));
137- #endif
138-
139133 pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG ;
140134 pio_cfg .skip_alarm_pool = true;
141135 pio_cfg .pin_dp = dp -> number ;
142- // Allocating the peripherals like this works on Pico W, where the
143- // "preferred PIO" for the cyw43 wifi chip is PIO 1.
144- pio_cfg .pio_tx_num = 1 ; // uses 22 instructions and 1 SM
145- pio_cfg .pio_rx_num = 0 ; // uses 31 instructions and 2 SM.
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- 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 ))) {
155- mp_raise_RuntimeError (MP_ERROR_TEXT ("All state machines in use" ));
136+ if (dp -> number - 1 == dm -> number ) {
137+ pio_cfg .pinout = PIO_USB_PINOUT_DMDP ;
156138 }
139+ pio_cfg .pio_tx_num = get_usb_pio ();
140+ pio_cfg .pio_rx_num = pio_cfg .pio_tx_num ;
157141 pio_cfg .tx_ch = dma_claim_unused_channel (false); // DMA channel
158142 if (pio_cfg .tx_ch < 0 ) {
159143 mp_raise_RuntimeError (MP_ERROR_TEXT ("All dma channels in use" ));
@@ -163,22 +147,15 @@ usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp,
163147 self -> dp = dp ;
164148 self -> dm = dm ;
165149
166- PIO tx_pio = pio_instances [pio_cfg .pio_tx_num ];
167- pio_cfg .sm_tx = pio_claim_unused_sm (tx_pio , false);
168- PIO rx_pio = pio_instances [pio_cfg .pio_rx_num ];
169- pio_cfg .sm_rx = pio_claim_unused_sm (rx_pio , false);
170- pio_cfg .sm_eop = pio_claim_unused_sm (rx_pio , false);
150+ PIO pio = pio_get_instance (pio_cfg .pio_tx_num );
171151
172152 // Unclaim everything so that the library can.
173153 dma_channel_unclaim (pio_cfg .tx_ch );
174- pio_sm_unclaim (tx_pio , pio_cfg .sm_tx );
175- pio_sm_unclaim (rx_pio , pio_cfg .sm_rx );
176- pio_sm_unclaim (rx_pio , pio_cfg .sm_eop );
177154
178155 // Set all of the state machines to never reset.
179- rp2pio_statemachine_never_reset (tx_pio , pio_cfg .sm_tx );
180- rp2pio_statemachine_never_reset (rx_pio , pio_cfg .sm_rx );
181- rp2pio_statemachine_never_reset (rx_pio , pio_cfg .sm_eop );
156+ rp2pio_statemachine_never_reset (pio , pio_cfg .sm_tx );
157+ rp2pio_statemachine_never_reset (pio , pio_cfg .sm_rx );
158+ rp2pio_statemachine_never_reset (pio , pio_cfg .sm_eop );
182159
183160 common_hal_never_reset_pin (dp );
184161 common_hal_never_reset_pin (dm );
0 commit comments