From bc95500babc5465a74689eb200c404cd4bb31fef Mon Sep 17 00:00:00 2001 From: Dave Marples Date: Tue, 14 Jul 2020 18:37:34 -0300 Subject: [PATCH] Add buttons support to iMXRT1060 --- arch/arm/src/imxrt/hardware/imxrt_gpio.h | 3 ++ arch/arm/src/imxrt/imxrt_gpio.h | 17 +++++-- arch/arm/src/imxrt/imxrt_gpioirq.c | 40 +++++++++++----- .../imxrt/imxrt1060-evk/src/imxrt1060-evk.h | 14 +++--- .../imxrt/imxrt1060-evk/src/imxrt_bringup.c | 18 +++++++ .../imxrt/imxrt1060-evk/src/imxrt_buttons.c | 48 +++++++++++++++---- 6 files changed, 108 insertions(+), 32 deletions(-) diff --git a/arch/arm/src/imxrt/hardware/imxrt_gpio.h b/arch/arm/src/imxrt/hardware/imxrt_gpio.h index fd87465085..2d63141592 100644 --- a/arch/arm/src/imxrt/hardware/imxrt_gpio.h +++ b/arch/arm/src/imxrt/hardware/imxrt_gpio.h @@ -90,4 +90,7 @@ #define GPIO_ICR_MASK(n) (3 << GPIO_ICR_SHIFT(n)) #define GPIO_ICR(i,n) ((uint32_t)(i) << GPIO_ICR_SHIFT(n)) +#define GPIO_EDGE_MASK(n) (1 << n) +#define GPIO_EDGE(i,n) ((uint32_t)(i) << n) + #endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_IMXRT_GPIO_H */ diff --git a/arch/arm/src/imxrt/imxrt_gpio.h b/arch/arm/src/imxrt/imxrt_gpio.h index 56c28e78e6..aad7e22dac 100644 --- a/arch/arm/src/imxrt/imxrt_gpio.h +++ b/arch/arm/src/imxrt/imxrt_gpio.h @@ -58,8 +58,8 @@ * 3322 2222 2222 1111 1111 1100 0000 0000 * 1098 7654 3210 9876 5432 1098 7654 3210 * ENCODING IIXX XXXX XXXX XXXX MMMM MMMM MMMM MMMM - * GPIO INPUT 00.. .EEG GGGP PPPP MMMM MMMM MMMM MMMM - * INT INPUT 11.. .EEG GGGP PPPP MMMM MMMM MMMM MMMM + * GPIO INPUT 00.. BEEG GGGP PPPP MMMM MMMM MMMM MMMM + * INT INPUT 11.. BEEG GGGP PPPP MMMM MMMM MMMM MMMM * GPIO OUTPUT 01V. ..SG GGGP PPPP MMMM MMMM MMMM MMMM * PERIPHERAL 10AA AAS. IIII IIII MMMM MMMM MMMM MMMM */ @@ -95,7 +95,7 @@ */ #define GPIO_PORT_SHIFT (21) /* Bits 21-23: GPIO port index */ -#define GPIO_PORT_MASK (15 << GPIO_PORT_SHIFT) +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) # define GPIO_PORT1 (GPIO1 << GPIO_PORT_SHIFT) /* GPIO1 */ # define GPIO_PORT2 (GPIO2 << GPIO_PORT_SHIFT) /* GPIO2 */ # define GPIO_PORT3 (GPIO3 << GPIO_PORT_SHIFT) /* GPIO3 */ @@ -195,6 +195,17 @@ # define GPIO_INT_RISINGEDGE (GPIO_ICR_RISINGEDGE << GPIO_INTCFG_SHIFT) # define GPIO_INT_FALLINGEDGE (GPIO_ICR_FALLINGEDGE << GPIO_INTCFG_SHIFT) +/* Interrupt on both edges configuration + * + * 3322 2222 2222 1111 1111 1100 0000 0000 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * INT INPUT 11.. B... .... .... .... .... .... .... + */ + +#define GPIO_INTBOTHCFG_SHIFT (27) /* Bit 27: Interrupt both edges configuration */ +#define GPIO_INTBOTHCFG_MASK (1 << GPIO_INTBOTHCFG_SHIFT) +# define GPIO_INTBOTH_EDGES (1 << GPIO_INTBOTHCFG_SHIFT) + /* Pad Mux Register Index: * * 3322 2222 2222 1111 1111 1100 0000 0000 diff --git a/arch/arm/src/imxrt/imxrt_gpioirq.c b/arch/arm/src/imxrt/imxrt_gpioirq.c index 92d647bf4e..cca24f45c1 100644 --- a/arch/arm/src/imxrt/imxrt_gpioirq.c +++ b/arch/arm/src/imxrt/imxrt_gpioirq.c @@ -617,18 +617,21 @@ static int imxrt_gpio5_16_31_interrupt(int irq, FAR void *context, return OK; } + #endif + /**************************************************************************** * Public Functions ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** * Name: imxrt_gpioirq_initialize * * Description: - * Initialize logic to support a second level of interrupt decoding for GPIO pins. + * Initialize logic to support a second level of interrupt decoding for + * GPIO pins. * - ************************************************************************************/ + ****************************************************************************/ void imxrt_gpioirq_initialize(void) { @@ -695,7 +698,7 @@ void imxrt_gpioirq_initialize(void) #ifdef CONFIG_IMXRT_GPIO2_0_15_IRQ DEBUGVERIFY(irq_attach(IMXRT_IRQ_GPIO2_0_15, - imxrt_gpio2_0_15_interrupt,NULL)); + imxrt_gpio2_0_15_interrupt, NULL)); up_enable_irq(IMXRT_IRQ_GPIO2_0_15); #endif @@ -744,13 +747,13 @@ void imxrt_gpioirq_initialize(void) #endif } -/************************************************************************************ +/**************************************************************************** * Name: imxrt_gpioirq_configure * * Description: * Configure an interrupt for the specified GPIO pin. * - ************************************************************************************/ + ****************************************************************************/ int imxrt_gpioirq_configure(gpio_pinset_t pinset) { @@ -759,12 +762,15 @@ int imxrt_gpioirq_configure(gpio_pinset_t pinset) uintptr_t regaddr; uint32_t regval; uint32_t icr; + uint32_t bothedge; /* Decode information in the pin configuration */ - port = ((unsigned int)pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; - pin = ((unsigned int)pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; - icr = ((uint32_t)pinset & GPIO_INTCFG_MASK) >> GPIO_INTCFG_SHIFT; + port = ((unsigned int)pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + pin = ((unsigned int)pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + icr = ((uint32_t)pinset & GPIO_INTCFG_MASK) >> GPIO_INTCFG_SHIFT; + bothedge = ((uint32_t)pinset & GPIO_INTBOTHCFG_MASK) >> + GPIO_INTBOTHCFG_SHIFT; /* Set the right field in the right ICR register */ @@ -774,16 +780,24 @@ int imxrt_gpioirq_configure(gpio_pinset_t pinset) regval |= GPIO_ICR(icr, pin); putreg32(regval, regaddr); + /* Add any both-edge setup (overrides above see User Manual 12.5.9) */ + + regaddr = IMXRT_GPIO_EDGE(port); + regval = getreg32(regaddr); + regval &= ~GPIO_EDGE_MASK(pin); + regval |= GPIO_EDGE(bothedge, pin); + putreg32(regval, regaddr); + return OK; } -/************************************************************************************ +/**************************************************************************** * Name: imxrt_gpioirq_enable * * Description: * Enable the interrupt for specified GPIO IRQ * - ************************************************************************************/ + ****************************************************************************/ int imxrt_gpioirq_enable(int irq) { @@ -800,13 +814,13 @@ int imxrt_gpioirq_enable(int irq) return ret; } -/************************************************************************************ +/**************************************************************************** * Name: imxrt_gpioirq_disable * * Description: * Disable the interrupt for specified GPIO IRQ * - ************************************************************************************/ + ****************************************************************************/ int imxrt_gpioirq_disable(int irq) { diff --git a/boards/arm/imxrt/imxrt1060-evk/src/imxrt1060-evk.h b/boards/arm/imxrt/imxrt1060-evk/src/imxrt1060-evk.h index 87ddbb999b..eb6e011389 100644 --- a/boards/arm/imxrt/imxrt1060-evk/src/imxrt1060-evk.h +++ b/boards/arm/imxrt/imxrt1060-evk/src/imxrt1060-evk.h @@ -88,17 +88,19 @@ #define GPIO_LED (GPIO_OUTPUT | IOMUX_LED_DEFAULT | \ GPIO_OUTPUT_ZERO | GPIO_PORT1 | GPIO_PIN9) /* AD_BO_09 */ -/* Buttons ****************************************************************/ +/* Buttons ******************************************************************/ /* The IMXRT board has one external user button * * 1. SW8 (IRQ88) GPIO5-00 */ -#define GPIO_SW8 (GPIO_INTERRUPT | GPIO_INT_FALLINGEDGE | \ +#define GPIO_SW8 (GPIO_INTERRUPT | GPIO_INTBOTH_EDGES | \ IOMUX_SW_DEFAULT | \ GPIO_PORT5 | GPIO_PIN0) /* WAKEUP */ +#define GPIO_SW8_INT (_IMXRT_GPIO5_0_15_BASE+0) + /* LCD Backlight */ #define GPIO_LCD_BL (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | GPIO_PORT2 | \ @@ -177,7 +179,7 @@ #define GPIO_FT5X06_CTRSTn (GPIO_OUTPUT | GPIO_OUTPUT_ZERO | \ GPIO_PORT1 | GPIO_PIN2 | IOMUX_FT5X06_RST) /* AD_B0_02 */ -/* Test Pins **************************************************************/ +/* Test Pins ****************************************************************/ #define BOARD_NGPIOIN 0 /* Amount of GPIO Input pins */ #define BOARD_NGPIOOUT 4 /* Amount of GPIO Output pins */ @@ -209,10 +211,6 @@ #ifndef __ASSEMBLY__ -/**************************************************************************** - * Public Functions - ****************************************************************************/ - /**************************************************************************** * Name: imxrt_bringup * @@ -235,7 +233,7 @@ int imxrt_bringup(void); void imxrt_spidev_initialize(void); -/***************************************************************************** +/**************************************************************************** * Name: imxrt_mmcsd_spi_initialize * * Description: diff --git a/boards/arm/imxrt/imxrt1060-evk/src/imxrt_bringup.c b/boards/arm/imxrt/imxrt1060-evk/src/imxrt_bringup.c index ef413761aa..8584f9eef2 100644 --- a/boards/arm/imxrt/imxrt1060-evk/src/imxrt_bringup.c +++ b/boards/arm/imxrt/imxrt1060-evk/src/imxrt_bringup.c @@ -49,6 +49,7 @@ #include #include #include +#include #ifdef CONFIG_IMXRT_USDHC # include "imxrt_usdhc.h" @@ -238,6 +239,23 @@ int imxrt_bringup(void) imxrt_lcd_initialize(); #endif +#ifdef CONFIG_BUTTONS +#ifdef CONFIG_BUTTONS_LOWER + /* Register the BUTTON driver */ + + ret = btn_lower_initialize("/dev/buttons"); + if (ret != OK) + { + syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret); + return ret; + } +#else + /* Enable BUTTON support for some other purpose */ + + board_button_initialize(); +#endif /* CONFIG_BUTTONS_LOWER */ +#endif /* CONFIG_BUTTONS */ + #ifdef CONFIG_VIDEO_FB /* Initialize and register the framebuffer driver */ diff --git a/boards/arm/imxrt/imxrt1060-evk/src/imxrt_buttons.c b/boards/arm/imxrt/imxrt1060-evk/src/imxrt_buttons.c index 75e4f4cf24..ae38e0c059 100644 --- a/boards/arm/imxrt/imxrt1060-evk/src/imxrt_buttons.c +++ b/boards/arm/imxrt/imxrt1060-evk/src/imxrt_buttons.c @@ -4,6 +4,7 @@ * Copyright (C) 2018 Gregory Nutt. All rights reserved. * Authors: Gregory Nutt * David Sidrane + * Dave Marples * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -65,6 +66,15 @@ * 1. SW8 (IRQ88) GPIO5-00 */ +const uint32_t gpio_pins[NUM_BUTTONS] = + { + GPIO_SW8 + }; +const uint32_t gpio_pins_int[NUM_BUTTONS] = + { + GPIO_SW8_INT + }; + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -82,9 +92,15 @@ uint32_t board_button_initialize(void) { - /* Configure the button as input */ + uint32_t i; + + /* Configure the buttons as input */ + + for (i = 0; i < NUM_BUTTONS; i++) + { + imxrt_config_gpio(gpio_pins[i]); + } - imxrt_config_gpio(GPIO_SW8); return NUM_BUTTONS; } @@ -102,10 +118,11 @@ uint32_t board_button_initialize(void) uint8_t board_buttons(void) { uint8_t ret = 0; + uint8_t i = 0; - if (!imxrt_gpio_read(GPIO_SW8)) + for (i = 0; i < NUM_BUTTONS; i++) { - ret |= BUTTON_SW8_BIT; + ret |= ((!imxrt_gpio_read(gpio_pins[i])) << i); } return ret; @@ -124,7 +141,7 @@ uint8_t board_buttons(void) ****************************************************************************/ #ifdef CONFIG_ARCH_IRQBUTTONS -int board_button_irq(int id, xcpt_t irqhandler) +int board_button_irq(int id, xcpt_t irqhandler, FAR void *arg) { int ret = -EINVAL; @@ -134,11 +151,26 @@ int board_button_irq(int id, xcpt_t irqhandler) * Attach the new button handler. */ - ret = irq_attach(id, irqhandler, NULL); + if (id < NUM_BUTTONS) + { + uint32_t irqnum = gpio_pins_int[id]; + if (irqhandler) + { + ret = irq_attach(irqnum, irqhandler, arg); + imxrt_gpioirq_enable (irqnum); - /* Then make sure that interrupts are enabled on the pin */ + /* Then make sure that interrupts are enabled on the pin */ + + up_enable_irq(irqnum); + } + else + { + up_disable_irq(irqnum); + imxrt_gpioirq_disable(irqnum); + ret = OK; + } + } - up_enable_irq(id); return ret; } #endif