diff --git a/boards/arm/stm32/stm32f4discovery/src/Make.defs b/boards/arm/stm32/stm32f4discovery/src/Make.defs index 1793630ca3e..98e33e0534c 100644 --- a/boards/arm/stm32/stm32f4discovery/src/Make.defs +++ b/boards/arm/stm32/stm32f4discovery/src/Make.defs @@ -175,6 +175,10 @@ ifeq ($(CONFIG_LCD_ST7789),y) CSRCS += stm32_st7789.c endif +ifeq ($(CONFIG_INPUT_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/stm32f4discovery/src/stm32_bringup.c b/boards/arm/stm32/stm32f4discovery/src/stm32_bringup.c index 99678d5c23d..3761a8db21d 100644 --- a/boards/arm/stm32/stm32f4discovery/src/stm32_bringup.c +++ b/boards/arm/stm32/stm32f4discovery/src/stm32_bringup.c @@ -382,6 +382,14 @@ int stm32_bringup(void) } #endif +#ifdef CONFIG_INPUT_DJOYSTICK + ret = stm32_djoy_initialize(); + if (ret != OK) + { + syslog(LOG_ERR, "Failed to register djoystick driver: %d\n", ret); + } +#endif + #ifdef CONFIG_INPUT_NUNCHUCK /* Register the Nunchuck driver */ diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32_djoystick.c b/boards/arm/stm32/stm32f4discovery/src/stm32_djoystick.c new file mode 100644 index 00000000000..2e0d9198b8d --- /dev/null +++ b/boards/arm/stm32/stm32f4discovery/src/stm32_djoystick.c @@ -0,0 +1,297 @@ +/**************************************************************************** + * boards/arm/stm32/stm32f4discovery/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 + +#include +#include +#include + +#include +#include +#include + +#include "stm32_gpio.h" +#include "stm32f4discovery.h" + +#ifdef CONFIG_INPUT_DJOYSTICK + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Number of Joystick discretes 5-WAY */ + +#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(const struct djoy_lowerhalf_s *lower); +static djoy_buttonset_t + djoy_sample(const struct djoy_lowerhalf_s *lower); +static void djoy_enable(const struct djoy_lowerhalf_s *lower, + djoy_buttonset_t press, djoy_buttonset_t release, + djoy_interrupt_t handler, void *arg); + +static void djoy_disable(void); +static int djoy_interrupt(int irq, void *context, 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 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(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(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(const struct djoy_lowerhalf_s *lower, + djoy_buttonset_t press, djoy_buttonset_t release, + djoy_interrupt_t handler, 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, void *context, 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_INPUT_DJOYSTICK */ diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32f4discovery.h b/boards/arm/stm32/stm32f4discovery/src/stm32f4discovery.h index 15953dd4a66..d35c0b2f91a 100644 --- a/boards/arm/stm32/stm32f4discovery/src/stm32f4discovery.h +++ b/boards/arm/stm32/stm32f4discovery/src/stm32f4discovery.h @@ -227,6 +227,14 @@ #define GPIO_CS43L22_RESET (GPIO_OUTPUT|GPIO_SPEED_50MHz|GPIO_PORTD|GPIO_PIN4) +/* Digital Joystick 5-WAY */ + +#define GPIO_JOY_UP (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN2) +#define GPIO_JOY_CENTER (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN3) +#define GPIO_JOY_LEFT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN4) +#define GPIO_JOY_DOWN (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN5) +#define GPIO_JOY_RIGHT (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTE|GPIO_PIN6) + /* LoRa SX127x */ #define GPIO_SX127X_DIO0 (GPIO_INPUT|GPIO_FLOAT|GPIO_EXTI|GPIO_PORTD|GPIO_PIN0) @@ -878,5 +886,17 @@ int hciuart_dev_initialize(void); int stm32_gs2200m_initialize(const char *devpath, int bus); #endif +/**************************************************************************** + * Name: stm32_djoy_initialize + * + * Description: + * Initialize and register the discrete joystick driver + * + ****************************************************************************/ + +#ifdef CONFIG_INPUT_DJOYSTICK +int stm32_djoy_initialize(void); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __BOARDS_ARM_STM32_STM32F4DISCOVERY_SRC_STM32F4DISCOVERY_H */