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