From f9e37cf73f95c0a1f66fb5aec1dc14b2719d0535 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Tue, 17 Sep 2019 17:55:33 -0500 Subject: [PATCH 1/3] gpio: Update mcux igpio driver to use new gpio api Updates the mcux igpio driver and all associated boards to use new device tree compatible gpio configuration flags. Implements new port get/set/clear/toggle and pin_interrupt_configure functions recently added to the gpio api. Assumes the gpio api layer handles translating logical flags to physical flags. Removes port configuration support since that feature is deprecated in the new gpio api. Tested with: - samples/basic/blinky - samples/basic/button - tests/drivers/gpio/gpio_api_1pin On boards: - mimxrt1015_evk - mimxrt1020_evk - mimxrt1050_evk - mimxrt1060_evk - mimxrt1064_evk Signed-off-by: Maureen Helm --- boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts | 4 +- boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts | 4 +- boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts | 4 +- boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts | 4 +- boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts | 4 +- drivers/gpio/gpio_mcux_igpio.c | 174 ++++++++++++++----- 6 files changed, 139 insertions(+), 55 deletions(-) diff --git a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts index 8f6262e5d52f6..492ee1b2353d6 100644 --- a/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts +++ b/boards/arm/mimxrt1015_evk/mimxrt1015_evk.dts @@ -33,7 +33,7 @@ leds { compatible = "gpio-leds"; green_led: led-1 { - gpios = <&gpio3 21 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio3 21 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -42,7 +42,7 @@ compatible = "gpio-keys"; user_button: button-1 { label = "User SW4"; - gpios = <&gpio2 9 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio2 9 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts index bb46a60de7fce..f1988c4829f16 100644 --- a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts +++ b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts @@ -41,7 +41,7 @@ leds { compatible = "gpio-leds"; green_led: led-1 { - gpios = <&gpio1 5 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 5 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -50,7 +50,7 @@ compatible = "gpio-keys"; user_button: button-1 { label = "User SW8"; - gpios = <&gpio5 0 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts index 68b47eb462c7c..8c746f700dbbe 100644 --- a/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts +++ b/boards/arm/mimxrt1050_evk/mimxrt1050_evk.dts @@ -42,7 +42,7 @@ leds { compatible = "gpio-leds"; green_led: led_0 { - gpios = <&gpio1 9 0>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -51,7 +51,7 @@ compatible = "gpio-keys"; user_button: button_0 { label = "User SW8"; - gpios = <&gpio5 0 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; }; }; diff --git a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts index 087953e2639a7..794691c8a392a 100644 --- a/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts +++ b/boards/arm/mimxrt1060_evk/mimxrt1060_evk.dts @@ -39,7 +39,7 @@ leds { compatible = "gpio-leds"; green_led: led-1 { - gpios = <&gpio1 9 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -48,7 +48,7 @@ compatible = "gpio-keys"; user_button: button-1 { label = "User SW8"; - gpios = <&gpio5 0 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; }; }; diff --git a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts index 783df94e9f95d..351c57dd15806 100644 --- a/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts +++ b/boards/arm/mimxrt1064_evk/mimxrt1064_evk.dts @@ -40,7 +40,7 @@ leds { compatible = "gpio-leds"; green_led: led-1 { - gpios = <&gpio1 9 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; label = "User LD1"; }; }; @@ -57,7 +57,7 @@ compatible = "gpio-keys"; user_button: button-1 { label = "User SW8"; - gpios = <&gpio5 0 GPIO_INT_ACTIVE_LOW>; + gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; }; }; diff --git a/drivers/gpio/gpio_mcux_igpio.c b/drivers/gpio/gpio_mcux_igpio.c index 9e7e78033e657..54f9eade95e32 100644 --- a/drivers/gpio/gpio_mcux_igpio.c +++ b/drivers/gpio/gpio_mcux_igpio.c @@ -18,6 +18,8 @@ struct mcux_igpio_config { }; struct mcux_igpio_data { + /* gpio_driver_data needs to be first */ + struct gpio_driver_data general; /* port ISR callback routine address */ sys_slist_t callbacks; /* pin callback routine enable flags, by pin number */ @@ -28,49 +30,34 @@ static int mcux_igpio_configure(struct device *dev, int access_op, u32_t pin, int flags) { const struct mcux_igpio_config *config = dev->config->config_info; - gpio_pin_config_t pin_config; - u32_t i; + GPIO_Type *base = config->base; - /* Check for an invalid pin configuration */ - if ((flags & GPIO_INT) && (flags & GPIO_DIR_OUT)) { - return -EINVAL; + if (((flags & GPIO_INPUT) != 0) && ((flags & GPIO_OUTPUT) != 0)) { + return -ENOTSUP; } - pin_config.direction = ((flags & GPIO_DIR_MASK) == GPIO_DIR_IN) - ? kGPIO_DigitalInput : kGPIO_DigitalOutput; - - pin_config.outputLogic = 0; - - if (flags & GPIO_INT) { - if (flags & GPIO_INT_EDGE) { - if (flags & GPIO_INT_ACTIVE_HIGH) { - pin_config.interruptMode = kGPIO_IntRisingEdge; - } else if (flags & GPIO_INT_DOUBLE_EDGE) { - pin_config.interruptMode = - kGPIO_IntRisingOrFallingEdge; - } else { - pin_config.interruptMode = - kGPIO_IntFallingEdge; - } - } else { /* GPIO_INT_LEVEL */ - if (flags & GPIO_INT_ACTIVE_HIGH) { - pin_config.interruptMode = kGPIO_IntHighLevel; - } else { - pin_config.interruptMode = kGPIO_IntLowLevel; - } - } - } else { - pin_config.interruptMode = kGPIO_NoIntmode; + if ((flags & GPIO_SINGLE_ENDED) != 0) { + return -ENOTSUP; } - if (access_op == GPIO_ACCESS_BY_PIN) { - GPIO_PinInit(config->base, pin, &pin_config); - } else { /* GPIO_ACCESS_BY_PORT */ - for (i = 0U; i < 32; i++) { - GPIO_PinInit(config->base, i, &pin_config); - } + if (((flags & GPIO_PULL_UP) != 0) || ((flags & GPIO_PULL_DOWN) != 0)) { + return -ENOTSUP; + } + + if (access_op == GPIO_ACCESS_BY_PORT) { + return -ENOTSUP; + } + + if (flags & GPIO_OUTPUT_INIT_HIGH) { + base->DR_SET = BIT(pin); + } + + if (flags & GPIO_OUTPUT_INIT_LOW) { + base->DR_CLEAR = BIT(pin); } + WRITE_BIT(base->GDIR, pin, flags & GPIO_OUTPUT); + return 0; } @@ -102,6 +89,103 @@ static int mcux_igpio_read(struct device *dev, return 0; } +static int mcux_igpio_port_get_raw(struct device *dev, u32_t *value) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + *value = base->DR; + + return 0; +} + +static int mcux_igpio_port_set_masked_raw(struct device *dev, u32_t mask, + u32_t value) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + base->DR = (base->DR & ~mask) | (mask & value); + + return 0; +} + +static int mcux_igpio_port_set_bits_raw(struct device *dev, u32_t mask) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + base->DR_SET = mask; + + return 0; +} + +static int mcux_igpio_port_clear_bits_raw(struct device *dev, u32_t mask) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + base->DR_CLEAR = mask; + + return 0; +} + +static int mcux_igpio_port_toggle_bits(struct device *dev, u32_t mask) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + GPIO_Type *base = config->base; + + base->DR_TOGGLE = mask; + + return 0; +} + +static int mcux_igpio_pin_interrupt_configure(struct device *dev, + unsigned int pin, enum gpio_int_mode mode, + enum gpio_int_trig trig) +{ + const struct mcux_igpio_config *config = dev->config->config_info; + struct mcux_igpio_data *data = dev->driver_data; + GPIO_Type *base = config->base; + unsigned int key; + u8_t icr; + int shift; + + if ((mode == GPIO_INT_MODE_EDGE) && (trig == GPIO_INT_TRIG_LOW)) { + icr = 3; + } else if ((mode == GPIO_INT_MODE_EDGE) && + (trig == GPIO_INT_TRIG_HIGH)) { + icr = 2; + } else if ((mode == GPIO_INT_MODE_LEVEL) && + (trig == GPIO_INT_TRIG_HIGH)) { + icr = 1; + } else { + icr = 0; + } + + if (pin < 16) { + shift = 2 * pin; + base->ICR1 = (base->ICR1 & ~(3 << shift)) | (icr << shift); + } else if (pin < 32) { + shift = 2 * (pin - 16); + base->ICR2 = (base->ICR2 & ~(3 << shift)) | (icr << shift); + } else { + return -EINVAL; + } + + key = irq_lock(); + + WRITE_BIT(base->EDGE_SEL, pin, trig == GPIO_INT_TRIG_BOTH); + WRITE_BIT(base->ISR, pin, mode != GPIO_INT_MODE_DISABLED); + WRITE_BIT(base->IMR, pin, mode != GPIO_INT_MODE_DISABLED); + WRITE_BIT(data->pin_callback_enables, pin, + mode != GPIO_INT_MODE_DISABLED); + + irq_unlock(key); + + return 0; +} + static int mcux_igpio_manage_callback(struct device *dev, struct gpio_callback *callback, bool set) { @@ -113,15 +197,12 @@ static int mcux_igpio_manage_callback(struct device *dev, static int mcux_igpio_enable_callback(struct device *dev, int access_op, u32_t pin) { - const struct mcux_igpio_config *config = dev->config->config_info; struct mcux_igpio_data *data = dev->driver_data; if (access_op == GPIO_ACCESS_BY_PIN) { data->pin_callback_enables |= BIT(pin); - GPIO_PortEnableInterrupts(config->base, BIT(pin)); } else { data->pin_callback_enables = 0xFFFFFFFF; - GPIO_PortEnableInterrupts(config->base, 0xFFFFFFFF); } return 0; @@ -130,14 +211,11 @@ static int mcux_igpio_enable_callback(struct device *dev, static int mcux_igpio_disable_callback(struct device *dev, int access_op, u32_t pin) { - const struct mcux_igpio_config *config = dev->config->config_info; struct mcux_igpio_data *data = dev->driver_data; if (access_op == GPIO_ACCESS_BY_PIN) { - GPIO_PortDisableInterrupts(config->base, BIT(pin)); data->pin_callback_enables &= ~BIT(pin); } else { - GPIO_PortDisableInterrupts(config->base, 0); data->pin_callback_enables = 0U; } @@ -149,20 +227,26 @@ static void mcux_igpio_port_isr(void *arg) struct device *dev = (struct device *)arg; const struct mcux_igpio_config *config = dev->config->config_info; struct mcux_igpio_data *data = dev->driver_data; + GPIO_Type *base = config->base; u32_t enabled_int, int_flags; - int_flags = GPIO_PortGetInterruptFlags(config->base); + int_flags = base->ISR; enabled_int = int_flags & data->pin_callback_enables; + base->ISR = enabled_int; gpio_fire_callbacks(&data->callbacks, dev, enabled_int); - - GPIO_ClearPinsInterruptFlags(config->base, enabled_int); } static const struct gpio_driver_api mcux_igpio_driver_api = { .config = mcux_igpio_configure, .write = mcux_igpio_write, .read = mcux_igpio_read, + .port_get_raw = mcux_igpio_port_get_raw, + .port_set_masked_raw = mcux_igpio_port_set_masked_raw, + .port_set_bits_raw = mcux_igpio_port_set_bits_raw, + .port_clear_bits_raw = mcux_igpio_port_clear_bits_raw, + .port_toggle_bits = mcux_igpio_port_toggle_bits, + .pin_interrupt_configure = mcux_igpio_pin_interrupt_configure, .manage_callback = mcux_igpio_manage_callback, .enable_callback = mcux_igpio_enable_callback, .disable_callback = mcux_igpio_disable_callback, From 7b8e5492a19cd5de96afa552248ef433062d2929 Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Wed, 18 Sep 2019 07:52:06 -0500 Subject: [PATCH 2/3] boards: mimxrt1020_evk: Fix button label to match silkscreen Fixes the user button label in the device tree to match the board's silkscreen. Signed-off-by: Maureen Helm --- boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts index f1988c4829f16..73774e22c2118 100644 --- a/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts +++ b/boards/arm/mimxrt1020_evk/mimxrt1020_evk.dts @@ -49,7 +49,7 @@ gpio_keys { compatible = "gpio-keys"; user_button: button-1 { - label = "User SW8"; + label = "User SW4"; gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; }; }; From 16396f74200f9941ede75e4c1a76c5a5f2a10b0e Mon Sep 17 00:00:00 2001 From: Maureen Helm Date: Thu, 3 Oct 2019 20:10:44 -0500 Subject: [PATCH 3/3] tests: gpio: Enable gpio_basic_api test on mimxrt1050_evk Enables the 2-pin gpio test on the mimxrt1050_evk board by adding a dts overlay and configuring pinmuxes on the arduino header. Signed-off-by: Maureen Helm --- .../boards/mimxrt1050_evk.overlay | 13 ++++++++++++ tests/drivers/gpio/gpio_basic_api/src/main.c | 20 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/drivers/gpio/gpio_basic_api/boards/mimxrt1050_evk.overlay diff --git a/tests/drivers/gpio/gpio_basic_api/boards/mimxrt1050_evk.overlay b/tests/drivers/gpio/gpio_basic_api/boards/mimxrt1050_evk.overlay new file mode 100644 index 0000000000000..5a8cb1b7c8e89 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/mimxrt1050_evk.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2019 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test,gpio_basic_api"; + out-gpios = <&gpio1 23 0>; /* Arduino D0 */ + in-gpios = <&gpio1 22 0>; /* Arduino D1 */ + }; +}; diff --git a/tests/drivers/gpio/gpio_basic_api/src/main.c b/tests/drivers/gpio/gpio_basic_api/src/main.c index 8930f5a3b531f..54776418e2c1a 100644 --- a/tests/drivers/gpio/gpio_basic_api/src/main.c +++ b/tests/drivers/gpio/gpio_basic_api/src/main.c @@ -13,6 +13,10 @@ #include #endif +#ifdef CONFIG_BOARD_MIMXRT1050_EVK +#include +#endif + static void board_setup(void) { #ifdef DT_INST_0_TEST_GPIO_BASIC_API @@ -34,6 +38,22 @@ static void board_setup(void) pinmux_pin_set(pmx, PIN_OUT, PORT_PCR_MUX(kPORT_MuxAsGpio)); pinmux_pin_set(pmx, PIN_IN, PORT_PCR_MUX(kPORT_MuxAsGpio)); #endif + +#ifdef CONFIG_BOARD_MIMXRT1050_EVK + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_06_GPIO1_IO22, 0); + IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B1_07_GPIO1_IO23, 0); + + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_06_GPIO1_IO22, + IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | + IOMUXC_SW_PAD_CTL_PAD_HYS_MASK | + IOMUXC_SW_PAD_CTL_PAD_SPEED(2) | + IOMUXC_SW_PAD_CTL_PAD_DSE(6)); + + IOMUXC_SetPinConfig(IOMUXC_GPIO_AD_B1_07_GPIO1_IO23, + IOMUXC_SW_PAD_CTL_PAD_PKE_MASK | + IOMUXC_SW_PAD_CTL_PAD_SPEED(2) | + IOMUXC_SW_PAD_CTL_PAD_DSE(6)); +#endif } void test_main(void)