rp2/machine_pin: Fix simulated open drain with more than 32 GPIOs.

Changes are:
- Refactor the open-drain macros, add GPIO_ENABLE/DISABLE_OPEN_DRAIN, and
  move them to `mphalport.h`.
- Only use `uint64_t` for the open-drain mask if there are more than 32
  GPIOs (saves code size).
- Ensure we're shifting a `uint64_t` by using 1ULL constants.

Signed-off-by: Phil Howard <github@gadgetoid.com>
This commit is contained in:
Phil Howard
2025-05-12 11:08:54 +01:00
committed by Damien George
parent 28c8fff6d8
commit 45cb9b4444
2 changed files with 19 additions and 7 deletions

View File

@@ -46,9 +46,6 @@
#define GPIO_IRQ_ALL (0xf)
// Open drain behaviour is simulated.
#define GPIO_IS_OPEN_DRAIN(id) (machine_pin_open_drain_mask & (1 << (id)))
#ifndef MICROPY_HW_PIN_RESERVED
#define MICROPY_HW_PIN_RESERVED(i) (0)
#endif
@@ -83,7 +80,11 @@ static const mp_irq_methods_t machine_pin_irq_methods;
static const int num_intr_regs = sizeof(iobank0_hw->intr) / sizeof(iobank0_hw->intr[0]);
// Mask with "1" indicating that the corresponding pin is in simulated open-drain mode.
#if NUM_BANK0_GPIOS > 32
uint64_t machine_pin_open_drain_mask;
#else
uint32_t machine_pin_open_drain_mask;
#endif
#if MICROPY_HW_PIN_EXT_COUNT
static inline bool is_ext_pin(__unused const machine_pin_obj_t *self) {
@@ -292,7 +293,7 @@ static mp_obj_t machine_pin_obj_init_helper(const machine_pin_obj_t *self, size_
mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("invalid pin af: %d"), af);
}
gpio_set_function(self->id, af);
machine_pin_open_drain_mask &= ~(1ULL << self->id);
GPIO_DISABLE_OPEN_DRAIN(self->id);
}
}

View File

@@ -123,7 +123,18 @@ static inline mp_uint_t mp_hal_get_cpu_freq(void) {
#define MP_HAL_PIN_PULL_UP (1)
#define MP_HAL_PIN_PULL_DOWN (2)
// Open drain behaviour is simulated.
#if NUM_BANK0_GPIOS > 32
extern uint64_t machine_pin_open_drain_mask;
#define GPIO_IS_OPEN_DRAIN(id) (machine_pin_open_drain_mask & (1ULL << id))
#define GPIO_ENABLE_OPEN_DRAIN(id) (machine_pin_open_drain_mask |= (1ULL << id))
#define GPIO_DISABLE_OPEN_DRAIN(id) (machine_pin_open_drain_mask &= ~(1ULL << id))
#else
extern uint32_t machine_pin_open_drain_mask;
#define GPIO_IS_OPEN_DRAIN(id) (machine_pin_open_drain_mask & (1U << id))
#define GPIO_ENABLE_OPEN_DRAIN(id) (machine_pin_open_drain_mask |= (1U << id))
#define GPIO_DISABLE_OPEN_DRAIN(id) (machine_pin_open_drain_mask &= ~(1U << id))
#endif
mp_hal_pin_obj_t mp_hal_get_pin_obj(mp_obj_t pin_in);
@@ -133,13 +144,13 @@ static inline unsigned int mp_hal_pin_name(mp_hal_pin_obj_t pin) {
static inline void mp_hal_pin_input(mp_hal_pin_obj_t pin) {
gpio_set_dir(pin, GPIO_IN);
machine_pin_open_drain_mask &= ~(1 << pin);
GPIO_DISABLE_OPEN_DRAIN(pin);
gpio_set_function(pin, GPIO_FUNC_SIO);
}
static inline void mp_hal_pin_output(mp_hal_pin_obj_t pin) {
gpio_set_dir(pin, GPIO_OUT);
machine_pin_open_drain_mask &= ~(1 << pin);
GPIO_DISABLE_OPEN_DRAIN(pin);
gpio_set_function(pin, GPIO_FUNC_SIO);
}
@@ -151,7 +162,7 @@ static inline void mp_hal_pin_open_drain_with_value(mp_hal_pin_obj_t pin, int v)
gpio_put(pin, 0);
gpio_set_dir(pin, GPIO_OUT);
}
machine_pin_open_drain_mask |= 1 << pin;
GPIO_ENABLE_OPEN_DRAIN(pin);
gpio_set_function(pin, GPIO_FUNC_SIO);
}