You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by gn...@apache.org on 2020/06/11 23:05:24 UTC

[incubator-nuttx] 03/04: boards/arm/stm32/olimex-stm32-p407: Add joystick support.

This is an automated email from the ASF dual-hosted git repository.

gnutt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit c3ba6031349cad8a86c69abbe4b3438bbfd07e7d
Author: Ouss4 <ab...@gmail.com>
AuthorDate: Wed Jun 10 22:31:33 2020 +0100

    boards/arm/stm32/olimex-stm32-p407: Add joystick support.
---
 boards/arm/stm32/olimex-stm32-p407/include/board.h |  42 +--
 boards/arm/stm32/olimex-stm32-p407/src/Make.defs   |   4 +
 .../olimex-stm32-p407/src/olimex-stm32-p407.h      |  35 ++-
 .../stm32/olimex-stm32-p407/src/stm32_bringup.c    |  10 +-
 .../stm32/olimex-stm32-p407/src/stm32_buttons.c    |  40 +--
 .../stm32/olimex-stm32-p407/src/stm32_djoystick.c  | 296 +++++++++++++++++++++
 6 files changed, 386 insertions(+), 41 deletions(-)

diff --git a/boards/arm/stm32/olimex-stm32-p407/include/board.h b/boards/arm/stm32/olimex-stm32-p407/include/board.h
index e5f5992..6d20355 100644
--- a/boards/arm/stm32/olimex-stm32-p407/include/board.h
+++ b/boards/arm/stm32/olimex-stm32-p407/include/board.h
@@ -209,23 +209,31 @@
 
 /* The Olimex STM32-P407 supports seven buttons: */
 
-#define BUTTON_TAMPER     0
-#define BUTTON_WKUP       1
-#define BUTTON_RIGHT      2
-#define BUTTON_UP         3
-#define BUTTON_LEFT       4
-#define BUTTON_DOWN       5
-#define BUTTON_CENTER     6
-
-#define NUM_BUTTONS       7
-
-#define BUTTON_TAMPER_BIT (1 << BUTTON_TAMPER)
-#define BUTTON_WKUP_BIT   (1 << BUTTON_WKUP)
-#define BUTTON_RIGHT_BIT  (1 << BUTTON_RIGHT)
-#define BUTTON_UP_BIT     (1 << BUTTON_UP)
-#define BUTTON_LEFT_BIT   (1 << BUTTON_LEFT)
-#define BUTTON_DOWN_BIT   (1 << BUTTON_DOWN)
-#define BUTTON_CENTER_BIT (1 << BUTTON_CENTER)
+#define BUTTON_TAMPER         0
+#define BUTTON_WKUP           1
+
+#ifdef CONFIG_DJOYSTICK
+#  define NUM_BUTTONS         2
+#else
+#  define JOYSTICK_RIGHT      2
+#  define JOYSTICK_UP         3
+#  define JOYSTICK_LEFT       4
+#  define JOYSTICK_DOWN       5
+#  define JOYSTICK_CENTER     6
+
+#  define NUM_BUTTONS         7
+#endif
+
+#define BUTTON_TAMPER_BIT     (1 << BUTTON_TAMPER)
+#define BUTTON_WKUP_BIT       (1 << BUTTON_WKUP)
+
+#ifndef CONFIG_DJOYSTICK
+#  define JOYSTICK_RIGHT_BIT  (1 << JOYSTICK_RIGHT)
+#  define JOYSTICK_UP_BIT     (1 << JOYSTICK_UP)
+#  define JOYSTICK_LEFT_BIT   (1 << JOYSTICK_LEFT)
+#  define JOYSTICK_DOWN_BIT   (1 << JOYSTICK_DOWN)
+#  define JOYSTICK_CENTER_BIT (1 << JOYSTICK_CENTER)
+#endif
 
 /* Alternate function pin selections ****************************************/
 
diff --git a/boards/arm/stm32/olimex-stm32-p407/src/Make.defs b/boards/arm/stm32/olimex-stm32-p407/src/Make.defs
index 7274cc9..d6a2691 100644
--- a/boards/arm/stm32/olimex-stm32-p407/src/Make.defs
+++ b/boards/arm/stm32/olimex-stm32-p407/src/Make.defs
@@ -71,6 +71,10 @@ ifeq ($(CONFIG_AUDIO_CS4344),y)
   CSRCS += stm32_cs4344.c
 endif
 
+ifeq ($(CONFIG_DJOYSTICK),y)
+  CSRCS += stm32_djoystick.c
+endif
+
 DEPPATH += --dep-path board
 VPATH += :board
 CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)
