Skip to content

Commit 31f7889

Browse files
committed
raspberrypi: Update usb_host for newer PIO resource usage
Closes: #9958
1 parent e03798b commit 31f7889

File tree

1 file changed

+20
-45
lines changed
  • ports/raspberrypi/common-hal/usb_host

1 file changed

+20
-45
lines changed

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

Lines changed: 20 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,20 @@ static bool _has_program_room(uint8_t pio_index, uint8_t program_size) {
9696
return pio_can_add_program(pio, &program_struct);
9797
}
9898

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
99+
// As of 0.6.1, the PIO resource requirement is 1 PIO with 3 state machines &
100+
// 32 instructions. Since there are only 32 instructions in a state machine, it should
101+
// be impossible to have an allocated state machine but 32 instruction slots available;
102+
// go ahead and check for it anyway.
103+
//
104+
// Since we check that ALL state machines are available, it's not possible for the GPIO
105+
// ranges to mismatch on rp2350b
106+
static size_t get_usb_pio(void) {
107+
for (size_t i = 0; i < NUM_PIOS; i++) {
108+
if (_has_program_room(i, 32) && _sm_free_count(i) == NUM_PIO_STATE_MACHINES) {
109+
return i;
110+
}
111+
}
112+
mp_raise_RuntimeError(MP_ERROR_TEXT("All state machines in use"));
110113
}
111114

112115

@@ -127,33 +130,12 @@ 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"));
156136
}
137+
pio_cfg.pio_tx_num = get_usb_pio();
138+
pio_cfg.pio_rx_num = pio_cfg.pio_tx_num;
157139
pio_cfg.tx_ch = dma_claim_unused_channel(false); // DMA channel
158140
if (pio_cfg.tx_ch < 0) {
159141
mp_raise_RuntimeError(MP_ERROR_TEXT("All dma channels in use"));
@@ -163,22 +145,15 @@ usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp,
163145
self->dp = dp;
164146
self->dm = dm;
165147

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);
148+
PIO pio = pio_instances[pio_cfg.pio_tx_num];
171149

172150
// Unclaim everything so that the library can.
173151
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);
177152

178153
// 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);
154+
rp2pio_statemachine_never_reset(pio, pio_cfg.sm_tx);
155+
rp2pio_statemachine_never_reset(pio, pio_cfg.sm_rx);
156+
rp2pio_statemachine_never_reset(pio, pio_cfg.sm_eop);
182157

183158
common_hal_never_reset_pin(dp);
184159
common_hal_never_reset_pin(dm);

0 commit comments

Comments
 (0)