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
This commit is contained in:
parent
31d7c91c85
commit
576a1ac700
@ -111,7 +111,7 @@ void alarm_pin_pinalarm_reset(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reset pins and pin IRQs
|
// Reset pins and pin IRQs
|
||||||
for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) {
|
for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) {
|
||||||
if (alarm_reserved_pins & (1 << i)) {
|
if (alarm_reserved_pins & (1 << i)) {
|
||||||
gpio_set_irq_enabled(i, GPIO_IRQ_ALL_EVENTS, false);
|
gpio_set_irq_enabled(i, GPIO_IRQ_ALL_EVENTS, false);
|
||||||
reset_pin_number(i);
|
reset_pin_number(i);
|
||||||
|
@ -46,7 +46,7 @@ void reset_pin_number_cyw(uint8_t pin_no) {
|
|||||||
STATIC uint32_t never_reset_pins;
|
STATIC uint32_t never_reset_pins;
|
||||||
|
|
||||||
void reset_all_pins(void) {
|
void reset_all_pins(void) {
|
||||||
for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) {
|
for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) {
|
||||||
if ((never_reset_pins & (1 << i)) != 0) {
|
if ((never_reset_pins & (1 << i)) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -54,16 +54,17 @@ void reset_all_pins(void) {
|
|||||||
}
|
}
|
||||||
#if CIRCUITPY_CYW43
|
#if CIRCUITPY_CYW43
|
||||||
if (cyw_ever_init) {
|
if (cyw_ever_init) {
|
||||||
for (size_t i = 0; i < 1; i++) {
|
// reset LED and SMPS_MODE to Low; don't touch VBUS_SENSE
|
||||||
cyw43_arch_gpio_put(i, 0);
|
// otherwise it is switched to output mode forever!
|
||||||
}
|
cyw43_arch_gpio_put(0, 0);
|
||||||
|
cyw43_arch_gpio_put(1, 0);
|
||||||
}
|
}
|
||||||
cyw_pin_claimed = 0;
|
cyw_pin_claimed = 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void never_reset_pin_number(uint8_t pin_number) {
|
void never_reset_pin_number(uint8_t pin_number) {
|
||||||
if (pin_number >= TOTAL_GPIO_COUNT) {
|
if (pin_number >= NUM_BANK0_GPIOS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ void never_reset_pin_number(uint8_t pin_number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void reset_pin_number(uint8_t pin_number) {
|
void reset_pin_number(uint8_t pin_number) {
|
||||||
if (pin_number >= TOTAL_GPIO_COUNT) {
|
if (pin_number >= NUM_BANK0_GPIOS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ void claim_pin(const mcu_pin_obj_t *pin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool pin_number_is_free(uint8_t pin_number) {
|
bool pin_number_is_free(uint8_t pin_number) {
|
||||||
if (pin_number >= TOTAL_GPIO_COUNT) {
|
if (pin_number >= NUM_BANK0_GPIOS) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ watchdog_watchdogtimer_obj_t common_hal_mcu_watchdogtimer_obj = {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This maps MCU pin names to pin objects.
|
// This maps MCU pin names to pin objects.
|
||||||
const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT] = {
|
const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) },
|
{ MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO1) },
|
{ MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO1) },
|
||||||
{ MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) },
|
{ 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] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table);
|
MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table);
|
||||||
|
|
||||||
|
const mcu_pin_obj_t *mcu_get_pin_by_number(int number) {
|
||||||
|
for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_pin_global_dict_table); i++) {
|
||||||
|
mcu_pin_obj_t *obj = MP_OBJ_TO_PTR(mcu_pin_global_dict_table[i].value);
|
||||||
|
if (obj->base.type == &mcu_pin_type && obj->number == number) {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -28,9 +28,8 @@
|
|||||||
#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H
|
#define MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H
|
||||||
|
|
||||||
#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h"
|
#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h"
|
||||||
|
#include "peripherals/pins.h"
|
||||||
|
|
||||||
#define TOTAL_GPIO_COUNT NUM_BANK0_GPIOS
|
const mcu_pin_obj_t *mcu_get_pin_by_number(int);
|
||||||
|
|
||||||
extern const mp_rom_map_elem_t mcu_pin_global_dict_table[TOTAL_GPIO_COUNT];
|
|
||||||
|
|
||||||
#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H
|
#endif // MICROPY_INCLUDED_RASPBERRYPI_COMMON_HAL_MICROCONTROLLER___INIT___H
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
#define NO_DMA_CHANNEL (-1)
|
#define NO_DMA_CHANNEL (-1)
|
||||||
|
|
||||||
// Count how many state machines are using each pin.
|
// Count how many state machines are using each pin.
|
||||||
STATIC uint8_t _pin_reference_count[TOTAL_GPIO_COUNT];
|
STATIC uint8_t _pin_reference_count[NUM_BANK0_GPIOS];
|
||||||
STATIC uint32_t _current_program_id[NUM_PIOS][NUM_PIO_STATE_MACHINES];
|
STATIC uint32_t _current_program_id[NUM_PIOS][NUM_PIO_STATE_MACHINES];
|
||||||
STATIC uint8_t _current_program_offset[NUM_PIOS][NUM_PIO_STATE_MACHINES];
|
STATIC uint8_t _current_program_offset[NUM_PIOS][NUM_PIO_STATE_MACHINES];
|
||||||
STATIC uint8_t _current_program_len[NUM_PIOS][NUM_PIO_STATE_MACHINES];
|
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];
|
|||||||
STATIC void rp2pio_statemachine_interrupt_handler(void);
|
STATIC void rp2pio_statemachine_interrupt_handler(void);
|
||||||
|
|
||||||
static void rp2pio_statemachine_set_pull(uint32_t pull_pin_up, uint32_t pull_pin_down, uint32_t pins_we_use) {
|
static void rp2pio_statemachine_set_pull(uint32_t pull_pin_up, uint32_t pull_pin_down, uint32_t pins_we_use) {
|
||||||
for (size_t i = 0; i < TOTAL_GPIO_COUNT; i++) {
|
for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) {
|
||||||
bool used = pins_we_use & (1 << i);
|
bool used = pins_we_use & (1 << i);
|
||||||
if (used) {
|
if (used) {
|
||||||
bool pull_up = pull_pin_up & (1 << i);
|
bool pull_up = pull_pin_up & (1 << i);
|
||||||
@ -120,7 +120,7 @@ STATIC void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pins = _current_sm_pins[pio_index][sm];
|
uint32_t pins = _current_sm_pins[pio_index][sm];
|
||||||
for (size_t pin_number = 0; pin_number < TOTAL_GPIO_COUNT; pin_number++) {
|
for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) {
|
||||||
if ((pins & (1 << pin_number)) == 0) {
|
if ((pins & (1 << pin_number)) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -161,10 +161,14 @@ STATIC uint32_t _check_pins_free(const mcu_pin_obj_t *first_pin, uint8_t pin_cou
|
|||||||
if (first_pin != NULL) {
|
if (first_pin != NULL) {
|
||||||
for (size_t i = 0; i < pin_count; i++) {
|
for (size_t i = 0; i < pin_count; i++) {
|
||||||
uint8_t pin_number = first_pin->number + i;
|
uint8_t pin_number = first_pin->number + i;
|
||||||
if (pin_number >= TOTAL_GPIO_COUNT) {
|
if (pin_number >= NUM_BANK0_GPIOS) {
|
||||||
mp_raise_ValueError(translate("Pin count too large"));
|
mp_raise_ValueError(translate("Pin count too large"));
|
||||||
}
|
}
|
||||||
const mcu_pin_obj_t *pin = mcu_pin_global_dict_table[pin_number].value;
|
const mcu_pin_obj_t *pin = mcu_get_pin_by_number(pin_number);
|
||||||
|
if (!pin) {
|
||||||
|
mp_raise_ValueError_varg(translate("%q in use"), MP_QSTR_Pin);
|
||||||
|
}
|
||||||
|
|
||||||
if (exclusive_pin_use || _pin_reference_count[pin_number] == 0) {
|
if (exclusive_pin_use || _pin_reference_count[pin_number] == 0) {
|
||||||
assert_pin_free(pin);
|
assert_pin_free(pin);
|
||||||
}
|
}
|
||||||
@ -269,12 +273,15 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self,
|
|||||||
self->pull_pin_up = pull_pin_up;
|
self->pull_pin_up = pull_pin_up;
|
||||||
self->pull_pin_down = pull_pin_down;
|
self->pull_pin_down = pull_pin_down;
|
||||||
|
|
||||||
for (size_t pin_number = 0; pin_number < TOTAL_GPIO_COUNT; pin_number++) {
|
for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) {
|
||||||
if ((pins_we_use & (1 << pin_number)) == 0) {
|
if ((pins_we_use & (1 << pin_number)) == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
const mcu_pin_obj_t *pin = mcu_get_pin_by_number(pin_number);
|
||||||
|
if (!pin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
_pin_reference_count[pin_number]++;
|
_pin_reference_count[pin_number]++;
|
||||||
const mcu_pin_obj_t *pin = mcu_pin_global_dict_table[pin_number].value;
|
|
||||||
// Also claim the pin at the top level when we're the first to grab it.
|
// Also claim the pin at the top level when we're the first to grab it.
|
||||||
if (_pin_reference_count[pin_number] == 1) {
|
if (_pin_reference_count[pin_number] == 1) {
|
||||||
if (claim_pins) {
|
if (claim_pins) {
|
||||||
|
Loading…
Reference in New Issue
Block a user