nucleo-wl55jc: add buttons and gpio interrupt support

This patch adds to the nucleo-wl55jc previously implemented EXTI support.
Button support with nuttx's button driver is added.

I've written small example to show how to use GPIO EXTI. B3 button can be
used (selectable via Kconfig) to toggle Red LED.

I've added new defconfig for demo purposes. I've included there config
and enabled example programs that are meant to demonstrate functions of
the board and does not really have a place in real world project. Like
Red LED can be toggled with B3 button, or LED example that flashes LEDS,
or button example to show which button has been pressed.

Signed-off-by: Michał Łyszczek <michal.lyszczek@bofc.pl>

--
v1 -> v2:
Suggested by: Petro Karashchenko
- Change (1 << 0) to (1 << BUTTON1_BIT (and similar)

v2 -> v3:
- Fix invalid BUTTON3_BIT value

v3 -> v4:
Suggested by: Petro Karashchenko
- Change 0/1 to false/true
This commit is contained in:
Michał Łyszczek 2022-06-12 14:19:50 +02:00 committed by Xiang Xiao
parent 288b57d5ca
commit 4e5d8aca3d
9 changed files with 282 additions and 3 deletions

View File

@ -79,6 +79,14 @@ nsh
Basic NuttShell configuration (console enabled in LPUART1, exposed via USB
connection, at 115200 bps 8n1).
demo
----
This configuration contains demonstration code and programs to show what
board is capable of. These programs and settings are usually absolutely
useless in production code and are here just to show, by example, what
you can do with the board.
Flash & Debug
=============

View File

@ -5,6 +5,16 @@
if ARCH_BOARD_NUCLEO_WL55JC
comment "empty"
config ARCH_BOARD_NUCLEO_WL55JC_DEMO_LED_IRQ
bool "[demo] LED on button interrupt"
depends on ARCH_BUTTONS
depends on NSH_ARCHINIT
---help---
When enabled, pressing B3 button will toggle red LED.
This options is mostly for demo purposes of how one
can install GPIO interrupt.
comment "[demo] LED on button interrupt requires NSH_ARCHINIT"
depends on !NSH_ARCHINIT || !ARCH_BUTTONS
endif # ARCH_BOARD_NUCLEO_WL55JC

View File

@ -0,0 +1,35 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="nucleo-wl55jc"
CONFIG_ARCH_BOARD_NUCLEO_WL55JC=y
CONFIG_ARCH_BOARD_NUCLEO_WL55JC_DEMO_LED_IRQ=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="stm32wl5"
CONFIG_ARCH_CHIP_STM32WL55JC_CPU1=y
CONFIG_ARCH_CHIP_STM32WL5=y
CONFIG_ARCH_IRQBUTTONS=y
CONFIG_BUILTIN=y
CONFIG_EXAMPLES_BUTTONS=y
CONFIG_EXAMPLES_LEDS=y
CONFIG_INIT_ENTRYNAME="main"
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INPUT=y
CONFIG_INPUT_BUTTONS=y
CONFIG_INPUT_BUTTONS_LOWER=y
CONFIG_LPUART1_SERIAL_CONSOLE=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_RAM_SIZE=32768
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_STM32WL5_LPUART1=y
CONFIG_SYSTEM_NSH=y
CONFIG_USERLED=y
CONFIG_USERLED_LOWER=y

View File

@ -136,6 +136,27 @@
#define GPIO_LPUART1_RX GPIO_LPUART1_RX_1 /* PA3 */
#define GPIO_LPUART1_TX GPIO_LPUART1_TX_1 /* PA2 */
/* user buttons
*
* There are 3 buttons provided for user to program
*
* PA0 - Button 1
* PA1 - Button 2
* PC6 - Button 3
*
* Buttons need to be pulled up internaly by chip,
* and button press will pull pin down to LOW level.
*/
#define BOARD_BUTTON1 0
#define BOARD_BUTTON2 1
#define BOARD_BUTTON3 2
#define BOARD_NBUTTONS 3
#define BUTTON1_BIT (1 << BOARD_BUTTON1)
#define BUTTON2_BIT (1 << BOARD_BUTTON2)
#define BUTTON3_BIT (1 << BOARD_BUTTON3)
/* LEDs
*
* The Nucleo wl55jc board provides 3 user leds

View File

@ -26,4 +26,8 @@ ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += stm32_appinit.c
endif
ifeq ($(CONFIG_ARCH_BUTTONS),y)
CSRCS += stm32_buttons.c
endif
include $(TOPDIR)/boards/Board.mk

View File

@ -29,6 +29,7 @@
#include <nuttx/compiler.h>
#include <stdint.h>
#include <stm32wl5.h>
/****************************************************************************
* Pre-processor Definitions
@ -51,6 +52,10 @@
#define GPIO_LED_RED (GPIO_PORTB|GPIO_PIN11|GPIO_OUTPUT|GPIO_PULLUP|GPIO_SPEED_50MHz)
#define GPIO_LED_BLUE (GPIO_PORTB|GPIO_PIN15|GPIO_OUTPUT|GPIO_PULLUP|GPIO_SPEED_50MHz)
#define GPIO_BUTTON1 (GPIO_PORTA|GPIO_PIN0|GPIO_INPUT|GPIO_PULLUP)
#define GPIO_BUTTON2 (GPIO_PORTA|GPIO_PIN1|GPIO_INPUT|GPIO_PULLUP)
#define GPIO_BUTTON3 (GPIO_PORTC|GPIO_PIN6|GPIO_INPUT|GPIO_PULLUP|GPIO_EXTI)
/****************************************************************************
* Public Data
****************************************************************************/

View File

@ -35,6 +35,7 @@
#include <nuttx/board.h>
#include <nuttx/fs/fs.h>
#include <nuttx/leds/userled.h>
#include <nuttx/input/buttons.h>
#include <stm32wl5.h>
#include <stm32wl5_uart.h>
@ -105,6 +106,16 @@ int board_app_initialize(uintptr_t arg)
}
#endif
#if defined(CONFIG_INPUT_BUTTONS_LOWER)
/* 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 ret;
}

View File

@ -0,0 +1,151 @@
/****************************************************************************
* boards/arm/stm32wl5/nucleo-wl55jc/src/stm32_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 <nuttx/config.h>
#include <stdint.h>
#include <errno.h>
#include <stdbool.h>
#include <nuttx/arch.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "nucleo-wl55jc.h"
/****************************************************************************
* 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)
{
/* Configure the single button as an input. NOTE that EXTI interrupts are
* also configured for the pin.
*/
stm32wl5_configgpio(GPIO_BUTTON1);
stm32wl5_configgpio(GPIO_BUTTON2);
#ifndef CONFIG_ARCH_BOARD_NUCLEO_WL55JC_DEMO_LED_IRQ
stm32wl5_configgpio(GPIO_BUTTON3);
return 3; /* number of buttons */
#else
return 2; /* number of buttons */
#endif
}
/****************************************************************************
* Name: board_buttons
****************************************************************************/
uint32_t board_buttons(void)
{
uint32_t state;
/* Check that state of each USER button.
* A LOW value means that the key is pressed.
*/
state = 0;
if (stm32wl5_gpioread(GPIO_BUTTON1) == 0)
{
state |= BUTTON1_BIT;
}
if (stm32wl5_gpioread(GPIO_BUTTON2) == 0)
{
state |= BUTTON2_BIT;
}
#ifndef CONFIG_ARCH_BOARD_NUCLEO_WL55JC_DEMO_LED_IRQ
if (stm32wl5_gpioread(GPIO_BUTTON3) == 0)
{
state |= BUTTON3_BIT;
}
#endif
return state;
}
/****************************************************************************
* 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 a
* 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;
if (id == BOARD_BUTTON1)
{
ret = stm32wl5_gpiosetevent(GPIO_BUTTON1, true, true, false,
irqhandler, arg);
}
if (id == BOARD_BUTTON2)
{
ret = stm32wl5_gpiosetevent(GPIO_BUTTON2, true, true, false,
irqhandler, arg);
}
#ifndef CONFIG_ARCH_BOARD_NUCLEO_WL55JC_DEMO_LED_IRQ
if (id == BOARD_BUTTON3)
{
ret = stm32wl5_gpiosetevent(GPIO_BUTTON3, true, true, false,
irqhandler, arg);
}
#endif
return ret;
}
#endif

View File

@ -27,6 +27,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <debug.h>
#include <stdbool.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
@ -36,6 +37,8 @@
#include "stm32wl5.h"
#include "nucleo-wl55jc.h"
#include <stdio.h>
/****************************************************************************
* Private Types
****************************************************************************/
@ -74,6 +77,31 @@ static void led_state(int state, unsigned int leds)
}
}
/****************************************************************************
* Name: button3_led
*
* Description:
* Toggles Red LED state from interrupt generated from button 3
****************************************************************************/
#ifdef CONFIG_ARCH_BOARD_NUCLEO_WL55JC_DEMO_LED_IRQ
static int button3_led(int irq, void *context, void *arg)
{
(void)irq;
(void)context;
(void)arg;
int state;
state = stm32wl5_gpioread(GPIO_LED_RED);
/* toggle state */
state = !state;
stm32wl5_gpiowrite(GPIO_LED_RED, state);
return 0;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -188,7 +216,13 @@ void board_autoled_off(int state)
uint32_t board_userled_initialize(void)
{
/* Already initialized by stm32_led_initialize. */
/* Leds are already initialized by stm32_led_initialize. */
#ifdef CONFIG_ARCH_BOARD_NUCLEO_WL55JC_DEMO_LED_IRQ
/* Configure B3 button to fire an interrupt on falling edge (on press) */
stm32wl5_gpiosetevent(GPIO_BUTTON3, false, true, false, button3_led, NULL);
#endif
return BOARD_NLEDS;
}
@ -209,7 +243,7 @@ void board_userled(int led, bool ledon)
unsigned int ledbit;
#ifndef CONFIG_ARCH_LEDS
if (led == BOARD_BLUE)
if (led == BOARD_LED_BLUE)
{
return;
}