diff --git a/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h b/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h
index c5e380a..0f25f50 100644
--- a/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h
+++ b/boards/arm/stm32/olimex-stm32-p407/src/olimex-stm32-p407.h
@@ -159,17 +159,24 @@
 
 /* BUTTONS -- NOTE that all have EXTI interrupts configured */
 
-#define MIN_IRQBUTTON     BUTTON_TAMPER
-#define MAX_IRQBUTTON     BUTTON_CENTER
-#define NUM_IRQBUTTONS    7
+#ifdef CONFIG_DJOYSTICK
+#  define MIN_IRQBUTTON     BUTTON_TAMPER
+#  define MAX_IRQBUTTON     BUTTON_WKUP
+#  define NUM_IRQBUTTONS    2
+#else
+#  define MIN_IRQBUTTON     BUTTON_TAMPER
+#  define MAX_IRQBUTTON     JOYSTICK_CENTER
+#  define NUM_IRQBUTTONS    7
+#endif
 
 #define GPIO_BTN_TAMPER   (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTC|GPIO_PIN13)
 #define GPIO_BTN_WKUP     (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTA|GPIO_PIN0)
-#define GPIO_BTN_RIGHT    (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN6)
-#define GPIO_BTN_UP       (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN7)
-#define GPIO_BTN_LEFT     (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN11)
-#define GPIO_BTN_DOWN     (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN8)
-#define GPIO_BTN_CENTER   (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN15)
+
+#define GPIO_JOY_RIGHT    (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN6)
+#define GPIO_JOY_UP       (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN7)
+#define GPIO_JOY_LEFT     (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN11)
+#define GPIO_JOY_DOWN     (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN8)
+#define GPIO_JOY_CENTER   (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTG|GPIO_PIN15)
 
 /* USB OTG FS
  *
@@ -324,5 +331,17 @@ int stm32_can_setup(void);
 int stm32_cs4344_initialize(int minor);
 #endif
 
+/****************************************************************************
+ * Name: stm32_djoy_initialize
+ *
+ * Description:
+ *   Initialize and register the discrete joystick driver
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DJOYSTICK
+int stm32_djoy_initialize(void);
+#endif
+
 #endif /* __ASSEMBLY__ */
 #endif /* __BOARDS_ARM_STM32_OLIMEX_STM32_P407_SRC_H */
diff --git a/boards/arm/stm32/olimex-stm32-p407/src/stm32_bringup.c b/boards/arm/stm32/olimex-stm32-p407/src/stm32_bringup.c
index 7431d87..9be0369 100644
--- a/boards/arm/stm32/olimex-stm32-p407/src/stm32_bringup.c
+++ b/boards/arm/stm32/olimex-stm32-p407/src/stm32_bringup.c
@@ -219,7 +219,15 @@ int stm32_bringup(void)
   ret = stm32_cs4344_initialize(1);
   if (ret != OK)
     {
-      serr("Failed to initialize CS43L22 audio: %d\n", ret);
+      syslog(LOG_ERR, "Failed to initialize CS4344 audio: %d\n", ret);
+    }
+#endif
+
+#ifdef CONFIG_DJOYSTICK
+  ret = stm32_djoy_initialize();
+  if (ret != OK)
+    {
+      syslog(LOG_ERR, "Failed to register djoystick driver: %d\n", ret);
     }
 #endif
 
