diff --git a/boards/arm/stm32/common/include/stm32_mpr121.h b/boards/arm/stm32/common/include/stm32_mpr121.h new file mode 100644 index 00000000000..185f2aac544 --- /dev/null +++ b/boards/arm/stm32/common/include/stm32_mpr121.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * boards/arm/stm32/common/include/stm32_mpr121.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_STM32_COMMON_INCLUDE_STM32_MPR121_H +#define __BOARDS_ARM_STM32_COMMON_INCLUDE_STM32_MPR121_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: board_mpr121_initialize + * + * Description: + * Initialize and register the MPR121 capacitive keypad. + * + * Input Parameters: + * devno - The device number, used to build the device path as /dev/keypadN + * busno - The I2C bus number + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int board_mpr121_initialize(int devno, int busno); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __BOARDS_ARM_STM32_COMMON_INCLUDE_STM32_MPR121_H */ diff --git a/boards/arm/stm32/common/src/CMakeLists.txt b/boards/arm/stm32/common/src/CMakeLists.txt index acbd4200a7f..6883bfaea51 100644 --- a/boards/arm/stm32/common/src/CMakeLists.txt +++ b/boards/arm/stm32/common/src/CMakeLists.txt @@ -166,4 +166,8 @@ if(CONFIG_INPUT_KMATRIX_I2C) list(APPEND SRCS stm32_kmatrix_i2c.c) endif() +if(CONFIG_INPUT_MPR121_KEYPAD) + list(APPEND SRCS stm32_mpr121.c) +endif() + target_sources(board PRIVATE ${SRCS}) diff --git a/boards/arm/stm32/common/src/Make.defs b/boards/arm/stm32/common/src/Make.defs index a86d230436e..bacc31b1dcf 100644 --- a/boards/arm/stm32/common/src/Make.defs +++ b/boards/arm/stm32/common/src/Make.defs @@ -86,6 +86,10 @@ ifeq ($(CONFIG_SENSORS_APDS9960),y) CSRCS += stm32_apds9960.c endif +ifeq ($(CONFIG_INPUT_MPR121_KEYPAD),y) + CSRCS += stm32_mpr121.c +endif + ifeq ($(CONFIG_SENSORS_ZEROCROSS),y) CSRCS += stm32_zerocross.c endif diff --git a/boards/arm/stm32/common/src/stm32_mpr121.c b/boards/arm/stm32/common/src/stm32_mpr121.c new file mode 100644 index 00000000000..bd0d0d5ad5e --- /dev/null +++ b/boards/arm/stm32/common/src/stm32_mpr121.c @@ -0,0 +1,182 @@ +/**************************************************************************** + * boards/arm/stm32/common/src/stm32_mpr121.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "stm32.h" +#include "stm32_i2c.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Device I2C Address of MPR121 Capacitive Keypad */ + +#define MPR121_I2C_ADDR 0x5a + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +struct stm32_mpr121config_s +{ + /* Configuration structure as seen by the MPR121 driver */ + + struct mpr121_config_s config; + + /* Additional private definitions only known to this driver */ + + void *arg; /* Argument to pass to the interrupt handler */ + xcpt_t isr; /* ISR Handler */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int mpr121_irq_attach(const struct mpr121_config_s *state, + xcpt_t isr, void *arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Keymap for 4x3 MPR121 Capacitive Keypad + * Keys named 11 and 10 were replaced with 'B' a 'A' + */ + +static const uint32_t g_mpr121_keymap[] = +{ + '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'A', 'B', +}; + +/* A reference to a structure of this type must be passed to the MPR121 + * driver. This structure provides information about the configuration + * of the MPR121 and provides some board-specific hooks. + * + * Memory for this structure is provided by the caller. It is not copied + * by the driver and is presumed to persist while the driver is active. The + * memory must be writable because, under certain circumstances, the driver + * may modify frequency or other values. + */ + +static struct stm32_mpr121config_s g_mpr121config = +{ + .config = + { + .irq_attach = mpr121_irq_attach, + .keymap = g_mpr121_keymap, + }, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Attach the MPR121 interrupt handler to the GPIO interrupt */ + +static int mpr121_irq_attach(const struct mpr121_config_s *state, + xcpt_t isr, void *arg) +{ + irqstate_t flags; + + iinfo("mpr121_irq_attach\n"); + + flags = enter_critical_section(); + + /* Setup interrupt for Falling Edge */ + + stm32_gpiosetevent(BOARD_MPR121_GPIO_INT, false, true, true, isr, arg); + + leave_critical_section(flags); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_mpr121_initialize + * + * Description: + * Initialize and register the MPR121 gesture sensor. + * + * Input Parameters: + * devno - The device number, used to build the device path as /dev/gestN + * busno - The I2C bus number + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int board_mpr121_initialize(int devno, int busno) +{ + struct i2c_master_s *i2c; + char devpath[14]; + int ret; + + iinfo("Initializing MPR121!\n"); + + /* Configure the GPIO interrupt */ + + stm32_configgpio(BOARD_MPR121_GPIO_INT); + + /* Initialize I2C */ + + i2c = stm32_i2cbus_initialize(busno); + if (i2c == NULL) + { + return -ENODEV; + } + + /* Save this i2c in the config */ + + g_mpr121config.config.i2c_dev = i2c; + g_mpr121config.config.i2c_addr = MPR121_I2C_ADDR; + + /* Then register the capacitive keypad */ + + snprintf(devpath, sizeof(devpath), "/dev/keypad%d", devno); + ret = mpr121_register(&g_mpr121config.config, devpath); + if (ret < 0) + { + ierr("ERROR: Failed registering APDS-9960!\n"); + } + + return ret; +} diff --git a/boards/arm/stm32/stm32f4discovery/configs/mpr121_keypad/defconfig b/boards/arm/stm32/stm32f4discovery/configs/mpr121_keypad/defconfig new file mode 100644 index 00000000000..8090b5152f0 --- /dev/null +++ b/boards/arm/stm32/stm32f4discovery/configs/mpr121_keypad/defconfig @@ -0,0 +1,58 @@ +# +# 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_ARCH_FPU is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32f4discovery" +CONFIG_ARCH_BOARD_COMMON=y +CONFIG_ARCH_BOARD_STM32F4_DISCOVERY=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F407VG=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_DEBUG_FEATURES=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_EXAMPLES_KEYBOARD=y +CONFIG_EXAMPLES_KEYBOARD_DEVPATH="/dev/keypad0" +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_I2C=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INPUT=y +CONFIG_INPUT_MPR121_KEYPAD=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LINE_MAX=64 +CONFIG_MM_REGIONS=2 +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_LPWORK=y +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32_I2C1=y +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_PWR=y +CONFIG_STM32_SPI1=y +CONFIG_STM32_USART2=y +CONFIG_SYSTEM_NSH=y +CONFIG_USART2_RXBUFSIZE=128 +CONFIG_USART2_SERIAL_CONSOLE=y +CONFIG_USART2_TXBUFSIZE=128 diff --git a/boards/arm/stm32/stm32f4discovery/include/board.h b/boards/arm/stm32/stm32f4discovery/include/board.h index 7392eff96cb..4f850570856 100644 --- a/boards/arm/stm32/stm32f4discovery/include/board.h +++ b/boards/arm/stm32/stm32f4discovery/include/board.h @@ -448,6 +448,13 @@ #define BOARD_APDS9960_GPIO_INT GPIO_APDS9960_INT +/* IRQ Pin for MPR121 Capacitive Keypad */ + +#define GPIO_MPR121_INT \ + (GPIO_INPUT|GPIO_PULLUP|GPIO_EXTI|GPIO_PORTB|GPIO_PIN0) + +#define BOARD_MPR121_GPIO_INT GPIO_MPR121_INT + /* LIS3DSH */ #define GPIO_LIS3DSH_EXT0 \ diff --git a/boards/arm/stm32/stm32f4discovery/src/stm32_bringup.c b/boards/arm/stm32/stm32f4discovery/src/stm32_bringup.c index ecb11f7e6e6..a49ce53519d 100644 --- a/boards/arm/stm32/stm32f4discovery/src/stm32_bringup.c +++ b/boards/arm/stm32/stm32f4discovery/src/stm32_bringup.c @@ -60,6 +60,10 @@ #include "stm32_apds9960.h" #endif +#ifdef CONFIG_INPUT_MPR121_KEYPAD +#include "stm32_mpr121.h" +#endif + #ifdef CONFIG_CL_MFRC522 #include "stm32_mfrc522.h" #endif @@ -272,6 +276,16 @@ int stm32_bringup(void) } #endif +#ifdef CONFIG_INPUT_MPR121_KEYPAD + /* Initialize MPR121 using I2C1 bus to /dev/keypad0 */ + + ret = board_mpr121_initialize(0, 1); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: board_mpr121_initialize failed: %d\n", ret); + } +#endif + #ifdef CONFIG_LCD_ST7032 ret = stm32_st7032init("/dev/slcd0"); if (ret < 0)