Skip to content

Commit 576a1ac

Browse files
committed
pico w: Disentangle "TOTAL_GPIO_COUNT", it's complicated
You might wonder how this fixes a problem with PulseIn, when the changes aren't to any of those files! PulseIn is implemented in terms of StateMachine, which had some assumptions about the relation between the index of a pin object in mcu_pin_global_dict_table and its "pin number". This was true, until some pins were removed from the microcontroller module on Pico W. Closes: #7078
1 parent 31d7c91 commit 576a1ac

File tree

5 files changed

+36
-19
lines changed

5 files changed

+36
-19
lines changed

ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ void alarm_pin_pinalarm_reset(void) {
111111
}
112112

113113
// Reset pins and pin IRQs
114-
for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) {
114+
for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) {
115115
if (alarm_reserved_pins & (1 << i)) {
116116
gpio_set_irq_enabled(i, GPIO_IRQ_ALL_EVENTS, false);
117117
reset_pin_number(i);

ports/raspberrypi/common-hal/microcontroller/Pin.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,32 +46,33 @@ void reset_pin_number_cyw(uint8_t pin_no) {
4646
STATIC uint32_t never_reset_pins;
4747

4848
void reset_all_pins(void) {
49-
for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) {
49+
for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) {
5050
if ((never_reset_pins & (1 << i)) != 0) {
5151
continue;
5252
}
5353
reset_pin_number(i);
5454
}
5555
#if CIRCUITPY_CYW43
5656
if (cyw_ever_init) {
57-
for (size_t i = 0; i < 1; i++) {
58-
cyw43_arch_gpio_put(i, 0);
59-
}
57+
// reset LED and SMPS_MODE to Low; don't touch VBUS_SENSE
58+
// otherwise it is switched to output mode forever!
59+
cyw43_arch_gpio_put(0, 0);
60+
cyw43_arch_gpio_put(1, 0);
6061
}
6162
cyw_pin_claimed = 0;
6263
#endif
6364
}
6465

6566
void never_reset_pin_number(uint8_t pin_number) {
66-
if (pin_number >= TOTAL_GPIO_COUNT) {
67+
if (pin_number >= NUM_BANK0_GPIOS) {
6768
return;
6869
}
6970

7071
never_reset_pins |= 1 << pin_number;
7172
}
7273

7374
void reset_pin_number(uint8_t pin_number) {
74-
if (pin_number >= TOTAL_GPIO_COUNT) {
75+
if (pin_number >= NUM_BANK0_GPIOS) {
7576
return;
7677
}
7778

@@ -110,7 +111,7 @@ void claim_pin(const mcu_pin_obj_t *pin) {
110111
}
111112

112113
bool pin_number_is_free(uint8_t pin_number) {
113-
if (pin_number >= TOTAL_GPIO_COUNT) {
114+
if (pin_number >= NUM_BANK0_GPIOS) {
114115
return false;
115116
}
116117

ports/raspberrypi/common-hal/microcontroller/__init__.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ watchdog_watchdogtimer_obj_t common_hal_mcu_watchdogtimer_obj = {
149149
#endif
150150

151151
// This maps MCU pin names to pin objects.
152-
const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = {
152+
const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
153153
{ MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) },
154154
{ MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO1) },
155155
{ MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) },
@@ -193,3 +193,13 @@ const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = {
193193
#endif
194194
};
195195
MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table);
196+
197+
const mcu_pin_obj_t *mcu_get_pin_by_number(int number) {
198+
for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_pin_global_dict_table); i++) {
199+
mcu_pin_obj_t *obj = MP_OBJ_TO_PTR(mcu_pin_global_dict_table[i].value);
200+
if (obj->base.type == &mcu_pin_type && obj->number == number) {
201+
return obj;
202+
}
203+
}
204+
return NULL;
205+
}

ports/raspberrypi/common-hal/microcontroller/__init__.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@
2828
#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H
2929

3030
#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h"
31+
#include "peripherals/pins.h"
3132

32-
#define TOTAL_GPIO_COUNT NUM_BANK0_GPIOS
33-
34-
extern const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT];
33+
const mcu_pin_obj_t *mcu_get_pin_by_number(int);
3534

3635
#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
#define NO_DMA_CHANNEL (-1)
4949

5050
// Count how many state machines are using each pin.
51-
STATIC uint8_t _pin_reference_count[TOTAL_GPIO_COUNT];
51+
STATIC uint8_t _pin_reference_count[NUM_BANK0_GPIOS];
5252
STATIC uint32_t _current_program_id[NUM_PIOS][NUM_PIO_STATE_MACHINES];
5353
STATIC uint8_t _current_program_offset[NUM_PIOS][NUM_PIO_STATE_MACHINES];
5454
STATIC uint8_t _current_program_len[NUM_PIOS][NUM_PIO_STATE_MACHINES];
@@ -71,7 +71,7 @@ STATIC void *_interrupt_arg[NUM_PIOS][NUM_PIO_STATE_MACHINES];
7171
STATIC void rp2pio_statemachine_interrupt_handler(void);
7272

7373
static void rp2pio_statemachine_set_pull(uint32_t pull_pin_up, uint32_t pull_pin_down, uint32_t pins_we_use) {
74-
for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) {
74+
for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) {
7575
bool used = pins_we_use & (1 << i);
7676
if (used) {
7777
bool pull_up = pull_pin_up & (1 << i);
@@ -120,7 +120,7 @@ STATIC void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) {
120120
}
121121

122122
uint32_t pins = _current_sm_pins[pio_index][sm];
123-
for (size_t pin_number = 0; pin_number < TOTAL_GPIO_COUNT; pin_number++) {
123+
for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) {
124124
if ((pins & (1 << pin_number)) == 0) {
125125
continue;
126126
}
@@ -161,10 +161,14 @@ STATIC uint32_t _check_pins_free(const mcu_pin_obj_t *first_pin, uint8_t pin_cou
161161
if (first_pin != NULL) {
162162
for (size_t i = 0; i < pin_count; i++) {
163163
uint8_t pin_number = first_pin->number + i;
164-
if (pin_number >= TOTAL_GPIO_COUNT) {
164+
if (pin_number >= NUM_BANK0_GPIOS) {
165165
mp_raise_ValueError(translate("Pin count too large"));
166166
}
167-
const mcu_pin_obj_t *pin = mcu_pin_global_dict_table[pin_number].value;
167+
const mcu_pin_obj_t *pin = mcu_get_pin_by_number(pin_number);
168+
if (!pin) {
169+
mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_Pin);
170+
}
171+
168172
if (exclusive_pin_use || _pin_reference_count[pin_number] == 0) {
169173
assert_pin_free(pin);
170174
}
@@ -269,12 +273,15 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
269273
self->pull_pin_up = pull_pin_up;
270274
self->pull_pin_down = pull_pin_down;
271275

272-
for (size_t pin_number = 0; pin_number < TOTAL_GPIO_COUNT; pin_number++) {
276+
for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) {
273277
if ((pins_we_use & (1 << pin_number)) == 0) {
274278
continue;
275279
}
280+
const mcu_pin_obj_t *pin = mcu_get_pin_by_number(pin_number);
281+
if (!pin) {
282+
return false;
283+
}
276284
_pin_reference_count[pin_number]++;
277-
const mcu_pin_obj_t *pin = mcu_pin_global_dict_table[pin_number].value;
278285
// Also claim the pin at the top level when we're the first to grab it.
279286
if (_pin_reference_count[pin_number] == 1) {
280287
if (claim_pins) {

0 commit comments

Comments
 (0)