From f0b40ba96a9d62cdcb57e3f8fdda76d85f284efb Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 13 Oct 2015 07:08:11 -0600 Subject: [PATCH] Add a a generic lower half button driver --- ChangeLog | 7 +- drivers/input/Kconfig | 27 ++- drivers/input/Make.defs | 8 +- drivers/input/button_lower.c | 235 ++++++++++++++++++++ drivers/input/{buttons.c => button_upper.c} | 2 +- 5 files changed, 273 insertions(+), 6 deletions(-) create mode 100644 drivers/input/button_lower.c rename drivers/input/{buttons.c => button_upper.c} (99%) diff --git a/ChangeLog b/ChangeLog index 374e99b091..fb499c6313 100755 --- a/ChangeLog +++ b/ChangeLog @@ -11021,6 +11021,9 @@ (2015-10-9). * fs/tmpfs: TMPFS file system is code complete and bascially functional although it has not been heavilay tested (2015-10-9). - * drivers/input/buttons/c and include/nuttx/input/buttons.h: Add a + * drivers/input/button_upper.c and include/nuttx/input/buttons.h: Add a driver to support application access to board buttons (2015-10-12). - + * drivers/input/button_lower.c: Add a generic lower half button driver. + This lower half driver is only usable in a limited number of + situations, but can still serve as a module for the lower half button + driver. (2015-10-13). diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 480403a534..88d1e07ad3 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -325,12 +325,37 @@ endif # INPUT_STMPE811 config BUTTONS bool "Button Inputs" default n - depends on ARCH_BUTTONS ---help--- Enable standard button upper half driver. if BUTTONS +config BUTTONS_LOWER + bool "Generic Lower Half Button Dirver" + default n + depends on ARCH_BUTTONS && ARCH_IRQBUTTONS + ---help--- + If the board supports the standard button interfaces as + defined in include/nuttx/board.h header file, then this + standard button lower half driver might be usable. + + In order for this generic driver to be usable: + + 1. The board implementation must provide the button + interfaces as defined in include/nuttx/board.h + 2. The board implementation must support interrupts for each + button. + 3. The board.h header file must provide the definition + NUM_BUTTONS, and + 4. The board.h header file must not include any other + header files that are not accessibble in this context + (such as those in arch//src/). + + If your board does not meet these requirements, then the + board_lower.c file can still be copied to your your + board src/ directory and modified for your specific board + requirements. + config BUTTONS_NPOLLWAITERS int "Max Number of Poll Waiters" default 2 diff --git a/drivers/input/Make.defs b/drivers/input/Make.defs index 899f6cdacb..8285bfda0f 100644 --- a/drivers/input/Make.defs +++ b/drivers/input/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # drivers/input/Make.defs # -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2012, 2015 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -72,7 +72,11 @@ endif endif ifeq ($(CONFIG_BUTTONS),y) - CSRCS += buttons.c + CSRCS += button_upper.c +ifeq ($(CONFIG_BUTTONS_LOWER),y) + CSRCS += button_lower.c +endif + endif ifeq ($(CONFIG_DJOYSTICK),y) diff --git a/drivers/input/button_lower.c b/drivers/input/button_lower.c new file mode 100644 index 0000000000..dba0b94bfa --- /dev/null +++ b/drivers/input/button_lower.c @@ -0,0 +1,235 @@ +/**************************************************************************** + * drivers/input/button_lower.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#if CONFIG_BUTTONS_LOWER + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static btn_buttonset_t btn_supported(FAR const struct btn_lowerhalf_s *lower); +static btn_buttonset_t btn_buttons(FAR const struct btn_lowerhalf_s *lower); +static void btn_enable(FAR const struct btn_lowerhalf_s *lower, + btn_buttonset_t press, btn_buttonset_t release, + btn_handler_t handler, FAR void *arg); + +static void btn_disable(void); +static int btn_interrupt(int irq, FAR void *context); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* This is the button button lower half driver interface */ + +static const struct btn_lowerhalf_s g_btnlower = +{ + .bl_supported = btn_supported, + .bl_buttons = btn_buttons, + .bl_enable = btn_enable, +}; + +/* Current interrupt handler and argument */ + +static btn_handler_t g_btnhandler; +static FAR void *g_btnarg; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: btn_supported + * + * Description: + * Return the set of buttons supported + * + ****************************************************************************/ + +static btn_buttonset_t btn_supported(FAR const struct btn_lowerhalf_s *lower) +{ + ivdbg("NUM_BUTTONS: %02x\n", NUM_BUTTONS); + return (btn_buttonset_t)((1 << NUM_BUTTONS) - 1); +} + +/**************************************************************************** + * Name: btn_buttons + * + * Description: + * Return the current state of button data + * + ****************************************************************************/ + +static btn_buttonset_t btn_buttons(FAR const struct btn_lowerhalf_s *lower) +{ + return board_buttons(); +} + +/**************************************************************************** + * Name: btn_enable + * + * Description: + * Enable interrupts on the selected set of buttons. And empty set or + * a NULL handler will disable all interrupts. + * + ****************************************************************************/ + +static void btn_enable(FAR const struct btn_lowerhalf_s *lower, + btn_buttonset_t press, btn_buttonset_t release, + btn_handler_t handler, FAR void *arg) +{ + btn_buttonset_t mask; + btn_buttonset_t either = press | release; + irqstate_t flags; + int id; + + /* Start with all interrupts disabled */ + + flags = irqsave(); + btn_disable(); + + illvdbg("press: %02x release: %02x handler: %p arg: %p\n", + press, release, handler, arg); + + /* If no events are indicated or if no handler is provided, then this + * must really be a request to disable interrupts. + */ + + if (either && handler) + { + /* Save the new the handler and argument */ + + g_btnhandler = handler; + g_btnarg = arg; + + /* Attach and enable each button interrupt */ + + for (id = 0; id < NUM_BUTTONS; id++) + { + mask = (1 << id); + if ((either & mask) != 0) + { + (void)board_button_irq(id, btn_interrupt); + } + } + } + + irqrestore(flags); +} + +/**************************************************************************** + * Name: btn_disable + * + * Description: + * Disable all button interrupts + * + ****************************************************************************/ + +static void btn_disable(void) +{ + irqstate_t flags; + int id; + + /* Disable each button interrupt */ + + flags = irqsave(); + for (id = 0; id < NUM_BUTTONS; id++) + { + (void)board_button_irq(id, NULL); + } + + /* Nullify the handler and argument */ + + g_btnhandler = NULL; + g_btnarg = NULL; + irqrestore(flags); +} + +/**************************************************************************** + * Name: btn_interrupt + * + * Description: + * Discrete button interrupt handler (all buttons) + * + ****************************************************************************/ + +static int btn_interrupt(int irq, FAR void *context) +{ + DEBUGASSERT(g_btnhandler); + + if (g_btnhandler) + { + g_btnhandler(&g_btnlower, g_btnarg); + } + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: btn_lower_initialize + * + * Description: + * Initialize the generic button lower half driver, bind it and register + * it with the upper half button driver as devname. + * + ****************************************************************************/ + +int btn_lower_initialize(FAR const char *devname) +{ + board_button_initialize(); + return btn_register(devname, &g_btnlower); +} + +#endif /* CONFIG_BUTTONS_LOWER */ diff --git a/drivers/input/buttons.c b/drivers/input/button_upper.c similarity index 99% rename from drivers/input/buttons.c rename to drivers/input/button_upper.c index e185e83c58..deb9492fba 100644 --- a/drivers/input/buttons.c +++ b/drivers/input/button_upper.c @@ -1,5 +1,5 @@ /**************************************************************************** - * drivers/buttons.c + * drivers/button_upper.c * * Copyright (C) 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt