diff --git a/ports/mimxrt/machine_pin.c b/ports/mimxrt/machine_pin.c index c66718e976..5dfb2b72e2 100644 --- a/ports/mimxrt/machine_pin.c +++ b/ports/mimxrt/machine_pin.c @@ -187,6 +187,60 @@ void machine_pin_set_mode(const machine_pin_obj_t *self, uint8_t mode) { GPIO_PinInit(self->gpio, self->pin, &pin_config); } +void machine_pin_config(const machine_pin_obj_t *self, uint8_t mode, + uint8_t pull, uint8_t drive, uint8_t speed, uint8_t alt) { + (void)speed; + gpio_pin_config_t pin_config = {0}; + + if (IS_GPIO_IT_MODE(mode)) { + if (mode == PIN_MODE_IT_FALLING) { + pin_config.interruptMode = kGPIO_IntFallingEdge; + } else if (mode == PIN_MODE_IT_RISING) { + pin_config.interruptMode = kGPIO_IntRisingEdge; + } else if (mode == PIN_MODE_IT_BOTH) { + pin_config.interruptMode = kGPIO_IntRisingOrFallingEdge; + } + // Set pad config mode to input. + mode = PIN_MODE_IN; + } + + if (mode == PIN_MODE_IN) { + pin_config.direction = kGPIO_DigitalInput; + } else { + pin_config.direction = kGPIO_DigitalOutput; + } + + if (mode != PIN_MODE_ALT) { + // GPIO is always ALT5 + alt = PIN_AF_MODE_ALT5; + } + + const machine_pin_af_obj_t *af = pin_find_af(self, alt); + if (af == NULL) { + return; + } + + // Configure the pad. + uint32_t pad_config = pin_generate_config(pull, mode, drive, self->configRegister); + IOMUXC_SetPinMux(self->muxRegister, alt, af->input_register, af->input_daisy, self->configRegister, 0U); + IOMUXC_SetPinConfig(self->muxRegister, alt, af->input_register, af->input_daisy, self->configRegister, pad_config); + + // Initialize the pin. + GPIO_PinInit(self->gpio, self->pin, &pin_config); + + // Configure interrupt (if enabled). + if (pin_config.interruptMode != kGPIO_NoIntmode) { + uint32_t gpio_nr = GPIO_get_instance(self->gpio); + uint32_t irq_num = self->pin < 16 ? GPIO_combined_low_irqs[gpio_nr] : GPIO_combined_high_irqs[gpio_nr]; + + GPIO_PortEnableInterrupts(self->gpio, 1U << self->pin); + GPIO_PortClearInterruptFlags(self->gpio, ~0); + + NVIC_SetPriority(irq_num, IRQ_PRI_EXTINT); + EnableIRQ(irq_num); + } +} + STATIC mp_obj_t machine_pin_obj_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 1, false); machine_pin_obj_t *self = self_in; diff --git a/ports/mimxrt/mphalport.h b/ports/mimxrt/mphalport.h index ba7e1cfa94..1813a9834b 100644 --- a/ports/mimxrt/mphalport.h +++ b/ports/mimxrt/mphalport.h @@ -38,6 +38,25 @@ #define MICROPY_HW_USB_CDC_TX_TIMEOUT (500) #define MP_HAL_PIN_FMT "%q" +#define MP_HAL_PIN_MODE_INPUT PIN_MODE_IN +#define MP_HAL_PIN_MODE_OUTPUT PIN_MODE_OUT +#define MP_HAL_PIN_MODE_ALT PIN_MODE_ALT +#define MP_HAL_PIN_MODE_OPEN_DRAIN PIN_MODE_OPEN_DRAIN + +#define MP_HAL_PIN_PULL_NONE PIN_PULL_DISABLED +#define MP_HAL_PIN_PULL_UP PIN_PULL_UP_100K +#define MP_HAL_PIN_PULL_DOWN PIN_PULL_DOWN_100K + +#define MP_HAL_PIN_SPEED_LOW (0) +#define MP_HAL_PIN_SPEED_MEDIUM (1) +#define MP_HAL_PIN_SPEED_HIGH (2) +#define MP_HAL_PIN_SPEED_VERY_HIGH (3) + +#define MP_HAL_PIN_TRIGGER_NONE kGPIO_NoIntmode +#define MP_HAL_PIN_TRIGGER_FALL kGPIO_IntFallingEdge +#define MP_HAL_PIN_TRIGGER_RISE kGPIO_IntRisingEdge +#define MP_HAL_PIN_TRIGGER_RISE_FALL kGPIO_IntRisingOrFallingEdge + extern ringbuf_t stdin_ringbuf; // Define an alias for systick_ms, because the shared softtimer.c uses diff --git a/ports/mimxrt/pin.h b/ports/mimxrt/pin.h index 63db55f8a7..aa86f05e82 100644 --- a/ports/mimxrt/pin.h +++ b/ports/mimxrt/pin.h @@ -39,6 +39,10 @@ ((MODE) == PIN_MODE_OPEN_DRAIN) || \ ((MODE) == PIN_MODE_ALT)) +#define IS_GPIO_IT_MODE(MODE) (((MODE) == PIN_MODE_IT_RISING) || \ + ((MODE) == PIN_MODE_IT_FALLING) || \ + ((MODE) == PIN_MODE_IT_BOTH)) + #define IS_GPIO_DRIVE(DRIVE) (((DRIVE) == PIN_DRIVE_OFF) || \ ((DRIVE) == PIN_DRIVE_0) || \ ((DRIVE) == PIN_DRIVE_1) || \ @@ -56,6 +60,9 @@ enum { PIN_MODE_OPEN_DRAIN, PIN_MODE_ALT, PIN_MODE_SKIP, + PIN_MODE_IT_RISING, + PIN_MODE_IT_FALLING, + PIN_MODE_IT_BOTH, }; enum { @@ -161,6 +168,8 @@ const machine_pin_af_obj_t *pin_find_af(const machine_pin_obj_t *pin, uint8_t fn const machine_pin_af_obj_t *pin_find_af_by_index(const machine_pin_obj_t *pin, mp_uint_t af_idx); const machine_pin_af_obj_t *pin_find_af_by_name(const machine_pin_obj_t *pin, const char *name); void machine_pin_set_mode(const machine_pin_obj_t *pin, uint8_t mode); +void machine_pin_config(const machine_pin_obj_t *self, uint8_t mode, + uint8_t pull, uint8_t drive, uint8_t speed, uint8_t alt); uint32_t pin_generate_config(const uint32_t pull, const uint32_t mode, const uint32_t drive, uint32_t config_register); #endif // MICROPY_INCLUDED_MIMXRT_PIN_H