From a542fc51bf953fa19fac229ec10e3df06ae2488e Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Fri, 22 Mar 2024 18:46:12 -0300 Subject: [PATCH] boards/raspberrypi-pico: Add buttons support example This patch add support to use buttons example on raspberrypi-pico. Note: unfortunately the raspberry-pico board doesn't have usables buttons, then you need to add external buttons connected to GPIO16 and GPIO17. Signed-off-by: Alan C. Assis --- boards/Kconfig | 2 + .../rp2040/raspberrypi-pico/include/board.h | 9 + .../arm/rp2040/raspberrypi-pico/src/Make.defs | 4 + .../raspberrypi-pico/src/rp2040_bringup.c | 10 + .../raspberrypi-pico/src/rp2040_buttons.c | 177 ++++++++++++++++++ .../rp2040/raspberrypi-pico/src/rp2040_pico.h | 13 ++ 6 files changed, 215 insertions(+) create mode 100644 boards/arm/rp2040/raspberrypi-pico/src/rp2040_buttons.c diff --git a/boards/Kconfig b/boards/Kconfig index b6204b216279d..eaf34dcfb4ff9 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -1853,6 +1853,8 @@ config ARCH_BOARD_RASPBERRYPI_PICO bool "Raspberry Pi Pico board (not W)" depends on ARCH_CHIP_RP2040 select ARCH_HAVE_LEDS + select ARCH_HAVE_BUTTONS + select ARCH_HAVE_IRQBUTTONS ---help--- This is a port to the Raspberry Pi Pico board. diff --git a/boards/arm/rp2040/raspberrypi-pico/include/board.h b/boards/arm/rp2040/raspberrypi-pico/include/board.h index 2b8f1a697e6a1..01cae6cef3e20 100644 --- a/boards/arm/rp2040/raspberrypi-pico/include/board.h +++ b/boards/arm/rp2040/raspberrypi-pico/include/board.h @@ -109,6 +109,15 @@ * 2Hz, then a fatal error has been detected and the system has halted. */ +/* BUTTON definitions *******************************************************/ + +#define NUM_BUTTONS 2 + +#define BUTTON_USER1 0 +#define BUTTON_USER2 1 +#define BUTTON_USER1_BIT (1 << BUTTON_USER1) +#define BUTTON_USER2_BIT (1 << BUTTON_USER2) + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/boards/arm/rp2040/raspberrypi-pico/src/Make.defs b/boards/arm/rp2040/raspberrypi-pico/src/Make.defs index ab5f13e26fdab..9bbcee7c7ce12 100644 --- a/boards/arm/rp2040/raspberrypi-pico/src/Make.defs +++ b/boards/arm/rp2040/raspberrypi-pico/src/Make.defs @@ -34,6 +34,10 @@ else CSRCS += rp2040_userleds.c endif +ifeq ($(CONFIG_ARCH_BUTTONS),y) + CSRCS += rp2040_buttons.c +endif + DEPPATH += --dep-path board VPATH += :board CFLAGS += ${INCDIR_PREFIX}$(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board diff --git a/boards/arm/rp2040/raspberrypi-pico/src/rp2040_bringup.c b/boards/arm/rp2040/raspberrypi-pico/src/rp2040_bringup.c index ac6f4bdfc1b8e..e303691b0a3e7 100644 --- a/boards/arm/rp2040/raspberrypi-pico/src/rp2040_bringup.c +++ b/boards/arm/rp2040/raspberrypi-pico/src/rp2040_bringup.c @@ -74,5 +74,15 @@ int rp2040_bringup(void) } #endif +#ifdef CONFIG_INPUT_BUTTONS + /* Register the BUTTON driver */ + + ret = btn_lower_initialize("/dev/buttons"); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret); + } +#endif + return OK; } diff --git a/boards/arm/rp2040/raspberrypi-pico/src/rp2040_buttons.c b/boards/arm/rp2040/raspberrypi-pico/src/rp2040_buttons.c new file mode 100644 index 0000000000000..1350cd24ec975 --- /dev/null +++ b/boards/arm/rp2040/raspberrypi-pico/src/rp2040_buttons.c @@ -0,0 +1,177 @@ +/**************************************************************************** + * boards/arm/rp2040/raspberrypi-pico/src/rp2040_buttons.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 "rp2040_gpio.h" +#include "rp2040_pico.h" + +#if defined(CONFIG_ARCH_BUTTONS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#if defined(CONFIG_INPUT_BUTTONS) && !defined(CONFIG_ARCH_IRQBUTTONS) +# error "The NuttX Buttons Driver depends on IRQ support to work!\n" +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Pin configuration for external raspberrypi-pico buttons. */ + +static const uint32_t g_buttons[NUM_BUTTONS] = +{ + GPIO_BTN_USER1, GPIO_BTN_USER2 +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_button_initialize + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + ****************************************************************************/ + +uint32_t board_button_initialize(void) +{ + int i; + + /* Configure the GPIO pins as inputs. And we will use interrupts */ + + for (i = 0; i < NUM_BUTTONS; i++) + { + /* Initialize input pin */ + + rp2040_gpio_init(g_buttons[i]); + + /* pull-up = false : pull-down = false */ + + rp2040_gpio_set_pulls(g_buttons[i], false, false); + } + + return NUM_BUTTONS; +} + +/**************************************************************************** + * Name: board_buttons + ****************************************************************************/ + +uint32_t board_buttons(void) +{ + uint32_t ret = 0; + int i; + + /* Check that state of each key */ + + for (i = 0; i < NUM_BUTTONS; i++) + { + /* A LOW value means that the key is pressed. */ + + bool released = rp2040_gpio_get(g_buttons[i]); + + /* Accumulate the set of depressed (not released) keys */ + + if (!released) + { + ret |= (1 << i); + } + } + + return ret; +} + +/**************************************************************************** + * Button support. + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + * After board_button_initialize() has been called, board_buttons() may be + * called to collect the state of all buttons. board_buttons() returns + * an 32-bit bit set with each bit associated with a button. See the + * BUTTON_*_BIT definitions in board.h for the meaning of each bit. + * + * board_button_irq() may be called to register an interrupt handler that + * will be called when a button is depressed or released. The ID value is + * a button enumeration value that uniquely identifies a button resource. + * See the BUTTON_* definitions in board.h for the meaning of enumeration + * value. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQBUTTONS +int board_button_irq(int id, xcpt_t irqhandler, void *arg) +{ + int ret = -EINVAL; + + /* The following should be atomic */ + + if (id >= MIN_IRQBUTTON && id <= MAX_IRQBUTTON) + { + /* Make sure the interrupt is disabled */ + + rp2040_gpio_disable_irq(g_buttons[id]); + + /* Attach the interrupt handler */ + + ret = rp2040_gpio_irq_attach(g_buttons[id], + RP2040_GPIO_INTR_EDGE_LOW, + irqhandler, + arg); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: irq_attach() failed: %d\n", ret); + return ret; + } + + /* Enable interruption for this pin */ + + rp2040_gpio_enable_irq(g_buttons[id]); + } + + return ret; +} +#endif + +#endif /* CONFIG_ARCH_BUTTONS */ diff --git a/boards/arm/rp2040/raspberrypi-pico/src/rp2040_pico.h b/boards/arm/rp2040/raspberrypi-pico/src/rp2040_pico.h index 914e956dd3000..c62cbe39d596f 100644 --- a/boards/arm/rp2040/raspberrypi-pico/src/rp2040_pico.h +++ b/boards/arm/rp2040/raspberrypi-pico/src/rp2040_pico.h @@ -31,6 +31,19 @@ #define GPIO_LED1 25 /* The board's LED is connected to this pin */ +/* Buttons */ + +/* Buttons GPIO pins definition */ + +#define GPIO_BTN_USER1 16 +#define GPIO_BTN_USER2 17 + +/* Buttons IRQ definitions */ + +#define MIN_IRQBUTTON BUTTON_USER1 +#define MAX_IRQBUTTON BUTTON_USER2 +#define NUM_IRQBUTTONS (BUTTON_USER1 - BUTTON_USER2 + 1) + int rp2040_bringup(void); #ifdef CONFIG_DEV_GPIO