summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xapps/ChangeLog.txt1
-rw-r--r--apps/examples/README.txt20
-rw-r--r--apps/examples/buttons/main.c382
-rw-r--r--nuttx/ChangeLog6
-rw-r--r--nuttx/configs/stm3210e-eval/buttons/defconfig13
-rwxr-xr-xnuttx/configs/stm3210e-eval/src/stm3210e-internal.h2
-rw-r--r--nuttx/configs/stm3210e-eval/src/up_buttons.c16
-rw-r--r--nuttx/include/nuttx/arch.h6
8 files changed, 434 insertions, 12 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt
index aeb403fc0..dc95f2e29 100755
--- a/apps/ChangeLog.txt
+++ b/apps/ChangeLog.txt
@@ -65,3 +65,4 @@
* Make.defs, namedapp/namedapp.c: Several structural changes made to get a
clean compile under the ez80 ZDS-II toolchain (no design changes).
+ * apps/examples/buttons: Add a test for the new standardized button interfaces
diff --git a/apps/examples/README.txt b/apps/examples/README.txt
index bda96a20a..3feb38314 100644
--- a/apps/examples/README.txt
+++ b/apps/examples/README.txt
@@ -19,16 +19,28 @@ examples/buttons
specific button interfaces. Configuration options:
CONFIG_ARCH_BUTTONS - Must be defined for button support
- CONFIG_EXAMPLE_BUTTONS_MIN - Lowest button number
- CONFIG_EXAMPLE_BUTTONS_MAX - Highest button number
+ CONFIG_EXAMPLE_BUTTONS_MIN - Lowest button number (MIN=0)
+ CONFIG_EXAMPLE_BUTTONS_MAX - Highest button number (MAX=7)
CONFIG_ARCH_IRQBUTTONS - Must be defined for interrupting button support
- CONFIG_EXAMPLE_IRQBUTTONS_MIN - Lowest interrupting button number
- CONFIG_EXAMPLE_IRQBUTTONS_MAX - Highest interrupting button number
+ CONFIG_EXAMPLE_IRQBUTTONS_MIN - Lowest interrupting button number (MIN=0)
+ CONFIG_EXAMPLE_IRQBUTTONS_MAX - Highest interrupting button number (MAX=7)
+
+ Name strings for buttons:
+
+ CONFIG_EXAMPLE_BUTTONS_NAME0, CONFIG_EXAMPLE_BUTTONS_NAME1,
+ CONFIG_EXAMPLE_BUTTONS_NAME2, CONFIG_EXAMPLE_BUTTONS_NAME3,
+ CONFIG_EXAMPLE_BUTTONS_NAME4, CONFIG_EXAMPLE_BUTTONS_NAME5,
+ CONFIG_EXAMPLE_BUTTONS_NAME6, CONFIG_EXAMPLE_BUTTONS_NAME7,
Additional architecture-/board- specific configuration settings may also
be required.
+ NOTE: This test exercises internal button driver interfaces. As such, it
+ it relies on internal OS interfaces that are not normally available to a
+ user-space program. As a result, this example cannot be used if a
+ NuttX is built as a protected, supervisor kernel (CONFIG_NUTTX_KERNEL).
+
examples/dhcpd
^^^^^^^^^^^^^^
diff --git a/apps/examples/buttons/main.c b/apps/examples/buttons/main.c
index cd1e0cce8..43999bc1a 100644
--- a/apps/examples/buttons/main.c
+++ b/apps/examples/buttons/main.c
@@ -34,30 +34,412 @@
****************************************************************************/
/****************************************************************************
+ * NOTE: This test exercises internal button driver interfaces. As such, it
+ * it relies on internal OS interfaces that are not normally available to a
+ * user-space program. As a result, this example cannot be used if a
+ * NuttX is built as a protected, supervisor kernel (CONFIG_NUTTX_KERNEL).
+ ****************************************************************************/
+
+/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
#include <stdio.h>
+#include <unistd.h>
+#include <debug.h>
/****************************************************************************
* Definitions
****************************************************************************/
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_ARCH_BUTTONS
+# error "CONFIG_ARCH_BUTTONS is not defined in the configuration"
+#endif
+
+#ifndef CONFIG_EXAMPLE_BUTTONS_NAME0
+# define CONFIG_EXAMPLE_BUTTONS_NAME0 "BUTTON0"
+#endif
+#ifndef CONFIG_EXAMPLE_BUTTONS_NAME1
+# define CONFIG_EXAMPLE_BUTTONS_NAME1 "BUTTON1"
+#endif
+#ifndef CONFIG_EXAMPLE_BUTTONS_NAME2
+# define CONFIG_EXAMPLE_BUTTONS_NAME2 "BUTTON2"
+#endif
+#ifndef CONFIG_EXAMPLE_BUTTONS_NAME3
+# define CONFIG_EXAMPLE_BUTTONS_NAME3 "BUTTON3"
+#endif
+#ifndef CONFIG_EXAMPLE_BUTTONS_NAME4
+# define CONFIG_EXAMPLE_BUTTONS_NAME4 "BUTTON4"
+#endif
+#ifndef CONFIG_EXAMPLE_BUTTONS_NAME5
+# define CONFIG_EXAMPLE_BUTTONS_NAME5 "BUTTON5"
+#endif
+#ifndef CONFIG_EXAMPLE_BUTTONS_NAME6
+# define CONFIG_EXAMPLE_BUTTONS_NAME6 "BUTTON6"
+#endif
+#ifndef CONFIG_EXAMPLE_BUTTONS_NAME7
+# define CONFIG_EXAMPLE_BUTTONS_NAME7 "BUTTON7"
+#endif
+
+#define BUTTON_MIN 0
+#define BUTTON_MAX 7
+
+#ifndef CONFIG_EXAMPLE_BUTTONS_MIN
+# define CONFIG_EXAMPLE_BUTTONS_MIN BUTTON_MIN
+#endif
+#ifndef CONFIG_EXAMPLE_BUTTONS_MAX
+# define CONFIG_EXAMPLE_BUTTONS_MAX BUTTON_MAX
+#endif
+
+#if CONFIG_EXAMPLE_BUTTONS_MIN > CONFIG_EXAMPLE_BUTTONS_MAX
+# error "CONFIG_EXAMPLE_BUTTONS_MIN > CONFIG_EXAMPLE_BUTTONS_MAX"
+#endif
+#if CONFIG_EXAMPLE_BUTTONS_MAX > 7
+# error "CONFIG_EXAMPLE_BUTTONS_MAX > 7"
+#endif
+
+#ifndef CONFIG_EXAMPLE_IRQBUTTONS_MIN
+# define CONFIG_EXAMPLE_IRQBUTTONS_MIN CONFIG_EXAMPLE_BUTTONS_MIN
+#endif
+#ifndef CONFIG_EXAMPLE_IRQBUTTONS_MAX
+# define CONFIG_EXAMPLE_IRQBUTTONS_MAX CONFIG_EXAMPLE_BUTTONS_MAX
+#endif
+
+#if CONFIG_EXAMPLE_IRQBUTTONS_MIN > CONFIG_EXAMPLE_IRQBUTTONS_MAX
+# error "CONFIG_EXAMPLE_IRQBUTTONS_MIN > CONFIG_EXAMPLE_IRQBUTTONS_MAX"
+#endif
+#if CONFIG_EXAMPLE_IRQBUTTONS_MAX > 7
+# error "CONFIG_EXAMPLE_IRQBUTTONS_MAX > 7"
+#endif
+
+#ifndef MIN
+# define MIN(a,b) (a < b ? a : b)
+#endif
+#ifndef MAX
+# define MAX(a,b) (a > b ? a : b)
+#endif
+
+#define MIN_BUTTON MIN(CONFIG_EXAMPLE_BUTTONS_MIN, CONFIG_EXAMPLE_IRQBUTTONS_MIN)
+#define MAX_BUTTON MAX(CONFIG_EXAMPLE_BUTTONS_MAX, CONFIG_EXAMPLE_IRQBUTTONS_MAX)
+
+#define NUM_BUTTONS (MAX_BUTTON - MIN_BUTTON + 1)
+#define BUTTON_INDEX(b) ((b)-MIN_BUTTON)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct button_info_s
+{
+ FAR const char *name; /* Name for the button */
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ xcpt_t handler; /* Button interrupt handler */
+#endif
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void show_buttons(uint8_t oldset, uint8_t newset);
+
+#ifdef CONFIG_ARCH_IRQBUTTONS
+static void button_handler(int id, int irq);
+
+#if MIN_BUTTON < 1
+static int button0_handler(int irq, FAR void *context);
+#endif
+#if MIN_BUTTON < 2 && MAX_BUTTON > 0
+static int button1_handler(int irq, FAR void *context);
+#endif
+#if MIN_BUTTON < 3 && MAX_BUTTON > 1
+static int button2_handler(int irq, FAR void *context);
+#endif
+#if MIN_BUTTON < 4 && MAX_BUTTON > 2
+static int button3_handler(int irq, FAR void *context);
+#endif
+#if MIN_BUTTON < 5 && MAX_BUTTON > 3
+static int button4_handler(int irq, FAR void *context);
+#endif
+#if MIN_BUTTON < 6 && MAX_BUTTON > 4
+static int button5_handler(int irq, FAR void *context);
+#endif
+#if MIN_BUTTON < 7 && MAX_BUTTON > 5
+static int button6_handler(int irq, FAR void *context);
+#endif
+#if MAX_BUTTON > 6
+static int button7_handler(int irq, FAR void *context);
+#endif
+#endif /* CONFIG_ARCH_IRQBUTTONS */
/****************************************************************************
* Private Data
****************************************************************************/
+ /* Button Names */
+
+static const struct button_info_s g_buttoninfo[NUM_BUTTONS] =
+{
+#if MIN_BUTTON < 1
+ {
+ CONFIG_EXAMPLE_BUTTONS_NAME0,
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ button0_handler
+#endif
+ },
+#endif
+#if MIN_BUTTON < 2 && MAX_BUTTON > 0
+ {
+ CONFIG_EXAMPLE_BUTTONS_NAME1,
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ button1_handler
+#endif
+ },
+#endif
+#if MIN_BUTTON < 3 && MAX_BUTTON > 1
+ {
+ CONFIG_EXAMPLE_BUTTONS_NAME2,
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ button2_handler
+#endif
+ },
+#endif
+#if MIN_BUTTON < 4 && MAX_BUTTON > 2
+ {
+ CONFIG_EXAMPLE_BUTTONS_NAME3,
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ button3_handler
+#endif
+ },
+#endif
+#if MIN_BUTTON < 5 && MAX_BUTTON > 3
+ {
+ CONFIG_EXAMPLE_BUTTONS_NAME4,
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ button4_handler
+#endif
+ },
+#endif
+#if MIN_BUTTON < 6 && MAX_BUTTON > 4
+ {
+ CONFIG_EXAMPLE_BUTTONS_NAME5,
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ button5_handler
+#endif
+ },
+#endif
+#if MIN_BUTTON < 7 && MAX_BUTTON > 5
+ {
+ CONFIG_EXAMPLE_BUTTONS_NAME6,
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ button6_handler
+#endif
+ },
+#endif
+#if MAX_BUTTON > 6
+ {
+ CONFIG_EXAMPLE_BUTTONS_NAME7,
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ button7_handler
+#endif
+ }
+#endif
+};
+
+/* Last sampled button set */
+
+static uint8_t g_oldset;
+
/****************************************************************************
* Public Functions
****************************************************************************/
+static void show_buttons(uint8_t oldset, uint8_t newset)
+{
+ uint8_t chgset = oldset ^ newset;
+ int i;
+
+ for (i = MIN_BUTTON; i <= MAX_BUTTON; i++)
+ {
+ uint8_t mask = (1 << i);
+ if ((chgset & mask) != 0)
+ {
+ FAR const char *state;
+
+ /* Get the button state */
+
+ if ((newset & mask) != 0)
+ {
+ state = "depressed";
+ }
+ else
+ {
+ state = "released";
+ }
+
+ /* Use lib_lowprintf() because we make be executing from an
+ * interrupt handler.
+ */
+
+ lib_lowprintf(" %s %s\n", g_buttoninfo[BUTTON_INDEX(i)].name, state);
+ }
+ }
+}
+
+#ifdef CONFIG_ARCH_IRQBUTTONS
+static void button_handler(int id, int irq)
+{
+ uint8_t newset = up_buttons();
+
+ lib_lowprintf("IRQ:%d Button %d:%s IRQ:%d SET:%02x:\n",
+ irq, id, g_buttoninfo[BUTTON_INDEX(id)].name, newset);
+ show_buttons(g_oldset, newset);
+ g_oldset = newset;
+}
+
+#if MIN_BUTTON < 1
+static int button0_handler(int irq, FAR void *context)
+{
+ button_handler(0, irq);
+ return OK;
+}
+#endif
+
+#if MIN_BUTTON < 2 && MAX_BUTTON > 0
+static int button1_handler(int irq, FAR void *context)
+{
+ button_handler(1, irq);
+ return OK;
+}
+#endif
+
+#if MIN_BUTTON < 3 && MAX_BUTTON > 1
+static int button2_handler(int irq, FAR void *context)
+{
+ button_handler(2, irq);
+ return OK;
+}
+#endif
+
+#if MIN_BUTTON < 4 && MAX_BUTTON > 2
+static int button3_handler(int irq, FAR void *context)
+{
+ button_handler(3, irq);
+ return OK;
+}
+#endif
+
+#if MIN_BUTTON < 5 && MAX_BUTTON > 3
+static int button4_handler(int irq, FAR void *context)
+{
+ button_handler(4, irq);
+ return OK;
+}
+#endif
+
+#if MIN_BUTTON < 6 && MAX_BUTTON > 4
+static int button5_handler(int irq, FAR void *context)
+{
+ button_handler(5, irq);
+ return OK;
+}
+#endif
+
+#if MIN_BUTTON < 7 && MAX_BUTTON > 5
+static int button6_handler(int irq, FAR void *context)
+{
+ button_handler(6, irq);
+ return OK;
+}
+#endif
+
+#if MAX_BUTTON > 6
+static int button7_handler(int irq, FAR void *context)
+{
+ button_handler(7, irq);
+ return OK;
+}
+#endif
+#endif /* CONFIG_ARCH_IRQBUTTONS */
+
/****************************************************************************
* user_start
****************************************************************************/
int user_start(int argc, char *argv[])
{
+ uint8_t newset;
+ irqstate_t flags;
+ int i;
+
+ /* Register to recieve button interrupts */
+
+#ifdef CONFIG_ARCH_IRQBUTTONS
+ for (i = CONFIG_EXAMPLE_IRQBUTTONS_MIN; i <= CONFIG_EXAMPLE_IRQBUTTONS_MAX; i++)
+ {
+ xcpt_t oldhandler = up_irqbutton(i, g_buttoninfo[BUTTON_INDEX(i)].handler);
+
+ /* Use lib_lowprintf() for compatibility with interrrupt handler output. */
+
+ lib_lowprintf("Attached handler at %p to button %d [%s], oldhandler:%p\n",
+ g_buttoninfo[BUTTON_INDEX(i)].handler, i,
+ g_buttoninfo[BUTTON_INDEX(i)].name, oldhandler);
+
+ /* Some hardware multiplexes different GPIO button sources to the same
+ * physical interrupt. If we register multiple such multiplexed button
+ * interrupts, then the second registration will overwrite the first. In
+ * this case, the first button interrupts may be aliased to the second
+ * interrupt handler (or worse, could be lost).
+ */
+
+ if (oldhandler != NULL)
+ {
+ lib_lowprintf("WARNING: oldhandler:%p is not NULL! "
+ "Button events may be lost or aliased!\n",
+ oldhandler);
+ }
+ }
+#endif
+
+ /* Poll button state */
+
+ g_oldset = up_buttons();
+ for (;;)
+ {
+ /* Get the set of pressed and release buttons. */
+
+ newset = up_buttons();
+
+ /* Any changes from the last sample? */
+
+ if (newset != g_oldset)
+ {
+ /* Disable interrupts so that output here will not collide with
+ * output from an interrupt handler.
+ */
+
+ flags = irqsave();
+
+ /* Use lib_lowprintf() for compatibility with interrrupt handler
+ * output.
+ */
+
+ lib_lowprintf("POLL SET:%02x:\n", newset);
+ show_buttons(g_oldset, newset);
+ g_oldset = newset;
+ irqrestore(flags);
+ }
+
+ /* Sleep a little... but not long. This will determine how fast we
+ * poll for button changes.
+ */
+
+ usleep(150000); /* 150 Milliseconds */
+ }
return 0;
}
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog
index 362ff62e5..18afe10e8 100644
--- a/nuttx/ChangeLog
+++ b/nuttx/ChangeLog
@@ -1869,3 +1869,9 @@
are trying to using multiple UARTs on STM32.
* configs/stm3210e-eval/src/up_lcd.c: Add a driver for the STM3210E-EVAL's LCD.
* configs/stm3210e-eval/nx: Add NX configuration for the STM3210E-EVAL.
+ * configs/nuttx/arch.h (and arch/arm/src/stm32, configs/*/src/up_buttons.c):
+ Standardize interfaces exported for button support and button interrupts.
+ * configs/stm3210e-eval/src/up_buttons.c - Add interrupting button support.
+ Also fixes a few errors in STM3210E-EVAL button decoding.
+ * configs/stm3210e-eval/buttons: Add a configuration to exercise STM3210E-EVAL
+ buttons.
diff --git a/nuttx/configs/stm3210e-eval/buttons/defconfig b/nuttx/configs/stm3210e-eval/buttons/defconfig
index 4a072721a..ebe5d7d44 100644
--- a/nuttx/configs/stm3210e-eval/buttons/defconfig
+++ b/nuttx/configs/stm3210e-eval/buttons/defconfig
@@ -684,14 +684,23 @@ CONFIG_EXAMPLE_NETTEST_CLIENTIP=(10<<24|0<<16|0<<8|1)
# Settings for examples/buttons
#
# CONFIG_EXAMPLE_BUTTONS_MIN and CONFIG_EXAMPLE_BUTTONS_MAX
-# Lowest and highest button number
+# Lowest and highest button number (0-7)
# CONFIG_EXAMPLE_IRQBUTTONS_MIN and CONFIG_EXAMPLE_IRQBUTTONS_MAX
-# Lowest and highest interrupting button number
+# Lowest and highest interrupting button number (-7)
+# CONFIG_EXAMPLE_BUTTONS_NAMEn - Name for button n
#
CONFIG_EXAMPLE_BUTTONS_MIN=0
CONFIG_EXAMPLE_BUTTONS_MAX=7
CONFIG_EXAMPLE_IRQBUTTONS_MIN=2
CONFIG_EXAMPLE_IRQBUTTONS_MAX=7
+CONFIG_EXAMPLE_BUTTONS_NAME0="WAKEUP"
+CONFIG_EXAMPLE_BUTTONS_NAME1="TAMPER"
+CONFIG_EXAMPLE_BUTTONS_NAME2="KEY"
+CONFIG_EXAMPLE_BUTTONS_NAME3="SELECT"
+CONFIG_EXAMPLE_BUTTONS_NAME4="DOWN"
+CONFIG_EXAMPLE_BUTTONS_NAME5="LEFT"
+CONFIG_EXAMPLE_BUTTONS_NAME6="RIGHT"
+CONFIG_EXAMPLE_BUTTONS_NAME7="UP"
#
# Settings for examples/ostest
diff --git a/nuttx/configs/stm3210e-eval/src/stm3210e-internal.h b/nuttx/configs/stm3210e-eval/src/stm3210e-internal.h
index 8634feab8..42d3090e0 100755
--- a/nuttx/configs/stm3210e-eval/src/stm3210e-internal.h
+++ b/nuttx/configs/stm3210e-eval/src/stm3210e-internal.h
@@ -83,7 +83,7 @@
#define GPIO_BTN_WAKEUP (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|\
GPIO_PORTA|GPIO_PIN0)
#define GPIO_BTN_TAMPER (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|\
- GPIO_PORTA|GPIO_PIN0)
+ GPIO_PORTC|GPIO_PIN13)
#define GPIO_BTN_KEY (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|\
GPIO_EXTI|GPIO_PORTG|GPIO_PIN8)
#define GPIO_JOY_SEL (GPIO_INPUT|GPIO_CNF_INFLOAT|GPIO_MODE_INPUT|\
diff --git a/nuttx/configs/stm3210e-eval/src/up_buttons.c b/nuttx/configs/stm3210e-eval/src/up_buttons.c
index 9803b604c..b9c9fb9d4 100644
--- a/nuttx/configs/stm3210e-eval/src/up_buttons.c
+++ b/nuttx/configs/stm3210e-eval/src/up_buttons.c
@@ -109,11 +109,21 @@ uint8_t up_buttons(void)
for (i = 0; i < NUM_BUTTONS; i++)
{
- /* A LOW value means that the key is pressed */
+ /* A LOW value means that the key is pressed for most keys. The exception
+ * is the WAKEUP button.
+ */
- if (!stm32_gpioread(g_buttons[i]))
+ bool released = stm32_gpioread(g_buttons[i]);
+ if (i == BUTTON_WAKEUP)
{
- ret |= (1 << i);
+ released = !released;
+ }
+
+ /* Accumulate the set of depressed (not released) keys */
+
+ if (!released)
+ {
+ ret |= (1 << i);
}
}
diff --git a/nuttx/include/nuttx/arch.h b/nuttx/include/nuttx/arch.h
index 5bc3980aa..3a4dedfa3 100644
--- a/nuttx/include/nuttx/arch.h
+++ b/nuttx/include/nuttx/arch.h
@@ -560,8 +560,10 @@ EXTERN void up_buttoninit(void);
* Description:
* After up_buttoninit() has been called, up_buttons() may be called to
* collect the state of all buttons. up_buttons() returns an 8-bit bit set
- * with each bit associated with a button. The meaning of the each button
- * bit is board-specific.
+ * with each bit associated with a button. A bit set to "1" means that the
+ * button is depressed; a bit set to "0" means that the button is released.
+ * The correspondence of the each button bit and physical buttons is board-
+ * specific.
*
* NOTE: This interface may or may not be supported by board-specific
* logic. If the board supports button interfaces, then CONFIG_ARCH_BUTTONS