8000 Merge pull request #9999 from jepler/rp2-usb-host-enhancements · chbeer/circuitpython@c3989b2 · GitHub
[go: up one dir, main page]

Skip to content

Commit c3989b2

Browse files
authored
Merge pull request adafruit#9999 from jepler/rp2-usb-host-enhancements
raspberrypi: Update usb_host for newer PIO resource usage
2 parents db1172f + 2eed793 commit c3989b2

File tree

4 files changed

+34
-66
lines changed

4 files changed

+34
-66
lines changed

ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c

-5Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@
2525

2626
picodvi_framebuffer_obj_t *active_picodvi = NULL;
2727

28-
static PIO pio_instances[2] = {pio0, pio1};
29-
3028
static void __not_in_flash_func(core1_main)(void) {
3129
// The MPU is reset before this starts.
3230

@@ -184,7 +182,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
184182
size_t pio_index = NUM_PIOS;
185183
int free_state_machines[4]; // We may find all four free. We only use the first three.
186184
for (size_t i = 0; i < NUM_PIOS; i++) {
187-
PIO pio = pio_instances[i];
185+
PIO pio = pio_get_instance(i);
188186
uint8_t free_count = 0;
189187
for (size_t sm = 0; sm < NUM_PIO_STATE_MACHINES; sm++) {
190188
if (!pio_sm_is_claimed(pio, sm)) {
@@ -244,7 +242,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
244242
}
245243

246244
for (size_t i = 0; i < 3; i++) {
247-
rp2pio_statemachine_never_reset(pio_instances[pio_index], free_state_machines[i]);
245+
rp2pio_statemachine_never_reset(pio_get_instance(pio_index), free_state_machines[i]);
248246
}
249247

250248
// For the output.
@@ -253,7 +251,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
253251
self->color_depth = color_depth;
254252

255253
self->dvi.timing = timing;
256-
self->dvi.ser_cfg.pio = pio_instances[pio_index];
254+
self->dvi.ser_cfg.pio = pio_get_instance(pio_index);
257255
self->dvi.ser_cfg.sm_tmds[0] = free_state_machines[0];
258256
self->dvi.ser_cfg.sm_tmds[1] = free_state_machines[1];
259257
self->dvi.ser_cfg.sm_tmds[2] = free_state_machines[2];

ports/raspberrypi/common-hal/rp2pio/StateMachine.c

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,6 @@ static int8_t _sm_dma_plus_one_read[NUM_PIOS][NUM_PIO_STATE_MACHINES];
5151
#define SM_DMA_CLEAR_CHANNEL_READ(pio_index, sm) (_sm_dma_plus_one_read[(pio_index)][(sm)] = 0)
5252
#define SM_DMA_SET_CHANNEL_READ(pio_index, sm, channel) (_sm_dma_plus_one_read[(pio_index)][(sm)] = (channel) + 1)
5353

54-
static PIO pio_instances[NUM_PIOS] = {
55-
pio0,
56-
pio1
57-
#if NUM_PIOS == 3
58-
, pio2
59-
#endif
60-
};
6154
typedef void (*interrupt_handler_type)(void *);
6255
static interrupt_handler_type _interrupt_handler[NUM_PIOS][NUM_PIO_STATE_MACHINES];
6356
static void *_interrupt_arg[NUM_PIOS][NUM_PIO_STATE_MACHINES];
@@ -162,7 +155,7 @@ static void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) {
162155

163156
void reset_rp2pio_statemachine(void) {
164157
for (size_t i = 0; i < NUM_PIOS; i++) {
165-
PIO pio = pio_instances[i];
158+
PIO pio = pio_get_instance(i);
166159
for (size_t j = 0; j < NUM_PIO_STATE_MACHINES; j++) {
167160
if (_never_reset[i][j]) {
168161
continue;
@@ -252,7 +245,7 @@ static bool use_existing_program(PIO *pio_out, uint *sm_out, int *offset_inout,
252245
}
253246

254247
for (size_t i = 0; i < NUM_PIOS; i++) {
255-
PIO pio = pio_instances[i];
248+
PIO pio = pio_get_instance(i);
256249
if (!is_gpio_compatible(pio, required_gpio_ranges)) {
257250
continue;
258251
}
@@ -1097,7 +1090,7 @@ void common_hal_rp2pio_statemachine_set_interrupt_handler(rp2pio_statemachine_ob
10971090

10981091
static void rp2pio_statemachine_interrupt_handler(void) {
10991092
for (size_t pio_index = 0; pio_index < NUM_PIOS; pio_index++) {
1100-
PIO pio = pio_instances[pio_index];
1093+
PIO pio = pio_get_instance(pio_index);
11011094
for (size_t sm = 0; sm < NUM_PIO_STATE_MACHINES; sm++) {
11021095
if (!_interrupt_handler[pio_index][sm]) {
11031096
continue;
@@ -1452,7 +1445,7 @@ int common_hal_rp2pio_statemachine_get_offset(rp2pio_statemachine_obj_t *self) {
14521445

14531446
int common_hal_rp2pio_statemachine_get_pc(rp2pio_statemachine_obj_t *self) {
14541447
uint8_t pio_index = pio_get_index(self->pio);
1455-
PIO pio = pio_instances[pio_index];
1448+
PIO pio = pio_get_instance(pio_index);
14561449
uint8_t sm = self->state_machine;
14571450
return pio_sm_get_pc(pio, sm);
14581451
}

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

Lines changed: 26 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333

3434
usb_host_port_obj_t usb_host_instance;
3535

36-
static PIO pio_instances[2] = {pio0, pio1};
3736
volatile bool _core1_ready = false;
3837

3938
static void __not_in_flash_func(core1_main)(void) {
@@ -76,7 +75,7 @@ static void __not_in_flash_func(core1_main)(void) {
7675
}
7776

7877
static 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

8988
static 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

113115
usb_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

Comments
 (0)
0