diff --git a/boards/arm/stm32/olimex-stm32-p407/src/stm32_buttons.c b/boards/arm/stm32/olimex-stm32-p407/src/stm32_buttons.c
index 2a3c0f9..12cf7ac 100644
--- a/boards/arm/stm32/olimex-stm32-p407/src/stm32_buttons.c
+++ b/boards/arm/stm32/olimex-stm32-p407/src/stm32_buttons.c
@@ -64,11 +64,19 @@ static const uint32_t g_buttons[NUM_BUTTONS] =
 {
   GPIO_BTN_TAMPER,
   GPIO_BTN_WKUP,
-  GPIO_BTN_RIGHT,
-  GPIO_BTN_UP,
-  GPIO_BTN_LEFT,
-  GPIO_BTN_DOWN,
-  GPIO_BTN_CENTER
+
+  /* The Joystick is treated like the other buttons unless CONFIG_DJOYSTICK
+   * is defined, then it is assumed that they should be used by the discrete
+   * joystick driver.
+   */
+
+#ifndef CONFIG_DJOYSTICK
+  GPIO_JOY_RIGHT,
+  GPIO_JOY_UP,
+  GPIO_JOY_LEFT,
+  GPIO_JOY_DOWN,
+  GPIO_JOY_CENTER
+#endif
 };
 
 /****************************************************************************
@@ -122,30 +130,32 @@ uint32_t board_buttons(void)
       ret |= BUTTON_WKUP_BIT;
     }
 
-  if (stm32_gpioread(g_buttons[BUTTON_RIGHT]))
+#ifndef CONFIG_DJOYSTICK
+  if (stm32_gpioread(g_buttons[JOYSTICK_RIGHT]))
     {
-      ret |= BUTTON_RIGHT_BIT;
+      ret |= JOYSTICK_RIGHT_BIT;
     }
 
-  if (stm32_gpioread(g_buttons[BUTTON_UP]))
+  if (stm32_gpioread(g_buttons[JOYSTICK_UP]))
     {
-      ret |= BUTTON_UP_BIT;
+      ret |= JOYSTICK_UP_BIT;
     }
 
-  if (stm32_gpioread(g_buttons[BUTTON_LEFT]))
+  if (stm32_gpioread(g_buttons[JOYSTICK_LEFT]))
     {
-      ret |= BUTTON_LEFT_BIT;
+      ret |= JOYSTICK_LEFT_BIT;
     }
 
-  if (stm32_gpioread(g_buttons[BUTTON_DOWN]))
+  if (stm32_gpioread(g_buttons[JOYSTICK_DOWN]))
     {
-      ret |= BUTTON_DOWN_BIT;
+      ret |= JOYSTICK_DOWN_BIT;
     }
 
-  if (stm32_gpioread(g_buttons[BUTTON_CENTER]))
+  if (stm32_gpioread(g_buttons[JOYSTICK_CENTER]))
     {
-      ret |= BUTTON_CENTER_BIT;
+      ret |= JOYSTICK_CENTER_BIT;
     }
+#endif
 
   return ret;
 }
diff --git a/boards/arm/stm32/olimex-stm32-p407/src/stm32_djoystick.c b/boards/arm/stm32/olimex-stm32-p407/src/stm32_djoystick.c
new file mode 100644
index 0000000..28c717e
--- /dev/null
+++ b/boards/arm/stm32/olimex-stm32-p407/src/stm32_djoystick.c
@@ -0,0 +1,296 @@
+/****************************************************************************
+ * boards/arm/stm32/olimex-stm32-p407/src/stm32_djoystick.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <debug.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/input/djoystick.h>
+
+#include "stm32_gpio.h"
+#include "olimex-stm32-p407.h"
+
+#ifdef CONFIG_DJOYSTICK
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Number of Joystick discretes */
+
+#define DJOY_NGPIOS  5
+
+/* Bitset of supported Joystick discretes */
+
+#define DJOY_SUPPORTED (DJOY_UP_BIT | DJOY_DOWN_BIT | DJOY_LEFT_BIT | \
+                        DJOY_RIGHT_BIT | DJOY_BUTTON_SELECT_BIT)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static djoy_buttonset_t
+  djoy_supported(FAR const struct djoy_lowerhalf_s *lower);
+static djoy_buttonset_t
+  djoy_sample(FAR const struct djoy_lowerhalf_s *lower);
+static void djoy_enable(FAR const struct djoy_lowerhalf_s *lower,
+                        djoy_buttonset_t press, djoy_buttonset_t release,
+                        djoy_interrupt_t handler, FAR void *arg);
+
+static void djoy_disable(void);
+static int djoy_interrupt(int irq, FAR void *context, FAR void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Pin configuration for each Olimex-P407 joystick "button."  Index using
+ * DJOY_* definitions in include/nuttx/input/djoystick.h.
+ */
+
+static const uint16_t g_joygpio[DJOY_NGPIOS] =
+{
+  GPIO_JOY_UP, GPIO_JOY_DOWN, GPIO_JOY_LEFT, GPIO_JOY_RIGHT, GPIO_JOY_CENTER
+};
+
+/* Current interrupt handler and argument */
+
+static djoy_interrupt_t g_djoyhandler;
+static FAR void *g_djoyarg;
+
+/* This is the discrete joystick lower half driver interface */
+
+static const struct djoy_lowerhalf_s g_djoylower =
+{
+  .dl_supported  = djoy_supported,
+  .dl_sample     = djoy_sample,
+  .dl_enable     = djoy_enable,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: djoy_supported
+ *
+ * Description:
+ *   Return the set of buttons supported on the discrete joystick device
+ *
+ ****************************************************************************/
+
+static djoy_buttonset_t
+  djoy_supported(FAR const struct djoy_lowerhalf_s *lower)
+{
+  iinfo("Supported: %02x\n", DJOY_SUPPORTED);
+  return (djoy_buttonset_t)DJOY_SUPPORTED;
+}
+
+/****************************************************************************
+ * Name: djoy_sample
+ *
+ * Description:
+ *   Return the current state of all discrete joystick buttons
+ *
+ ****************************************************************************/
+
+static djoy_buttonset_t djoy_sample(FAR const struct djoy_lowerhalf_s *lower)
+{
+  djoy_buttonset_t ret = 0;
+  int i;
+
+  /* Read each joystick GPIO value */
+
+  for (i = 0; i < DJOY_NGPIOS; i++)
+    {
+      bool released = stm32_gpioread(g_joygpio[i]);
+      if (!released)
+        {
+           ret |= (1 << i);
+        }
+    }
+
+  iinfo("Retuning: %02x\n", DJOY_SUPPORTED);
+  return ret;
+}
+
+/****************************************************************************
+ * Name: djoy_enable
+ *
+ * Description:
+ *   Enable interrupts on the selected set of joystick buttons.  And empty
+ *   set will disable all interrupts.
+ *
+ ****************************************************************************/
+
+static void djoy_enable(FAR const struct djoy_lowerhalf_s *lower,
+                         djoy_buttonset_t press, djoy_buttonset_t release,
+                         djoy_interrupt_t handler, FAR void *arg)
+{
+  irqstate_t flags;
+  djoy_buttonset_t either = press | release;
+  djoy_buttonset_t bit;
+  bool rising;
+  bool falling;
+  int i;
+
+  /* Start with all interrupts disabled */
+
+  flags = enter_critical_section();
+  djoy_disable();
+
+  iinfo("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_djoyhandler = handler;
+      g_djoyarg     = arg;
+
+      /* Check each GPIO. */
+
+      for (i = 0; i < DJOY_NGPIOS; i++)
+        {
+          /* Enable interrupts on each pin that has either a press or
+           * release event associated with it.
+           */
+
+          bit = (1 << i);
+          if ((either & bit) != 0)
+            {
+              /* Active low so a press corresponds to a falling edge and
+               * a release corresponds to a rising edge.
+               */
+
+              falling = ((press & bit) != 0);
+              rising  = ((release & bit) != 0);
+
+              iinfo("GPIO %d: rising: %d falling: %d\n",
+                     i, rising, falling);
+
+              stm32_gpiosetevent(g_joygpio[i], rising, falling,
+                                 true, djoy_interrupt, NULL);
+            }
+        }
+    }
+
+  leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: djoy_disable
+ *
+ * Description:
+ *   Disable all joystick interrupts
+ *
+ ****************************************************************************/
+
+static void djoy_disable(void)
+{
+  irqstate_t flags;
+  int i;
+
+  /* Disable each joystick interrupt */
+
+  flags = enter_critical_section();
+  for (i = 0; i < DJOY_NGPIOS; i++)
+    {
+      stm32_gpiosetevent(g_joygpio[i], false, false, false, NULL, NULL);
+    }
+
+  leave_critical_section(flags);
+
+  /* Nullify the handler and argument */
+
+  g_djoyhandler = NULL;
+  g_djoyarg     = NULL;
+}
+
+/****************************************************************************
+ * Name: djoy_interrupt
+ *
+ * Description:
+ *   Discrete joystick interrupt handler
+ *
+ ****************************************************************************/
+
+static int djoy_interrupt(int irq, FAR void *context, FAR void *arg)
+{
+  DEBUGASSERT(g_djoyhandler);
+  if (g_djoyhandler)
+    {
+      g_djoyhandler(&g_djoylower, g_djoyarg);
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_djoy_initialize
+ *
+ * Description:
+ *   Initialize and register the discrete joystick driver
+ *
+ ****************************************************************************/
+
+int stm32_djoy_initialize(void)
+{
+  int i;
+
+  /* Configure the GPIO pins as inputs.    NOTE: This is unnecessary for
+   * interrupting pins since it will also be done by stm32_gpiosetevent().
+   */
+
+  for (i = 0; i < DJOY_NGPIOS; i++)
+    {
+      stm32_configgpio(g_joygpio[i]);
+    }
+
+  /* Make sure that all interrupts are disabled */
+
+  djoy_disable();
+
+  /* Register the joystick device as /dev/djoy0 */
+
+  return djoy_register("/dev/djoy0", &g_djoylower);
+}
+
+#endif /* CONFIG_DJOYSTICK */