Add buttons support to iMXRT1060

This commit is contained in:
Dave Marples 2020-07-14 18:37:34 -03:00 committed by Abdelatif Guettouche
parent 6f6d61eec4
commit bc95500bab
6 changed files with 108 additions and 32 deletions

View File

@ -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 */

View File

@ -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

View File

@ -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)
{

View File

@ -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:

View File

@ -49,6 +49,7 @@
#include <nuttx/video/fb.h>
#include <imxrt_lpi2c.h>
#include <imxrt_lpspi.h>
#include <nuttx/input/buttons.h>
#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 */

View File

@ -4,6 +4,7 @@
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
* David Sidrane <david_s5@nscdg.com>
* Dave Marples <dave@marples.net>
*
* 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