From a6df724b4f4f4e4a38111270336aafacbfde8fbd Mon Sep 17 00:00:00 2001 From: Samuel Martinez Date: Thu, 13 Jun 2024 12:34:54 -0400 Subject: [PATCH] BlackPill buttons example Description: Example to interact with KEY button and user external button connected to PA1. For KEY button pull-up resistor is active, board schematic does not show any pull-up or pull-down resistor. Results: Example working as expected. BlackPill PWM example Description: PWM example using PB0 - Timer3 - Channel 3 Create default configuration for the example. Controlling_RGB_LED Description: Controlling a RGB LED on NuttX for Black Pill board [STM32F411] Note: Example currently not working as expected. --- .../stm32f411-minimum/configs/pwm/defconfig | 53 +++++ .../configs/rgbled/defconfig | 69 +++++++ .../stm32/stm32f411-minimum/include/board.h | 30 ++- .../stm32f411-minimum/src/CMakeLists.txt | 12 ++ .../arm/stm32/stm32f411-minimum/src/Make.defs | 12 ++ .../stm32f411-minimum/src/stm32_bringup.c | 34 ++++ .../stm32f411-minimum/src/stm32_buttons.c | 158 +++++++++++++++ .../stm32/stm32f411-minimum/src/stm32_pwm.c | 125 ++++++++++++ .../stm32f411-minimum/src/stm32_rgbled.c | 181 ++++++++++++++++++ .../stm32f411-minimum/src/stm32f411-minimum.h | 46 ++++- 10 files changed, 715 insertions(+), 5 deletions(-) create mode 100644 boards/arm/stm32/stm32f411-minimum/configs/pwm/defconfig create mode 100644 boards/arm/stm32/stm32f411-minimum/configs/rgbled/defconfig create mode 100644 boards/arm/stm32/stm32f411-minimum/src/stm32_buttons.c create mode 100644 boards/arm/stm32/stm32f411-minimum/src/stm32_pwm.c create mode 100644 boards/arm/stm32/stm32f411-minimum/src/stm32_rgbled.c diff --git a/boards/arm/stm32/stm32f411-minimum/configs/pwm/defconfig b/boards/arm/stm32/stm32f411-minimum/configs/pwm/defconfig new file mode 100644 index 0000000000000..e7ceff11af471 --- /dev/null +++ b/boards/arm/stm32/stm32f411-minimum/configs/pwm/defconfig @@ -0,0 +1,53 @@ +# +# 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_DISABLE_OS_API is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_DISABLE_IFCONFIG is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_STM32_SYSCFG is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32f411-minimum" +CONFIG_ARCH_BOARD_STM32F411_MINIMUM=y +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F411CE=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=8499 +CONFIG_BUILTIN=y +CONFIG_EXAMPLES_PWM=y +CONFIG_HAVE_CXX=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PWM=y +CONFIG_RAM_SIZE=131072 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=6 +CONFIG_START_YEAR=2020 +CONFIG_STM32_FLASH_CONFIG_E=y +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_TIM3=y +CONFIG_STM32_TIM3_CH3OUT=y +CONFIG_STM32_TIM3_CHANNEL=3 +CONFIG_STM32_TIM3_PWM=y +CONFIG_STM32_USART1=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_USART1_SERIAL_CONSOLE=y diff --git a/boards/arm/stm32/stm32f411-minimum/configs/rgbled/defconfig b/boards/arm/stm32/stm32f411-minimum/configs/rgbled/defconfig new file mode 100644 index 0000000000000..c5e10b314722c --- /dev/null +++ b/boards/arm/stm32/stm32f411-minimum/configs/rgbled/defconfig @@ -0,0 +1,69 @@ +# +# 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_DISABLE_OS_API is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_DISABLE_IFCONFIG is not set +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_STM32_SYSCFG is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="stm32f411-minimum" +CONFIG_ARCH_BOARD_STM32F411_MINIMUM=y +CONFIG_ARCH_CHIP="stm32" +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F411CE=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARD_LOOPSPERMSEC=8499 +CONFIG_BUILTIN=y +CONFIG_EXAMPLES_RGBLED=y +CONFIG_HAVE_CXX=y +CONFIG_INIT_ENTRYPOINT="nsh_main" +CONFIG_INTELHEX_BINARY=y +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PWM=y +CONFIG_RAM_SIZE=131072 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RGBLED=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=6 +CONFIG_START_YEAR=2020 +CONFIG_STM32_FLASH_CONFIG_E=y +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_TIM1=y +CONFIG_STM32_TIM1_CH1OUT=y +CONFIG_STM32_TIM1_CHMODE=0 +CONFIG_STM32_TIM1_PWM=y +CONFIG_STM32_TIM2=y +CONFIG_STM32_TIM2_CH2OUT=y +CONFIG_STM32_TIM2_CHANNEL=2 +CONFIG_STM32_TIM2_CHMODE=0 +CONFIG_STM32_TIM2_PWM=y +CONFIG_STM32_TIM3=y +CONFIG_STM32_TIM3_CH3OUT=y +CONFIG_STM32_TIM3_CHANNEL=3 +CONFIG_STM32_TIM3_CHMODE=0 +CONFIG_STM32_TIM3_PWM=y +CONFIG_STM32_TIM4=y +CONFIG_STM32_TIM4_CH4OUT=y +CONFIG_STM32_TIM4_CHANNEL=4 +CONFIG_STM32_TIM4_CHMODE=0 +CONFIG_STM32_TIM4_PWM=y +CONFIG_STM32_USART1=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=0 +CONFIG_USART1_SERIAL_CONSOLE=y diff --git a/boards/arm/stm32/stm32f411-minimum/include/board.h b/boards/arm/stm32/stm32f411-minimum/include/board.h index 667c4541c116b..99978b159756c 100644 --- a/boards/arm/stm32/stm32f411-minimum/include/board.h +++ b/boards/arm/stm32/stm32f411-minimum/include/board.h @@ -250,6 +250,30 @@ #define GPIO_USART6_RX GPIO_USART6_RX_1 /* PC7 */ #define GPIO_USART6_TX GPIO_USART6_TX_1 /* PC6 */ +/* PWM + * + * The STM32F4 Discovery has no real on-board PWM devices, but the board + * can be configured to output a pulse train using TIM4 CH2 on PD13. + */ +#define GPIO_TIM1_CH1OUT GPIO_TIM1_CH1OUT_1 //PA8 +#define GPIO_TIM2_CH2OUT GPIO_TIM2_CH2OUT_1 //PA1 +#define GPIO_TIM3_CH3OUT GPIO_TIM3_CH3OUT_1 //PB0 +#define GPIO_TIM4_CH4OUT GPIO_TIM4_CH4OUT_1 //PB9 + +/* RGB LED + * + * R = TIM1 CH1 on PA8 | G = TIM2 CH2 on PA1 | B = TIM4 CH4 on PB9 + * + * Note: Pin boards: GPIO_TIM1_CH1OUT ; GPIO_TIM2_CH2OUT ; GPIO_TIM4_CH4OUT + */ + +#define RGBLED_RPWMTIMER 1 +#define RGBLED_RPWMCHANNEL 1 +#define RGBLED_GPWMTIMER 2 +#define RGBLED_GPWMCHANNEL 2 +#define RGBLED_BPWMTIMER 4 +#define RGBLED_BPWMCHANNEL 4 + /* UART RX DMA configurations */ #define DMAMAP_USART1_RX DMAMAP_USART1_RX_2 @@ -321,8 +345,10 @@ */ #define BUTTON_USER 0 -#define NUM_BUTTONS 1 +#define BUTTON_EXTERNAL 1 //External user button connected to PA1 +#define NUM_BUTTONS 2 -#define BUTTON_USER_BIT (1 << BUTTON_USER) +#define BUTTON_USER_BIT (1 << BUTTON_USER) +#define BUTTON_EXTERNAL_BIT (1 << BUTTON_EXTERNAL) #endif /* __BOARDS_ARM_STM32_STM32F411_MINIMUM_INCLUDE_BOARD_H */ diff --git a/boards/arm/stm32/stm32f411-minimum/src/CMakeLists.txt b/boards/arm/stm32/stm32f411-minimum/src/CMakeLists.txt index 6ee723460f606..0dd0cdf1a5cb9 100644 --- a/boards/arm/stm32/stm32f411-minimum/src/CMakeLists.txt +++ b/boards/arm/stm32/stm32f411-minimum/src/CMakeLists.txt @@ -32,6 +32,18 @@ if(CONFIG_USERLED) list(APPEND SRCS stm32_userleds.c) endif() +if(CONFIG_ARCH_BUTTONS) + list(APPEND SRCS stm32_buttons.c) +endif() + +if(CONFIG_PWM) + list(APPEND SRCS stm32_pwm.c) +endif() + +if(CONFIG_RGBLED) + list(APPEND SRCS stm32_rgbled.c) +endif() + if(CONFIG_SPI) list(APPEND SRCS stm32_spi.c) endif() diff --git a/boards/arm/stm32/stm32f411-minimum/src/Make.defs b/boards/arm/stm32/stm32f411-minimum/src/Make.defs index b9fbe021b5207..6bee13a23f9e9 100644 --- a/boards/arm/stm32/stm32f411-minimum/src/Make.defs +++ b/boards/arm/stm32/stm32f411-minimum/src/Make.defs @@ -34,6 +34,18 @@ ifeq ($(CONFIG_USERLED),y) CSRCS += stm32_userleds.c endif +ifeq ($(CONFIG_ARCH_BUTTONS),y) + CSRCS += stm32_buttons.c +endif + +ifeq ($(CONFIG_PWM),y) + CSRCS += stm32_pwm.c +endif + +ifeq ($(CONFIG_RGBLED),y) + CSRCS += stm32_rgbled.c +endif + ifeq ($(CONFIG_ADC_HX711),y) CSRCS += stm32_hx711.c endif diff --git a/boards/arm/stm32/stm32f411-minimum/src/stm32_bringup.c b/boards/arm/stm32/stm32f411-minimum/src/stm32_bringup.c index fa710238c3eaa..7fbad3e8f7bd9 100644 --- a/boards/arm/stm32/stm32f411-minimum/src/stm32_bringup.c +++ b/boards/arm/stm32/stm32f411-minimum/src/stm32_bringup.c @@ -34,6 +34,10 @@ # include #endif +#ifdef CONFIG_INPUT_BUTTONS +# include +#endif + #ifdef CONFIG_STM32_OTGFS # include "stm32_usbhost.h" #endif @@ -98,6 +102,36 @@ int stm32_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 + +#ifdef CONFIG_PWM + /* Initialize PWM and register the PWM device. */ + + ret = stm32_pwm_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_pwm_setup() failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_RGBLED + /* Configure and initialize the RGB LED. */ + + ret = stm32_rgbled_setup(); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_rgbled_setup() failed: %d\n", ret); + } +#endif + #ifdef CONFIG_STM32F411MINIMUM_GPIO ret = stm32_gpio_initialize(); if (ret != OK) diff --git a/boards/arm/stm32/stm32f411-minimum/src/stm32_buttons.c b/boards/arm/stm32/stm32f411-minimum/src/stm32_buttons.c new file mode 100644 index 0000000000000..777e6c244c322 --- /dev/null +++ b/boards/arm/stm32/stm32f411-minimum/src/stm32_buttons.c @@ -0,0 +1,158 @@ +/**************************************************************************** + * boards/arm/stm32/stm32f411-minimum/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 + +#include +#include + +#include +#include +#include + +#include "stm32_gpio.h" +#include "stm32f411-minimum.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 each STM32F3Discovery button. This array is indexed + * by the BUTTON_* definitions in board.h + */ + +static const uint32_t g_buttons[NUM_BUTTONS] = +{ + GPIO_BTN_USER, GPIO_BTN_EXTERNAL +}; + +/**************************************************************************** + * 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. NOTE that EXTI interrupts are + * configured for all pins. + */ + + for (i = 0; i < NUM_BUTTONS; i++) + { + stm32_configgpio(g_buttons[i]); + } + + 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 = stm32_gpioread(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) + { + ret = stm32_gpiosetevent(g_buttons[id], true, true, true, irqhandler, + arg); + } + + return ret; +} +#endif + +#endif /* CONFIG_ARCH_BUTTONS */ diff --git a/boards/arm/stm32/stm32f411-minimum/src/stm32_pwm.c b/boards/arm/stm32/stm32f411-minimum/src/stm32_pwm.c new file mode 100644 index 0000000000000..bc7e2f06cb1d4 --- /dev/null +++ b/boards/arm/stm32/stm32f411-minimum/src/stm32_pwm.c @@ -0,0 +1,125 @@ +/**************************************************************************** + * boards/arm/stm32/stm32f411-minimum/src/stm32_pwm.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 "chip.h" +#include "arm_internal.h" +#include "stm32_pwm.h" +#include "stm32f411-minimum.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* PWM + * + * The stm32f411-minimum has no real on-board PWM devices, but the board can + * be configured to output a pulse train using TIM4 CH2. + * This pin is used by FSMC is connect to CN5 just for this purpose: + * + * PB0 ADC12_IN8/TIM3_CH3 + * + */ + +#define HAVE_PWM 1 + +#ifndef CONFIG_PWM +# undef HAVE_PWM +#endif + +#ifndef CONFIG_STM32_TIM3 +# undef HAVE_PWM +#endif + +#ifndef CONFIG_STM32_TIM3_PWM +# undef HAVE_PWM +#endif + +#if !defined(CONFIG_STM32_TIM3_CHANNEL) || CONFIG_STM32_TIM3_CHANNEL != STM32F411MINIMUM_PWMCHANNEL +# undef HAVE_PWM +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ****************************************************************************/ + +int stm32_pwm_setup(void) +{ +#ifdef HAVE_PWM + static bool initialized = false; + struct pwm_lowerhalf_s *pwm; + int ret; + + /* Have we already initialized? */ + + if (!initialized) + { + /* Call stm32_pwminitialize() to get an instance of the PWM interface */ + + pwm = stm32_pwminitialize(STM32F411MINIMUM_PWMTIMER); + if (!pwm) + { + aerr("ERROR: Failed to get the STM32 PWM lower half\n"); + return -ENODEV; + } + + /* Register the PWM driver at "/dev/pwm0" */ + + ret = pwm_register("/dev/pwm0", pwm); + if (ret < 0) + { + aerr("ERROR: pwm_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +#else + return -ENODEV; +#endif +} diff --git a/boards/arm/stm32/stm32f411-minimum/src/stm32_rgbled.c b/boards/arm/stm32/stm32f411-minimum/src/stm32_rgbled.c new file mode 100644 index 0000000000000..0ef9cd9e1fcc9 --- /dev/null +++ b/boards/arm/stm32/stm32f411-minimum/src/stm32_rgbled.c @@ -0,0 +1,181 @@ +/**************************************************************************** + * boards/arm/stm32/stm32f411-minimum/src/stm32_rgbled.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 "chip.h" +#include "arm_internal.h" +#include "stm32_pwm.h" +#include "stm32f411-minimum.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +#define HAVE_RGBLED 1 + +#ifndef CONFIG_PWM +# undef HAVE_RGBLED +#endif + +#ifndef CONFIG_STM32_TIM1 +# undef HAVE_RGBLED +#endif + +#ifndef CONFIG_STM32_TIM2 +# undef HAVE_RGBLED +#endif + +#ifndef CONFIG_STM32_TIM4 +# undef HAVE_RGBLED +#endif + +#ifndef CONFIG_STM32_TIM1_PWM +# undef HAVE_RGBLED +#endif + +#ifndef CONFIG_STM32_TIM2_PWM +# undef HAVE_RGBLED +#endif + +#ifndef CONFIG_STM32_TIM4_PWM +# undef HAVE_RGBLED +#endif + +#if CONFIG_STM32_TIM1_CHANNEL != RGBLED_RPWMCHANNEL +# undef HAVE_PWM +#endif + +#if CONFIG_STM32_TIM2_CHANNEL != RGBLED_GPWMCHANNEL +# undef HAVE_PWM +#endif + +#if CONFIG_STM32_TIM4_CHANNEL != RGBLED_BPWMCHANNEL +# undef HAVE_PWM +#endif + +#ifdef HAVE_RGBLED + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rgbled_setup + * + * Description: + * Initial for support of a connected RGB LED using PWM. + * + ****************************************************************************/ + +int stm32_rgbled_setup(void) +{ + static bool initialized = false; + struct pwm_lowerhalf_s *ledr; + struct pwm_lowerhalf_s *ledg; + struct pwm_lowerhalf_s *ledb; + struct pwm_info_s info; + int ret; + + /* Have we already initialized? */ + + if (!initialized) + { + /* Call stm32_pwminitialize() to get an instance of the PWM interface */ + + ledr = stm32_pwminitialize(RGBLED_RPWMTIMER); + if (!ledr) + { + lederr("ERROR: Failed to get the STM32 PWM lower half to LEDR\n"); + return -ENODEV; + } + + /* Define frequency and duty cycle */ + + info.frequency = 100; + info.duty = 0; + + /* Initialize LED R */ + + ledr->ops->setup(ledr); + ledr->ops->start(ledr, &info); + + /* Call stm32_pwminitialize() to get an instance of the PWM interface */ + + ledg = stm32_pwminitialize(RGBLED_GPWMTIMER); + if (!ledg) + { + lederr("ERROR: Failed to get the STM32 PWM lower half to LEDG\n"); + return -ENODEV; + } + + /* Initialize LED G */ + + ledg->ops->setup(ledg); + ledg->ops->start(ledg, &info); + + /* Call stm32_pwminitialize() to get an instance of the PWM interface */ + + ledb = stm32_pwminitialize(RGBLED_BPWMTIMER); + if (!ledb) + { + lederr("ERROR: Failed to get the STM32 PWM lower half to LEDB\n"); + return -ENODEV; + } + + /* Initialize LED B */ + + ledb->ops->setup(ledb); + ledb->ops->start(ledb, &info); + + /* Register the RGB LED diver at "/dev/rgbled0" */ + + ret = rgbled_register("/dev/rgbled0", ledr, ledg, ledb); + if (ret < 0) + { + lederr("ERROR: rgbled_register failed: %d\n", ret); + return ret; + } + + /* Now we are initialized */ + + initialized = true; + } + + return OK; +} + +#else +# error "HAVE_RGBLED is undefined" +#endif /* HAVE_RGBLED */ diff --git a/boards/arm/stm32/stm32f411-minimum/src/stm32f411-minimum.h b/boards/arm/stm32/stm32f411-minimum/src/stm32f411-minimum.h index 53770be2667d3..96e821c9a51b8 100644 --- a/boards/arm/stm32/stm32f411-minimum/src/stm32f411-minimum.h +++ b/boards/arm/stm32/stm32f411-minimum/src/stm32f411-minimum.h @@ -59,11 +59,19 @@ */ #define MIN_IRQBUTTON BUTTON_USER -#define MAX_IRQBUTTON BUTTON_USER -#define NUM_IRQBUTTONS 1 +#define MAX_IRQBUTTON BUTTON_EXTERNAL +#define NUM_IRQBUTTONS (BUTTON_USER - BUTTON_EXTERNAL + 1) #define GPIO_BTN_USER \ - (GPIO_INPUT |GPIO_FLOAT |GPIO_EXTI | GPIO_PORTA | GPIO_PIN0) + (GPIO_INPUT |GPIO_PULLUP |GPIO_EXTI | GPIO_PORTA | GPIO_PIN0) + +#define GPIO_BTN_EXTERNAL \ + (GPIO_INPUT |GPIO_FLOAT |GPIO_EXTI | GPIO_PORTA | GPIO_PIN1) + +/* PWM Configuration */ + +#define STM32F411MINIMUM_PWMTIMER 3 +#define STM32F411MINIMUM_PWMCHANNEL 3 /* SPI chip selects */ @@ -200,6 +208,38 @@ int stm32_usbhost_initialize(void); int stm32_gpio_initialize(void); #endif +/**************************************************************************** + * Name: stm32_pwm_setup + * + * Description: + * Initialize PWM and register the PWM device. + * + ****************************************************************************/ + +#ifdef CONFIG_PWM +int stm32_pwm_setup(void); +#endif + +/**************************************************************************** + * Name: stm32_rgbled_setup + * + * Description: + * This function is called by board initialization logic to configure the + * RGB LED driver. This function will register the driver as /dev/rgbled0. + * + * Input Parameters: + * None + * + * Returned Value: + * Zero is returned on success. Otherwise, a negated errno value is + * returned to indicate the nature of the failure. + * + ****************************************************************************/ + +#ifdef CONFIG_RGBLED +int stm32_rgbled_setup(void); +#endif + /**************************************************************************** * Name: stm32_bringup *